Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Cygdb.py +180 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/DebugWriter.py +90 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Tests/__pycache__/__init__.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Tests/__pycache__/test_libpython_in_gdb.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Tests/cfuncs.c +8 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/__init__.py +1 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/__pycache__/DebugWriter.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/__pycache__/libcython.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/libcython.py +1461 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/libpython.py +2851 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__init__.py +2 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/__init__.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/build_ext.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/extension.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/old_build_ext.cpython-311.pyc +0 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/build_ext.py +138 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/old_build_ext.py +357 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/bytearray.pxd +33 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/bytes.pxd +200 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/contextvars.pxd +140 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/datetime.pxd +426 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/dict.pxd +186 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/genobject.pxd +25 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/iterator.pxd +36 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/method.pxd +49 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/pylifecycle.pxd +68 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/time.pxd +79 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/tuple.pxd +72 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/unicode.pxd +639 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/__init__.pxd +1 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/complex.pxd +35 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/errno.pxd +127 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/float.pxd +43 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/limits.pxd +28 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/locale.pxd +46 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/math.pxd +209 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/setjmp.pxd +10 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/signal.pxd +64 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stddef.pxd +9 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stdint.pxd +105 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stdio.pxd +80 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stdlib.pxd +72 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/string.pxd +50 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/time.pxd +47 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/__init__.pxd +1 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/fcntl.pxd +86 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/mman.pxd +101 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/signal.pxd +73 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/stdio.pxd +37 -0
- tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/stdlib.pxd +29 -0
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Cygdb.py
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
|
| 3 |
+
"""
|
| 4 |
+
The Cython debugger
|
| 5 |
+
|
| 6 |
+
The current directory should contain a directory named 'cython_debug', or a
|
| 7 |
+
path to the cython project directory should be given (the parent directory of
|
| 8 |
+
cython_debug).
|
| 9 |
+
|
| 10 |
+
Additional gdb args can be provided only if a path to the project directory is
|
| 11 |
+
given.
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
import os
|
| 15 |
+
import sys
|
| 16 |
+
import glob
|
| 17 |
+
import tempfile
|
| 18 |
+
import textwrap
|
| 19 |
+
import subprocess
|
| 20 |
+
import optparse
|
| 21 |
+
import logging
|
| 22 |
+
|
| 23 |
+
logger = logging.getLogger(__name__)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def make_command_file(path_to_debug_info, prefix_code='',
|
| 27 |
+
no_import=False, skip_interpreter=False):
|
| 28 |
+
if not no_import:
|
| 29 |
+
pattern = os.path.join(path_to_debug_info,
|
| 30 |
+
'cython_debug',
|
| 31 |
+
'cython_debug_info_*')
|
| 32 |
+
debug_files = glob.glob(pattern)
|
| 33 |
+
|
| 34 |
+
if not debug_files:
|
| 35 |
+
sys.exit('%s.\nNo debug files were found in %s. Aborting.' % (
|
| 36 |
+
usage, os.path.abspath(path_to_debug_info)))
|
| 37 |
+
|
| 38 |
+
fd, tempfilename = tempfile.mkstemp()
|
| 39 |
+
f = os.fdopen(fd, 'w')
|
| 40 |
+
try:
|
| 41 |
+
f.write(prefix_code)
|
| 42 |
+
f.write(textwrap.dedent('''\
|
| 43 |
+
# This is a gdb command file
|
| 44 |
+
# See https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html
|
| 45 |
+
|
| 46 |
+
set breakpoint pending on
|
| 47 |
+
set print pretty on
|
| 48 |
+
|
| 49 |
+
python
|
| 50 |
+
try:
|
| 51 |
+
# Activate virtualenv, if we were launched from one
|
| 52 |
+
import os
|
| 53 |
+
virtualenv = os.getenv('VIRTUAL_ENV')
|
| 54 |
+
if virtualenv:
|
| 55 |
+
path_to_activate_this_py = os.path.join(virtualenv, 'bin', 'activate_this.py')
|
| 56 |
+
print("gdb command file: Activating virtualenv: %s; path_to_activate_this_py: %s" % (
|
| 57 |
+
virtualenv, path_to_activate_this_py))
|
| 58 |
+
with open(path_to_activate_this_py) as f:
|
| 59 |
+
exec(f.read(), dict(__file__=path_to_activate_this_py))
|
| 60 |
+
from Cython.Debugger import libcython, libpython
|
| 61 |
+
except Exception as ex:
|
| 62 |
+
from traceback import print_exc
|
| 63 |
+
print("There was an error in Python code originating from the file ''' + str(__file__) + '''")
|
| 64 |
+
print("It used the Python interpreter " + str(sys.executable))
|
| 65 |
+
print_exc()
|
| 66 |
+
exit(1)
|
| 67 |
+
end
|
| 68 |
+
'''))
|
| 69 |
+
|
| 70 |
+
if no_import:
|
| 71 |
+
# don't do this, this overrides file command in .gdbinit
|
| 72 |
+
# f.write("file %s\n" % sys.executable)
|
| 73 |
+
pass
|
| 74 |
+
else:
|
| 75 |
+
if not skip_interpreter:
|
| 76 |
+
# Point Cygdb to the interpreter that was used to generate
|
| 77 |
+
# the debugging information.
|
| 78 |
+
path = os.path.join(path_to_debug_info, "cython_debug", "interpreter")
|
| 79 |
+
interpreter_file = open(path)
|
| 80 |
+
try:
|
| 81 |
+
interpreter = interpreter_file.read()
|
| 82 |
+
finally:
|
| 83 |
+
interpreter_file.close()
|
| 84 |
+
f.write("file %s\n" % interpreter)
|
| 85 |
+
|
| 86 |
+
f.write('\n'.join('cy import %s\n' % fn for fn in debug_files))
|
| 87 |
+
|
| 88 |
+
if not skip_interpreter:
|
| 89 |
+
f.write(textwrap.dedent('''\
|
| 90 |
+
python
|
| 91 |
+
import sys
|
| 92 |
+
try:
|
| 93 |
+
gdb.lookup_type('PyModuleObject')
|
| 94 |
+
except RuntimeError:
|
| 95 |
+
sys.stderr.write(
|
| 96 |
+
"''' + interpreter + ''' was not compiled with debug symbols (or it was "
|
| 97 |
+
"stripped). Some functionality may not work (properly).\\n")
|
| 98 |
+
end
|
| 99 |
+
'''))
|
| 100 |
+
|
| 101 |
+
f.write("source .cygdbinit")
|
| 102 |
+
finally:
|
| 103 |
+
f.close()
|
| 104 |
+
|
| 105 |
+
return tempfilename
|
| 106 |
+
|
| 107 |
+
usage = "Usage: cygdb [options] [PATH [-- GDB_ARGUMENTS]]"
|
| 108 |
+
|
| 109 |
+
def main(path_to_debug_info=None, gdb_argv=None, no_import=False):
|
| 110 |
+
"""
|
| 111 |
+
Start the Cython debugger. This tells gdb to import the Cython and Python
|
| 112 |
+
extensions (libcython.py and libpython.py) and it enables gdb's pending
|
| 113 |
+
breakpoints.
|
| 114 |
+
|
| 115 |
+
path_to_debug_info is the path to the Cython build directory
|
| 116 |
+
gdb_argv is the list of options to gdb
|
| 117 |
+
no_import tells cygdb whether it should import debug information
|
| 118 |
+
"""
|
| 119 |
+
parser = optparse.OptionParser(usage=usage)
|
| 120 |
+
parser.add_option("--gdb-executable",
|
| 121 |
+
dest="gdb", default='gdb',
|
| 122 |
+
help="gdb executable to use [default: gdb]")
|
| 123 |
+
parser.add_option("--verbose", "-v",
|
| 124 |
+
dest="verbosity", action="count", default=0,
|
| 125 |
+
help="Verbose mode. Multiple -v options increase the verbosity")
|
| 126 |
+
parser.add_option("--skip-interpreter",
|
| 127 |
+
dest="skip_interpreter", default=False, action="store_true",
|
| 128 |
+
help="Do not automatically point GDB to the same interpreter "
|
| 129 |
+
"used to generate debugging information")
|
| 130 |
+
|
| 131 |
+
(options, args) = parser.parse_args()
|
| 132 |
+
if path_to_debug_info is None:
|
| 133 |
+
if len(args) > 1:
|
| 134 |
+
path_to_debug_info = args[0]
|
| 135 |
+
else:
|
| 136 |
+
path_to_debug_info = os.curdir
|
| 137 |
+
|
| 138 |
+
if gdb_argv is None:
|
| 139 |
+
gdb_argv = args[1:]
|
| 140 |
+
|
| 141 |
+
if path_to_debug_info == '--':
|
| 142 |
+
no_import = True
|
| 143 |
+
|
| 144 |
+
logging_level = logging.WARN
|
| 145 |
+
if options.verbosity == 1:
|
| 146 |
+
logging_level = logging.INFO
|
| 147 |
+
if options.verbosity >= 2:
|
| 148 |
+
logging_level = logging.DEBUG
|
| 149 |
+
logging.basicConfig(level=logging_level)
|
| 150 |
+
|
| 151 |
+
skip_interpreter = options.skip_interpreter
|
| 152 |
+
|
| 153 |
+
logger.info("verbosity = %r", options.verbosity)
|
| 154 |
+
logger.debug("options = %r; args = %r", options, args)
|
| 155 |
+
logger.debug("Done parsing command-line options. path_to_debug_info = %r, gdb_argv = %r",
|
| 156 |
+
path_to_debug_info, gdb_argv)
|
| 157 |
+
|
| 158 |
+
tempfilename = make_command_file(path_to_debug_info,
|
| 159 |
+
no_import=no_import,
|
| 160 |
+
skip_interpreter=skip_interpreter)
|
| 161 |
+
logger.info("Launching %s with command file: %s and gdb_argv: %s",
|
| 162 |
+
options.gdb, tempfilename, gdb_argv)
|
| 163 |
+
with open(tempfilename) as tempfile:
|
| 164 |
+
logger.debug('Command file (%s) contains: """\n%s"""', tempfilename, tempfile.read())
|
| 165 |
+
logger.info("Spawning %s...", options.gdb)
|
| 166 |
+
p = subprocess.Popen([options.gdb, '-command', tempfilename] + gdb_argv)
|
| 167 |
+
logger.info("Spawned %s (pid %d)", options.gdb, p.pid)
|
| 168 |
+
while True:
|
| 169 |
+
try:
|
| 170 |
+
logger.debug("Waiting for gdb (pid %d) to exit...", p.pid)
|
| 171 |
+
ret = p.wait()
|
| 172 |
+
logger.debug("Wait for gdb (pid %d) to exit is done. Returned: %r", p.pid, ret)
|
| 173 |
+
except KeyboardInterrupt:
|
| 174 |
+
pass
|
| 175 |
+
else:
|
| 176 |
+
break
|
| 177 |
+
logger.debug("Closing temp command file with fd: %s", tempfile.fileno())
|
| 178 |
+
logger.debug("Removing temp command file: %s", tempfilename)
|
| 179 |
+
os.remove(tempfilename)
|
| 180 |
+
logger.debug("Removed temp command file: %s", tempfilename)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/DebugWriter.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import absolute_import
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
import sys
|
| 5 |
+
import errno
|
| 6 |
+
|
| 7 |
+
try:
|
| 8 |
+
from lxml import etree
|
| 9 |
+
have_lxml = True
|
| 10 |
+
except ImportError:
|
| 11 |
+
have_lxml = False
|
| 12 |
+
try:
|
| 13 |
+
from xml.etree import cElementTree as etree
|
| 14 |
+
except ImportError:
|
| 15 |
+
try:
|
| 16 |
+
from xml.etree import ElementTree as etree
|
| 17 |
+
except ImportError:
|
| 18 |
+
etree = None
|
| 19 |
+
|
| 20 |
+
from ..Compiler import Errors
|
| 21 |
+
from ..Compiler.StringEncoding import EncodedString
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def is_valid_tag(name):
|
| 25 |
+
"""
|
| 26 |
+
Names like '.0' are used internally for arguments
|
| 27 |
+
to functions creating generator expressions,
|
| 28 |
+
however they are not identifiers.
|
| 29 |
+
|
| 30 |
+
See https://github.com/cython/cython/issues/5552
|
| 31 |
+
"""
|
| 32 |
+
if isinstance(name, EncodedString):
|
| 33 |
+
if name.startswith(".") and name[1:].isdecimal():
|
| 34 |
+
return False
|
| 35 |
+
return True
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class CythonDebugWriter(object):
|
| 39 |
+
"""
|
| 40 |
+
Class to output debugging information for cygdb
|
| 41 |
+
|
| 42 |
+
It writes debug information to cython_debug/cython_debug_info_<modulename>
|
| 43 |
+
in the build directory.
|
| 44 |
+
"""
|
| 45 |
+
|
| 46 |
+
def __init__(self, output_dir):
|
| 47 |
+
if etree is None:
|
| 48 |
+
raise Errors.NoElementTreeInstalledException()
|
| 49 |
+
|
| 50 |
+
self.output_dir = os.path.join(output_dir or os.curdir, 'cython_debug')
|
| 51 |
+
self.tb = etree.TreeBuilder()
|
| 52 |
+
# set by Cython.Compiler.ParseTreeTransforms.DebugTransform
|
| 53 |
+
self.module_name = None
|
| 54 |
+
self.start('cython_debug', attrs=dict(version='1.0'))
|
| 55 |
+
|
| 56 |
+
def start(self, name, attrs=None):
|
| 57 |
+
if is_valid_tag(name):
|
| 58 |
+
self.tb.start(name, attrs or {})
|
| 59 |
+
|
| 60 |
+
def end(self, name):
|
| 61 |
+
if is_valid_tag(name):
|
| 62 |
+
self.tb.end(name)
|
| 63 |
+
|
| 64 |
+
def add_entry(self, name, **attrs):
|
| 65 |
+
if is_valid_tag(name):
|
| 66 |
+
self.tb.start(name, attrs)
|
| 67 |
+
self.tb.end(name)
|
| 68 |
+
|
| 69 |
+
def serialize(self):
|
| 70 |
+
self.tb.end('Module')
|
| 71 |
+
self.tb.end('cython_debug')
|
| 72 |
+
xml_root_element = self.tb.close()
|
| 73 |
+
|
| 74 |
+
try:
|
| 75 |
+
os.makedirs(self.output_dir)
|
| 76 |
+
except OSError as e:
|
| 77 |
+
if e.errno != errno.EEXIST:
|
| 78 |
+
raise
|
| 79 |
+
|
| 80 |
+
et = etree.ElementTree(xml_root_element)
|
| 81 |
+
kw = {}
|
| 82 |
+
if have_lxml:
|
| 83 |
+
kw['pretty_print'] = True
|
| 84 |
+
|
| 85 |
+
fn = "cython_debug_info_" + self.module_name
|
| 86 |
+
et.write(os.path.join(self.output_dir, fn), encoding="UTF-8", **kw)
|
| 87 |
+
|
| 88 |
+
interpreter_path = os.path.join(self.output_dir, 'interpreter')
|
| 89 |
+
with open(interpreter_path, 'w') as f:
|
| 90 |
+
f.write(sys.executable)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Tests/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (222 Bytes). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Tests/__pycache__/test_libpython_in_gdb.cpython-311.pyc
ADDED
|
Binary file (7.46 kB). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/Tests/cfuncs.c
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
void
|
| 2 |
+
some_c_function(void)
|
| 3 |
+
{
|
| 4 |
+
int a, b, c;
|
| 5 |
+
|
| 6 |
+
a = 1;
|
| 7 |
+
b = 2;
|
| 8 |
+
}
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# empty file
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/__pycache__/DebugWriter.cpython-311.pyc
ADDED
|
Binary file (5.24 kB). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/__pycache__/libcython.cpython-311.pyc
ADDED
|
Binary file (73.4 kB). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/libcython.py
ADDED
|
@@ -0,0 +1,1461 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
GDB extension that adds Cython support.
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
from __future__ import print_function
|
| 6 |
+
|
| 7 |
+
try:
|
| 8 |
+
input = raw_input
|
| 9 |
+
except NameError:
|
| 10 |
+
pass
|
| 11 |
+
|
| 12 |
+
import sys
|
| 13 |
+
import textwrap
|
| 14 |
+
import functools
|
| 15 |
+
import itertools
|
| 16 |
+
import collections
|
| 17 |
+
|
| 18 |
+
import gdb
|
| 19 |
+
|
| 20 |
+
try: # python 2
|
| 21 |
+
UNICODE = unicode
|
| 22 |
+
BYTES = str
|
| 23 |
+
except NameError: # python 3
|
| 24 |
+
UNICODE = str
|
| 25 |
+
BYTES = bytes
|
| 26 |
+
|
| 27 |
+
try:
|
| 28 |
+
from lxml import etree
|
| 29 |
+
have_lxml = True
|
| 30 |
+
except ImportError:
|
| 31 |
+
have_lxml = False
|
| 32 |
+
try:
|
| 33 |
+
# Python 2.5
|
| 34 |
+
from xml.etree import cElementTree as etree
|
| 35 |
+
except ImportError:
|
| 36 |
+
try:
|
| 37 |
+
# Python 2.5
|
| 38 |
+
from xml.etree import ElementTree as etree
|
| 39 |
+
except ImportError:
|
| 40 |
+
try:
|
| 41 |
+
# normal cElementTree install
|
| 42 |
+
import cElementTree as etree
|
| 43 |
+
except ImportError:
|
| 44 |
+
# normal ElementTree install
|
| 45 |
+
import elementtree.ElementTree as etree
|
| 46 |
+
|
| 47 |
+
try:
|
| 48 |
+
import pygments.lexers
|
| 49 |
+
import pygments.formatters
|
| 50 |
+
except ImportError:
|
| 51 |
+
pygments = None
|
| 52 |
+
sys.stderr.write("Install pygments for colorized source code.\n")
|
| 53 |
+
|
| 54 |
+
if hasattr(gdb, 'string_to_argv'):
|
| 55 |
+
from gdb import string_to_argv
|
| 56 |
+
else:
|
| 57 |
+
from shlex import split as string_to_argv
|
| 58 |
+
|
| 59 |
+
from Cython.Debugger import libpython
|
| 60 |
+
|
| 61 |
+
# C or Python type
|
| 62 |
+
CObject = 'CObject'
|
| 63 |
+
PythonObject = 'PythonObject'
|
| 64 |
+
|
| 65 |
+
_data_types = dict(CObject=CObject, PythonObject=PythonObject)
|
| 66 |
+
_filesystemencoding = sys.getfilesystemencoding() or 'UTF-8'
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
# decorators
|
| 70 |
+
|
| 71 |
+
def default_selected_gdb_frame(err=True):
|
| 72 |
+
def decorator(function):
|
| 73 |
+
@functools.wraps(function)
|
| 74 |
+
def wrapper(self, frame=None, *args, **kwargs):
|
| 75 |
+
try:
|
| 76 |
+
frame = frame or gdb.selected_frame()
|
| 77 |
+
except RuntimeError:
|
| 78 |
+
raise gdb.GdbError("No frame is currently selected.")
|
| 79 |
+
|
| 80 |
+
if err and frame.name() is None:
|
| 81 |
+
raise NoFunctionNameInFrameError()
|
| 82 |
+
|
| 83 |
+
return function(self, frame, *args, **kwargs)
|
| 84 |
+
return wrapper
|
| 85 |
+
return decorator
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def require_cython_frame(function):
|
| 89 |
+
@functools.wraps(function)
|
| 90 |
+
@require_running_program
|
| 91 |
+
def wrapper(self, *args, **kwargs):
|
| 92 |
+
frame = kwargs.get('frame') or gdb.selected_frame()
|
| 93 |
+
if not self.is_cython_function(frame):
|
| 94 |
+
raise gdb.GdbError('Selected frame does not correspond with a '
|
| 95 |
+
'Cython function we know about.')
|
| 96 |
+
return function(self, *args, **kwargs)
|
| 97 |
+
return wrapper
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def dispatch_on_frame(c_command, python_command=None):
|
| 101 |
+
def decorator(function):
|
| 102 |
+
@functools.wraps(function)
|
| 103 |
+
def wrapper(self, *args, **kwargs):
|
| 104 |
+
is_cy = self.is_cython_function()
|
| 105 |
+
is_py = self.is_python_function()
|
| 106 |
+
|
| 107 |
+
if is_cy or (is_py and not python_command):
|
| 108 |
+
function(self, *args, **kwargs)
|
| 109 |
+
elif is_py:
|
| 110 |
+
gdb.execute(python_command)
|
| 111 |
+
elif self.is_relevant_function():
|
| 112 |
+
gdb.execute(c_command)
|
| 113 |
+
else:
|
| 114 |
+
raise gdb.GdbError("Not a function cygdb knows about. "
|
| 115 |
+
"Use the normal GDB commands instead.")
|
| 116 |
+
|
| 117 |
+
return wrapper
|
| 118 |
+
return decorator
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def require_running_program(function):
|
| 122 |
+
@functools.wraps(function)
|
| 123 |
+
def wrapper(*args, **kwargs):
|
| 124 |
+
try:
|
| 125 |
+
gdb.selected_frame()
|
| 126 |
+
except RuntimeError:
|
| 127 |
+
raise gdb.GdbError("No frame is currently selected.")
|
| 128 |
+
|
| 129 |
+
return function(*args, **kwargs)
|
| 130 |
+
return wrapper
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
def gdb_function_value_to_unicode(function):
|
| 134 |
+
@functools.wraps(function)
|
| 135 |
+
def wrapper(self, string, *args, **kwargs):
|
| 136 |
+
if isinstance(string, gdb.Value):
|
| 137 |
+
string = string.string()
|
| 138 |
+
|
| 139 |
+
return function(self, string, *args, **kwargs)
|
| 140 |
+
return wrapper
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
# Classes that represent the debug information
|
| 144 |
+
# Don't rename the parameters of these classes, they come directly from the XML
|
| 145 |
+
|
| 146 |
+
class CythonModule(object):
|
| 147 |
+
def __init__(self, module_name, filename, c_filename):
|
| 148 |
+
self.name = module_name
|
| 149 |
+
self.filename = filename
|
| 150 |
+
self.c_filename = c_filename
|
| 151 |
+
self.globals = {}
|
| 152 |
+
# {cython_lineno: min(c_linenos)}
|
| 153 |
+
self.lineno_cy2c = {}
|
| 154 |
+
# {c_lineno: cython_lineno}
|
| 155 |
+
self.lineno_c2cy = {}
|
| 156 |
+
self.functions = {}
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
class CythonVariable(object):
|
| 160 |
+
|
| 161 |
+
def __init__(self, name, cname, qualified_name, type, lineno):
|
| 162 |
+
self.name = name
|
| 163 |
+
self.cname = cname
|
| 164 |
+
self.qualified_name = qualified_name
|
| 165 |
+
self.type = type
|
| 166 |
+
self.lineno = int(lineno)
|
| 167 |
+
|
| 168 |
+
|
| 169 |
+
class CythonFunction(CythonVariable):
|
| 170 |
+
def __init__(self,
|
| 171 |
+
module,
|
| 172 |
+
name,
|
| 173 |
+
cname,
|
| 174 |
+
pf_cname,
|
| 175 |
+
qualified_name,
|
| 176 |
+
lineno,
|
| 177 |
+
type=CObject,
|
| 178 |
+
is_initmodule_function="False"):
|
| 179 |
+
super(CythonFunction, self).__init__(name,
|
| 180 |
+
cname,
|
| 181 |
+
qualified_name,
|
| 182 |
+
type,
|
| 183 |
+
lineno)
|
| 184 |
+
self.module = module
|
| 185 |
+
self.pf_cname = pf_cname
|
| 186 |
+
self.is_initmodule_function = is_initmodule_function == "True"
|
| 187 |
+
self.locals = {}
|
| 188 |
+
self.arguments = []
|
| 189 |
+
self.step_into_functions = set()
|
| 190 |
+
|
| 191 |
+
|
| 192 |
+
# General purpose classes
|
| 193 |
+
|
| 194 |
+
class CythonBase(object):
|
| 195 |
+
|
| 196 |
+
@default_selected_gdb_frame(err=False)
|
| 197 |
+
def is_cython_function(self, frame):
|
| 198 |
+
return frame.name() in self.cy.functions_by_cname
|
| 199 |
+
|
| 200 |
+
@default_selected_gdb_frame(err=False)
|
| 201 |
+
def is_python_function(self, frame):
|
| 202 |
+
"""
|
| 203 |
+
Tells if a frame is associated with a Python function.
|
| 204 |
+
If we can't read the Python frame information, don't regard it as such.
|
| 205 |
+
"""
|
| 206 |
+
if frame.name() == 'PyEval_EvalFrameEx':
|
| 207 |
+
pyframe = libpython.Frame(frame).get_pyop()
|
| 208 |
+
return pyframe and not pyframe.is_optimized_out()
|
| 209 |
+
return False
|
| 210 |
+
|
| 211 |
+
@default_selected_gdb_frame()
|
| 212 |
+
def get_c_function_name(self, frame):
|
| 213 |
+
return frame.name()
|
| 214 |
+
|
| 215 |
+
@default_selected_gdb_frame()
|
| 216 |
+
def get_c_lineno(self, frame):
|
| 217 |
+
return frame.find_sal().line
|
| 218 |
+
|
| 219 |
+
@default_selected_gdb_frame()
|
| 220 |
+
def get_cython_function(self, frame):
|
| 221 |
+
result = self.cy.functions_by_cname.get(frame.name())
|
| 222 |
+
if result is None:
|
| 223 |
+
raise NoCythonFunctionInFrameError()
|
| 224 |
+
|
| 225 |
+
return result
|
| 226 |
+
|
| 227 |
+
@default_selected_gdb_frame()
|
| 228 |
+
def get_cython_lineno(self, frame):
|
| 229 |
+
"""
|
| 230 |
+
Get the current Cython line number. Returns 0 if there is no
|
| 231 |
+
correspondence between the C and Cython code.
|
| 232 |
+
"""
|
| 233 |
+
cyfunc = self.get_cython_function(frame)
|
| 234 |
+
return cyfunc.module.lineno_c2cy.get(self.get_c_lineno(frame), 0)
|
| 235 |
+
|
| 236 |
+
@default_selected_gdb_frame()
|
| 237 |
+
def get_source_desc(self, frame):
|
| 238 |
+
filename = lineno = lexer = None
|
| 239 |
+
if self.is_cython_function(frame):
|
| 240 |
+
filename = self.get_cython_function(frame).module.filename
|
| 241 |
+
filename_and_lineno = self.get_cython_lineno(frame)
|
| 242 |
+
assert filename == filename_and_lineno[0]
|
| 243 |
+
lineno = filename_and_lineno[1]
|
| 244 |
+
if pygments:
|
| 245 |
+
lexer = pygments.lexers.CythonLexer(stripall=False)
|
| 246 |
+
elif self.is_python_function(frame):
|
| 247 |
+
pyframeobject = libpython.Frame(frame).get_pyop()
|
| 248 |
+
|
| 249 |
+
if not pyframeobject:
|
| 250 |
+
raise gdb.GdbError(
|
| 251 |
+
'Unable to read information on python frame')
|
| 252 |
+
|
| 253 |
+
filename = pyframeobject.filename()
|
| 254 |
+
lineno = pyframeobject.current_line_num()
|
| 255 |
+
|
| 256 |
+
if pygments:
|
| 257 |
+
lexer = pygments.lexers.PythonLexer(stripall=False)
|
| 258 |
+
else:
|
| 259 |
+
symbol_and_line_obj = frame.find_sal()
|
| 260 |
+
if not symbol_and_line_obj or not symbol_and_line_obj.symtab:
|
| 261 |
+
filename = None
|
| 262 |
+
lineno = 0
|
| 263 |
+
else:
|
| 264 |
+
filename = symbol_and_line_obj.symtab.fullname()
|
| 265 |
+
lineno = symbol_and_line_obj.line
|
| 266 |
+
if pygments:
|
| 267 |
+
lexer = pygments.lexers.CLexer(stripall=False)
|
| 268 |
+
|
| 269 |
+
return SourceFileDescriptor(filename, lexer), lineno
|
| 270 |
+
|
| 271 |
+
@default_selected_gdb_frame()
|
| 272 |
+
def get_source_line(self, frame):
|
| 273 |
+
source_desc, lineno = self.get_source_desc()
|
| 274 |
+
return source_desc.get_source(lineno)
|
| 275 |
+
|
| 276 |
+
@default_selected_gdb_frame()
|
| 277 |
+
def is_relevant_function(self, frame):
|
| 278 |
+
"""
|
| 279 |
+
returns whether we care about a frame on the user-level when debugging
|
| 280 |
+
Cython code
|
| 281 |
+
"""
|
| 282 |
+
name = frame.name()
|
| 283 |
+
older_frame = frame.older()
|
| 284 |
+
if self.is_cython_function(frame) or self.is_python_function(frame):
|
| 285 |
+
return True
|
| 286 |
+
elif older_frame and self.is_cython_function(older_frame):
|
| 287 |
+
# check for direct C function call from a Cython function
|
| 288 |
+
cython_func = self.get_cython_function(older_frame)
|
| 289 |
+
return name in cython_func.step_into_functions
|
| 290 |
+
|
| 291 |
+
return False
|
| 292 |
+
|
| 293 |
+
@default_selected_gdb_frame(err=False)
|
| 294 |
+
def print_stackframe(self, frame, index, is_c=False):
|
| 295 |
+
"""
|
| 296 |
+
Print a C, Cython or Python stack frame and the line of source code
|
| 297 |
+
if available.
|
| 298 |
+
"""
|
| 299 |
+
# do this to prevent the require_cython_frame decorator from
|
| 300 |
+
# raising GdbError when calling self.cy.cy_cvalue.invoke()
|
| 301 |
+
selected_frame = gdb.selected_frame()
|
| 302 |
+
frame.select()
|
| 303 |
+
|
| 304 |
+
try:
|
| 305 |
+
source_desc, lineno = self.get_source_desc(frame)
|
| 306 |
+
except NoFunctionNameInFrameError:
|
| 307 |
+
print('#%-2d Unknown Frame (compile with -g)' % index)
|
| 308 |
+
return
|
| 309 |
+
|
| 310 |
+
if not is_c and self.is_python_function(frame):
|
| 311 |
+
pyframe = libpython.Frame(frame).get_pyop()
|
| 312 |
+
if pyframe is None or pyframe.is_optimized_out():
|
| 313 |
+
# print this python function as a C function
|
| 314 |
+
return self.print_stackframe(frame, index, is_c=True)
|
| 315 |
+
|
| 316 |
+
func_name = pyframe.co_name
|
| 317 |
+
func_cname = 'PyEval_EvalFrameEx'
|
| 318 |
+
func_args = []
|
| 319 |
+
elif self.is_cython_function(frame):
|
| 320 |
+
cyfunc = self.get_cython_function(frame)
|
| 321 |
+
f = lambda arg: self.cy.cy_cvalue.invoke(arg, frame=frame)
|
| 322 |
+
|
| 323 |
+
func_name = cyfunc.name
|
| 324 |
+
func_cname = cyfunc.cname
|
| 325 |
+
func_args = [] # [(arg, f(arg)) for arg in cyfunc.arguments]
|
| 326 |
+
else:
|
| 327 |
+
source_desc, lineno = self.get_source_desc(frame)
|
| 328 |
+
func_name = frame.name()
|
| 329 |
+
func_cname = func_name
|
| 330 |
+
func_args = []
|
| 331 |
+
|
| 332 |
+
try:
|
| 333 |
+
gdb_value = gdb.parse_and_eval(func_cname)
|
| 334 |
+
except RuntimeError:
|
| 335 |
+
func_address = 0
|
| 336 |
+
else:
|
| 337 |
+
func_address = gdb_value.address
|
| 338 |
+
if not isinstance(func_address, int):
|
| 339 |
+
# Seriously? Why is the address not an int?
|
| 340 |
+
if not isinstance(func_address, (str, bytes)):
|
| 341 |
+
func_address = str(func_address)
|
| 342 |
+
func_address = int(func_address.split()[0], 0)
|
| 343 |
+
|
| 344 |
+
a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
|
| 345 |
+
sys.stdout.write('#%-2d 0x%016x in %s(%s)' % (index, func_address, func_name, a))
|
| 346 |
+
|
| 347 |
+
if source_desc.filename is not None:
|
| 348 |
+
sys.stdout.write(' at %s:%s' % (source_desc.filename, lineno))
|
| 349 |
+
|
| 350 |
+
sys.stdout.write('\n')
|
| 351 |
+
|
| 352 |
+
try:
|
| 353 |
+
sys.stdout.write(' ' + source_desc.get_source(lineno))
|
| 354 |
+
except gdb.GdbError:
|
| 355 |
+
pass
|
| 356 |
+
|
| 357 |
+
selected_frame.select()
|
| 358 |
+
|
| 359 |
+
def get_remote_cython_globals_dict(self):
|
| 360 |
+
m = gdb.parse_and_eval('__pyx_m')
|
| 361 |
+
|
| 362 |
+
try:
|
| 363 |
+
PyModuleObject = gdb.lookup_type('PyModuleObject')
|
| 364 |
+
except RuntimeError:
|
| 365 |
+
raise gdb.GdbError(textwrap.dedent("""\
|
| 366 |
+
Unable to lookup type PyModuleObject, did you compile python
|
| 367 |
+
with debugging support (-g)?"""))
|
| 368 |
+
|
| 369 |
+
m = m.cast(PyModuleObject.pointer())
|
| 370 |
+
return m['md_dict']
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
def get_cython_globals_dict(self):
|
| 374 |
+
"""
|
| 375 |
+
Get the Cython globals dict where the remote names are turned into
|
| 376 |
+
local strings.
|
| 377 |
+
"""
|
| 378 |
+
remote_dict = self.get_remote_cython_globals_dict()
|
| 379 |
+
pyobject_dict = libpython.PyObjectPtr.from_pyobject_ptr(remote_dict)
|
| 380 |
+
|
| 381 |
+
result = {}
|
| 382 |
+
seen = set()
|
| 383 |
+
for k, v in pyobject_dict.iteritems():
|
| 384 |
+
result[k.proxyval(seen)] = v
|
| 385 |
+
|
| 386 |
+
return result
|
| 387 |
+
|
| 388 |
+
def print_gdb_value(self, name, value, max_name_length=None, prefix=''):
|
| 389 |
+
if libpython.pretty_printer_lookup(value):
|
| 390 |
+
typename = ''
|
| 391 |
+
else:
|
| 392 |
+
typename = '(%s) ' % (value.type,)
|
| 393 |
+
|
| 394 |
+
if max_name_length is None:
|
| 395 |
+
print('%s%s = %s%s' % (prefix, name, typename, value))
|
| 396 |
+
else:
|
| 397 |
+
print('%s%-*s = %s%s' % (prefix, max_name_length, name, typename, value))
|
| 398 |
+
|
| 399 |
+
def is_initialized(self, cython_func, local_name):
|
| 400 |
+
cyvar = cython_func.locals[local_name]
|
| 401 |
+
cur_lineno = self.get_cython_lineno()[1]
|
| 402 |
+
|
| 403 |
+
if '->' in cyvar.cname:
|
| 404 |
+
# Closed over free variable
|
| 405 |
+
if cur_lineno > cython_func.lineno:
|
| 406 |
+
if cyvar.type == PythonObject:
|
| 407 |
+
return int(gdb.parse_and_eval(cyvar.cname))
|
| 408 |
+
return True
|
| 409 |
+
return False
|
| 410 |
+
|
| 411 |
+
return cur_lineno > cyvar.lineno
|
| 412 |
+
|
| 413 |
+
|
| 414 |
+
class SourceFileDescriptor(object):
|
| 415 |
+
def __init__(self, filename, lexer, formatter=None):
|
| 416 |
+
self.filename = filename
|
| 417 |
+
self.lexer = lexer
|
| 418 |
+
self.formatter = formatter
|
| 419 |
+
|
| 420 |
+
def valid(self):
|
| 421 |
+
return self.filename is not None
|
| 422 |
+
|
| 423 |
+
def lex(self, code):
|
| 424 |
+
if pygments and self.lexer and parameters.colorize_code:
|
| 425 |
+
bg = parameters.terminal_background.value
|
| 426 |
+
if self.formatter is None:
|
| 427 |
+
formatter = pygments.formatters.TerminalFormatter(bg=bg)
|
| 428 |
+
else:
|
| 429 |
+
formatter = self.formatter
|
| 430 |
+
|
| 431 |
+
return pygments.highlight(code, self.lexer, formatter)
|
| 432 |
+
|
| 433 |
+
return code
|
| 434 |
+
|
| 435 |
+
def _get_source(self, start, stop, lex_source, mark_line, lex_entire):
|
| 436 |
+
with open(self.filename) as f:
|
| 437 |
+
# to provide "correct" colouring, the entire code needs to be
|
| 438 |
+
# lexed. However, this makes a lot of things terribly slow, so
|
| 439 |
+
# we decide not to. Besides, it's unlikely to matter.
|
| 440 |
+
|
| 441 |
+
if lex_source and lex_entire:
|
| 442 |
+
f = self.lex(f.read()).splitlines()
|
| 443 |
+
|
| 444 |
+
slice = itertools.islice(f, start - 1, stop - 1)
|
| 445 |
+
|
| 446 |
+
for idx, line in enumerate(slice):
|
| 447 |
+
if start + idx == mark_line:
|
| 448 |
+
prefix = '>'
|
| 449 |
+
else:
|
| 450 |
+
prefix = ' '
|
| 451 |
+
|
| 452 |
+
if lex_source and not lex_entire:
|
| 453 |
+
line = self.lex(line)
|
| 454 |
+
|
| 455 |
+
yield '%s %4d %s' % (prefix, start + idx, line.rstrip())
|
| 456 |
+
|
| 457 |
+
def get_source(self, start, stop=None, lex_source=True, mark_line=0,
|
| 458 |
+
lex_entire=False):
|
| 459 |
+
exc = gdb.GdbError('Unable to retrieve source code')
|
| 460 |
+
|
| 461 |
+
if not self.filename:
|
| 462 |
+
raise exc
|
| 463 |
+
|
| 464 |
+
start = max(start, 1)
|
| 465 |
+
if stop is None:
|
| 466 |
+
stop = start + 1
|
| 467 |
+
|
| 468 |
+
try:
|
| 469 |
+
return '\n'.join(
|
| 470 |
+
self._get_source(start, stop, lex_source, mark_line, lex_entire))
|
| 471 |
+
except IOError:
|
| 472 |
+
raise exc
|
| 473 |
+
|
| 474 |
+
|
| 475 |
+
# Errors
|
| 476 |
+
|
| 477 |
+
class CyGDBError(gdb.GdbError):
|
| 478 |
+
"""
|
| 479 |
+
Base class for Cython-command related errors
|
| 480 |
+
"""
|
| 481 |
+
|
| 482 |
+
def __init__(self, *args):
|
| 483 |
+
args = args or (self.msg,)
|
| 484 |
+
super(CyGDBError, self).__init__(*args)
|
| 485 |
+
|
| 486 |
+
|
| 487 |
+
class NoCythonFunctionInFrameError(CyGDBError):
|
| 488 |
+
"""
|
| 489 |
+
raised when the user requests the current cython function, which is
|
| 490 |
+
unavailable
|
| 491 |
+
"""
|
| 492 |
+
msg = "Current function is a function cygdb doesn't know about"
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
class NoFunctionNameInFrameError(NoCythonFunctionInFrameError):
|
| 496 |
+
"""
|
| 497 |
+
raised when the name of the C function could not be determined
|
| 498 |
+
in the current C stack frame
|
| 499 |
+
"""
|
| 500 |
+
msg = ('C function name could not be determined in the current C stack '
|
| 501 |
+
'frame')
|
| 502 |
+
|
| 503 |
+
|
| 504 |
+
# Parameters
|
| 505 |
+
|
| 506 |
+
class CythonParameter(gdb.Parameter):
|
| 507 |
+
"""
|
| 508 |
+
Base class for cython parameters
|
| 509 |
+
"""
|
| 510 |
+
|
| 511 |
+
def __init__(self, name, command_class, parameter_class, default=None):
|
| 512 |
+
self.show_doc = self.set_doc = self.__class__.__doc__
|
| 513 |
+
super(CythonParameter, self).__init__(name, command_class,
|
| 514 |
+
parameter_class)
|
| 515 |
+
if default is not None:
|
| 516 |
+
self.value = default
|
| 517 |
+
|
| 518 |
+
def __bool__(self):
|
| 519 |
+
return bool(self.value)
|
| 520 |
+
|
| 521 |
+
__nonzero__ = __bool__ # Python 2
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
|
| 525 |
+
class CompleteUnqualifiedFunctionNames(CythonParameter):
|
| 526 |
+
"""
|
| 527 |
+
Have 'cy break' complete unqualified function or method names.
|
| 528 |
+
"""
|
| 529 |
+
|
| 530 |
+
|
| 531 |
+
class ColorizeSourceCode(CythonParameter):
|
| 532 |
+
"""
|
| 533 |
+
Tell cygdb whether to colorize source code.
|
| 534 |
+
"""
|
| 535 |
+
|
| 536 |
+
|
| 537 |
+
class TerminalBackground(CythonParameter):
|
| 538 |
+
"""
|
| 539 |
+
Tell cygdb about the user's terminal background (light or dark).
|
| 540 |
+
"""
|
| 541 |
+
|
| 542 |
+
|
| 543 |
+
class CythonParameters(object):
|
| 544 |
+
"""
|
| 545 |
+
Simple container class that might get more functionality in the distant
|
| 546 |
+
future (mostly to remind us that we're dealing with parameters).
|
| 547 |
+
"""
|
| 548 |
+
|
| 549 |
+
def __init__(self):
|
| 550 |
+
self.complete_unqualified = CompleteUnqualifiedFunctionNames(
|
| 551 |
+
'cy_complete_unqualified',
|
| 552 |
+
gdb.COMMAND_BREAKPOINTS,
|
| 553 |
+
gdb.PARAM_BOOLEAN,
|
| 554 |
+
True)
|
| 555 |
+
self.colorize_code = ColorizeSourceCode(
|
| 556 |
+
'cy_colorize_code',
|
| 557 |
+
gdb.COMMAND_FILES,
|
| 558 |
+
gdb.PARAM_BOOLEAN,
|
| 559 |
+
True)
|
| 560 |
+
self.terminal_background = TerminalBackground(
|
| 561 |
+
'cy_terminal_background_color',
|
| 562 |
+
gdb.COMMAND_FILES,
|
| 563 |
+
gdb.PARAM_STRING,
|
| 564 |
+
"dark")
|
| 565 |
+
|
| 566 |
+
parameters = CythonParameters()
|
| 567 |
+
|
| 568 |
+
|
| 569 |
+
# Commands
|
| 570 |
+
|
| 571 |
+
class CythonCommand(gdb.Command, CythonBase):
|
| 572 |
+
"""
|
| 573 |
+
Base class for Cython commands
|
| 574 |
+
"""
|
| 575 |
+
|
| 576 |
+
command_class = gdb.COMMAND_NONE
|
| 577 |
+
|
| 578 |
+
@classmethod
|
| 579 |
+
def _register(cls, clsname, args, kwargs):
|
| 580 |
+
if not hasattr(cls, 'completer_class'):
|
| 581 |
+
return cls(clsname, cls.command_class, *args, **kwargs)
|
| 582 |
+
else:
|
| 583 |
+
return cls(clsname, cls.command_class, cls.completer_class,
|
| 584 |
+
*args, **kwargs)
|
| 585 |
+
|
| 586 |
+
@classmethod
|
| 587 |
+
def register(cls, *args, **kwargs):
|
| 588 |
+
alias = getattr(cls, 'alias', None)
|
| 589 |
+
if alias:
|
| 590 |
+
cls._register(cls.alias, args, kwargs)
|
| 591 |
+
|
| 592 |
+
return cls._register(cls.name, args, kwargs)
|
| 593 |
+
|
| 594 |
+
|
| 595 |
+
class CyCy(CythonCommand):
|
| 596 |
+
"""
|
| 597 |
+
Invoke a Cython command. Available commands are:
|
| 598 |
+
|
| 599 |
+
cy import
|
| 600 |
+
cy break
|
| 601 |
+
cy step
|
| 602 |
+
cy next
|
| 603 |
+
cy run
|
| 604 |
+
cy cont
|
| 605 |
+
cy finish
|
| 606 |
+
cy up
|
| 607 |
+
cy down
|
| 608 |
+
cy select
|
| 609 |
+
cy bt / cy backtrace
|
| 610 |
+
cy list
|
| 611 |
+
cy print
|
| 612 |
+
cy set
|
| 613 |
+
cy locals
|
| 614 |
+
cy globals
|
| 615 |
+
cy exec
|
| 616 |
+
"""
|
| 617 |
+
|
| 618 |
+
name = 'cy'
|
| 619 |
+
command_class = gdb.COMMAND_NONE
|
| 620 |
+
completer_class = gdb.COMPLETE_COMMAND
|
| 621 |
+
|
| 622 |
+
def __init__(self, name, command_class, completer_class):
|
| 623 |
+
# keep the signature 2.5 compatible (i.e. do not use f(*a, k=v)
|
| 624 |
+
super(CythonCommand, self).__init__(name, command_class,
|
| 625 |
+
completer_class, prefix=True)
|
| 626 |
+
|
| 627 |
+
commands = dict(
|
| 628 |
+
# GDB commands
|
| 629 |
+
import_ = CyImport.register(),
|
| 630 |
+
break_ = CyBreak.register(),
|
| 631 |
+
step = CyStep.register(),
|
| 632 |
+
next = CyNext.register(),
|
| 633 |
+
run = CyRun.register(),
|
| 634 |
+
cont = CyCont.register(),
|
| 635 |
+
finish = CyFinish.register(),
|
| 636 |
+
up = CyUp.register(),
|
| 637 |
+
down = CyDown.register(),
|
| 638 |
+
select = CySelect.register(),
|
| 639 |
+
bt = CyBacktrace.register(),
|
| 640 |
+
list = CyList.register(),
|
| 641 |
+
print_ = CyPrint.register(),
|
| 642 |
+
locals = CyLocals.register(),
|
| 643 |
+
globals = CyGlobals.register(),
|
| 644 |
+
exec_ = libpython.FixGdbCommand('cy exec', '-cy-exec'),
|
| 645 |
+
_exec = CyExec.register(),
|
| 646 |
+
set = CySet.register(),
|
| 647 |
+
|
| 648 |
+
# GDB functions
|
| 649 |
+
cy_cname = CyCName('cy_cname'),
|
| 650 |
+
cy_cvalue = CyCValue('cy_cvalue'),
|
| 651 |
+
cy_lineno = CyLine('cy_lineno'),
|
| 652 |
+
cy_eval = CyEval('cy_eval'),
|
| 653 |
+
)
|
| 654 |
+
|
| 655 |
+
for command_name, command in commands.items():
|
| 656 |
+
command.cy = self
|
| 657 |
+
setattr(self, command_name, command)
|
| 658 |
+
|
| 659 |
+
self.cy = self
|
| 660 |
+
|
| 661 |
+
# Cython module namespace
|
| 662 |
+
self.cython_namespace = {}
|
| 663 |
+
|
| 664 |
+
# maps (unique) qualified function names (e.g.
|
| 665 |
+
# cythonmodule.ClassName.method_name) to the CythonFunction object
|
| 666 |
+
self.functions_by_qualified_name = {}
|
| 667 |
+
|
| 668 |
+
# unique cnames of Cython functions
|
| 669 |
+
self.functions_by_cname = {}
|
| 670 |
+
|
| 671 |
+
# map function names like method_name to a list of all such
|
| 672 |
+
# CythonFunction objects
|
| 673 |
+
self.functions_by_name = collections.defaultdict(list)
|
| 674 |
+
|
| 675 |
+
|
| 676 |
+
class CyImport(CythonCommand):
|
| 677 |
+
"""
|
| 678 |
+
Import debug information outputted by the Cython compiler
|
| 679 |
+
Example: cy import FILE...
|
| 680 |
+
"""
|
| 681 |
+
|
| 682 |
+
name = 'cy import'
|
| 683 |
+
command_class = gdb.COMMAND_STATUS
|
| 684 |
+
completer_class = gdb.COMPLETE_FILENAME
|
| 685 |
+
|
| 686 |
+
@libpython.dont_suppress_errors
|
| 687 |
+
def invoke(self, args, from_tty):
|
| 688 |
+
if isinstance(args, BYTES):
|
| 689 |
+
args = args.decode(_filesystemencoding)
|
| 690 |
+
for arg in string_to_argv(args):
|
| 691 |
+
try:
|
| 692 |
+
f = open(arg)
|
| 693 |
+
except OSError as e:
|
| 694 |
+
raise gdb.GdbError('Unable to open file %r: %s' % (args, e.args[1]))
|
| 695 |
+
|
| 696 |
+
t = etree.parse(f)
|
| 697 |
+
|
| 698 |
+
for module in t.getroot():
|
| 699 |
+
cython_module = CythonModule(**module.attrib)
|
| 700 |
+
self.cy.cython_namespace[cython_module.name] = cython_module
|
| 701 |
+
|
| 702 |
+
for variable in module.find('Globals'):
|
| 703 |
+
d = variable.attrib
|
| 704 |
+
cython_module.globals[d['name']] = CythonVariable(**d)
|
| 705 |
+
|
| 706 |
+
for function in module.find('Functions'):
|
| 707 |
+
cython_function = CythonFunction(module=cython_module,
|
| 708 |
+
**function.attrib)
|
| 709 |
+
|
| 710 |
+
# update the global function mappings
|
| 711 |
+
name = cython_function.name
|
| 712 |
+
qname = cython_function.qualified_name
|
| 713 |
+
|
| 714 |
+
self.cy.functions_by_name[name].append(cython_function)
|
| 715 |
+
self.cy.functions_by_qualified_name[
|
| 716 |
+
cython_function.qualified_name] = cython_function
|
| 717 |
+
self.cy.functions_by_cname[
|
| 718 |
+
cython_function.cname] = cython_function
|
| 719 |
+
|
| 720 |
+
d = cython_module.functions[qname] = cython_function
|
| 721 |
+
|
| 722 |
+
for local in function.find('Locals'):
|
| 723 |
+
d = local.attrib
|
| 724 |
+
cython_function.locals[d['name']] = CythonVariable(**d)
|
| 725 |
+
|
| 726 |
+
for step_into_func in function.find('StepIntoFunctions'):
|
| 727 |
+
d = step_into_func.attrib
|
| 728 |
+
cython_function.step_into_functions.add(d['name'])
|
| 729 |
+
|
| 730 |
+
cython_function.arguments.extend(
|
| 731 |
+
funcarg.tag for funcarg in function.find('Arguments'))
|
| 732 |
+
|
| 733 |
+
for marker in module.find('LineNumberMapping'):
|
| 734 |
+
src_lineno = int(marker.attrib['src_lineno'])
|
| 735 |
+
src_path = marker.attrib['src_path']
|
| 736 |
+
c_linenos = list(map(int, marker.attrib['c_linenos'].split()))
|
| 737 |
+
cython_module.lineno_cy2c[src_path, src_lineno] = min(c_linenos)
|
| 738 |
+
for c_lineno in c_linenos:
|
| 739 |
+
cython_module.lineno_c2cy[c_lineno] = (src_path, src_lineno)
|
| 740 |
+
|
| 741 |
+
|
| 742 |
+
class CyBreak(CythonCommand):
|
| 743 |
+
"""
|
| 744 |
+
Set a breakpoint for Cython code using Cython qualified name notation, e.g.:
|
| 745 |
+
|
| 746 |
+
cy break cython_modulename.ClassName.method_name...
|
| 747 |
+
|
| 748 |
+
or normal notation:
|
| 749 |
+
|
| 750 |
+
cy break function_or_method_name...
|
| 751 |
+
|
| 752 |
+
or for a line number:
|
| 753 |
+
|
| 754 |
+
cy break cython_module:lineno...
|
| 755 |
+
|
| 756 |
+
Set a Python breakpoint:
|
| 757 |
+
Break on any function or method named 'func' in module 'modname'
|
| 758 |
+
|
| 759 |
+
cy break -p modname.func...
|
| 760 |
+
|
| 761 |
+
Break on any function or method named 'func'
|
| 762 |
+
|
| 763 |
+
cy break -p func...
|
| 764 |
+
"""
|
| 765 |
+
|
| 766 |
+
name = 'cy break'
|
| 767 |
+
command_class = gdb.COMMAND_BREAKPOINTS
|
| 768 |
+
|
| 769 |
+
def _break_pyx(self, name):
|
| 770 |
+
modulename, _, lineno = name.partition(':')
|
| 771 |
+
lineno = int(lineno)
|
| 772 |
+
if modulename:
|
| 773 |
+
cython_module = self.cy.cython_namespace[modulename]
|
| 774 |
+
else:
|
| 775 |
+
cython_module = self.get_cython_function().module
|
| 776 |
+
|
| 777 |
+
if (cython_module.filename, lineno) in cython_module.lineno_cy2c:
|
| 778 |
+
c_lineno = cython_module.lineno_cy2c[cython_module.filename, lineno]
|
| 779 |
+
breakpoint = '%s:%s' % (cython_module.c_filename, c_lineno)
|
| 780 |
+
gdb.execute('break ' + breakpoint)
|
| 781 |
+
else:
|
| 782 |
+
raise gdb.GdbError("Not a valid line number. "
|
| 783 |
+
"Does it contain actual code?")
|
| 784 |
+
|
| 785 |
+
def _break_funcname(self, funcname):
|
| 786 |
+
func = self.cy.functions_by_qualified_name.get(funcname)
|
| 787 |
+
|
| 788 |
+
if func and func.is_initmodule_function:
|
| 789 |
+
func = None
|
| 790 |
+
|
| 791 |
+
break_funcs = [func]
|
| 792 |
+
|
| 793 |
+
if not func:
|
| 794 |
+
funcs = self.cy.functions_by_name.get(funcname) or []
|
| 795 |
+
funcs = [f for f in funcs if not f.is_initmodule_function]
|
| 796 |
+
|
| 797 |
+
if not funcs:
|
| 798 |
+
gdb.execute('break ' + funcname)
|
| 799 |
+
return
|
| 800 |
+
|
| 801 |
+
if len(funcs) > 1:
|
| 802 |
+
# multiple functions, let the user pick one
|
| 803 |
+
print('There are multiple such functions:')
|
| 804 |
+
for idx, func in enumerate(funcs):
|
| 805 |
+
print('%3d) %s' % (idx, func.qualified_name))
|
| 806 |
+
|
| 807 |
+
while True:
|
| 808 |
+
try:
|
| 809 |
+
result = input(
|
| 810 |
+
"Select a function, press 'a' for all "
|
| 811 |
+
"functions or press 'q' or '^D' to quit: ")
|
| 812 |
+
except EOFError:
|
| 813 |
+
return
|
| 814 |
+
else:
|
| 815 |
+
if result.lower() == 'q':
|
| 816 |
+
return
|
| 817 |
+
elif result.lower() == 'a':
|
| 818 |
+
break_funcs = funcs
|
| 819 |
+
break
|
| 820 |
+
elif (result.isdigit() and
|
| 821 |
+
0 <= int(result) < len(funcs)):
|
| 822 |
+
break_funcs = [funcs[int(result)]]
|
| 823 |
+
break
|
| 824 |
+
else:
|
| 825 |
+
print('Not understood...')
|
| 826 |
+
else:
|
| 827 |
+
break_funcs = [funcs[0]]
|
| 828 |
+
|
| 829 |
+
for func in break_funcs:
|
| 830 |
+
gdb.execute('break %s' % func.cname)
|
| 831 |
+
if func.pf_cname:
|
| 832 |
+
gdb.execute('break %s' % func.pf_cname)
|
| 833 |
+
|
| 834 |
+
@libpython.dont_suppress_errors
|
| 835 |
+
def invoke(self, function_names, from_tty):
|
| 836 |
+
if isinstance(function_names, BYTES):
|
| 837 |
+
function_names = function_names.decode(_filesystemencoding)
|
| 838 |
+
argv = string_to_argv(function_names)
|
| 839 |
+
if function_names.startswith('-p'):
|
| 840 |
+
argv = argv[1:]
|
| 841 |
+
python_breakpoints = True
|
| 842 |
+
else:
|
| 843 |
+
python_breakpoints = False
|
| 844 |
+
|
| 845 |
+
for funcname in argv:
|
| 846 |
+
if python_breakpoints:
|
| 847 |
+
gdb.execute('py-break %s' % funcname)
|
| 848 |
+
elif ':' in funcname:
|
| 849 |
+
self._break_pyx(funcname)
|
| 850 |
+
else:
|
| 851 |
+
self._break_funcname(funcname)
|
| 852 |
+
|
| 853 |
+
@libpython.dont_suppress_errors
|
| 854 |
+
def complete(self, text, word):
|
| 855 |
+
# Filter init-module functions (breakpoints can be set using
|
| 856 |
+
# modulename:linenumber).
|
| 857 |
+
names = [n for n, L in self.cy.functions_by_name.items()
|
| 858 |
+
if any(not f.is_initmodule_function for f in L)]
|
| 859 |
+
qnames = [n for n, f in self.cy.functions_by_qualified_name.items()
|
| 860 |
+
if not f.is_initmodule_function]
|
| 861 |
+
|
| 862 |
+
if parameters.complete_unqualified:
|
| 863 |
+
all_names = itertools.chain(qnames, names)
|
| 864 |
+
else:
|
| 865 |
+
all_names = qnames
|
| 866 |
+
|
| 867 |
+
words = text.strip().split()
|
| 868 |
+
if not words or '.' not in words[-1]:
|
| 869 |
+
# complete unqualified
|
| 870 |
+
seen = set(text[:-len(word)].split())
|
| 871 |
+
return [n for n in all_names
|
| 872 |
+
if n.startswith(word) and n not in seen]
|
| 873 |
+
|
| 874 |
+
# complete qualified name
|
| 875 |
+
lastword = words[-1]
|
| 876 |
+
compl = [n for n in qnames if n.startswith(lastword)]
|
| 877 |
+
|
| 878 |
+
if len(lastword) > len(word):
|
| 879 |
+
# readline sees something (e.g. a '.') as a word boundary, so don't
|
| 880 |
+
# "recomplete" this prefix
|
| 881 |
+
strip_prefix_length = len(lastword) - len(word)
|
| 882 |
+
compl = [n[strip_prefix_length:] for n in compl]
|
| 883 |
+
|
| 884 |
+
return compl
|
| 885 |
+
|
| 886 |
+
|
| 887 |
+
class CythonInfo(CythonBase, libpython.PythonInfo):
|
| 888 |
+
"""
|
| 889 |
+
Implementation of the interface dictated by libpython.LanguageInfo.
|
| 890 |
+
"""
|
| 891 |
+
|
| 892 |
+
def lineno(self, frame):
|
| 893 |
+
# Take care of the Python and Cython levels. We need to care for both
|
| 894 |
+
# as we can't simply dispatch to 'py-step', since that would work for
|
| 895 |
+
# stepping through Python code, but it would not step back into Cython-
|
| 896 |
+
# related code. The C level should be dispatched to the 'step' command.
|
| 897 |
+
if self.is_cython_function(frame):
|
| 898 |
+
return self.get_cython_lineno(frame)[1]
|
| 899 |
+
return super(CythonInfo, self).lineno(frame)
|
| 900 |
+
|
| 901 |
+
def get_source_line(self, frame):
|
| 902 |
+
try:
|
| 903 |
+
line = super(CythonInfo, self).get_source_line(frame)
|
| 904 |
+
except gdb.GdbError:
|
| 905 |
+
return None
|
| 906 |
+
else:
|
| 907 |
+
return line.strip() or None
|
| 908 |
+
|
| 909 |
+
def exc_info(self, frame):
|
| 910 |
+
if self.is_python_function:
|
| 911 |
+
return super(CythonInfo, self).exc_info(frame)
|
| 912 |
+
|
| 913 |
+
def runtime_break_functions(self):
|
| 914 |
+
if self.is_cython_function():
|
| 915 |
+
return self.get_cython_function().step_into_functions
|
| 916 |
+
return ()
|
| 917 |
+
|
| 918 |
+
def static_break_functions(self):
|
| 919 |
+
result = ['PyEval_EvalFrameEx']
|
| 920 |
+
result.extend(self.cy.functions_by_cname)
|
| 921 |
+
return result
|
| 922 |
+
|
| 923 |
+
|
| 924 |
+
class CythonExecutionControlCommand(CythonCommand,
|
| 925 |
+
libpython.ExecutionControlCommandBase):
|
| 926 |
+
|
| 927 |
+
@classmethod
|
| 928 |
+
def register(cls):
|
| 929 |
+
return cls(cls.name, cython_info)
|
| 930 |
+
|
| 931 |
+
|
| 932 |
+
class CyStep(CythonExecutionControlCommand, libpython.PythonStepperMixin):
|
| 933 |
+
"Step through Cython, Python or C code."
|
| 934 |
+
|
| 935 |
+
name = 'cy -step'
|
| 936 |
+
stepinto = True
|
| 937 |
+
|
| 938 |
+
@libpython.dont_suppress_errors
|
| 939 |
+
def invoke(self, args, from_tty):
|
| 940 |
+
if self.is_python_function():
|
| 941 |
+
self.python_step(self.stepinto)
|
| 942 |
+
elif not self.is_cython_function():
|
| 943 |
+
if self.stepinto:
|
| 944 |
+
command = 'step'
|
| 945 |
+
else:
|
| 946 |
+
command = 'next'
|
| 947 |
+
|
| 948 |
+
self.finish_executing(gdb.execute(command, to_string=True))
|
| 949 |
+
else:
|
| 950 |
+
self.step(stepinto=self.stepinto)
|
| 951 |
+
|
| 952 |
+
|
| 953 |
+
class CyNext(CyStep):
|
| 954 |
+
"Step-over Cython, Python or C code."
|
| 955 |
+
|
| 956 |
+
name = 'cy -next'
|
| 957 |
+
stepinto = False
|
| 958 |
+
|
| 959 |
+
|
| 960 |
+
class CyRun(CythonExecutionControlCommand):
|
| 961 |
+
"""
|
| 962 |
+
Run a Cython program. This is like the 'run' command, except that it
|
| 963 |
+
displays Cython or Python source lines as well
|
| 964 |
+
"""
|
| 965 |
+
|
| 966 |
+
name = 'cy run'
|
| 967 |
+
|
| 968 |
+
invoke = libpython.dont_suppress_errors(CythonExecutionControlCommand.run)
|
| 969 |
+
|
| 970 |
+
|
| 971 |
+
class CyCont(CythonExecutionControlCommand):
|
| 972 |
+
"""
|
| 973 |
+
Continue a Cython program. This is like the 'run' command, except that it
|
| 974 |
+
displays Cython or Python source lines as well.
|
| 975 |
+
"""
|
| 976 |
+
|
| 977 |
+
name = 'cy cont'
|
| 978 |
+
invoke = libpython.dont_suppress_errors(CythonExecutionControlCommand.cont)
|
| 979 |
+
|
| 980 |
+
|
| 981 |
+
class CyFinish(CythonExecutionControlCommand):
|
| 982 |
+
"""
|
| 983 |
+
Execute until the function returns.
|
| 984 |
+
"""
|
| 985 |
+
name = 'cy finish'
|
| 986 |
+
|
| 987 |
+
invoke = libpython.dont_suppress_errors(CythonExecutionControlCommand.finish)
|
| 988 |
+
|
| 989 |
+
|
| 990 |
+
class CyUp(CythonCommand):
|
| 991 |
+
"""
|
| 992 |
+
Go up a Cython, Python or relevant C frame.
|
| 993 |
+
"""
|
| 994 |
+
name = 'cy up'
|
| 995 |
+
_command = 'up'
|
| 996 |
+
|
| 997 |
+
@libpython.dont_suppress_errors
|
| 998 |
+
def invoke(self, *args):
|
| 999 |
+
try:
|
| 1000 |
+
gdb.execute(self._command, to_string=True)
|
| 1001 |
+
while not self.is_relevant_function(gdb.selected_frame()):
|
| 1002 |
+
gdb.execute(self._command, to_string=True)
|
| 1003 |
+
except RuntimeError as e:
|
| 1004 |
+
raise gdb.GdbError(*e.args)
|
| 1005 |
+
|
| 1006 |
+
frame = gdb.selected_frame()
|
| 1007 |
+
index = 0
|
| 1008 |
+
while frame:
|
| 1009 |
+
frame = frame.older()
|
| 1010 |
+
index += 1
|
| 1011 |
+
|
| 1012 |
+
self.print_stackframe(index=index - 1)
|
| 1013 |
+
|
| 1014 |
+
|
| 1015 |
+
class CyDown(CyUp):
|
| 1016 |
+
"""
|
| 1017 |
+
Go down a Cython, Python or relevant C frame.
|
| 1018 |
+
"""
|
| 1019 |
+
|
| 1020 |
+
name = 'cy down'
|
| 1021 |
+
_command = 'down'
|
| 1022 |
+
|
| 1023 |
+
|
| 1024 |
+
class CySelect(CythonCommand):
|
| 1025 |
+
"""
|
| 1026 |
+
Select a frame. Use frame numbers as listed in `cy backtrace`.
|
| 1027 |
+
This command is useful because `cy backtrace` prints a reversed backtrace.
|
| 1028 |
+
"""
|
| 1029 |
+
|
| 1030 |
+
name = 'cy select'
|
| 1031 |
+
|
| 1032 |
+
@libpython.dont_suppress_errors
|
| 1033 |
+
def invoke(self, stackno, from_tty):
|
| 1034 |
+
try:
|
| 1035 |
+
stackno = int(stackno)
|
| 1036 |
+
except ValueError:
|
| 1037 |
+
raise gdb.GdbError("Not a valid number: %r" % (stackno,))
|
| 1038 |
+
|
| 1039 |
+
frame = gdb.selected_frame()
|
| 1040 |
+
while frame.newer():
|
| 1041 |
+
frame = frame.newer()
|
| 1042 |
+
|
| 1043 |
+
stackdepth = libpython.stackdepth(frame)
|
| 1044 |
+
|
| 1045 |
+
try:
|
| 1046 |
+
gdb.execute('select %d' % (stackdepth - stackno - 1,))
|
| 1047 |
+
except RuntimeError as e:
|
| 1048 |
+
raise gdb.GdbError(*e.args)
|
| 1049 |
+
|
| 1050 |
+
|
| 1051 |
+
class CyBacktrace(CythonCommand):
|
| 1052 |
+
'Print the Cython stack'
|
| 1053 |
+
|
| 1054 |
+
name = 'cy bt'
|
| 1055 |
+
alias = 'cy backtrace'
|
| 1056 |
+
command_class = gdb.COMMAND_STACK
|
| 1057 |
+
completer_class = gdb.COMPLETE_NONE
|
| 1058 |
+
|
| 1059 |
+
@libpython.dont_suppress_errors
|
| 1060 |
+
@require_running_program
|
| 1061 |
+
def invoke(self, args, from_tty):
|
| 1062 |
+
# get the first frame
|
| 1063 |
+
frame = gdb.selected_frame()
|
| 1064 |
+
while frame.older():
|
| 1065 |
+
frame = frame.older()
|
| 1066 |
+
|
| 1067 |
+
print_all = args == '-a'
|
| 1068 |
+
|
| 1069 |
+
index = 0
|
| 1070 |
+
while frame:
|
| 1071 |
+
try:
|
| 1072 |
+
is_relevant = self.is_relevant_function(frame)
|
| 1073 |
+
except CyGDBError:
|
| 1074 |
+
is_relevant = False
|
| 1075 |
+
|
| 1076 |
+
if print_all or is_relevant:
|
| 1077 |
+
self.print_stackframe(frame, index)
|
| 1078 |
+
|
| 1079 |
+
index += 1
|
| 1080 |
+
frame = frame.newer()
|
| 1081 |
+
|
| 1082 |
+
|
| 1083 |
+
class CyList(CythonCommand):
|
| 1084 |
+
"""
|
| 1085 |
+
List Cython source code. To disable to customize colouring see the cy_*
|
| 1086 |
+
parameters.
|
| 1087 |
+
"""
|
| 1088 |
+
|
| 1089 |
+
name = 'cy list'
|
| 1090 |
+
command_class = gdb.COMMAND_FILES
|
| 1091 |
+
completer_class = gdb.COMPLETE_NONE
|
| 1092 |
+
|
| 1093 |
+
@libpython.dont_suppress_errors
|
| 1094 |
+
# @dispatch_on_frame(c_command='list')
|
| 1095 |
+
def invoke(self, _, from_tty):
|
| 1096 |
+
sd, lineno = self.get_source_desc()
|
| 1097 |
+
source = sd.get_source(lineno - 5, lineno + 5, mark_line=lineno,
|
| 1098 |
+
lex_entire=True)
|
| 1099 |
+
print(source)
|
| 1100 |
+
|
| 1101 |
+
|
| 1102 |
+
class CyPrint(CythonCommand):
|
| 1103 |
+
"""
|
| 1104 |
+
Print a Cython variable using 'cy-print x' or 'cy-print module.function.x'
|
| 1105 |
+
"""
|
| 1106 |
+
|
| 1107 |
+
name = 'cy print'
|
| 1108 |
+
command_class = gdb.COMMAND_DATA
|
| 1109 |
+
|
| 1110 |
+
@libpython.dont_suppress_errors
|
| 1111 |
+
def invoke(self, name, from_tty):
|
| 1112 |
+
global_python_dict = self.get_cython_globals_dict()
|
| 1113 |
+
module_globals = self.get_cython_function().module.globals
|
| 1114 |
+
|
| 1115 |
+
if name in global_python_dict:
|
| 1116 |
+
value = global_python_dict[name].get_truncated_repr(libpython.MAX_OUTPUT_LEN)
|
| 1117 |
+
print('%s = %s' % (name, value))
|
| 1118 |
+
#This also would work, but because the output of cy exec is not captured in gdb.execute, TestPrint would fail
|
| 1119 |
+
#self.cy.exec_.invoke("print('"+name+"','=', type(" + name + "), "+name+", flush=True )", from_tty)
|
| 1120 |
+
elif name in module_globals:
|
| 1121 |
+
cname = module_globals[name].cname
|
| 1122 |
+
try:
|
| 1123 |
+
value = gdb.parse_and_eval(cname)
|
| 1124 |
+
except RuntimeError:
|
| 1125 |
+
print("unable to get value of %s" % name)
|
| 1126 |
+
else:
|
| 1127 |
+
if not value.is_optimized_out:
|
| 1128 |
+
self.print_gdb_value(name, value)
|
| 1129 |
+
else:
|
| 1130 |
+
print("%s is optimized out" % name)
|
| 1131 |
+
elif self.is_python_function():
|
| 1132 |
+
return gdb.execute('py-print ' + name)
|
| 1133 |
+
elif self.is_cython_function():
|
| 1134 |
+
value = self.cy.cy_cvalue.invoke(name.lstrip('*'))
|
| 1135 |
+
for c in name:
|
| 1136 |
+
if c == '*':
|
| 1137 |
+
value = value.dereference()
|
| 1138 |
+
else:
|
| 1139 |
+
break
|
| 1140 |
+
|
| 1141 |
+
self.print_gdb_value(name, value)
|
| 1142 |
+
else:
|
| 1143 |
+
gdb.execute('print ' + name)
|
| 1144 |
+
|
| 1145 |
+
def complete(self):
|
| 1146 |
+
if self.is_cython_function():
|
| 1147 |
+
f = self.get_cython_function()
|
| 1148 |
+
return list(itertools.chain(f.locals, f.globals))
|
| 1149 |
+
else:
|
| 1150 |
+
return []
|
| 1151 |
+
|
| 1152 |
+
|
| 1153 |
+
sortkey = lambda item: item[0].lower()
|
| 1154 |
+
|
| 1155 |
+
|
| 1156 |
+
class CyLocals(CythonCommand):
|
| 1157 |
+
"""
|
| 1158 |
+
List the locals from the current Cython frame.
|
| 1159 |
+
"""
|
| 1160 |
+
|
| 1161 |
+
name = 'cy locals'
|
| 1162 |
+
command_class = gdb.COMMAND_STACK
|
| 1163 |
+
completer_class = gdb.COMPLETE_NONE
|
| 1164 |
+
|
| 1165 |
+
@libpython.dont_suppress_errors
|
| 1166 |
+
@dispatch_on_frame(c_command='info locals', python_command='py-locals')
|
| 1167 |
+
def invoke(self, args, from_tty):
|
| 1168 |
+
cython_function = self.get_cython_function()
|
| 1169 |
+
|
| 1170 |
+
if cython_function.is_initmodule_function:
|
| 1171 |
+
self.cy.globals.invoke(args, from_tty)
|
| 1172 |
+
return
|
| 1173 |
+
|
| 1174 |
+
local_cython_vars = cython_function.locals
|
| 1175 |
+
max_name_length = len(max(local_cython_vars, key=len))
|
| 1176 |
+
for name, cyvar in sorted(local_cython_vars.items(), key=sortkey):
|
| 1177 |
+
if self.is_initialized(self.get_cython_function(), cyvar.name):
|
| 1178 |
+
value = gdb.parse_and_eval(cyvar.cname)
|
| 1179 |
+
if not value.is_optimized_out:
|
| 1180 |
+
self.print_gdb_value(cyvar.name, value,
|
| 1181 |
+
max_name_length, '')
|
| 1182 |
+
|
| 1183 |
+
|
| 1184 |
+
class CyGlobals(CyLocals):
|
| 1185 |
+
"""
|
| 1186 |
+
List the globals from the current Cython module.
|
| 1187 |
+
"""
|
| 1188 |
+
|
| 1189 |
+
name = 'cy globals'
|
| 1190 |
+
command_class = gdb.COMMAND_STACK
|
| 1191 |
+
completer_class = gdb.COMPLETE_NONE
|
| 1192 |
+
|
| 1193 |
+
@libpython.dont_suppress_errors
|
| 1194 |
+
@dispatch_on_frame(c_command='info variables', python_command='py-globals')
|
| 1195 |
+
def invoke(self, args, from_tty):
|
| 1196 |
+
global_python_dict = self.get_cython_globals_dict()
|
| 1197 |
+
module_globals = self.get_cython_function().module.globals
|
| 1198 |
+
|
| 1199 |
+
max_globals_len = 0
|
| 1200 |
+
max_globals_dict_len = 0
|
| 1201 |
+
if module_globals:
|
| 1202 |
+
max_globals_len = len(max(module_globals, key=len))
|
| 1203 |
+
if global_python_dict:
|
| 1204 |
+
max_globals_dict_len = len(max(global_python_dict))
|
| 1205 |
+
|
| 1206 |
+
max_name_length = max(max_globals_len, max_globals_dict_len)
|
| 1207 |
+
|
| 1208 |
+
seen = set()
|
| 1209 |
+
print('Python globals:')
|
| 1210 |
+
|
| 1211 |
+
for k, v in sorted(global_python_dict.items(), key=sortkey):
|
| 1212 |
+
v = v.get_truncated_repr(libpython.MAX_OUTPUT_LEN)
|
| 1213 |
+
seen.add(k)
|
| 1214 |
+
print(' %-*s = %s' % (max_name_length, k, v))
|
| 1215 |
+
|
| 1216 |
+
print('C globals:')
|
| 1217 |
+
for name, cyvar in sorted(module_globals.items(), key=sortkey):
|
| 1218 |
+
if name not in seen:
|
| 1219 |
+
try:
|
| 1220 |
+
value = gdb.parse_and_eval(cyvar.cname)
|
| 1221 |
+
except RuntimeError:
|
| 1222 |
+
pass
|
| 1223 |
+
else:
|
| 1224 |
+
if not value.is_optimized_out:
|
| 1225 |
+
self.print_gdb_value(cyvar.name, value,
|
| 1226 |
+
max_name_length, ' ')
|
| 1227 |
+
|
| 1228 |
+
|
| 1229 |
+
class EvaluateOrExecuteCodeMixin(object):
|
| 1230 |
+
"""
|
| 1231 |
+
Evaluate or execute Python code in a Cython or Python frame. The 'evalcode'
|
| 1232 |
+
method evaluations Python code, prints a traceback if an exception went
|
| 1233 |
+
uncaught, and returns any return value as a gdb.Value (NULL on exception).
|
| 1234 |
+
"""
|
| 1235 |
+
|
| 1236 |
+
def _fill_locals_dict(self, executor, local_dict_pointer):
|
| 1237 |
+
"Fill a remotely allocated dict with values from the Cython C stack"
|
| 1238 |
+
cython_func = self.get_cython_function()
|
| 1239 |
+
|
| 1240 |
+
for name, cyvar in cython_func.locals.items():
|
| 1241 |
+
if (cyvar.type == PythonObject
|
| 1242 |
+
and self.is_initialized(cython_func, name)):
|
| 1243 |
+
|
| 1244 |
+
try:
|
| 1245 |
+
val = gdb.parse_and_eval(cyvar.cname)
|
| 1246 |
+
except RuntimeError:
|
| 1247 |
+
continue
|
| 1248 |
+
else:
|
| 1249 |
+
if val.is_optimized_out:
|
| 1250 |
+
continue
|
| 1251 |
+
|
| 1252 |
+
pystringp = executor.alloc_pystring(name)
|
| 1253 |
+
code = '''
|
| 1254 |
+
(PyObject *) PyDict_SetItem(
|
| 1255 |
+
(PyObject *) %d,
|
| 1256 |
+
(PyObject *) %d,
|
| 1257 |
+
(PyObject *) %s)
|
| 1258 |
+
''' % (local_dict_pointer, pystringp, cyvar.cname)
|
| 1259 |
+
|
| 1260 |
+
try:
|
| 1261 |
+
if gdb.parse_and_eval(code) < 0:
|
| 1262 |
+
gdb.parse_and_eval('PyErr_Print()')
|
| 1263 |
+
raise gdb.GdbError("Unable to execute Python code.")
|
| 1264 |
+
finally:
|
| 1265 |
+
# PyDict_SetItem doesn't steal our reference
|
| 1266 |
+
executor.xdecref(pystringp)
|
| 1267 |
+
|
| 1268 |
+
def _find_first_cython_or_python_frame(self):
|
| 1269 |
+
frame = gdb.selected_frame()
|
| 1270 |
+
while frame:
|
| 1271 |
+
if (self.is_cython_function(frame)
|
| 1272 |
+
or self.is_python_function(frame)):
|
| 1273 |
+
frame.select()
|
| 1274 |
+
return frame
|
| 1275 |
+
|
| 1276 |
+
frame = frame.older()
|
| 1277 |
+
|
| 1278 |
+
raise gdb.GdbError("There is no Cython or Python frame on the stack.")
|
| 1279 |
+
|
| 1280 |
+
def _evalcode_cython(self, executor, code, input_type):
|
| 1281 |
+
with libpython.FetchAndRestoreError():
|
| 1282 |
+
# get the dict of Cython globals and construct a dict in the
|
| 1283 |
+
# inferior with Cython locals
|
| 1284 |
+
global_dict = gdb.parse_and_eval(
|
| 1285 |
+
'(PyObject *) PyModule_GetDict(__pyx_m)')
|
| 1286 |
+
local_dict = gdb.parse_and_eval('(PyObject *) PyDict_New()')
|
| 1287 |
+
|
| 1288 |
+
try:
|
| 1289 |
+
self._fill_locals_dict(executor,
|
| 1290 |
+
libpython.pointervalue(local_dict))
|
| 1291 |
+
result = executor.evalcode(code, input_type, global_dict,
|
| 1292 |
+
local_dict)
|
| 1293 |
+
finally:
|
| 1294 |
+
executor.xdecref(libpython.pointervalue(local_dict))
|
| 1295 |
+
|
| 1296 |
+
return result
|
| 1297 |
+
|
| 1298 |
+
def evalcode(self, code, input_type):
|
| 1299 |
+
"""
|
| 1300 |
+
Evaluate `code` in a Python or Cython stack frame using the given
|
| 1301 |
+
`input_type`.
|
| 1302 |
+
"""
|
| 1303 |
+
frame = self._find_first_cython_or_python_frame()
|
| 1304 |
+
executor = libpython.PythonCodeExecutor()
|
| 1305 |
+
if self.is_python_function(frame):
|
| 1306 |
+
return libpython._evalcode_python(executor, code, input_type)
|
| 1307 |
+
return self._evalcode_cython(executor, code, input_type)
|
| 1308 |
+
|
| 1309 |
+
|
| 1310 |
+
class CyExec(CythonCommand, libpython.PyExec, EvaluateOrExecuteCodeMixin):
|
| 1311 |
+
"""
|
| 1312 |
+
Execute Python code in the nearest Python or Cython frame.
|
| 1313 |
+
"""
|
| 1314 |
+
|
| 1315 |
+
name = '-cy-exec'
|
| 1316 |
+
command_class = gdb.COMMAND_STACK
|
| 1317 |
+
completer_class = gdb.COMPLETE_NONE
|
| 1318 |
+
|
| 1319 |
+
@libpython.dont_suppress_errors
|
| 1320 |
+
def invoke(self, expr, from_tty):
|
| 1321 |
+
expr, input_type = self.readcode(expr)
|
| 1322 |
+
executor = libpython.PythonCodeExecutor()
|
| 1323 |
+
executor.xdecref(self.evalcode(expr, executor.Py_file_input))
|
| 1324 |
+
|
| 1325 |
+
|
| 1326 |
+
class CySet(CythonCommand):
|
| 1327 |
+
"""
|
| 1328 |
+
Set a Cython variable to a certain value
|
| 1329 |
+
|
| 1330 |
+
cy set my_cython_c_variable = 10
|
| 1331 |
+
cy set my_cython_py_variable = $cy_eval("{'doner': 'kebab'}")
|
| 1332 |
+
|
| 1333 |
+
This is equivalent to
|
| 1334 |
+
|
| 1335 |
+
set $cy_value("my_cython_variable") = 10
|
| 1336 |
+
"""
|
| 1337 |
+
|
| 1338 |
+
name = 'cy set'
|
| 1339 |
+
command_class = gdb.COMMAND_DATA
|
| 1340 |
+
completer_class = gdb.COMPLETE_NONE
|
| 1341 |
+
|
| 1342 |
+
@libpython.dont_suppress_errors
|
| 1343 |
+
@require_cython_frame
|
| 1344 |
+
def invoke(self, expr, from_tty):
|
| 1345 |
+
name_and_expr = expr.split('=', 1)
|
| 1346 |
+
if len(name_and_expr) != 2:
|
| 1347 |
+
raise gdb.GdbError("Invalid expression. Use 'cy set var = expr'.")
|
| 1348 |
+
|
| 1349 |
+
varname, expr = name_and_expr
|
| 1350 |
+
cname = self.cy.cy_cname.invoke(varname.strip())
|
| 1351 |
+
gdb.execute("set %s = %s" % (cname, expr))
|
| 1352 |
+
|
| 1353 |
+
|
| 1354 |
+
# Functions
|
| 1355 |
+
|
| 1356 |
+
class CyCName(gdb.Function, CythonBase):
|
| 1357 |
+
"""
|
| 1358 |
+
Get the C name of a Cython variable in the current context.
|
| 1359 |
+
Examples:
|
| 1360 |
+
|
| 1361 |
+
print $cy_cname("function")
|
| 1362 |
+
print $cy_cname("Class.method")
|
| 1363 |
+
print $cy_cname("module.function")
|
| 1364 |
+
"""
|
| 1365 |
+
|
| 1366 |
+
@libpython.dont_suppress_errors
|
| 1367 |
+
@require_cython_frame
|
| 1368 |
+
@gdb_function_value_to_unicode
|
| 1369 |
+
def invoke(self, cyname, frame=None):
|
| 1370 |
+
frame = frame or gdb.selected_frame()
|
| 1371 |
+
cname = None
|
| 1372 |
+
|
| 1373 |
+
if self.is_cython_function(frame):
|
| 1374 |
+
cython_function = self.get_cython_function(frame)
|
| 1375 |
+
if cyname in cython_function.locals:
|
| 1376 |
+
cname = cython_function.locals[cyname].cname
|
| 1377 |
+
elif cyname in cython_function.module.globals:
|
| 1378 |
+
cname = cython_function.module.globals[cyname].cname
|
| 1379 |
+
else:
|
| 1380 |
+
qname = '%s.%s' % (cython_function.module.name, cyname)
|
| 1381 |
+
if qname in cython_function.module.functions:
|
| 1382 |
+
cname = cython_function.module.functions[qname].cname
|
| 1383 |
+
|
| 1384 |
+
if not cname:
|
| 1385 |
+
cname = self.cy.functions_by_qualified_name.get(cyname)
|
| 1386 |
+
|
| 1387 |
+
if not cname:
|
| 1388 |
+
raise gdb.GdbError('No such Cython variable: %s' % cyname)
|
| 1389 |
+
|
| 1390 |
+
return cname
|
| 1391 |
+
|
| 1392 |
+
|
| 1393 |
+
class CyCValue(CyCName):
|
| 1394 |
+
"""
|
| 1395 |
+
Get the value of a Cython variable.
|
| 1396 |
+
"""
|
| 1397 |
+
|
| 1398 |
+
@libpython.dont_suppress_errors
|
| 1399 |
+
@require_cython_frame
|
| 1400 |
+
@gdb_function_value_to_unicode
|
| 1401 |
+
def invoke(self, cyname, frame=None):
|
| 1402 |
+
globals_dict = self.get_cython_globals_dict()
|
| 1403 |
+
cython_function = self.get_cython_function(frame)
|
| 1404 |
+
|
| 1405 |
+
if self.is_initialized(cython_function, cyname):
|
| 1406 |
+
cname = super(CyCValue, self).invoke(cyname, frame=frame)
|
| 1407 |
+
return gdb.parse_and_eval(cname)
|
| 1408 |
+
elif cyname in globals_dict:
|
| 1409 |
+
return globals_dict[cyname]._gdbval
|
| 1410 |
+
else:
|
| 1411 |
+
raise gdb.GdbError("Variable %s is not initialized." % cyname)
|
| 1412 |
+
|
| 1413 |
+
|
| 1414 |
+
class CyLine(gdb.Function, CythonBase):
|
| 1415 |
+
"""
|
| 1416 |
+
Get the current Cython line.
|
| 1417 |
+
"""
|
| 1418 |
+
|
| 1419 |
+
@libpython.dont_suppress_errors
|
| 1420 |
+
@require_cython_frame
|
| 1421 |
+
def invoke(self):
|
| 1422 |
+
return self.get_cython_lineno()[1]
|
| 1423 |
+
|
| 1424 |
+
|
| 1425 |
+
class CyEval(gdb.Function, CythonBase, EvaluateOrExecuteCodeMixin):
|
| 1426 |
+
"""
|
| 1427 |
+
Evaluate Python code in the nearest Python or Cython frame and return
|
| 1428 |
+
"""
|
| 1429 |
+
|
| 1430 |
+
@libpython.dont_suppress_errors
|
| 1431 |
+
@gdb_function_value_to_unicode
|
| 1432 |
+
def invoke(self, python_expression):
|
| 1433 |
+
input_type = libpython.PythonCodeExecutor.Py_eval_input
|
| 1434 |
+
return self.evalcode(python_expression, input_type)
|
| 1435 |
+
|
| 1436 |
+
|
| 1437 |
+
cython_info = CythonInfo()
|
| 1438 |
+
cy = CyCy.register()
|
| 1439 |
+
cython_info.cy = cy
|
| 1440 |
+
|
| 1441 |
+
|
| 1442 |
+
def register_defines():
|
| 1443 |
+
libpython.source_gdb_script(textwrap.dedent("""\
|
| 1444 |
+
define cy step
|
| 1445 |
+
cy -step
|
| 1446 |
+
end
|
| 1447 |
+
|
| 1448 |
+
define cy next
|
| 1449 |
+
cy -next
|
| 1450 |
+
end
|
| 1451 |
+
|
| 1452 |
+
document cy step
|
| 1453 |
+
%s
|
| 1454 |
+
end
|
| 1455 |
+
|
| 1456 |
+
document cy next
|
| 1457 |
+
%s
|
| 1458 |
+
end
|
| 1459 |
+
""") % (CyStep.__doc__, CyNext.__doc__))
|
| 1460 |
+
|
| 1461 |
+
register_defines()
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Debugger/libpython.py
ADDED
|
@@ -0,0 +1,2851 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/python
|
| 2 |
+
|
| 3 |
+
# NOTE: Most of this file is taken from the Python source distribution
|
| 4 |
+
# It can be found under Tools/gdb/libpython.py. It is shipped with Cython
|
| 5 |
+
# because it's not installed as a python module, and because changes are only
|
| 6 |
+
# merged into new python versions (v3.2+).
|
| 7 |
+
# We added some of our code below the "## added, not in CPython" comment.
|
| 8 |
+
|
| 9 |
+
'''
|
| 10 |
+
From gdb 7 onwards, gdb's build can be configured --with-python, allowing gdb
|
| 11 |
+
to be extended with Python code e.g. for library-specific data visualizations,
|
| 12 |
+
such as for the C++ STL types. Documentation on this API can be seen at:
|
| 13 |
+
http://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
This python module deals with the case when the process being debugged (the
|
| 17 |
+
"inferior process" in gdb parlance) is itself python, or more specifically,
|
| 18 |
+
linked against libpython. In this situation, almost every item of data is a
|
| 19 |
+
(PyObject*), and having the debugger merely print their addresses is not very
|
| 20 |
+
enlightening.
|
| 21 |
+
|
| 22 |
+
This module embeds knowledge about the implementation details of libpython so
|
| 23 |
+
that we can emit useful visualizations e.g. a string, a list, a dict, a frame
|
| 24 |
+
giving file/line information and the state of local variables
|
| 25 |
+
|
| 26 |
+
In particular, given a gdb.Value corresponding to a PyObject* in the inferior
|
| 27 |
+
process, we can generate a "proxy value" within the gdb process. For example,
|
| 28 |
+
given a PyObject* in the inferior process that is in fact a PyListObject*
|
| 29 |
+
holding three PyObject* that turn out to be PyBytesObject* instances, we can
|
| 30 |
+
generate a proxy value within the gdb process that is a list of bytes
|
| 31 |
+
instances:
|
| 32 |
+
[b"foo", b"bar", b"baz"]
|
| 33 |
+
|
| 34 |
+
Doing so can be expensive for complicated graphs of objects, and could take
|
| 35 |
+
some time, so we also have a "write_repr" method that writes a representation
|
| 36 |
+
of the data to a file-like object. This allows us to stop the traversal by
|
| 37 |
+
having the file-like object raise an exception if it gets too much data.
|
| 38 |
+
|
| 39 |
+
With both "proxyval" and "write_repr" we keep track of the set of all addresses
|
| 40 |
+
visited so far in the traversal, to avoid infinite recursion due to cycles in
|
| 41 |
+
the graph of object references.
|
| 42 |
+
|
| 43 |
+
We try to defer gdb.lookup_type() invocations for python types until as late as
|
| 44 |
+
possible: for a dynamically linked python binary, when the process starts in
|
| 45 |
+
the debugger, the libpython.so hasn't been dynamically loaded yet, so none of
|
| 46 |
+
the type names are known to the debugger
|
| 47 |
+
|
| 48 |
+
The module also extends gdb with some python-specific commands.
|
| 49 |
+
'''
|
| 50 |
+
|
| 51 |
+
# NOTE: some gdbs are linked with Python 3, so this file should be dual-syntax
|
| 52 |
+
# compatible (2.6+ and 3.0+). See #19308.
|
| 53 |
+
|
| 54 |
+
from __future__ import print_function
|
| 55 |
+
import gdb
|
| 56 |
+
import os
|
| 57 |
+
import locale
|
| 58 |
+
import sys
|
| 59 |
+
|
| 60 |
+
if sys.version_info[0] >= 3:
|
| 61 |
+
unichr = chr
|
| 62 |
+
xrange = range
|
| 63 |
+
long = int
|
| 64 |
+
|
| 65 |
+
# Look up the gdb.Type for some standard types:
|
| 66 |
+
# Those need to be refreshed as types (pointer sizes) may change when
|
| 67 |
+
# gdb loads different executables
|
| 68 |
+
|
| 69 |
+
def _type_char_ptr():
|
| 70 |
+
return gdb.lookup_type('char').pointer() # char*
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def _type_unsigned_char_ptr():
|
| 74 |
+
return gdb.lookup_type('unsigned char').pointer() # unsigned char*
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def _type_unsigned_short_ptr():
|
| 78 |
+
return gdb.lookup_type('unsigned short').pointer()
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
def _type_unsigned_int_ptr():
|
| 82 |
+
return gdb.lookup_type('unsigned int').pointer()
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def _sizeof_void_p():
|
| 86 |
+
return gdb.lookup_type('void').pointer().sizeof
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
# value computed later, see PyUnicodeObjectPtr.proxy()
|
| 90 |
+
_is_pep393 = None
|
| 91 |
+
|
| 92 |
+
Py_TPFLAGS_HEAPTYPE = (1 << 9)
|
| 93 |
+
Py_TPFLAGS_LONG_SUBCLASS = (1 << 24)
|
| 94 |
+
Py_TPFLAGS_LIST_SUBCLASS = (1 << 25)
|
| 95 |
+
Py_TPFLAGS_TUPLE_SUBCLASS = (1 << 26)
|
| 96 |
+
Py_TPFLAGS_BYTES_SUBCLASS = (1 << 27)
|
| 97 |
+
Py_TPFLAGS_UNICODE_SUBCLASS = (1 << 28)
|
| 98 |
+
Py_TPFLAGS_DICT_SUBCLASS = (1 << 29)
|
| 99 |
+
Py_TPFLAGS_BASE_EXC_SUBCLASS = (1 << 30)
|
| 100 |
+
Py_TPFLAGS_TYPE_SUBCLASS = (1 << 31)
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
MAX_OUTPUT_LEN=1024
|
| 104 |
+
|
| 105 |
+
hexdigits = "0123456789abcdef"
|
| 106 |
+
|
| 107 |
+
ENCODING = locale.getpreferredencoding()
|
| 108 |
+
|
| 109 |
+
FRAME_INFO_OPTIMIZED_OUT = '(frame information optimized out)'
|
| 110 |
+
UNABLE_READ_INFO_PYTHON_FRAME = 'Unable to read information on python frame'
|
| 111 |
+
EVALFRAME = '_PyEval_EvalFrameDefault'
|
| 112 |
+
|
| 113 |
+
class NullPyObjectPtr(RuntimeError):
|
| 114 |
+
pass
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
def safety_limit(val):
|
| 118 |
+
# Given an integer value from the process being debugged, limit it to some
|
| 119 |
+
# safety threshold so that arbitrary breakage within said process doesn't
|
| 120 |
+
# break the gdb process too much (e.g. sizes of iterations, sizes of lists)
|
| 121 |
+
return min(val, 1000)
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def safe_range(val):
|
| 125 |
+
# As per range, but don't trust the value too much: cap it to a safety
|
| 126 |
+
# threshold in case the data was corrupted
|
| 127 |
+
return xrange(safety_limit(int(val)))
|
| 128 |
+
|
| 129 |
+
if sys.version_info[0] >= 3:
|
| 130 |
+
def write_unicode(file, text):
|
| 131 |
+
file.write(text)
|
| 132 |
+
else:
|
| 133 |
+
def write_unicode(file, text):
|
| 134 |
+
# Write a byte or unicode string to file. Unicode strings are encoded to
|
| 135 |
+
# ENCODING encoding with 'backslashreplace' error handler to avoid
|
| 136 |
+
# UnicodeEncodeError.
|
| 137 |
+
if isinstance(text, unicode):
|
| 138 |
+
text = text.encode(ENCODING, 'backslashreplace')
|
| 139 |
+
file.write(text)
|
| 140 |
+
|
| 141 |
+
try:
|
| 142 |
+
os_fsencode = os.fsencode
|
| 143 |
+
except AttributeError:
|
| 144 |
+
def os_fsencode(filename):
|
| 145 |
+
if not isinstance(filename, unicode):
|
| 146 |
+
return filename
|
| 147 |
+
encoding = sys.getfilesystemencoding()
|
| 148 |
+
if encoding == 'mbcs':
|
| 149 |
+
# mbcs doesn't support surrogateescape
|
| 150 |
+
return filename.encode(encoding)
|
| 151 |
+
encoded = []
|
| 152 |
+
for char in filename:
|
| 153 |
+
# surrogateescape error handler
|
| 154 |
+
if 0xDC80 <= ord(char) <= 0xDCFF:
|
| 155 |
+
byte = chr(ord(char) - 0xDC00)
|
| 156 |
+
else:
|
| 157 |
+
byte = char.encode(encoding)
|
| 158 |
+
encoded.append(byte)
|
| 159 |
+
return ''.join(encoded)
|
| 160 |
+
|
| 161 |
+
class StringTruncated(RuntimeError):
|
| 162 |
+
pass
|
| 163 |
+
|
| 164 |
+
class TruncatedStringIO(object):
|
| 165 |
+
'''Similar to io.StringIO, but can truncate the output by raising a
|
| 166 |
+
StringTruncated exception'''
|
| 167 |
+
def __init__(self, maxlen=None):
|
| 168 |
+
self._val = ''
|
| 169 |
+
self.maxlen = maxlen
|
| 170 |
+
|
| 171 |
+
def write(self, data):
|
| 172 |
+
if self.maxlen:
|
| 173 |
+
if len(data) + len(self._val) > self.maxlen:
|
| 174 |
+
# Truncation:
|
| 175 |
+
self._val += data[0:self.maxlen - len(self._val)]
|
| 176 |
+
raise StringTruncated()
|
| 177 |
+
|
| 178 |
+
self._val += data
|
| 179 |
+
|
| 180 |
+
def getvalue(self):
|
| 181 |
+
return self._val
|
| 182 |
+
|
| 183 |
+
class PyObjectPtr(object):
|
| 184 |
+
"""
|
| 185 |
+
Class wrapping a gdb.Value that's either a (PyObject*) within the
|
| 186 |
+
inferior process, or some subclass pointer e.g. (PyBytesObject*)
|
| 187 |
+
|
| 188 |
+
There will be a subclass for every refined PyObject type that we care
|
| 189 |
+
about.
|
| 190 |
+
|
| 191 |
+
Note that at every stage the underlying pointer could be NULL, point
|
| 192 |
+
to corrupt data, etc; this is the debugger, after all.
|
| 193 |
+
"""
|
| 194 |
+
_typename = 'PyObject'
|
| 195 |
+
|
| 196 |
+
def __init__(self, gdbval, cast_to=None):
|
| 197 |
+
if cast_to:
|
| 198 |
+
self._gdbval = gdbval.cast(cast_to)
|
| 199 |
+
else:
|
| 200 |
+
self._gdbval = gdbval
|
| 201 |
+
|
| 202 |
+
def field(self, name):
|
| 203 |
+
'''
|
| 204 |
+
Get the gdb.Value for the given field within the PyObject, coping with
|
| 205 |
+
some python 2 versus python 3 differences.
|
| 206 |
+
|
| 207 |
+
Various libpython types are defined using the "PyObject_HEAD" and
|
| 208 |
+
"PyObject_VAR_HEAD" macros.
|
| 209 |
+
|
| 210 |
+
In Python 2, this these are defined so that "ob_type" and (for a var
|
| 211 |
+
object) "ob_size" are fields of the type in question.
|
| 212 |
+
|
| 213 |
+
In Python 3, this is defined as an embedded PyVarObject type thus:
|
| 214 |
+
PyVarObject ob_base;
|
| 215 |
+
so that the "ob_size" field is located insize the "ob_base" field, and
|
| 216 |
+
the "ob_type" is most easily accessed by casting back to a (PyObject*).
|
| 217 |
+
'''
|
| 218 |
+
if self.is_null():
|
| 219 |
+
raise NullPyObjectPtr(self)
|
| 220 |
+
|
| 221 |
+
if name == 'ob_type':
|
| 222 |
+
pyo_ptr = self._gdbval.cast(PyObjectPtr.get_gdb_type())
|
| 223 |
+
return pyo_ptr.dereference()[name]
|
| 224 |
+
|
| 225 |
+
if name == 'ob_size':
|
| 226 |
+
pyo_ptr = self._gdbval.cast(PyVarObjectPtr.get_gdb_type())
|
| 227 |
+
return pyo_ptr.dereference()[name]
|
| 228 |
+
|
| 229 |
+
# General case: look it up inside the object:
|
| 230 |
+
return self._gdbval.dereference()[name]
|
| 231 |
+
|
| 232 |
+
def pyop_field(self, name):
|
| 233 |
+
'''
|
| 234 |
+
Get a PyObjectPtr for the given PyObject* field within this PyObject,
|
| 235 |
+
coping with some python 2 versus python 3 differences.
|
| 236 |
+
'''
|
| 237 |
+
return PyObjectPtr.from_pyobject_ptr(self.field(name))
|
| 238 |
+
|
| 239 |
+
def write_field_repr(self, name, out, visited):
|
| 240 |
+
'''
|
| 241 |
+
Extract the PyObject* field named "name", and write its representation
|
| 242 |
+
to file-like object "out"
|
| 243 |
+
'''
|
| 244 |
+
field_obj = self.pyop_field(name)
|
| 245 |
+
field_obj.write_repr(out, visited)
|
| 246 |
+
|
| 247 |
+
def get_truncated_repr(self, maxlen):
|
| 248 |
+
'''
|
| 249 |
+
Get a repr-like string for the data, but truncate it at "maxlen" bytes
|
| 250 |
+
(ending the object graph traversal as soon as you do)
|
| 251 |
+
'''
|
| 252 |
+
out = TruncatedStringIO(maxlen)
|
| 253 |
+
try:
|
| 254 |
+
self.write_repr(out, set())
|
| 255 |
+
except StringTruncated:
|
| 256 |
+
# Truncation occurred:
|
| 257 |
+
return out.getvalue() + '...(truncated)'
|
| 258 |
+
|
| 259 |
+
# No truncation occurred:
|
| 260 |
+
return out.getvalue()
|
| 261 |
+
|
| 262 |
+
def type(self):
|
| 263 |
+
return PyTypeObjectPtr(self.field('ob_type'))
|
| 264 |
+
|
| 265 |
+
def is_null(self):
|
| 266 |
+
return 0 == long(self._gdbval)
|
| 267 |
+
|
| 268 |
+
def is_optimized_out(self):
|
| 269 |
+
'''
|
| 270 |
+
Is the value of the underlying PyObject* visible to the debugger?
|
| 271 |
+
|
| 272 |
+
This can vary with the precise version of the compiler used to build
|
| 273 |
+
Python, and the precise version of gdb.
|
| 274 |
+
|
| 275 |
+
See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with
|
| 276 |
+
PyEval_EvalFrameEx's "f"
|
| 277 |
+
'''
|
| 278 |
+
return self._gdbval.is_optimized_out
|
| 279 |
+
|
| 280 |
+
def safe_tp_name(self):
|
| 281 |
+
try:
|
| 282 |
+
ob_type = self.type()
|
| 283 |
+
tp_name = ob_type.field('tp_name')
|
| 284 |
+
return tp_name.string()
|
| 285 |
+
# NullPyObjectPtr: NULL tp_name?
|
| 286 |
+
# RuntimeError: Can't even read the object at all?
|
| 287 |
+
# UnicodeDecodeError: Failed to decode tp_name bytestring
|
| 288 |
+
except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError):
|
| 289 |
+
return 'unknown'
|
| 290 |
+
|
| 291 |
+
def proxyval(self, visited):
|
| 292 |
+
'''
|
| 293 |
+
Scrape a value from the inferior process, and try to represent it
|
| 294 |
+
within the gdb process, whilst (hopefully) avoiding crashes when
|
| 295 |
+
the remote data is corrupt.
|
| 296 |
+
|
| 297 |
+
Derived classes will override this.
|
| 298 |
+
|
| 299 |
+
For example, a PyIntObject* with ob_ival 42 in the inferior process
|
| 300 |
+
should result in an int(42) in this process.
|
| 301 |
+
|
| 302 |
+
visited: a set of all gdb.Value pyobject pointers already visited
|
| 303 |
+
whilst generating this value (to guard against infinite recursion when
|
| 304 |
+
visiting object graphs with loops). Analogous to Py_ReprEnter and
|
| 305 |
+
Py_ReprLeave
|
| 306 |
+
'''
|
| 307 |
+
|
| 308 |
+
class FakeRepr(object):
|
| 309 |
+
"""
|
| 310 |
+
Class representing a non-descript PyObject* value in the inferior
|
| 311 |
+
process for when we don't have a custom scraper, intended to have
|
| 312 |
+
a sane repr().
|
| 313 |
+
"""
|
| 314 |
+
|
| 315 |
+
def __init__(self, tp_name, address):
|
| 316 |
+
self.tp_name = tp_name
|
| 317 |
+
self.address = address
|
| 318 |
+
|
| 319 |
+
def __repr__(self):
|
| 320 |
+
# For the NULL pointer, we have no way of knowing a type, so
|
| 321 |
+
# special-case it as per
|
| 322 |
+
# http://bugs.python.org/issue8032#msg100882
|
| 323 |
+
if self.address == 0:
|
| 324 |
+
return '0x0'
|
| 325 |
+
return '<%s at remote 0x%x>' % (self.tp_name, self.address)
|
| 326 |
+
|
| 327 |
+
return FakeRepr(self.safe_tp_name(),
|
| 328 |
+
long(self._gdbval))
|
| 329 |
+
|
| 330 |
+
def write_repr(self, out, visited):
|
| 331 |
+
'''
|
| 332 |
+
Write a string representation of the value scraped from the inferior
|
| 333 |
+
process to "out", a file-like object.
|
| 334 |
+
'''
|
| 335 |
+
# Default implementation: generate a proxy value and write its repr
|
| 336 |
+
# However, this could involve a lot of work for complicated objects,
|
| 337 |
+
# so for derived classes we specialize this
|
| 338 |
+
return out.write(repr(self.proxyval(visited)))
|
| 339 |
+
|
| 340 |
+
@classmethod
|
| 341 |
+
def subclass_from_type(cls, t):
|
| 342 |
+
'''
|
| 343 |
+
Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a
|
| 344 |
+
(PyTypeObject*), determine the corresponding subclass of PyObjectPtr
|
| 345 |
+
to use
|
| 346 |
+
|
| 347 |
+
Ideally, we would look up the symbols for the global types, but that
|
| 348 |
+
isn't working yet:
|
| 349 |
+
(gdb) python print gdb.lookup_symbol('PyList_Type')[0].value
|
| 350 |
+
Traceback (most recent call last):
|
| 351 |
+
File "<string>", line 1, in <module>
|
| 352 |
+
NotImplementedError: Symbol type not yet supported in Python scripts.
|
| 353 |
+
Error while executing Python code.
|
| 354 |
+
|
| 355 |
+
For now, we use tp_flags, after doing some string comparisons on the
|
| 356 |
+
tp_name for some special-cases that don't seem to be visible through
|
| 357 |
+
flags
|
| 358 |
+
'''
|
| 359 |
+
try:
|
| 360 |
+
tp_name = t.field('tp_name').string()
|
| 361 |
+
tp_flags = int(t.field('tp_flags'))
|
| 362 |
+
# RuntimeError: NULL pointers
|
| 363 |
+
# UnicodeDecodeError: string() fails to decode the bytestring
|
| 364 |
+
except (RuntimeError, UnicodeDecodeError):
|
| 365 |
+
# Handle any kind of error e.g. NULL ptrs by simply using the base
|
| 366 |
+
# class
|
| 367 |
+
return cls
|
| 368 |
+
|
| 369 |
+
#print('tp_flags = 0x%08x' % tp_flags)
|
| 370 |
+
#print('tp_name = %r' % tp_name)
|
| 371 |
+
|
| 372 |
+
name_map = {'bool': PyBoolObjectPtr,
|
| 373 |
+
'classobj': PyClassObjectPtr,
|
| 374 |
+
'NoneType': PyNoneStructPtr,
|
| 375 |
+
'frame': PyFrameObjectPtr,
|
| 376 |
+
'set' : PySetObjectPtr,
|
| 377 |
+
'frozenset' : PySetObjectPtr,
|
| 378 |
+
'builtin_function_or_method' : PyCFunctionObjectPtr,
|
| 379 |
+
'method-wrapper': wrapperobject,
|
| 380 |
+
}
|
| 381 |
+
if tp_name in name_map:
|
| 382 |
+
return name_map[tp_name]
|
| 383 |
+
|
| 384 |
+
if tp_flags & Py_TPFLAGS_HEAPTYPE:
|
| 385 |
+
return HeapTypeObjectPtr
|
| 386 |
+
|
| 387 |
+
if tp_flags & Py_TPFLAGS_LONG_SUBCLASS:
|
| 388 |
+
return PyLongObjectPtr
|
| 389 |
+
if tp_flags & Py_TPFLAGS_LIST_SUBCLASS:
|
| 390 |
+
return PyListObjectPtr
|
| 391 |
+
if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS:
|
| 392 |
+
return PyTupleObjectPtr
|
| 393 |
+
if tp_flags & Py_TPFLAGS_BYTES_SUBCLASS:
|
| 394 |
+
return PyBytesObjectPtr
|
| 395 |
+
if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS:
|
| 396 |
+
return PyUnicodeObjectPtr
|
| 397 |
+
if tp_flags & Py_TPFLAGS_DICT_SUBCLASS:
|
| 398 |
+
return PyDictObjectPtr
|
| 399 |
+
if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS:
|
| 400 |
+
return PyBaseExceptionObjectPtr
|
| 401 |
+
#if tp_flags & Py_TPFLAGS_TYPE_SUBCLASS:
|
| 402 |
+
# return PyTypeObjectPtr
|
| 403 |
+
|
| 404 |
+
# Use the base class:
|
| 405 |
+
return cls
|
| 406 |
+
|
| 407 |
+
@classmethod
|
| 408 |
+
def from_pyobject_ptr(cls, gdbval):
|
| 409 |
+
'''
|
| 410 |
+
Try to locate the appropriate derived class dynamically, and cast
|
| 411 |
+
the pointer accordingly.
|
| 412 |
+
'''
|
| 413 |
+
try:
|
| 414 |
+
p = PyObjectPtr(gdbval)
|
| 415 |
+
cls = cls.subclass_from_type(p.type())
|
| 416 |
+
return cls(gdbval, cast_to=cls.get_gdb_type())
|
| 417 |
+
except RuntimeError:
|
| 418 |
+
# Handle any kind of error e.g. NULL ptrs by simply using the base
|
| 419 |
+
# class
|
| 420 |
+
pass
|
| 421 |
+
return cls(gdbval)
|
| 422 |
+
|
| 423 |
+
@classmethod
|
| 424 |
+
def get_gdb_type(cls):
|
| 425 |
+
return gdb.lookup_type(cls._typename).pointer()
|
| 426 |
+
|
| 427 |
+
def as_address(self):
|
| 428 |
+
return long(self._gdbval)
|
| 429 |
+
|
| 430 |
+
class PyVarObjectPtr(PyObjectPtr):
|
| 431 |
+
_typename = 'PyVarObject'
|
| 432 |
+
|
| 433 |
+
class ProxyAlreadyVisited(object):
|
| 434 |
+
'''
|
| 435 |
+
Placeholder proxy to use when protecting against infinite recursion due to
|
| 436 |
+
loops in the object graph.
|
| 437 |
+
|
| 438 |
+
Analogous to the values emitted by the users of Py_ReprEnter and Py_ReprLeave
|
| 439 |
+
'''
|
| 440 |
+
def __init__(self, rep):
|
| 441 |
+
self._rep = rep
|
| 442 |
+
|
| 443 |
+
def __repr__(self):
|
| 444 |
+
return self._rep
|
| 445 |
+
|
| 446 |
+
|
| 447 |
+
def _write_instance_repr(out, visited, name, pyop_attrdict, address):
|
| 448 |
+
'''Shared code for use by all classes:
|
| 449 |
+
write a representation to file-like object "out"'''
|
| 450 |
+
out.write('<')
|
| 451 |
+
out.write(name)
|
| 452 |
+
|
| 453 |
+
# Write dictionary of instance attributes:
|
| 454 |
+
if isinstance(pyop_attrdict, PyDictObjectPtr):
|
| 455 |
+
out.write('(')
|
| 456 |
+
first = True
|
| 457 |
+
for pyop_arg, pyop_val in pyop_attrdict.iteritems():
|
| 458 |
+
if not first:
|
| 459 |
+
out.write(', ')
|
| 460 |
+
first = False
|
| 461 |
+
out.write(pyop_arg.proxyval(visited))
|
| 462 |
+
out.write('=')
|
| 463 |
+
pyop_val.write_repr(out, visited)
|
| 464 |
+
out.write(')')
|
| 465 |
+
out.write(' at remote 0x%x>' % address)
|
| 466 |
+
|
| 467 |
+
|
| 468 |
+
class InstanceProxy(object):
|
| 469 |
+
|
| 470 |
+
def __init__(self, cl_name, attrdict, address):
|
| 471 |
+
self.cl_name = cl_name
|
| 472 |
+
self.attrdict = attrdict
|
| 473 |
+
self.address = address
|
| 474 |
+
|
| 475 |
+
def __repr__(self):
|
| 476 |
+
if isinstance(self.attrdict, dict):
|
| 477 |
+
kwargs = ', '.join(["%s=%r" % (arg, val)
|
| 478 |
+
for arg, val in self.attrdict.iteritems()])
|
| 479 |
+
return '<%s(%s) at remote 0x%x>' % (self.cl_name,
|
| 480 |
+
kwargs, self.address)
|
| 481 |
+
else:
|
| 482 |
+
return '<%s at remote 0x%x>' % (self.cl_name,
|
| 483 |
+
self.address)
|
| 484 |
+
|
| 485 |
+
def _PyObject_VAR_SIZE(typeobj, nitems):
|
| 486 |
+
if _PyObject_VAR_SIZE._type_size_t is None:
|
| 487 |
+
_PyObject_VAR_SIZE._type_size_t = gdb.lookup_type('size_t')
|
| 488 |
+
|
| 489 |
+
return ( ( typeobj.field('tp_basicsize') +
|
| 490 |
+
nitems * typeobj.field('tp_itemsize') +
|
| 491 |
+
(_sizeof_void_p() - 1)
|
| 492 |
+
) & ~(_sizeof_void_p() - 1)
|
| 493 |
+
).cast(_PyObject_VAR_SIZE._type_size_t)
|
| 494 |
+
_PyObject_VAR_SIZE._type_size_t = None
|
| 495 |
+
|
| 496 |
+
class HeapTypeObjectPtr(PyObjectPtr):
|
| 497 |
+
_typename = 'PyObject'
|
| 498 |
+
|
| 499 |
+
def get_attr_dict(self):
|
| 500 |
+
'''
|
| 501 |
+
Get the PyDictObject ptr representing the attribute dictionary
|
| 502 |
+
(or None if there's a problem)
|
| 503 |
+
'''
|
| 504 |
+
try:
|
| 505 |
+
typeobj = self.type()
|
| 506 |
+
dictoffset = int_from_int(typeobj.field('tp_dictoffset'))
|
| 507 |
+
if dictoffset != 0:
|
| 508 |
+
if dictoffset < 0:
|
| 509 |
+
type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer()
|
| 510 |
+
tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size'])
|
| 511 |
+
if tsize < 0:
|
| 512 |
+
tsize = -tsize
|
| 513 |
+
size = _PyObject_VAR_SIZE(typeobj, tsize)
|
| 514 |
+
dictoffset += size
|
| 515 |
+
assert dictoffset > 0
|
| 516 |
+
assert dictoffset % _sizeof_void_p() == 0
|
| 517 |
+
|
| 518 |
+
dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset
|
| 519 |
+
PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer()
|
| 520 |
+
dictptr = dictptr.cast(PyObjectPtrPtr)
|
| 521 |
+
return PyObjectPtr.from_pyobject_ptr(dictptr.dereference())
|
| 522 |
+
except RuntimeError:
|
| 523 |
+
# Corrupt data somewhere; fail safe
|
| 524 |
+
pass
|
| 525 |
+
|
| 526 |
+
# Not found, or some kind of error:
|
| 527 |
+
return None
|
| 528 |
+
|
| 529 |
+
def proxyval(self, visited):
|
| 530 |
+
'''
|
| 531 |
+
Support for classes.
|
| 532 |
+
|
| 533 |
+
Currently we just locate the dictionary using a transliteration to
|
| 534 |
+
python of _PyObject_GetDictPtr, ignoring descriptors
|
| 535 |
+
'''
|
| 536 |
+
# Guard against infinite loops:
|
| 537 |
+
if self.as_address() in visited:
|
| 538 |
+
return ProxyAlreadyVisited('<...>')
|
| 539 |
+
visited.add(self.as_address())
|
| 540 |
+
|
| 541 |
+
pyop_attr_dict = self.get_attr_dict()
|
| 542 |
+
if pyop_attr_dict:
|
| 543 |
+
attr_dict = pyop_attr_dict.proxyval(visited)
|
| 544 |
+
else:
|
| 545 |
+
attr_dict = {}
|
| 546 |
+
tp_name = self.safe_tp_name()
|
| 547 |
+
|
| 548 |
+
# Class:
|
| 549 |
+
return InstanceProxy(tp_name, attr_dict, long(self._gdbval))
|
| 550 |
+
|
| 551 |
+
def write_repr(self, out, visited):
|
| 552 |
+
# Guard against infinite loops:
|
| 553 |
+
if self.as_address() in visited:
|
| 554 |
+
out.write('<...>')
|
| 555 |
+
return
|
| 556 |
+
visited.add(self.as_address())
|
| 557 |
+
|
| 558 |
+
pyop_attrdict = self.get_attr_dict()
|
| 559 |
+
_write_instance_repr(out, visited,
|
| 560 |
+
self.safe_tp_name(), pyop_attrdict, self.as_address())
|
| 561 |
+
|
| 562 |
+
class ProxyException(Exception):
|
| 563 |
+
def __init__(self, tp_name, args):
|
| 564 |
+
self.tp_name = tp_name
|
| 565 |
+
self.args = args
|
| 566 |
+
|
| 567 |
+
def __repr__(self):
|
| 568 |
+
return '%s%r' % (self.tp_name, self.args)
|
| 569 |
+
|
| 570 |
+
class PyBaseExceptionObjectPtr(PyObjectPtr):
|
| 571 |
+
"""
|
| 572 |
+
Class wrapping a gdb.Value that's a PyBaseExceptionObject* i.e. an exception
|
| 573 |
+
within the process being debugged.
|
| 574 |
+
"""
|
| 575 |
+
_typename = 'PyBaseExceptionObject'
|
| 576 |
+
|
| 577 |
+
def proxyval(self, visited):
|
| 578 |
+
# Guard against infinite loops:
|
| 579 |
+
if self.as_address() in visited:
|
| 580 |
+
return ProxyAlreadyVisited('(...)')
|
| 581 |
+
visited.add(self.as_address())
|
| 582 |
+
arg_proxy = self.pyop_field('args').proxyval(visited)
|
| 583 |
+
return ProxyException(self.safe_tp_name(),
|
| 584 |
+
arg_proxy)
|
| 585 |
+
|
| 586 |
+
def write_repr(self, out, visited):
|
| 587 |
+
# Guard against infinite loops:
|
| 588 |
+
if self.as_address() in visited:
|
| 589 |
+
out.write('(...)')
|
| 590 |
+
return
|
| 591 |
+
visited.add(self.as_address())
|
| 592 |
+
|
| 593 |
+
out.write(self.safe_tp_name())
|
| 594 |
+
self.write_field_repr('args', out, visited)
|
| 595 |
+
|
| 596 |
+
class PyClassObjectPtr(PyObjectPtr):
|
| 597 |
+
"""
|
| 598 |
+
Class wrapping a gdb.Value that's a PyClassObject* i.e. a <classobj>
|
| 599 |
+
instance within the process being debugged.
|
| 600 |
+
"""
|
| 601 |
+
_typename = 'PyClassObject'
|
| 602 |
+
|
| 603 |
+
|
| 604 |
+
class BuiltInFunctionProxy(object):
|
| 605 |
+
def __init__(self, ml_name):
|
| 606 |
+
self.ml_name = ml_name
|
| 607 |
+
|
| 608 |
+
def __repr__(self):
|
| 609 |
+
return "<built-in function %s>" % self.ml_name
|
| 610 |
+
|
| 611 |
+
class BuiltInMethodProxy(object):
|
| 612 |
+
def __init__(self, ml_name, pyop_m_self):
|
| 613 |
+
self.ml_name = ml_name
|
| 614 |
+
self.pyop_m_self = pyop_m_self
|
| 615 |
+
|
| 616 |
+
def __repr__(self):
|
| 617 |
+
return ('<built-in method %s of %s object at remote 0x%x>'
|
| 618 |
+
% (self.ml_name,
|
| 619 |
+
self.pyop_m_self.safe_tp_name(),
|
| 620 |
+
self.pyop_m_self.as_address())
|
| 621 |
+
)
|
| 622 |
+
|
| 623 |
+
class PyCFunctionObjectPtr(PyObjectPtr):
|
| 624 |
+
"""
|
| 625 |
+
Class wrapping a gdb.Value that's a PyCFunctionObject*
|
| 626 |
+
(see Include/methodobject.h and Objects/methodobject.c)
|
| 627 |
+
"""
|
| 628 |
+
_typename = 'PyCFunctionObject'
|
| 629 |
+
|
| 630 |
+
def proxyval(self, visited):
|
| 631 |
+
m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*)
|
| 632 |
+
try:
|
| 633 |
+
ml_name = m_ml['ml_name'].string()
|
| 634 |
+
except UnicodeDecodeError:
|
| 635 |
+
ml_name = '<ml_name:UnicodeDecodeError>'
|
| 636 |
+
|
| 637 |
+
pyop_m_self = self.pyop_field('m_self')
|
| 638 |
+
if pyop_m_self.is_null():
|
| 639 |
+
return BuiltInFunctionProxy(ml_name)
|
| 640 |
+
else:
|
| 641 |
+
return BuiltInMethodProxy(ml_name, pyop_m_self)
|
| 642 |
+
|
| 643 |
+
|
| 644 |
+
class PyCodeObjectPtr(PyObjectPtr):
|
| 645 |
+
"""
|
| 646 |
+
Class wrapping a gdb.Value that's a PyCodeObject* i.e. a <code> instance
|
| 647 |
+
within the process being debugged.
|
| 648 |
+
"""
|
| 649 |
+
_typename = 'PyCodeObject'
|
| 650 |
+
|
| 651 |
+
def addr2line(self, addrq):
|
| 652 |
+
'''
|
| 653 |
+
Get the line number for a given bytecode offset
|
| 654 |
+
|
| 655 |
+
Analogous to PyCode_Addr2Line; translated from pseudocode in
|
| 656 |
+
Objects/lnotab_notes.txt
|
| 657 |
+
'''
|
| 658 |
+
co_lnotab = self.pyop_field('co_lnotab').proxyval(set())
|
| 659 |
+
|
| 660 |
+
# Initialize lineno to co_firstlineno as per PyCode_Addr2Line
|
| 661 |
+
# not 0, as lnotab_notes.txt has it:
|
| 662 |
+
lineno = int_from_int(self.field('co_firstlineno'))
|
| 663 |
+
|
| 664 |
+
addr = 0
|
| 665 |
+
for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]):
|
| 666 |
+
addr += ord(addr_incr)
|
| 667 |
+
if addr > addrq:
|
| 668 |
+
return lineno
|
| 669 |
+
lineno += ord(line_incr)
|
| 670 |
+
return lineno
|
| 671 |
+
|
| 672 |
+
|
| 673 |
+
class PyDictObjectPtr(PyObjectPtr):
|
| 674 |
+
"""
|
| 675 |
+
Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance
|
| 676 |
+
within the process being debugged.
|
| 677 |
+
"""
|
| 678 |
+
_typename = 'PyDictObject'
|
| 679 |
+
|
| 680 |
+
def iteritems(self):
|
| 681 |
+
'''
|
| 682 |
+
Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs,
|
| 683 |
+
analogous to dict.iteritems()
|
| 684 |
+
'''
|
| 685 |
+
keys = self.field('ma_keys')
|
| 686 |
+
values = self.field('ma_values')
|
| 687 |
+
entries, nentries = self._get_entries(keys)
|
| 688 |
+
for i in safe_range(nentries):
|
| 689 |
+
ep = entries[i]
|
| 690 |
+
if long(values):
|
| 691 |
+
pyop_value = PyObjectPtr.from_pyobject_ptr(values[i])
|
| 692 |
+
else:
|
| 693 |
+
pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value'])
|
| 694 |
+
if not pyop_value.is_null():
|
| 695 |
+
pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key'])
|
| 696 |
+
yield (pyop_key, pyop_value)
|
| 697 |
+
|
| 698 |
+
def proxyval(self, visited):
|
| 699 |
+
# Guard against infinite loops:
|
| 700 |
+
if self.as_address() in visited:
|
| 701 |
+
return ProxyAlreadyVisited('{...}')
|
| 702 |
+
visited.add(self.as_address())
|
| 703 |
+
|
| 704 |
+
result = {}
|
| 705 |
+
for pyop_key, pyop_value in self.iteritems():
|
| 706 |
+
proxy_key = pyop_key.proxyval(visited)
|
| 707 |
+
proxy_value = pyop_value.proxyval(visited)
|
| 708 |
+
result[proxy_key] = proxy_value
|
| 709 |
+
return result
|
| 710 |
+
|
| 711 |
+
def write_repr(self, out, visited):
|
| 712 |
+
# Guard against infinite loops:
|
| 713 |
+
if self.as_address() in visited:
|
| 714 |
+
out.write('{...}')
|
| 715 |
+
return
|
| 716 |
+
visited.add(self.as_address())
|
| 717 |
+
|
| 718 |
+
out.write('{')
|
| 719 |
+
first = True
|
| 720 |
+
for pyop_key, pyop_value in self.iteritems():
|
| 721 |
+
if not first:
|
| 722 |
+
out.write(', ')
|
| 723 |
+
first = False
|
| 724 |
+
pyop_key.write_repr(out, visited)
|
| 725 |
+
out.write(': ')
|
| 726 |
+
pyop_value.write_repr(out, visited)
|
| 727 |
+
out.write('}')
|
| 728 |
+
|
| 729 |
+
def _get_entries(self, keys):
|
| 730 |
+
dk_nentries = int(keys['dk_nentries'])
|
| 731 |
+
dk_size = int(keys['dk_size'])
|
| 732 |
+
try:
|
| 733 |
+
# <= Python 3.5
|
| 734 |
+
return keys['dk_entries'], dk_size
|
| 735 |
+
except RuntimeError:
|
| 736 |
+
# >= Python 3.6
|
| 737 |
+
pass
|
| 738 |
+
|
| 739 |
+
if dk_size <= 0xFF:
|
| 740 |
+
offset = dk_size
|
| 741 |
+
elif dk_size <= 0xFFFF:
|
| 742 |
+
offset = 2 * dk_size
|
| 743 |
+
elif dk_size <= 0xFFFFFFFF:
|
| 744 |
+
offset = 4 * dk_size
|
| 745 |
+
else:
|
| 746 |
+
offset = 8 * dk_size
|
| 747 |
+
|
| 748 |
+
ent_addr = keys['dk_indices'].address
|
| 749 |
+
ent_addr = ent_addr.cast(_type_unsigned_char_ptr()) + offset
|
| 750 |
+
ent_ptr_t = gdb.lookup_type('PyDictKeyEntry').pointer()
|
| 751 |
+
ent_addr = ent_addr.cast(ent_ptr_t)
|
| 752 |
+
|
| 753 |
+
return ent_addr, dk_nentries
|
| 754 |
+
|
| 755 |
+
|
| 756 |
+
class PyListObjectPtr(PyObjectPtr):
|
| 757 |
+
_typename = 'PyListObject'
|
| 758 |
+
|
| 759 |
+
def __getitem__(self, i):
|
| 760 |
+
# Get the gdb.Value for the (PyObject*) with the given index:
|
| 761 |
+
field_ob_item = self.field('ob_item')
|
| 762 |
+
return field_ob_item[i]
|
| 763 |
+
|
| 764 |
+
def proxyval(self, visited):
|
| 765 |
+
# Guard against infinite loops:
|
| 766 |
+
if self.as_address() in visited:
|
| 767 |
+
return ProxyAlreadyVisited('[...]')
|
| 768 |
+
visited.add(self.as_address())
|
| 769 |
+
|
| 770 |
+
result = [PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
|
| 771 |
+
for i in safe_range(int_from_int(self.field('ob_size')))]
|
| 772 |
+
return result
|
| 773 |
+
|
| 774 |
+
def write_repr(self, out, visited):
|
| 775 |
+
# Guard against infinite loops:
|
| 776 |
+
if self.as_address() in visited:
|
| 777 |
+
out.write('[...]')
|
| 778 |
+
return
|
| 779 |
+
visited.add(self.as_address())
|
| 780 |
+
|
| 781 |
+
out.write('[')
|
| 782 |
+
for i in safe_range(int_from_int(self.field('ob_size'))):
|
| 783 |
+
if i > 0:
|
| 784 |
+
out.write(', ')
|
| 785 |
+
element = PyObjectPtr.from_pyobject_ptr(self[i])
|
| 786 |
+
element.write_repr(out, visited)
|
| 787 |
+
out.write(']')
|
| 788 |
+
|
| 789 |
+
class PyLongObjectPtr(PyObjectPtr):
|
| 790 |
+
_typename = 'PyLongObject'
|
| 791 |
+
|
| 792 |
+
def proxyval(self, visited):
|
| 793 |
+
'''
|
| 794 |
+
Python's Include/longobjrep.h has this declaration:
|
| 795 |
+
struct _longobject {
|
| 796 |
+
PyObject_VAR_HEAD
|
| 797 |
+
digit ob_digit[1];
|
| 798 |
+
};
|
| 799 |
+
|
| 800 |
+
with this description:
|
| 801 |
+
The absolute value of a number is equal to
|
| 802 |
+
SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
|
| 803 |
+
Negative numbers are represented with ob_size < 0;
|
| 804 |
+
zero is represented by ob_size == 0.
|
| 805 |
+
|
| 806 |
+
where SHIFT can be either:
|
| 807 |
+
#define PyLong_SHIFT 30
|
| 808 |
+
#define PyLong_SHIFT 15
|
| 809 |
+
'''
|
| 810 |
+
ob_size = long(self.field('ob_size'))
|
| 811 |
+
if ob_size == 0:
|
| 812 |
+
return 0
|
| 813 |
+
|
| 814 |
+
ob_digit = self.field('ob_digit')
|
| 815 |
+
|
| 816 |
+
if gdb.lookup_type('digit').sizeof == 2:
|
| 817 |
+
SHIFT = 15
|
| 818 |
+
else:
|
| 819 |
+
SHIFT = 30
|
| 820 |
+
|
| 821 |
+
digits = [long(ob_digit[i]) * 2**(SHIFT*i)
|
| 822 |
+
for i in safe_range(abs(ob_size))]
|
| 823 |
+
result = sum(digits)
|
| 824 |
+
if ob_size < 0:
|
| 825 |
+
result = -result
|
| 826 |
+
return result
|
| 827 |
+
|
| 828 |
+
def write_repr(self, out, visited):
|
| 829 |
+
# Write this out as a Python 3 int literal, i.e. without the "L" suffix
|
| 830 |
+
proxy = self.proxyval(visited)
|
| 831 |
+
out.write("%s" % proxy)
|
| 832 |
+
|
| 833 |
+
|
| 834 |
+
class PyBoolObjectPtr(PyLongObjectPtr):
|
| 835 |
+
"""
|
| 836 |
+
Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two
|
| 837 |
+
<bool> instances (Py_True/Py_False) within the process being debugged.
|
| 838 |
+
"""
|
| 839 |
+
def proxyval(self, visited):
|
| 840 |
+
if PyLongObjectPtr.proxyval(self, visited):
|
| 841 |
+
return True
|
| 842 |
+
else:
|
| 843 |
+
return False
|
| 844 |
+
|
| 845 |
+
class PyNoneStructPtr(PyObjectPtr):
|
| 846 |
+
"""
|
| 847 |
+
Class wrapping a gdb.Value that's a PyObject* pointing to the
|
| 848 |
+
singleton (we hope) _Py_NoneStruct with ob_type PyNone_Type
|
| 849 |
+
"""
|
| 850 |
+
_typename = 'PyObject'
|
| 851 |
+
|
| 852 |
+
def proxyval(self, visited):
|
| 853 |
+
return None
|
| 854 |
+
|
| 855 |
+
|
| 856 |
+
class PyFrameObjectPtr(PyObjectPtr):
|
| 857 |
+
_typename = 'PyFrameObject'
|
| 858 |
+
|
| 859 |
+
def __init__(self, gdbval, cast_to=None):
|
| 860 |
+
PyObjectPtr.__init__(self, gdbval, cast_to)
|
| 861 |
+
|
| 862 |
+
if not self.is_optimized_out():
|
| 863 |
+
self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code'))
|
| 864 |
+
self.co_name = self.co.pyop_field('co_name')
|
| 865 |
+
self.co_filename = self.co.pyop_field('co_filename')
|
| 866 |
+
|
| 867 |
+
self.f_lineno = int_from_int(self.field('f_lineno'))
|
| 868 |
+
self.f_lasti = int_from_int(self.field('f_lasti'))
|
| 869 |
+
self.co_nlocals = int_from_int(self.co.field('co_nlocals'))
|
| 870 |
+
self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames'))
|
| 871 |
+
|
| 872 |
+
def iter_locals(self):
|
| 873 |
+
'''
|
| 874 |
+
Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
|
| 875 |
+
the local variables of this frame
|
| 876 |
+
'''
|
| 877 |
+
if self.is_optimized_out():
|
| 878 |
+
return
|
| 879 |
+
|
| 880 |
+
f_localsplus = self.field('f_localsplus')
|
| 881 |
+
for i in safe_range(self.co_nlocals):
|
| 882 |
+
pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i])
|
| 883 |
+
if not pyop_value.is_null():
|
| 884 |
+
pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i])
|
| 885 |
+
yield (pyop_name, pyop_value)
|
| 886 |
+
|
| 887 |
+
def iter_globals(self):
|
| 888 |
+
'''
|
| 889 |
+
Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
|
| 890 |
+
the global variables of this frame
|
| 891 |
+
'''
|
| 892 |
+
if self.is_optimized_out():
|
| 893 |
+
return ()
|
| 894 |
+
|
| 895 |
+
pyop_globals = self.pyop_field('f_globals')
|
| 896 |
+
return pyop_globals.iteritems()
|
| 897 |
+
|
| 898 |
+
def iter_builtins(self):
|
| 899 |
+
'''
|
| 900 |
+
Yield a sequence of (name,value) pairs of PyObjectPtr instances, for
|
| 901 |
+
the builtin variables
|
| 902 |
+
'''
|
| 903 |
+
if self.is_optimized_out():
|
| 904 |
+
return ()
|
| 905 |
+
|
| 906 |
+
pyop_builtins = self.pyop_field('f_builtins')
|
| 907 |
+
return pyop_builtins.iteritems()
|
| 908 |
+
|
| 909 |
+
def get_var_by_name(self, name):
|
| 910 |
+
'''
|
| 911 |
+
Look for the named local variable, returning a (PyObjectPtr, scope) pair
|
| 912 |
+
where scope is a string 'local', 'global', 'builtin'
|
| 913 |
+
|
| 914 |
+
If not found, return (None, None)
|
| 915 |
+
'''
|
| 916 |
+
for pyop_name, pyop_value in self.iter_locals():
|
| 917 |
+
if name == pyop_name.proxyval(set()):
|
| 918 |
+
return pyop_value, 'local'
|
| 919 |
+
for pyop_name, pyop_value in self.iter_globals():
|
| 920 |
+
if name == pyop_name.proxyval(set()):
|
| 921 |
+
return pyop_value, 'global'
|
| 922 |
+
for pyop_name, pyop_value in self.iter_builtins():
|
| 923 |
+
if name == pyop_name.proxyval(set()):
|
| 924 |
+
return pyop_value, 'builtin'
|
| 925 |
+
return None, None
|
| 926 |
+
|
| 927 |
+
def filename(self):
|
| 928 |
+
'''Get the path of the current Python source file, as a string'''
|
| 929 |
+
if self.is_optimized_out():
|
| 930 |
+
return FRAME_INFO_OPTIMIZED_OUT
|
| 931 |
+
return self.co_filename.proxyval(set())
|
| 932 |
+
|
| 933 |
+
def current_line_num(self):
|
| 934 |
+
'''Get current line number as an integer (1-based)
|
| 935 |
+
|
| 936 |
+
Translated from PyFrame_GetLineNumber and PyCode_Addr2Line
|
| 937 |
+
|
| 938 |
+
See Objects/lnotab_notes.txt
|
| 939 |
+
'''
|
| 940 |
+
if self.is_optimized_out():
|
| 941 |
+
return None
|
| 942 |
+
f_trace = self.field('f_trace')
|
| 943 |
+
if long(f_trace) != 0:
|
| 944 |
+
# we have a non-NULL f_trace:
|
| 945 |
+
return self.f_lineno
|
| 946 |
+
|
| 947 |
+
try:
|
| 948 |
+
return self.co.addr2line(self.f_lasti)
|
| 949 |
+
except Exception:
|
| 950 |
+
# bpo-34989: addr2line() is a complex function, it can fail in many
|
| 951 |
+
# ways. For example, it fails with a TypeError on "FakeRepr" if
|
| 952 |
+
# gdb fails to load debug symbols. Use a catch-all "except
|
| 953 |
+
# Exception" to make the whole function safe. The caller has to
|
| 954 |
+
# handle None anyway for optimized Python.
|
| 955 |
+
return None
|
| 956 |
+
|
| 957 |
+
def current_line(self):
|
| 958 |
+
'''Get the text of the current source line as a string, with a trailing
|
| 959 |
+
newline character'''
|
| 960 |
+
if self.is_optimized_out():
|
| 961 |
+
return FRAME_INFO_OPTIMIZED_OUT
|
| 962 |
+
|
| 963 |
+
lineno = self.current_line_num()
|
| 964 |
+
if lineno is None:
|
| 965 |
+
return '(failed to get frame line number)'
|
| 966 |
+
|
| 967 |
+
filename = self.filename()
|
| 968 |
+
try:
|
| 969 |
+
with open(os_fsencode(filename), 'r') as fp:
|
| 970 |
+
lines = fp.readlines()
|
| 971 |
+
except IOError:
|
| 972 |
+
return None
|
| 973 |
+
|
| 974 |
+
try:
|
| 975 |
+
# Convert from 1-based current_line_num to 0-based list offset
|
| 976 |
+
return lines[lineno - 1]
|
| 977 |
+
except IndexError:
|
| 978 |
+
return None
|
| 979 |
+
|
| 980 |
+
def write_repr(self, out, visited):
|
| 981 |
+
if self.is_optimized_out():
|
| 982 |
+
out.write(FRAME_INFO_OPTIMIZED_OUT)
|
| 983 |
+
return
|
| 984 |
+
lineno = self.current_line_num()
|
| 985 |
+
lineno = str(lineno) if lineno is not None else "?"
|
| 986 |
+
out.write('Frame 0x%x, for file %s, line %s, in %s ('
|
| 987 |
+
% (self.as_address(),
|
| 988 |
+
self.co_filename.proxyval(visited),
|
| 989 |
+
lineno,
|
| 990 |
+
self.co_name.proxyval(visited)))
|
| 991 |
+
first = True
|
| 992 |
+
for pyop_name, pyop_value in self.iter_locals():
|
| 993 |
+
if not first:
|
| 994 |
+
out.write(', ')
|
| 995 |
+
first = False
|
| 996 |
+
|
| 997 |
+
out.write(pyop_name.proxyval(visited))
|
| 998 |
+
out.write('=')
|
| 999 |
+
pyop_value.write_repr(out, visited)
|
| 1000 |
+
|
| 1001 |
+
out.write(')')
|
| 1002 |
+
|
| 1003 |
+
def print_traceback(self):
|
| 1004 |
+
if self.is_optimized_out():
|
| 1005 |
+
sys.stdout.write(' %s\n' % FRAME_INFO_OPTIMIZED_OUT)
|
| 1006 |
+
return
|
| 1007 |
+
visited = set()
|
| 1008 |
+
lineno = self.current_line_num()
|
| 1009 |
+
lineno = str(lineno) if lineno is not None else "?"
|
| 1010 |
+
sys.stdout.write(' File "%s", line %s, in %s\n'
|
| 1011 |
+
% (self.co_filename.proxyval(visited),
|
| 1012 |
+
lineno,
|
| 1013 |
+
self.co_name.proxyval(visited)))
|
| 1014 |
+
|
| 1015 |
+
class PySetObjectPtr(PyObjectPtr):
|
| 1016 |
+
_typename = 'PySetObject'
|
| 1017 |
+
|
| 1018 |
+
@classmethod
|
| 1019 |
+
def _dummy_key(self):
|
| 1020 |
+
return gdb.lookup_global_symbol('_PySet_Dummy').value()
|
| 1021 |
+
|
| 1022 |
+
def __iter__(self):
|
| 1023 |
+
dummy_ptr = self._dummy_key()
|
| 1024 |
+
table = self.field('table')
|
| 1025 |
+
for i in safe_range(self.field('mask') + 1):
|
| 1026 |
+
setentry = table[i]
|
| 1027 |
+
key = setentry['key']
|
| 1028 |
+
if key != 0 and key != dummy_ptr:
|
| 1029 |
+
yield PyObjectPtr.from_pyobject_ptr(key)
|
| 1030 |
+
|
| 1031 |
+
def proxyval(self, visited):
|
| 1032 |
+
# Guard against infinite loops:
|
| 1033 |
+
if self.as_address() in visited:
|
| 1034 |
+
return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name())
|
| 1035 |
+
visited.add(self.as_address())
|
| 1036 |
+
|
| 1037 |
+
members = (key.proxyval(visited) for key in self)
|
| 1038 |
+
if self.safe_tp_name() == 'frozenset':
|
| 1039 |
+
return frozenset(members)
|
| 1040 |
+
else:
|
| 1041 |
+
return set(members)
|
| 1042 |
+
|
| 1043 |
+
def write_repr(self, out, visited):
|
| 1044 |
+
# Emulate Python 3's set_repr
|
| 1045 |
+
tp_name = self.safe_tp_name()
|
| 1046 |
+
|
| 1047 |
+
# Guard against infinite loops:
|
| 1048 |
+
if self.as_address() in visited:
|
| 1049 |
+
out.write('(...)')
|
| 1050 |
+
return
|
| 1051 |
+
visited.add(self.as_address())
|
| 1052 |
+
|
| 1053 |
+
# Python 3's set_repr special-cases the empty set:
|
| 1054 |
+
if not self.field('used'):
|
| 1055 |
+
out.write(tp_name)
|
| 1056 |
+
out.write('()')
|
| 1057 |
+
return
|
| 1058 |
+
|
| 1059 |
+
# Python 3 uses {} for set literals:
|
| 1060 |
+
if tp_name != 'set':
|
| 1061 |
+
out.write(tp_name)
|
| 1062 |
+
out.write('(')
|
| 1063 |
+
|
| 1064 |
+
out.write('{')
|
| 1065 |
+
first = True
|
| 1066 |
+
for key in self:
|
| 1067 |
+
if not first:
|
| 1068 |
+
out.write(', ')
|
| 1069 |
+
first = False
|
| 1070 |
+
key.write_repr(out, visited)
|
| 1071 |
+
out.write('}')
|
| 1072 |
+
|
| 1073 |
+
if tp_name != 'set':
|
| 1074 |
+
out.write(')')
|
| 1075 |
+
|
| 1076 |
+
|
| 1077 |
+
class PyBytesObjectPtr(PyObjectPtr):
|
| 1078 |
+
_typename = 'PyBytesObject'
|
| 1079 |
+
|
| 1080 |
+
def __str__(self):
|
| 1081 |
+
field_ob_size = self.field('ob_size')
|
| 1082 |
+
field_ob_sval = self.field('ob_sval')
|
| 1083 |
+
char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr())
|
| 1084 |
+
return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)])
|
| 1085 |
+
|
| 1086 |
+
def proxyval(self, visited):
|
| 1087 |
+
return str(self)
|
| 1088 |
+
|
| 1089 |
+
def write_repr(self, out, visited):
|
| 1090 |
+
# Write this out as a Python 3 bytes literal, i.e. with a "b" prefix
|
| 1091 |
+
|
| 1092 |
+
# Get a PyStringObject* within the Python 2 gdb process:
|
| 1093 |
+
proxy = self.proxyval(visited)
|
| 1094 |
+
|
| 1095 |
+
# Transliteration of Python 3's Objects/bytesobject.c:PyBytes_Repr
|
| 1096 |
+
# to Python 2 code:
|
| 1097 |
+
quote = "'"
|
| 1098 |
+
if "'" in proxy and not '"' in proxy:
|
| 1099 |
+
quote = '"'
|
| 1100 |
+
out.write('b')
|
| 1101 |
+
out.write(quote)
|
| 1102 |
+
for byte in proxy:
|
| 1103 |
+
if byte == quote or byte == '\\':
|
| 1104 |
+
out.write('\\')
|
| 1105 |
+
out.write(byte)
|
| 1106 |
+
elif byte == '\t':
|
| 1107 |
+
out.write('\\t')
|
| 1108 |
+
elif byte == '\n':
|
| 1109 |
+
out.write('\\n')
|
| 1110 |
+
elif byte == '\r':
|
| 1111 |
+
out.write('\\r')
|
| 1112 |
+
elif byte < ' ' or ord(byte) >= 0x7f:
|
| 1113 |
+
out.write('\\x')
|
| 1114 |
+
out.write(hexdigits[(ord(byte) & 0xf0) >> 4])
|
| 1115 |
+
out.write(hexdigits[ord(byte) & 0xf])
|
| 1116 |
+
else:
|
| 1117 |
+
out.write(byte)
|
| 1118 |
+
out.write(quote)
|
| 1119 |
+
|
| 1120 |
+
class PyTupleObjectPtr(PyObjectPtr):
|
| 1121 |
+
_typename = 'PyTupleObject'
|
| 1122 |
+
|
| 1123 |
+
def __getitem__(self, i):
|
| 1124 |
+
# Get the gdb.Value for the (PyObject*) with the given index:
|
| 1125 |
+
field_ob_item = self.field('ob_item')
|
| 1126 |
+
return field_ob_item[i]
|
| 1127 |
+
|
| 1128 |
+
def proxyval(self, visited):
|
| 1129 |
+
# Guard against infinite loops:
|
| 1130 |
+
if self.as_address() in visited:
|
| 1131 |
+
return ProxyAlreadyVisited('(...)')
|
| 1132 |
+
visited.add(self.as_address())
|
| 1133 |
+
|
| 1134 |
+
result = tuple(PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited)
|
| 1135 |
+
for i in safe_range(int_from_int(self.field('ob_size'))))
|
| 1136 |
+
return result
|
| 1137 |
+
|
| 1138 |
+
def write_repr(self, out, visited):
|
| 1139 |
+
# Guard against infinite loops:
|
| 1140 |
+
if self.as_address() in visited:
|
| 1141 |
+
out.write('(...)')
|
| 1142 |
+
return
|
| 1143 |
+
visited.add(self.as_address())
|
| 1144 |
+
|
| 1145 |
+
out.write('(')
|
| 1146 |
+
for i in safe_range(int_from_int(self.field('ob_size'))):
|
| 1147 |
+
if i > 0:
|
| 1148 |
+
out.write(', ')
|
| 1149 |
+
element = PyObjectPtr.from_pyobject_ptr(self[i])
|
| 1150 |
+
element.write_repr(out, visited)
|
| 1151 |
+
if self.field('ob_size') == 1:
|
| 1152 |
+
out.write(',)')
|
| 1153 |
+
else:
|
| 1154 |
+
out.write(')')
|
| 1155 |
+
|
| 1156 |
+
class PyTypeObjectPtr(PyObjectPtr):
|
| 1157 |
+
_typename = 'PyTypeObject'
|
| 1158 |
+
|
| 1159 |
+
|
| 1160 |
+
def _unichr_is_printable(char):
|
| 1161 |
+
# Logic adapted from Python 3's Tools/unicode/makeunicodedata.py
|
| 1162 |
+
if char == u" ":
|
| 1163 |
+
return True
|
| 1164 |
+
import unicodedata
|
| 1165 |
+
return unicodedata.category(char) not in ("C", "Z")
|
| 1166 |
+
|
| 1167 |
+
if sys.maxunicode >= 0x10000:
|
| 1168 |
+
_unichr = unichr
|
| 1169 |
+
else:
|
| 1170 |
+
# Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb
|
| 1171 |
+
def _unichr(x):
|
| 1172 |
+
if x < 0x10000:
|
| 1173 |
+
return unichr(x)
|
| 1174 |
+
x -= 0x10000
|
| 1175 |
+
ch1 = 0xD800 | (x >> 10)
|
| 1176 |
+
ch2 = 0xDC00 | (x & 0x3FF)
|
| 1177 |
+
return unichr(ch1) + unichr(ch2)
|
| 1178 |
+
|
| 1179 |
+
|
| 1180 |
+
class PyUnicodeObjectPtr(PyObjectPtr):
|
| 1181 |
+
_typename = 'PyUnicodeObject'
|
| 1182 |
+
|
| 1183 |
+
def char_width(self):
|
| 1184 |
+
_type_Py_UNICODE = gdb.lookup_type('Py_UNICODE')
|
| 1185 |
+
return _type_Py_UNICODE.sizeof
|
| 1186 |
+
|
| 1187 |
+
def proxyval(self, visited):
|
| 1188 |
+
global _is_pep393
|
| 1189 |
+
if _is_pep393 is None:
|
| 1190 |
+
fields = gdb.lookup_type('PyUnicodeObject').fields()
|
| 1191 |
+
_is_pep393 = 'data' in [f.name for f in fields]
|
| 1192 |
+
if _is_pep393:
|
| 1193 |
+
# Python 3.3 and newer
|
| 1194 |
+
may_have_surrogates = False
|
| 1195 |
+
compact = self.field('_base')
|
| 1196 |
+
ascii = compact['_base']
|
| 1197 |
+
state = ascii['state']
|
| 1198 |
+
is_compact_ascii = (int(state['ascii']) and int(state['compact']))
|
| 1199 |
+
if not int(state['ready']):
|
| 1200 |
+
# string is not ready
|
| 1201 |
+
field_length = long(compact['wstr_length'])
|
| 1202 |
+
may_have_surrogates = True
|
| 1203 |
+
field_str = ascii['wstr']
|
| 1204 |
+
else:
|
| 1205 |
+
field_length = long(ascii['length'])
|
| 1206 |
+
if is_compact_ascii:
|
| 1207 |
+
field_str = ascii.address + 1
|
| 1208 |
+
elif int(state['compact']):
|
| 1209 |
+
field_str = compact.address + 1
|
| 1210 |
+
else:
|
| 1211 |
+
field_str = self.field('data')['any']
|
| 1212 |
+
repr_kind = int(state['kind'])
|
| 1213 |
+
if repr_kind == 1:
|
| 1214 |
+
field_str = field_str.cast(_type_unsigned_char_ptr())
|
| 1215 |
+
elif repr_kind == 2:
|
| 1216 |
+
field_str = field_str.cast(_type_unsigned_short_ptr())
|
| 1217 |
+
elif repr_kind == 4:
|
| 1218 |
+
field_str = field_str.cast(_type_unsigned_int_ptr())
|
| 1219 |
+
else:
|
| 1220 |
+
# Python 3.2 and earlier
|
| 1221 |
+
field_length = long(self.field('length'))
|
| 1222 |
+
field_str = self.field('str')
|
| 1223 |
+
may_have_surrogates = self.char_width() == 2
|
| 1224 |
+
|
| 1225 |
+
# Gather a list of ints from the Py_UNICODE array; these are either
|
| 1226 |
+
# UCS-1, UCS-2 or UCS-4 code points:
|
| 1227 |
+
if not may_have_surrogates:
|
| 1228 |
+
Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
|
| 1229 |
+
else:
|
| 1230 |
+
# A more elaborate routine if sizeof(Py_UNICODE) is 2 in the
|
| 1231 |
+
# inferior process: we must join surrogate pairs.
|
| 1232 |
+
Py_UNICODEs = []
|
| 1233 |
+
i = 0
|
| 1234 |
+
limit = safety_limit(field_length)
|
| 1235 |
+
while i < limit:
|
| 1236 |
+
ucs = int(field_str[i])
|
| 1237 |
+
i += 1
|
| 1238 |
+
if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
|
| 1239 |
+
Py_UNICODEs.append(ucs)
|
| 1240 |
+
continue
|
| 1241 |
+
# This could be a surrogate pair.
|
| 1242 |
+
ucs2 = int(field_str[i])
|
| 1243 |
+
if ucs2 < 0xDC00 or ucs2 > 0xDFFF:
|
| 1244 |
+
continue
|
| 1245 |
+
code = (ucs & 0x03FF) << 10
|
| 1246 |
+
code |= ucs2 & 0x03FF
|
| 1247 |
+
code += 0x00010000
|
| 1248 |
+
Py_UNICODEs.append(code)
|
| 1249 |
+
i += 1
|
| 1250 |
+
|
| 1251 |
+
# Convert the int code points to unicode characters, and generate a
|
| 1252 |
+
# local unicode instance.
|
| 1253 |
+
# This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb).
|
| 1254 |
+
result = u''.join([
|
| 1255 |
+
(_unichr(ucs) if ucs <= 0x10ffff else '\ufffd')
|
| 1256 |
+
for ucs in Py_UNICODEs])
|
| 1257 |
+
return result
|
| 1258 |
+
|
| 1259 |
+
def write_repr(self, out, visited):
|
| 1260 |
+
# Write this out as a Python 3 str literal, i.e. without a "u" prefix
|
| 1261 |
+
|
| 1262 |
+
# Get a PyUnicodeObject* within the Python 2 gdb process:
|
| 1263 |
+
proxy = self.proxyval(visited)
|
| 1264 |
+
|
| 1265 |
+
# Transliteration of Python 3's Object/unicodeobject.c:unicode_repr
|
| 1266 |
+
# to Python 2:
|
| 1267 |
+
if "'" in proxy and '"' not in proxy:
|
| 1268 |
+
quote = '"'
|
| 1269 |
+
else:
|
| 1270 |
+
quote = "'"
|
| 1271 |
+
out.write(quote)
|
| 1272 |
+
|
| 1273 |
+
i = 0
|
| 1274 |
+
while i < len(proxy):
|
| 1275 |
+
ch = proxy[i]
|
| 1276 |
+
i += 1
|
| 1277 |
+
|
| 1278 |
+
# Escape quotes and backslashes
|
| 1279 |
+
if ch == quote or ch == '\\':
|
| 1280 |
+
out.write('\\')
|
| 1281 |
+
out.write(ch)
|
| 1282 |
+
|
| 1283 |
+
# Map special whitespace to '\t', \n', '\r'
|
| 1284 |
+
elif ch == '\t':
|
| 1285 |
+
out.write('\\t')
|
| 1286 |
+
elif ch == '\n':
|
| 1287 |
+
out.write('\\n')
|
| 1288 |
+
elif ch == '\r':
|
| 1289 |
+
out.write('\\r')
|
| 1290 |
+
|
| 1291 |
+
# Map non-printable US ASCII to '\xhh' */
|
| 1292 |
+
elif ch < ' ' or ch == 0x7F:
|
| 1293 |
+
out.write('\\x')
|
| 1294 |
+
out.write(hexdigits[(ord(ch) >> 4) & 0x000F])
|
| 1295 |
+
out.write(hexdigits[ord(ch) & 0x000F])
|
| 1296 |
+
|
| 1297 |
+
# Copy ASCII characters as-is
|
| 1298 |
+
elif ord(ch) < 0x7F:
|
| 1299 |
+
out.write(ch)
|
| 1300 |
+
|
| 1301 |
+
# Non-ASCII characters
|
| 1302 |
+
else:
|
| 1303 |
+
ucs = ch
|
| 1304 |
+
ch2 = None
|
| 1305 |
+
if sys.maxunicode < 0x10000:
|
| 1306 |
+
# If sizeof(Py_UNICODE) is 2 here (in gdb), join
|
| 1307 |
+
# surrogate pairs before calling _unichr_is_printable.
|
| 1308 |
+
if (i < len(proxy)
|
| 1309 |
+
and 0xD800 <= ord(ch) < 0xDC00
|
| 1310 |
+
and 0xDC00 <= ord(proxy[i]) <= 0xDFFF):
|
| 1311 |
+
ch2 = proxy[i]
|
| 1312 |
+
ucs = ch + ch2
|
| 1313 |
+
i += 1
|
| 1314 |
+
|
| 1315 |
+
# Unfortunately, Python 2's unicode type doesn't seem
|
| 1316 |
+
# to expose the "isprintable" method
|
| 1317 |
+
printable = _unichr_is_printable(ucs)
|
| 1318 |
+
if printable:
|
| 1319 |
+
try:
|
| 1320 |
+
ucs.encode(ENCODING)
|
| 1321 |
+
except UnicodeEncodeError:
|
| 1322 |
+
printable = False
|
| 1323 |
+
|
| 1324 |
+
# Map Unicode whitespace and control characters
|
| 1325 |
+
# (categories Z* and C* except ASCII space)
|
| 1326 |
+
if not printable:
|
| 1327 |
+
if ch2 is not None:
|
| 1328 |
+
# Match Python 3's representation of non-printable
|
| 1329 |
+
# wide characters.
|
| 1330 |
+
code = (ord(ch) & 0x03FF) << 10
|
| 1331 |
+
code |= ord(ch2) & 0x03FF
|
| 1332 |
+
code += 0x00010000
|
| 1333 |
+
else:
|
| 1334 |
+
code = ord(ucs)
|
| 1335 |
+
|
| 1336 |
+
# Map 8-bit characters to '\\xhh'
|
| 1337 |
+
if code <= 0xff:
|
| 1338 |
+
out.write('\\x')
|
| 1339 |
+
out.write(hexdigits[(code >> 4) & 0x000F])
|
| 1340 |
+
out.write(hexdigits[code & 0x000F])
|
| 1341 |
+
# Map 21-bit characters to '\U00xxxxxx'
|
| 1342 |
+
elif code >= 0x10000:
|
| 1343 |
+
out.write('\\U')
|
| 1344 |
+
out.write(hexdigits[(code >> 28) & 0x0000000F])
|
| 1345 |
+
out.write(hexdigits[(code >> 24) & 0x0000000F])
|
| 1346 |
+
out.write(hexdigits[(code >> 20) & 0x0000000F])
|
| 1347 |
+
out.write(hexdigits[(code >> 16) & 0x0000000F])
|
| 1348 |
+
out.write(hexdigits[(code >> 12) & 0x0000000F])
|
| 1349 |
+
out.write(hexdigits[(code >> 8) & 0x0000000F])
|
| 1350 |
+
out.write(hexdigits[(code >> 4) & 0x0000000F])
|
| 1351 |
+
out.write(hexdigits[code & 0x0000000F])
|
| 1352 |
+
# Map 16-bit characters to '\uxxxx'
|
| 1353 |
+
else:
|
| 1354 |
+
out.write('\\u')
|
| 1355 |
+
out.write(hexdigits[(code >> 12) & 0x000F])
|
| 1356 |
+
out.write(hexdigits[(code >> 8) & 0x000F])
|
| 1357 |
+
out.write(hexdigits[(code >> 4) & 0x000F])
|
| 1358 |
+
out.write(hexdigits[code & 0x000F])
|
| 1359 |
+
else:
|
| 1360 |
+
# Copy characters as-is
|
| 1361 |
+
out.write(ch)
|
| 1362 |
+
if ch2 is not None:
|
| 1363 |
+
out.write(ch2)
|
| 1364 |
+
|
| 1365 |
+
out.write(quote)
|
| 1366 |
+
|
| 1367 |
+
|
| 1368 |
+
class wrapperobject(PyObjectPtr):
|
| 1369 |
+
_typename = 'wrapperobject'
|
| 1370 |
+
|
| 1371 |
+
def safe_name(self):
|
| 1372 |
+
try:
|
| 1373 |
+
name = self.field('descr')['d_base']['name'].string()
|
| 1374 |
+
return repr(name)
|
| 1375 |
+
except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError):
|
| 1376 |
+
return '<unknown name>'
|
| 1377 |
+
|
| 1378 |
+
def safe_tp_name(self):
|
| 1379 |
+
try:
|
| 1380 |
+
return self.field('self')['ob_type']['tp_name'].string()
|
| 1381 |
+
except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError):
|
| 1382 |
+
return '<unknown tp_name>'
|
| 1383 |
+
|
| 1384 |
+
def safe_self_addresss(self):
|
| 1385 |
+
try:
|
| 1386 |
+
address = long(self.field('self'))
|
| 1387 |
+
return '%#x' % address
|
| 1388 |
+
except (NullPyObjectPtr, RuntimeError):
|
| 1389 |
+
return '<failed to get self address>'
|
| 1390 |
+
|
| 1391 |
+
def proxyval(self, visited):
|
| 1392 |
+
name = self.safe_name()
|
| 1393 |
+
tp_name = self.safe_tp_name()
|
| 1394 |
+
self_address = self.safe_self_addresss()
|
| 1395 |
+
return ("<method-wrapper %s of %s object at %s>"
|
| 1396 |
+
% (name, tp_name, self_address))
|
| 1397 |
+
|
| 1398 |
+
def write_repr(self, out, visited):
|
| 1399 |
+
proxy = self.proxyval(visited)
|
| 1400 |
+
out.write(proxy)
|
| 1401 |
+
|
| 1402 |
+
|
| 1403 |
+
def int_from_int(gdbval):
|
| 1404 |
+
return int(gdbval)
|
| 1405 |
+
|
| 1406 |
+
|
| 1407 |
+
def stringify(val):
|
| 1408 |
+
# TODO: repr() puts everything on one line; pformat can be nicer, but
|
| 1409 |
+
# can lead to v.long results; this function isolates the choice
|
| 1410 |
+
if True:
|
| 1411 |
+
return repr(val)
|
| 1412 |
+
else:
|
| 1413 |
+
from pprint import pformat
|
| 1414 |
+
return pformat(val)
|
| 1415 |
+
|
| 1416 |
+
|
| 1417 |
+
class PyObjectPtrPrinter:
|
| 1418 |
+
"Prints a (PyObject*)"
|
| 1419 |
+
|
| 1420 |
+
def __init__ (self, gdbval):
|
| 1421 |
+
self.gdbval = gdbval
|
| 1422 |
+
|
| 1423 |
+
def to_string (self):
|
| 1424 |
+
pyop = PyObjectPtr.from_pyobject_ptr(self.gdbval)
|
| 1425 |
+
if True:
|
| 1426 |
+
return pyop.get_truncated_repr(MAX_OUTPUT_LEN)
|
| 1427 |
+
else:
|
| 1428 |
+
# Generate full proxy value then stringify it.
|
| 1429 |
+
# Doing so could be expensive
|
| 1430 |
+
proxyval = pyop.proxyval(set())
|
| 1431 |
+
return stringify(proxyval)
|
| 1432 |
+
|
| 1433 |
+
def pretty_printer_lookup(gdbval):
|
| 1434 |
+
type = gdbval.type.unqualified()
|
| 1435 |
+
if type.code != gdb.TYPE_CODE_PTR:
|
| 1436 |
+
return None
|
| 1437 |
+
|
| 1438 |
+
type = type.target().unqualified()
|
| 1439 |
+
t = str(type)
|
| 1440 |
+
if t in ("PyObject", "PyFrameObject", "PyUnicodeObject", "wrapperobject"):
|
| 1441 |
+
return PyObjectPtrPrinter(gdbval)
|
| 1442 |
+
|
| 1443 |
+
"""
|
| 1444 |
+
During development, I've been manually invoking the code in this way:
|
| 1445 |
+
(gdb) python
|
| 1446 |
+
|
| 1447 |
+
import sys
|
| 1448 |
+
sys.path.append('/home/david/coding/python-gdb')
|
| 1449 |
+
import libpython
|
| 1450 |
+
end
|
| 1451 |
+
|
| 1452 |
+
then reloading it after each edit like this:
|
| 1453 |
+
(gdb) python reload(libpython)
|
| 1454 |
+
|
| 1455 |
+
The following code should ensure that the prettyprinter is registered
|
| 1456 |
+
if the code is autoloaded by gdb when visiting libpython.so, provided
|
| 1457 |
+
that this python file is installed to the same path as the library (or its
|
| 1458 |
+
.debug file) plus a "-gdb.py" suffix, e.g:
|
| 1459 |
+
/usr/lib/libpython2.6.so.1.0-gdb.py
|
| 1460 |
+
/usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py
|
| 1461 |
+
"""
|
| 1462 |
+
def register (obj):
|
| 1463 |
+
if obj is None:
|
| 1464 |
+
obj = gdb
|
| 1465 |
+
|
| 1466 |
+
# Wire up the pretty-printer
|
| 1467 |
+
obj.pretty_printers.append(pretty_printer_lookup)
|
| 1468 |
+
|
| 1469 |
+
register (gdb.current_objfile ())
|
| 1470 |
+
|
| 1471 |
+
|
| 1472 |
+
|
| 1473 |
+
# Unfortunately, the exact API exposed by the gdb module varies somewhat
|
| 1474 |
+
# from build to build
|
| 1475 |
+
# See http://bugs.python.org/issue8279?#msg102276
|
| 1476 |
+
|
| 1477 |
+
class Frame(object):
|
| 1478 |
+
'''
|
| 1479 |
+
Wrapper for gdb.Frame, adding various methods
|
| 1480 |
+
'''
|
| 1481 |
+
def __init__(self, gdbframe):
|
| 1482 |
+
self._gdbframe = gdbframe
|
| 1483 |
+
|
| 1484 |
+
def older(self):
|
| 1485 |
+
older = self._gdbframe.older()
|
| 1486 |
+
if older:
|
| 1487 |
+
return Frame(older)
|
| 1488 |
+
else:
|
| 1489 |
+
return None
|
| 1490 |
+
|
| 1491 |
+
def newer(self):
|
| 1492 |
+
newer = self._gdbframe.newer()
|
| 1493 |
+
if newer:
|
| 1494 |
+
return Frame(newer)
|
| 1495 |
+
else:
|
| 1496 |
+
return None
|
| 1497 |
+
|
| 1498 |
+
def select(self):
|
| 1499 |
+
'''If supported, select this frame and return True; return False if unsupported
|
| 1500 |
+
|
| 1501 |
+
Not all builds have a gdb.Frame.select method; seems to be present on Fedora 12
|
| 1502 |
+
onwards, but absent on Ubuntu buildbot'''
|
| 1503 |
+
if not hasattr(self._gdbframe, 'select'):
|
| 1504 |
+
print ('Unable to select frame: '
|
| 1505 |
+
'this build of gdb does not expose a gdb.Frame.select method')
|
| 1506 |
+
return False
|
| 1507 |
+
self._gdbframe.select()
|
| 1508 |
+
return True
|
| 1509 |
+
|
| 1510 |
+
def get_index(self):
|
| 1511 |
+
'''Calculate index of frame, starting at 0 for the newest frame within
|
| 1512 |
+
this thread'''
|
| 1513 |
+
index = 0
|
| 1514 |
+
# Go down until you reach the newest frame:
|
| 1515 |
+
iter_frame = self
|
| 1516 |
+
while iter_frame.newer():
|
| 1517 |
+
index += 1
|
| 1518 |
+
iter_frame = iter_frame.newer()
|
| 1519 |
+
return index
|
| 1520 |
+
|
| 1521 |
+
# We divide frames into:
|
| 1522 |
+
# - "python frames":
|
| 1523 |
+
# - "bytecode frames" i.e. PyEval_EvalFrameEx
|
| 1524 |
+
# - "other python frames": things that are of interest from a python
|
| 1525 |
+
# POV, but aren't bytecode (e.g. GC, GIL)
|
| 1526 |
+
# - everything else
|
| 1527 |
+
|
| 1528 |
+
def is_python_frame(self):
|
| 1529 |
+
'''Is this a _PyEval_EvalFrameDefault frame, or some other important
|
| 1530 |
+
frame? (see is_other_python_frame for what "important" means in this
|
| 1531 |
+
context)'''
|
| 1532 |
+
if self.is_evalframe():
|
| 1533 |
+
return True
|
| 1534 |
+
if self.is_other_python_frame():
|
| 1535 |
+
return True
|
| 1536 |
+
return False
|
| 1537 |
+
|
| 1538 |
+
def is_evalframe(self):
|
| 1539 |
+
'''Is this a _PyEval_EvalFrameDefault frame?'''
|
| 1540 |
+
if self._gdbframe.name() == EVALFRAME:
|
| 1541 |
+
'''
|
| 1542 |
+
I believe we also need to filter on the inline
|
| 1543 |
+
struct frame_id.inline_depth, only regarding frames with
|
| 1544 |
+
an inline depth of 0 as actually being this function
|
| 1545 |
+
|
| 1546 |
+
So we reject those with type gdb.INLINE_FRAME
|
| 1547 |
+
'''
|
| 1548 |
+
if self._gdbframe.type() == gdb.NORMAL_FRAME:
|
| 1549 |
+
# We have a _PyEval_EvalFrameDefault frame:
|
| 1550 |
+
return True
|
| 1551 |
+
|
| 1552 |
+
return False
|
| 1553 |
+
|
| 1554 |
+
def is_other_python_frame(self):
|
| 1555 |
+
'''Is this frame worth displaying in python backtraces?
|
| 1556 |
+
Examples:
|
| 1557 |
+
- waiting on the GIL
|
| 1558 |
+
- garbage-collecting
|
| 1559 |
+
- within a CFunction
|
| 1560 |
+
If it is, return a descriptive string
|
| 1561 |
+
For other frames, return False
|
| 1562 |
+
'''
|
| 1563 |
+
if self.is_waiting_for_gil():
|
| 1564 |
+
return 'Waiting for the GIL'
|
| 1565 |
+
|
| 1566 |
+
if self.is_gc_collect():
|
| 1567 |
+
return 'Garbage-collecting'
|
| 1568 |
+
|
| 1569 |
+
# Detect invocations of PyCFunction instances:
|
| 1570 |
+
frame = self._gdbframe
|
| 1571 |
+
caller = frame.name()
|
| 1572 |
+
if not caller:
|
| 1573 |
+
return False
|
| 1574 |
+
|
| 1575 |
+
if (caller.startswith('cfunction_vectorcall_') or
|
| 1576 |
+
caller == 'cfunction_call'):
|
| 1577 |
+
arg_name = 'func'
|
| 1578 |
+
# Within that frame:
|
| 1579 |
+
# "func" is the local containing the PyObject* of the
|
| 1580 |
+
# PyCFunctionObject instance
|
| 1581 |
+
# "f" is the same value, but cast to (PyCFunctionObject*)
|
| 1582 |
+
# "self" is the (PyObject*) of the 'self'
|
| 1583 |
+
try:
|
| 1584 |
+
# Use the prettyprinter for the func:
|
| 1585 |
+
func = frame.read_var(arg_name)
|
| 1586 |
+
return str(func)
|
| 1587 |
+
except ValueError:
|
| 1588 |
+
return ('PyCFunction invocation (unable to read %s: '
|
| 1589 |
+
'missing debuginfos?)' % arg_name)
|
| 1590 |
+
except RuntimeError:
|
| 1591 |
+
return 'PyCFunction invocation (unable to read %s)' % arg_name
|
| 1592 |
+
|
| 1593 |
+
if caller == 'wrapper_call':
|
| 1594 |
+
arg_name = 'wp'
|
| 1595 |
+
try:
|
| 1596 |
+
func = frame.read_var(arg_name)
|
| 1597 |
+
return str(func)
|
| 1598 |
+
except ValueError:
|
| 1599 |
+
return ('<wrapper_call invocation (unable to read %s: '
|
| 1600 |
+
'missing debuginfos?)>' % arg_name)
|
| 1601 |
+
except RuntimeError:
|
| 1602 |
+
return '<wrapper_call invocation (unable to read %s)>' % arg_name
|
| 1603 |
+
|
| 1604 |
+
# This frame isn't worth reporting:
|
| 1605 |
+
return False
|
| 1606 |
+
|
| 1607 |
+
def is_waiting_for_gil(self):
|
| 1608 |
+
'''Is this frame waiting on the GIL?'''
|
| 1609 |
+
# This assumes the _POSIX_THREADS version of Python/ceval_gil.h:
|
| 1610 |
+
name = self._gdbframe.name()
|
| 1611 |
+
if name:
|
| 1612 |
+
return (name == 'take_gil')
|
| 1613 |
+
|
| 1614 |
+
def is_gc_collect(self):
|
| 1615 |
+
'''Is this frame "collect" within the garbage-collector?'''
|
| 1616 |
+
return self._gdbframe.name() == 'collect'
|
| 1617 |
+
|
| 1618 |
+
def get_pyop(self):
|
| 1619 |
+
try:
|
| 1620 |
+
f = self._gdbframe.read_var('f')
|
| 1621 |
+
frame = PyFrameObjectPtr.from_pyobject_ptr(f)
|
| 1622 |
+
if not frame.is_optimized_out():
|
| 1623 |
+
return frame
|
| 1624 |
+
# gdb is unable to get the "f" argument of PyEval_EvalFrameEx()
|
| 1625 |
+
# because it was "optimized out". Try to get "f" from the frame
|
| 1626 |
+
# of the caller, PyEval_EvalCodeEx().
|
| 1627 |
+
orig_frame = frame
|
| 1628 |
+
caller = self._gdbframe.older()
|
| 1629 |
+
if caller:
|
| 1630 |
+
f = caller.read_var('f')
|
| 1631 |
+
frame = PyFrameObjectPtr.from_pyobject_ptr(f)
|
| 1632 |
+
if not frame.is_optimized_out():
|
| 1633 |
+
return frame
|
| 1634 |
+
return orig_frame
|
| 1635 |
+
except ValueError:
|
| 1636 |
+
return None
|
| 1637 |
+
|
| 1638 |
+
@classmethod
|
| 1639 |
+
def get_selected_frame(cls):
|
| 1640 |
+
_gdbframe = gdb.selected_frame()
|
| 1641 |
+
if _gdbframe:
|
| 1642 |
+
return Frame(_gdbframe)
|
| 1643 |
+
return None
|
| 1644 |
+
|
| 1645 |
+
@classmethod
|
| 1646 |
+
def get_selected_python_frame(cls):
|
| 1647 |
+
'''Try to obtain the Frame for the python-related code in the selected
|
| 1648 |
+
frame, or None'''
|
| 1649 |
+
try:
|
| 1650 |
+
frame = cls.get_selected_frame()
|
| 1651 |
+
except gdb.error:
|
| 1652 |
+
# No frame: Python didn't start yet
|
| 1653 |
+
return None
|
| 1654 |
+
|
| 1655 |
+
while frame:
|
| 1656 |
+
if frame.is_python_frame():
|
| 1657 |
+
return frame
|
| 1658 |
+
frame = frame.older()
|
| 1659 |
+
|
| 1660 |
+
# Not found:
|
| 1661 |
+
return None
|
| 1662 |
+
|
| 1663 |
+
@classmethod
|
| 1664 |
+
def get_selected_bytecode_frame(cls):
|
| 1665 |
+
'''Try to obtain the Frame for the python bytecode interpreter in the
|
| 1666 |
+
selected GDB frame, or None'''
|
| 1667 |
+
frame = cls.get_selected_frame()
|
| 1668 |
+
|
| 1669 |
+
while frame:
|
| 1670 |
+
if frame.is_evalframe():
|
| 1671 |
+
return frame
|
| 1672 |
+
frame = frame.older()
|
| 1673 |
+
|
| 1674 |
+
# Not found:
|
| 1675 |
+
return None
|
| 1676 |
+
|
| 1677 |
+
def print_summary(self):
|
| 1678 |
+
if self.is_evalframe():
|
| 1679 |
+
pyop = self.get_pyop()
|
| 1680 |
+
if pyop:
|
| 1681 |
+
line = pyop.get_truncated_repr(MAX_OUTPUT_LEN)
|
| 1682 |
+
write_unicode(sys.stdout, '#%i %s\n' % (self.get_index(), line))
|
| 1683 |
+
if not pyop.is_optimized_out():
|
| 1684 |
+
line = pyop.current_line()
|
| 1685 |
+
if line is not None:
|
| 1686 |
+
sys.stdout.write(' %s\n' % line.strip())
|
| 1687 |
+
else:
|
| 1688 |
+
sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index())
|
| 1689 |
+
else:
|
| 1690 |
+
info = self.is_other_python_frame()
|
| 1691 |
+
if info:
|
| 1692 |
+
sys.stdout.write('#%i %s\n' % (self.get_index(), info))
|
| 1693 |
+
else:
|
| 1694 |
+
sys.stdout.write('#%i\n' % self.get_index())
|
| 1695 |
+
|
| 1696 |
+
def print_traceback(self):
|
| 1697 |
+
if self.is_evalframe():
|
| 1698 |
+
pyop = self.get_pyop()
|
| 1699 |
+
if pyop:
|
| 1700 |
+
pyop.print_traceback()
|
| 1701 |
+
if not pyop.is_optimized_out():
|
| 1702 |
+
line = pyop.current_line()
|
| 1703 |
+
if line is not None:
|
| 1704 |
+
sys.stdout.write(' %s\n' % line.strip())
|
| 1705 |
+
else:
|
| 1706 |
+
sys.stdout.write(' (unable to read python frame information)\n')
|
| 1707 |
+
else:
|
| 1708 |
+
info = self.is_other_python_frame()
|
| 1709 |
+
if info:
|
| 1710 |
+
sys.stdout.write(' %s\n' % info)
|
| 1711 |
+
else:
|
| 1712 |
+
sys.stdout.write(' (not a python frame)\n')
|
| 1713 |
+
|
| 1714 |
+
class PyList(gdb.Command):
|
| 1715 |
+
'''List the current Python source code, if any
|
| 1716 |
+
|
| 1717 |
+
Use
|
| 1718 |
+
py-list START
|
| 1719 |
+
to list at a different line number within the python source.
|
| 1720 |
+
|
| 1721 |
+
Use
|
| 1722 |
+
py-list START, END
|
| 1723 |
+
to list a specific range of lines within the python source.
|
| 1724 |
+
'''
|
| 1725 |
+
|
| 1726 |
+
def __init__(self):
|
| 1727 |
+
gdb.Command.__init__ (self,
|
| 1728 |
+
"py-list",
|
| 1729 |
+
gdb.COMMAND_FILES,
|
| 1730 |
+
gdb.COMPLETE_NONE)
|
| 1731 |
+
|
| 1732 |
+
|
| 1733 |
+
def invoke(self, args, from_tty):
|
| 1734 |
+
import re
|
| 1735 |
+
|
| 1736 |
+
start = None
|
| 1737 |
+
end = None
|
| 1738 |
+
|
| 1739 |
+
m = re.match(r'\s*(\d+)\s*', args)
|
| 1740 |
+
if m:
|
| 1741 |
+
start = int(m.group(0))
|
| 1742 |
+
end = start + 10
|
| 1743 |
+
|
| 1744 |
+
m = re.match(r'\s*(\d+)\s*,\s*(\d+)\s*', args)
|
| 1745 |
+
if m:
|
| 1746 |
+
start, end = map(int, m.groups())
|
| 1747 |
+
|
| 1748 |
+
# py-list requires an actual PyEval_EvalFrameEx frame:
|
| 1749 |
+
frame = Frame.get_selected_bytecode_frame()
|
| 1750 |
+
if not frame:
|
| 1751 |
+
print('Unable to locate gdb frame for python bytecode interpreter')
|
| 1752 |
+
return
|
| 1753 |
+
|
| 1754 |
+
pyop = frame.get_pyop()
|
| 1755 |
+
if not pyop or pyop.is_optimized_out():
|
| 1756 |
+
print(UNABLE_READ_INFO_PYTHON_FRAME)
|
| 1757 |
+
return
|
| 1758 |
+
|
| 1759 |
+
filename = pyop.filename()
|
| 1760 |
+
lineno = pyop.current_line_num()
|
| 1761 |
+
if lineno is None:
|
| 1762 |
+
print('Unable to read python frame line number')
|
| 1763 |
+
return
|
| 1764 |
+
|
| 1765 |
+
if start is None:
|
| 1766 |
+
start = lineno - 5
|
| 1767 |
+
end = lineno + 5
|
| 1768 |
+
|
| 1769 |
+
if start<1:
|
| 1770 |
+
start = 1
|
| 1771 |
+
|
| 1772 |
+
try:
|
| 1773 |
+
f = open(os_fsencode(filename), 'r')
|
| 1774 |
+
except IOError as err:
|
| 1775 |
+
sys.stdout.write('Unable to open %s: %s\n'
|
| 1776 |
+
% (filename, err))
|
| 1777 |
+
return
|
| 1778 |
+
with f:
|
| 1779 |
+
all_lines = f.readlines()
|
| 1780 |
+
# start and end are 1-based, all_lines is 0-based;
|
| 1781 |
+
# so [start-1:end] as a python slice gives us [start, end] as a
|
| 1782 |
+
# closed interval
|
| 1783 |
+
for i, line in enumerate(all_lines[start-1:end]):
|
| 1784 |
+
linestr = str(i+start)
|
| 1785 |
+
# Highlight current line:
|
| 1786 |
+
if i + start == lineno:
|
| 1787 |
+
linestr = '>' + linestr
|
| 1788 |
+
sys.stdout.write('%4s %s' % (linestr, line))
|
| 1789 |
+
|
| 1790 |
+
|
| 1791 |
+
# ...and register the command:
|
| 1792 |
+
PyList()
|
| 1793 |
+
|
| 1794 |
+
def move_in_stack(move_up):
|
| 1795 |
+
'''Move up or down the stack (for the py-up/py-down command)'''
|
| 1796 |
+
frame = Frame.get_selected_python_frame()
|
| 1797 |
+
if not frame:
|
| 1798 |
+
print('Unable to locate python frame')
|
| 1799 |
+
return
|
| 1800 |
+
|
| 1801 |
+
while frame:
|
| 1802 |
+
if move_up:
|
| 1803 |
+
iter_frame = frame.older()
|
| 1804 |
+
else:
|
| 1805 |
+
iter_frame = frame.newer()
|
| 1806 |
+
|
| 1807 |
+
if not iter_frame:
|
| 1808 |
+
break
|
| 1809 |
+
|
| 1810 |
+
if iter_frame.is_python_frame():
|
| 1811 |
+
# Result:
|
| 1812 |
+
if iter_frame.select():
|
| 1813 |
+
iter_frame.print_summary()
|
| 1814 |
+
return
|
| 1815 |
+
|
| 1816 |
+
frame = iter_frame
|
| 1817 |
+
|
| 1818 |
+
if move_up:
|
| 1819 |
+
print('Unable to find an older python frame')
|
| 1820 |
+
else:
|
| 1821 |
+
print('Unable to find a newer python frame')
|
| 1822 |
+
|
| 1823 |
+
class PyUp(gdb.Command):
|
| 1824 |
+
'Select and print the python stack frame that called this one (if any)'
|
| 1825 |
+
def __init__(self):
|
| 1826 |
+
gdb.Command.__init__ (self,
|
| 1827 |
+
"py-up",
|
| 1828 |
+
gdb.COMMAND_STACK,
|
| 1829 |
+
gdb.COMPLETE_NONE)
|
| 1830 |
+
|
| 1831 |
+
|
| 1832 |
+
def invoke(self, args, from_tty):
|
| 1833 |
+
move_in_stack(move_up=True)
|
| 1834 |
+
|
| 1835 |
+
class PyDown(gdb.Command):
|
| 1836 |
+
'Select and print the python stack frame called by this one (if any)'
|
| 1837 |
+
def __init__(self):
|
| 1838 |
+
gdb.Command.__init__ (self,
|
| 1839 |
+
"py-down",
|
| 1840 |
+
gdb.COMMAND_STACK,
|
| 1841 |
+
gdb.COMPLETE_NONE)
|
| 1842 |
+
|
| 1843 |
+
|
| 1844 |
+
def invoke(self, args, from_tty):
|
| 1845 |
+
move_in_stack(move_up=False)
|
| 1846 |
+
|
| 1847 |
+
# Not all builds of gdb have gdb.Frame.select
|
| 1848 |
+
if hasattr(gdb.Frame, 'select'):
|
| 1849 |
+
PyUp()
|
| 1850 |
+
PyDown()
|
| 1851 |
+
|
| 1852 |
+
class PyBacktraceFull(gdb.Command):
|
| 1853 |
+
'Display the current python frame and all the frames within its call stack (if any)'
|
| 1854 |
+
def __init__(self):
|
| 1855 |
+
gdb.Command.__init__ (self,
|
| 1856 |
+
"py-bt-full",
|
| 1857 |
+
gdb.COMMAND_STACK,
|
| 1858 |
+
gdb.COMPLETE_NONE)
|
| 1859 |
+
|
| 1860 |
+
|
| 1861 |
+
def invoke(self, args, from_tty):
|
| 1862 |
+
frame = Frame.get_selected_python_frame()
|
| 1863 |
+
if not frame:
|
| 1864 |
+
print('Unable to locate python frame')
|
| 1865 |
+
return
|
| 1866 |
+
|
| 1867 |
+
while frame:
|
| 1868 |
+
if frame.is_python_frame():
|
| 1869 |
+
frame.print_summary()
|
| 1870 |
+
frame = frame.older()
|
| 1871 |
+
|
| 1872 |
+
PyBacktraceFull()
|
| 1873 |
+
|
| 1874 |
+
class PyBacktrace(gdb.Command):
|
| 1875 |
+
'Display the current python frame and all the frames within its call stack (if any)'
|
| 1876 |
+
def __init__(self):
|
| 1877 |
+
gdb.Command.__init__ (self,
|
| 1878 |
+
"py-bt",
|
| 1879 |
+
gdb.COMMAND_STACK,
|
| 1880 |
+
gdb.COMPLETE_NONE)
|
| 1881 |
+
|
| 1882 |
+
|
| 1883 |
+
def invoke(self, args, from_tty):
|
| 1884 |
+
frame = Frame.get_selected_python_frame()
|
| 1885 |
+
if not frame:
|
| 1886 |
+
print('Unable to locate python frame')
|
| 1887 |
+
return
|
| 1888 |
+
|
| 1889 |
+
sys.stdout.write('Traceback (most recent call first):\n')
|
| 1890 |
+
while frame:
|
| 1891 |
+
if frame.is_python_frame():
|
| 1892 |
+
frame.print_traceback()
|
| 1893 |
+
frame = frame.older()
|
| 1894 |
+
|
| 1895 |
+
PyBacktrace()
|
| 1896 |
+
|
| 1897 |
+
class PyPrint(gdb.Command):
|
| 1898 |
+
'Look up the given python variable name, and print it'
|
| 1899 |
+
def __init__(self):
|
| 1900 |
+
gdb.Command.__init__ (self,
|
| 1901 |
+
"py-print",
|
| 1902 |
+
gdb.COMMAND_DATA,
|
| 1903 |
+
gdb.COMPLETE_NONE)
|
| 1904 |
+
|
| 1905 |
+
|
| 1906 |
+
def invoke(self, args, from_tty):
|
| 1907 |
+
name = str(args)
|
| 1908 |
+
|
| 1909 |
+
frame = Frame.get_selected_python_frame()
|
| 1910 |
+
if not frame:
|
| 1911 |
+
print('Unable to locate python frame')
|
| 1912 |
+
return
|
| 1913 |
+
|
| 1914 |
+
pyop_frame = frame.get_pyop()
|
| 1915 |
+
if not pyop_frame:
|
| 1916 |
+
print(UNABLE_READ_INFO_PYTHON_FRAME)
|
| 1917 |
+
return
|
| 1918 |
+
|
| 1919 |
+
pyop_var, scope = pyop_frame.get_var_by_name(name)
|
| 1920 |
+
|
| 1921 |
+
if pyop_var:
|
| 1922 |
+
print('%s %r = %s'
|
| 1923 |
+
% (scope,
|
| 1924 |
+
name,
|
| 1925 |
+
pyop_var.get_truncated_repr(MAX_OUTPUT_LEN)))
|
| 1926 |
+
else:
|
| 1927 |
+
print('%r not found' % name)
|
| 1928 |
+
|
| 1929 |
+
PyPrint()
|
| 1930 |
+
|
| 1931 |
+
class PyLocals(gdb.Command):
|
| 1932 |
+
'Look up the given python variable name, and print it'
|
| 1933 |
+
def __init__(self):
|
| 1934 |
+
gdb.Command.__init__ (self,
|
| 1935 |
+
"py-locals",
|
| 1936 |
+
gdb.COMMAND_DATA,
|
| 1937 |
+
gdb.COMPLETE_NONE)
|
| 1938 |
+
|
| 1939 |
+
|
| 1940 |
+
def invoke(self, args, from_tty):
|
| 1941 |
+
name = str(args)
|
| 1942 |
+
|
| 1943 |
+
frame = Frame.get_selected_python_frame()
|
| 1944 |
+
if not frame:
|
| 1945 |
+
print('Unable to locate python frame')
|
| 1946 |
+
return
|
| 1947 |
+
|
| 1948 |
+
pyop_frame = frame.get_pyop()
|
| 1949 |
+
if not pyop_frame:
|
| 1950 |
+
print(UNABLE_READ_INFO_PYTHON_FRAME)
|
| 1951 |
+
return
|
| 1952 |
+
|
| 1953 |
+
for pyop_name, pyop_value in pyop_frame.iter_locals():
|
| 1954 |
+
print('%s = %s' % (
|
| 1955 |
+
pyop_name.proxyval(set()),
|
| 1956 |
+
pyop_value.get_truncated_repr(MAX_OUTPUT_LEN),
|
| 1957 |
+
))
|
| 1958 |
+
|
| 1959 |
+
PyLocals()
|
| 1960 |
+
|
| 1961 |
+
|
| 1962 |
+
##################################################################
|
| 1963 |
+
## added, not in CPython
|
| 1964 |
+
##################################################################
|
| 1965 |
+
|
| 1966 |
+
import re
|
| 1967 |
+
import warnings
|
| 1968 |
+
import tempfile
|
| 1969 |
+
import functools
|
| 1970 |
+
import textwrap
|
| 1971 |
+
import itertools
|
| 1972 |
+
import traceback
|
| 1973 |
+
|
| 1974 |
+
|
| 1975 |
+
def dont_suppress_errors(function):
|
| 1976 |
+
"*sigh*, readline"
|
| 1977 |
+
@functools.wraps(function)
|
| 1978 |
+
def wrapper(*args, **kwargs):
|
| 1979 |
+
try:
|
| 1980 |
+
return function(*args, **kwargs)
|
| 1981 |
+
except Exception:
|
| 1982 |
+
traceback.print_exc()
|
| 1983 |
+
raise
|
| 1984 |
+
|
| 1985 |
+
return wrapper
|
| 1986 |
+
|
| 1987 |
+
class PyGlobals(gdb.Command):
|
| 1988 |
+
'List all the globals in the currently select Python frame'
|
| 1989 |
+
def __init__(self):
|
| 1990 |
+
gdb.Command.__init__ (self,
|
| 1991 |
+
"py-globals",
|
| 1992 |
+
gdb.COMMAND_DATA,
|
| 1993 |
+
gdb.COMPLETE_NONE)
|
| 1994 |
+
|
| 1995 |
+
@dont_suppress_errors
|
| 1996 |
+
def invoke(self, args, from_tty):
|
| 1997 |
+
name = str(args)
|
| 1998 |
+
|
| 1999 |
+
frame = Frame.get_selected_python_frame()
|
| 2000 |
+
if not frame:
|
| 2001 |
+
print('Unable to locate python frame')
|
| 2002 |
+
return
|
| 2003 |
+
|
| 2004 |
+
pyop_frame = frame.get_pyop()
|
| 2005 |
+
if not pyop_frame:
|
| 2006 |
+
print(UNABLE_READ_INFO_PYTHON_FRAME)
|
| 2007 |
+
return
|
| 2008 |
+
|
| 2009 |
+
for pyop_name, pyop_value in pyop_frame.iter_locals():
|
| 2010 |
+
print('%s = %s'
|
| 2011 |
+
% (pyop_name.proxyval(set()),
|
| 2012 |
+
pyop_value.get_truncated_repr(MAX_OUTPUT_LEN)))
|
| 2013 |
+
|
| 2014 |
+
def get_namespace(self, pyop_frame):
|
| 2015 |
+
return pyop_frame.iter_globals()
|
| 2016 |
+
|
| 2017 |
+
|
| 2018 |
+
PyGlobals()
|
| 2019 |
+
|
| 2020 |
+
# This function used to be a part of CPython's libpython.py (as a member function of frame).
|
| 2021 |
+
# It isn't anymore, so I copied it.
|
| 2022 |
+
def is_evalframeex(frame):
|
| 2023 |
+
'''Is this a PyEval_EvalFrameEx frame?'''
|
| 2024 |
+
if frame._gdbframe.name() == 'PyEval_EvalFrameEx':
|
| 2025 |
+
'''
|
| 2026 |
+
I believe we also need to filter on the inline
|
| 2027 |
+
struct frame_id.inline_depth, only regarding frames with
|
| 2028 |
+
an inline depth of 0 as actually being this function
|
| 2029 |
+
|
| 2030 |
+
So we reject those with type gdb.INLINE_FRAME
|
| 2031 |
+
'''
|
| 2032 |
+
if frame._gdbframe.type() == gdb.NORMAL_FRAME:
|
| 2033 |
+
# We have a PyEval_EvalFrameEx frame:
|
| 2034 |
+
return True
|
| 2035 |
+
|
| 2036 |
+
return False
|
| 2037 |
+
|
| 2038 |
+
class PyNameEquals(gdb.Function):
|
| 2039 |
+
|
| 2040 |
+
def _get_pycurframe_attr(self, attr):
|
| 2041 |
+
frame = Frame(gdb.selected_frame())
|
| 2042 |
+
if is_evalframeex(frame):
|
| 2043 |
+
pyframe = frame.get_pyop()
|
| 2044 |
+
if pyframe is None:
|
| 2045 |
+
warnings.warn("Use a Python debug build, Python breakpoints "
|
| 2046 |
+
"won't work otherwise.")
|
| 2047 |
+
return None
|
| 2048 |
+
|
| 2049 |
+
return getattr(pyframe, attr).proxyval(set())
|
| 2050 |
+
|
| 2051 |
+
return None
|
| 2052 |
+
|
| 2053 |
+
@dont_suppress_errors
|
| 2054 |
+
def invoke(self, funcname):
|
| 2055 |
+
attr = self._get_pycurframe_attr('co_name')
|
| 2056 |
+
return attr is not None and attr == funcname.string()
|
| 2057 |
+
|
| 2058 |
+
PyNameEquals("pyname_equals")
|
| 2059 |
+
|
| 2060 |
+
|
| 2061 |
+
class PyModEquals(PyNameEquals):
|
| 2062 |
+
|
| 2063 |
+
@dont_suppress_errors
|
| 2064 |
+
def invoke(self, modname):
|
| 2065 |
+
attr = self._get_pycurframe_attr('co_filename')
|
| 2066 |
+
if attr is not None:
|
| 2067 |
+
filename, ext = os.path.splitext(os.path.basename(attr))
|
| 2068 |
+
return filename == modname.string()
|
| 2069 |
+
return False
|
| 2070 |
+
|
| 2071 |
+
PyModEquals("pymod_equals")
|
| 2072 |
+
|
| 2073 |
+
|
| 2074 |
+
class PyBreak(gdb.Command):
|
| 2075 |
+
"""
|
| 2076 |
+
Set a Python breakpoint. Examples:
|
| 2077 |
+
|
| 2078 |
+
Break on any function or method named 'func' in module 'modname'
|
| 2079 |
+
|
| 2080 |
+
py-break modname.func
|
| 2081 |
+
|
| 2082 |
+
Break on any function or method named 'func'
|
| 2083 |
+
|
| 2084 |
+
py-break func
|
| 2085 |
+
"""
|
| 2086 |
+
|
| 2087 |
+
@dont_suppress_errors
|
| 2088 |
+
def invoke(self, funcname, from_tty):
|
| 2089 |
+
if '.' in funcname:
|
| 2090 |
+
modname, dot, funcname = funcname.rpartition('.')
|
| 2091 |
+
cond = '$pyname_equals("%s") && $pymod_equals("%s")' % (funcname,
|
| 2092 |
+
modname)
|
| 2093 |
+
else:
|
| 2094 |
+
cond = '$pyname_equals("%s")' % funcname
|
| 2095 |
+
|
| 2096 |
+
gdb.execute('break PyEval_EvalFrameEx if ' + cond)
|
| 2097 |
+
|
| 2098 |
+
PyBreak("py-break", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE)
|
| 2099 |
+
|
| 2100 |
+
|
| 2101 |
+
class _LoggingState(object):
|
| 2102 |
+
"""
|
| 2103 |
+
State that helps to provide a reentrant gdb.execute() function.
|
| 2104 |
+
"""
|
| 2105 |
+
|
| 2106 |
+
def __init__(self):
|
| 2107 |
+
f = tempfile.NamedTemporaryFile('r+')
|
| 2108 |
+
self.file = f
|
| 2109 |
+
self.filename = f.name
|
| 2110 |
+
self.fd = f.fileno()
|
| 2111 |
+
_execute("set logging file %s" % self.filename)
|
| 2112 |
+
self.file_position_stack = []
|
| 2113 |
+
|
| 2114 |
+
def __enter__(self):
|
| 2115 |
+
if not self.file_position_stack:
|
| 2116 |
+
_execute("set logging redirect on")
|
| 2117 |
+
_execute("set logging on")
|
| 2118 |
+
_execute("set pagination off")
|
| 2119 |
+
|
| 2120 |
+
self.file_position_stack.append(os.fstat(self.fd).st_size)
|
| 2121 |
+
return self
|
| 2122 |
+
|
| 2123 |
+
def getoutput(self):
|
| 2124 |
+
gdb.flush()
|
| 2125 |
+
self.file.seek(self.file_position_stack[-1])
|
| 2126 |
+
result = self.file.read()
|
| 2127 |
+
return result
|
| 2128 |
+
|
| 2129 |
+
def __exit__(self, exc_type, exc_val, tb):
|
| 2130 |
+
startpos = self.file_position_stack.pop()
|
| 2131 |
+
self.file.seek(startpos)
|
| 2132 |
+
self.file.truncate()
|
| 2133 |
+
if not self.file_position_stack:
|
| 2134 |
+
_execute("set logging off")
|
| 2135 |
+
_execute("set logging redirect off")
|
| 2136 |
+
_execute("set pagination on")
|
| 2137 |
+
|
| 2138 |
+
|
| 2139 |
+
def execute(command, from_tty=False, to_string=False):
|
| 2140 |
+
"""
|
| 2141 |
+
Replace gdb.execute() with this function and have it accept a 'to_string'
|
| 2142 |
+
argument (new in 7.2). Have it properly capture stderr also. Ensure
|
| 2143 |
+
reentrancy.
|
| 2144 |
+
"""
|
| 2145 |
+
if to_string:
|
| 2146 |
+
with _logging_state as state:
|
| 2147 |
+
_execute(command, from_tty)
|
| 2148 |
+
return state.getoutput()
|
| 2149 |
+
else:
|
| 2150 |
+
_execute(command, from_tty)
|
| 2151 |
+
|
| 2152 |
+
|
| 2153 |
+
_execute = gdb.execute
|
| 2154 |
+
gdb.execute = execute
|
| 2155 |
+
_logging_state = _LoggingState()
|
| 2156 |
+
|
| 2157 |
+
|
| 2158 |
+
def get_selected_inferior():
|
| 2159 |
+
"""
|
| 2160 |
+
Return the selected inferior in gdb.
|
| 2161 |
+
"""
|
| 2162 |
+
# Woooh, another bug in gdb! Is there an end in sight?
|
| 2163 |
+
# http://sourceware.org/bugzilla/show_bug.cgi?id=12212
|
| 2164 |
+
return gdb.inferiors()[0]
|
| 2165 |
+
|
| 2166 |
+
selected_thread = gdb.selected_thread()
|
| 2167 |
+
|
| 2168 |
+
for inferior in gdb.inferiors():
|
| 2169 |
+
for thread in inferior.threads():
|
| 2170 |
+
if thread == selected_thread:
|
| 2171 |
+
return inferior
|
| 2172 |
+
|
| 2173 |
+
|
| 2174 |
+
def source_gdb_script(script_contents, to_string=False):
|
| 2175 |
+
"""
|
| 2176 |
+
Source a gdb script with script_contents passed as a string. This is useful
|
| 2177 |
+
to provide defines for py-step and py-next to make them repeatable (this is
|
| 2178 |
+
not possible with gdb.execute()). See
|
| 2179 |
+
http://sourceware.org/bugzilla/show_bug.cgi?id=12216
|
| 2180 |
+
"""
|
| 2181 |
+
fd, filename = tempfile.mkstemp()
|
| 2182 |
+
f = os.fdopen(fd, 'w')
|
| 2183 |
+
f.write(script_contents)
|
| 2184 |
+
f.close()
|
| 2185 |
+
gdb.execute("source %s" % filename, to_string=to_string)
|
| 2186 |
+
os.remove(filename)
|
| 2187 |
+
|
| 2188 |
+
|
| 2189 |
+
def register_defines():
|
| 2190 |
+
source_gdb_script(textwrap.dedent("""\
|
| 2191 |
+
define py-step
|
| 2192 |
+
-py-step
|
| 2193 |
+
end
|
| 2194 |
+
|
| 2195 |
+
define py-next
|
| 2196 |
+
-py-next
|
| 2197 |
+
end
|
| 2198 |
+
|
| 2199 |
+
document py-step
|
| 2200 |
+
%s
|
| 2201 |
+
end
|
| 2202 |
+
|
| 2203 |
+
document py-next
|
| 2204 |
+
%s
|
| 2205 |
+
end
|
| 2206 |
+
""") % (PyStep.__doc__, PyNext.__doc__))
|
| 2207 |
+
|
| 2208 |
+
|
| 2209 |
+
def stackdepth(frame):
|
| 2210 |
+
"Tells the stackdepth of a gdb frame."
|
| 2211 |
+
depth = 0
|
| 2212 |
+
while frame:
|
| 2213 |
+
frame = frame.older()
|
| 2214 |
+
depth += 1
|
| 2215 |
+
|
| 2216 |
+
return depth
|
| 2217 |
+
|
| 2218 |
+
|
| 2219 |
+
class ExecutionControlCommandBase(gdb.Command):
|
| 2220 |
+
"""
|
| 2221 |
+
Superclass for language specific execution control. Language specific
|
| 2222 |
+
features should be implemented by lang_info using the LanguageInfo
|
| 2223 |
+
interface. 'name' is the name of the command.
|
| 2224 |
+
"""
|
| 2225 |
+
|
| 2226 |
+
def __init__(self, name, lang_info):
|
| 2227 |
+
super(ExecutionControlCommandBase, self).__init__(
|
| 2228 |
+
name, gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE)
|
| 2229 |
+
self.lang_info = lang_info
|
| 2230 |
+
|
| 2231 |
+
def install_breakpoints(self):
|
| 2232 |
+
all_locations = itertools.chain(
|
| 2233 |
+
self.lang_info.static_break_functions(),
|
| 2234 |
+
self.lang_info.runtime_break_functions())
|
| 2235 |
+
|
| 2236 |
+
for location in all_locations:
|
| 2237 |
+
result = gdb.execute('break %s' % location, to_string=True)
|
| 2238 |
+
yield re.search(r'Breakpoint (\d+)', result).group(1)
|
| 2239 |
+
|
| 2240 |
+
def delete_breakpoints(self, breakpoint_list):
|
| 2241 |
+
for bp in breakpoint_list:
|
| 2242 |
+
gdb.execute("delete %s" % bp)
|
| 2243 |
+
|
| 2244 |
+
def filter_output(self, result):
|
| 2245 |
+
reflags = re.MULTILINE
|
| 2246 |
+
|
| 2247 |
+
output_on_halt = [
|
| 2248 |
+
(r'^Program received signal .*', reflags|re.DOTALL),
|
| 2249 |
+
(r'.*[Ww]arning.*', 0),
|
| 2250 |
+
(r'^Program exited .*', reflags),
|
| 2251 |
+
]
|
| 2252 |
+
|
| 2253 |
+
output_always = [
|
| 2254 |
+
# output when halting on a watchpoint
|
| 2255 |
+
(r'^(Old|New) value = .*', reflags),
|
| 2256 |
+
# output from the 'display' command
|
| 2257 |
+
(r'^\d+: \w+ = .*', reflags),
|
| 2258 |
+
]
|
| 2259 |
+
|
| 2260 |
+
def filter_output(regexes):
|
| 2261 |
+
output = []
|
| 2262 |
+
for regex, flags in regexes:
|
| 2263 |
+
for match in re.finditer(regex, result, flags):
|
| 2264 |
+
output.append(match.group(0))
|
| 2265 |
+
|
| 2266 |
+
return '\n'.join(output)
|
| 2267 |
+
|
| 2268 |
+
# Filter the return value output of the 'finish' command
|
| 2269 |
+
match_finish = re.search(r'^Value returned is \$\d+ = (.*)', result,
|
| 2270 |
+
re.MULTILINE)
|
| 2271 |
+
if match_finish:
|
| 2272 |
+
finish_output = 'Value returned: %s\n' % match_finish.group(1)
|
| 2273 |
+
else:
|
| 2274 |
+
finish_output = ''
|
| 2275 |
+
|
| 2276 |
+
return (filter_output(output_on_halt),
|
| 2277 |
+
finish_output + filter_output(output_always))
|
| 2278 |
+
|
| 2279 |
+
def stopped(self):
|
| 2280 |
+
return get_selected_inferior().pid == 0
|
| 2281 |
+
|
| 2282 |
+
def finish_executing(self, result):
|
| 2283 |
+
"""
|
| 2284 |
+
After doing some kind of code running in the inferior, print the line
|
| 2285 |
+
of source code or the result of the last executed gdb command (passed
|
| 2286 |
+
in as the `result` argument).
|
| 2287 |
+
"""
|
| 2288 |
+
output_on_halt, output_always = self.filter_output(result)
|
| 2289 |
+
|
| 2290 |
+
if self.stopped():
|
| 2291 |
+
print(output_always)
|
| 2292 |
+
print(output_on_halt)
|
| 2293 |
+
else:
|
| 2294 |
+
frame = gdb.selected_frame()
|
| 2295 |
+
source_line = self.lang_info.get_source_line(frame)
|
| 2296 |
+
if self.lang_info.is_relevant_function(frame):
|
| 2297 |
+
raised_exception = self.lang_info.exc_info(frame)
|
| 2298 |
+
if raised_exception:
|
| 2299 |
+
print(raised_exception)
|
| 2300 |
+
|
| 2301 |
+
if source_line:
|
| 2302 |
+
if output_always.rstrip():
|
| 2303 |
+
print(output_always.rstrip())
|
| 2304 |
+
print(source_line)
|
| 2305 |
+
else:
|
| 2306 |
+
print(result)
|
| 2307 |
+
|
| 2308 |
+
def _finish(self):
|
| 2309 |
+
"""
|
| 2310 |
+
Execute until the function returns (or until something else makes it
|
| 2311 |
+
stop)
|
| 2312 |
+
"""
|
| 2313 |
+
if gdb.selected_frame().older() is not None:
|
| 2314 |
+
return gdb.execute('finish', to_string=True)
|
| 2315 |
+
else:
|
| 2316 |
+
# outermost frame, continue
|
| 2317 |
+
return gdb.execute('cont', to_string=True)
|
| 2318 |
+
|
| 2319 |
+
def _finish_frame(self):
|
| 2320 |
+
"""
|
| 2321 |
+
Execute until the function returns to a relevant caller.
|
| 2322 |
+
"""
|
| 2323 |
+
while True:
|
| 2324 |
+
result = self._finish()
|
| 2325 |
+
|
| 2326 |
+
try:
|
| 2327 |
+
frame = gdb.selected_frame()
|
| 2328 |
+
except RuntimeError:
|
| 2329 |
+
break
|
| 2330 |
+
|
| 2331 |
+
hitbp = re.search(r'Breakpoint (\d+)', result)
|
| 2332 |
+
is_relevant = self.lang_info.is_relevant_function(frame)
|
| 2333 |
+
if hitbp or is_relevant or self.stopped():
|
| 2334 |
+
break
|
| 2335 |
+
|
| 2336 |
+
return result
|
| 2337 |
+
|
| 2338 |
+
def finish(self, *args):
|
| 2339 |
+
"Implements the finish command."
|
| 2340 |
+
result = self._finish_frame()
|
| 2341 |
+
self.finish_executing(result)
|
| 2342 |
+
|
| 2343 |
+
def step(self, stepinto, stepover_command='next'):
|
| 2344 |
+
"""
|
| 2345 |
+
Do a single step or step-over. Returns the result of the last gdb
|
| 2346 |
+
command that made execution stop.
|
| 2347 |
+
|
| 2348 |
+
This implementation, for stepping, sets (conditional) breakpoints for
|
| 2349 |
+
all functions that are deemed relevant. It then does a step over until
|
| 2350 |
+
either something halts execution, or until the next line is reached.
|
| 2351 |
+
|
| 2352 |
+
If, however, stepover_command is given, it should be a string gdb
|
| 2353 |
+
command that continues execution in some way. The idea is that the
|
| 2354 |
+
caller has set a (conditional) breakpoint or watchpoint that can work
|
| 2355 |
+
more efficiently than the step-over loop. For Python this means setting
|
| 2356 |
+
a watchpoint for f->f_lasti, which means we can then subsequently
|
| 2357 |
+
"finish" frames.
|
| 2358 |
+
We want f->f_lasti instead of f->f_lineno, because the latter only
|
| 2359 |
+
works properly with local trace functions, see
|
| 2360 |
+
PyFrameObjectPtr.current_line_num and PyFrameObjectPtr.addr2line.
|
| 2361 |
+
"""
|
| 2362 |
+
if stepinto:
|
| 2363 |
+
breakpoint_list = list(self.install_breakpoints())
|
| 2364 |
+
|
| 2365 |
+
beginframe = gdb.selected_frame()
|
| 2366 |
+
|
| 2367 |
+
if self.lang_info.is_relevant_function(beginframe):
|
| 2368 |
+
# If we start in a relevant frame, initialize stuff properly. If
|
| 2369 |
+
# we don't start in a relevant frame, the loop will halt
|
| 2370 |
+
# immediately. So don't call self.lang_info.lineno() as it may
|
| 2371 |
+
# raise for irrelevant frames.
|
| 2372 |
+
beginline = self.lang_info.lineno(beginframe)
|
| 2373 |
+
|
| 2374 |
+
if not stepinto:
|
| 2375 |
+
depth = stackdepth(beginframe)
|
| 2376 |
+
|
| 2377 |
+
newframe = beginframe
|
| 2378 |
+
|
| 2379 |
+
while True:
|
| 2380 |
+
if self.lang_info.is_relevant_function(newframe):
|
| 2381 |
+
result = gdb.execute(stepover_command, to_string=True)
|
| 2382 |
+
else:
|
| 2383 |
+
result = self._finish_frame()
|
| 2384 |
+
|
| 2385 |
+
if self.stopped():
|
| 2386 |
+
break
|
| 2387 |
+
|
| 2388 |
+
newframe = gdb.selected_frame()
|
| 2389 |
+
is_relevant_function = self.lang_info.is_relevant_function(newframe)
|
| 2390 |
+
try:
|
| 2391 |
+
framename = newframe.name()
|
| 2392 |
+
except RuntimeError:
|
| 2393 |
+
framename = None
|
| 2394 |
+
|
| 2395 |
+
m = re.search(r'Breakpoint (\d+)', result)
|
| 2396 |
+
if m:
|
| 2397 |
+
if is_relevant_function and m.group(1) in breakpoint_list:
|
| 2398 |
+
# although we hit a breakpoint, we still need to check
|
| 2399 |
+
# that the function, in case hit by a runtime breakpoint,
|
| 2400 |
+
# is in the right context
|
| 2401 |
+
break
|
| 2402 |
+
|
| 2403 |
+
if newframe != beginframe:
|
| 2404 |
+
# new function
|
| 2405 |
+
|
| 2406 |
+
if not stepinto:
|
| 2407 |
+
# see if we returned to the caller
|
| 2408 |
+
newdepth = stackdepth(newframe)
|
| 2409 |
+
is_relevant_function = (newdepth < depth and
|
| 2410 |
+
is_relevant_function)
|
| 2411 |
+
|
| 2412 |
+
if is_relevant_function:
|
| 2413 |
+
break
|
| 2414 |
+
else:
|
| 2415 |
+
# newframe equals beginframe, check for a difference in the
|
| 2416 |
+
# line number
|
| 2417 |
+
lineno = self.lang_info.lineno(newframe)
|
| 2418 |
+
if lineno and lineno != beginline:
|
| 2419 |
+
break
|
| 2420 |
+
|
| 2421 |
+
if stepinto:
|
| 2422 |
+
self.delete_breakpoints(breakpoint_list)
|
| 2423 |
+
|
| 2424 |
+
self.finish_executing(result)
|
| 2425 |
+
|
| 2426 |
+
def run(self, args, from_tty):
|
| 2427 |
+
self.finish_executing(gdb.execute('run ' + args, to_string=True))
|
| 2428 |
+
|
| 2429 |
+
def cont(self, *args):
|
| 2430 |
+
self.finish_executing(gdb.execute('cont', to_string=True))
|
| 2431 |
+
|
| 2432 |
+
|
| 2433 |
+
class LanguageInfo(object):
|
| 2434 |
+
"""
|
| 2435 |
+
This class defines the interface that ExecutionControlCommandBase needs to
|
| 2436 |
+
provide language-specific execution control.
|
| 2437 |
+
|
| 2438 |
+
Classes that implement this interface should implement:
|
| 2439 |
+
|
| 2440 |
+
lineno(frame)
|
| 2441 |
+
Tells the current line number (only called for a relevant frame).
|
| 2442 |
+
If lineno is a false value it is not checked for a difference.
|
| 2443 |
+
|
| 2444 |
+
is_relevant_function(frame)
|
| 2445 |
+
tells whether we care about frame 'frame'
|
| 2446 |
+
|
| 2447 |
+
get_source_line(frame)
|
| 2448 |
+
get the line of source code for the current line (only called for a
|
| 2449 |
+
relevant frame). If the source code cannot be retrieved this
|
| 2450 |
+
function should return None
|
| 2451 |
+
|
| 2452 |
+
exc_info(frame) -- optional
|
| 2453 |
+
tells whether an exception was raised, if so, it should return a
|
| 2454 |
+
string representation of the exception value, None otherwise.
|
| 2455 |
+
|
| 2456 |
+
static_break_functions()
|
| 2457 |
+
returns an iterable of function names that are considered relevant
|
| 2458 |
+
and should halt step-into execution. This is needed to provide a
|
| 2459 |
+
performing step-into
|
| 2460 |
+
|
| 2461 |
+
runtime_break_functions() -- optional
|
| 2462 |
+
list of functions that we should break into depending on the
|
| 2463 |
+
context
|
| 2464 |
+
"""
|
| 2465 |
+
|
| 2466 |
+
def exc_info(self, frame):
|
| 2467 |
+
"See this class' docstring."
|
| 2468 |
+
|
| 2469 |
+
def runtime_break_functions(self):
|
| 2470 |
+
"""
|
| 2471 |
+
Implement this if the list of step-into functions depends on the
|
| 2472 |
+
context.
|
| 2473 |
+
"""
|
| 2474 |
+
return ()
|
| 2475 |
+
|
| 2476 |
+
|
| 2477 |
+
class PythonInfo(LanguageInfo):
|
| 2478 |
+
|
| 2479 |
+
def pyframe(self, frame):
|
| 2480 |
+
pyframe = Frame(frame).get_pyop()
|
| 2481 |
+
if pyframe:
|
| 2482 |
+
return pyframe
|
| 2483 |
+
else:
|
| 2484 |
+
raise gdb.RuntimeError(
|
| 2485 |
+
"Unable to find the Python frame, run your code with a debug "
|
| 2486 |
+
"build (configure with --with-pydebug or compile with -g).")
|
| 2487 |
+
|
| 2488 |
+
def lineno(self, frame):
|
| 2489 |
+
return self.pyframe(frame).current_line_num()
|
| 2490 |
+
|
| 2491 |
+
def is_relevant_function(self, frame):
|
| 2492 |
+
return Frame(frame).is_evalframeex()
|
| 2493 |
+
|
| 2494 |
+
def get_source_line(self, frame):
|
| 2495 |
+
try:
|
| 2496 |
+
pyframe = self.pyframe(frame)
|
| 2497 |
+
return '%4d %s' % (pyframe.current_line_num(),
|
| 2498 |
+
pyframe.current_line().rstrip())
|
| 2499 |
+
except IOError:
|
| 2500 |
+
return None
|
| 2501 |
+
|
| 2502 |
+
def exc_info(self, frame):
|
| 2503 |
+
try:
|
| 2504 |
+
tstate = frame.read_var('tstate').dereference()
|
| 2505 |
+
if gdb.parse_and_eval('tstate->frame == f'):
|
| 2506 |
+
# tstate local variable initialized, check for an exception
|
| 2507 |
+
if sys.version_info >= (3, 12, 0, 'alpha', 6):
|
| 2508 |
+
inf_type = inf_value = tstate['current_exception']
|
| 2509 |
+
else:
|
| 2510 |
+
inf_type = tstate['curexc_type']
|
| 2511 |
+
inf_value = tstate['curexc_value']
|
| 2512 |
+
|
| 2513 |
+
if inf_type:
|
| 2514 |
+
return 'An exception was raised: %s' % (inf_value,)
|
| 2515 |
+
except (ValueError, RuntimeError):
|
| 2516 |
+
# Could not read the variable tstate or it's memory, it's ok
|
| 2517 |
+
pass
|
| 2518 |
+
|
| 2519 |
+
def static_break_functions(self):
|
| 2520 |
+
yield 'PyEval_EvalFrameEx'
|
| 2521 |
+
|
| 2522 |
+
|
| 2523 |
+
class PythonStepperMixin(object):
|
| 2524 |
+
"""
|
| 2525 |
+
Make this a mixin so CyStep can also inherit from this and use a
|
| 2526 |
+
CythonCodeStepper at the same time.
|
| 2527 |
+
"""
|
| 2528 |
+
|
| 2529 |
+
def python_step(self, stepinto):
|
| 2530 |
+
"""
|
| 2531 |
+
Set a watchpoint on the Python bytecode instruction pointer and try
|
| 2532 |
+
to finish the frame
|
| 2533 |
+
"""
|
| 2534 |
+
output = gdb.execute('watch f->f_lasti', to_string=True)
|
| 2535 |
+
watchpoint = int(re.search(r'[Ww]atchpoint (\d+):', output).group(1))
|
| 2536 |
+
self.step(stepinto=stepinto, stepover_command='finish')
|
| 2537 |
+
gdb.execute('delete %s' % watchpoint)
|
| 2538 |
+
|
| 2539 |
+
|
| 2540 |
+
class PyStep(ExecutionControlCommandBase, PythonStepperMixin):
|
| 2541 |
+
"Step through Python code."
|
| 2542 |
+
|
| 2543 |
+
stepinto = True
|
| 2544 |
+
|
| 2545 |
+
@dont_suppress_errors
|
| 2546 |
+
def invoke(self, args, from_tty):
|
| 2547 |
+
self.python_step(stepinto=self.stepinto)
|
| 2548 |
+
|
| 2549 |
+
|
| 2550 |
+
class PyNext(PyStep):
|
| 2551 |
+
"Step-over Python code."
|
| 2552 |
+
|
| 2553 |
+
stepinto = False
|
| 2554 |
+
|
| 2555 |
+
|
| 2556 |
+
class PyFinish(ExecutionControlCommandBase):
|
| 2557 |
+
"Execute until function returns to a caller."
|
| 2558 |
+
|
| 2559 |
+
invoke = dont_suppress_errors(ExecutionControlCommandBase.finish)
|
| 2560 |
+
|
| 2561 |
+
|
| 2562 |
+
class PyRun(ExecutionControlCommandBase):
|
| 2563 |
+
"Run the program."
|
| 2564 |
+
|
| 2565 |
+
invoke = dont_suppress_errors(ExecutionControlCommandBase.run)
|
| 2566 |
+
|
| 2567 |
+
|
| 2568 |
+
class PyCont(ExecutionControlCommandBase):
|
| 2569 |
+
|
| 2570 |
+
invoke = dont_suppress_errors(ExecutionControlCommandBase.cont)
|
| 2571 |
+
|
| 2572 |
+
|
| 2573 |
+
def _pointervalue(gdbval):
|
| 2574 |
+
"""
|
| 2575 |
+
Return the value of the pointer as a Python int.
|
| 2576 |
+
|
| 2577 |
+
gdbval.type must be a pointer type
|
| 2578 |
+
"""
|
| 2579 |
+
# don't convert with int() as it will raise a RuntimeError
|
| 2580 |
+
if gdbval.address is not None:
|
| 2581 |
+
return int(gdbval.address)
|
| 2582 |
+
else:
|
| 2583 |
+
# the address attribute is None sometimes, in which case we can
|
| 2584 |
+
# still convert the pointer to an int
|
| 2585 |
+
return int(gdbval)
|
| 2586 |
+
|
| 2587 |
+
|
| 2588 |
+
def pointervalue(gdbval):
|
| 2589 |
+
pointer = _pointervalue(gdbval)
|
| 2590 |
+
try:
|
| 2591 |
+
if pointer < 0:
|
| 2592 |
+
raise gdb.GdbError("Negative pointer value, presumably a bug "
|
| 2593 |
+
"in gdb, aborting.")
|
| 2594 |
+
except RuntimeError:
|
| 2595 |
+
# work around yet another bug in gdb where you get random behaviour
|
| 2596 |
+
# and tracebacks
|
| 2597 |
+
pass
|
| 2598 |
+
|
| 2599 |
+
return pointer
|
| 2600 |
+
|
| 2601 |
+
|
| 2602 |
+
def get_inferior_unicode_postfix():
|
| 2603 |
+
try:
|
| 2604 |
+
gdb.parse_and_eval('PyUnicode_FromEncodedObject')
|
| 2605 |
+
except RuntimeError:
|
| 2606 |
+
try:
|
| 2607 |
+
gdb.parse_and_eval('PyUnicodeUCS2_FromEncodedObject')
|
| 2608 |
+
except RuntimeError:
|
| 2609 |
+
return 'UCS4'
|
| 2610 |
+
else:
|
| 2611 |
+
return 'UCS2'
|
| 2612 |
+
else:
|
| 2613 |
+
return ''
|
| 2614 |
+
|
| 2615 |
+
|
| 2616 |
+
class PythonCodeExecutor(object):
|
| 2617 |
+
|
| 2618 |
+
Py_single_input = 256
|
| 2619 |
+
Py_file_input = 257
|
| 2620 |
+
Py_eval_input = 258
|
| 2621 |
+
|
| 2622 |
+
def malloc(self, size):
|
| 2623 |
+
chunk = (gdb.parse_and_eval("(void *) malloc((size_t) %d)" % size))
|
| 2624 |
+
|
| 2625 |
+
pointer = pointervalue(chunk)
|
| 2626 |
+
if pointer == 0:
|
| 2627 |
+
raise gdb.GdbError("No memory could be allocated in the inferior.")
|
| 2628 |
+
|
| 2629 |
+
return pointer
|
| 2630 |
+
|
| 2631 |
+
def alloc_string(self, string):
|
| 2632 |
+
pointer = self.malloc(len(string))
|
| 2633 |
+
get_selected_inferior().write_memory(pointer, string)
|
| 2634 |
+
|
| 2635 |
+
return pointer
|
| 2636 |
+
|
| 2637 |
+
def alloc_pystring(self, string):
|
| 2638 |
+
stringp = self.alloc_string(string)
|
| 2639 |
+
PyString_FromStringAndSize = 'PyString_FromStringAndSize'
|
| 2640 |
+
|
| 2641 |
+
try:
|
| 2642 |
+
gdb.parse_and_eval(PyString_FromStringAndSize)
|
| 2643 |
+
except RuntimeError:
|
| 2644 |
+
# Python 3
|
| 2645 |
+
PyString_FromStringAndSize = ('PyUnicode%s_FromStringAndSize' %
|
| 2646 |
+
(get_inferior_unicode_postfix(),))
|
| 2647 |
+
|
| 2648 |
+
try:
|
| 2649 |
+
result = gdb.parse_and_eval(
|
| 2650 |
+
'(PyObject *) %s((char *) %d, (size_t) %d)' % (
|
| 2651 |
+
PyString_FromStringAndSize, stringp, len(string)))
|
| 2652 |
+
finally:
|
| 2653 |
+
self.free(stringp)
|
| 2654 |
+
|
| 2655 |
+
pointer = pointervalue(result)
|
| 2656 |
+
if pointer == 0:
|
| 2657 |
+
raise gdb.GdbError("Unable to allocate Python string in "
|
| 2658 |
+
"the inferior.")
|
| 2659 |
+
|
| 2660 |
+
return pointer
|
| 2661 |
+
|
| 2662 |
+
def free(self, pointer):
|
| 2663 |
+
gdb.parse_and_eval("(void) free((void *) %d)" % pointer)
|
| 2664 |
+
|
| 2665 |
+
def incref(self, pointer):
|
| 2666 |
+
"Increment the reference count of a Python object in the inferior."
|
| 2667 |
+
gdb.parse_and_eval('Py_IncRef((PyObject *) %d)' % pointer)
|
| 2668 |
+
|
| 2669 |
+
def xdecref(self, pointer):
|
| 2670 |
+
"Decrement the reference count of a Python object in the inferior."
|
| 2671 |
+
# Py_DecRef is like Py_XDECREF, but a function. So we don't have
|
| 2672 |
+
# to check for NULL. This should also decref all our allocated
|
| 2673 |
+
# Python strings.
|
| 2674 |
+
gdb.parse_and_eval('Py_DecRef((PyObject *) %d)' % pointer)
|
| 2675 |
+
|
| 2676 |
+
def evalcode(self, code, input_type, global_dict=None, local_dict=None):
|
| 2677 |
+
"""
|
| 2678 |
+
Evaluate python code `code` given as a string in the inferior and
|
| 2679 |
+
return the result as a gdb.Value. Returns a new reference in the
|
| 2680 |
+
inferior.
|
| 2681 |
+
|
| 2682 |
+
Of course, executing any code in the inferior may be dangerous and may
|
| 2683 |
+
leave the debuggee in an unsafe state or terminate it altogether.
|
| 2684 |
+
"""
|
| 2685 |
+
if '\0' in code:
|
| 2686 |
+
raise gdb.GdbError("String contains NUL byte.")
|
| 2687 |
+
|
| 2688 |
+
code += '\0'
|
| 2689 |
+
|
| 2690 |
+
pointer = self.alloc_string(code)
|
| 2691 |
+
|
| 2692 |
+
globalsp = pointervalue(global_dict)
|
| 2693 |
+
localsp = pointervalue(local_dict)
|
| 2694 |
+
|
| 2695 |
+
if globalsp == 0 or localsp == 0:
|
| 2696 |
+
raise gdb.GdbError("Unable to obtain or create locals or globals.")
|
| 2697 |
+
|
| 2698 |
+
code = """
|
| 2699 |
+
PyRun_String(
|
| 2700 |
+
(char *) %(code)d,
|
| 2701 |
+
(int) %(start)d,
|
| 2702 |
+
(PyObject *) %(globals)s,
|
| 2703 |
+
(PyObject *) %(locals)d)
|
| 2704 |
+
""" % dict(code=pointer, start=input_type,
|
| 2705 |
+
globals=globalsp, locals=localsp)
|
| 2706 |
+
|
| 2707 |
+
with FetchAndRestoreError():
|
| 2708 |
+
try:
|
| 2709 |
+
pyobject_return_value = gdb.parse_and_eval(code)
|
| 2710 |
+
finally:
|
| 2711 |
+
self.free(pointer)
|
| 2712 |
+
|
| 2713 |
+
return pyobject_return_value
|
| 2714 |
+
|
| 2715 |
+
|
| 2716 |
+
class FetchAndRestoreError(PythonCodeExecutor):
|
| 2717 |
+
"""
|
| 2718 |
+
Context manager that fetches the error indicator in the inferior and
|
| 2719 |
+
restores it on exit.
|
| 2720 |
+
"""
|
| 2721 |
+
|
| 2722 |
+
def __init__(self):
|
| 2723 |
+
self.sizeof_PyObjectPtr = gdb.lookup_type('PyObject').pointer().sizeof
|
| 2724 |
+
self.pointer = self.malloc(self.sizeof_PyObjectPtr * 3)
|
| 2725 |
+
|
| 2726 |
+
type = self.pointer
|
| 2727 |
+
value = self.pointer + self.sizeof_PyObjectPtr
|
| 2728 |
+
traceback = self.pointer + self.sizeof_PyObjectPtr * 2
|
| 2729 |
+
|
| 2730 |
+
self.errstate = type, value, traceback
|
| 2731 |
+
|
| 2732 |
+
def __enter__(self):
|
| 2733 |
+
gdb.parse_and_eval("PyErr_Fetch(%d, %d, %d)" % self.errstate)
|
| 2734 |
+
|
| 2735 |
+
def __exit__(self, *args):
|
| 2736 |
+
if gdb.parse_and_eval("(int) PyErr_Occurred()"):
|
| 2737 |
+
gdb.parse_and_eval("PyErr_Print()")
|
| 2738 |
+
|
| 2739 |
+
pyerr_restore = ("PyErr_Restore("
|
| 2740 |
+
"(PyObject *) *%d,"
|
| 2741 |
+
"(PyObject *) *%d,"
|
| 2742 |
+
"(PyObject *) *%d)")
|
| 2743 |
+
|
| 2744 |
+
try:
|
| 2745 |
+
gdb.parse_and_eval(pyerr_restore % self.errstate)
|
| 2746 |
+
finally:
|
| 2747 |
+
self.free(self.pointer)
|
| 2748 |
+
|
| 2749 |
+
|
| 2750 |
+
class FixGdbCommand(gdb.Command):
|
| 2751 |
+
|
| 2752 |
+
def __init__(self, command, actual_command):
|
| 2753 |
+
super(FixGdbCommand, self).__init__(command, gdb.COMMAND_DATA,
|
| 2754 |
+
gdb.COMPLETE_NONE)
|
| 2755 |
+
self.actual_command = actual_command
|
| 2756 |
+
|
| 2757 |
+
def fix_gdb(self):
|
| 2758 |
+
"""
|
| 2759 |
+
It seems that invoking either 'cy exec' and 'py-exec' work perfectly
|
| 2760 |
+
fine, but after this gdb's python API is entirely broken.
|
| 2761 |
+
Maybe some uncleared exception value is still set?
|
| 2762 |
+
sys.exc_clear() didn't help. A demonstration:
|
| 2763 |
+
|
| 2764 |
+
(gdb) cy exec 'hello'
|
| 2765 |
+
'hello'
|
| 2766 |
+
(gdb) python gdb.execute('cont')
|
| 2767 |
+
RuntimeError: Cannot convert value to int.
|
| 2768 |
+
Error while executing Python code.
|
| 2769 |
+
(gdb) python gdb.execute('cont')
|
| 2770 |
+
[15148 refs]
|
| 2771 |
+
|
| 2772 |
+
Program exited normally.
|
| 2773 |
+
"""
|
| 2774 |
+
warnings.filterwarnings('ignore', r'.*', RuntimeWarning,
|
| 2775 |
+
re.escape(__name__))
|
| 2776 |
+
try:
|
| 2777 |
+
int(gdb.parse_and_eval("(void *) 0")) == 0
|
| 2778 |
+
except RuntimeError:
|
| 2779 |
+
pass
|
| 2780 |
+
# warnings.resetwarnings()
|
| 2781 |
+
|
| 2782 |
+
@dont_suppress_errors
|
| 2783 |
+
def invoke(self, args, from_tty):
|
| 2784 |
+
self.fix_gdb()
|
| 2785 |
+
try:
|
| 2786 |
+
gdb.execute('%s %s' % (self.actual_command, args))
|
| 2787 |
+
except RuntimeError as e:
|
| 2788 |
+
raise gdb.GdbError(str(e))
|
| 2789 |
+
self.fix_gdb()
|
| 2790 |
+
|
| 2791 |
+
|
| 2792 |
+
def _evalcode_python(executor, code, input_type):
|
| 2793 |
+
"""
|
| 2794 |
+
Execute Python code in the most recent stack frame.
|
| 2795 |
+
"""
|
| 2796 |
+
global_dict = gdb.parse_and_eval('PyEval_GetGlobals()')
|
| 2797 |
+
local_dict = gdb.parse_and_eval('PyEval_GetLocals()')
|
| 2798 |
+
|
| 2799 |
+
if (pointervalue(global_dict) == 0 or pointervalue(local_dict) == 0):
|
| 2800 |
+
raise gdb.GdbError("Unable to find the locals or globals of the "
|
| 2801 |
+
"most recent Python function (relative to the "
|
| 2802 |
+
"selected frame).")
|
| 2803 |
+
|
| 2804 |
+
return executor.evalcode(code, input_type, global_dict, local_dict)
|
| 2805 |
+
|
| 2806 |
+
|
| 2807 |
+
class PyExec(gdb.Command):
|
| 2808 |
+
|
| 2809 |
+
def readcode(self, expr):
|
| 2810 |
+
if expr:
|
| 2811 |
+
return expr, PythonCodeExecutor.Py_single_input
|
| 2812 |
+
else:
|
| 2813 |
+
lines = []
|
| 2814 |
+
while True:
|
| 2815 |
+
try:
|
| 2816 |
+
if sys.version_info[0] == 2:
|
| 2817 |
+
line = raw_input()
|
| 2818 |
+
else:
|
| 2819 |
+
line = input('>')
|
| 2820 |
+
except EOFError:
|
| 2821 |
+
break
|
| 2822 |
+
else:
|
| 2823 |
+
if line.rstrip() == 'end':
|
| 2824 |
+
break
|
| 2825 |
+
|
| 2826 |
+
lines.append(line)
|
| 2827 |
+
|
| 2828 |
+
return '\n'.join(lines), PythonCodeExecutor.Py_file_input
|
| 2829 |
+
|
| 2830 |
+
@dont_suppress_errors
|
| 2831 |
+
def invoke(self, expr, from_tty):
|
| 2832 |
+
expr, input_type = self.readcode(expr)
|
| 2833 |
+
executor = PythonCodeExecutor()
|
| 2834 |
+
executor.xdecref(_evalcode_python(executor, input_type, global_dict, local_dict))
|
| 2835 |
+
|
| 2836 |
+
|
| 2837 |
+
gdb.execute('set breakpoint pending on')
|
| 2838 |
+
|
| 2839 |
+
if hasattr(gdb, 'GdbError'):
|
| 2840 |
+
# Wrap py-step and py-next in gdb defines to make them repeatable.
|
| 2841 |
+
py_step = PyStep('-py-step', PythonInfo())
|
| 2842 |
+
py_next = PyNext('-py-next', PythonInfo())
|
| 2843 |
+
register_defines()
|
| 2844 |
+
py_finish = PyFinish('py-finish', PythonInfo())
|
| 2845 |
+
py_run = PyRun('py-run', PythonInfo())
|
| 2846 |
+
py_cont = PyCont('py-cont', PythonInfo())
|
| 2847 |
+
|
| 2848 |
+
py_exec = FixGdbCommand('py-exec', '-py-exec')
|
| 2849 |
+
_py_exec = PyExec("-py-exec", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
|
| 2850 |
+
else:
|
| 2851 |
+
warnings.warn("Use gdb 7.2 or higher to use the py-exec command.")
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__init__.py
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from Cython.Distutils.build_ext import build_ext
|
| 2 |
+
from Cython.Distutils.extension import Extension
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (367 Bytes). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/build_ext.cpython-311.pyc
ADDED
|
Binary file (6.06 kB). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/extension.cpython-311.pyc
ADDED
|
Binary file (3.64 kB). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/__pycache__/old_build_ext.cpython-311.pyc
ADDED
|
Binary file (13.5 kB). View file
|
|
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/build_ext.py
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
try:
|
| 5 |
+
from __builtin__ import basestring
|
| 6 |
+
except ImportError:
|
| 7 |
+
basestring = str
|
| 8 |
+
|
| 9 |
+
# Always inherit from the "build_ext" in distutils since setuptools already imports
|
| 10 |
+
# it from Cython if available, and does the proper distutils fallback otherwise.
|
| 11 |
+
# https://github.com/pypa/setuptools/blob/9f1822ee910df3df930a98ab99f66d18bb70659b/setuptools/command/build_ext.py#L16
|
| 12 |
+
|
| 13 |
+
# setuptools imports Cython's "build_ext", so make sure we go first.
|
| 14 |
+
_build_ext_module = sys.modules.get('setuptools.command.build_ext')
|
| 15 |
+
if _build_ext_module is None:
|
| 16 |
+
try:
|
| 17 |
+
import distutils.command.build_ext as _build_ext_module
|
| 18 |
+
except ImportError:
|
| 19 |
+
# Python 3.12 no longer has distutils, but setuptools can replace it.
|
| 20 |
+
try:
|
| 21 |
+
import setuptools.command.build_ext as _build_ext_module
|
| 22 |
+
except ImportError:
|
| 23 |
+
raise ImportError("'distutils' cannot be imported. Please install setuptools.")
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
# setuptools remembers the original distutils "build_ext" as "_du_build_ext"
|
| 27 |
+
_build_ext = getattr(_build_ext_module, '_du_build_ext', None)
|
| 28 |
+
if _build_ext is None:
|
| 29 |
+
_build_ext = getattr(_build_ext_module, 'build_ext', None)
|
| 30 |
+
if _build_ext is None:
|
| 31 |
+
from distutils.command.build_ext import build_ext as _build_ext
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class build_ext(_build_ext, object):
|
| 35 |
+
|
| 36 |
+
user_options = _build_ext.user_options + [
|
| 37 |
+
('cython-cplus', None,
|
| 38 |
+
"generate C++ source files"),
|
| 39 |
+
('cython-create-listing', None,
|
| 40 |
+
"write errors to a listing file"),
|
| 41 |
+
('cython-line-directives', None,
|
| 42 |
+
"emit source line directives"),
|
| 43 |
+
('cython-include-dirs=', None,
|
| 44 |
+
"path to the Cython include files" + _build_ext.sep_by),
|
| 45 |
+
('cython-c-in-temp', None,
|
| 46 |
+
"put generated C files in temp directory"),
|
| 47 |
+
('cython-gen-pxi', None,
|
| 48 |
+
"generate .pxi file for public declarations"),
|
| 49 |
+
('cython-directives=', None,
|
| 50 |
+
"compiler directive overrides"),
|
| 51 |
+
('cython-gdb', None,
|
| 52 |
+
"generate debug information for cygdb"),
|
| 53 |
+
('cython-compile-time-env', None,
|
| 54 |
+
"cython compile time environment"),
|
| 55 |
+
]
|
| 56 |
+
|
| 57 |
+
boolean_options = _build_ext.boolean_options + [
|
| 58 |
+
'cython-cplus', 'cython-create-listing', 'cython-line-directives',
|
| 59 |
+
'cython-c-in-temp', 'cython-gdb',
|
| 60 |
+
]
|
| 61 |
+
|
| 62 |
+
def initialize_options(self):
|
| 63 |
+
super(build_ext, self).initialize_options()
|
| 64 |
+
self.cython_cplus = 0
|
| 65 |
+
self.cython_create_listing = 0
|
| 66 |
+
self.cython_line_directives = 0
|
| 67 |
+
self.cython_include_dirs = None
|
| 68 |
+
self.cython_directives = None
|
| 69 |
+
self.cython_c_in_temp = 0
|
| 70 |
+
self.cython_gen_pxi = 0
|
| 71 |
+
self.cython_gdb = False
|
| 72 |
+
self.cython_compile_time_env = None
|
| 73 |
+
|
| 74 |
+
def finalize_options(self):
|
| 75 |
+
super(build_ext, self).finalize_options()
|
| 76 |
+
if self.cython_include_dirs is None:
|
| 77 |
+
self.cython_include_dirs = []
|
| 78 |
+
elif isinstance(self.cython_include_dirs, basestring):
|
| 79 |
+
self.cython_include_dirs = \
|
| 80 |
+
self.cython_include_dirs.split(os.pathsep)
|
| 81 |
+
if self.cython_directives is None:
|
| 82 |
+
self.cython_directives = {}
|
| 83 |
+
|
| 84 |
+
def get_extension_attr(self, extension, option_name, default=False):
|
| 85 |
+
return getattr(self, option_name) or getattr(extension, option_name, default)
|
| 86 |
+
|
| 87 |
+
def build_extension(self, ext):
|
| 88 |
+
from Cython.Build.Dependencies import cythonize
|
| 89 |
+
|
| 90 |
+
# Set up the include_path for the Cython compiler:
|
| 91 |
+
# 1. Start with the command line option.
|
| 92 |
+
# 2. Add in any (unique) paths from the extension
|
| 93 |
+
# cython_include_dirs (if Cython.Distutils.extension is used).
|
| 94 |
+
# 3. Add in any (unique) paths from the extension include_dirs
|
| 95 |
+
includes = list(self.cython_include_dirs)
|
| 96 |
+
for include_dir in getattr(ext, 'cython_include_dirs', []):
|
| 97 |
+
if include_dir not in includes:
|
| 98 |
+
includes.append(include_dir)
|
| 99 |
+
|
| 100 |
+
# In case extension.include_dirs is a generator, evaluate it and keep
|
| 101 |
+
# result
|
| 102 |
+
ext.include_dirs = list(ext.include_dirs)
|
| 103 |
+
for include_dir in ext.include_dirs + list(self.include_dirs):
|
| 104 |
+
if include_dir not in includes:
|
| 105 |
+
includes.append(include_dir)
|
| 106 |
+
|
| 107 |
+
# Set up Cython compiler directives:
|
| 108 |
+
# 1. Start with the command line option.
|
| 109 |
+
# 2. Add in any (unique) entries from the extension
|
| 110 |
+
# cython_directives (if Cython.Distutils.extension is used).
|
| 111 |
+
directives = dict(self.cython_directives)
|
| 112 |
+
if hasattr(ext, "cython_directives"):
|
| 113 |
+
directives.update(ext.cython_directives)
|
| 114 |
+
|
| 115 |
+
if self.get_extension_attr(ext, 'cython_cplus'):
|
| 116 |
+
ext.language = 'c++'
|
| 117 |
+
|
| 118 |
+
options = {
|
| 119 |
+
'use_listing_file': self.get_extension_attr(ext, 'cython_create_listing'),
|
| 120 |
+
'emit_linenums': self.get_extension_attr(ext, 'cython_line_directives'),
|
| 121 |
+
'include_path': includes,
|
| 122 |
+
'compiler_directives': directives,
|
| 123 |
+
'build_dir': self.build_temp if self.get_extension_attr(ext, 'cython_c_in_temp') else None,
|
| 124 |
+
'generate_pxi': self.get_extension_attr(ext, 'cython_gen_pxi'),
|
| 125 |
+
'gdb_debug': self.get_extension_attr(ext, 'cython_gdb'),
|
| 126 |
+
'c_line_in_traceback': not getattr(ext, 'no_c_in_traceback', 0),
|
| 127 |
+
'compile_time_env': self.get_extension_attr(ext, 'cython_compile_time_env', default=None),
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
new_ext = cythonize(
|
| 131 |
+
ext,force=self.force, quiet=self.verbose == 0, **options
|
| 132 |
+
)[0]
|
| 133 |
+
|
| 134 |
+
ext.sources = new_ext.sources
|
| 135 |
+
super(build_ext, self).build_extension(ext)
|
| 136 |
+
|
| 137 |
+
# backward compatibility
|
| 138 |
+
new_build_ext = build_ext
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Distutils/old_build_ext.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Cython.Distutils.old_build_ext
|
| 2 |
+
|
| 3 |
+
Implements a version of the Distutils 'build_ext' command, for
|
| 4 |
+
building Cython extension modules.
|
| 5 |
+
|
| 6 |
+
Note that this module is deprecated. Use cythonize() instead.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
__revision__ = "$Id:$"
|
| 10 |
+
|
| 11 |
+
import sys
|
| 12 |
+
import os
|
| 13 |
+
from distutils.errors import DistutilsPlatformError
|
| 14 |
+
from distutils.dep_util import newer, newer_group
|
| 15 |
+
from distutils import log
|
| 16 |
+
from distutils.command import build_ext as _build_ext
|
| 17 |
+
from distutils import sysconfig
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
try:
|
| 21 |
+
from __builtin__ import basestring
|
| 22 |
+
except ImportError:
|
| 23 |
+
basestring = str
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
# FIXME: the below does not work as intended since importing 'Cython.Distutils' already
|
| 27 |
+
# imports this module through 'Cython/Distutils/build_ext.py', so the condition is
|
| 28 |
+
# always false and never prints the warning.
|
| 29 |
+
"""
|
| 30 |
+
import inspect
|
| 31 |
+
import warnings
|
| 32 |
+
|
| 33 |
+
def _check_stack(path):
|
| 34 |
+
try:
|
| 35 |
+
for frame in inspect.getouterframes(inspect.currentframe(), 0):
|
| 36 |
+
if path in frame[1].replace(os.sep, '/'):
|
| 37 |
+
return True
|
| 38 |
+
except Exception:
|
| 39 |
+
pass
|
| 40 |
+
return False
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
if (not _check_stack('setuptools/extensions.py')
|
| 44 |
+
and not _check_stack('pyximport/pyxbuild.py')
|
| 45 |
+
and not _check_stack('Cython/Distutils/build_ext.py')):
|
| 46 |
+
warnings.warn(
|
| 47 |
+
"Cython.Distutils.old_build_ext does not properly handle dependencies "
|
| 48 |
+
"and is deprecated.")
|
| 49 |
+
"""
|
| 50 |
+
|
| 51 |
+
extension_name_re = _build_ext.extension_name_re
|
| 52 |
+
|
| 53 |
+
show_compilers = _build_ext.show_compilers
|
| 54 |
+
|
| 55 |
+
class Optimization(object):
|
| 56 |
+
def __init__(self):
|
| 57 |
+
self.flags = (
|
| 58 |
+
'OPT',
|
| 59 |
+
'CFLAGS',
|
| 60 |
+
'CPPFLAGS',
|
| 61 |
+
'EXTRA_CFLAGS',
|
| 62 |
+
'BASECFLAGS',
|
| 63 |
+
'PY_CFLAGS',
|
| 64 |
+
)
|
| 65 |
+
self.state = sysconfig.get_config_vars(*self.flags)
|
| 66 |
+
self.config_vars = sysconfig.get_config_vars()
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def disable_optimization(self):
|
| 70 |
+
"disable optimization for the C or C++ compiler"
|
| 71 |
+
badoptions = ('-O1', '-O2', '-O3')
|
| 72 |
+
|
| 73 |
+
for flag, option in zip(self.flags, self.state):
|
| 74 |
+
if option is not None:
|
| 75 |
+
L = [opt for opt in option.split() if opt not in badoptions]
|
| 76 |
+
self.config_vars[flag] = ' '.join(L)
|
| 77 |
+
|
| 78 |
+
def restore_state(self):
|
| 79 |
+
"restore the original state"
|
| 80 |
+
for flag, option in zip(self.flags, self.state):
|
| 81 |
+
if option is not None:
|
| 82 |
+
self.config_vars[flag] = option
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
optimization = Optimization()
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
class old_build_ext(_build_ext.build_ext):
|
| 89 |
+
|
| 90 |
+
description = "build C/C++ and Cython extensions (compile/link to build directory)"
|
| 91 |
+
|
| 92 |
+
sep_by = _build_ext.build_ext.sep_by
|
| 93 |
+
user_options = _build_ext.build_ext.user_options[:]
|
| 94 |
+
boolean_options = _build_ext.build_ext.boolean_options[:]
|
| 95 |
+
help_options = _build_ext.build_ext.help_options[:]
|
| 96 |
+
|
| 97 |
+
# Add the pyrex specific data.
|
| 98 |
+
user_options.extend([
|
| 99 |
+
('cython-cplus', None,
|
| 100 |
+
"generate C++ source files"),
|
| 101 |
+
('cython-create-listing', None,
|
| 102 |
+
"write errors to a listing file"),
|
| 103 |
+
('cython-line-directives', None,
|
| 104 |
+
"emit source line directives"),
|
| 105 |
+
('cython-include-dirs=', None,
|
| 106 |
+
"path to the Cython include files" + sep_by),
|
| 107 |
+
('cython-c-in-temp', None,
|
| 108 |
+
"put generated C files in temp directory"),
|
| 109 |
+
('cython-gen-pxi', None,
|
| 110 |
+
"generate .pxi file for public declarations"),
|
| 111 |
+
('cython-directives=', None,
|
| 112 |
+
"compiler directive overrides"),
|
| 113 |
+
('cython-gdb', None,
|
| 114 |
+
"generate debug information for cygdb"),
|
| 115 |
+
('cython-compile-time-env', None,
|
| 116 |
+
"cython compile time environment"),
|
| 117 |
+
|
| 118 |
+
# For backwards compatibility.
|
| 119 |
+
('pyrex-cplus', None,
|
| 120 |
+
"generate C++ source files"),
|
| 121 |
+
('pyrex-create-listing', None,
|
| 122 |
+
"write errors to a listing file"),
|
| 123 |
+
('pyrex-line-directives', None,
|
| 124 |
+
"emit source line directives"),
|
| 125 |
+
('pyrex-include-dirs=', None,
|
| 126 |
+
"path to the Cython include files" + sep_by),
|
| 127 |
+
('pyrex-c-in-temp', None,
|
| 128 |
+
"put generated C files in temp directory"),
|
| 129 |
+
('pyrex-gen-pxi', None,
|
| 130 |
+
"generate .pxi file for public declarations"),
|
| 131 |
+
('pyrex-directives=', None,
|
| 132 |
+
"compiler directive overrides"),
|
| 133 |
+
('pyrex-gdb', None,
|
| 134 |
+
"generate debug information for cygdb"),
|
| 135 |
+
])
|
| 136 |
+
|
| 137 |
+
boolean_options.extend([
|
| 138 |
+
'cython-cplus', 'cython-create-listing', 'cython-line-directives',
|
| 139 |
+
'cython-c-in-temp', 'cython-gdb',
|
| 140 |
+
|
| 141 |
+
# For backwards compatibility.
|
| 142 |
+
'pyrex-cplus', 'pyrex-create-listing', 'pyrex-line-directives',
|
| 143 |
+
'pyrex-c-in-temp', 'pyrex-gdb',
|
| 144 |
+
])
|
| 145 |
+
|
| 146 |
+
def initialize_options(self):
|
| 147 |
+
_build_ext.build_ext.initialize_options(self)
|
| 148 |
+
self.cython_cplus = 0
|
| 149 |
+
self.cython_create_listing = 0
|
| 150 |
+
self.cython_line_directives = 0
|
| 151 |
+
self.cython_include_dirs = None
|
| 152 |
+
self.cython_directives = None
|
| 153 |
+
self.cython_c_in_temp = 0
|
| 154 |
+
self.cython_gen_pxi = 0
|
| 155 |
+
self.cython_gdb = False
|
| 156 |
+
self.no_c_in_traceback = 0
|
| 157 |
+
self.cython_compile_time_env = None
|
| 158 |
+
|
| 159 |
+
def __getattr__(self, name):
|
| 160 |
+
if name[:6] == 'pyrex_':
|
| 161 |
+
return getattr(self, 'cython_' + name[6:])
|
| 162 |
+
else:
|
| 163 |
+
return _build_ext.build_ext.__getattr__(self, name)
|
| 164 |
+
|
| 165 |
+
def __setattr__(self, name, value):
|
| 166 |
+
if name[:6] == 'pyrex_':
|
| 167 |
+
return setattr(self, 'cython_' + name[6:], value)
|
| 168 |
+
else:
|
| 169 |
+
# _build_ext.build_ext.__setattr__(self, name, value)
|
| 170 |
+
self.__dict__[name] = value
|
| 171 |
+
|
| 172 |
+
def finalize_options(self):
|
| 173 |
+
_build_ext.build_ext.finalize_options(self)
|
| 174 |
+
if self.cython_include_dirs is None:
|
| 175 |
+
self.cython_include_dirs = []
|
| 176 |
+
elif isinstance(self.cython_include_dirs, basestring):
|
| 177 |
+
self.cython_include_dirs = \
|
| 178 |
+
self.cython_include_dirs.split(os.pathsep)
|
| 179 |
+
if self.cython_directives is None:
|
| 180 |
+
self.cython_directives = {}
|
| 181 |
+
# finalize_options ()
|
| 182 |
+
|
| 183 |
+
def run(self):
|
| 184 |
+
# We have one shot at this before build_ext initializes the compiler.
|
| 185 |
+
# If --pyrex-gdb is in effect as a command line option or as option
|
| 186 |
+
# of any Extension module, disable optimization for the C or C++
|
| 187 |
+
# compiler.
|
| 188 |
+
if self.cython_gdb or [1 for ext in self.extensions
|
| 189 |
+
if getattr(ext, 'cython_gdb', False)]:
|
| 190 |
+
optimization.disable_optimization()
|
| 191 |
+
|
| 192 |
+
_build_ext.build_ext.run(self)
|
| 193 |
+
|
| 194 |
+
def check_extensions_list(self, extensions):
|
| 195 |
+
# Note: might get called multiple times.
|
| 196 |
+
_build_ext.build_ext.check_extensions_list(self, extensions)
|
| 197 |
+
for ext in self.extensions:
|
| 198 |
+
ext.sources = self.cython_sources(ext.sources, ext)
|
| 199 |
+
|
| 200 |
+
def cython_sources(self, sources, extension):
|
| 201 |
+
"""
|
| 202 |
+
Walk the list of source files in 'sources', looking for Cython
|
| 203 |
+
source files (.pyx and .py). Run Cython on all that are
|
| 204 |
+
found, and return a modified 'sources' list with Cython source
|
| 205 |
+
files replaced by the generated C (or C++) files.
|
| 206 |
+
"""
|
| 207 |
+
new_sources = []
|
| 208 |
+
cython_sources = []
|
| 209 |
+
cython_targets = {}
|
| 210 |
+
|
| 211 |
+
# Setup create_list and cplus from the extension options if
|
| 212 |
+
# Cython.Distutils.extension.Extension is used, otherwise just
|
| 213 |
+
# use what was parsed from the command-line or the configuration file.
|
| 214 |
+
# cplus will also be set to true is extension.language is equal to
|
| 215 |
+
# 'C++' or 'c++'.
|
| 216 |
+
#try:
|
| 217 |
+
# create_listing = self.cython_create_listing or \
|
| 218 |
+
# extension.cython_create_listing
|
| 219 |
+
# cplus = self.cython_cplus or \
|
| 220 |
+
# extension.cython_cplus or \
|
| 221 |
+
# (extension.language != None and \
|
| 222 |
+
# extension.language.lower() == 'c++')
|
| 223 |
+
#except AttributeError:
|
| 224 |
+
# create_listing = self.cython_create_listing
|
| 225 |
+
# cplus = self.cython_cplus or \
|
| 226 |
+
# (extension.language != None and \
|
| 227 |
+
# extension.language.lower() == 'c++')
|
| 228 |
+
|
| 229 |
+
create_listing = self.cython_create_listing or \
|
| 230 |
+
getattr(extension, 'cython_create_listing', 0)
|
| 231 |
+
line_directives = self.cython_line_directives or \
|
| 232 |
+
getattr(extension, 'cython_line_directives', 0)
|
| 233 |
+
no_c_in_traceback = self.no_c_in_traceback or \
|
| 234 |
+
getattr(extension, 'no_c_in_traceback', 0)
|
| 235 |
+
cplus = self.cython_cplus or getattr(extension, 'cython_cplus', 0) or \
|
| 236 |
+
(extension.language and extension.language.lower() == 'c++')
|
| 237 |
+
cython_gen_pxi = self.cython_gen_pxi or getattr(extension, 'cython_gen_pxi', 0)
|
| 238 |
+
cython_gdb = self.cython_gdb or getattr(extension, 'cython_gdb', False)
|
| 239 |
+
cython_compile_time_env = self.cython_compile_time_env or \
|
| 240 |
+
getattr(extension, 'cython_compile_time_env', None)
|
| 241 |
+
|
| 242 |
+
# Set up the include_path for the Cython compiler:
|
| 243 |
+
# 1. Start with the command line option.
|
| 244 |
+
# 2. Add in any (unique) paths from the extension
|
| 245 |
+
# cython_include_dirs (if Cython.Distutils.extension is used).
|
| 246 |
+
# 3. Add in any (unique) paths from the extension include_dirs
|
| 247 |
+
includes = list(self.cython_include_dirs)
|
| 248 |
+
try:
|
| 249 |
+
for i in extension.cython_include_dirs:
|
| 250 |
+
if i not in includes:
|
| 251 |
+
includes.append(i)
|
| 252 |
+
except AttributeError:
|
| 253 |
+
pass
|
| 254 |
+
|
| 255 |
+
# In case extension.include_dirs is a generator, evaluate it and keep
|
| 256 |
+
# result
|
| 257 |
+
extension.include_dirs = list(extension.include_dirs)
|
| 258 |
+
for i in extension.include_dirs:
|
| 259 |
+
if i not in includes:
|
| 260 |
+
includes.append(i)
|
| 261 |
+
|
| 262 |
+
# Set up Cython compiler directives:
|
| 263 |
+
# 1. Start with the command line option.
|
| 264 |
+
# 2. Add in any (unique) entries from the extension
|
| 265 |
+
# cython_directives (if Cython.Distutils.extension is used).
|
| 266 |
+
directives = dict(self.cython_directives)
|
| 267 |
+
if hasattr(extension, "cython_directives"):
|
| 268 |
+
directives.update(extension.cython_directives)
|
| 269 |
+
|
| 270 |
+
# Set the target file extension for C/C++ mode.
|
| 271 |
+
if cplus:
|
| 272 |
+
target_ext = '.cpp'
|
| 273 |
+
else:
|
| 274 |
+
target_ext = '.c'
|
| 275 |
+
|
| 276 |
+
# Decide whether to drop the generated C files into the temp dir
|
| 277 |
+
# or the source tree.
|
| 278 |
+
|
| 279 |
+
if not self.inplace and (self.cython_c_in_temp
|
| 280 |
+
or getattr(extension, 'cython_c_in_temp', 0)):
|
| 281 |
+
target_dir = os.path.join(self.build_temp, "pyrex")
|
| 282 |
+
for package_name in extension.name.split('.')[:-1]:
|
| 283 |
+
target_dir = os.path.join(target_dir, package_name)
|
| 284 |
+
else:
|
| 285 |
+
target_dir = None
|
| 286 |
+
|
| 287 |
+
newest_dependency = None
|
| 288 |
+
for source in sources:
|
| 289 |
+
(base, ext) = os.path.splitext(os.path.basename(source))
|
| 290 |
+
if ext == ".py":
|
| 291 |
+
# FIXME: we might want to special case this some more
|
| 292 |
+
ext = '.pyx'
|
| 293 |
+
if ext == ".pyx": # Cython source file
|
| 294 |
+
output_dir = target_dir or os.path.dirname(source)
|
| 295 |
+
new_sources.append(os.path.join(output_dir, base + target_ext))
|
| 296 |
+
cython_sources.append(source)
|
| 297 |
+
cython_targets[source] = new_sources[-1]
|
| 298 |
+
elif ext == '.pxi' or ext == '.pxd':
|
| 299 |
+
if newest_dependency is None \
|
| 300 |
+
or newer(source, newest_dependency):
|
| 301 |
+
newest_dependency = source
|
| 302 |
+
else:
|
| 303 |
+
new_sources.append(source)
|
| 304 |
+
|
| 305 |
+
if not cython_sources:
|
| 306 |
+
return new_sources
|
| 307 |
+
|
| 308 |
+
try:
|
| 309 |
+
from Cython.Compiler.Main \
|
| 310 |
+
import CompilationOptions, \
|
| 311 |
+
default_options as cython_default_options, \
|
| 312 |
+
compile as cython_compile
|
| 313 |
+
from Cython.Compiler.Errors import PyrexError
|
| 314 |
+
except ImportError:
|
| 315 |
+
e = sys.exc_info()[1]
|
| 316 |
+
print("failed to import Cython: %s" % e)
|
| 317 |
+
raise DistutilsPlatformError("Cython does not appear to be installed")
|
| 318 |
+
|
| 319 |
+
module_name = extension.name
|
| 320 |
+
|
| 321 |
+
for source in cython_sources:
|
| 322 |
+
target = cython_targets[source]
|
| 323 |
+
depends = [source] + list(extension.depends or ())
|
| 324 |
+
if source[-4:].lower() == ".pyx" and os.path.isfile(source[:-3] + "pxd"):
|
| 325 |
+
depends += [source[:-3] + "pxd"]
|
| 326 |
+
rebuild = self.force or newer_group(depends, target, 'newer')
|
| 327 |
+
if not rebuild and newest_dependency is not None:
|
| 328 |
+
rebuild = newer(newest_dependency, target)
|
| 329 |
+
if rebuild:
|
| 330 |
+
log.info("cythoning %s to %s", source, target)
|
| 331 |
+
self.mkpath(os.path.dirname(target))
|
| 332 |
+
if self.inplace:
|
| 333 |
+
output_dir = os.curdir
|
| 334 |
+
else:
|
| 335 |
+
output_dir = self.build_lib
|
| 336 |
+
options = CompilationOptions(cython_default_options,
|
| 337 |
+
use_listing_file = create_listing,
|
| 338 |
+
include_path = includes,
|
| 339 |
+
compiler_directives = directives,
|
| 340 |
+
output_file = target,
|
| 341 |
+
cplus = cplus,
|
| 342 |
+
emit_linenums = line_directives,
|
| 343 |
+
c_line_in_traceback = not no_c_in_traceback,
|
| 344 |
+
generate_pxi = cython_gen_pxi,
|
| 345 |
+
output_dir = output_dir,
|
| 346 |
+
gdb_debug = cython_gdb,
|
| 347 |
+
compile_time_env = cython_compile_time_env)
|
| 348 |
+
result = cython_compile(source, options=options,
|
| 349 |
+
full_module_name=module_name)
|
| 350 |
+
else:
|
| 351 |
+
log.info("skipping '%s' Cython extension (up-to-date)", target)
|
| 352 |
+
|
| 353 |
+
return new_sources
|
| 354 |
+
|
| 355 |
+
# cython_sources ()
|
| 356 |
+
|
| 357 |
+
# class build_ext
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/bytearray.pxd
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .object cimport PyObject
|
| 2 |
+
|
| 3 |
+
cdef extern from "Python.h":
|
| 4 |
+
bint PyByteArray_Check(object o)
|
| 5 |
+
# Return true if the object o is a bytearray object or an instance of a subtype of the bytearray type.
|
| 6 |
+
|
| 7 |
+
bint PyByteArray_CheckExact(object o)
|
| 8 |
+
# Return true if the object o is a bytearray object, but not an instance of a subtype of the bytearray type.
|
| 9 |
+
|
| 10 |
+
bytearray PyByteArray_FromObject(object o)
|
| 11 |
+
# Return a new bytearray object from any object, o, that implements the buffer protocol.
|
| 12 |
+
|
| 13 |
+
bytearray PyByteArray_FromStringAndSize(char *string, Py_ssize_t len)
|
| 14 |
+
# Create a new bytearray object from string and its length, len. On failure, NULL is returned.
|
| 15 |
+
|
| 16 |
+
bytearray PyByteArray_Concat(object a, object b)
|
| 17 |
+
# Concat bytearrays a and b and return a new bytearray with the result.
|
| 18 |
+
|
| 19 |
+
Py_ssize_t PyByteArray_Size(object bytearray)
|
| 20 |
+
# Return the size of bytearray after checking for a NULL pointer.
|
| 21 |
+
|
| 22 |
+
char* PyByteArray_AsString(object bytearray)
|
| 23 |
+
# Return the contents of bytearray as a char array after checking for a NULL pointer.
|
| 24 |
+
# The returned array always has an extra null byte appended.
|
| 25 |
+
|
| 26 |
+
int PyByteArray_Resize(object bytearray, Py_ssize_t len)
|
| 27 |
+
# Resize the internal buffer of bytearray to len.
|
| 28 |
+
|
| 29 |
+
char* PyByteArray_AS_STRING(object bytearray)
|
| 30 |
+
# Macro version of PyByteArray_AsString().
|
| 31 |
+
|
| 32 |
+
Py_ssize_t PyByteArray_GET_SIZE(object bytearray)
|
| 33 |
+
# Macro version of PyByteArray_Size().
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/bytes.pxd
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .object cimport PyObject
|
| 2 |
+
|
| 3 |
+
cdef extern from "Python.h":
|
| 4 |
+
ctypedef struct va_list
|
| 5 |
+
|
| 6 |
+
############################################################################
|
| 7 |
+
# 7.3.1 String Objects
|
| 8 |
+
############################################################################
|
| 9 |
+
|
| 10 |
+
# These functions raise TypeError when expecting a string
|
| 11 |
+
# parameter and are called with a non-string parameter.
|
| 12 |
+
# PyStringObject
|
| 13 |
+
# This subtype of PyObject represents a Python bytes object.
|
| 14 |
+
# PyTypeObject PyBytes_Type
|
| 15 |
+
# This instance of PyTypeObject represents the Python bytes type;
|
| 16 |
+
# it is the same object as bytes and types.BytesType in the Python
|
| 17 |
+
# layer.
|
| 18 |
+
|
| 19 |
+
bint PyBytes_Check(object o)
|
| 20 |
+
# Return true if the object o is a string object or an instance of
|
| 21 |
+
# a subtype of the string type.
|
| 22 |
+
|
| 23 |
+
bint PyBytes_CheckExact(object o)
|
| 24 |
+
# Return true if the object o is a string object, but not an instance of a subtype of the string type.
|
| 25 |
+
|
| 26 |
+
bytes PyBytes_FromString(char *v)
|
| 27 |
+
# Return value: New reference.
|
| 28 |
+
# Return a new string object with the value v on success, and NULL
|
| 29 |
+
# on failure. The parameter v must not be NULL; it will not be
|
| 30 |
+
# checked.
|
| 31 |
+
|
| 32 |
+
bytes PyBytes_FromStringAndSize(char *v, Py_ssize_t len)
|
| 33 |
+
# Return value: New reference.
|
| 34 |
+
# Return a new string object with the value v and length len on
|
| 35 |
+
# success, and NULL on failure. If v is NULL, the contents of the
|
| 36 |
+
# string are uninitialized.
|
| 37 |
+
|
| 38 |
+
bytes PyBytes_FromFormat(char *format, ...)
|
| 39 |
+
# Return value: New reference.
|
| 40 |
+
# Take a C printf()-style format string and a variable number of
|
| 41 |
+
# arguments, calculate the size of the resulting Python string and
|
| 42 |
+
# return a string with the values formatted into it. The variable
|
| 43 |
+
# arguments must be C types and must correspond exactly to the
|
| 44 |
+
# format characters in the format string. The following format
|
| 45 |
+
# characters are allowed:
|
| 46 |
+
# Format Characters Type Comment
|
| 47 |
+
# %% n/a The literal % character.
|
| 48 |
+
# %c int A single character, represented as an C int.
|
| 49 |
+
# %d int Exactly equivalent to printf("%d").
|
| 50 |
+
# %u unsigned int Exactly equivalent to printf("%u").
|
| 51 |
+
# %ld long Exactly equivalent to printf("%ld").
|
| 52 |
+
# %lu unsigned long Exactly equivalent to printf("%lu").
|
| 53 |
+
# %zd Py_ssize_t Exactly equivalent to printf("%zd").
|
| 54 |
+
# %zu size_t Exactly equivalent to printf("%zu").
|
| 55 |
+
# %i int Exactly equivalent to printf("%i").
|
| 56 |
+
# %x int Exactly equivalent to printf("%x").
|
| 57 |
+
# %s char* A null-terminated C character array.
|
| 58 |
+
|
| 59 |
+
# %p void* The hex representation of a C pointer.
|
| 60 |
+
# Mostly equivalent to printf("%p") except that it is guaranteed to
|
| 61 |
+
# start with the literal 0x regardless of what the platform's printf
|
| 62 |
+
# yields.
|
| 63 |
+
# An unrecognized format character causes all the rest of the
|
| 64 |
+
# format string to be copied as-is to the result string, and any
|
| 65 |
+
# extra arguments discarded.
|
| 66 |
+
|
| 67 |
+
bytes PyBytes_FromFormatV(char *format, va_list vargs)
|
| 68 |
+
# Return value: New reference.
|
| 69 |
+
# Identical to PyBytes_FromFormat() except that it takes exactly two arguments.
|
| 70 |
+
|
| 71 |
+
bytes PyBytes_FromObject(object o)
|
| 72 |
+
# Return value: New reference.
|
| 73 |
+
# Return the bytes representation of object o that implements the buffer protocol.
|
| 74 |
+
|
| 75 |
+
Py_ssize_t PyBytes_Size(object string) except -1
|
| 76 |
+
# Return the length of the string in string object string.
|
| 77 |
+
|
| 78 |
+
Py_ssize_t PyBytes_GET_SIZE(object string)
|
| 79 |
+
# Macro form of PyBytes_Size() but without error checking.
|
| 80 |
+
|
| 81 |
+
char* PyBytes_AsString(object string) except NULL
|
| 82 |
+
# Return a NUL-terminated representation of the contents of
|
| 83 |
+
# string. The pointer refers to the internal buffer of string, not
|
| 84 |
+
# a copy. The data must not be modified in any way, unless the
|
| 85 |
+
# string was just created using PyBytes_FromStringAndSize(NULL,
|
| 86 |
+
# size). It must not be deallocated. If string is a Unicode
|
| 87 |
+
# object, this function computes the default encoding of string
|
| 88 |
+
# and operates on that. If string is not a string object at all,
|
| 89 |
+
# PyBytes_AsString() returns NULL and raises TypeError.
|
| 90 |
+
|
| 91 |
+
char* PyBytes_AS_STRING(object string)
|
| 92 |
+
# Macro form of PyBytes_AsString() but without error
|
| 93 |
+
# checking. Only string objects are supported; no Unicode objects
|
| 94 |
+
# should be passed.
|
| 95 |
+
|
| 96 |
+
int PyBytes_AsStringAndSize(object obj, char **buffer, Py_ssize_t *length) except -1
|
| 97 |
+
# Return a NULL-terminated representation of the contents of the
|
| 98 |
+
# object obj through the output variables buffer and length.
|
| 99 |
+
#
|
| 100 |
+
# The function accepts both string and Unicode objects as
|
| 101 |
+
# input. For Unicode objects it returns the default encoded
|
| 102 |
+
# version of the object. If length is NULL, the resulting buffer
|
| 103 |
+
# may not contain NUL characters; if it does, the function returns
|
| 104 |
+
# -1 and a TypeError is raised.
|
| 105 |
+
|
| 106 |
+
# The buffer refers to an internal string buffer of obj, not a
|
| 107 |
+
# copy. The data must not be modified in any way, unless the
|
| 108 |
+
# string was just created using PyBytes_FromStringAndSize(NULL,
|
| 109 |
+
# size). It must not be deallocated. If string is a Unicode
|
| 110 |
+
# object, this function computes the default encoding of string
|
| 111 |
+
# and operates on that. If string is not a string object at all,
|
| 112 |
+
# PyBytes_AsStringAndSize() returns -1 and raises TypeError.
|
| 113 |
+
|
| 114 |
+
void PyBytes_Concat(PyObject **string, object newpart)
|
| 115 |
+
# Create a new string object in *string containing the contents of
|
| 116 |
+
# newpart appended to string; the caller will own the new
|
| 117 |
+
# reference. The reference to the old value of string will be
|
| 118 |
+
# stolen. If the new string cannot be created, the old reference
|
| 119 |
+
# to string will still be discarded and the value of *string will
|
| 120 |
+
# be set to NULL; the appropriate exception will be set.
|
| 121 |
+
|
| 122 |
+
void PyBytes_ConcatAndDel(PyObject **string, object newpart)
|
| 123 |
+
# Create a new string object in *string containing the contents of
|
| 124 |
+
# newpart appended to string. This version decrements the
|
| 125 |
+
# reference count of newpart.
|
| 126 |
+
|
| 127 |
+
int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1
|
| 128 |
+
# A way to resize a string object even though it is
|
| 129 |
+
# ``immutable''. Only use this to build up a brand new string
|
| 130 |
+
# object; don't use this if the string may already be known in
|
| 131 |
+
# other parts of the code. It is an error to call this function if
|
| 132 |
+
# the refcount on the input string object is not one. Pass the
|
| 133 |
+
# address of an existing string object as an lvalue (it may be
|
| 134 |
+
# written into), and the new size desired. On success, *string
|
| 135 |
+
# holds the resized string object and 0 is returned; the address
|
| 136 |
+
# in *string may differ from its input value. If the reallocation
|
| 137 |
+
# fails, the original string object at *string is deallocated,
|
| 138 |
+
# *string is set to NULL, a memory exception is set, and -1 is
|
| 139 |
+
# returned.
|
| 140 |
+
|
| 141 |
+
bytes PyBytes_Format(object format, object args)
|
| 142 |
+
# Return value: New reference. Return a new string object from
|
| 143 |
+
# format and args. Analogous to format % args. The args argument
|
| 144 |
+
# must be a tuple.
|
| 145 |
+
|
| 146 |
+
void PyBytes_InternInPlace(PyObject **string)
|
| 147 |
+
# Intern the argument *string in place. The argument must be the
|
| 148 |
+
# address of a pointer variable pointing to a Python string
|
| 149 |
+
# object. If there is an existing interned string that is the same
|
| 150 |
+
# as *string, it sets *string to it (decrementing the reference
|
| 151 |
+
# count of the old string object and incrementing the reference
|
| 152 |
+
# count of the interned string object), otherwise it leaves
|
| 153 |
+
# *string alone and interns it (incrementing its reference
|
| 154 |
+
# count). (Clarification: even though there is a lot of talk about
|
| 155 |
+
# reference counts, think of this function as
|
| 156 |
+
# reference-count-neutral; you own the object after the call if
|
| 157 |
+
# and only if you owned it before the call.)
|
| 158 |
+
|
| 159 |
+
bytes PyBytes_InternFromString(char *v)
|
| 160 |
+
# Return value: New reference.
|
| 161 |
+
# A combination of PyBytes_FromString() and
|
| 162 |
+
# PyBytes_InternInPlace(), returning either a new string object
|
| 163 |
+
# that has been interned, or a new (``owned'') reference to an
|
| 164 |
+
# earlier interned string object with the same value.
|
| 165 |
+
|
| 166 |
+
object PyBytes_Decode(char *s, Py_ssize_t size, char *encoding, char *errors)
|
| 167 |
+
# Return value: New reference.
|
| 168 |
+
# Create an object by decoding size bytes of the encoded buffer s
|
| 169 |
+
# using the codec registered for encoding. encoding and errors
|
| 170 |
+
# have the same meaning as the parameters of the same name in the
|
| 171 |
+
# unicode() built-in function. The codec to be used is looked up
|
| 172 |
+
# using the Python codec registry. Return NULL if an exception was
|
| 173 |
+
# raised by the codec.
|
| 174 |
+
|
| 175 |
+
object PyBytes_AsDecodedObject(object str, char *encoding, char *errors)
|
| 176 |
+
# Return value: New reference.
|
| 177 |
+
# Decode a string object by passing it to the codec registered for
|
| 178 |
+
# encoding and return the result as Python object. encoding and
|
| 179 |
+
# errors have the same meaning as the parameters of the same name
|
| 180 |
+
# in the string encode() method. The codec to be used is looked up
|
| 181 |
+
# using the Python codec registry. Return NULL if an exception was
|
| 182 |
+
# raised by the codec.
|
| 183 |
+
|
| 184 |
+
object PyBytes_Encode(char *s, Py_ssize_t size, char *encoding, char *errors)
|
| 185 |
+
# Return value: New reference.
|
| 186 |
+
# Encode the char buffer of the given size by passing it to the
|
| 187 |
+
# codec registered for encoding and return a Python
|
| 188 |
+
# object. encoding and errors have the same meaning as the
|
| 189 |
+
# parameters of the same name in the string encode() method. The
|
| 190 |
+
# codec to be used is looked up using the Python codec
|
| 191 |
+
# registry. Return NULL if an exception was raised by the codec.
|
| 192 |
+
|
| 193 |
+
object PyBytes_AsEncodedObject(object str, char *encoding, char *errors)
|
| 194 |
+
# Return value: New reference.
|
| 195 |
+
# Encode a string object using the codec registered for encoding
|
| 196 |
+
# and return the result as Python object. encoding and errors have
|
| 197 |
+
# the same meaning as the parameters of the same name in the
|
| 198 |
+
# string encode() method. The codec to be used is looked up using
|
| 199 |
+
# the Python codec registry. Return NULL if an exception was
|
| 200 |
+
# raised by the codec.
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/contextvars.pxd
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from cpython.object cimport PyObject
|
| 2 |
+
from cpython.ref cimport Py_XDECREF
|
| 3 |
+
|
| 4 |
+
cdef extern from "Python.h":
|
| 5 |
+
# Defining PyContextVar_Get() below to always return the default value for Py<3.7 and PyPy<7.3.6
|
| 6 |
+
# to make the inline functions sort-of work.
|
| 7 |
+
"""
|
| 8 |
+
#if (PY_VERSION_HEX < 0x030700b1 || (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030600)) && !defined(PyContextVar_Get)
|
| 9 |
+
#define PyContextVar_Get(var, d, v) \
|
| 10 |
+
((d) ? \
|
| 11 |
+
((void)(var), Py_INCREF(d), (v)[0] = (d), 0) : \
|
| 12 |
+
((v)[0] = NULL, 0) \
|
| 13 |
+
)
|
| 14 |
+
#endif
|
| 15 |
+
"""
|
| 16 |
+
|
| 17 |
+
############################################################################
|
| 18 |
+
# Context Variables Objects
|
| 19 |
+
############################################################################
|
| 20 |
+
|
| 21 |
+
# PyContext
|
| 22 |
+
# The C structure used to represent a `contextvars.Context` object.
|
| 23 |
+
|
| 24 |
+
# PyContextVar
|
| 25 |
+
# The C structure used to represent a `contextvars.ContextVar` object.
|
| 26 |
+
|
| 27 |
+
# PyContextToken
|
| 28 |
+
# The C structure used to represent a `contextvars.Token` object.
|
| 29 |
+
|
| 30 |
+
# PyTypeObject PyContext_Type
|
| 31 |
+
# Type object representing the `contextvars.Context` type.
|
| 32 |
+
|
| 33 |
+
# PyTypeObject PyContextVar_Type
|
| 34 |
+
# Type object representing the `contextvars.ContextVar` type.
|
| 35 |
+
|
| 36 |
+
# PyTypeObject PyContextToken_Type
|
| 37 |
+
# Type object representing the `contextvars.Token` type.
|
| 38 |
+
|
| 39 |
+
bint PyContext_CheckExact(object obj)
|
| 40 |
+
# Return `true` if `obj` is of type `PyContext_Type`.
|
| 41 |
+
# `obj` must not be NULL. This function always succeeds.
|
| 42 |
+
|
| 43 |
+
bint PyContextVar_CheckExact(object obj)
|
| 44 |
+
# Return `true` if `obj` is of type `PyContextVar_Type`.
|
| 45 |
+
# `obj` must not be NULL. This function always succeeds.
|
| 46 |
+
|
| 47 |
+
bint PyContextToken_CheckExact(object obj)
|
| 48 |
+
# Return `true` if `obj` is of type `PyContextToken_Type`.
|
| 49 |
+
# `obj` must not be NULL. This function always succeeds.
|
| 50 |
+
|
| 51 |
+
object PyContext_New()
|
| 52 |
+
# Return value: New reference.
|
| 53 |
+
# Create a new empty context object.
|
| 54 |
+
# Returns NULL if an error has occurred.
|
| 55 |
+
|
| 56 |
+
object PyContext_Copy(object ctx)
|
| 57 |
+
# Return value: New reference.
|
| 58 |
+
# Create a shallow copy of the passed `ctx` context object.
|
| 59 |
+
# Returns NULL if an error has occurred.
|
| 60 |
+
|
| 61 |
+
object PyContext_CopyCurrent()
|
| 62 |
+
# Return value: New reference.
|
| 63 |
+
# Create a shallow copy of the current thread context.
|
| 64 |
+
# Returns NULL if an error has occurred.
|
| 65 |
+
|
| 66 |
+
int PyContext_Enter(object ctx) except -1
|
| 67 |
+
# Set `ctx` as the current context for the current thread.
|
| 68 |
+
# Returns 0 on success, and -1 on error.
|
| 69 |
+
|
| 70 |
+
int PyContext_Exit(object ctx) except -1
|
| 71 |
+
# Deactivate the `ctx` context and restore the previous context
|
| 72 |
+
# as the current context for the current thread.
|
| 73 |
+
# Returns 0 on success, and -1 on error.
|
| 74 |
+
|
| 75 |
+
object PyContextVar_New(const char* name, PyObject* default_value)
|
| 76 |
+
# Return value: New reference.
|
| 77 |
+
# Create a new ContextVar object. The `name` parameter is used
|
| 78 |
+
# for introspection and debug purposes. The `default_value` parameter
|
| 79 |
+
# may optionally specify the default value for the context variable.
|
| 80 |
+
# If an error has occurred, this function returns NULL.
|
| 81 |
+
|
| 82 |
+
object PyContextVar_New_with_default "PyContextVar_New" (const char* name, object default_value)
|
| 83 |
+
# A different declaration of PyContextVar_New that requires a default value
|
| 84 |
+
# to be passed on call.
|
| 85 |
+
|
| 86 |
+
int PyContextVar_Get(object var, PyObject* default_value, PyObject** value) except -1
|
| 87 |
+
# Get the value of a context variable.
|
| 88 |
+
# Returns -1 if an error has occurred during lookup, and 0 if no error
|
| 89 |
+
# occurred, whether or not a value was found.
|
| 90 |
+
#
|
| 91 |
+
# If the context variable was found, `value` will be a pointer to it.
|
| 92 |
+
# If the context variable was not found, `value` will point to:
|
| 93 |
+
#
|
| 94 |
+
# • `default_value`, if not NULL;
|
| 95 |
+
# • the default value of `var`, if not NULL;
|
| 96 |
+
# • NULL
|
| 97 |
+
int PyContextVar_Get_with_default "PyContextVar_Get" (object var, object default_value, PyObject** value) except -1
|
| 98 |
+
# A different declaration of PyContextVar_Get that requires a default value
|
| 99 |
+
# to be passed on call.
|
| 100 |
+
|
| 101 |
+
object PyContextVar_Set(object var, object value)
|
| 102 |
+
# Return value: New reference.
|
| 103 |
+
# Set the value of `var` to `value` in the current context.
|
| 104 |
+
# Returns a token object for this value change, or NULL if an error has occurred.
|
| 105 |
+
|
| 106 |
+
int PyContextVar_Reset(object var, object token) except -1
|
| 107 |
+
# Reset the state of the `var` context variable to that it was in
|
| 108 |
+
# before `PyContextVar_Set()` that returned `token` was called.
|
| 109 |
+
# This function returns 0 on success and -1 on error.
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
cdef inline object get_value(var, default_value=None):
|
| 113 |
+
"""Return a new reference to the value of the context variable,
|
| 114 |
+
or the default value of the context variable,
|
| 115 |
+
or None if no such value or default was found.
|
| 116 |
+
"""
|
| 117 |
+
cdef PyObject *value = NULL
|
| 118 |
+
PyContextVar_Get(var, NULL, &value)
|
| 119 |
+
if value is NULL:
|
| 120 |
+
# context variable does not have a default
|
| 121 |
+
pyvalue = default_value
|
| 122 |
+
else:
|
| 123 |
+
# value or default value of context variable
|
| 124 |
+
pyvalue = <object>value
|
| 125 |
+
Py_XDECREF(value) # PyContextVar_Get() returned an owned reference as 'PyObject*'
|
| 126 |
+
return pyvalue
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
cdef inline object get_value_no_default(var, default_value=None):
|
| 130 |
+
"""Return a new reference to the value of the context variable,
|
| 131 |
+
or the provided default value if no such value was found.
|
| 132 |
+
|
| 133 |
+
Ignores the default value of the context variable, if any.
|
| 134 |
+
"""
|
| 135 |
+
cdef PyObject *value = NULL
|
| 136 |
+
PyContextVar_Get(var, <PyObject*>default_value, &value)
|
| 137 |
+
# value of context variable or 'default_value'
|
| 138 |
+
pyvalue = <object>value
|
| 139 |
+
Py_XDECREF(value) # PyContextVar_Get() returned an owned reference as 'PyObject*'
|
| 140 |
+
return pyvalue
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/datetime.pxd
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from cpython.object cimport PyObject
|
| 2 |
+
from cpython.version cimport PY_VERSION_HEX
|
| 3 |
+
|
| 4 |
+
cdef extern from "Python.h":
|
| 5 |
+
ctypedef struct PyTypeObject:
|
| 6 |
+
pass
|
| 7 |
+
|
| 8 |
+
cdef extern from "datetime.h":
|
| 9 |
+
"""
|
| 10 |
+
/* Backport for Python 2.x */
|
| 11 |
+
#if PY_MAJOR_VERSION < 3
|
| 12 |
+
#ifndef PyDateTime_DELTA_GET_DAYS
|
| 13 |
+
#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
|
| 14 |
+
#endif
|
| 15 |
+
#ifndef PyDateTime_DELTA_GET_SECONDS
|
| 16 |
+
#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds)
|
| 17 |
+
#endif
|
| 18 |
+
#ifndef PyDateTime_DELTA_GET_MICROSECONDS
|
| 19 |
+
#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds)
|
| 20 |
+
#endif
|
| 21 |
+
#endif
|
| 22 |
+
|
| 23 |
+
/* Backport for Python < 3.6 */
|
| 24 |
+
#if PY_VERSION_HEX < 0x030600a4
|
| 25 |
+
#ifndef PyDateTime_TIME_GET_FOLD
|
| 26 |
+
#define PyDateTime_TIME_GET_FOLD(o) ((void)(o), 0)
|
| 27 |
+
#endif
|
| 28 |
+
#ifndef PyDateTime_DATE_GET_FOLD
|
| 29 |
+
#define PyDateTime_DATE_GET_FOLD(o) ((void)(o), 0)
|
| 30 |
+
#endif
|
| 31 |
+
#endif
|
| 32 |
+
|
| 33 |
+
/* Backport for Python < 3.6 */
|
| 34 |
+
#if PY_VERSION_HEX < 0x030600a4
|
| 35 |
+
#define __Pyx_DateTime_DateTimeWithFold(year, month, day, hour, minute, second, microsecond, tz, fold) \
|
| 36 |
+
((void)(fold), PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, minute, second, \
|
| 37 |
+
microsecond, tz, PyDateTimeAPI->DateTimeType))
|
| 38 |
+
#define __Pyx_DateTime_TimeWithFold(hour, minute, second, microsecond, tz, fold) \
|
| 39 |
+
((void)(fold), PyDateTimeAPI->Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI->TimeType))
|
| 40 |
+
#else /* For Python 3.6+ so that we can pass tz */
|
| 41 |
+
#define __Pyx_DateTime_DateTimeWithFold(year, month, day, hour, minute, second, microsecond, tz, fold) \
|
| 42 |
+
PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, minute, second, \
|
| 43 |
+
microsecond, tz, fold, PyDateTimeAPI->DateTimeType)
|
| 44 |
+
#define __Pyx_DateTime_TimeWithFold(hour, minute, second, microsecond, tz, fold) \
|
| 45 |
+
PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, microsecond, tz, fold, PyDateTimeAPI->TimeType)
|
| 46 |
+
#endif
|
| 47 |
+
|
| 48 |
+
/* Backport for Python < 3.7 */
|
| 49 |
+
#if PY_VERSION_HEX < 0x030700b1
|
| 50 |
+
#define __Pyx_TimeZone_UTC NULL
|
| 51 |
+
#define __Pyx_TimeZone_FromOffsetAndName(offset, name) ((void)(offset), (void)(name), (PyObject*)NULL)
|
| 52 |
+
#else
|
| 53 |
+
#define __Pyx_TimeZone_UTC PyDateTime_TimeZone_UTC
|
| 54 |
+
#define __Pyx_TimeZone_FromOffsetAndName(offset, name) PyTimeZone_FromOffsetAndName(offset, name)
|
| 55 |
+
#endif
|
| 56 |
+
|
| 57 |
+
/* Backport for Python < 3.10 */
|
| 58 |
+
#if PY_VERSION_HEX < 0x030a00a1
|
| 59 |
+
#ifndef PyDateTime_TIME_GET_TZINFO
|
| 60 |
+
#define PyDateTime_TIME_GET_TZINFO(o) \
|
| 61 |
+
((((PyDateTime_Time*)o)->hastzinfo) ? ((PyDateTime_Time*)o)->tzinfo : Py_None)
|
| 62 |
+
#endif
|
| 63 |
+
#ifndef PyDateTime_DATE_GET_TZINFO
|
| 64 |
+
#define PyDateTime_DATE_GET_TZINFO(o) \
|
| 65 |
+
((((PyDateTime_DateTime*)o)->hastzinfo) ? ((PyDateTime_DateTime*)o)->tzinfo : Py_None)
|
| 66 |
+
#endif
|
| 67 |
+
#endif
|
| 68 |
+
"""
|
| 69 |
+
|
| 70 |
+
ctypedef extern class datetime.date[object PyDateTime_Date]:
|
| 71 |
+
@property
|
| 72 |
+
cdef inline int year(self) noexcept:
|
| 73 |
+
return PyDateTime_GET_YEAR(self)
|
| 74 |
+
|
| 75 |
+
@property
|
| 76 |
+
cdef inline int month(self) noexcept:
|
| 77 |
+
return PyDateTime_GET_MONTH(self)
|
| 78 |
+
|
| 79 |
+
@property
|
| 80 |
+
cdef inline int day(self) noexcept:
|
| 81 |
+
return PyDateTime_GET_DAY(self)
|
| 82 |
+
|
| 83 |
+
ctypedef extern class datetime.time[object PyDateTime_Time]:
|
| 84 |
+
@property
|
| 85 |
+
cdef inline int hour(self) noexcept:
|
| 86 |
+
return PyDateTime_TIME_GET_HOUR(self)
|
| 87 |
+
|
| 88 |
+
@property
|
| 89 |
+
cdef inline int minute(self) noexcept:
|
| 90 |
+
return PyDateTime_TIME_GET_MINUTE(self)
|
| 91 |
+
|
| 92 |
+
@property
|
| 93 |
+
cdef inline int second(self) noexcept:
|
| 94 |
+
return PyDateTime_TIME_GET_SECOND(self)
|
| 95 |
+
|
| 96 |
+
@property
|
| 97 |
+
cdef inline int microsecond(self) noexcept:
|
| 98 |
+
return PyDateTime_TIME_GET_MICROSECOND(self)
|
| 99 |
+
|
| 100 |
+
@property
|
| 101 |
+
cdef inline object tzinfo(self):
|
| 102 |
+
return <object>PyDateTime_TIME_GET_TZINFO(self)
|
| 103 |
+
|
| 104 |
+
@property
|
| 105 |
+
cdef inline int fold(self) noexcept:
|
| 106 |
+
# For Python < 3.6 this returns 0 no matter what
|
| 107 |
+
return PyDateTime_TIME_GET_FOLD(self)
|
| 108 |
+
|
| 109 |
+
ctypedef extern class datetime.datetime[object PyDateTime_DateTime]:
|
| 110 |
+
@property
|
| 111 |
+
cdef inline int year(self) noexcept:
|
| 112 |
+
return PyDateTime_GET_YEAR(self)
|
| 113 |
+
|
| 114 |
+
@property
|
| 115 |
+
cdef inline int month(self) noexcept:
|
| 116 |
+
return PyDateTime_GET_MONTH(self)
|
| 117 |
+
|
| 118 |
+
@property
|
| 119 |
+
cdef inline int day(self) noexcept:
|
| 120 |
+
return PyDateTime_GET_DAY(self)
|
| 121 |
+
|
| 122 |
+
@property
|
| 123 |
+
cdef inline int hour(self) noexcept:
|
| 124 |
+
return PyDateTime_DATE_GET_HOUR(self)
|
| 125 |
+
|
| 126 |
+
@property
|
| 127 |
+
cdef inline int minute(self) noexcept:
|
| 128 |
+
return PyDateTime_DATE_GET_MINUTE(self)
|
| 129 |
+
|
| 130 |
+
@property
|
| 131 |
+
cdef inline int second(self) noexcept:
|
| 132 |
+
return PyDateTime_DATE_GET_SECOND(self)
|
| 133 |
+
|
| 134 |
+
@property
|
| 135 |
+
cdef inline int microsecond(self) noexcept:
|
| 136 |
+
return PyDateTime_DATE_GET_MICROSECOND(self)
|
| 137 |
+
|
| 138 |
+
@property
|
| 139 |
+
cdef inline object tzinfo(self):
|
| 140 |
+
return <object>PyDateTime_DATE_GET_TZINFO(self)
|
| 141 |
+
|
| 142 |
+
@property
|
| 143 |
+
cdef inline int fold(self) noexcept:
|
| 144 |
+
# For Python < 3.6 this returns 0 no matter what
|
| 145 |
+
return PyDateTime_DATE_GET_FOLD(self)
|
| 146 |
+
|
| 147 |
+
ctypedef extern class datetime.timedelta[object PyDateTime_Delta]:
|
| 148 |
+
@property
|
| 149 |
+
cdef inline int day(self) noexcept:
|
| 150 |
+
return PyDateTime_DELTA_GET_DAYS(self)
|
| 151 |
+
|
| 152 |
+
@property
|
| 153 |
+
cdef inline int second(self) noexcept:
|
| 154 |
+
return PyDateTime_DELTA_GET_SECONDS(self)
|
| 155 |
+
|
| 156 |
+
@property
|
| 157 |
+
cdef inline int microsecond(self) noexcept:
|
| 158 |
+
return PyDateTime_DELTA_GET_MICROSECONDS(self)
|
| 159 |
+
|
| 160 |
+
ctypedef extern class datetime.tzinfo[object PyDateTime_TZInfo]:
|
| 161 |
+
pass
|
| 162 |
+
|
| 163 |
+
ctypedef struct PyDateTime_Date:
|
| 164 |
+
pass
|
| 165 |
+
|
| 166 |
+
ctypedef struct PyDateTime_Time:
|
| 167 |
+
unsigned char fold
|
| 168 |
+
char hastzinfo
|
| 169 |
+
PyObject *tzinfo
|
| 170 |
+
|
| 171 |
+
ctypedef struct PyDateTime_DateTime:
|
| 172 |
+
unsigned char fold
|
| 173 |
+
char hastzinfo
|
| 174 |
+
PyObject *tzinfo
|
| 175 |
+
|
| 176 |
+
ctypedef struct PyDateTime_Delta:
|
| 177 |
+
int days
|
| 178 |
+
int seconds
|
| 179 |
+
int microseconds
|
| 180 |
+
|
| 181 |
+
# Define structure for C API.
|
| 182 |
+
ctypedef struct PyDateTime_CAPI:
|
| 183 |
+
# type objects
|
| 184 |
+
PyTypeObject *DateType
|
| 185 |
+
PyTypeObject *DateTimeType
|
| 186 |
+
PyTypeObject *TimeType
|
| 187 |
+
PyTypeObject *DeltaType
|
| 188 |
+
PyTypeObject *TZInfoType
|
| 189 |
+
|
| 190 |
+
# constructors
|
| 191 |
+
date (*Date_FromDate)(int, int, int, PyTypeObject*)
|
| 192 |
+
datetime (*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, object, PyTypeObject*)
|
| 193 |
+
time (*Time_FromTime)(int, int, int, int, object, PyTypeObject*)
|
| 194 |
+
timedelta (*Delta_FromDelta)(int, int, int, int, PyTypeObject*)
|
| 195 |
+
|
| 196 |
+
# constructors for the DB API
|
| 197 |
+
datetime (*DateTime_FromTimestamp)(PyObject*, object, PyObject*)
|
| 198 |
+
date (*Date_FromTimestamp)(PyObject*, object)
|
| 199 |
+
|
| 200 |
+
# We cannot use the following because they do not compile in older Python versions.
|
| 201 |
+
# Instead, we use datetime.h's macros here that we can backport in C.
|
| 202 |
+
|
| 203 |
+
# Python 3.7+ constructors
|
| 204 |
+
object (*TimeZone_FromTimeZone)(object offset, PyObject *name)
|
| 205 |
+
|
| 206 |
+
# Python 3.7+ singletons
|
| 207 |
+
PyObject *TimeZone_UTC
|
| 208 |
+
|
| 209 |
+
# Python 3.6+ PEP 495 constructors
|
| 210 |
+
datetime (*DateTime_FromDateAndTimeAndFold)(int, int, int, int, int, int, int, object, int, PyTypeObject*)
|
| 211 |
+
time (*Time_FromTimeAndFold)(int, int, int ,int, object, int, PyTypeObject*)
|
| 212 |
+
|
| 213 |
+
# Check type of the object.
|
| 214 |
+
bint PyDate_Check(object op)
|
| 215 |
+
bint PyDate_CheckExact(object op)
|
| 216 |
+
|
| 217 |
+
bint PyDateTime_Check(object op)
|
| 218 |
+
bint PyDateTime_CheckExact(object op)
|
| 219 |
+
|
| 220 |
+
bint PyTime_Check(object op)
|
| 221 |
+
bint PyTime_CheckExact(object op)
|
| 222 |
+
|
| 223 |
+
bint PyDelta_Check(object op)
|
| 224 |
+
bint PyDelta_CheckExact(object op)
|
| 225 |
+
|
| 226 |
+
bint PyTZInfo_Check(object op)
|
| 227 |
+
bint PyTZInfo_CheckExact(object op)
|
| 228 |
+
|
| 229 |
+
# Getters for date and datetime (C macros).
|
| 230 |
+
int PyDateTime_GET_YEAR(object o)
|
| 231 |
+
int PyDateTime_GET_MONTH(object o)
|
| 232 |
+
int PyDateTime_GET_DAY(object o)
|
| 233 |
+
|
| 234 |
+
# Getters for datetime (C macros).
|
| 235 |
+
int PyDateTime_DATE_GET_HOUR(object o)
|
| 236 |
+
int PyDateTime_DATE_GET_MINUTE(object o)
|
| 237 |
+
int PyDateTime_DATE_GET_SECOND(object o)
|
| 238 |
+
int PyDateTime_DATE_GET_MICROSECOND(object o)
|
| 239 |
+
int PyDateTime_DATE_GET_FOLD(object o)
|
| 240 |
+
PyObject* PyDateTime_DATE_GET_TZINFO(object o) # returns a borrowed reference
|
| 241 |
+
|
| 242 |
+
# Getters for time (C macros).
|
| 243 |
+
int PyDateTime_TIME_GET_HOUR(object o)
|
| 244 |
+
int PyDateTime_TIME_GET_MINUTE(object o)
|
| 245 |
+
int PyDateTime_TIME_GET_SECOND(object o)
|
| 246 |
+
int PyDateTime_TIME_GET_MICROSECOND(object o)
|
| 247 |
+
int PyDateTime_TIME_GET_FOLD(object o)
|
| 248 |
+
PyObject* PyDateTime_TIME_GET_TZINFO(object o) # returns a borrowed reference
|
| 249 |
+
|
| 250 |
+
# Getters for timedelta (C macros).
|
| 251 |
+
int PyDateTime_DELTA_GET_DAYS(object o)
|
| 252 |
+
int PyDateTime_DELTA_GET_SECONDS(object o)
|
| 253 |
+
int PyDateTime_DELTA_GET_MICROSECONDS(object o)
|
| 254 |
+
|
| 255 |
+
# Constructors
|
| 256 |
+
object PyTimeZone_FromOffset(object offset)
|
| 257 |
+
object PyTimeZone_FromOffsetAndName(object offset, object name)
|
| 258 |
+
|
| 259 |
+
# The above macros is Python 3.7+ so we use these instead
|
| 260 |
+
object __Pyx_TimeZone_FromOffsetAndName(object offset, PyObject* name)
|
| 261 |
+
|
| 262 |
+
# Constructors for the DB API
|
| 263 |
+
datetime PyDateTime_FromTimeStamp(object args)
|
| 264 |
+
date PyDate_FromTimeStamp(object args)
|
| 265 |
+
|
| 266 |
+
# PEP 495 constructors but patched above to allow passing tz
|
| 267 |
+
datetime __Pyx_DateTime_DateTimeWithFold(int, int, int, int, int, int, int, object, int)
|
| 268 |
+
datetime __Pyx_DateTime_TimeWithFold(int, int, int ,int, object, int)
|
| 269 |
+
|
| 270 |
+
# PyDateTime CAPI object.
|
| 271 |
+
PyDateTime_CAPI *PyDateTimeAPI
|
| 272 |
+
|
| 273 |
+
PyObject* PyDateTime_TimeZone_UTC
|
| 274 |
+
|
| 275 |
+
# PyDateTime_TimeZone_UTC is Python 3.7+ so instead we use the following macro
|
| 276 |
+
PyObject* __Pyx_TimeZone_UTC
|
| 277 |
+
|
| 278 |
+
void PyDateTime_IMPORT()
|
| 279 |
+
|
| 280 |
+
# Datetime C API initialization function.
|
| 281 |
+
# You have to call it before any usage of DateTime CAPI functions.
|
| 282 |
+
cdef inline void import_datetime() noexcept:
|
| 283 |
+
PyDateTime_IMPORT
|
| 284 |
+
|
| 285 |
+
# Create date object using DateTime CAPI factory function.
|
| 286 |
+
# Note, there are no range checks for any of the arguments.
|
| 287 |
+
cdef inline date date_new(int year, int month, int day):
|
| 288 |
+
return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType)
|
| 289 |
+
|
| 290 |
+
# Create time object using DateTime CAPI factory function
|
| 291 |
+
# Note, there are no range checks for any of the arguments.
|
| 292 |
+
cdef inline time time_new(int hour, int minute, int second, int microsecond, object tz, int fold=0):
|
| 293 |
+
return __Pyx_DateTime_TimeWithFold(hour, minute, second, microsecond, tz, fold)
|
| 294 |
+
|
| 295 |
+
# Create datetime object using DateTime CAPI factory function.
|
| 296 |
+
# Note, there are no range checks for any of the arguments.
|
| 297 |
+
cdef inline datetime datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz, int fold=0):
|
| 298 |
+
return __Pyx_DateTime_DateTimeWithFold(year, month, day, hour, minute, second, microsecond, tz, fold)
|
| 299 |
+
|
| 300 |
+
# Create timedelta object using DateTime CAPI factory function.
|
| 301 |
+
# Note, there are no range checks for any of the arguments.
|
| 302 |
+
cdef inline timedelta timedelta_new(int days, int seconds, int useconds):
|
| 303 |
+
return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType)
|
| 304 |
+
|
| 305 |
+
# Create timedelta object using DateTime CAPI factory function.
|
| 306 |
+
cdef inline object timezone_new(object offset, object name=None):
|
| 307 |
+
if PY_VERSION_HEX < 0x030700b1:
|
| 308 |
+
raise RuntimeError('Time zones are not available from the C-API.')
|
| 309 |
+
return __Pyx_TimeZone_FromOffsetAndName(offset, <PyObject*>name if name is not None else NULL)
|
| 310 |
+
|
| 311 |
+
# Create datetime object using DB API constructor.
|
| 312 |
+
cdef inline datetime datetime_from_timestamp(timestamp, tz=None):
|
| 313 |
+
return PyDateTimeAPI.DateTime_FromTimestamp(
|
| 314 |
+
<PyObject*>PyDateTimeAPI.DateTimeType, (timestamp, tz) if tz is not None else (timestamp,), NULL)
|
| 315 |
+
|
| 316 |
+
# Create date object using DB API constructor.
|
| 317 |
+
cdef inline date date_from_timestamp(timestamp):
|
| 318 |
+
return PyDateTimeAPI.Date_FromTimestamp(<PyObject*>PyDateTimeAPI.DateType, (timestamp,))
|
| 319 |
+
|
| 320 |
+
# More recognizable getters for date/time/datetime/timedelta.
|
| 321 |
+
# There are no setters because datetime.h hasn't them.
|
| 322 |
+
# This is because of immutable nature of these objects by design.
|
| 323 |
+
# If you would change time/date/datetime/timedelta object you need to recreate.
|
| 324 |
+
|
| 325 |
+
# Get UTC singleton
|
| 326 |
+
cdef inline object get_utc():
|
| 327 |
+
if PY_VERSION_HEX < 0x030700b1:
|
| 328 |
+
raise RuntimeError('Time zones are not available from the C-API.')
|
| 329 |
+
return <object>__Pyx_TimeZone_UTC
|
| 330 |
+
|
| 331 |
+
# Get tzinfo of time
|
| 332 |
+
cdef inline object time_tzinfo(object o):
|
| 333 |
+
return <object>PyDateTime_TIME_GET_TZINFO(o)
|
| 334 |
+
|
| 335 |
+
# Get tzinfo of datetime
|
| 336 |
+
cdef inline object datetime_tzinfo(object o):
|
| 337 |
+
return <object>PyDateTime_DATE_GET_TZINFO(o)
|
| 338 |
+
|
| 339 |
+
# Get year of date
|
| 340 |
+
cdef inline int date_year(object o) noexcept:
|
| 341 |
+
return PyDateTime_GET_YEAR(o)
|
| 342 |
+
|
| 343 |
+
# Get month of date
|
| 344 |
+
cdef inline int date_month(object o) noexcept:
|
| 345 |
+
return PyDateTime_GET_MONTH(o)
|
| 346 |
+
|
| 347 |
+
# Get day of date
|
| 348 |
+
cdef inline int date_day(object o) noexcept:
|
| 349 |
+
return PyDateTime_GET_DAY(o)
|
| 350 |
+
|
| 351 |
+
# Get year of datetime
|
| 352 |
+
cdef inline int datetime_year(object o) noexcept:
|
| 353 |
+
return PyDateTime_GET_YEAR(o)
|
| 354 |
+
|
| 355 |
+
# Get month of datetime
|
| 356 |
+
cdef inline int datetime_month(object o) noexcept:
|
| 357 |
+
return PyDateTime_GET_MONTH(o)
|
| 358 |
+
|
| 359 |
+
# Get day of datetime
|
| 360 |
+
cdef inline int datetime_day(object o) noexcept:
|
| 361 |
+
return PyDateTime_GET_DAY(o)
|
| 362 |
+
|
| 363 |
+
# Get hour of time
|
| 364 |
+
cdef inline int time_hour(object o) noexcept:
|
| 365 |
+
return PyDateTime_TIME_GET_HOUR(o)
|
| 366 |
+
|
| 367 |
+
# Get minute of time
|
| 368 |
+
cdef inline int time_minute(object o) noexcept:
|
| 369 |
+
return PyDateTime_TIME_GET_MINUTE(o)
|
| 370 |
+
|
| 371 |
+
# Get second of time
|
| 372 |
+
cdef inline int time_second(object o) noexcept:
|
| 373 |
+
return PyDateTime_TIME_GET_SECOND(o)
|
| 374 |
+
|
| 375 |
+
# Get microsecond of time
|
| 376 |
+
cdef inline int time_microsecond(object o) noexcept:
|
| 377 |
+
return PyDateTime_TIME_GET_MICROSECOND(o)
|
| 378 |
+
|
| 379 |
+
# Get fold of time
|
| 380 |
+
cdef inline int time_fold(object o) noexcept:
|
| 381 |
+
# For Python < 3.6 this returns 0 no matter what
|
| 382 |
+
return PyDateTime_TIME_GET_FOLD(o)
|
| 383 |
+
|
| 384 |
+
# Get hour of datetime
|
| 385 |
+
cdef inline int datetime_hour(object o) noexcept:
|
| 386 |
+
return PyDateTime_DATE_GET_HOUR(o)
|
| 387 |
+
|
| 388 |
+
# Get minute of datetime
|
| 389 |
+
cdef inline int datetime_minute(object o) noexcept:
|
| 390 |
+
return PyDateTime_DATE_GET_MINUTE(o)
|
| 391 |
+
|
| 392 |
+
# Get second of datetime
|
| 393 |
+
cdef inline int datetime_second(object o) noexcept:
|
| 394 |
+
return PyDateTime_DATE_GET_SECOND(o)
|
| 395 |
+
|
| 396 |
+
# Get microsecond of datetime
|
| 397 |
+
cdef inline int datetime_microsecond(object o) noexcept:
|
| 398 |
+
return PyDateTime_DATE_GET_MICROSECOND(o)
|
| 399 |
+
|
| 400 |
+
# Get fold of datetime
|
| 401 |
+
cdef inline int datetime_fold(object o) noexcept:
|
| 402 |
+
# For Python < 3.6 this returns 0 no matter what
|
| 403 |
+
return PyDateTime_DATE_GET_FOLD(o)
|
| 404 |
+
|
| 405 |
+
# Get days of timedelta
|
| 406 |
+
cdef inline int timedelta_days(object o) noexcept:
|
| 407 |
+
return (<PyDateTime_Delta*>o).days
|
| 408 |
+
|
| 409 |
+
# Get seconds of timedelta
|
| 410 |
+
cdef inline int timedelta_seconds(object o) noexcept:
|
| 411 |
+
return (<PyDateTime_Delta*>o).seconds
|
| 412 |
+
|
| 413 |
+
# Get microseconds of timedelta
|
| 414 |
+
cdef inline int timedelta_microseconds(object o) noexcept:
|
| 415 |
+
return (<PyDateTime_Delta*>o).microseconds
|
| 416 |
+
|
| 417 |
+
cdef inline double total_seconds(timedelta obj) noexcept:
|
| 418 |
+
# Mirrors the "timedelta.total_seconds()" method.
|
| 419 |
+
# Note that this implementation is not guaranteed to give *exactly* the same
|
| 420 |
+
# result as the original method, due to potential differences in floating point rounding.
|
| 421 |
+
cdef:
|
| 422 |
+
double days, seconds, micros
|
| 423 |
+
days = <double>PyDateTime_DELTA_GET_DAYS(obj)
|
| 424 |
+
seconds = <double>PyDateTime_DELTA_GET_SECONDS(obj)
|
| 425 |
+
micros = <double>PyDateTime_DELTA_GET_MICROSECONDS(obj)
|
| 426 |
+
return days * 24 * 3600 + seconds + micros / 1_000_000
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/dict.pxd
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .object cimport PyObject
|
| 2 |
+
from .pyport cimport uint64_t
|
| 3 |
+
|
| 4 |
+
cdef extern from "Python.h":
|
| 5 |
+
# On Python 2, PyDict_GetItemWithError is called _PyDict_GetItemWithError
|
| 6 |
+
"""
|
| 7 |
+
#if PY_MAJOR_VERSION <= 2
|
| 8 |
+
#define PyDict_GetItemWithError _PyDict_GetItemWithError
|
| 9 |
+
#endif
|
| 10 |
+
"""
|
| 11 |
+
|
| 12 |
+
############################################################################
|
| 13 |
+
# 7.4.1 Dictionary Objects
|
| 14 |
+
############################################################################
|
| 15 |
+
|
| 16 |
+
# PyDictObject
|
| 17 |
+
#
|
| 18 |
+
# This subtype of PyObject represents a Python dictionary object
|
| 19 |
+
# (i.e. the 'dict' type).
|
| 20 |
+
|
| 21 |
+
# PyTypeObject PyDict_Type
|
| 22 |
+
#
|
| 23 |
+
# This instance of PyTypeObject represents the Python dictionary
|
| 24 |
+
# type. This is exposed to Python programs as dict and
|
| 25 |
+
# types.DictType.
|
| 26 |
+
|
| 27 |
+
bint PyDict_Check(object p)
|
| 28 |
+
# Return true if p is a dict object or an instance of a subtype of
|
| 29 |
+
# the dict type.
|
| 30 |
+
|
| 31 |
+
bint PyDict_CheckExact(object p)
|
| 32 |
+
# Return true if p is a dict object, but not an instance of a
|
| 33 |
+
# subtype of the dict type.
|
| 34 |
+
|
| 35 |
+
dict PyDict_New()
|
| 36 |
+
# Return value: New reference.
|
| 37 |
+
# Return a new empty dictionary, or NULL on failure.
|
| 38 |
+
|
| 39 |
+
object PyDictProxy_New(object dict)
|
| 40 |
+
# Return value: New reference.
|
| 41 |
+
# Return a proxy object for a mapping which enforces read-only
|
| 42 |
+
# behavior. This is normally used to create a proxy to prevent
|
| 43 |
+
# modification of the dictionary for non-dynamic class types.
|
| 44 |
+
|
| 45 |
+
void PyDict_Clear(object p)
|
| 46 |
+
# Empty an existing dictionary of all key-value pairs.
|
| 47 |
+
|
| 48 |
+
int PyDict_Contains(object p, object key) except -1
|
| 49 |
+
# Determine if dictionary p contains key. If an item in p is
|
| 50 |
+
# matches key, return 1, otherwise return 0. On error, return
|
| 51 |
+
# -1. This is equivalent to the Python expression "key in p".
|
| 52 |
+
|
| 53 |
+
dict PyDict_Copy(object p)
|
| 54 |
+
# Return value: New reference.
|
| 55 |
+
# Return a new dictionary that contains the same key-value pairs as p.
|
| 56 |
+
|
| 57 |
+
int PyDict_SetItem(object p, object key, object val) except -1
|
| 58 |
+
# Insert value into the dictionary p with a key of key. key must
|
| 59 |
+
# be hashable; if it isn't, TypeError will be raised. Return 0 on
|
| 60 |
+
# success or -1 on failure.
|
| 61 |
+
|
| 62 |
+
int PyDict_SetItemString(object p, const char *key, object val) except -1
|
| 63 |
+
# Insert value into the dictionary p using key as a key. key
|
| 64 |
+
# should be a char*. The key object is created using
|
| 65 |
+
# PyString_FromString(key). Return 0 on success or -1 on failure.
|
| 66 |
+
|
| 67 |
+
int PyDict_DelItem(object p, object key) except -1
|
| 68 |
+
# Remove the entry in dictionary p with key key. key must be
|
| 69 |
+
# hashable; if it isn't, TypeError is raised. Return 0 on success
|
| 70 |
+
# or -1 on failure.
|
| 71 |
+
|
| 72 |
+
int PyDict_DelItemString(object p, const char *key) except -1
|
| 73 |
+
# Remove the entry in dictionary p which has a key specified by
|
| 74 |
+
# the string key. Return 0 on success or -1 on failure.
|
| 75 |
+
|
| 76 |
+
PyObject* PyDict_GetItem(object p, object key)
|
| 77 |
+
# Return value: Borrowed reference.
|
| 78 |
+
# Return the object from dictionary p which has a key key. Return
|
| 79 |
+
# NULL if the key key is not present, but without setting an
|
| 80 |
+
# exception.
|
| 81 |
+
|
| 82 |
+
PyObject* PyDict_GetItemWithError(object p, object key) except? NULL
|
| 83 |
+
# Return value: Borrowed reference.
|
| 84 |
+
# Variant of PyDict_GetItem() that does not suppress exceptions. Return
|
| 85 |
+
# NULL with an exception set if an exception occurred. Return NULL
|
| 86 |
+
# without an exception set if the key wasn’t present.
|
| 87 |
+
|
| 88 |
+
PyObject* PyDict_GetItemString(object p, const char *key)
|
| 89 |
+
# Return value: Borrowed reference.
|
| 90 |
+
# This is the same as PyDict_GetItem(), but key is specified as a
|
| 91 |
+
# char*, rather than a PyObject*.
|
| 92 |
+
|
| 93 |
+
PyObject* PyDict_SetDefault(object p, object key, object default) except NULL
|
| 94 |
+
# Return value: Borrowed reference.
|
| 95 |
+
# This is the same as the Python-level dict.setdefault(). If present, it
|
| 96 |
+
# returns the value corresponding to key from the dictionary p. If the key
|
| 97 |
+
# is not in the dict, it is inserted with value defaultobj and defaultobj
|
| 98 |
+
# is returned. This function evaluates the hash function of key only once,
|
| 99 |
+
# instead of evaluating it independently for the lookup and the insertion.
|
| 100 |
+
|
| 101 |
+
list PyDict_Items(object p)
|
| 102 |
+
# Return value: New reference.
|
| 103 |
+
# Return a PyListObject containing all the items from the
|
| 104 |
+
# dictionary, as in the dictionary method items() (see the Python
|
| 105 |
+
# Library Reference).
|
| 106 |
+
|
| 107 |
+
list PyDict_Keys(object p)
|
| 108 |
+
# Return value: New reference.
|
| 109 |
+
# Return a PyListObject containing all the keys from the
|
| 110 |
+
# dictionary, as in the dictionary method keys() (see the Python
|
| 111 |
+
# Library Reference).
|
| 112 |
+
|
| 113 |
+
list PyDict_Values(object p)
|
| 114 |
+
# Return value: New reference.
|
| 115 |
+
# Return a PyListObject containing all the values from the
|
| 116 |
+
# dictionary p, as in the dictionary method values() (see the
|
| 117 |
+
# Python Library Reference).
|
| 118 |
+
|
| 119 |
+
Py_ssize_t PyDict_Size(object p) except -1
|
| 120 |
+
# Return the number of items in the dictionary. This is equivalent
|
| 121 |
+
# to "len(p)" on a dictionary.
|
| 122 |
+
|
| 123 |
+
int PyDict_Next(object p, Py_ssize_t *ppos, PyObject* *pkey, PyObject* *pvalue)
|
| 124 |
+
# Iterate over all key-value pairs in the dictionary p. The int
|
| 125 |
+
# referred to by ppos must be initialized to 0 prior to the first
|
| 126 |
+
# call to this function to start the iteration; the function
|
| 127 |
+
# returns true for each pair in the dictionary, and false once all
|
| 128 |
+
# pairs have been reported. The parameters pkey and pvalue should
|
| 129 |
+
# either point to PyObject* variables that will be filled in with
|
| 130 |
+
# each key and value, respectively, or may be NULL. Any references
|
| 131 |
+
# returned through them are borrowed. ppos should not be altered
|
| 132 |
+
# during iteration. Its value represents offsets within the
|
| 133 |
+
# internal dictionary structure, and since the structure is
|
| 134 |
+
# sparse, the offsets are not consecutive.
|
| 135 |
+
# For example:
|
| 136 |
+
#
|
| 137 |
+
#object key, *value;
|
| 138 |
+
#int pos = 0;
|
| 139 |
+
#
|
| 140 |
+
#while (PyDict_Next(self->dict, &pos, &key, &value)) {
|
| 141 |
+
# /* do something interesting with the values... */
|
| 142 |
+
# ...
|
| 143 |
+
#}
|
| 144 |
+
# The dictionary p should not be mutated during iteration. It is
|
| 145 |
+
# safe (since Python 2.1) to modify the values of the keys as you
|
| 146 |
+
# iterate over the dictionary, but only so long as the set of keys
|
| 147 |
+
# does not change. For example:
|
| 148 |
+
# object key, *value;
|
| 149 |
+
# int pos = 0;
|
| 150 |
+
# while (PyDict_Next(self->dict, &pos, &key, &value)) {
|
| 151 |
+
# int i = PyInt_AS_LONG(value) + 1;
|
| 152 |
+
# object o = PyInt_FromLong(i);
|
| 153 |
+
# if (o == NULL)
|
| 154 |
+
# return -1;
|
| 155 |
+
# if (PyDict_SetItem(self->dict, key, o) < 0) {
|
| 156 |
+
# Py_DECREF(o);
|
| 157 |
+
# return -1;
|
| 158 |
+
# }
|
| 159 |
+
# Py_DECREF(o);
|
| 160 |
+
# }
|
| 161 |
+
|
| 162 |
+
int PyDict_Merge(object a, object b, int override) except -1
|
| 163 |
+
# Iterate over mapping object b adding key-value pairs to
|
| 164 |
+
# dictionary a. b may be a dictionary, or any object supporting
|
| 165 |
+
# PyMapping_Keys() and PyObject_GetItem(). If override is true,
|
| 166 |
+
# existing pairs in a will be replaced if a matching key is found
|
| 167 |
+
# in b, otherwise pairs will only be added if there is not a
|
| 168 |
+
# matching key in a. Return 0 on success or -1 if an exception was
|
| 169 |
+
# raised.
|
| 170 |
+
|
| 171 |
+
int PyDict_Update(object a, object b) except -1
|
| 172 |
+
# This is the same as PyDict_Merge(a, b, 1) in C, or a.update(b)
|
| 173 |
+
# in Python. Return 0 on success or -1 if an exception was raised.
|
| 174 |
+
|
| 175 |
+
int PyDict_MergeFromSeq2(object a, object seq2, int override) except -1
|
| 176 |
+
# Update or merge into dictionary a, from the key-value pairs in
|
| 177 |
+
# seq2. seq2 must be an iterable object producing iterable objects
|
| 178 |
+
# of length 2, viewed as key-value pairs. In case of duplicate
|
| 179 |
+
# keys, the last wins if override is true, else the first
|
| 180 |
+
# wins. Return 0 on success or -1 if an exception was
|
| 181 |
+
# raised. Equivalent Python (except for the return value):
|
| 182 |
+
#
|
| 183 |
+
#def PyDict_MergeFromSeq2(a, seq2, override):
|
| 184 |
+
# for key, value in seq2:
|
| 185 |
+
# if override or key not in a:
|
| 186 |
+
# a[key] = value
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/genobject.pxd
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .pystate cimport PyFrameObject
|
| 2 |
+
|
| 3 |
+
cdef extern from "Python.h":
|
| 4 |
+
|
| 5 |
+
###########################################################################
|
| 6 |
+
# Generator Objects
|
| 7 |
+
###########################################################################
|
| 8 |
+
|
| 9 |
+
bint PyGen_Check(object ob)
|
| 10 |
+
# Return true if ob is a generator object; ob must not be NULL.
|
| 11 |
+
|
| 12 |
+
bint PyGen_CheckExact(object ob)
|
| 13 |
+
# Return true if ob's type is PyGen_Type; ob must not be NULL.
|
| 14 |
+
|
| 15 |
+
object PyGen_New(PyFrameObject *frame)
|
| 16 |
+
# Return value: New reference.
|
| 17 |
+
# Create and return a new generator object based on the frame object. A
|
| 18 |
+
# reference to frame is stolen by this function. The argument must not be
|
| 19 |
+
# NULL.
|
| 20 |
+
|
| 21 |
+
object PyGen_NewWithQualName(PyFrameObject *frame, object name, object qualname)
|
| 22 |
+
# Return value: New reference.
|
| 23 |
+
# Create and return a new generator object based on the frame object, with
|
| 24 |
+
# __name__ and __qualname__ set to name and qualname. A reference to frame
|
| 25 |
+
# is stolen by this function. The frame argument must not be NULL.
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/iterator.pxd
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cdef extern from "Python.h":
|
| 2 |
+
|
| 3 |
+
############################################################################
|
| 4 |
+
# 6.5 Iterator Protocol
|
| 5 |
+
############################################################################
|
| 6 |
+
bint PyIter_Check(object o)
|
| 7 |
+
# Return true if the object o supports the iterator protocol.
|
| 8 |
+
|
| 9 |
+
object PyIter_Next(object o)
|
| 10 |
+
# Return value: New reference.
|
| 11 |
+
# Return the next value from the iteration o. If the object is an
|
| 12 |
+
# iterator, this retrieves the next value from the iteration, and
|
| 13 |
+
# returns NULL with no exception set if there are no remaining
|
| 14 |
+
# items. If the object is not an iterator, TypeError is raised, or
|
| 15 |
+
# if there is an error in retrieving the item, returns NULL and
|
| 16 |
+
# passes along the exception.
|
| 17 |
+
|
| 18 |
+
# To write a loop which iterates over an iterator, the C code should look something like this:
|
| 19 |
+
# PyObject *iterator = PyObject_GetIter(obj);
|
| 20 |
+
# PyObject *item;
|
| 21 |
+
# if (iterator == NULL) {
|
| 22 |
+
# /* propagate error */
|
| 23 |
+
# }
|
| 24 |
+
# while (item = PyIter_Next(iterator)) {
|
| 25 |
+
# /* do something with item */
|
| 26 |
+
# ...
|
| 27 |
+
# /* release reference when done */
|
| 28 |
+
# Py_DECREF(item);
|
| 29 |
+
# }
|
| 30 |
+
# Py_DECREF(iterator);
|
| 31 |
+
# if (PyErr_Occurred()) {
|
| 32 |
+
# /* propagate error */
|
| 33 |
+
# }
|
| 34 |
+
# else {
|
| 35 |
+
# /* continue doing useful work */
|
| 36 |
+
# }
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/method.pxd
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .object cimport PyObject
|
| 2 |
+
|
| 3 |
+
cdef extern from "Python.h":
|
| 4 |
+
############################################################################
|
| 5 |
+
# 7.5.4 Method Objects
|
| 6 |
+
############################################################################
|
| 7 |
+
|
| 8 |
+
# There are some useful functions that are useful for working with method objects.
|
| 9 |
+
# PyTypeObject PyMethod_Type
|
| 10 |
+
# This instance of PyTypeObject represents the Python method type. This is exposed to Python programs as types.MethodType.
|
| 11 |
+
|
| 12 |
+
bint PyMethod_Check(object o)
|
| 13 |
+
# Return true if o is a method object (has type
|
| 14 |
+
# PyMethod_Type). The parameter must not be NULL.
|
| 15 |
+
|
| 16 |
+
object PyMethod_New(object func, object self, object cls)
|
| 17 |
+
# Return value: New reference.
|
| 18 |
+
# Return a new method object, with func being any callable object;
|
| 19 |
+
# this is the function that will be called when the method is
|
| 20 |
+
# called. If this method should be bound to an instance, self
|
| 21 |
+
# should be the instance and class should be the class of self,
|
| 22 |
+
# otherwise self should be NULL and class should be the class
|
| 23 |
+
# which provides the unbound method..
|
| 24 |
+
|
| 25 |
+
PyObject* PyMethod_Class(object meth) except NULL
|
| 26 |
+
# Return value: Borrowed reference.
|
| 27 |
+
# Return the class object from which the method meth was created;
|
| 28 |
+
# if this was created from an instance, it will be the class of
|
| 29 |
+
# the instance.
|
| 30 |
+
|
| 31 |
+
PyObject* PyMethod_GET_CLASS(object meth)
|
| 32 |
+
# Return value: Borrowed reference.
|
| 33 |
+
# Macro version of PyMethod_Class() which avoids error checking.
|
| 34 |
+
|
| 35 |
+
PyObject* PyMethod_Function(object meth) except NULL
|
| 36 |
+
# Return value: Borrowed reference.
|
| 37 |
+
# Return the function object associated with the method meth.
|
| 38 |
+
|
| 39 |
+
PyObject* PyMethod_GET_FUNCTION(object meth)
|
| 40 |
+
# Return value: Borrowed reference.
|
| 41 |
+
# Macro version of PyMethod_Function() which avoids error checking.
|
| 42 |
+
|
| 43 |
+
PyObject* PyMethod_Self(object meth) except? NULL
|
| 44 |
+
# Return value: Borrowed reference.
|
| 45 |
+
# Return the instance associated with the method meth if it is bound, otherwise return NULL.
|
| 46 |
+
|
| 47 |
+
PyObject* PyMethod_GET_SELF(object meth)
|
| 48 |
+
# Return value: Borrowed reference.
|
| 49 |
+
# Macro version of PyMethod_Self() which avoids error checking.
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/pylifecycle.pxd
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Interfaces to configure, query, create & destroy the Python runtime
|
| 2 |
+
|
| 3 |
+
from libc.stdio cimport FILE
|
| 4 |
+
from .pystate cimport PyThreadState
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
cdef extern from "Python.h":
|
| 8 |
+
ctypedef int wchar_t
|
| 9 |
+
|
| 10 |
+
void Py_SetProgramName(wchar_t *)
|
| 11 |
+
wchar_t *Py_GetProgramName()
|
| 12 |
+
|
| 13 |
+
void Py_SetPythonHome(wchar_t *)
|
| 14 |
+
wchar_t *Py_GetPythonHome()
|
| 15 |
+
|
| 16 |
+
# Only used by applications that embed the interpreter and need to
|
| 17 |
+
# override the standard encoding determination mechanism
|
| 18 |
+
int Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
|
| 19 |
+
|
| 20 |
+
void Py_Initialize()
|
| 21 |
+
void Py_InitializeEx(int)
|
| 22 |
+
void _Py_InitializeEx_Private(int, int)
|
| 23 |
+
void Py_Finalize()
|
| 24 |
+
int Py_FinalizeEx()
|
| 25 |
+
int Py_IsInitialized()
|
| 26 |
+
PyThreadState *Py_NewInterpreter()
|
| 27 |
+
void Py_EndInterpreter(PyThreadState *)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
# _Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
|
| 31 |
+
# exit functions.
|
| 32 |
+
void _Py_PyAtExit(void (*func)(object), object)
|
| 33 |
+
int Py_AtExit(void (*func)())
|
| 34 |
+
|
| 35 |
+
void Py_Exit(int)
|
| 36 |
+
|
| 37 |
+
# Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
|
| 38 |
+
void _Py_RestoreSignals()
|
| 39 |
+
|
| 40 |
+
int Py_FdIsInteractive(FILE *, const char *)
|
| 41 |
+
|
| 42 |
+
# Bootstrap __main__ (defined in Modules/main.c)
|
| 43 |
+
int Py_Main(int argc, wchar_t **argv)
|
| 44 |
+
|
| 45 |
+
# In getpath.c
|
| 46 |
+
wchar_t *Py_GetProgramFullPath()
|
| 47 |
+
wchar_t *Py_GetPrefix()
|
| 48 |
+
wchar_t *Py_GetExecPrefix()
|
| 49 |
+
wchar_t *Py_GetPath()
|
| 50 |
+
void Py_SetPath(const wchar_t *)
|
| 51 |
+
int _Py_CheckPython3()
|
| 52 |
+
|
| 53 |
+
# In their own files
|
| 54 |
+
const char *Py_GetVersion()
|
| 55 |
+
const char *Py_GetPlatform()
|
| 56 |
+
const char *Py_GetCopyright()
|
| 57 |
+
const char *Py_GetCompiler()
|
| 58 |
+
const char *Py_GetBuildInfo()
|
| 59 |
+
const char *_Py_gitidentifier()
|
| 60 |
+
const char *_Py_gitversion()
|
| 61 |
+
|
| 62 |
+
ctypedef void (*PyOS_sighandler_t)(int)
|
| 63 |
+
PyOS_sighandler_t PyOS_getsig(int)
|
| 64 |
+
PyOS_sighandler_t PyOS_setsig(int, PyOS_sighandler_t)
|
| 65 |
+
|
| 66 |
+
# Random
|
| 67 |
+
int _PyOS_URandom(void *buffer, Py_ssize_t size)
|
| 68 |
+
int _PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/time.pxd
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Cython implementation of (parts of) the standard library time module.
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
from libc.stdint cimport int64_t
|
| 6 |
+
from cpython.exc cimport PyErr_SetFromErrno
|
| 7 |
+
|
| 8 |
+
cdef extern from *:
|
| 9 |
+
"""
|
| 10 |
+
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_t)
|
| 11 |
+
#define __Pyx_PyTime_t PyTime_t
|
| 12 |
+
#else
|
| 13 |
+
#define __Pyx_PyTime_t _PyTime_t
|
| 14 |
+
#endif
|
| 15 |
+
|
| 16 |
+
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_TimeRaw)
|
| 17 |
+
static CYTHON_INLINE __Pyx_PyTime_t __Pyx_PyTime_TimeUnchecked(void) {
|
| 18 |
+
__Pyx_PyTime_t tic;
|
| 19 |
+
(void) PyTime_TimeRaw(&tic);
|
| 20 |
+
return tic;
|
| 21 |
+
}
|
| 22 |
+
#else
|
| 23 |
+
#define __Pyx_PyTime_TimeUnchecked() _PyTime_GetSystemClock()
|
| 24 |
+
#endif
|
| 25 |
+
|
| 26 |
+
#if PY_VERSION_HEX >= 0x030d00b1 || defined(PyTime_AsSecondsDouble)
|
| 27 |
+
#define __Pyx_PyTime_AsSecondsDouble(t) PyTime_AsSecondsDouble(t)
|
| 28 |
+
#else
|
| 29 |
+
#define __Pyx_PyTime_AsSecondsDouble(t) _PyTime_AsSecondsDouble(t)
|
| 30 |
+
#endif
|
| 31 |
+
"""
|
| 32 |
+
ctypedef int64_t PyTime_t "__Pyx_PyTime_t"
|
| 33 |
+
ctypedef int64_t _PyTime_t "__Pyx_PyTime_t"
|
| 34 |
+
|
| 35 |
+
_PyTime_t _PyTime_GetSystemClock "__Pyx_PyTime_TimeUnchecked" () nogil
|
| 36 |
+
_PyTime_t PyTime_TimeUnchecked "__Pyx_PyTime_TimeUnchecked" () nogil
|
| 37 |
+
|
| 38 |
+
double _PyTime_AsSecondsDouble "__Pyx_PyTime_AsSecondsDouble" (_PyTime_t t) nogil
|
| 39 |
+
double PyTime_AsSecondsDouble "__Pyx_PyTime_AsSecondsDouble" (_PyTime_t t) nogil
|
| 40 |
+
|
| 41 |
+
from libc.time cimport (
|
| 42 |
+
tm,
|
| 43 |
+
time_t,
|
| 44 |
+
localtime as libc_localtime,
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
cdef inline double time() noexcept nogil:
|
| 49 |
+
cdef:
|
| 50 |
+
_PyTime_t tic
|
| 51 |
+
|
| 52 |
+
tic = PyTime_TimeUnchecked()
|
| 53 |
+
return PyTime_AsSecondsDouble(tic)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
cdef inline int _raise_from_errno() except -1 with gil:
|
| 57 |
+
PyErr_SetFromErrno(RuntimeError)
|
| 58 |
+
return <int> -1 # Let the C compiler know that this function always raises.
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
cdef inline tm localtime() except * nogil:
|
| 62 |
+
"""
|
| 63 |
+
Analogue to the stdlib time.localtime. The returned struct
|
| 64 |
+
has some entries that the stdlib version does not: tm_gmtoff, tm_zone
|
| 65 |
+
"""
|
| 66 |
+
cdef:
|
| 67 |
+
time_t tic = <time_t>time()
|
| 68 |
+
tm* result
|
| 69 |
+
|
| 70 |
+
result = libc_localtime(&tic)
|
| 71 |
+
if result is NULL:
|
| 72 |
+
_raise_from_errno()
|
| 73 |
+
# Fix 0-based date values (and the 1900-based year).
|
| 74 |
+
# See tmtotuple() in https://github.com/python/cpython/blob/master/Modules/timemodule.c
|
| 75 |
+
result.tm_year += 1900
|
| 76 |
+
result.tm_mon += 1
|
| 77 |
+
result.tm_wday = <int> ((result.tm_wday + 6) % 7)
|
| 78 |
+
result.tm_yday += 1
|
| 79 |
+
return result[0]
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/tuple.pxd
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .object cimport PyObject
|
| 2 |
+
|
| 3 |
+
cdef extern from "Python.h":
|
| 4 |
+
|
| 5 |
+
############################################################################
|
| 6 |
+
# Tuples
|
| 7 |
+
############################################################################
|
| 8 |
+
|
| 9 |
+
bint PyTuple_Check(object p)
|
| 10 |
+
# Return true if p is a tuple object or an instance of a subtype
|
| 11 |
+
# of the tuple type.
|
| 12 |
+
|
| 13 |
+
bint PyTuple_CheckExact(object p)
|
| 14 |
+
# Return true if p is a tuple object, but not an instance of a subtype of the tuple type.
|
| 15 |
+
|
| 16 |
+
tuple PyTuple_New(Py_ssize_t len)
|
| 17 |
+
# Return value: New reference.
|
| 18 |
+
# Return a new tuple object of size len, or NULL on failure.
|
| 19 |
+
|
| 20 |
+
tuple PyTuple_Pack(Py_ssize_t n, ...)
|
| 21 |
+
# Return value: New reference.
|
| 22 |
+
# Return a new tuple object of size n, or NULL on failure. The
|
| 23 |
+
# tuple values are initialized to the subsequent n C arguments
|
| 24 |
+
# pointing to Python objects. "PyTuple_Pack(2, a, b)" is
|
| 25 |
+
# equivalent to "Py_BuildValue("(OO)", a, b)".
|
| 26 |
+
|
| 27 |
+
Py_ssize_t PyTuple_Size(object p) except -1
|
| 28 |
+
# Take a pointer to a tuple object, and return the size of that tuple.
|
| 29 |
+
|
| 30 |
+
Py_ssize_t PyTuple_GET_SIZE(object p)
|
| 31 |
+
# Return the size of the tuple p, which must be non-NULL and point
|
| 32 |
+
# to a tuple; no error checking is performed.
|
| 33 |
+
|
| 34 |
+
PyObject* PyTuple_GetItem(object p, Py_ssize_t pos) except NULL
|
| 35 |
+
# Return value: Borrowed reference.
|
| 36 |
+
# Return the object at position pos in the tuple pointed to by
|
| 37 |
+
# p. If pos is out of bounds, return NULL and sets an IndexError
|
| 38 |
+
# exception.
|
| 39 |
+
|
| 40 |
+
PyObject* PyTuple_GET_ITEM(object p, Py_ssize_t pos)
|
| 41 |
+
# Return value: Borrowed reference.
|
| 42 |
+
# Like PyTuple_GetItem(), but does no checking of its arguments.
|
| 43 |
+
|
| 44 |
+
tuple PyTuple_GetSlice(object p, Py_ssize_t low, Py_ssize_t high)
|
| 45 |
+
# Return value: New reference.
|
| 46 |
+
# Take a slice of the tuple pointed to by p from low to high and return it as a new tuple.
|
| 47 |
+
|
| 48 |
+
int PyTuple_SetItem(object p, Py_ssize_t pos, object o) except -1
|
| 49 |
+
# Insert a reference to object o at position pos of the tuple
|
| 50 |
+
# pointed to by p. Return 0 on success.
|
| 51 |
+
#
|
| 52 |
+
# WARNING: This function _steals_ a reference to o.
|
| 53 |
+
|
| 54 |
+
void PyTuple_SET_ITEM(object p, Py_ssize_t pos, object o)
|
| 55 |
+
# Like PyTuple_SetItem(), but does no error checking, and should
|
| 56 |
+
# only be used to fill in brand new tuples.
|
| 57 |
+
#
|
| 58 |
+
# WARNING: This function _steals_ a reference to o.
|
| 59 |
+
|
| 60 |
+
int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) except -1
|
| 61 |
+
# Can be used to resize a tuple. newsize will be the new length of
|
| 62 |
+
# the tuple. Because tuples are supposed to be immutable, this
|
| 63 |
+
# should only be used if there is only one reference to the
|
| 64 |
+
# object. Do not use this if the tuple may already be known to
|
| 65 |
+
# some other part of the code. The tuple will always grow or
|
| 66 |
+
# shrink at the end. Think of this as destroying the old tuple and
|
| 67 |
+
# creating a new one, only more efficiently. Returns 0 on
|
| 68 |
+
# success. Client code should never assume that the resulting
|
| 69 |
+
# value of *p will be the same as before calling this function. If
|
| 70 |
+
# the object referenced by *p is replaced, the original *p is
|
| 71 |
+
# destroyed. On failure, returns -1 and sets *p to NULL, and
|
| 72 |
+
# raises MemoryError or SystemError.
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/cpython/unicode.pxd
ADDED
|
@@ -0,0 +1,639 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from libc.stddef cimport wchar_t
|
| 2 |
+
|
| 3 |
+
cdef extern from *:
|
| 4 |
+
ctypedef unsigned char Py_UCS1 # uint8_t
|
| 5 |
+
ctypedef unsigned short Py_UCS2 # uint16_t
|
| 6 |
+
|
| 7 |
+
# Return true if the object o is a Unicode object or an instance
|
| 8 |
+
# of a Unicode subtype. Changed in version 2.2: Allowed subtypes
|
| 9 |
+
# to be accepted.
|
| 10 |
+
bint PyUnicode_Check(object o)
|
| 11 |
+
|
| 12 |
+
# Return true if the object o is a Unicode object, but not an
|
| 13 |
+
# instance of a subtype. New in version 2.2.
|
| 14 |
+
bint PyUnicode_CheckExact(object o)
|
| 15 |
+
|
| 16 |
+
# Return the size of the object. o has to be a PyUnicodeObject
|
| 17 |
+
# (not checked).
|
| 18 |
+
#
|
| 19 |
+
# Deprecated since version 3.3, will be removed in version 3.10:
|
| 20 |
+
# Part of the old-style Unicode API, please migrate to using
|
| 21 |
+
# PyUnicode_GET_LENGTH().
|
| 22 |
+
Py_ssize_t PyUnicode_GET_SIZE(object o)
|
| 23 |
+
|
| 24 |
+
# Return the length of the Unicode string, in code points. o has
|
| 25 |
+
# to be a Unicode object in the “canonical” representation (not
|
| 26 |
+
# checked).
|
| 27 |
+
#
|
| 28 |
+
# New in version 3.3.
|
| 29 |
+
Py_ssize_t PyUnicode_GET_LENGTH(object o)
|
| 30 |
+
|
| 31 |
+
Py_UCS1 *PyUnicode_1BYTE_DATA(object o)
|
| 32 |
+
Py_UCS2 *PyUnicode_2BYTE_DATA(object o)
|
| 33 |
+
Py_UCS4 *PyUnicode_4BYTE_DATA(object o)
|
| 34 |
+
|
| 35 |
+
int PyUnicode_WCHAR_KIND # Deprecated since Python 3.10, removed in 3.12.
|
| 36 |
+
int PyUnicode_1BYTE_KIND
|
| 37 |
+
int PyUnicode_2BYTE_KIND
|
| 38 |
+
int PyUnicode_4BYTE_KIND
|
| 39 |
+
void PyUnicode_WRITE(int kind, void *data, Py_ssize_t index, Py_UCS4 value)
|
| 40 |
+
Py_UCS4 PyUnicode_READ(int kind, void *data, Py_ssize_t index)
|
| 41 |
+
Py_UCS4 PyUnicode_READ_CHAR(object o, Py_ssize_t index)
|
| 42 |
+
|
| 43 |
+
unsigned int PyUnicode_KIND(object o)
|
| 44 |
+
void *PyUnicode_DATA(object o)
|
| 45 |
+
|
| 46 |
+
# Return the size of the object's internal buffer in bytes. o has
|
| 47 |
+
# to be a PyUnicodeObject (not checked).
|
| 48 |
+
Py_ssize_t PyUnicode_GET_DATA_SIZE(object o)
|
| 49 |
+
|
| 50 |
+
# Return a pointer to the internal Py_UNICODE buffer of the
|
| 51 |
+
# object. o has to be a PyUnicodeObject (not checked).
|
| 52 |
+
Py_UNICODE* PyUnicode_AS_UNICODE(object o)
|
| 53 |
+
|
| 54 |
+
# Return a pointer to the internal buffer of the object. o has to
|
| 55 |
+
# be a PyUnicodeObject (not checked).
|
| 56 |
+
char* PyUnicode_AS_DATA(object o)
|
| 57 |
+
|
| 58 |
+
bint PyUnicode_IsIdentifier(object o)
|
| 59 |
+
|
| 60 |
+
# Return 1 or 0 depending on whether ch is a whitespace character.
|
| 61 |
+
bint Py_UNICODE_ISSPACE(Py_UCS4 ch)
|
| 62 |
+
|
| 63 |
+
# Return 1 or 0 depending on whether ch is a lowercase character.
|
| 64 |
+
bint Py_UNICODE_ISLOWER(Py_UCS4 ch)
|
| 65 |
+
|
| 66 |
+
# Return 1 or 0 depending on whether ch is an uppercase character.
|
| 67 |
+
bint Py_UNICODE_ISUPPER(Py_UCS4 ch)
|
| 68 |
+
|
| 69 |
+
# Return 1 or 0 depending on whether ch is a titlecase character.
|
| 70 |
+
bint Py_UNICODE_ISTITLE(Py_UCS4 ch)
|
| 71 |
+
|
| 72 |
+
# Return 1 or 0 depending on whether ch is a linebreak character.
|
| 73 |
+
bint Py_UNICODE_ISLINEBREAK(Py_UCS4 ch)
|
| 74 |
+
|
| 75 |
+
# Return 1 or 0 depending on whether ch is a decimal character.
|
| 76 |
+
bint Py_UNICODE_ISDECIMAL(Py_UCS4 ch)
|
| 77 |
+
|
| 78 |
+
# Return 1 or 0 depending on whether ch is a digit character.
|
| 79 |
+
bint Py_UNICODE_ISDIGIT(Py_UCS4 ch)
|
| 80 |
+
|
| 81 |
+
# Return 1 or 0 depending on whether ch is a numeric character.
|
| 82 |
+
bint Py_UNICODE_ISNUMERIC(Py_UCS4 ch)
|
| 83 |
+
|
| 84 |
+
# Return 1 or 0 depending on whether ch is an alphabetic character.
|
| 85 |
+
bint Py_UNICODE_ISALPHA(Py_UCS4 ch)
|
| 86 |
+
|
| 87 |
+
# Return 1 or 0 depending on whether ch is an alphanumeric character.
|
| 88 |
+
bint Py_UNICODE_ISALNUM(Py_UCS4 ch)
|
| 89 |
+
|
| 90 |
+
bint Py_UNICODE_ISPRINTABLE(Py_UCS4 ch)
|
| 91 |
+
|
| 92 |
+
# Return the character ch converted to lower case.
|
| 93 |
+
# Used to return a Py_UNICODE value before Py3.3.
|
| 94 |
+
Py_UCS4 Py_UNICODE_TOLOWER(Py_UCS4 ch)
|
| 95 |
+
|
| 96 |
+
# Return the character ch converted to upper case.
|
| 97 |
+
# Used to return a Py_UNICODE value before Py3.3.
|
| 98 |
+
Py_UCS4 Py_UNICODE_TOUPPER(Py_UCS4 ch)
|
| 99 |
+
|
| 100 |
+
# Return the character ch converted to title case.
|
| 101 |
+
# Used to return a Py_UNICODE value before Py3.3.
|
| 102 |
+
Py_UCS4 Py_UNICODE_TOTITLE(Py_UCS4 ch)
|
| 103 |
+
|
| 104 |
+
# Return the character ch converted to a decimal positive
|
| 105 |
+
# integer. Return -1 if this is not possible. This macro does not
|
| 106 |
+
# raise exceptions.
|
| 107 |
+
int Py_UNICODE_TODECIMAL(Py_UCS4 ch)
|
| 108 |
+
|
| 109 |
+
# Return the character ch converted to a single digit
|
| 110 |
+
# integer. Return -1 if this is not possible. This macro does not
|
| 111 |
+
# raise exceptions.
|
| 112 |
+
int Py_UNICODE_TODIGIT(Py_UCS4 ch)
|
| 113 |
+
|
| 114 |
+
# Return the character ch converted to a double. Return -1.0 if
|
| 115 |
+
# this is not possible. This macro does not raise exceptions.
|
| 116 |
+
double Py_UNICODE_TONUMERIC(Py_UCS4 ch)
|
| 117 |
+
|
| 118 |
+
# To create Unicode objects and access their basic sequence
|
| 119 |
+
# properties, use these APIs:
|
| 120 |
+
|
| 121 |
+
# Create a Unicode Object from the Py_UNICODE buffer u of the
|
| 122 |
+
# given size. u may be NULL which causes the contents to be
|
| 123 |
+
# undefined. It is the user's responsibility to fill in the needed
|
| 124 |
+
# data. The buffer is copied into the new object. If the buffer is
|
| 125 |
+
# not NULL, the return value might be a shared object. Therefore,
|
| 126 |
+
# modification of the resulting Unicode object is only allowed
|
| 127 |
+
# when u is NULL.
|
| 128 |
+
unicode PyUnicode_FromUnicode(Py_UNICODE *u, Py_ssize_t size)
|
| 129 |
+
|
| 130 |
+
# Similar to PyUnicode_FromUnicode(), but u points to UTF-8 encoded
|
| 131 |
+
# bytes
|
| 132 |
+
unicode PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
|
| 133 |
+
|
| 134 |
+
# Similar to PyUnicode_FromUnicode(), but u points to null-terminated
|
| 135 |
+
# UTF-8 encoded bytes. The size is determined with strlen().
|
| 136 |
+
unicode PyUnicode_FromString(const char *u)
|
| 137 |
+
|
| 138 |
+
unicode PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar)
|
| 139 |
+
unicode PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size)
|
| 140 |
+
unicode PyUnicode_FromFormat(const char *format, ...)
|
| 141 |
+
Py_ssize_t PyUnicode_GetLength(object unicode) except -1
|
| 142 |
+
Py_ssize_t PyUnicode_CopyCharacters(object to, Py_ssize_t to_start, object from_, Py_ssize_t from_start, Py_ssize_t how_many) except -1
|
| 143 |
+
Py_ssize_t PyUnicode_Fill(object unicode, Py_ssize_t start, Py_ssize_t length, Py_UCS4 fill_char) except -1
|
| 144 |
+
int PyUnicode_WriteChar(object unicode, Py_ssize_t index, Py_UCS4 character) except -1
|
| 145 |
+
Py_UCS4 PyUnicode_ReadChar(object unicode, Py_ssize_t index) except -1
|
| 146 |
+
unicode PyUnicode_Substring(object str, Py_ssize_t start, Py_ssize_t end)
|
| 147 |
+
Py_UCS4 *PyUnicode_AsUCS4(object u, Py_UCS4 *buffer, Py_ssize_t buflen, int copy_null) except NULL
|
| 148 |
+
Py_UCS4 *PyUnicode_AsUCS4Copy(object u) except NULL
|
| 149 |
+
|
| 150 |
+
# Create a Unicode Object from the given Unicode code point ordinal.
|
| 151 |
+
#
|
| 152 |
+
# The ordinal must be in range(0x10000) on narrow Python builds
|
| 153 |
+
# (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError
|
| 154 |
+
# is raised in case it is not.
|
| 155 |
+
unicode PyUnicode_FromOrdinal(int ordinal)
|
| 156 |
+
|
| 157 |
+
# Return a read-only pointer to the Unicode object's internal
|
| 158 |
+
# Py_UNICODE buffer, NULL if unicode is not a Unicode object.
|
| 159 |
+
Py_UNICODE* PyUnicode_AsUnicode(object o) except NULL
|
| 160 |
+
|
| 161 |
+
# Return the length of the Unicode object.
|
| 162 |
+
Py_ssize_t PyUnicode_GetSize(object o) except -1
|
| 163 |
+
|
| 164 |
+
# Coerce an encoded object obj to an Unicode object and return a
|
| 165 |
+
# reference with incremented refcount.
|
| 166 |
+
# String and other char buffer compatible objects are decoded
|
| 167 |
+
# according to the given encoding and using the error handling
|
| 168 |
+
# defined by errors. Both can be NULL to have the interface use
|
| 169 |
+
# the default values (see the next section for details).
|
| 170 |
+
# All other objects, including Unicode objects, cause a TypeError
|
| 171 |
+
# to be set.
|
| 172 |
+
object PyUnicode_FromEncodedObject(object o, char *encoding, char *errors)
|
| 173 |
+
|
| 174 |
+
# Shortcut for PyUnicode_FromEncodedObject(obj, NULL, "strict")
|
| 175 |
+
# which is used throughout the interpreter whenever coercion to
|
| 176 |
+
# Unicode is needed.
|
| 177 |
+
object PyUnicode_FromObject(object obj)
|
| 178 |
+
|
| 179 |
+
# If the platform supports wchar_t and provides a header file
|
| 180 |
+
# wchar.h, Python can interface directly to this type using the
|
| 181 |
+
# following functions. Support is optimized if Python's own
|
| 182 |
+
# Py_UNICODE type is identical to the system's wchar_t.
|
| 183 |
+
|
| 184 |
+
# Create a Unicode object from the wchar_t buffer w of the given
|
| 185 |
+
# size. Return NULL on failure.
|
| 186 |
+
object PyUnicode_FromWideChar(wchar_t *w, Py_ssize_t size)
|
| 187 |
+
|
| 188 |
+
# Copy the Unicode object contents into the wchar_t buffer w.
|
| 189 |
+
# At most size wchar_t characters are copied (excluding a possibly
|
| 190 |
+
# trailing null termination character). Return the number of wchar_t
|
| 191 |
+
# characters copied or -1 in case of an error. Note that the
|
| 192 |
+
# esulting wchar_t* string may or may not be null-terminated.
|
| 193 |
+
# It is the responsibility of the caller to make sure that the wchar_t*
|
| 194 |
+
# string is null-terminated in case this is required by the application.
|
| 195 |
+
# Also, note that the wchar_t* string might contain null characters,
|
| 196 |
+
# which would cause the string to be truncated when used with most C functions.
|
| 197 |
+
Py_ssize_t PyUnicode_AsWideChar(object o, wchar_t *w, Py_ssize_t size) except -1
|
| 198 |
+
|
| 199 |
+
# Convert the Unicode object to a wide character string. The output
|
| 200 |
+
# string always ends with a null character. If size is not NULL,
|
| 201 |
+
# write the number of wide characters (excluding the trailing null
|
| 202 |
+
# termination character) into *size. Note that the resulting wchar_t
|
| 203 |
+
# string might contain null characters, which would cause the string
|
| 204 |
+
# to be truncated when used with most C functions. If size is NULL and
|
| 205 |
+
# the wchar_t* string contains null characters a ValueError is raised.
|
| 206 |
+
|
| 207 |
+
# Returns a buffer allocated by PyMem_New (use PyMem_Free() to free it)
|
| 208 |
+
# on success. On error, returns NULL and *size is undefined. Raises a
|
| 209 |
+
# MemoryError if memory allocation is failed.
|
| 210 |
+
wchar_t *PyUnicode_AsWideCharString(object o, Py_ssize_t *size) except NULL
|
| 211 |
+
|
| 212 |
+
# Unicode Methods
|
| 213 |
+
|
| 214 |
+
# Concat two strings giving a new Unicode string.
|
| 215 |
+
# Return value: New reference.
|
| 216 |
+
unicode PyUnicode_Concat(object left, object right)
|
| 217 |
+
|
| 218 |
+
# Split a string giving a list of Unicode strings. If sep is NULL,
|
| 219 |
+
# splitting will be done at all whitespace substrings. Otherwise,
|
| 220 |
+
# splits occur at the given separator. At most maxsplit splits will
|
| 221 |
+
# be done. If negative, no limit is set. Separators are not included
|
| 222 |
+
# in the resulting list.
|
| 223 |
+
# Return value: New reference.
|
| 224 |
+
list PyUnicode_Split(object s, object sep, Py_ssize_t maxsplit)
|
| 225 |
+
|
| 226 |
+
# Split a Unicode string at line breaks, returning a list of Unicode
|
| 227 |
+
# strings. CRLF is considered to be one line break. If keepend is 0,
|
| 228 |
+
# the Line break characters are not included in the resulting strings.
|
| 229 |
+
# Return value: New reference.
|
| 230 |
+
list PyUnicode_Splitlines(object s, bint keepend)
|
| 231 |
+
|
| 232 |
+
# Translate a string by applying a character mapping table to it and
|
| 233 |
+
# return the resulting Unicode object.
|
| 234 |
+
#
|
| 235 |
+
# The mapping table must map Unicode ordinal integers to Unicode ordinal
|
| 236 |
+
# integers or None (causing deletion of the character).
|
| 237 |
+
#
|
| 238 |
+
# Mapping tables need only provide the __getitem__() interface;
|
| 239 |
+
# dictionaries and sequences work well. Unmapped character ordinals (ones
|
| 240 |
+
# which cause a LookupError) are left untouched and are copied as-is.
|
| 241 |
+
#
|
| 242 |
+
# errors has the usual meaning for codecs. It may be NULL which indicates
|
| 243 |
+
# to use the default error handling.
|
| 244 |
+
# Return value: New reference.
|
| 245 |
+
unicode PyUnicode_Translate(object str, object table, const char *errors)
|
| 246 |
+
|
| 247 |
+
# Join a sequence of strings using the given separator and return the
|
| 248 |
+
# resulting Unicode string.
|
| 249 |
+
# Return value: New reference.
|
| 250 |
+
unicode PyUnicode_Join(object separator, object seq)
|
| 251 |
+
|
| 252 |
+
# Return 1 if substr matches str[start:end] at the given tail end
|
| 253 |
+
# (direction == -1 means to do a prefix match, direction == 1 a
|
| 254 |
+
# suffix match), 0 otherwise.
|
| 255 |
+
# Return -1 if an error occurred.
|
| 256 |
+
Py_ssize_t PyUnicode_Tailmatch(object str, object substr,
|
| 257 |
+
Py_ssize_t start, Py_ssize_t end, int direction) except -1
|
| 258 |
+
|
| 259 |
+
# Return the first position of substr in str[start:end] using the given
|
| 260 |
+
# direction (direction == 1 means to do a forward search, direction == -1
|
| 261 |
+
# a backward search). The return value is the index of the first match;
|
| 262 |
+
# a value of -1 indicates that no match was found, and -2 indicates that an
|
| 263 |
+
# error occurred and an exception has been set.
|
| 264 |
+
Py_ssize_t PyUnicode_Find(object str, object substr, Py_ssize_t start, Py_ssize_t end, int direction) except -2
|
| 265 |
+
|
| 266 |
+
# Return the first position of the character ch in str[start:end] using
|
| 267 |
+
# the given direction (direction == 1 means to do a forward search,
|
| 268 |
+
# direction == -1 a backward search). The return value is the index of
|
| 269 |
+
# the first match; a value of -1 indicates that no match was found, and
|
| 270 |
+
# -2 indicates that an error occurred and an exception has been set.
|
| 271 |
+
# New in version 3.3.
|
| 272 |
+
Py_ssize_t PyUnicode_FindChar(object str, Py_UCS4 ch, Py_ssize_t start, Py_ssize_t end, int direction) except -2
|
| 273 |
+
|
| 274 |
+
# Return the number of non-overlapping occurrences of substr in
|
| 275 |
+
# str[start:end]. Return -1 if an error occurred.
|
| 276 |
+
Py_ssize_t PyUnicode_Count(object str, object substr, Py_ssize_t start, Py_ssize_t end) except -1
|
| 277 |
+
|
| 278 |
+
# Replace at most maxcount occurrences of substr in str with replstr and
|
| 279 |
+
# return the resulting Unicode object. maxcount == -1 means replace all
|
| 280 |
+
# occurrences.
|
| 281 |
+
# Return value: New reference.
|
| 282 |
+
unicode PyUnicode_Replace(object str, object substr, object replstr, Py_ssize_t maxcount)
|
| 283 |
+
|
| 284 |
+
# Compare two strings and return -1, 0, 1 for less than,
|
| 285 |
+
# equal, and greater than, respectively.
|
| 286 |
+
int PyUnicode_Compare(object left, object right) except? -1
|
| 287 |
+
|
| 288 |
+
# Compare a unicode object, uni, with string and return -1, 0, 1 for less than,
|
| 289 |
+
# equal, and greater than, respectively. It is best to pass only ASCII-encoded
|
| 290 |
+
# strings, but the function interprets the input string as ISO-8859-1 if it
|
| 291 |
+
# contains non-ASCII characters.
|
| 292 |
+
int PyUnicode_CompareWithASCIIString(object uni, const char *string)
|
| 293 |
+
|
| 294 |
+
# Rich compare two unicode strings and return one of the following:
|
| 295 |
+
#
|
| 296 |
+
# NULL in case an exception was raised
|
| 297 |
+
# Py_True or Py_False for successful comparisons
|
| 298 |
+
# Py_NotImplemented in case the type combination is unknown
|
| 299 |
+
#
|
| 300 |
+
# Note that Py_EQ and Py_NE comparisons can cause a UnicodeWarning in case
|
| 301 |
+
# the conversion of the arguments to Unicode fails with a UnicodeDecodeError.
|
| 302 |
+
#
|
| 303 |
+
# Possible values for op are Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, and Py_LE.
|
| 304 |
+
object PyUnicode_RichCompare(object left, object right, int op)
|
| 305 |
+
|
| 306 |
+
# Return a new string object from format and args; this is analogous to
|
| 307 |
+
# format % args.
|
| 308 |
+
# Return value: New reference.
|
| 309 |
+
unicode PyUnicode_Format(object format, object args)
|
| 310 |
+
|
| 311 |
+
# Check whether element is contained in container and return true or false
|
| 312 |
+
# accordingly.
|
| 313 |
+
#
|
| 314 |
+
# element has to coerce to a one element Unicode string. -1 is returned
|
| 315 |
+
# if there was an error.
|
| 316 |
+
int PyUnicode_Contains(object container, object element) except -1
|
| 317 |
+
|
| 318 |
+
# Intern the argument *string in place. The argument must be the address
|
| 319 |
+
# of a pointer variable pointing to a Python unicode string object. If
|
| 320 |
+
# there is an existing interned string that is the same as *string, it sets
|
| 321 |
+
# *string to it (decrementing the reference count of the old string object
|
| 322 |
+
# and incrementing the reference count of the interned string object),
|
| 323 |
+
# otherwise it leaves *string alone and interns it (incrementing its reference
|
| 324 |
+
# count). (Clarification: even though there is a lot of talk about reference
|
| 325 |
+
# counts, think of this function as reference-count-neutral; you own the object
|
| 326 |
+
# after the call if and only if you owned it before the call.)
|
| 327 |
+
#void PyUnicode_InternInPlace(PyObject **string)
|
| 328 |
+
|
| 329 |
+
# A combination of PyUnicode_FromString() and PyUnicode_InternInPlace(),
|
| 330 |
+
# returning either a new unicode string object that has been interned, or
|
| 331 |
+
# a new ("owned") reference to an earlier interned string object with the
|
| 332 |
+
# same value.
|
| 333 |
+
unicode PyUnicode_InternFromString(const char *v)
|
| 334 |
+
|
| 335 |
+
|
| 336 |
+
# Codecs
|
| 337 |
+
|
| 338 |
+
# Create a Unicode object by decoding size bytes of the encoded
|
| 339 |
+
# string s. encoding and errors have the same meaning as the
|
| 340 |
+
# parameters of the same name in the unicode() builtin
|
| 341 |
+
# function. The codec to be used is looked up using the Python
|
| 342 |
+
# codec registry. Return NULL if an exception was raised by the
|
| 343 |
+
# codec.
|
| 344 |
+
object PyUnicode_Decode(char *s, Py_ssize_t size, char *encoding, char *errors)
|
| 345 |
+
|
| 346 |
+
# Encode the Py_UNICODE buffer of the given size and return a
|
| 347 |
+
# Python string object. encoding and errors have the same meaning
|
| 348 |
+
# as the parameters of the same name in the Unicode encode()
|
| 349 |
+
# method. The codec to be used is looked up using the Python codec
|
| 350 |
+
# registry. Return NULL if an exception was raised by the codec.
|
| 351 |
+
object PyUnicode_Encode(Py_UNICODE *s, Py_ssize_t size,
|
| 352 |
+
char *encoding, char *errors)
|
| 353 |
+
|
| 354 |
+
# Encode a Unicode object and return the result as Python string
|
| 355 |
+
# object. encoding and errors have the same meaning as the
|
| 356 |
+
# parameters of the same name in the Unicode encode() method. The
|
| 357 |
+
# codec to be used is looked up using the Python codec
|
| 358 |
+
# registry. Return NULL if an exception was raised by the codec.
|
| 359 |
+
object PyUnicode_AsEncodedString(object unicode, char *encoding, char *errors)
|
| 360 |
+
|
| 361 |
+
# These are the UTF-8 codec APIs:
|
| 362 |
+
|
| 363 |
+
# Create a Unicode object by decoding size bytes of the UTF-8
|
| 364 |
+
# encoded string s. Return NULL if an exception was raised by the
|
| 365 |
+
# codec.
|
| 366 |
+
unicode PyUnicode_DecodeUTF8(char *s, Py_ssize_t size, char *errors)
|
| 367 |
+
|
| 368 |
+
# If consumed is NULL, behave like PyUnicode_DecodeUTF8(). If
|
| 369 |
+
# consumed is not NULL, trailing incomplete UTF-8 byte sequences
|
| 370 |
+
# will not be treated as an error. Those bytes will not be decoded
|
| 371 |
+
# and the number of bytes that have been decoded will be stored in
|
| 372 |
+
# consumed. New in version 2.4.
|
| 373 |
+
unicode PyUnicode_DecodeUTF8Stateful(char *s, Py_ssize_t size, char *errors, Py_ssize_t *consumed)
|
| 374 |
+
|
| 375 |
+
# Encode the Py_UNICODE buffer of the given size using UTF-8 and
|
| 376 |
+
# return a Python string object. Return NULL if an exception was
|
| 377 |
+
# raised by the codec.
|
| 378 |
+
bytes PyUnicode_EncodeUTF8(Py_UNICODE *s, Py_ssize_t size, char *errors)
|
| 379 |
+
|
| 380 |
+
# Encode a Unicode objects using UTF-8 and return the result as Python bytes object. Error handling is ``strict''. Return NULL if an exception was raised by the codec.
|
| 381 |
+
bytes PyUnicode_AsUTF8String(object unicode)
|
| 382 |
+
|
| 383 |
+
|
| 384 |
+
# Return a pointer to the UTF-8 encoding of the Unicode object,
|
| 385 |
+
# and store the size of the encoded representation (in bytes) in size.
|
| 386 |
+
# The size argument can be NULL; in this case no size will be stored.
|
| 387 |
+
# The returned buffer always has an extra null byte appended
|
| 388 |
+
# (not included in size), regardless of whether there are any
|
| 389 |
+
# other null code points.
|
| 390 |
+
|
| 391 |
+
# In the case of an error, NULL is returned with an exception set and
|
| 392 |
+
# no size is stored.
|
| 393 |
+
|
| 394 |
+
# This caches the UTF-8 representation of the string in the Unicode
|
| 395 |
+
# object, and subsequent calls will return a pointer to the same buffer.
|
| 396 |
+
# The caller is not responsible for deallocating the buffer
|
| 397 |
+
const char* PyUnicode_AsUTF8AndSize(object unicode, Py_ssize_t *size) except NULL
|
| 398 |
+
|
| 399 |
+
|
| 400 |
+
# As PyUnicode_AsUTF8AndSize(), but does not store the size.
|
| 401 |
+
const char *PyUnicode_AsUTF8(object unicode) except NULL
|
| 402 |
+
|
| 403 |
+
# These are the UTF-16 codec APIs:
|
| 404 |
+
|
| 405 |
+
# Decode length bytes from a UTF-16 encoded buffer string and
|
| 406 |
+
# return the corresponding Unicode object. errors (if non-NULL)
|
| 407 |
+
# defines the error handling. It defaults to ``strict''.
|
| 408 |
+
#
|
| 409 |
+
# If byteorder is non-NULL, the decoder starts decoding using the
|
| 410 |
+
# given byte order:
|
| 411 |
+
#
|
| 412 |
+
# *byteorder == -1: little endian
|
| 413 |
+
# *byteorder == 0: native order
|
| 414 |
+
# *byteorder == 1: big endian
|
| 415 |
+
#
|
| 416 |
+
# and then switches if the first two bytes of the input data are a
|
| 417 |
+
# byte order mark (BOM) and the specified byte order is native
|
| 418 |
+
# order. This BOM is not copied into the resulting Unicode
|
| 419 |
+
# string. After completion, *byteorder is set to the current byte
|
| 420 |
+
# order at the.
|
| 421 |
+
#
|
| 422 |
+
# If byteorder is NULL, the codec starts in native order mode.
|
| 423 |
+
unicode PyUnicode_DecodeUTF16(char *s, Py_ssize_t size, char *errors, int *byteorder)
|
| 424 |
+
|
| 425 |
+
# If consumed is NULL, behave like PyUnicode_DecodeUTF16(). If
|
| 426 |
+
# consumed is not NULL, PyUnicode_DecodeUTF16Stateful() will not
|
| 427 |
+
# treat trailing incomplete UTF-16 byte sequences (such as an odd
|
| 428 |
+
# number of bytes or a split surrogate pair) as an error. Those
|
| 429 |
+
# bytes will not be decoded and the number of bytes that have been
|
| 430 |
+
# decoded will be stored in consumed. New in version 2.4.
|
| 431 |
+
unicode PyUnicode_DecodeUTF16Stateful(char *s, Py_ssize_t size, char *errors, int *byteorder, Py_ssize_t *consumed)
|
| 432 |
+
|
| 433 |
+
# Return a Python string object holding the UTF-16 encoded value
|
| 434 |
+
# of the Unicode data in s. If byteorder is not 0, output is
|
| 435 |
+
# written according to the following byte order:
|
| 436 |
+
#
|
| 437 |
+
# byteorder == -1: little endian
|
| 438 |
+
# byteorder == 0: native byte order (writes a BOM mark)
|
| 439 |
+
# byteorder == 1: big endian
|
| 440 |
+
#
|
| 441 |
+
# If byteorder is 0, the output string will always start with the
|
| 442 |
+
# Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark
|
| 443 |
+
# is prepended.
|
| 444 |
+
#
|
| 445 |
+
# If Py_UNICODE_WIDE is defined, a single Py_UNICODE value may get
|
| 446 |
+
# represented as a surrogate pair. If it is not defined, each
|
| 447 |
+
# Py_UNICODE values is interpreted as an UCS-2 character.
|
| 448 |
+
bytes PyUnicode_EncodeUTF16(Py_UNICODE *s, Py_ssize_t size, char *errors, int byteorder)
|
| 449 |
+
|
| 450 |
+
# Return a Python string using the UTF-16 encoding in native byte
|
| 451 |
+
# order. The string always starts with a BOM mark. Error handling
|
| 452 |
+
# is ``strict''. Return NULL if an exception was raised by the
|
| 453 |
+
# codec.
|
| 454 |
+
bytes PyUnicode_AsUTF16String(object unicode)
|
| 455 |
+
|
| 456 |
+
# These are the ``Unicode Escape'' codec APIs:
|
| 457 |
+
|
| 458 |
+
# Create a Unicode object by decoding size bytes of the
|
| 459 |
+
# Unicode-Escape encoded string s. Return NULL if an exception was
|
| 460 |
+
# raised by the codec.
|
| 461 |
+
object PyUnicode_DecodeUnicodeEscape(char *s, Py_ssize_t size, char *errors)
|
| 462 |
+
|
| 463 |
+
# Encode the Py_UNICODE buffer of the given size using
|
| 464 |
+
# Unicode-Escape and return a Python string object. Return NULL if
|
| 465 |
+
# an exception was raised by the codec.
|
| 466 |
+
object PyUnicode_EncodeUnicodeEscape(Py_UNICODE *s, Py_ssize_t size)
|
| 467 |
+
|
| 468 |
+
# Encode a Unicode objects using Unicode-Escape and return the
|
| 469 |
+
# result as Python string object. Error handling is
|
| 470 |
+
# ``strict''. Return NULL if an exception was raised by the codec.
|
| 471 |
+
object PyUnicode_AsUnicodeEscapeString(object unicode)
|
| 472 |
+
|
| 473 |
+
# These are the ``Raw Unicode Escape'' codec APIs:
|
| 474 |
+
|
| 475 |
+
# Create a Unicode object by decoding size bytes of the
|
| 476 |
+
# Raw-Unicode-Escape encoded string s. Return NULL if an exception
|
| 477 |
+
# was raised by the codec.
|
| 478 |
+
object PyUnicode_DecodeRawUnicodeEscape(char *s, Py_ssize_t size, char *errors)
|
| 479 |
+
|
| 480 |
+
# Encode the Py_UNICODE buffer of the given size using
|
| 481 |
+
# Raw-Unicode-Escape and return a Python string object. Return
|
| 482 |
+
# NULL if an exception was raised by the codec.
|
| 483 |
+
object PyUnicode_EncodeRawUnicodeEscape(Py_UNICODE *s, Py_ssize_t size, char *errors)
|
| 484 |
+
|
| 485 |
+
# Encode a Unicode objects using Raw-Unicode-Escape and return the
|
| 486 |
+
# result as Python string object. Error handling is
|
| 487 |
+
# ``strict''. Return NULL if an exception was raised by the codec.
|
| 488 |
+
object PyUnicode_AsRawUnicodeEscapeString(object unicode)
|
| 489 |
+
|
| 490 |
+
# These are the Latin-1 codec APIs: Latin-1 corresponds to the first 256 Unicode ordinals and only these are accepted by the codecs during encoding.
|
| 491 |
+
|
| 492 |
+
# Create a Unicode object by decoding size bytes of the Latin-1
|
| 493 |
+
# encoded string s. Return NULL if an exception was raised by the
|
| 494 |
+
# codec.
|
| 495 |
+
unicode PyUnicode_DecodeLatin1(char *s, Py_ssize_t size, char *errors)
|
| 496 |
+
|
| 497 |
+
# Encode the Py_UNICODE buffer of the given size using Latin-1 and
|
| 498 |
+
# return a Python bytes object. Return NULL if an exception was
|
| 499 |
+
# raised by the codec.
|
| 500 |
+
bytes PyUnicode_EncodeLatin1(Py_UNICODE *s, Py_ssize_t size, char *errors)
|
| 501 |
+
|
| 502 |
+
# Encode a Unicode objects using Latin-1 and return the result as
|
| 503 |
+
# Python bytes object. Error handling is ``strict''. Return NULL
|
| 504 |
+
# if an exception was raised by the codec.
|
| 505 |
+
bytes PyUnicode_AsLatin1String(object unicode)
|
| 506 |
+
|
| 507 |
+
# These are the ASCII codec APIs. Only 7-bit ASCII data is
|
| 508 |
+
# accepted. All other codes generate errors.
|
| 509 |
+
|
| 510 |
+
# Create a Unicode object by decoding size bytes of the ASCII
|
| 511 |
+
# encoded string s. Return NULL if an exception was raised by the
|
| 512 |
+
# codec.
|
| 513 |
+
unicode PyUnicode_DecodeASCII(char *s, Py_ssize_t size, char *errors)
|
| 514 |
+
|
| 515 |
+
# Encode the Py_UNICODE buffer of the given size using ASCII and
|
| 516 |
+
# return a Python bytes object. Return NULL if an exception was
|
| 517 |
+
# raised by the codec.
|
| 518 |
+
bytes PyUnicode_EncodeASCII(Py_UNICODE *s, Py_ssize_t size, char *errors)
|
| 519 |
+
|
| 520 |
+
# Encode a Unicode objects using ASCII and return the result as
|
| 521 |
+
# Python bytes object. Error handling is ``strict''. Return NULL
|
| 522 |
+
# if an exception was raised by the codec.
|
| 523 |
+
bytes PyUnicode_AsASCIIString(object o)
|
| 524 |
+
|
| 525 |
+
# These are the mapping codec APIs:
|
| 526 |
+
#
|
| 527 |
+
# This codec is special in that it can be used to implement many
|
| 528 |
+
# different codecs (and this is in fact what was done to obtain most
|
| 529 |
+
# of the standard codecs included in the encodings package). The codec
|
| 530 |
+
# uses mapping to encode and decode characters.
|
| 531 |
+
#
|
| 532 |
+
# Decoding mappings must map single string characters to single
|
| 533 |
+
# Unicode characters, integers (which are then interpreted as Unicode
|
| 534 |
+
# ordinals) or None (meaning "undefined mapping" and causing an
|
| 535 |
+
# error).
|
| 536 |
+
#
|
| 537 |
+
# Encoding mappings must map single Unicode characters to single
|
| 538 |
+
# string characters, integers (which are then interpreted as Latin-1
|
| 539 |
+
# ordinals) or None (meaning "undefined mapping" and causing an
|
| 540 |
+
# error).
|
| 541 |
+
#
|
| 542 |
+
# The mapping objects provided must only support the __getitem__
|
| 543 |
+
# mapping interface.
|
| 544 |
+
#
|
| 545 |
+
# If a character lookup fails with a LookupError, the character is
|
| 546 |
+
# copied as-is meaning that its ordinal value will be interpreted as
|
| 547 |
+
# Unicode or Latin-1 ordinal resp. Because of this, mappings only need
|
| 548 |
+
# to contain those mappings which map characters to different code
|
| 549 |
+
# points.
|
| 550 |
+
|
| 551 |
+
# Create a Unicode object by decoding size bytes of the encoded
|
| 552 |
+
# string s using the given mapping object. Return NULL if an
|
| 553 |
+
# exception was raised by the codec. If mapping is NULL latin-1
|
| 554 |
+
# decoding will be done. Else it can be a dictionary mapping byte
|
| 555 |
+
# or a unicode string, which is treated as a lookup table. Byte
|
| 556 |
+
# values greater that the length of the string and U+FFFE
|
| 557 |
+
# "characters" are treated as "undefined mapping". Changed in
|
| 558 |
+
# version 2.4: Allowed unicode string as mapping argument.
|
| 559 |
+
object PyUnicode_DecodeCharmap(char *s, Py_ssize_t size, object mapping, char *errors)
|
| 560 |
+
|
| 561 |
+
# Encode the Py_UNICODE buffer of the given size using the given
|
| 562 |
+
# mapping object and return a Python string object. Return NULL if
|
| 563 |
+
# an exception was raised by the codec.
|
| 564 |
+
#
|
| 565 |
+
# Deprecated since version 3.3, will be removed in version 4.0.
|
| 566 |
+
object PyUnicode_EncodeCharmap(Py_UNICODE *s, Py_ssize_t size, object mapping, char *errors)
|
| 567 |
+
|
| 568 |
+
# Encode a Unicode objects using the given mapping object and
|
| 569 |
+
# return the result as Python string object. Error handling is
|
| 570 |
+
# ``strict''. Return NULL if an exception was raised by the codec.
|
| 571 |
+
object PyUnicode_AsCharmapString(object o, object mapping)
|
| 572 |
+
|
| 573 |
+
# The following codec API is special in that maps Unicode to Unicode.
|
| 574 |
+
|
| 575 |
+
# Translate a Py_UNICODE buffer of the given length by applying a
|
| 576 |
+
# character mapping table to it and return the resulting Unicode
|
| 577 |
+
# object. Return NULL when an exception was raised by the codec.
|
| 578 |
+
#
|
| 579 |
+
# The mapping table must map Unicode ordinal integers to Unicode
|
| 580 |
+
# ordinal integers or None (causing deletion of the character).
|
| 581 |
+
#
|
| 582 |
+
# Mapping tables need only provide the __getitem__() interface;
|
| 583 |
+
# dictionaries and sequences work well. Unmapped character
|
| 584 |
+
# ordinals (ones which cause a LookupError) are left untouched and
|
| 585 |
+
# are copied as-is.
|
| 586 |
+
#
|
| 587 |
+
# Deprecated since version 3.3, will be removed in version 4.0.
|
| 588 |
+
object PyUnicode_TranslateCharmap(Py_UNICODE *s, Py_ssize_t size,
|
| 589 |
+
object table, char *errors)
|
| 590 |
+
|
| 591 |
+
# These are the MBCS codec APIs. They are currently only available on
|
| 592 |
+
# Windows and use the Win32 MBCS converters to implement the
|
| 593 |
+
# conversions. Note that MBCS (or DBCS) is a class of encodings, not
|
| 594 |
+
# just one. The target encoding is defined by the user settings on the
|
| 595 |
+
# machine running the codec.
|
| 596 |
+
|
| 597 |
+
# Create a Unicode object by decoding size bytes of the MBCS
|
| 598 |
+
# encoded string s. Return NULL if an exception was raised by the
|
| 599 |
+
# codec.
|
| 600 |
+
unicode PyUnicode_DecodeMBCS(char *s, Py_ssize_t size, char *errors)
|
| 601 |
+
|
| 602 |
+
# If consumed is NULL, behave like PyUnicode_DecodeMBCS(). If
|
| 603 |
+
# consumed is not NULL, PyUnicode_DecodeMBCSStateful() will not
|
| 604 |
+
# decode trailing lead byte and the number of bytes that have been
|
| 605 |
+
# decoded will be stored in consumed. New in version 2.5.
|
| 606 |
+
# NOTE: Python 2.x uses 'int' values for 'size' and 'consumed' (changed in 3.0)
|
| 607 |
+
unicode PyUnicode_DecodeMBCSStateful(char *s, Py_ssize_t size, char *errors, Py_ssize_t *consumed)
|
| 608 |
+
|
| 609 |
+
# Encode the Py_UNICODE buffer of the given size using MBCS and
|
| 610 |
+
# return a Python string object. Return NULL if an exception was
|
| 611 |
+
# raised by the codec.
|
| 612 |
+
bytes PyUnicode_EncodeMBCS(Py_UNICODE *s, Py_ssize_t size, char *errors)
|
| 613 |
+
|
| 614 |
+
# Encode a Unicode objects using MBCS and return the result as
|
| 615 |
+
# Python string object. Error handling is ``strict''. Return NULL
|
| 616 |
+
# if an exception was raised by the codec.
|
| 617 |
+
bytes PyUnicode_AsMBCSString(object o)
|
| 618 |
+
|
| 619 |
+
# Encode the Unicode object using the specified code page and return
|
| 620 |
+
# a Python bytes object. Return NULL if an exception was raised by the
|
| 621 |
+
# codec. Use CP_ACP code page to get the MBCS encoder.
|
| 622 |
+
#
|
| 623 |
+
# New in version 3.3.
|
| 624 |
+
bytes PyUnicode_EncodeCodePage(int code_page, object unicode, const char *errors)
|
| 625 |
+
|
| 626 |
+
|
| 627 |
+
# Py_UCS4 helpers (new in CPython 3.3)
|
| 628 |
+
|
| 629 |
+
# These utility functions work on strings of Py_UCS4 characters and
|
| 630 |
+
# otherwise behave like the C standard library functions with the same name.
|
| 631 |
+
|
| 632 |
+
size_t Py_UCS4_strlen(const Py_UCS4 *u)
|
| 633 |
+
Py_UCS4* Py_UCS4_strcpy(Py_UCS4 *s1, const Py_UCS4 *s2)
|
| 634 |
+
Py_UCS4* Py_UCS4_strncpy(Py_UCS4 *s1, const Py_UCS4 *s2, size_t n)
|
| 635 |
+
Py_UCS4* Py_UCS4_strcat(Py_UCS4 *s1, const Py_UCS4 *s2)
|
| 636 |
+
int Py_UCS4_strcmp(const Py_UCS4 *s1, const Py_UCS4 *s2)
|
| 637 |
+
int Py_UCS4_strncmp(const Py_UCS4 *s1, const Py_UCS4 *s2, size_t n)
|
| 638 |
+
Py_UCS4* Py_UCS4_strchr(const Py_UCS4 *s, Py_UCS4 c)
|
| 639 |
+
Py_UCS4* Py_UCS4_strrchr(const Py_UCS4 *s, Py_UCS4 c)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/__init__.pxd
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# empty file
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/complex.pxd
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cdef extern from "<complex.h>" nogil:
|
| 2 |
+
# Trigonometric functions.
|
| 3 |
+
double complex cacos(double complex z)
|
| 4 |
+
double complex casin(double complex z)
|
| 5 |
+
double complex catan(double complex z)
|
| 6 |
+
double complex ccos(double complex z)
|
| 7 |
+
double complex csin(double complex z)
|
| 8 |
+
double complex ctan(double complex z)
|
| 9 |
+
|
| 10 |
+
# Hyperbolic functions.
|
| 11 |
+
double complex cacosh(double complex z)
|
| 12 |
+
double complex casinh(double complex z)
|
| 13 |
+
double complex catanh(double complex z)
|
| 14 |
+
double complex ccosh(double complex z)
|
| 15 |
+
double complex csinh(double complex z)
|
| 16 |
+
double complex ctanh(double complex z)
|
| 17 |
+
|
| 18 |
+
# Exponential and logarithmic functions.
|
| 19 |
+
double complex cexp(double complex z)
|
| 20 |
+
double complex clog(double complex z)
|
| 21 |
+
double complex clog10(double complex z)
|
| 22 |
+
|
| 23 |
+
# Power functions.
|
| 24 |
+
double complex cpow(double complex x, double complex y)
|
| 25 |
+
double complex csqrt(double complex z)
|
| 26 |
+
|
| 27 |
+
# Absolute value, conjugates, and projection.
|
| 28 |
+
double cabs(double complex z)
|
| 29 |
+
double carg(double complex z)
|
| 30 |
+
double complex conj(double complex z)
|
| 31 |
+
double complex cproj(double complex z)
|
| 32 |
+
|
| 33 |
+
# Decomposing complex values.
|
| 34 |
+
double cimag(double complex z)
|
| 35 |
+
double creal(double complex z)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/errno.pxd
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.5 Errors <errno.h>
|
| 2 |
+
|
| 3 |
+
cdef extern from "<errno.h>" nogil:
|
| 4 |
+
enum:
|
| 5 |
+
EPERM
|
| 6 |
+
ENOENT
|
| 7 |
+
ESRCH
|
| 8 |
+
EINTR
|
| 9 |
+
EIO
|
| 10 |
+
ENXIO
|
| 11 |
+
E2BIG
|
| 12 |
+
ENOEXEC
|
| 13 |
+
EBADF
|
| 14 |
+
ECHILD
|
| 15 |
+
EAGAIN
|
| 16 |
+
ENOMEM
|
| 17 |
+
EACCES
|
| 18 |
+
EFAULT
|
| 19 |
+
ENOTBLK
|
| 20 |
+
EBUSY
|
| 21 |
+
EEXIST
|
| 22 |
+
EXDEV
|
| 23 |
+
ENODEV
|
| 24 |
+
ENOTDIR
|
| 25 |
+
EISDIR
|
| 26 |
+
EINVAL
|
| 27 |
+
ENFILE
|
| 28 |
+
EMFILE
|
| 29 |
+
ENOTTY
|
| 30 |
+
ETXTBSY
|
| 31 |
+
EFBIG
|
| 32 |
+
ENOSPC
|
| 33 |
+
ESPIPE
|
| 34 |
+
EROFS
|
| 35 |
+
EMLINK
|
| 36 |
+
EPIPE
|
| 37 |
+
EDOM
|
| 38 |
+
ERANGE
|
| 39 |
+
EDEADLOCK
|
| 40 |
+
ENAMETOOLONG
|
| 41 |
+
ENOLCK
|
| 42 |
+
ENOSYS
|
| 43 |
+
ENOTEMPTY
|
| 44 |
+
ELOOP
|
| 45 |
+
ENOMSG
|
| 46 |
+
EIDRM
|
| 47 |
+
ECHRNG
|
| 48 |
+
EL2NSYNC
|
| 49 |
+
EL3HLT
|
| 50 |
+
EL3RST
|
| 51 |
+
ELNRNG
|
| 52 |
+
EUNATCH
|
| 53 |
+
ENOCSI
|
| 54 |
+
EL2HLT
|
| 55 |
+
EBADE
|
| 56 |
+
EBADR
|
| 57 |
+
EXFULL
|
| 58 |
+
ENOANO
|
| 59 |
+
EBADRQC
|
| 60 |
+
EBADSLT
|
| 61 |
+
EBFONT
|
| 62 |
+
ENOSTR
|
| 63 |
+
ENODATA
|
| 64 |
+
ENOATTR
|
| 65 |
+
ETIME
|
| 66 |
+
ENOSR
|
| 67 |
+
ENONET
|
| 68 |
+
ENOPKG
|
| 69 |
+
EREMOTE
|
| 70 |
+
ENOLINK
|
| 71 |
+
EADV
|
| 72 |
+
ESRMNT
|
| 73 |
+
ECOMM
|
| 74 |
+
EPROTO
|
| 75 |
+
EMULTIHOP
|
| 76 |
+
EDOTDOT
|
| 77 |
+
EBADMSG
|
| 78 |
+
EOVERFLOW
|
| 79 |
+
ENOTUNIQ
|
| 80 |
+
EBADFD
|
| 81 |
+
EREMCHG
|
| 82 |
+
ELIBACC
|
| 83 |
+
ELIBBAD
|
| 84 |
+
ELIBSCN
|
| 85 |
+
ELIBMAX
|
| 86 |
+
ELIBEXEC
|
| 87 |
+
EILSEQ
|
| 88 |
+
ERESTART
|
| 89 |
+
ESTRPIPE
|
| 90 |
+
EUSERS
|
| 91 |
+
ENOTSOCK
|
| 92 |
+
EDESTADDRREQ
|
| 93 |
+
EMSGSIZE
|
| 94 |
+
EPROTOTYPE
|
| 95 |
+
ENOPROTOOPT
|
| 96 |
+
EPROTONOSUPPORT
|
| 97 |
+
ESOCKTNOSUPPORT
|
| 98 |
+
EOPNOTSUPP
|
| 99 |
+
EPFNOSUPPORT
|
| 100 |
+
EAFNOSUPPORT
|
| 101 |
+
EADDRINUSE
|
| 102 |
+
EADDRNOTAVAIL
|
| 103 |
+
ENETDOWN
|
| 104 |
+
ENETUNREACH
|
| 105 |
+
ENETRESET
|
| 106 |
+
ECONNABORTED
|
| 107 |
+
ECONNRESET
|
| 108 |
+
ENOBUFS
|
| 109 |
+
EISCONN
|
| 110 |
+
ENOTCONN
|
| 111 |
+
ESHUTDOWN
|
| 112 |
+
ETOOMANYREFS
|
| 113 |
+
ETIMEDOUT
|
| 114 |
+
ECONNREFUSED
|
| 115 |
+
EHOSTDOWN
|
| 116 |
+
EHOSTUNREACH
|
| 117 |
+
EALREADY
|
| 118 |
+
EINPROGRESS
|
| 119 |
+
ESTALE
|
| 120 |
+
EUCLEAN
|
| 121 |
+
ENOTNAM
|
| 122 |
+
ENAVAIL
|
| 123 |
+
EISNAM
|
| 124 |
+
EREMOTEIO
|
| 125 |
+
EDQUOT
|
| 126 |
+
|
| 127 |
+
int errno
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/float.pxd
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 5.2.4.2.2 Characteristics of floating types <float.h>
|
| 2 |
+
|
| 3 |
+
cdef extern from "<float.h>":
|
| 4 |
+
|
| 5 |
+
const float FLT_RADIX
|
| 6 |
+
|
| 7 |
+
const float FLT_MANT_DIG
|
| 8 |
+
const double DBL_MANT_DIG
|
| 9 |
+
const long double LDBL_MANT_DIG
|
| 10 |
+
|
| 11 |
+
const double DECIMAL_DIG
|
| 12 |
+
|
| 13 |
+
const float FLT_DIG
|
| 14 |
+
const double DBL_DIG
|
| 15 |
+
const long double LDBL_DIG
|
| 16 |
+
|
| 17 |
+
const float FLT_MIN_EXP
|
| 18 |
+
const double DBL_MIN_EXP
|
| 19 |
+
const long double LDBL_MIN_EXP
|
| 20 |
+
|
| 21 |
+
const float FLT_MIN_10_EXP
|
| 22 |
+
const double DBL_MIN_10_EXP
|
| 23 |
+
const long double LDBL_MIN_10_EXP
|
| 24 |
+
|
| 25 |
+
const float FLT_MAX_EXP
|
| 26 |
+
const double DBL_MAX_EXP
|
| 27 |
+
const long double LDBL_MAX_EXP
|
| 28 |
+
|
| 29 |
+
const float FLT_MAX_10_EXP
|
| 30 |
+
const double DBL_MAX_10_EXP
|
| 31 |
+
const long double LDBL_MAX_10_EXP
|
| 32 |
+
|
| 33 |
+
const float FLT_MAX
|
| 34 |
+
const double DBL_MAX
|
| 35 |
+
const long double LDBL_MAX
|
| 36 |
+
|
| 37 |
+
const float FLT_EPSILON
|
| 38 |
+
const double DBL_EPSILON
|
| 39 |
+
const long double LDBL_EPSILON
|
| 40 |
+
|
| 41 |
+
const float FLT_MIN
|
| 42 |
+
const double DBL_MIN
|
| 43 |
+
const long double LDBL_MIN
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/limits.pxd
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 5.2.4.2.1 Sizes of integer types <limits.h>
|
| 2 |
+
|
| 3 |
+
cdef extern from "<limits.h>":
|
| 4 |
+
const int CHAR_BIT
|
| 5 |
+
const int MB_LEN_MAX
|
| 6 |
+
|
| 7 |
+
const char CHAR_MIN
|
| 8 |
+
const char CHAR_MAX
|
| 9 |
+
|
| 10 |
+
const signed char SCHAR_MIN
|
| 11 |
+
const signed char SCHAR_MAX
|
| 12 |
+
const unsigned char UCHAR_MAX
|
| 13 |
+
|
| 14 |
+
const short SHRT_MIN
|
| 15 |
+
const short SHRT_MAX
|
| 16 |
+
const unsigned short USHRT_MAX
|
| 17 |
+
|
| 18 |
+
const int INT_MIN
|
| 19 |
+
const int INT_MAX
|
| 20 |
+
const unsigned int UINT_MAX
|
| 21 |
+
|
| 22 |
+
const long LONG_MIN
|
| 23 |
+
const long LONG_MAX
|
| 24 |
+
const unsigned long ULONG_MAX
|
| 25 |
+
|
| 26 |
+
const long long LLONG_MIN
|
| 27 |
+
const long long LLONG_MAX
|
| 28 |
+
const unsigned long long ULLONG_MAX
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/locale.pxd
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.11 Localization <locale.h>
|
| 2 |
+
|
| 3 |
+
# deprecated cimport for backwards compatibility:
|
| 4 |
+
from libc.string cimport const_char
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
cdef extern from "<locale.h>" nogil:
|
| 8 |
+
|
| 9 |
+
struct lconv:
|
| 10 |
+
char *decimal_point
|
| 11 |
+
char *thousands_sep
|
| 12 |
+
char *grouping
|
| 13 |
+
char *mon_decimal_point
|
| 14 |
+
char *mon_thousands_sep
|
| 15 |
+
char *mon_grouping
|
| 16 |
+
char *positive_sign
|
| 17 |
+
char *negative_sign
|
| 18 |
+
char *currency_symbol
|
| 19 |
+
char frac_digits
|
| 20 |
+
char p_cs_precedes
|
| 21 |
+
char n_cs_precedes
|
| 22 |
+
char p_sep_by_space
|
| 23 |
+
char n_sep_by_space
|
| 24 |
+
char p_sign_posn
|
| 25 |
+
char n_sign_posn
|
| 26 |
+
char *int_curr_symbol
|
| 27 |
+
char int_frac_digits
|
| 28 |
+
char int_p_cs_precedes
|
| 29 |
+
char int_n_cs_precedes
|
| 30 |
+
char int_p_sep_by_space
|
| 31 |
+
char int_n_sep_by_space
|
| 32 |
+
char int_p_sign_posn
|
| 33 |
+
char int_n_sign_posn
|
| 34 |
+
|
| 35 |
+
enum: LC_ALL
|
| 36 |
+
enum: LC_COLLATE
|
| 37 |
+
enum: LC_CTYPE
|
| 38 |
+
enum: LC_MONETARY
|
| 39 |
+
enum: LC_NUMERIC
|
| 40 |
+
enum: LC_TIME
|
| 41 |
+
|
| 42 |
+
# 7.11.1 Locale control
|
| 43 |
+
char *setlocale (int category, const char *locale)
|
| 44 |
+
|
| 45 |
+
# 7.11.2 Numeric formatting convention inquiry
|
| 46 |
+
lconv *localeconv ()
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/math.pxd
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cdef extern from "<math.h>" nogil:
|
| 2 |
+
const double M_E
|
| 3 |
+
const double e "M_E" # as in Python's math module
|
| 4 |
+
const double M_LOG2E
|
| 5 |
+
const double M_LOG10E
|
| 6 |
+
const double M_LN2
|
| 7 |
+
const double M_LN10
|
| 8 |
+
const double M_PI
|
| 9 |
+
const double pi "M_PI" # as in Python's math module
|
| 10 |
+
const double M_PI_2
|
| 11 |
+
const double M_PI_4
|
| 12 |
+
const double M_1_PI
|
| 13 |
+
const double M_2_PI
|
| 14 |
+
const double M_2_SQRTPI
|
| 15 |
+
const double M_SQRT2
|
| 16 |
+
const double M_SQRT1_2
|
| 17 |
+
|
| 18 |
+
# C99 constants
|
| 19 |
+
const float INFINITY
|
| 20 |
+
const float NAN
|
| 21 |
+
# note: not providing "nan" and "inf" aliases here as nan() is a function in C
|
| 22 |
+
const double HUGE_VAL
|
| 23 |
+
const float HUGE_VALF
|
| 24 |
+
const long double HUGE_VALL
|
| 25 |
+
|
| 26 |
+
# All C99 functions in alphabetical order
|
| 27 |
+
double acos(double x)
|
| 28 |
+
float acosf(float)
|
| 29 |
+
double acosh(double x)
|
| 30 |
+
float acoshf(float)
|
| 31 |
+
long double acoshl(long double)
|
| 32 |
+
long double acosl(long double)
|
| 33 |
+
double asin(double x)
|
| 34 |
+
float asinf(float)
|
| 35 |
+
double asinh(double x)
|
| 36 |
+
float asinhf(float)
|
| 37 |
+
long double asinhl(long double)
|
| 38 |
+
long double asinl(long double)
|
| 39 |
+
double atan(double x)
|
| 40 |
+
double atan2(double y, double x)
|
| 41 |
+
float atan2f(float, float)
|
| 42 |
+
long double atan2l(long double, long double)
|
| 43 |
+
float atanf(float)
|
| 44 |
+
double atanh(double x)
|
| 45 |
+
float atanhf(float)
|
| 46 |
+
long double atanhl(long double)
|
| 47 |
+
long double atanl(long double)
|
| 48 |
+
double cbrt(double x)
|
| 49 |
+
float cbrtf(float)
|
| 50 |
+
long double cbrtl(long double)
|
| 51 |
+
double ceil(double x)
|
| 52 |
+
float ceilf(float)
|
| 53 |
+
long double ceill(long double)
|
| 54 |
+
double copysign(double, double)
|
| 55 |
+
float copysignf(float, float)
|
| 56 |
+
long double copysignl(long double, long double)
|
| 57 |
+
double cos(double x)
|
| 58 |
+
float cosf(float)
|
| 59 |
+
double cosh(double x)
|
| 60 |
+
float coshf(float)
|
| 61 |
+
long double coshl(long double)
|
| 62 |
+
long double cosl(long double)
|
| 63 |
+
double erf(double)
|
| 64 |
+
double erfc(double)
|
| 65 |
+
float erfcf(float)
|
| 66 |
+
long double erfcl(long double)
|
| 67 |
+
float erff(float)
|
| 68 |
+
long double erfl(long double)
|
| 69 |
+
double exp(double x)
|
| 70 |
+
double exp2(double x)
|
| 71 |
+
float exp2f(float)
|
| 72 |
+
long double exp2l(long double)
|
| 73 |
+
float expf(float)
|
| 74 |
+
long double expl(long double)
|
| 75 |
+
double expm1(double x)
|
| 76 |
+
float expm1f(float)
|
| 77 |
+
long double expm1l(long double)
|
| 78 |
+
double fabs(double x)
|
| 79 |
+
float fabsf(float)
|
| 80 |
+
long double fabsl(long double)
|
| 81 |
+
double fdim(double x, double y)
|
| 82 |
+
float fdimf(float, float)
|
| 83 |
+
long double fdiml(long double, long double)
|
| 84 |
+
double floor(double x)
|
| 85 |
+
float floorf(float)
|
| 86 |
+
long double floorl(long double)
|
| 87 |
+
double fma(double x, double y, double z)
|
| 88 |
+
float fmaf(float, float, float)
|
| 89 |
+
long double fmal(long double, long double, long double)
|
| 90 |
+
double fmax(double x, double y)
|
| 91 |
+
float fmaxf(float, float)
|
| 92 |
+
long double fmaxl(long double, long double)
|
| 93 |
+
double fmin(double x, double y)
|
| 94 |
+
float fminf(float, float)
|
| 95 |
+
long double fminl(long double, long double)
|
| 96 |
+
double fmod(double x, double y)
|
| 97 |
+
float fmodf(float, float)
|
| 98 |
+
long double fmodl(long double, long double)
|
| 99 |
+
double frexp(double x, int* exponent)
|
| 100 |
+
float frexpf(float, int* exponent)
|
| 101 |
+
long double frexpl(long double, int*)
|
| 102 |
+
double hypot(double x, double y)
|
| 103 |
+
float hypotf(float, float)
|
| 104 |
+
long double hypotl(long double, long double)
|
| 105 |
+
int ilogb(double x)
|
| 106 |
+
int ilogbf(float)
|
| 107 |
+
int ilogbl(long double)
|
| 108 |
+
double ldexp(double x, int exponent)
|
| 109 |
+
float ldexpf(float, int exponent)
|
| 110 |
+
long double ldexpl(long double, int exponent)
|
| 111 |
+
double lgamma(double x)
|
| 112 |
+
float lgammaf(float)
|
| 113 |
+
long double lgammal(long double)
|
| 114 |
+
long long llrint(double)
|
| 115 |
+
long long llrintf(float)
|
| 116 |
+
long long llrintl(long double)
|
| 117 |
+
long long llround(double)
|
| 118 |
+
long long llroundf(float)
|
| 119 |
+
long long llroundl(long double)
|
| 120 |
+
double log(double x)
|
| 121 |
+
double log10(double x)
|
| 122 |
+
float log10f(float)
|
| 123 |
+
long double log10l(long double)
|
| 124 |
+
double log1p(double x)
|
| 125 |
+
float log1pf(float)
|
| 126 |
+
long double log1pl(long double)
|
| 127 |
+
double log2(double x)
|
| 128 |
+
float log2f(float)
|
| 129 |
+
long double log2l(long double)
|
| 130 |
+
double logb(double x)
|
| 131 |
+
float logbf(float)
|
| 132 |
+
long double logbl(long double)
|
| 133 |
+
float logf(float)
|
| 134 |
+
long double logl(long double)
|
| 135 |
+
long lrint(double)
|
| 136 |
+
long lrintf(float)
|
| 137 |
+
long lrintl(long double)
|
| 138 |
+
long lround(double)
|
| 139 |
+
long lroundf(float)
|
| 140 |
+
long lroundl(long double)
|
| 141 |
+
double modf(double x, double* iptr)
|
| 142 |
+
float modff(float, float* iptr)
|
| 143 |
+
long double modfl(long double, long double* iptr)
|
| 144 |
+
double nan(const char*)
|
| 145 |
+
float nanf(const char*)
|
| 146 |
+
long double nanl(const char*)
|
| 147 |
+
double nearbyint(double x)
|
| 148 |
+
float nearbyintf(float)
|
| 149 |
+
long double nearbyintl(long double)
|
| 150 |
+
double nextafter(double, double)
|
| 151 |
+
float nextafterf(float, float)
|
| 152 |
+
long double nextafterl(long double, long double)
|
| 153 |
+
double nexttoward(double, long double)
|
| 154 |
+
float nexttowardf(float, long double)
|
| 155 |
+
long double nexttowardl(long double, long double)
|
| 156 |
+
double pow(double x, double y)
|
| 157 |
+
float powf(float, float)
|
| 158 |
+
long double powl(long double, long double)
|
| 159 |
+
double remainder(double x, double y)
|
| 160 |
+
float remainderf(float, float)
|
| 161 |
+
long double remainderl(long double, long double)
|
| 162 |
+
double remquo(double x, double y, int* quot)
|
| 163 |
+
float remquof(float, float, int* quot)
|
| 164 |
+
long double remquol(long double, long double, int* quot)
|
| 165 |
+
double rint(double x)
|
| 166 |
+
float rintf(float)
|
| 167 |
+
long double rintl(long double)
|
| 168 |
+
double round(double x)
|
| 169 |
+
float roundf(float)
|
| 170 |
+
long double roundl(long double)
|
| 171 |
+
double scalbln(double x, long n)
|
| 172 |
+
float scalblnf(float, long)
|
| 173 |
+
long double scalblnl(long double, long)
|
| 174 |
+
double scalbn(double x, int n)
|
| 175 |
+
float scalbnf(float, int)
|
| 176 |
+
long double scalbnl(long double, int)
|
| 177 |
+
double sin(double x)
|
| 178 |
+
float sinf(float)
|
| 179 |
+
double sinh(double x)
|
| 180 |
+
float sinhf(float)
|
| 181 |
+
long double sinhl(long double)
|
| 182 |
+
long double sinl(long double)
|
| 183 |
+
double sqrt(double x)
|
| 184 |
+
float sqrtf(float)
|
| 185 |
+
long double sqrtl(long double)
|
| 186 |
+
double tan(double x)
|
| 187 |
+
float tanf(float)
|
| 188 |
+
double tanh(double x)
|
| 189 |
+
float tanhf(float)
|
| 190 |
+
long double tanhl(long double)
|
| 191 |
+
long double tanl(long double)
|
| 192 |
+
double tgamma(double x)
|
| 193 |
+
float tgammaf(float)
|
| 194 |
+
long double tgammal(long double)
|
| 195 |
+
double trunc(double x)
|
| 196 |
+
float truncf(float)
|
| 197 |
+
long double truncl(long double)
|
| 198 |
+
|
| 199 |
+
int isinf(long double) # -1 / 0 / 1
|
| 200 |
+
bint isfinite(long double)
|
| 201 |
+
bint isnan(long double)
|
| 202 |
+
bint isnormal(long double)
|
| 203 |
+
bint signbit(long double)
|
| 204 |
+
int fpclassify(long double)
|
| 205 |
+
const int FP_NAN
|
| 206 |
+
const int FP_INFINITE
|
| 207 |
+
const int FP_ZERO
|
| 208 |
+
const int FP_SUBNORMAL
|
| 209 |
+
const int FP_NORMAL
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/setjmp.pxd
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cdef extern from "<setjmp.h>" nogil:
|
| 2 |
+
ctypedef struct jmp_buf:
|
| 3 |
+
pass
|
| 4 |
+
int setjmp(jmp_buf state)
|
| 5 |
+
void longjmp(jmp_buf state, int value)
|
| 6 |
+
|
| 7 |
+
ctypedef struct sigjmp_buf:
|
| 8 |
+
pass
|
| 9 |
+
int sigsetjmp(sigjmp_buf state, int savesigs)
|
| 10 |
+
void siglongjmp(sigjmp_buf state, int value)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/signal.pxd
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.14 Signal handling <signal.h>
|
| 2 |
+
|
| 3 |
+
ctypedef void (*sighandler_t)(int SIGNUM) noexcept nogil
|
| 4 |
+
|
| 5 |
+
cdef extern from "<signal.h>" nogil:
|
| 6 |
+
|
| 7 |
+
ctypedef int sig_atomic_t
|
| 8 |
+
|
| 9 |
+
sighandler_t SIG_DFL
|
| 10 |
+
sighandler_t SIG_IGN
|
| 11 |
+
sighandler_t SIG_ERR
|
| 12 |
+
|
| 13 |
+
sighandler_t signal (int signum, sighandler_t action)
|
| 14 |
+
int raise_"raise" (int signum)
|
| 15 |
+
|
| 16 |
+
# Signals
|
| 17 |
+
enum:
|
| 18 |
+
# Program Error
|
| 19 |
+
SIGFPE
|
| 20 |
+
SIGILL
|
| 21 |
+
SIGSEGV
|
| 22 |
+
SIGBUS
|
| 23 |
+
SIGABRT
|
| 24 |
+
SIGIOT
|
| 25 |
+
SIGTRAP
|
| 26 |
+
SIGEMT
|
| 27 |
+
SIGSYS
|
| 28 |
+
SIGSTKFLT
|
| 29 |
+
# Termination
|
| 30 |
+
SIGTERM
|
| 31 |
+
SIGINT
|
| 32 |
+
SIGQUIT
|
| 33 |
+
SIGKILL
|
| 34 |
+
SIGHUP
|
| 35 |
+
# Alarm
|
| 36 |
+
SIGALRM
|
| 37 |
+
SIGVTALRM
|
| 38 |
+
SIGPROF
|
| 39 |
+
# Asynchronous I/O
|
| 40 |
+
SIGIO
|
| 41 |
+
SIGURG
|
| 42 |
+
SIGPOLL
|
| 43 |
+
# Job Control
|
| 44 |
+
SIGCHLD
|
| 45 |
+
SIGCLD
|
| 46 |
+
SIGCONT
|
| 47 |
+
SIGSTOP
|
| 48 |
+
SIGTSTP
|
| 49 |
+
SIGTTIN
|
| 50 |
+
SIGTTOU
|
| 51 |
+
# Operation Error
|
| 52 |
+
SIGPIPE
|
| 53 |
+
SIGLOST
|
| 54 |
+
SIGXCPU
|
| 55 |
+
SIGXFSZ
|
| 56 |
+
SIGPWR
|
| 57 |
+
# Miscellaneous
|
| 58 |
+
SIGUSR1
|
| 59 |
+
SIGUSR2
|
| 60 |
+
SIGWINCH
|
| 61 |
+
SIGINFO
|
| 62 |
+
# Real-time signals
|
| 63 |
+
SIGRTMIN
|
| 64 |
+
SIGRTMAX
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stddef.pxd
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.17 Common definitions <stddef.h>
|
| 2 |
+
|
| 3 |
+
cdef extern from "<stddef.h>":
|
| 4 |
+
|
| 5 |
+
ctypedef signed int ptrdiff_t
|
| 6 |
+
|
| 7 |
+
ctypedef unsigned int size_t
|
| 8 |
+
|
| 9 |
+
ctypedef int wchar_t
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stdint.pxd
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Longness only used for type promotion.
|
| 2 |
+
# Actual compile time size used for conversions.
|
| 3 |
+
|
| 4 |
+
# 7.18 Integer types <stdint.h>
|
| 5 |
+
cdef extern from "<stdint.h>" nogil:
|
| 6 |
+
|
| 7 |
+
# 7.18.1 Integer types
|
| 8 |
+
# 7.18.1.1 Exact-width integer types
|
| 9 |
+
ctypedef signed char int8_t
|
| 10 |
+
ctypedef signed short int16_t
|
| 11 |
+
ctypedef signed int int32_t
|
| 12 |
+
ctypedef signed long int64_t
|
| 13 |
+
ctypedef unsigned char uint8_t
|
| 14 |
+
ctypedef unsigned short uint16_t
|
| 15 |
+
ctypedef unsigned int uint32_t
|
| 16 |
+
ctypedef unsigned long long uint64_t
|
| 17 |
+
# 7.18.1.2 Minimum-width integer types
|
| 18 |
+
ctypedef signed char int_least8_t
|
| 19 |
+
ctypedef signed short int_least16_t
|
| 20 |
+
ctypedef signed int int_least32_t
|
| 21 |
+
ctypedef signed long int_least64_t
|
| 22 |
+
ctypedef unsigned char uint_least8_t
|
| 23 |
+
ctypedef unsigned short uint_least16_t
|
| 24 |
+
ctypedef unsigned int uint_least32_t
|
| 25 |
+
ctypedef unsigned long long uint_least64_t
|
| 26 |
+
# 7.18.1.3 Fastest minimum-width integer types
|
| 27 |
+
ctypedef signed char int_fast8_t
|
| 28 |
+
ctypedef signed short int_fast16_t
|
| 29 |
+
ctypedef signed int int_fast32_t
|
| 30 |
+
ctypedef signed long int_fast64_t
|
| 31 |
+
ctypedef unsigned char uint_fast8_t
|
| 32 |
+
ctypedef unsigned short uint_fast16_t
|
| 33 |
+
ctypedef unsigned int uint_fast32_t
|
| 34 |
+
ctypedef unsigned long long uint_fast64_t
|
| 35 |
+
# 7.18.1.4 Integer types capable of holding object pointers
|
| 36 |
+
ctypedef ssize_t intptr_t
|
| 37 |
+
ctypedef size_t uintptr_t
|
| 38 |
+
# 7.18.1.5 Greatest-width integer types
|
| 39 |
+
ctypedef signed long long intmax_t
|
| 40 |
+
ctypedef unsigned long long uintmax_t
|
| 41 |
+
|
| 42 |
+
# 7.18.2 Limits of specified-width integer types
|
| 43 |
+
# 7.18.2.1 Limits of exact-width integer types
|
| 44 |
+
int8_t INT8_MIN
|
| 45 |
+
int16_t INT16_MIN
|
| 46 |
+
int32_t INT32_MIN
|
| 47 |
+
int64_t INT64_MIN
|
| 48 |
+
int8_t INT8_MAX
|
| 49 |
+
int16_t INT16_MAX
|
| 50 |
+
int32_t INT32_MAX
|
| 51 |
+
int64_t INT64_MAX
|
| 52 |
+
uint8_t UINT8_MAX
|
| 53 |
+
uint16_t UINT16_MAX
|
| 54 |
+
uint32_t UINT32_MAX
|
| 55 |
+
uint64_t UINT64_MAX
|
| 56 |
+
#7.18.2.2 Limits of minimum-width integer types
|
| 57 |
+
int_least8_t INT_LEAST8_MIN
|
| 58 |
+
int_least16_t INT_LEAST16_MIN
|
| 59 |
+
int_least32_t INT_LEAST32_MIN
|
| 60 |
+
int_least64_t INT_LEAST64_MIN
|
| 61 |
+
int_least8_t INT_LEAST8_MAX
|
| 62 |
+
int_least16_t INT_LEAST16_MAX
|
| 63 |
+
int_least32_t INT_LEAST32_MAX
|
| 64 |
+
int_least64_t INT_LEAST64_MAX
|
| 65 |
+
uint_least8_t UINT_LEAST8_MAX
|
| 66 |
+
uint_least16_t UINT_LEAST16_MAX
|
| 67 |
+
uint_least32_t UINT_LEAST32_MAX
|
| 68 |
+
uint_least64_t UINT_LEAST64_MAX
|
| 69 |
+
#7.18.2.3 Limits of fastest minimum-width integer types
|
| 70 |
+
int_fast8_t INT_FAST8_MIN
|
| 71 |
+
int_fast16_t INT_FAST16_MIN
|
| 72 |
+
int_fast32_t INT_FAST32_MIN
|
| 73 |
+
int_fast64_t INT_FAST64_MIN
|
| 74 |
+
int_fast8_t INT_FAST8_MAX
|
| 75 |
+
int_fast16_t INT_FAST16_MAX
|
| 76 |
+
int_fast32_t INT_FAST32_MAX
|
| 77 |
+
int_fast64_t INT_FAST64_MAX
|
| 78 |
+
uint_fast8_t UINT_FAST8_MAX
|
| 79 |
+
uint_fast16_t UINT_FAST16_MAX
|
| 80 |
+
uint_fast32_t UINT_FAST32_MAX
|
| 81 |
+
uint_fast64_t UINT_FAST64_MAX
|
| 82 |
+
#7.18.2.4 Limits of integer types capable of holding object pointers
|
| 83 |
+
enum: INTPTR_MIN
|
| 84 |
+
enum: INTPTR_MAX
|
| 85 |
+
enum: UINTPTR_MAX
|
| 86 |
+
# 7.18.2.5 Limits of greatest-width integer types
|
| 87 |
+
enum: INTMAX_MAX
|
| 88 |
+
enum: INTMAX_MIN
|
| 89 |
+
enum: UINTMAX_MAX
|
| 90 |
+
|
| 91 |
+
# 7.18.3 Limits of other integer types
|
| 92 |
+
# ptrdiff_t
|
| 93 |
+
enum: PTRDIFF_MIN
|
| 94 |
+
enum: PTRDIFF_MAX
|
| 95 |
+
# sig_atomic_t
|
| 96 |
+
enum: SIG_ATOMIC_MIN
|
| 97 |
+
enum: SIG_ATOMIC_MAX
|
| 98 |
+
# size_t
|
| 99 |
+
size_t SIZE_MAX
|
| 100 |
+
# wchar_t
|
| 101 |
+
enum: WCHAR_MIN
|
| 102 |
+
enum: WCHAR_MAX
|
| 103 |
+
# wint_t
|
| 104 |
+
enum: WINT_MIN
|
| 105 |
+
enum: WINT_MAX
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stdio.pxd
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.19 Input/output <stdio.h>
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
# deprecated cimports for backwards compatibility:
|
| 5 |
+
from libc.string cimport const_char, const_void
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
cdef extern from "<stdio.h>" nogil:
|
| 9 |
+
|
| 10 |
+
ctypedef struct FILE
|
| 11 |
+
cdef FILE *stdin
|
| 12 |
+
cdef FILE *stdout
|
| 13 |
+
cdef FILE *stderr
|
| 14 |
+
|
| 15 |
+
enum: FOPEN_MAX
|
| 16 |
+
enum: FILENAME_MAX
|
| 17 |
+
FILE *fopen (const char *filename, const char *opentype)
|
| 18 |
+
FILE *freopen (const char *filename, const char *opentype, FILE *stream)
|
| 19 |
+
FILE *fdopen (int fdescriptor, const char *opentype)
|
| 20 |
+
int fclose (FILE *stream)
|
| 21 |
+
int remove (const char *filename)
|
| 22 |
+
int rename (const char *oldname, const char *newname)
|
| 23 |
+
FILE *tmpfile ()
|
| 24 |
+
|
| 25 |
+
int remove (const char *pathname)
|
| 26 |
+
int rename (const char *oldpath, const char *newpath)
|
| 27 |
+
|
| 28 |
+
enum: _IOFBF
|
| 29 |
+
enum: _IOLBF
|
| 30 |
+
enum: _IONBF
|
| 31 |
+
int setvbuf (FILE *stream, char *buf, int mode, size_t size)
|
| 32 |
+
enum: BUFSIZ
|
| 33 |
+
void setbuf (FILE *stream, char *buf)
|
| 34 |
+
|
| 35 |
+
size_t fread (void *data, size_t size, size_t count, FILE *stream)
|
| 36 |
+
size_t fwrite (const void *data, size_t size, size_t count, FILE *stream)
|
| 37 |
+
int fflush (FILE *stream)
|
| 38 |
+
|
| 39 |
+
enum: EOF
|
| 40 |
+
void clearerr (FILE *stream)
|
| 41 |
+
int feof (FILE *stream)
|
| 42 |
+
int ferror (FILE *stream)
|
| 43 |
+
|
| 44 |
+
enum: SEEK_SET
|
| 45 |
+
enum: SEEK_CUR
|
| 46 |
+
enum: SEEK_END
|
| 47 |
+
int fseek (FILE *stream, long int offset, int whence)
|
| 48 |
+
void rewind (FILE *stream)
|
| 49 |
+
long int ftell (FILE *stream)
|
| 50 |
+
|
| 51 |
+
ctypedef struct fpos_t
|
| 52 |
+
ctypedef const fpos_t const_fpos_t "const fpos_t"
|
| 53 |
+
int fgetpos (FILE *stream, fpos_t *position)
|
| 54 |
+
int fsetpos (FILE *stream, const fpos_t *position)
|
| 55 |
+
|
| 56 |
+
int scanf (const char *template, ...)
|
| 57 |
+
int sscanf (const char *s, const char *template, ...)
|
| 58 |
+
int fscanf (FILE *stream, const char *template, ...)
|
| 59 |
+
|
| 60 |
+
int printf (const char *template, ...)
|
| 61 |
+
int sprintf (char *s, const char *template, ...)
|
| 62 |
+
int snprintf (char *s, size_t size, const char *template, ...)
|
| 63 |
+
int fprintf (FILE *stream, const char *template, ...)
|
| 64 |
+
|
| 65 |
+
void perror (const char *message)
|
| 66 |
+
|
| 67 |
+
char *gets (char *s)
|
| 68 |
+
char *fgets (char *s, int count, FILE *stream)
|
| 69 |
+
int getchar ()
|
| 70 |
+
int fgetc (FILE *stream)
|
| 71 |
+
int getc (FILE *stream)
|
| 72 |
+
int ungetc (int c, FILE *stream)
|
| 73 |
+
|
| 74 |
+
int puts (const char *s)
|
| 75 |
+
int fputs (const char *s, FILE *stream)
|
| 76 |
+
int putchar (int c)
|
| 77 |
+
int fputc (int c, FILE *stream)
|
| 78 |
+
int putc (int c, FILE *stream)
|
| 79 |
+
|
| 80 |
+
size_t getline(char **lineptr, size_t *n, FILE *stream)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/stdlib.pxd
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.20 General utilities <stdlib.h>
|
| 2 |
+
|
| 3 |
+
# deprecated cimports for backwards compatibility:
|
| 4 |
+
from libc.string cimport const_char, const_void
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
cdef extern from "<stdlib.h>" nogil:
|
| 8 |
+
|
| 9 |
+
# 7.20.1 Numeric conversion functions
|
| 10 |
+
int atoi (const char *string)
|
| 11 |
+
long atol (const char *string)
|
| 12 |
+
long long atoll (const char *string)
|
| 13 |
+
double atof (const char *string)
|
| 14 |
+
long strtol (const char *string, char **tailptr, int base)
|
| 15 |
+
unsigned long int strtoul (const char *string, char **tailptr, int base)
|
| 16 |
+
long long int strtoll (const char *string, char **tailptr, int base)
|
| 17 |
+
unsigned long long int strtoull (const char *string, char **tailptr, int base)
|
| 18 |
+
float strtof (const char *string, char **tailptr)
|
| 19 |
+
double strtod (const char *string, char **tailptr)
|
| 20 |
+
long double strtold (const char *string, char **tailptr)
|
| 21 |
+
|
| 22 |
+
# 7.20.2 Pseudo-random sequence generation functions
|
| 23 |
+
enum: RAND_MAX
|
| 24 |
+
int rand ()
|
| 25 |
+
void srand (unsigned int seed)
|
| 26 |
+
|
| 27 |
+
# 7.20.3 Memory management functions
|
| 28 |
+
void *calloc (size_t count, size_t eltsize)
|
| 29 |
+
void free (void *ptr)
|
| 30 |
+
void *malloc (size_t size)
|
| 31 |
+
void *realloc (void *ptr, size_t newsize)
|
| 32 |
+
|
| 33 |
+
# 7.20.4 Communication with the environment
|
| 34 |
+
enum: EXIT_FAILURE
|
| 35 |
+
enum: EXIT_SUCCESS
|
| 36 |
+
void exit (int status)
|
| 37 |
+
void _exit (int status)
|
| 38 |
+
int atexit (void (*function) ())
|
| 39 |
+
void abort ()
|
| 40 |
+
char *getenv (const char *name)
|
| 41 |
+
int system (const char *command)
|
| 42 |
+
|
| 43 |
+
#7.20.5 Searching and sorting utilities
|
| 44 |
+
void *bsearch (const void *key, const void *array,
|
| 45 |
+
size_t count, size_t size,
|
| 46 |
+
int (*compare)(const void *, const void *))
|
| 47 |
+
void qsort (void *array, size_t count, size_t size,
|
| 48 |
+
int (*compare)(const void *, const void *))
|
| 49 |
+
|
| 50 |
+
# 7.20.6 Integer arithmetic functions
|
| 51 |
+
int abs (int number)
|
| 52 |
+
long int labs (long int number)
|
| 53 |
+
long long int llabs (long long int number)
|
| 54 |
+
ctypedef struct div_t:
|
| 55 |
+
int quot
|
| 56 |
+
int rem
|
| 57 |
+
div_t div (int numerator, int denominator)
|
| 58 |
+
ctypedef struct ldiv_t:
|
| 59 |
+
long int quot
|
| 60 |
+
long int rem
|
| 61 |
+
ldiv_t ldiv (long int numerator, long int denominator)
|
| 62 |
+
ctypedef struct lldiv_t:
|
| 63 |
+
long long int quot
|
| 64 |
+
long long int rem
|
| 65 |
+
lldiv_t lldiv (long long int numerator, long long int denominator)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
# 7.20.7 Multibyte/wide character conversion functions
|
| 69 |
+
# XXX TODO
|
| 70 |
+
|
| 71 |
+
# 7.20.8 Multibyte/wide string conversion functions
|
| 72 |
+
# XXX TODO
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/string.pxd
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.21 String handling <string.h>
|
| 2 |
+
|
| 3 |
+
cdef extern from *:
|
| 4 |
+
# deprecated backwards compatibility declarations
|
| 5 |
+
ctypedef const char const_char "const char"
|
| 6 |
+
ctypedef const signed char const_schar "const signed char"
|
| 7 |
+
ctypedef const unsigned char const_uchar "const unsigned char"
|
| 8 |
+
ctypedef const void const_void "const void"
|
| 9 |
+
|
| 10 |
+
cdef extern from "<string.h>" nogil:
|
| 11 |
+
|
| 12 |
+
void *memcpy (void *pto, const void *pfrom, size_t size)
|
| 13 |
+
void *memmove (void *pto, const void *pfrom, size_t size)
|
| 14 |
+
void *memset (void *block, int c, size_t size)
|
| 15 |
+
int memcmp (const void *a1, const void *a2, size_t size)
|
| 16 |
+
void *memchr (const void *block, int c, size_t size)
|
| 17 |
+
|
| 18 |
+
void *memchr (const void *block, int c, size_t size)
|
| 19 |
+
void *memrchr (const void *block, int c, size_t size)
|
| 20 |
+
|
| 21 |
+
size_t strlen (const char *s)
|
| 22 |
+
char *strcpy (char *pto, const char *pfrom)
|
| 23 |
+
char *strncpy (char *pto, const char *pfrom, size_t size)
|
| 24 |
+
char *strdup (const char *s)
|
| 25 |
+
char *strndup (const char *s, size_t size)
|
| 26 |
+
char *strcat (char *pto, const char *pfrom)
|
| 27 |
+
char *strncat (char *pto, const char *pfrom, size_t size)
|
| 28 |
+
|
| 29 |
+
int strcmp (const char *s1, const char *s2)
|
| 30 |
+
int strcasecmp (const char *s1, const char *s2)
|
| 31 |
+
int strncmp (const char *s1, const char *s2, size_t size)
|
| 32 |
+
int strncasecmp (const char *s1, const char *s2, size_t n)
|
| 33 |
+
|
| 34 |
+
int strcoll (const char *s1, const char *s2)
|
| 35 |
+
size_t strxfrm (char *pto, const char *pfrom, size_t size)
|
| 36 |
+
|
| 37 |
+
char *strerror (int errnum)
|
| 38 |
+
|
| 39 |
+
char *strchr (const char *string, int c)
|
| 40 |
+
char *strrchr (const char *string, int c)
|
| 41 |
+
|
| 42 |
+
char *strstr (const char *haystack, const char *needle)
|
| 43 |
+
char *strcasestr (const char *haystack, const char *needle)
|
| 44 |
+
|
| 45 |
+
size_t strcspn (const char *string, const char *stopset)
|
| 46 |
+
size_t strspn (const char *string, const char *set)
|
| 47 |
+
char * strpbrk (const char *string, const char *stopset)
|
| 48 |
+
|
| 49 |
+
char *strtok (char *newstring, const char *delimiters)
|
| 50 |
+
char *strsep (char **string_ptr, const char *delimiter)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/libc/time.pxd
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# https://en.wikipedia.org/wiki/C_date_and_time_functions
|
| 2 |
+
|
| 3 |
+
from libc.stddef cimport wchar_t
|
| 4 |
+
|
| 5 |
+
cdef extern from "<time.h>" nogil:
|
| 6 |
+
ctypedef long clock_t
|
| 7 |
+
ctypedef long time_t
|
| 8 |
+
|
| 9 |
+
enum: CLOCKS_PER_SEC
|
| 10 |
+
clock_t clock() # CPU time
|
| 11 |
+
time_t time(time_t *) # wall clock time since Unix epoch
|
| 12 |
+
|
| 13 |
+
cdef struct tm:
|
| 14 |
+
int tm_sec
|
| 15 |
+
int tm_min
|
| 16 |
+
int tm_hour
|
| 17 |
+
int tm_mday
|
| 18 |
+
int tm_mon
|
| 19 |
+
int tm_year
|
| 20 |
+
int tm_wday
|
| 21 |
+
int tm_yday
|
| 22 |
+
int tm_isdst
|
| 23 |
+
# GNU specific extensions
|
| 24 |
+
#char *tm_zone
|
| 25 |
+
#long tm_gmtoff
|
| 26 |
+
|
| 27 |
+
int daylight # global state
|
| 28 |
+
long timezone
|
| 29 |
+
char *tzname[2]
|
| 30 |
+
void tzset()
|
| 31 |
+
|
| 32 |
+
char *asctime(const tm *)
|
| 33 |
+
char *asctime_r(const tm *, char *)
|
| 34 |
+
char *ctime(const time_t *)
|
| 35 |
+
char *ctime_r(const time_t *, char *)
|
| 36 |
+
double difftime(time_t, time_t)
|
| 37 |
+
tm *getdate(const char *)
|
| 38 |
+
tm *gmtime(const time_t *)
|
| 39 |
+
tm *gmtime_r(const time_t *, tm *)
|
| 40 |
+
tm *localtime(const time_t *)
|
| 41 |
+
tm *localtime_r(const time_t *, tm *)
|
| 42 |
+
time_t mktime(tm *)
|
| 43 |
+
size_t strftime(char *, size_t, const char *, const tm *)
|
| 44 |
+
size_t wcsftime(wchar_t *str, size_t cnt, const wchar_t *fmt, tm *time)
|
| 45 |
+
|
| 46 |
+
# POSIX not stdC
|
| 47 |
+
char *strptime(const char *, const char *, tm *)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/__init__.pxd
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# empty file
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/fcntl.pxd
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/fcntl.h.html
|
| 2 |
+
|
| 3 |
+
from posix.types cimport mode_t, off_t, pid_t
|
| 4 |
+
|
| 5 |
+
cdef extern from "<fcntl.h>" nogil:
|
| 6 |
+
|
| 7 |
+
enum: F_DUPFD
|
| 8 |
+
enum: F_DUPFD_CLOEXEC
|
| 9 |
+
enum: F_GETFD
|
| 10 |
+
enum: F_SETFD
|
| 11 |
+
enum: F_GETFL
|
| 12 |
+
enum: F_SETFL
|
| 13 |
+
enum: F_GETLK
|
| 14 |
+
enum: F_SETLK
|
| 15 |
+
enum: F_SETLKW
|
| 16 |
+
enum: F_GETOWN
|
| 17 |
+
enum: F_SETOWN
|
| 18 |
+
|
| 19 |
+
enum: FD_CLOEXEC
|
| 20 |
+
|
| 21 |
+
enum: F_RDLCK
|
| 22 |
+
enum: F_UNLCK
|
| 23 |
+
enum: F_WRLCK
|
| 24 |
+
|
| 25 |
+
enum: SEEK_SET
|
| 26 |
+
enum: SEEK_CUR
|
| 27 |
+
enum: SEEK_END
|
| 28 |
+
|
| 29 |
+
enum: O_CLOEXEC
|
| 30 |
+
enum: O_CREAT
|
| 31 |
+
enum: O_DIRECT
|
| 32 |
+
enum: O_DIRECTORY
|
| 33 |
+
enum: O_EXCL
|
| 34 |
+
enum: O_NOCTTY
|
| 35 |
+
enum: O_TRUNC
|
| 36 |
+
enum: O_TTY_INIT
|
| 37 |
+
|
| 38 |
+
enum: O_APPEND
|
| 39 |
+
enum: O_DSYNC
|
| 40 |
+
enum: O_NONBLOCK
|
| 41 |
+
enum: O_RSYNC
|
| 42 |
+
enum: O_SYNC
|
| 43 |
+
|
| 44 |
+
enum: O_ACCMODE # O_RDONLY|O_WRONLY|O_RDWR
|
| 45 |
+
|
| 46 |
+
enum: O_EXEC
|
| 47 |
+
enum: O_RDONLY
|
| 48 |
+
enum: O_WRONLY
|
| 49 |
+
enum: O_RDWR
|
| 50 |
+
enum: O_SEARCH
|
| 51 |
+
|
| 52 |
+
enum: AT_FDCWD
|
| 53 |
+
enum: AT_EACCESS
|
| 54 |
+
enum: AT_SYMLINK_NOFOLLOW
|
| 55 |
+
enum: AT_SYMLINK_FOLLOW
|
| 56 |
+
enum: AT_REMOVEDIR
|
| 57 |
+
|
| 58 |
+
enum: S_IFMT
|
| 59 |
+
enum: S_IFBLK
|
| 60 |
+
enum: S_IFCHR
|
| 61 |
+
enum: S_IFIFO
|
| 62 |
+
enum: S_IFREG
|
| 63 |
+
enum: S_IFDIR
|
| 64 |
+
enum: S_IFLNK
|
| 65 |
+
enum: S_IFSOCK
|
| 66 |
+
|
| 67 |
+
enum: POSIX_FADV_DONTNEED
|
| 68 |
+
enum: POSIX_FADV_NOREUSE
|
| 69 |
+
enum: POSIX_FADV_NORMAL
|
| 70 |
+
enum: POSIX_FADV_RANDOM
|
| 71 |
+
enum: POSIX_FADV_SEQUENTIAL
|
| 72 |
+
enum: POSIX_FADV_WILLNEED
|
| 73 |
+
|
| 74 |
+
struct flock:
|
| 75 |
+
short l_type
|
| 76 |
+
short l_whence
|
| 77 |
+
off_t l_start
|
| 78 |
+
off_t l_len
|
| 79 |
+
pid_t l_pid
|
| 80 |
+
|
| 81 |
+
int creat(const char *, mode_t)
|
| 82 |
+
int fcntl(int, int, ...)
|
| 83 |
+
int open(const char *, int, ...)
|
| 84 |
+
int openat(int, const char *, int, ...)
|
| 85 |
+
int posix_fadvise(int, off_t, off_t, int)
|
| 86 |
+
int posix_fallocate(int, off_t, off_t)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/mman.pxd
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_mman.h.html
|
| 2 |
+
# https://man7.org/linux/man-pages/man2/mmap.2.html
|
| 3 |
+
# https://www.freebsd.org/cgi/man.cgi?query=mmap&sektion=2
|
| 4 |
+
|
| 5 |
+
from posix.types cimport off_t, mode_t
|
| 6 |
+
|
| 7 |
+
cdef extern from "<sys/mman.h>" nogil:
|
| 8 |
+
enum: PROT_EXEC # protection bits for mmap/mprotect
|
| 9 |
+
enum: PROT_READ
|
| 10 |
+
enum: PROT_WRITE
|
| 11 |
+
enum: PROT_NONE
|
| 12 |
+
|
| 13 |
+
enum: MAP_PRIVATE # flag bits for mmap
|
| 14 |
+
enum: MAP_SHARED
|
| 15 |
+
enum: MAP_FIXED
|
| 16 |
+
enum: MAP_ANON # These three are not in POSIX, but are
|
| 17 |
+
enum: MAP_ANONYMOUS # fairly common in spelling/semantics
|
| 18 |
+
enum: MAP_STACK
|
| 19 |
+
|
| 20 |
+
enum: MAP_LOCKED # Typically available only on Linux
|
| 21 |
+
enum: MAP_HUGETLB
|
| 22 |
+
enum: MAP_POPULATE
|
| 23 |
+
enum: MAP_NORESERVE
|
| 24 |
+
enum: MAP_GROWSDOWN
|
| 25 |
+
|
| 26 |
+
enum: MAP_NOCORE # Typically available only on BSD
|
| 27 |
+
enum: MAP_NOSYNC
|
| 28 |
+
|
| 29 |
+
void *MAP_FAILED
|
| 30 |
+
|
| 31 |
+
void *mmap(void *addr, size_t Len, int prot, int flags, int fd, off_t off)
|
| 32 |
+
int munmap(void *addr, size_t Len)
|
| 33 |
+
int mprotect(void *addr, size_t Len, int prot)
|
| 34 |
+
|
| 35 |
+
enum: MS_ASYNC
|
| 36 |
+
enum: MS_SYNC
|
| 37 |
+
enum: MS_INVALIDATE
|
| 38 |
+
int msync(void *addr, size_t Len, int flags)
|
| 39 |
+
|
| 40 |
+
enum: POSIX_MADV_NORMAL # POSIX advice flags
|
| 41 |
+
enum: POSIX_MADV_SEQUENTIAL
|
| 42 |
+
enum: POSIX_MADV_RANDOM
|
| 43 |
+
enum: POSIX_MADV_WILLNEED
|
| 44 |
+
enum: POSIX_MADV_DONTNEED
|
| 45 |
+
int posix_madvise(void *addr, size_t Len, int advice)
|
| 46 |
+
|
| 47 |
+
enum: MCL_CURRENT
|
| 48 |
+
enum: MCL_FUTURE
|
| 49 |
+
int mlock(const void *addr, size_t Len)
|
| 50 |
+
int munlock(const void *addr, size_t Len)
|
| 51 |
+
int mlockall(int flags)
|
| 52 |
+
int munlockall()
|
| 53 |
+
# Linux-specific
|
| 54 |
+
enum: MLOCK_ONFAULT
|
| 55 |
+
enum: MCL_ONFAULT
|
| 56 |
+
int mlock2(const void *addr, size_t len, int flags)
|
| 57 |
+
|
| 58 |
+
int shm_open(const char *name, int oflag, mode_t mode)
|
| 59 |
+
int shm_unlink(const char *name)
|
| 60 |
+
|
| 61 |
+
# often available
|
| 62 |
+
enum: MADV_NORMAL # pre-POSIX advice flags; should translate 1-1 to POSIX_*
|
| 63 |
+
enum: MADV_RANDOM # but in practice it is not always the same.
|
| 64 |
+
enum: MADV_SEQUENTIAL
|
| 65 |
+
enum: MADV_WILLNEED
|
| 66 |
+
enum: MADV_DONTNEED
|
| 67 |
+
enum: MADV_REMOVE # other pre-POSIX advice flags; often available
|
| 68 |
+
enum: MADV_DONTFORK
|
| 69 |
+
enum: MADV_DOFORK
|
| 70 |
+
enum: MADV_HWPOISON
|
| 71 |
+
enum: MADV_MERGEABLE,
|
| 72 |
+
enum: MADV_UNMERGEABLE
|
| 73 |
+
enum: MADV_SOFT_OFFLINE
|
| 74 |
+
enum: MADV_HUGEPAGE
|
| 75 |
+
enum: MADV_NOHUGEPAGE
|
| 76 |
+
enum: MADV_DONTDUMP
|
| 77 |
+
enum: MADV_DODUMP
|
| 78 |
+
enum: MADV_FREE
|
| 79 |
+
enum: MADV_WIPEONFORK
|
| 80 |
+
enum: MADV_KEEPONFORK
|
| 81 |
+
int madvise(void *addr, size_t Len, int advice)
|
| 82 |
+
|
| 83 |
+
# sometimes available
|
| 84 |
+
int mincore(void *addr, size_t Len, unsigned char *vec)
|
| 85 |
+
|
| 86 |
+
# These two are Linux specific but sometimes very efficient
|
| 87 |
+
void *mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
|
| 88 |
+
int remap_file_pages(void *addr, size_t Len, int prot,
|
| 89 |
+
size_t pgoff, int flags)
|
| 90 |
+
|
| 91 |
+
# The rare but standardized typed memory option
|
| 92 |
+
enum: POSIX_TYPED_MEM_ALLOCATE
|
| 93 |
+
enum: POSIX_TYPED_MEM_ALLOCATE_CONTIG
|
| 94 |
+
enum: POSIX_TYPED_MEM_MAP_ALLOCATABLE
|
| 95 |
+
int posix_typed_mem_open(const char *name, int oflag, int tflag)
|
| 96 |
+
int posix_mem_offset(const void *addr, size_t Len, off_t *off,
|
| 97 |
+
size_t *contig_len, int *fildes)
|
| 98 |
+
|
| 99 |
+
cdef struct posix_typed_mem_info:
|
| 100 |
+
size_t posix_tmi_length
|
| 101 |
+
int posix_typed_mem_get_info(int fildes, posix_typed_mem_info *info)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/signal.pxd
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 7.14 Signal handling <signal.h>
|
| 2 |
+
|
| 3 |
+
from posix.types cimport pid_t, sigset_t, uid_t
|
| 4 |
+
|
| 5 |
+
cdef extern from "<signal.h>" nogil:
|
| 6 |
+
|
| 7 |
+
cdef union sigval:
|
| 8 |
+
int sival_int
|
| 9 |
+
void *sival_ptr
|
| 10 |
+
|
| 11 |
+
cdef struct sigevent:
|
| 12 |
+
int sigev_notify
|
| 13 |
+
int sigev_signo
|
| 14 |
+
sigval sigev_value
|
| 15 |
+
void sigev_notify_function(sigval)
|
| 16 |
+
|
| 17 |
+
ctypedef struct siginfo_t:
|
| 18 |
+
int si_signo
|
| 19 |
+
int si_code
|
| 20 |
+
int si_errno
|
| 21 |
+
pid_t si_pid
|
| 22 |
+
uid_t si_uid
|
| 23 |
+
void *si_addr
|
| 24 |
+
int si_status
|
| 25 |
+
long si_band
|
| 26 |
+
sigval si_value
|
| 27 |
+
|
| 28 |
+
cdef struct sigaction_t "sigaction":
|
| 29 |
+
void sa_handler(int)
|
| 30 |
+
void sa_sigaction(int, siginfo_t *, void *)
|
| 31 |
+
sigset_t sa_mask
|
| 32 |
+
int sa_flags
|
| 33 |
+
|
| 34 |
+
ctypedef struct stack_t:
|
| 35 |
+
void *ss_sp
|
| 36 |
+
int ss_flags
|
| 37 |
+
size_t ss_size
|
| 38 |
+
|
| 39 |
+
enum: SA_NOCLDSTOP
|
| 40 |
+
enum: SIG_BLOCK
|
| 41 |
+
enum: SIG_UNBLOCK
|
| 42 |
+
enum: SIG_SETMASK
|
| 43 |
+
enum: SA_ONSTACK
|
| 44 |
+
enum: SA_RESETHAND
|
| 45 |
+
enum: SA_RESTART
|
| 46 |
+
enum: SA_SIGINFO
|
| 47 |
+
enum: SA_NOCLDWAIT
|
| 48 |
+
enum: SA_NODEFER
|
| 49 |
+
enum: SS_ONSTACK
|
| 50 |
+
enum: SS_DISABLE
|
| 51 |
+
enum: MINSIGSTKSZ
|
| 52 |
+
enum: SIGSTKSZ
|
| 53 |
+
|
| 54 |
+
enum: SIGEV_NONE
|
| 55 |
+
enum: SIGEV_SIGNAL
|
| 56 |
+
enum: SIGEV_THREAD
|
| 57 |
+
enum: SIGEV_THREAD_ID
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
int kill (pid_t, int)
|
| 61 |
+
int killpg (pid_t, int)
|
| 62 |
+
int sigaction (int, const sigaction_t *, sigaction_t *)
|
| 63 |
+
int sigpending (sigset_t *)
|
| 64 |
+
int sigprocmask (int, const sigset_t *, sigset_t *)
|
| 65 |
+
int sigsuspend (const sigset_t *)
|
| 66 |
+
|
| 67 |
+
int sigaddset (sigset_t *, int)
|
| 68 |
+
int sigdelset (sigset_t *, int)
|
| 69 |
+
int sigemptyset (sigset_t *)
|
| 70 |
+
int sigfillset (sigset_t *)
|
| 71 |
+
int sigismember (const sigset_t *, int)
|
| 72 |
+
|
| 73 |
+
int sigaltstack(const stack_t *, stack_t *)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/stdio.pxd
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# POSIX additions to <stdio.h>.
|
| 2 |
+
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdio.h.html
|
| 3 |
+
|
| 4 |
+
from libc.stdio cimport FILE
|
| 5 |
+
from libc.stddef cimport wchar_t
|
| 6 |
+
from posix.types cimport off_t
|
| 7 |
+
|
| 8 |
+
cdef extern from "<stdio.h>" nogil:
|
| 9 |
+
# File descriptors
|
| 10 |
+
FILE *fdopen(int, const char *)
|
| 11 |
+
int fileno(FILE *)
|
| 12 |
+
|
| 13 |
+
# Pipes
|
| 14 |
+
FILE *popen(const char *, const char *)
|
| 15 |
+
int pclose(FILE *)
|
| 16 |
+
|
| 17 |
+
# Memory streams (POSIX.2008)
|
| 18 |
+
FILE *fmemopen(void *, size_t, const char *)
|
| 19 |
+
FILE *open_memstream(char **, size_t *)
|
| 20 |
+
FILE *open_wmemstream(wchar_t **, size_t *)
|
| 21 |
+
|
| 22 |
+
# Seek and tell with off_t
|
| 23 |
+
int fseeko(FILE *, off_t, int)
|
| 24 |
+
off_t ftello(FILE *)
|
| 25 |
+
|
| 26 |
+
# Locking (for multithreading)
|
| 27 |
+
void flockfile(FILE *)
|
| 28 |
+
int ftrylockfile(FILE *)
|
| 29 |
+
void funlockfile(FILE *)
|
| 30 |
+
int getc_unlocked(FILE *)
|
| 31 |
+
int getchar_unlocked()
|
| 32 |
+
int putc_unlocked(int, FILE *)
|
| 33 |
+
int putchar_unlocked(int)
|
| 34 |
+
|
| 35 |
+
# Reading lines and records (POSIX.2008)
|
| 36 |
+
ssize_t getline(char **, size_t *, FILE *)
|
| 37 |
+
ssize_t getdelim(char **, size_t *, int, FILE *)
|
tuning-competition-baseline/.venv/lib/python3.11/site-packages/Cython/Includes/posix/stdlib.pxd
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# POSIX additions to <stdlib.h>
|
| 2 |
+
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html
|
| 3 |
+
|
| 4 |
+
cdef extern from "<stdlib.h>" nogil:
|
| 5 |
+
void _Exit(int)
|
| 6 |
+
double drand48()
|
| 7 |
+
double erand48(unsigned short *)
|
| 8 |
+
int getsubopt(char **, char *const *, char **)
|
| 9 |
+
void lcong48(unsigned short *)
|
| 10 |
+
long lrand()
|
| 11 |
+
char *mkdtemp(char *)
|
| 12 |
+
int mkstemp(char *)
|
| 13 |
+
long mrand()
|
| 14 |
+
long nrand48(unsigned short *)
|
| 15 |
+
int posix_memalign(void **, size_t, size_t)
|
| 16 |
+
int posix_openpt(int)
|
| 17 |
+
char *ptsname(int)
|
| 18 |
+
int putenv(char *)
|
| 19 |
+
int rand_r(unsigned *)
|
| 20 |
+
long random()
|
| 21 |
+
char *realpath(const char *, char *)
|
| 22 |
+
unsigned short *seed48(unsigned short *)
|
| 23 |
+
int setenv(const char *, const char *, int)
|
| 24 |
+
void setkey(const char *)
|
| 25 |
+
char *setstate(char *)
|
| 26 |
+
void srand48(long)
|
| 27 |
+
void srandom(unsigned)
|
| 28 |
+
int unlockpt(int)
|
| 29 |
+
int unsetenv(const char *)
|