From 248a034dc93d6ce4d983af6ce83c0b8b112e4f5c Mon Sep 17 00:00:00 2001 From: Jason Saporta Date: Fri, 17 May 2019 17:19:35 -0700 Subject: [PATCH 001/441] Issue 29847 fix with tests. --- Lib/pathlib.py | 10 ++++++++++ Lib/test/test_pathlib.py | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index b5bab1fe8f5acb..2d61bd733a25b3 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1512,6 +1512,11 @@ class PosixPath(Path, PurePosixPath): """ __slots__ = () + def __new__(cls, *args, **kwargs): + if kwargs: + raise TypeError("keyword arguments provided but ignored") + return super().__new__(cls, *args, **kwargs) + class WindowsPath(Path, PureWindowsPath): """Path subclass for Windows systems. @@ -1519,6 +1524,11 @@ class WindowsPath(Path, PureWindowsPath): """ __slots__ = () + def __new__(cls, *args, **kwargs): + if kwargs: + raise TypeError("keyword arguments provided but ignored") + return super().__new__(cls, *args, **kwargs) + def owner(self): raise NotImplementedError("Path.owner() is unsupported on this system") diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index caad1c23876abd..262d0828ed6f8b 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2254,6 +2254,10 @@ def test_handling_bad_descriptor(self): self.fail("Bad file descriptor not handled.") raise + def test_kwargs(self): + with self.assertRaises(TypeError): + self.cls(".", test_kwarg="test") + @only_nt class WindowsPathTest(_BasePathTest, unittest.TestCase): @@ -2324,6 +2328,9 @@ def check(): env['USERPROFILE'] = 'C:\\Users\\alice' check() + def test_kwargs(self): + with self.assertRaises(TypeError): + self.cls(".", test_kwarg="test") if __name__ == "__main__": unittest.main() From bab0db6076900cd828588be8595b3cdfade7e7e9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 18 May 2019 03:21:27 +0200 Subject: [PATCH 002/441] bpo-36763: Use _PyCoreConfig_InitPythonConfig() (GH-13398) _PyPreConfig_InitPythonConfig() and _PyCoreConfig_InitPythonConfig() no longer inherit their values from global configuration variables. Changes: * _PyPreCmdline_Read() now ignores -X dev and PYTHONDEVMODE if dev_mode is already set. * Inline _PyPreConfig_INIT macro into _PyPreConfig_Init() function. * Inline _PyCoreConfig_INIT macro into _PyCoreConfig_Init() function. * Replace _PyCoreConfig_Init() with _PyCoreConfig_InitPythonConfig() in most tests of _testembed.c. * Replace _PyCoreConfig_Init() with _PyCoreConfig_InitIsolatedConfig() in _freeze_importlib.c. * Move some initialization functions from the internal to the private API. --- Include/cpython/coreconfig.h | 77 ++++--------------- Include/internal/pycore_coreconfig.h | 20 +---- Lib/test/test_embed.py | 105 +++++++++++++++---------- Programs/_freeze_importlib.c | 6 +- Programs/_testembed.c | 111 +++++++++++++++++++-------- Python/coreconfig.c | 77 ++++++++++++++----- Python/frozenmain.c | 2 +- Python/preconfig.c | 23 ++++-- 8 files changed, 240 insertions(+), 181 deletions(-) diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index f05eddad912ffe..ca71c15b67d6f9 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -115,27 +115,8 @@ typedef struct { PyMemAllocatorName allocator; } _PyPreConfig; -#ifdef MS_WINDOWS -# define _PyPreConfig_WINDOWS_INIT \ - .legacy_windows_fs_encoding = -1, -#else -# define _PyPreConfig_WINDOWS_INIT -#endif - -#define _PyPreConfig_INIT \ - (_PyPreConfig){ \ - _PyPreConfig_WINDOWS_INIT \ - ._config_version = _Py_CONFIG_VERSION, \ - .isolated = -1, \ - .use_environment = -1, \ - .configure_locale = 1, \ - .utf8_mode = -2, \ - .dev_mode = -1, \ - .allocator = PYMEM_ALLOCATOR_NOT_SET} - -PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config); PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config); -PyAPI_FUNC(void) _PyPreConfig_InitIsolateConfig(_PyPreConfig *config); +PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config); /* --- _PyCoreConfig ---------------------------------------------- */ @@ -419,47 +400,23 @@ typedef struct { } _PyCoreConfig; -#ifdef MS_WINDOWS -# define _PyCoreConfig_WINDOWS_INIT \ - .legacy_windows_stdio = -1, -#else -# define _PyCoreConfig_WINDOWS_INIT -#endif - -#define _PyCoreConfig_INIT \ - (_PyCoreConfig){ \ - _PyCoreConfig_WINDOWS_INIT \ - ._config_version = _Py_CONFIG_VERSION, \ - .isolated = -1, \ - .use_environment = -1, \ - .dev_mode = -1, \ - .install_signal_handlers = 1, \ - .use_hash_seed = -1, \ - .faulthandler = -1, \ - .tracemalloc = -1, \ - .use_module_search_paths = 0, \ - .parse_argv = 0, \ - .site_import = -1, \ - .bytes_warning = -1, \ - .inspect = -1, \ - .interactive = -1, \ - .optimization_level = -1, \ - .parser_debug= -1, \ - .write_bytecode = -1, \ - .verbose = -1, \ - .quiet = -1, \ - .user_site_directory = -1, \ - .configure_c_stdio = 0, \ - .buffered_stdio = -1, \ - ._install_importlib = 1, \ - .check_hash_pycs_mode = NULL, \ - .pathconfig_warnings = -1, \ - ._init_main = 1} -/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */ - -PyAPI_FUNC(void) _PyCoreConfig_Init(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolateConfig(_PyCoreConfig *config); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config); +PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString( + wchar_t **config_str, + const wchar_t *str); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_DecodeLocale( + wchar_t **config_str, + const char *str); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetArgv( + _PyCoreConfig *config, + Py_ssize_t argc, + char **argv); +PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, + Py_ssize_t argc, + wchar_t **argv); #ifdef __cplusplus } diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index ea4418f5061ce2..edde7b1d8d8817 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -121,8 +121,6 @@ PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline, /* --- _PyPreConfig ----------------------------------------------- */ PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config); -PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config); -PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config); PyAPI_FUNC(void) _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2); PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config); @@ -135,34 +133,18 @@ PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(const _PyPreConfig *config); /* --- _PyCoreConfig ---------------------------------------------- */ -PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config); +PyAPI_FUNC(void) _PyCoreConfig_Init(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy( _PyCoreConfig *config, const _PyCoreConfig *config2); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString( - wchar_t **config_str, - const wchar_t *str); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_DecodeLocale( - wchar_t **config_str, - const char *str); PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig( const _PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime); PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPyArgv( _PyCoreConfig *config, const _PyArgv *args); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetArgv( - _PyCoreConfig *config, - Py_ssize_t argc, - char **argv); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, - Py_ssize_t argc, - wchar_t **argv); /* --- Function used for testing ---------------------------------- */ diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index c389df85fb6c09..6b77a2d1fd8dd9 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -285,6 +285,16 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'coerce_c_locale_warn': 0, 'utf8_mode': 0, } + ISOLATED_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG, + configure_locale=0, + isolated=1, + use_environment=0, + utf8_mode=0, + dev_mode=0, + ) + if MS_WINDOWS: + ISOLATED_PRE_CONFIG['legacy_windows_fs_encoding'] = 0 + COPY_PRE_CONFIG = [ 'dev_mode', 'isolated', @@ -363,6 +373,24 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'legacy_windows_stdio': 0, }) + PYTHON_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG, + configure_c_stdio=1, + parse_argv=1, + ) + ISOLATED_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG, + isolated=1, + use_environment=0, + user_site_directory=0, + dev_mode=0, + install_signal_handlers=0, + use_hash_seed=0, + faulthandler=0, + tracemalloc=0, + pathconfig_warnings=0, + ) + if MS_WINDOWS: + ISOLATED_CORE_CONFIG['legacy_windows_stdio'] = 0 + # global config DEFAULT_GLOBAL_CONFIG = { 'Py_HasFileSystemDefaultEncoding': 0, @@ -410,8 +438,15 @@ def main_xoptions(self, xoptions_list): xoptions[opt] = True return xoptions - def get_expected_config(self, expected_preconfig, expected, env, add_path=None): - expected = dict(self.DEFAULT_CORE_CONFIG, **expected) + def get_expected_config(self, expected_preconfig, expected, env, api, + add_path=None): + if api == "python": + default_config = self.PYTHON_CORE_CONFIG + elif api == "isolated": + default_config = self.ISOLATED_CORE_CONFIG + else: + default_config = self.DEFAULT_CORE_CONFIG + expected = dict(default_config, **expected) code = textwrap.dedent(''' import json @@ -521,8 +556,8 @@ def check_global_config(self, config): self.assertEqual(config['global_config'], expected) - def check_config(self, testname, expected_config, expected_preconfig, - add_path=None, stderr=None): + def check_config(self, testname, expected_config=None, expected_preconfig=None, + add_path=None, stderr=None, api="default"): env = dict(os.environ) # Remove PYTHON* environment variables to get deterministic environment for key in list(env): @@ -533,8 +568,18 @@ def check_config(self, testname, expected_config, expected_preconfig, env['PYTHONCOERCECLOCALE'] = '0' env['PYTHONUTF8'] = '0' - expected_preconfig = dict(self.DEFAULT_PRE_CONFIG, **expected_preconfig) - expected_config = self.get_expected_config(expected_preconfig, expected_config, env, add_path) + if api == "isolated": + default_preconfig = self.ISOLATED_PRE_CONFIG + else: + default_preconfig = self.DEFAULT_PRE_CONFIG + if expected_preconfig is None: + expected_preconfig = {} + expected_preconfig = dict(default_preconfig, **expected_preconfig) + if expected_config is None: + expected_config = {} + expected_config = self.get_expected_config(expected_preconfig, + expected_config, env, + api, add_path) for key in self.COPY_PRE_CONFIG: if key not in expected_preconfig: expected_preconfig[key] = expected_config[key] @@ -677,76 +722,56 @@ def test_init_dev_mode(self): 'dev_mode': 1, 'warnoptions': ['default'], } - self.check_config("init_dev_mode", config, preconfig) + self.check_config("init_dev_mode", config, preconfig, api="python") def test_init_isolated_flag(self): - preconfig = {} config = { 'isolated': 1, 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("init_isolated_flag", config, preconfig) + self.check_config("init_isolated_flag", config, api="python") def test_preinit_isolated1(self): # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set - preconfig = {} config = { 'isolated': 1, 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated1", config, preconfig) + self.check_config("preinit_isolated1", config) def test_preinit_isolated2(self): # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 - preconfig = {} config = { 'isolated': 1, 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated2", config, preconfig) + self.check_config("preinit_isolated2", config) def test_init_isolated_config(self): - preconfig = { - 'configure_locale': 0, - } - config = { - 'isolated': 1, - 'use_environment': 0, - 'user_site_directory': 0, - 'install_signal_handlers': 0, - 'pathconfig_warnings': 0, - } - self.check_config("init_isolated_config", config, preconfig) + self.check_config("init_isolated_config", api="isolated") def test_init_python_config(self): - preconfig = {} - config = { - 'configure_c_stdio': 1, - 'parse_argv': 1, - } - self.check_config("init_python_config", config, preconfig) + self.check_config("init_python_config", api="python") def test_init_dont_configure_locale(self): # _PyPreConfig.configure_locale=0 preconfig = { 'configure_locale': 0, } - self.check_config("init_dont_configure_locale", {}, preconfig) + self.check_config("init_dont_configure_locale", {}, preconfig, api="python") def test_init_read_set(self): - preconfig = {} core_config = { 'program_name': './init_read_set', 'executable': 'my_executable', } - self.check_config("init_read_set", core_config, preconfig, + self.check_config("init_read_set", core_config, api="python", add_path="init_read_set_path") def test_init_run_main(self): - preconfig = {} code = ('import _testinternalcapi, json; ' 'print(json.dumps(_testinternalcapi.get_configs()))') core_config = { @@ -755,10 +780,9 @@ def test_init_run_main(self): 'run_command': code + '\n', 'parse_argv': 1, } - self.check_config("init_run_main", core_config, preconfig) + self.check_config("init_run_main", core_config, api="python") def test_init_main(self): - preconfig = {} code = ('import _testinternalcapi, json; ' 'print(json.dumps(_testinternalcapi.get_configs()))') core_config = { @@ -768,25 +792,26 @@ def test_init_main(self): 'parse_argv': 1, '_init_main': 0, } - self.check_config("init_main", core_config, preconfig, + self.check_config("init_main", core_config, api="python", stderr="Run Python code before _Py_InitializeMain") def test_init_parse_argv(self): core_config = { + 'parse_argv': 1, 'argv': ['-c', 'arg1', '-v', 'arg3'], 'program_name': './argv0', - 'parse_argv': 1, 'run_command': 'pass\n', 'use_environment': 0, } - self.check_config("init_parse_argv", core_config, {}) + self.check_config("init_parse_argv", core_config, api="python") def test_init_dont_parse_argv(self): core_config = { + 'parse_argv': 0, 'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], 'program_name': './argv0', } - self.check_config("init_dont_parse_argv", core_config, {}) + self.check_config("init_dont_parse_argv", core_config, api="python") if __name__ == "__main__": diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c index d89d66abee7364..1a719e2f96735e 100644 --- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -77,14 +77,12 @@ main(int argc, char *argv[]) text[text_size] = '\0'; _PyCoreConfig config; - _PyCoreConfig_Init(&config); - config.use_environment = 0; - config.user_site_directory = 0; + _PyCoreConfig_InitIsolatedConfig(&config); + config.site_import = 0; config.program_name = L"./_freeze_importlib"; /* Don't install importlib, since it could execute outdated bytecode. */ config._install_importlib = 0; - config.pathconfig_warnings = 0; config._init_main = 0; _PyInitError err = _Py_InitializeFromConfig(&config); diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 2352179cc6fc2a..f1bb731dcba2b7 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -5,6 +5,7 @@ #include #include "pycore_coreconfig.h" /* FIXME: PEP 587 makes these functions public */ +#include #include "pythread.h" #include #include @@ -404,7 +405,7 @@ static int test_init_from_config(void) config.use_hash_seed = 1; config.hash_seed = 123; - /* dev_mode=1 is tested in init_dev_mode() */ + /* dev_mode=1 is tested in test_init_dev_mode() */ putenv("PYTHONFAULTHANDLER="); config.faulthandler = 1; @@ -521,12 +522,12 @@ static int test_init_from_config(void) } -static int test_init_parse_argv(int parse_argv) +static int check_init_parse_argv(int parse_argv) { _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); static wchar_t* argv[] = { L"./argv0", @@ -552,15 +553,15 @@ static int test_init_parse_argv(int parse_argv) } -static int init_parse_argv(void) +static int test_init_parse_argv(void) { - return test_init_parse_argv(1); + return check_init_parse_argv(1); } -static int init_dont_parse_argv(void) +static int test_init_dont_parse_argv(void) { - return test_init_parse_argv(0); + return check_init_parse_argv(0); } @@ -603,7 +604,7 @@ static int test_init_env(void) } -static void test_init_env_dev_mode_putenvs(void) +static void set_all_env_vars(void) { test_init_env_putenvs(); putenv("PYTHONMALLOC="); @@ -616,7 +617,7 @@ static int test_init_env_dev_mode(void) { /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; - test_init_env_dev_mode_putenvs(); + set_all_env_vars(); _testembed_Py_Initialize(); dump_config(); Py_Finalize(); @@ -628,7 +629,7 @@ static int test_init_env_dev_mode_alloc(void) { /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; - test_init_env_dev_mode_putenvs(); + set_all_env_vars(); putenv("PYTHONMALLOC=malloc"); _testembed_Py_Initialize(); dump_config(); @@ -637,13 +638,13 @@ static int test_init_env_dev_mode_alloc(void) } -static int init_isolated_flag(void) +static int test_init_isolated_flag(void) { _PyInitError err; /* Test _PyCoreConfig.isolated=1 */ _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); Py_IsolatedFlag = 0; config.isolated = 1; @@ -651,7 +652,7 @@ static int init_isolated_flag(void) /* Use path starting with "./" avoids a search along the PATH */ config.program_name = L"./_testembed"; - test_init_env_dev_mode_putenvs(); + set_all_env_vars(); err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); @@ -680,7 +681,7 @@ static int test_preinit_isolated1(void) _PyCoreConfig_Init(&config); config.program_name = L"./_testembed"; - test_init_env_dev_mode_putenvs(); + set_all_env_vars(); err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); @@ -715,7 +716,7 @@ static int test_preinit_isolated2(void) /* Use path starting with "./" avoids a search along the PATH */ config.program_name = L"./_testembed"; - test_init_env_dev_mode_putenvs(); + set_all_env_vars(); err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); @@ -726,10 +727,38 @@ static int test_preinit_isolated2(void) } -static int init_isolated_config(void) +static void set_all_global_config_variables(void) +{ + Py_IsolatedFlag = 0; + Py_IgnoreEnvironmentFlag = 0; + Py_BytesWarningFlag = 2; + Py_InspectFlag = 1; + Py_InteractiveFlag = 1; + Py_OptimizeFlag = 1; + Py_DebugFlag = 1; + Py_VerboseFlag = 1; + Py_QuietFlag = 1; + Py_FrozenFlag = 0; + Py_UnbufferedStdioFlag = 1; + Py_NoSiteFlag = 1; + Py_DontWriteBytecodeFlag = 1; + Py_NoUserSiteDirectory = 1; +#ifdef MS_WINDOWS + Py_LegacyWindowsStdioFlag = 1; +#endif +} + + +static int test_init_isolated_config(void) { _PyInitError err; + /* environment variables must be ignored */ + set_all_env_vars(); + + /* global configuration variables must be ignored */ + set_all_global_config_variables(); + _PyPreConfig preconfig; _PyPreConfig_InitIsolatedConfig(&preconfig); @@ -759,10 +788,23 @@ static int init_isolated_config(void) } -static int init_python_config(void) +static int test_init_python_config(void) { _PyInitError err; + /* global configuration variables must be ignored */ + set_all_global_config_variables(); + Py_IsolatedFlag = 1; + Py_IgnoreEnvironmentFlag = 1; + Py_FrozenFlag = 1; + Py_UnbufferedStdioFlag = 1; + Py_NoSiteFlag = 1; + Py_DontWriteBytecodeFlag = 1; + Py_NoUserSiteDirectory = 1; +#ifdef MS_WINDOWS + Py_LegacyWindowsStdioFlag = 1; +#endif + _PyPreConfig preconfig; _PyPreConfig_InitPythonConfig(&preconfig); @@ -788,11 +830,12 @@ static int init_python_config(void) } -static int init_dont_configure_locale(void) +static int test_init_dont_configure_locale(void) { _PyInitError err; - _PyPreConfig preconfig = _PyPreConfig_INIT; + _PyPreConfig preconfig; + _PyPreConfig_InitPythonConfig(&preconfig); preconfig.configure_locale = 0; preconfig.coerce_c_locale = 1; preconfig.coerce_c_locale_warn = 1; @@ -802,7 +845,8 @@ static int init_dont_configure_locale(void) _Py_ExitInitError(err); } - _PyCoreConfig config = _PyCoreConfig_INIT; + _PyCoreConfig config; + _PyCoreConfig_InitPythonConfig(&config); config.program_name = L"./_testembed"; err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { @@ -815,10 +859,10 @@ static int init_dont_configure_locale(void) } -static int init_dev_mode(void) +static int test_init_dev_mode(void) { _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); putenv("PYTHONFAULTHANDLER="); putenv("PYTHONMALLOC="); config.dev_mode = 1; @@ -837,7 +881,7 @@ static int test_init_read_set(void) { _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); err = _PyCoreConfig_DecodeLocale(&config.program_name, "./init_read_set"); if (_PyInitError_Failed(err)) { @@ -894,7 +938,7 @@ static void configure_init_main(_PyCoreConfig *config) static int test_init_run_main(void) { _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); configure_init_main(&config); _PyInitError err = _Py_InitializeFromConfig(&config); @@ -909,7 +953,7 @@ static int test_init_run_main(void) static int test_init_main(void) { _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); configure_init_main(&config); config._init_main = 0; @@ -939,7 +983,7 @@ static int test_init_main(void) static int test_run_main(void) { _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); wchar_t *argv[] = {L"python3", L"-c", (L"import sys; " @@ -947,7 +991,6 @@ static int test_run_main(void) L"arg2"}; config.argv.length = Py_ARRAY_LENGTH(argv); config.argv.items = argv; - config.parse_argv = 1; config.program_name = L"./python3"; _PyInitError err = _Py_InitializeFromConfig(&config); @@ -988,16 +1031,16 @@ static struct TestCase TestCases[] = { { "init_default_config", test_init_default_config }, { "init_global_config", test_init_global_config }, { "init_from_config", test_init_from_config }, - { "init_parse_argv", init_parse_argv }, - { "init_dont_parse_argv", init_dont_parse_argv }, + { "init_parse_argv", test_init_parse_argv }, + { "init_dont_parse_argv", test_init_dont_parse_argv }, { "init_env", test_init_env }, { "init_env_dev_mode", test_init_env_dev_mode }, { "init_env_dev_mode_alloc", test_init_env_dev_mode_alloc }, - { "init_dont_configure_locale", init_dont_configure_locale }, - { "init_dev_mode", init_dev_mode }, - { "init_isolated_flag", init_isolated_flag }, - { "init_isolated_config", init_isolated_config }, - { "init_python_config", init_python_config }, + { "init_dont_configure_locale", test_init_dont_configure_locale }, + { "init_dev_mode", test_init_dev_mode }, + { "init_isolated_flag", test_init_isolated_flag }, + { "init_isolated_config", test_init_isolated_config }, + { "init_python_config", test_init_python_config }, { "preinit_isolated1", test_preinit_isolated1 }, { "preinit_isolated2", test_preinit_isolated2 }, { "init_read_set", test_init_read_set }, diff --git a/Python/coreconfig.c b/Python/coreconfig.c index fd457262a82431..3678d124067169 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -551,14 +551,69 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) void _PyCoreConfig_Init(_PyCoreConfig *config) { - *config = _PyCoreConfig_INIT; + memset(config, 0, sizeof(*config)); + + config->_config_version = _Py_CONFIG_VERSION; + config->isolated = -1; + config->use_environment = -1; + config->dev_mode = -1; + config->install_signal_handlers = 1; + config->use_hash_seed = -1; + config->faulthandler = -1; + config->tracemalloc = -1; + config->use_module_search_paths = 0; + config->parse_argv = 0; + config->site_import = -1; + config->bytes_warning = -1; + config->inspect = -1; + config->interactive = -1; + config->optimization_level = -1; + config->parser_debug= -1; + config->write_bytecode = -1; + config->verbose = -1; + config->quiet = -1; + config->user_site_directory = -1; + config->configure_c_stdio = 0; + config->buffered_stdio = -1; + config->_install_importlib = 1; + config->check_hash_pycs_mode = NULL; + config->pathconfig_warnings = -1; + config->_init_main = 1; +#ifdef MS_WINDOWS + config->legacy_windows_stdio = -1; +#endif +} + + +static void +_PyCoreConfig_InitDefaults(_PyCoreConfig *config) +{ + _PyCoreConfig_Init(config); + + config->isolated = 0; + config->use_environment = 1; + config->site_import = 1; + config->bytes_warning = 0; + config->inspect = 0; + config->interactive = 0; + config->optimization_level = 0; + config->parser_debug= 0; + config->write_bytecode = 1; + config->verbose = 0; + config->quiet = 0; + config->user_site_directory = 1; + config->buffered_stdio = 1; + config->pathconfig_warnings = 1; +#ifdef MS_WINDOWS + config->legacy_windows_stdio = 0; +#endif } _PyInitError _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config) { - _PyCoreConfig_Init(config); + _PyCoreConfig_InitDefaults(config); config->configure_c_stdio = 1; config->parse_argv = 1; @@ -570,30 +625,16 @@ _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config) _PyInitError _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config) { - _PyCoreConfig_Init(config); + _PyCoreConfig_InitDefaults(config); - /* set to 1 */ config->isolated = 1; - config->site_import = 1; - config->write_bytecode = 1; - config->buffered_stdio = 1; - - /* set to 0 */ config->use_environment = 0; + config->user_site_directory = 0; config->dev_mode = 0; config->install_signal_handlers = 0; config->use_hash_seed = 0; config->faulthandler = 0; config->tracemalloc = 0; - config->bytes_warning = 0; - config->inspect = 0; - config->interactive = 0; - config->optimization_level = 0; - config->parser_debug = 0; - config->verbose = 0; - config->quiet = 0; - config->user_site_directory = 0; - config->configure_c_stdio = 0; config->pathconfig_warnings = 0; #ifdef MS_WINDOWS config->legacy_windows_stdio = 0; diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 7b232bb8023fef..a51fb5800127d8 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -40,7 +40,7 @@ Py_FrozenMain(int argc, char **argv) } _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitPythonConfig(&config); config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') diff --git a/Python/preconfig.c b/Python/preconfig.c index b7bcfeb9b2f65c..0f4bd8ece534c0 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -241,8 +241,9 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, } /* dev_mode */ - if ((cmdline && _Py_get_xoption(&cmdline->xoptions, L"dev")) - || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE")) + if ((cmdline->dev_mode < 0) + && (_Py_get_xoption(&cmdline->xoptions, L"dev") + || _Py_GetEnv(cmdline->use_environment, "PYTHONDEVMODE"))) { cmdline->dev_mode = 1; } @@ -260,10 +261,22 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, /* --- _PyPreConfig ----------------------------------------------- */ + void _PyPreConfig_Init(_PyPreConfig *config) { - *config = _PyPreConfig_INIT; + memset(config, 0, sizeof(*config)); + + config->_config_version = _Py_CONFIG_VERSION; + config->isolated = -1; + config->use_environment = -1; + config->configure_locale = 1; + config->utf8_mode = -2; + config->dev_mode = -1; + config->allocator = PYMEM_ALLOCATOR_NOT_SET; +#ifdef MS_WINDOWS + config->legacy_windows_fs_encoding = -1; +#endif } @@ -289,11 +302,11 @@ _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config) config->configure_locale = 0; config->isolated = 1; config->use_environment = 0; + config->utf8_mode = 0; + config->dev_mode = 0; #ifdef MS_WINDOWS config->legacy_windows_fs_encoding = 0; #endif - config->utf8_mode = 0; - config->dev_mode = 0; } From 410759fba80aded5247b693c60745aa16906f3bb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 18 May 2019 04:17:01 +0200 Subject: [PATCH 003/441] bpo-36763: Remove _PyCoreConfig.dll_path (GH-13402) --- Include/cpython/coreconfig.h | 3 --- Include/internal/pycore_pathconfig.h | 4 ++++ Lib/test/test_embed.py | 3 --- PC/getpathp.c | 18 ++++++++---------- Python/coreconfig.c | 12 ------------ Python/pathconfig.c | 16 +++------------- 6 files changed, 15 insertions(+), 41 deletions(-) diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index ca71c15b67d6f9..a71f16171b7334 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -353,9 +353,6 @@ typedef struct { wchar_t *base_prefix; /* sys.base_prefix */ wchar_t *exec_prefix; /* sys.exec_prefix */ wchar_t *base_exec_prefix; /* sys.base_exec_prefix */ -#ifdef MS_WINDOWS - wchar_t *dll_path; /* Windows DLL path */ -#endif /* --- Parameter only used by Py_Main() ---------- */ diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index 9eb8e88df76736..bee391187cc97d 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.h @@ -53,6 +53,10 @@ PyAPI_FUNC(int) _Py_FindEnvConfigValue( wchar_t *value, size_t value_size); +#ifdef MS_WINDOWS +extern wchar_t* _Py_GetDLLPath(void); +#endif + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 6b77a2d1fd8dd9..5a5419dcfcf57e 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -369,7 +369,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'legacy_windows_fs_encoding': 0, }) DEFAULT_CORE_CONFIG.update({ - 'dll_path': GET_DEFAULT_CONFIG, 'legacy_windows_stdio': 0, }) @@ -466,8 +465,6 @@ def get_expected_config(self, expected_preconfig, expected, env, api, 'filesystem_errors': sys.getfilesystemencodeerrors(), 'module_search_paths': core_config['module_search_paths'], } - if sys.platform == 'win32': - data['dll_path'] = core_config['dll_path'] data = json.dumps(data) data = data.encode('utf-8') diff --git a/PC/getpathp.c b/PC/getpathp.c index 64aa1e0d141f05..62c42ecefe9e18 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -508,8 +508,8 @@ getpythonregpath(HKEY keyBase, int skipcore) #endif /* Py_ENABLE_SHARED */ -static _PyInitError -get_dll_path(PyCalculatePath *calculate, _PyPathConfig *config) +wchar_t* +_Py_GetDLLPath(void) { wchar_t dll_path[MAXPATHLEN+1]; memset(dll_path, 0, sizeof(dll_path)); @@ -525,11 +525,7 @@ get_dll_path(PyCalculatePath *calculate, _PyPathConfig *config) dll_path[0] = 0; #endif - config->dll_path = _PyMem_RawWcsdup(dll_path); - if (config->dll_path == NULL) { - return _Py_INIT_NO_MEMORY(); - } - return _Py_INIT_OK(); + return _PyMem_RawWcsdup(dll_path); } @@ -956,9 +952,11 @@ calculate_path_impl(const _PyCoreConfig *core_config, { _PyInitError err; - err = get_dll_path(calculate, config); - if (_Py_INIT_FAILED(err)) { - return err; + assert(config->dll_path == NULL); + + config->dll_path = _Py_GetDLLPath(); + if (config->dll_path == NULL) { + return _Py_INIT_NO_MEMORY(); } err = get_program_full_path(core_config, calculate, config); diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 3678d124067169..470bda870288b5 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -531,9 +531,6 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) CLEAR(config->prefix); CLEAR(config->base_prefix); CLEAR(config->exec_prefix); -#ifdef MS_WINDOWS - CLEAR(config->dll_path); -#endif CLEAR(config->base_exec_prefix); CLEAR(config->filesystem_encoding); @@ -761,9 +758,6 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_WSTR_ATTR(prefix); COPY_WSTR_ATTR(base_prefix); COPY_WSTR_ATTR(exec_prefix); -#ifdef MS_WINDOWS - COPY_WSTR_ATTR(dll_path); -#endif COPY_WSTR_ATTR(base_exec_prefix); COPY_ATTR(site_import); @@ -864,9 +858,6 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) SET_ITEM_WSTR(base_prefix); SET_ITEM_WSTR(exec_prefix); SET_ITEM_WSTR(base_exec_prefix); -#ifdef MS_WINDOWS - SET_ITEM_WSTR(dll_path); -#endif SET_ITEM_INT(site_import); SET_ITEM_INT(bytes_warning); SET_ITEM_INT(inspect); @@ -2355,9 +2346,6 @@ _PyCoreConfig_Read(_PyCoreConfig *config) assert(config->base_prefix != NULL); assert(config->exec_prefix != NULL); assert(config->base_exec_prefix != NULL); -#ifdef MS_WINDOWS - assert(config->dll_path != NULL); -#endif } assert(config->filesystem_encoding != NULL); assert(config->filesystem_errors != NULL); diff --git a/Python/pathconfig.c b/Python/pathconfig.c index c8c69ebad6a032..3d9d3b1b205fc9 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -214,7 +214,8 @@ _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) goto no_memory; } #ifdef MS_WINDOWS - if (copy_wstr(&path_config.dll_path, core_config->dll_path) < 0) { + path_config.dll_path = _Py_GetDLLPath(); + if (path_config.dll_path == NULL) { goto no_memory; } #endif @@ -322,14 +323,6 @@ _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config) } } -#ifdef MS_WINDOWS - if (config->dll_path == NULL) { - if (copy_wstr(&config->dll_path, path_config.dll_path) < 0) { - goto no_memory; - } - } -#endif - if (path_config.isolated != -1) { config->isolated = path_config.isolated; } @@ -356,9 +349,6 @@ _PyCoreConfig_InitPathConfig(_PyCoreConfig *config) if (!config->use_module_search_paths || (config->executable == NULL) || (config->prefix == NULL) -#ifdef MS_WINDOWS - || (config->dll_path == NULL) -#endif || (config->exec_prefix == NULL)) { _PyInitError err = _PyCoreConfig_CalculatePathConfig(config); @@ -435,7 +425,7 @@ Py_SetPath(const wchar_t *path) new_config.exec_prefix = _PyMem_RawWcsdup(L""); alloc_error |= (new_config.exec_prefix == NULL); #ifdef MS_WINDOWS - new_config.dll_path = _PyMem_RawWcsdup(L""); + new_config.dll_path = _Py_GetDLLPath(); alloc_error |= (new_config.dll_path == NULL); #endif new_config.module_search_path = _PyMem_RawWcsdup(path); From 73934b9da07daefb203e7d26089e7486a1ce4fdf Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 18 May 2019 12:29:50 +0100 Subject: [PATCH 004/441] bpo-36887: add math.isqrt (GH-13244) * Add math.isqrt function computing the integer square root. * Code cleanup: remove redundant comments, rename some variables. * Tighten up code a bit more; use Py_XDECREF to simplify error handling. * Update Modules/mathmodule.c Co-Authored-By: Serhiy Storchaka * Update Modules/mathmodule.c Use real argument clinic type instead of an alias Co-Authored-By: Serhiy Storchaka * Add proof sketch * Updates from review. * Correct and expand documentation. * Fix bad reference handling on error; make some variables block-local; other tidying. * Style and consistency fixes. * Add missing error check; don't try to DECREF a NULL a * Simplify some error returns. * Another two test cases: - clarify that floats are rejected even if they happen to be squares of small integers - TypeError beats ValueError for a negative float * Documentation and markup improvements; thanks Serhiy for the suggestions! * Cleaner Misc/NEWS entry wording. * Clean up (with one fix) to the algorithm explanation and proof. --- Doc/library/math.rst | 17 ++ Doc/whatsnew/3.8.rst | 3 + Lib/test/test_math.py | 51 ++++ .../2019-05-11-14-50-59.bpo-36887.XD3f22.rst | 1 + Modules/clinic/mathmodule.c.h | 11 +- Modules/mathmodule.c | 261 ++++++++++++++++++ 6 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 49f932d03845c8..bf660ae9defa07 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -166,6 +166,20 @@ Number-theoretic and representation functions Return ``True`` if *x* is a NaN (not a number), and ``False`` otherwise. +.. function:: isqrt(n) + + Return the integer square root of the nonnegative integer *n*. This is the + floor of the exact square root of *n*, or equivalently the greatest integer + *a* such that *a*\ ² |nbsp| ≤ |nbsp| *n*. + + For some applications, it may be more convenient to have the least integer + *a* such that *n* |nbsp| ≤ |nbsp| *a*\ ², or in other words the ceiling of + the exact square root of *n*. For positive *n*, this can be computed using + ``a = 1 + isqrt(n - 1)``. + + .. versionadded:: 3.8 + + .. function:: ldexp(x, i) Return ``x * (2**i)``. This is essentially the inverse of function @@ -538,3 +552,6 @@ Constants Module :mod:`cmath` Complex number versions of many of these functions. + +.. |nbsp| unicode:: 0xA0 + :trim: diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index d47993bf1129f8..07da4047a383a7 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -344,6 +344,9 @@ Added new function, :func:`math.prod`, as analogous function to :func:`sum` that returns the product of a 'start' value (default: 1) times an iterable of numbers. (Contributed by Pablo Galindo in :issue:`35606`) +Added new function :func:`math.isqrt` for computing integer square roots. +(Contributed by Mark Dickinson in :issue:`36887`.) + os -- diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index cb05dee0e0fd3c..a11a3447856402 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -912,6 +912,57 @@ class T(tuple): self.assertEqual(math.dist(p, q), 5*scale) self.assertEqual(math.dist(q, p), 5*scale) + def testIsqrt(self): + # Test a variety of inputs, large and small. + test_values = ( + list(range(1000)) + + list(range(10**6 - 1000, 10**6 + 1000)) + + [3**9999, 10**5001] + ) + + for value in test_values: + with self.subTest(value=value): + s = math.isqrt(value) + self.assertIs(type(s), int) + self.assertLessEqual(s*s, value) + self.assertLess(value, (s+1)*(s+1)) + + # Negative values + with self.assertRaises(ValueError): + math.isqrt(-1) + + # Integer-like things + s = math.isqrt(True) + self.assertIs(type(s), int) + self.assertEqual(s, 1) + + s = math.isqrt(False) + self.assertIs(type(s), int) + self.assertEqual(s, 0) + + class IntegerLike(object): + def __init__(self, value): + self.value = value + + def __index__(self): + return self.value + + s = math.isqrt(IntegerLike(1729)) + self.assertIs(type(s), int) + self.assertEqual(s, 41) + + with self.assertRaises(ValueError): + math.isqrt(IntegerLike(-3)) + + # Non-integer-like things + bad_values = [ + 3.5, "a string", decimal.Decimal("3.5"), 3.5j, + 100.0, -4.0, + ] + for value in bad_values: + with self.subTest(value=value): + with self.assertRaises(TypeError): + math.isqrt(value) def testLdexp(self): self.assertRaises(TypeError, math.ldexp) diff --git a/Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst b/Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst new file mode 100644 index 00000000000000..fe2929cea85a9b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst @@ -0,0 +1 @@ +Add new function :func:`math.isqrt` to compute integer square roots. diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 1806a01588c5ab..e677bd896cd885 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -65,6 +65,15 @@ PyDoc_STRVAR(math_fsum__doc__, #define MATH_FSUM_METHODDEF \ {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__}, +PyDoc_STRVAR(math_isqrt__doc__, +"isqrt($module, n, /)\n" +"--\n" +"\n" +"Return the integer part of the square root of the input."); + +#define MATH_ISQRT_METHODDEF \ + {"isqrt", (PyCFunction)math_isqrt, METH_O, math_isqrt__doc__}, + PyDoc_STRVAR(math_factorial__doc__, "factorial($module, x, /)\n" "--\n" @@ -628,4 +637,4 @@ math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k exit: return return_value; } -/*[clinic end generated code: output=96e71135dce41c48 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aeed62f403b90199 input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 8f6a303cc4deb4..821309221f820a 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1476,6 +1476,266 @@ count_set_bits(unsigned long n) return count; } +/* Integer square root + +Given a nonnegative integer `n`, we want to compute the largest integer +`a` for which `a * a <= n`, or equivalently the integer part of the exact +square root of `n`. + +We use an adaptive-precision pure-integer version of Newton's iteration. Given +a positive integer `n`, the algorithm produces at each iteration an integer +approximation `a` to the square root of `n >> s` for some even integer `s`, +with `s` decreasing as the iterations progress. On the final iteration, `s` is +zero and we have an approximation to the square root of `n` itself. + +At every step, the approximation `a` is strictly within 1.0 of the true square +root, so we have + + (a - 1)**2 < (n >> s) < (a + 1)**2 + +After the final iteration, a check-and-correct step is needed to determine +whether `a` or `a - 1` gives the desired integer square root of `n`. + +The algorithm is remarkable in its simplicity. There's no need for a +per-iteration check-and-correct step, and termination is straightforward: the +number of iterations is known in advance (it's exactly `floor(log2(log2(n)))` +for `n > 1`). The only tricky part of the correctness proof is in establishing +that the bound `(a - 1)**2 < (n >> s) < (a + 1)**2` is maintained from one +iteration to the next. A sketch of the proof of this is given below. + +In addition to the proof sketch, a formal, computer-verified proof +of correctness (using Lean) of an equivalent recursive algorithm can be found +here: + + https://github.com/mdickinson/snippets/blob/master/proofs/isqrt/src/isqrt.lean + + +Here's Python code equivalent to the C implementation below: + + def isqrt(n): + """ + Return the integer part of the square root of the input. + """ + n = operator.index(n) + + if n < 0: + raise ValueError("isqrt() argument must be nonnegative") + if n == 0: + return 0 + + c = (n.bit_length() - 1) // 2 + a = 1 + d = 0 + for s in reversed(range(c.bit_length())): + e = d + d = c >> s + a = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a + assert (a-1)**2 < n >> 2*(c - d) < (a+1)**2 + + return a - (a*a > n) + + +Sketch of proof of correctness +------------------------------ + +The delicate part of the correctness proof is showing that the loop invariant +is preserved from one iteration to the next. That is, just before the line + + a = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a + +is executed in the above code, we know that + + (1) (a - 1)**2 < (n >> 2*(c - e)) < (a + 1)**2. + +(since `e` is always the value of `d` from the previous iteration). We must +prove that after that line is executed, we have + + (a - 1)**2 < (n >> 2*(c - d)) < (a + 1)**2 + +To faciliate the proof, we make some changes of notation. Write `m` for +`n >> 2*(c-d)`, and write `b` for the new value of `a`, so + + b = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a + +or equivalently: + + (2) b = (a << d - e - 1) + (m >> d - e + 1) // a + +Then we can rewrite (1) as: + + (3) (a - 1)**2 < (m >> 2*(d - e)) < (a + 1)**2 + +and we must show that (b - 1)**2 < m < (b + 1)**2. + +From this point on, we switch to mathematical notation, so `/` means exact +division rather than integer division and `^` is used for exponentiation. We +use the `√` symbol for the exact square root. In (3), we can remove the +implicit floor operation to give: + + (4) (a - 1)^2 < m / 4^(d - e) < (a + 1)^2 + +Taking square roots throughout (4), scaling by `2^(d-e)`, and rearranging gives + + (5) 0 <= | 2^(d-e)a - √m | < 2^(d-e) + +Squaring and dividing through by `2^(d-e+1) a` gives + + (6) 0 <= 2^(d-e-1) a + m / (2^(d-e+1) a) - √m < 2^(d-e-1) / a + +We'll show below that `2^(d-e-1) <= a`. Given that, we can replace the +right-hand side of (6) with `1`, and now replacing the central +term `m / (2^(d-e+1) a)` with its floor in (6) gives + + (7) -1 < 2^(d-e-1) a + m // 2^(d-e+1) a - √m < 1 + +Or equivalently, from (2): + + (7) -1 < b - √m < 1 + +and rearranging gives that `(b-1)^2 < m < (b+1)^2`, which is what we needed +to prove. + +We're not quite done: we still have to prove the inequality `2^(d - e - 1) <= +a` that was used to get line (7) above. From the definition of `c`, we have +`4^c <= n`, which implies + + (8) 4^d <= m + +also, since `e == d >> 1`, `d` is at most `2e + 1`, from which it follows +that `2d - 2e - 1 <= d` and hence that + + (9) 4^(2d - 2e - 1) <= m + +Dividing both sides by `4^(d - e)` gives + + (10) 4^(d - e - 1) <= m / 4^(d - e) + +But we know from (4) that `m / 4^(d-e) < (a + 1)^2`, hence + + (11) 4^(d - e - 1) < (a + 1)^2 + +Now taking square roots of both sides and observing that both `2^(d-e-1)` and +`a` are integers gives `2^(d - e - 1) <= a`, which is what we needed. This +completes the proof sketch. + +*/ + +/*[clinic input] +math.isqrt + + n: object + / + +Return the integer part of the square root of the input. +[clinic start generated code]*/ + +static PyObject * +math_isqrt(PyObject *module, PyObject *n) +/*[clinic end generated code: output=35a6f7f980beab26 input=5b6e7ae4fa6c43d6]*/ +{ + int a_too_large, s; + size_t c, d; + PyObject *a = NULL, *b; + + n = PyNumber_Index(n); + if (n == NULL) { + return NULL; + } + + if (_PyLong_Sign(n) < 0) { + PyErr_SetString( + PyExc_ValueError, + "isqrt() argument must be nonnegative"); + goto error; + } + if (_PyLong_Sign(n) == 0) { + Py_DECREF(n); + return PyLong_FromLong(0); + } + + c = _PyLong_NumBits(n); + if (c == (size_t)(-1)) { + goto error; + } + c = (c - 1U) / 2U; + + /* s = c.bit_length() */ + s = 0; + while ((c >> s) > 0) { + ++s; + } + + a = PyLong_FromLong(1); + if (a == NULL) { + goto error; + } + d = 0; + while (--s >= 0) { + PyObject *q, *shift; + size_t e = d; + + d = c >> s; + + /* q = (n >> 2*c - e - d + 1) // a */ + shift = PyLong_FromSize_t(2U*c - d - e + 1U); + if (shift == NULL) { + goto error; + } + q = PyNumber_Rshift(n, shift); + Py_DECREF(shift); + if (q == NULL) { + goto error; + } + Py_SETREF(q, PyNumber_FloorDivide(q, a)); + if (q == NULL) { + goto error; + } + + /* a = (a << d - 1 - e) + q */ + shift = PyLong_FromSize_t(d - 1U - e); + if (shift == NULL) { + Py_DECREF(q); + goto error; + } + Py_SETREF(a, PyNumber_Lshift(a, shift)); + Py_DECREF(shift); + if (a == NULL) { + Py_DECREF(q); + goto error; + } + Py_SETREF(a, PyNumber_Add(a, q)); + Py_DECREF(q); + if (a == NULL) { + goto error; + } + } + + /* The correct result is either a or a - 1. Figure out which, and + decrement a if necessary. */ + + /* a_too_large = n < a * a */ + b = PyNumber_Multiply(a, a); + if (b == NULL) { + goto error; + } + a_too_large = PyObject_RichCompareBool(n, b, Py_LT); + Py_DECREF(b); + if (a_too_large == -1) { + goto error; + } + + if (a_too_large) { + Py_SETREF(a, PyNumber_Subtract(a, _PyLong_One)); + } + Py_DECREF(n); + return a; + + error: + Py_XDECREF(a); + Py_DECREF(n); + return NULL; +} + /* Divide-and-conquer factorial algorithm * * Based on the formula and pseudo-code provided at: @@ -2737,6 +2997,7 @@ static PyMethodDef math_methods[] = { MATH_ISFINITE_METHODDEF MATH_ISINF_METHODDEF MATH_ISNAN_METHODDEF + MATH_ISQRT_METHODDEF MATH_LDEXP_METHODDEF {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, MATH_LOG_METHODDEF From e917f2ed9af044fe808fc9b4ddc6c5eb99003500 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 18 May 2019 10:18:29 -0700 Subject: [PATCH 005/441] bpo-36546: Add more tests and expand docs (#13406) --- Doc/library/statistics.rst | 33 +++++++++++++++++++++----------- Lib/test/test_statistics.py | 38 ++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index fb7df4e7188a07..bc841fda72f887 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -511,22 +511,33 @@ However, for reading convenience, most of the examples show sorted sequences. is not least 1. The *dist* can be any iterable containing sample data or it can be an - instance of a class that defines an :meth:`~inv_cdf` method. + instance of a class that defines an :meth:`~inv_cdf` method. For meaningful + results, the number of data points in *dist* should be larger than *n*. Raises :exc:`StatisticsError` if there are not at least two data points. For sample data, the cut points are linearly interpolated from the two nearest data points. For example, if a cut point falls one-third of the distance between two sample values, ``100`` and ``112``, the - cut-point will evaluate to ``104``. Other selection methods may be - offered in the future (for example choose ``100`` as the nearest - value or compute ``106`` as the midpoint). This might matter if - there are too few samples for a given number of cut points. - - If *method* is set to *inclusive*, *dist* is treated as population data. - The minimum value is treated as the 0th percentile and the maximum - value is treated as the 100th percentile. If *dist* is an instance of - a class that defines an :meth:`~inv_cdf` method, setting *method* - has no effect. + cut-point will evaluate to ``104``. + + The *method* for computing quantiles can be varied depending on + whether the data in *dist* includes or excludes the lowest and + highest possible values from the population. + + The default *method* is "exclusive" and is used for data sampled from + a population that can have more extreme values than found in the + samples. The portion of the population falling below the *i-th* of + *m* data points is computed as ``i / (m + 1)``. + + Setting the *method* to "inclusive" is used for describing population + data or for samples that include the extreme points. The minimum + value in *dist* is treated as the 0th percentile and the maximum + value is treated as the 100th percentile. The portion of the + population falling below the *i-th* of *m* data points is computed as + ``(i - 1) / (m - 1)``. + + If *dist* is an instance of a class that defines an + :meth:`~inv_cdf` method, setting *method* has no effect. .. doctest:: diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 1922de5df4b0c5..946c7428c61311 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -2161,17 +2161,18 @@ def test_specific_cases(self): # Quantiles should be idempotent if len(expected) >= 2: self.assertEqual(quantiles(expected, n=n), expected) - # Cross-check against other methods - if len(data) >= n: - # After end caps are added, method='inclusive' should - # give the same result as method='exclusive' whenever - # there are more data points than desired cut points. - padded_data = [min(data) - 1000] + data + [max(data) + 1000] - self.assertEqual( - quantiles(data, n=n), - quantiles(padded_data, n=n, method='inclusive'), - (n, data), - ) + # Cross-check against method='inclusive' which should give + # the same result after adding in minimum and maximum values + # extrapolated from the two lowest and two highest points. + sdata = sorted(data) + lo = 2 * sdata[0] - sdata[1] + hi = 2 * sdata[-1] - sdata[-2] + padded_data = data + [lo, hi] + self.assertEqual( + quantiles(data, n=n), + quantiles(padded_data, n=n, method='inclusive'), + (n, data), + ) # Invariant under tranlation and scaling def f(x): return 3.5 * x - 1234.675 @@ -2188,6 +2189,11 @@ def f(x): actual = quantiles(statistics.NormalDist(), n=n) self.assertTrue(all(math.isclose(e, a, abs_tol=0.0001) for e, a in zip(expected, actual))) + # Q2 agrees with median() + for k in range(2, 60): + data = random.choices(range(100), k=k) + q1, q2, q3 = quantiles(data) + self.assertEqual(q2, statistics.median(data)) def test_specific_cases_inclusive(self): # Match results computed by hand and cross-checked @@ -2233,6 +2239,11 @@ def f(x): actual = quantiles(statistics.NormalDist(), n=n, method="inclusive") self.assertTrue(all(math.isclose(e, a, abs_tol=0.0001) for e, a in zip(expected, actual))) + # Natural deciles + self.assertEqual(quantiles([0, 100], n=10, method='inclusive'), + [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0]) + self.assertEqual(quantiles(range(0, 101), n=10, method='inclusive'), + [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0]) # Whenever n is smaller than the number of data points, running # method='inclusive' should give the same result as method='exclusive' # after the two included extreme points are removed. @@ -2242,6 +2253,11 @@ def f(x): data.remove(max(data)) expected = quantiles(data, n=32) self.assertEqual(expected, actual) + # Q2 agrees with median() + for k in range(2, 60): + data = random.choices(range(100), k=k) + q1, q2, q3 = quantiles(data, method='inclusive') + self.assertEqual(q2, statistics.median(data)) def test_equal_inputs(self): quantiles = statistics.quantiles From abea73bf4a320ff658c9a98fef3d948a142e61a9 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 18 May 2019 11:27:17 -0700 Subject: [PATCH 006/441] bpo-2180: Treat line continuation at EOF as a `SyntaxError` (GH-13401) This makes the parser consistent with the tokenize module (already the case in `pypy`). sample ------ ```python x = 5\ ``` before ------ ```console $ python3 t.py $ python3 -mtokenize t.py t.py:2:0: error: EOF in multi-line statement ``` after ----- ```console $ ./python t.py File "t.py", line 3 x = 5\ ^ SyntaxError: unexpected EOF while parsing $ ./python -m tokenize t.py t.py:2:0: error: EOF in multi-line statement ``` https://bugs.python.org/issue2180 --- Lib/test/test_eof.py | 26 ++++++++++++++++++- .../2019-05-17-18-34-30.bpo-2180.aBqHeW.rst | 1 + Parser/tokenizer.c | 11 +++++++- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst diff --git a/Lib/test/test_eof.py b/Lib/test/test_eof.py index 7baa7ae57c6ff4..a091ceaa25bc4f 100644 --- a/Lib/test/test_eof.py +++ b/Lib/test/test_eof.py @@ -1,7 +1,9 @@ """test script for a few new invalid token catches""" -import unittest +import sys from test import support +from test.support import script_helper +import unittest class EOFTestCase(unittest.TestCase): def test_EOFC(self): @@ -24,5 +26,27 @@ def test_EOFS(self): else: raise support.TestFailed + def test_line_continuation_EOF(self): + """A contination at the end of input must be an error; bpo2180.""" + expect = 'unexpected EOF while parsing (, line 1)' + with self.assertRaises(SyntaxError) as excinfo: + exec('x = 5\\') + self.assertEqual(str(excinfo.exception), expect) + with self.assertRaises(SyntaxError) as excinfo: + exec('\\') + self.assertEqual(str(excinfo.exception), expect) + + @unittest.skipIf(not sys.executable, "sys.executable required") + def test_line_continuation_EOF_from_file_bpo2180(self): + """Ensure tok_nextc() does not add too many ending newlines.""" + with support.temp_dir() as temp_dir: + file_name = script_helper.make_script(temp_dir, 'foo', '\\') + rc, out, err = script_helper.assert_python_failure(file_name) + self.assertIn(b'unexpected EOF while parsing', err) + + file_name = script_helper.make_script(temp_dir, 'foo', 'y = 6\\') + rc, out, err = script_helper.assert_python_failure(file_name) + self.assertIn(b'unexpected EOF while parsing', err) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst new file mode 100644 index 00000000000000..a2207c17aea0a8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst @@ -0,0 +1 @@ +Treat line continuation at EOF as a ``SyntaxError`` by Anthony Sottile. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 5dc2ae65c42daf..e52d498d5542d5 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -983,7 +983,8 @@ tok_nextc(struct tok_state *tok) return EOF; /* Last line does not end in \n, fake one */ - strcpy(tok->inp, "\n"); + if (tok->inp[-1] != '\n') + strcpy(tok->inp, "\n"); } tok->inp = strchr(tok->inp, '\0'); done = tok->inp[-1] == '\n'; @@ -1674,6 +1675,14 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) tok->cur = tok->inp; return ERRORTOKEN; } + c = tok_nextc(tok); + if (c == EOF) { + tok->done = E_EOF; + tok->cur = tok->inp; + return ERRORTOKEN; + } else { + tok_backup(tok, c); + } tok->cont_line = 1; goto again; /* Read next line */ } From 56027ccd6b9dab4a090e4fef8574933fb9a36ff2 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Singh Date: Sun, 19 May 2019 02:06:19 +0530 Subject: [PATCH 007/441] bpo-19376: Added doc mentioning `datetime.strptime()` without a year fails for Feb 29. (GH-10243) --- Doc/library/datetime.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index abdc977354803e..3c45e56b5f4fef 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -2048,6 +2048,9 @@ For :class:`date` objects, the format codes for hours, minutes, seconds, and microseconds should not be used, as :class:`date` objects have no such values. If they're used anyway, ``0`` is substituted for them. +For the :meth:`datetime.strptime` class method, the default value is ``1900-01-01T00:00:00.000``: +any components not specified in the format string will be pulled from the default value. [#]_ + The full set of format codes supported varies across platforms, because Python calls the platform C library's :func:`strftime` function, and platform variations are common. To see the full set of format codes supported on your @@ -2282,3 +2285,4 @@ Notes: .. rubric:: Footnotes .. [#] If, that is, we ignore the effects of Relativity +.. [#] Passing ``datetime.strptime('Feb 29', '%b %d')`` will fail since ``1900`` is not a leap year. From eab99650799699f766c2660f4cfa8ff3f9e8457f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= <47358913+isidentical@users.noreply.github.com> Date: Sun, 19 May 2019 00:53:53 +0300 Subject: [PATCH 008/441] bpo-36567: Use manpages_url to create links for man pages (GH-13339) --- Doc/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/conf.py b/Doc/conf.py index afe66270c10e8c..e85ea5b2d2ff49 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -23,6 +23,9 @@ except ImportError: _tkinter = None ''' + +manpages_url = 'https://manpages.debian.org/{path}' + # General substitutions. project = 'Python' copyright = '2001-%s, Python Software Foundation' % time.strftime('%Y') From fa19a25c238d0769e6a5aa63ce05133d66043556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= <47358913+isidentical@users.noreply.github.com> Date: Sun, 19 May 2019 01:10:20 +0300 Subject: [PATCH 009/441] Add support for PEP572 in ast_unparse.c (GH-13337) --- Lib/test/test_future.py | 2 ++ .../2019-05-15-14-01-09.bpo-36826.GLrO3W.rst | 1 + Python/ast_unparse.c | 13 +++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index 38de3dfdafcdb1..cd320a266a8741 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -275,6 +275,8 @@ def test_annotations(self): eq('f((x for x in a), 2)') eq('(((a)))', 'a') eq('(((a, b)))', '(a, b)') + eq("(x:=10)") + eq("f'{(x:=10):=10}'") if __name__ == "__main__": diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst new file mode 100644 index 00000000000000..5a1b51999f26fc --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst @@ -0,0 +1 @@ +Add NamedExpression kind support to ast_unparse.c diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index 25a5c698a1db9e..5f366a188b36e7 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -809,6 +809,17 @@ append_ast_await(_PyUnicodeWriter *writer, expr_ty e, int level) return 0; } +static int +append_named_expr(_PyUnicodeWriter *writer, expr_ty e, int level) +{ + APPEND_STR_IF(level > PR_TUPLE, "("); + APPEND_EXPR(e->v.NamedExpr.target, PR_ATOM); + APPEND_STR(":="); + APPEND_EXPR(e->v.NamedExpr.value, PR_ATOM); + APPEND_STR_IF(level > PR_TUPLE, ")"); + return 0; +} + static int append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) { @@ -867,6 +878,8 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) return append_ast_list(writer, e); case Tuple_kind: return append_ast_tuple(writer, e, level); + case NamedExpr_kind: + return append_named_expr(writer, e, level); default: PyErr_SetString(PyExc_SystemError, "unknown expression kind"); From da6129e821099c1372d511a11d18af83d6d5d128 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 18 May 2019 23:40:22 +0100 Subject: [PATCH 010/441] bpo-36961: Handle positional-only arguments in uparse.c (GH-13412) --- Lib/test/test_future.py | 12 ++++++++++++ Python/ast_unparse.c | 22 ++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index cd320a266a8741..dd148b62956298 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -183,6 +183,18 @@ def test_annotations(self): eq('lambda a, b, c=True: a') eq("lambda a, b, c=True, *, d=1 << v2, e='str': a") eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b") + eq("lambda a, /, b, c=True, *vararg, d, e='str', **kwargs: a + b") + eq('lambda x, /: x') + eq('lambda x=1, /: x') + eq('lambda x, /, y: x + y') + eq('lambda x=1, /, y=2: x + y') + eq('lambda x, /, y=1: x + y') + eq('lambda x, /, y=1, *, z=3: x + y + z') + eq('lambda x=1, /, y=2, *, z=3: x + y + z') + eq('lambda x=1, /, y=2, *, z: x + y + z') + eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2: x + y + z + w + l + l2') + eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2, **kwargs: x + y + z + w + l + l2') + eq('lambda x, /, y=1, *, z: x + y + z') eq('lambda x: lambda y: x + y') eq('1 if True else 2') eq('str or None if int or True else str or bytes or None') diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index 5f366a188b36e7..f1b991a7c38788 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -193,22 +193,30 @@ static int append_ast_args(_PyUnicodeWriter *writer, arguments_ty args) { bool first; - Py_ssize_t i, di, arg_count, default_count; + Py_ssize_t i, di, arg_count, posonlyarg_count, default_count; first = true; - /* positional arguments with defaults */ + /* positional-only and positional arguments with defaults */ + posonlyarg_count = asdl_seq_LEN(args->posonlyargs); arg_count = asdl_seq_LEN(args->args); default_count = asdl_seq_LEN(args->defaults); - for (i = 0; i < arg_count; i++) { + for (i = 0; i < posonlyarg_count + arg_count; i++) { APPEND_STR_IF_NOT_FIRST(", "); - APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i)); + if (i < posonlyarg_count){ + APPEND(arg, (arg_ty)asdl_seq_GET(args->posonlyargs, i)); + } else { + APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i-posonlyarg_count)); + } - di = i - arg_count + default_count; + di = i - posonlyarg_count - arg_count + default_count; if (di >= 0) { APPEND_STR("="); APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST); } + if (posonlyarg_count && i + 1 == posonlyarg_count) { + APPEND_STR(", /"); + } } /* vararg, or bare '*' if no varargs but keyword-only arguments present */ @@ -251,7 +259,9 @@ static int append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level) { APPEND_STR_IF(level > PR_TEST, "("); - APPEND_STR(asdl_seq_LEN(e->v.Lambda.args->args) ? "lambda " : "lambda"); + Py_ssize_t n_positional = (asdl_seq_LEN(e->v.Lambda.args->args) + + asdl_seq_LEN(e->v.Lambda.args->posonlyargs)); + APPEND_STR(n_positional ? "lambda " : "lambda"); APPEND(args, e->v.Lambda.args); APPEND_STR(": "); APPEND_EXPR(e->v.Lambda.body, PR_TEST); From 9892f454d11b7ea9ba394a115b3e6f48ef6f78fe Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 18 May 2019 17:17:56 -0700 Subject: [PATCH 011/441] bpo-33519: clarify that .copy() is not part of the MutableSequence ABC (GH-6965) --- Doc/library/stdtypes.rst | 6 ++++-- .../Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 53337291dd39ce..293a1ab6a0d966 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1114,7 +1114,7 @@ Notes: item is removed and returned. (3) - ``remove`` raises :exc:`ValueError` when *x* is not found in *s*. + :meth:`remove` raises :exc:`ValueError` when *x* is not found in *s*. (4) The :meth:`reverse` method modifies the sequence in place for economy of @@ -1124,7 +1124,9 @@ Notes: (5) :meth:`clear` and :meth:`!copy` are included for consistency with the interfaces of mutable containers that don't support slicing operations - (such as :class:`dict` and :class:`set`) + (such as :class:`dict` and :class:`set`). :meth:`!copy` is not part of the + :class:`collections.abc.MutableSequence` ABC, but most concrete + mutable sequence classes provide it. .. versionadded:: 3.3 :meth:`clear` and :meth:`!copy` methods. diff --git a/Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst b/Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst new file mode 100644 index 00000000000000..0ee6c0d5f8eae7 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst @@ -0,0 +1 @@ +Clarify that `copy()` is not part of the `MutableSequence` ABC. From f665b96e92a6a6943e312e2c606f348db95939ab Mon Sep 17 00:00:00 2001 From: Ashwin Ramaswami Date: Sat, 18 May 2019 18:17:48 -0700 Subject: [PATCH 012/441] Fix typo in test comment (GH-11442) --- Lib/unittest/test/test_case.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py index 687fe5b65f109e..c2401c39b917e3 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -620,7 +620,7 @@ def AllSnakesCreatedEqual(a, b, msg=None): self.addTypeEqualityFunc(SadSnake, AllSnakesCreatedEqual) self.assertEqual(s1, s2) # No this doesn't clean up and remove the SadSnake equality func - # from this TestCase instance but since its a local nothing else + # from this TestCase instance but since it's local nothing else # will ever notice that. def testAssertIs(self): From 1d5bdef550d4395211fbe5f3c1444d7ea5bb54a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bo=C5=A1tjan=20Mejak?= Date: Sun, 19 May 2019 11:01:36 +0200 Subject: [PATCH 013/441] Orthographical fix (GH-13418) Add a missing comma. --- Doc/library/asyncio-task.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index e7cf39b2bccd5f..bb064bd93deaf7 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -40,7 +40,7 @@ be executed:: >>> main() -To actually run a coroutine asyncio provides three main mechanisms: +To actually run a coroutine, asyncio provides three main mechanisms: * The :func:`asyncio.run` function to run the top-level entry point "main()" function (see the above example.) From a5119e7d75c9729fc36c059d05f3d7132e7f6bb4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 19 May 2019 14:14:38 +0300 Subject: [PATCH 014/441] bpo-36957: Add _PyLong_Rshift() and _PyLong_Lshift(). (GH-13416) --- Include/longobject.h | 3 ++ Modules/mathmodule.c | 30 +++--------- Objects/floatobject.c | 4 +- Objects/longobject.c | 103 ++++++++++++++++++++++++++++++------------ 4 files changed, 87 insertions(+), 53 deletions(-) diff --git a/Include/longobject.h b/Include/longobject.h index b696f544b9c192..a24bbea3a9044f 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -230,6 +230,9 @@ PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); #ifndef Py_LIMITED_API PyAPI_DATA(PyObject *) _PyLong_Zero; PyAPI_DATA(PyObject *) _PyLong_One; + +PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t); +PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t); #endif #ifdef __cplusplus diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 821309221f820a..7a0044a9fcf0b9 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1671,18 +1671,13 @@ math_isqrt(PyObject *module, PyObject *n) } d = 0; while (--s >= 0) { - PyObject *q, *shift; + PyObject *q; size_t e = d; d = c >> s; /* q = (n >> 2*c - e - d + 1) // a */ - shift = PyLong_FromSize_t(2U*c - d - e + 1U); - if (shift == NULL) { - goto error; - } - q = PyNumber_Rshift(n, shift); - Py_DECREF(shift); + q = _PyLong_Rshift(n, 2U*c - d - e + 1U); if (q == NULL) { goto error; } @@ -1692,13 +1687,7 @@ math_isqrt(PyObject *module, PyObject *n) } /* a = (a << d - 1 - e) + q */ - shift = PyLong_FromSize_t(d - 1U - e); - if (shift == NULL) { - Py_DECREF(q); - goto error; - } - Py_SETREF(a, PyNumber_Lshift(a, shift)); - Py_DECREF(shift); + Py_SETREF(a, _PyLong_Lshift(a, d - 1U - e)); if (a == NULL) { Py_DECREF(q); goto error; @@ -1939,9 +1928,9 @@ static PyObject * math_factorial(PyObject *module, PyObject *arg) /*[clinic end generated code: output=6686f26fae00e9ca input=6d1c8105c0d91fb4]*/ { - long x; + long x, two_valuation; int overflow; - PyObject *result, *odd_part, *two_valuation, *pyint_form; + PyObject *result, *odd_part, *pyint_form; if (PyFloat_Check(arg)) { PyObject *lx; @@ -1990,13 +1979,8 @@ math_factorial(PyObject *module, PyObject *arg) odd_part = factorial_odd_part(x); if (odd_part == NULL) return NULL; - two_valuation = PyLong_FromLong(x - count_set_bits(x)); - if (two_valuation == NULL) { - Py_DECREF(odd_part); - return NULL; - } - result = PyNumber_Lshift(odd_part, two_valuation); - Py_DECREF(two_valuation); + two_valuation = x - count_set_bits(x); + result = _PyLong_Lshift(odd_part, two_valuation); Py_DECREF(odd_part); return result; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index adb9b80c271349..4ff43bb338f982 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -463,13 +463,13 @@ float_richcompare(PyObject *v, PyObject *w, int op) */ PyObject *temp; - temp = PyNumber_Lshift(ww, _PyLong_One); + temp = _PyLong_Lshift(ww, 1); if (temp == NULL) goto Error; Py_DECREF(ww); ww = temp; - temp = PyNumber_Lshift(vv, _PyLong_One); + temp = _PyLong_Lshift(vv, 1); if (temp == NULL) goto Error; Py_DECREF(vv); diff --git a/Objects/longobject.c b/Objects/longobject.c index 9fb1fb02c276bd..1934328820c0c5 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4416,9 +4416,9 @@ long_bool(PyLongObject *v) /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ static int -divmod_shift(PyLongObject *shiftby, Py_ssize_t *wordshift, digit *remshift) +divmod_shift(PyObject *shiftby, Py_ssize_t *wordshift, digit *remshift) { - assert(PyLong_Check((PyObject *)shiftby)); + assert(PyLong_Check(shiftby)); assert(Py_SIZE(shiftby) >= 0); Py_ssize_t lshiftby = PyLong_AsSsize_t((PyObject *)shiftby); if (lshiftby >= 0) { @@ -4430,7 +4430,7 @@ divmod_shift(PyLongObject *shiftby, Py_ssize_t *wordshift, digit *remshift) be that PyLong_AsSsize_t raised an OverflowError. */ assert(PyErr_ExceptionMatches(PyExc_OverflowError)); PyErr_Clear(); - PyLongObject *wordshift_obj = divrem1(shiftby, PyLong_SHIFT, remshift); + PyLongObject *wordshift_obj = divrem1((PyLongObject *)shiftby, PyLong_SHIFT, remshift); if (wordshift_obj == NULL) { return -1; } @@ -4448,19 +4448,11 @@ divmod_shift(PyLongObject *shiftby, Py_ssize_t *wordshift, digit *remshift) } static PyObject * -long_rshift(PyLongObject *a, PyLongObject *b) +long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) { PyLongObject *z = NULL; - Py_ssize_t newsize, wordshift, hishift, i, j; - digit loshift, lomask, himask; - - CHECK_BINOP(a, b); - - if (Py_SIZE(b) < 0) { - PyErr_SetString(PyExc_ValueError, - "negative shift count"); - return NULL; - } + Py_ssize_t newsize, hishift, i, j; + digit lomask, himask; if (Py_SIZE(a) < 0) { /* Right shifting negative numbers is harder */ @@ -4468,7 +4460,7 @@ long_rshift(PyLongObject *a, PyLongObject *b) a1 = (PyLongObject *) long_invert(a); if (a1 == NULL) return NULL; - a2 = (PyLongObject *) long_rshift(a1, b); + a2 = (PyLongObject *) long_rshift1(a1, wordshift, remshift); Py_DECREF(a1); if (a2 == NULL) return NULL; @@ -4476,19 +4468,17 @@ long_rshift(PyLongObject *a, PyLongObject *b) Py_DECREF(a2); } else { - if (divmod_shift(b, &wordshift, &loshift) < 0) - return NULL; newsize = Py_SIZE(a) - wordshift; if (newsize <= 0) return PyLong_FromLong(0); - hishift = PyLong_SHIFT - loshift; + hishift = PyLong_SHIFT - remshift; lomask = ((digit)1 << hishift) - 1; himask = PyLong_MASK ^ lomask; z = _PyLong_New(newsize); if (z == NULL) return NULL; for (i = 0, j = wordshift; i < newsize; i++, j++) { - z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; + z->ob_digit[i] = (a->ob_digit[j] >> remshift) & lomask; if (i+1 < newsize) z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask; } @@ -4498,15 +4488,10 @@ long_rshift(PyLongObject *a, PyLongObject *b) } static PyObject * -long_lshift(PyObject *v, PyObject *w) +long_rshift(PyObject *a, PyObject *b) { - /* This version due to Tim Peters */ - PyLongObject *a = (PyLongObject*)v; - PyLongObject *b = (PyLongObject*)w; - PyLongObject *z = NULL; - Py_ssize_t oldsize, newsize, wordshift, i, j; + Py_ssize_t wordshift; digit remshift; - twodigits accum; CHECK_BINOP(a, b); @@ -4517,9 +4502,35 @@ long_lshift(PyObject *v, PyObject *w) if (Py_SIZE(a) == 0) { return PyLong_FromLong(0); } - if (divmod_shift(b, &wordshift, &remshift) < 0) return NULL; + return long_rshift1((PyLongObject *)a, wordshift, remshift); +} + +/* Return a >> shiftby. */ +PyObject * +_PyLong_Rshift(PyObject *a, size_t shiftby) +{ + Py_ssize_t wordshift; + digit remshift; + + assert(PyLong_Check(a)); + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + wordshift = shiftby / PyLong_SHIFT; + remshift = shiftby % PyLong_SHIFT; + return long_rshift1((PyLongObject *)a, wordshift, remshift); +} + +static PyObject * +long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) +{ + /* This version due to Tim Peters */ + PyLongObject *z = NULL; + Py_ssize_t oldsize, newsize, i, j; + twodigits accum; + oldsize = Py_ABS(Py_SIZE(a)); newsize = oldsize + wordshift; if (remshift) @@ -4547,6 +4558,42 @@ long_lshift(PyObject *v, PyObject *w) return (PyObject *) maybe_small_long(z); } +static PyObject * +long_lshift(PyObject *a, PyObject *b) +{ + Py_ssize_t wordshift; + digit remshift; + + CHECK_BINOP(a, b); + + if (Py_SIZE(b) < 0) { + PyErr_SetString(PyExc_ValueError, "negative shift count"); + return NULL; + } + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + if (divmod_shift(b, &wordshift, &remshift) < 0) + return NULL; + return long_lshift1((PyLongObject *)a, wordshift, remshift); +} + +/* Return a << shiftby. */ +PyObject * +_PyLong_Lshift(PyObject *a, size_t shiftby) +{ + Py_ssize_t wordshift; + digit remshift; + + assert(PyLong_Check(a)); + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + wordshift = shiftby / PyLong_SHIFT; + remshift = shiftby % PyLong_SHIFT; + return long_lshift1((PyLongObject *)a, wordshift, remshift); +} + /* Compute two's complement of digit vector a[0:m], writing result to z[0:m]. The digit vector a need not be normalized, but should not be entirely zero. a and z may point to the same digit vector. */ @@ -5552,7 +5599,7 @@ static PyNumberMethods long_as_number = { (inquiry)long_bool, /*tp_bool*/ (unaryfunc)long_invert, /*nb_invert*/ long_lshift, /*nb_lshift*/ - (binaryfunc)long_rshift, /*nb_rshift*/ + long_rshift, /*nb_rshift*/ long_and, /*nb_and*/ long_xor, /*nb_xor*/ long_or, /*nb_or*/ From c661b30f89ffe7a7995538d3b1649469b184bee4 Mon Sep 17 00:00:00 2001 From: Xtreak Date: Sun, 19 May 2019 19:10:06 +0530 Subject: [PATCH 015/441] bpo-36948: Fix NameError in urllib.request.URLopener.retrieve (GH-13389) --- Lib/test/test_urllib.py | 20 ++++++++++++++++++- Lib/urllib/request.py | 10 +++++----- .../2019-05-17-21-42-58.bpo-36948.vnUDvk.rst | 2 ++ 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 7214492eca9d88..74b19fbdcd8dbe 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1445,7 +1445,7 @@ def test_thishost(self): self.assertIsInstance(urllib.request.thishost(), tuple) -class URLopener_Tests(unittest.TestCase): +class URLopener_Tests(FakeHTTPMixin, unittest.TestCase): """Testcase to test the open method of URLopener class.""" def test_quoted_open(self): @@ -1463,6 +1463,24 @@ def open_spam(self, url): "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"), "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/") + @support.ignore_warnings(category=DeprecationWarning) + def test_urlopener_retrieve_file(self): + with support.temp_dir() as tmpdir: + fd, tmpfile = tempfile.mkstemp(dir=tmpdir) + os.close(fd) + fileurl = "file:" + urllib.request.pathname2url(tmpfile) + filename, _ = urllib.request.URLopener().retrieve(fileurl) + self.assertEqual(filename, tmpfile) + + @support.ignore_warnings(category=DeprecationWarning) + def test_urlopener_retrieve_remote(self): + url = "http://www.python.org/file.txt" + self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello!") + self.addCleanup(self.unfakehttp) + filename, _ = urllib.request.URLopener().retrieve(url) + self.assertEqual(os.path.splitext(filename)[1], ".txt") + + # Just commented them out. # Can't really tell why keep failing in windows and sparc. # Everywhere else they work ok, but on those machines, sometimes diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index df2ff06f0fc9a2..230ac390abb332 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1783,7 +1783,7 @@ def retrieve(self, url, filename=None, reporthook=None, data=None): fp = self.open_local_file(url1) hdrs = fp.info() fp.close() - return url2pathname(splithost(url1)[1]), hdrs + return url2pathname(_splithost(url1)[1]), hdrs except OSError as msg: pass fp = self.open(url, data) @@ -1792,10 +1792,10 @@ def retrieve(self, url, filename=None, reporthook=None, data=None): if filename: tfp = open(filename, 'wb') else: - garbage, path = splittype(url) - garbage, path = splithost(path or "") - path, garbage = splitquery(path or "") - path, garbage = splitattr(path or "") + garbage, path = _splittype(url) + garbage, path = _splithost(path or "") + path, garbage = _splitquery(path or "") + path, garbage = _splitattr(path or "") suffix = os.path.splitext(path)[1] (fd, filename) = tempfile.mkstemp(suffix) self.__tempfiles.append(filename) diff --git a/Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst b/Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst new file mode 100644 index 00000000000000..c8cfa54067fd35 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst @@ -0,0 +1,2 @@ +Fix :exc:`NameError` in :meth:`urllib.request.URLopener.retrieve`. Patch by +Karthikeyan Singaravelan. From f4e1babf44792bdeb0c01da96821ba0800a51fd8 Mon Sep 17 00:00:00 2001 From: Bar Harel Date: Sun, 19 May 2019 16:57:13 +0300 Subject: [PATCH 016/441] bpo-27141: Fix collections.UserList and UserDict shallow copy. (GH-4094) --- Lib/collections/__init__.py | 14 +++++++++++ Lib/test/test_collections.py | 24 +++++++++++++++++++ .../2017-10-24-00-42-14.bpo-27141.zbAgSs.rst | 3 +++ 3 files changed, 41 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 706907ad4a282d..960d82a5dcfbf5 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1038,6 +1038,13 @@ def __contains__(self, key): # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) + def __copy__(self): + inst = self.__class__.__new__(self.__class__) + inst.__dict__.update(self.__dict__) + # Create a copy and avoid triggering descriptors + inst.__dict__["data"] = self.__dict__["data"].copy() + return inst + def copy(self): if self.__class__ is UserDict: return UserDict(self.data.copy()) @@ -1050,6 +1057,7 @@ def copy(self): self.data = data c.update(self) return c + @classmethod def fromkeys(cls, iterable, value=None): d = cls() @@ -1118,6 +1126,12 @@ def __mul__(self, n): def __imul__(self, n): self.data *= n return self + def __copy__(self): + inst = self.__class__.__new__(self.__class__) + inst.__dict__.update(self.__dict__) + # Create a copy and avoid triggering descriptors + inst.__dict__["data"] = self.__dict__["data"][:] + return inst def append(self, item): self.data.append(item) def insert(self, i, item): self.data.insert(i, item) def pop(self, i=-1): return self.data.pop(i) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 1f619bcdac9203..e2d04d5b476196 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -37,6 +37,20 @@ def _superset_test(self, a, b): b=b.__name__, ), ) + + def _copy_test(self, obj): + # Test internal copy + obj_copy = obj.copy() + self.assertIsNot(obj.data, obj_copy.data) + self.assertEqual(obj.data, obj_copy.data) + + # Test copy.copy + obj.test = [1234] # Make sure instance vars are also copied. + obj_copy = copy.copy(obj) + self.assertIsNot(obj.data, obj_copy.data) + self.assertEqual(obj.data, obj_copy.data) + self.assertIs(obj.test, obj_copy.test) + def test_str_protocol(self): self._superset_test(UserString, str) @@ -46,6 +60,16 @@ def test_list_protocol(self): def test_dict_protocol(self): self._superset_test(UserDict, dict) + def test_list_copy(self): + obj = UserList() + obj.append(123) + self._copy_test(obj) + + def test_dict_copy(self): + obj = UserDict() + obj[123] = "abc" + self._copy_test(obj) + ################################################################################ ### ChainMap (helper class for configparser and the string module) diff --git a/Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst b/Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst new file mode 100644 index 00000000000000..76c2abbf82d689 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst @@ -0,0 +1,3 @@ +Added a ``__copy__()`` to ``collections.UserList`` and +``collections.UserDict`` in order to correctly implement shallow copying of +the objects. Patch by Bar Harel. From 7c59362a15dfce538512ff1fce4e07d33a925cfb Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 19 May 2019 18:56:15 +0300 Subject: [PATCH 017/441] bpo-29183: Fix double exceptions in wsgiref.handlers.BaseHandler (GH-12914) --- Lib/test/test_wsgiref.py | 25 +++++++++++++++++++ Lib/wsgiref/handlers.py | 11 +++++++- .../2019-04-22-22-55-29.bpo-29183.MILvsk.rst | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 46f88a94434bcd..42432bfbd260e7 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -806,6 +806,31 @@ def write(self, b): self.assertFalse(stderr.getvalue()) + def testDontResetInternalStateOnException(self): + class CustomException(ValueError): + pass + + # We are raising CustomException here to trigger an exception + # during the execution of SimpleHandler.finish_response(), so + # we can easily test that the internal state of the handler is + # preserved in case of an exception. + class AbortingWriter: + def write(self, b): + raise CustomException + + stderr = StringIO() + environ = {"SERVER_PROTOCOL": "HTTP/1.0"} + h = SimpleHandler(BytesIO(), AbortingWriter(), stderr, environ) + h.run(hello_app) + + self.assertIn("CustomException", stderr.getvalue()) + + # Test that the internal state of the handler is preserved. + self.assertIsNotNone(h.result) + self.assertIsNotNone(h.headers) + self.assertIsNotNone(h.status) + self.assertIsNotNone(h.environ) + if __name__ == "__main__": unittest.main() diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py index 834073d50091e0..31360e58785ac6 100644 --- a/Lib/wsgiref/handlers.py +++ b/Lib/wsgiref/handlers.py @@ -183,7 +183,16 @@ def finish_response(self): for data in self.result: self.write(data) self.finish_content() - finally: + except: + # Call close() on the iterable returned by the WSGI application + # in case of an exception. + if hasattr(self.result, 'close'): + self.result.close() + raise + else: + # We only call close() when no exception is raised, because it + # will set status, result, headers, and environ fields to None. + # See bpo-29183 for more details. self.close() diff --git a/Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst b/Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst new file mode 100644 index 00000000000000..1d19f191eeded5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst @@ -0,0 +1,3 @@ +Fix double exceptions in :class:`wsgiref.handlers.BaseHandler` by calling +its :meth:`~wsgiref.handlers.BaseHandler.close` method only when no +exception is raised. From 5c08ce9bf712acbb3f05a3a57baf51fcb534cdf0 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 19 May 2019 17:51:56 +0100 Subject: [PATCH 018/441] bpo-36957: Speed up math.isqrt (#13405) * Add math.isqrt function computing the integer square root. * Code cleanup: remove redundant comments, rename some variables. * Tighten up code a bit more; use Py_XDECREF to simplify error handling. * Update Modules/mathmodule.c Co-Authored-By: Serhiy Storchaka * Update Modules/mathmodule.c Use real argument clinic type instead of an alias Co-Authored-By: Serhiy Storchaka * Add proof sketch * Updates from review. * Correct and expand documentation. * Fix bad reference handling on error; make some variables block-local; other tidying. * Style and consistency fixes. * Add missing error check; don't try to DECREF a NULL a * Simplify some error returns. * Another two test cases: - clarify that floats are rejected even if they happen to be squares of small integers - TypeError beats ValueError for a negative float * Add fast path for small inputs. Needs tests. * Speed up isqrt for n >= 2**64 as well; add extra tests. * Reduce number of test-cases to avoid dominating the run-time of test_math. * Don't perform unnecessary extra iterations when computing c_bit_length. * Abstract common uint64_t code out into a separate function. * Cleanup. * Add a missing Py_DECREF in an error branch. More cleanup. * Update Modules/mathmodule.c Add missing `static` declaration to helper function. Co-Authored-By: Serhiy Storchaka * Add missing backtick. --- Lib/test/test_math.py | 1 + Modules/mathmodule.c | 64 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index a11a3447856402..853a0e62f82351 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -917,6 +917,7 @@ def testIsqrt(self): test_values = ( list(range(1000)) + list(range(10**6 - 1000, 10**6 + 1000)) + + [2**e + i for e in range(60, 200) for i in range(-40, 40)] + [3**9999, 10**5001] ) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 7a0044a9fcf0b9..a153e984ca59f2 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1620,6 +1620,22 @@ completes the proof sketch. */ + +/* Approximate square root of a large 64-bit integer. + + Given `n` satisfying `2**62 <= n < 2**64`, return `a` + satisfying `(a - 1)**2 < n < (a + 1)**2`. */ + +static uint64_t +_approximate_isqrt(uint64_t n) +{ + uint32_t u = 1U + (n >> 62); + u = (u << 1) + (n >> 59) / u; + u = (u << 3) + (n >> 53) / u; + u = (u << 7) + (n >> 41) / u; + return (u << 15) + (n >> 17) / u; +} + /*[clinic input] math.isqrt @@ -1633,8 +1649,9 @@ static PyObject * math_isqrt(PyObject *module, PyObject *n) /*[clinic end generated code: output=35a6f7f980beab26 input=5b6e7ae4fa6c43d6]*/ { - int a_too_large, s; + int a_too_large, c_bit_length; size_t c, d; + uint64_t m, u; PyObject *a = NULL, *b; n = PyNumber_Index(n); @@ -1653,24 +1670,55 @@ math_isqrt(PyObject *module, PyObject *n) return PyLong_FromLong(0); } + /* c = (n.bit_length() - 1) // 2 */ c = _PyLong_NumBits(n); if (c == (size_t)(-1)) { goto error; } c = (c - 1U) / 2U; - /* s = c.bit_length() */ - s = 0; - while ((c >> s) > 0) { - ++s; + /* Fast path: if c <= 31 then n < 2**64 and we can compute directly with a + fast, almost branch-free algorithm. In the final correction, we use `u*u + - 1 >= m` instead of the simpler `u*u > m` in order to get the correct + result in the corner case where `u=2**32`. */ + if (c <= 31U) { + m = (uint64_t)PyLong_AsUnsignedLongLong(n); + Py_DECREF(n); + if (m == (uint64_t)(-1) && PyErr_Occurred()) { + return NULL; + } + u = _approximate_isqrt(m << (62U - 2U*c)) >> (31U - c); + u -= u * u - 1U >= m; + return PyLong_FromUnsignedLongLong((unsigned long long)u); } - a = PyLong_FromLong(1); + /* Slow path: n >= 2**64. We perform the first five iterations in C integer + arithmetic, then switch to using Python long integers. */ + + /* From n >= 2**64 it follows that c.bit_length() >= 6. */ + c_bit_length = 6; + while ((c >> c_bit_length) > 0U) { + ++c_bit_length; + } + + /* Initialise d and a. */ + d = c >> (c_bit_length - 5); + b = _PyLong_Rshift(n, 2U*c - 62U); + if (b == NULL) { + goto error; + } + m = (uint64_t)PyLong_AsUnsignedLongLong(b); + Py_DECREF(b); + if (m == (uint64_t)(-1) && PyErr_Occurred()) { + goto error; + } + u = _approximate_isqrt(m) >> (31U - d); + a = PyLong_FromUnsignedLongLong((unsigned long long)u); if (a == NULL) { goto error; } - d = 0; - while (--s >= 0) { + + for (int s = c_bit_length - 6; s >= 0; --s) { PyObject *q; size_t e = d; From 287b84de939db47aa8c6f30734ceb8aba9d1db29 Mon Sep 17 00:00:00 2001 From: Xtreak Date: Mon, 20 May 2019 03:22:20 +0530 Subject: [PATCH 019/441] bpo-34580: Update sqlite3 examples to call close() explicitly (GH-9079) The sqlit3.Connection object doesn't call its close() method when it's used as a context manager. --- Doc/includes/sqlite3/adapter_datetime.py | 2 ++ Doc/includes/sqlite3/adapter_point_1.py | 2 ++ Doc/includes/sqlite3/adapter_point_2.py | 2 ++ Doc/includes/sqlite3/connect_db_1.py | 3 --- Doc/includes/sqlite3/connect_db_2.py | 3 --- Doc/includes/sqlite3/countcursors.py | 2 ++ Doc/includes/sqlite3/ctx_manager.py | 4 ++++ Doc/includes/sqlite3/execsql_fetchonerow.py | 2 ++ Doc/includes/sqlite3/execsql_printall_1.py | 2 ++ Doc/includes/sqlite3/execute_1.py | 2 ++ Doc/includes/sqlite3/execute_3.py | 12 ------------ Doc/includes/sqlite3/executemany_1.py | 2 ++ Doc/includes/sqlite3/executemany_2.py | 2 ++ Doc/includes/sqlite3/executescript.py | 1 + Doc/includes/sqlite3/insert_more_people.py | 2 ++ Doc/includes/sqlite3/load_extension.py | 2 ++ Doc/includes/sqlite3/md5func.py | 2 ++ Doc/includes/sqlite3/mysumaggr.py | 2 ++ Doc/includes/sqlite3/parse_colnames.py | 2 ++ Doc/includes/sqlite3/pysqlite_datetime.py | 2 ++ Doc/includes/sqlite3/row_factory.py | 2 ++ Doc/includes/sqlite3/rowclass.py | 2 ++ Doc/includes/sqlite3/shortcut_methods.py | 4 ++++ Doc/includes/sqlite3/simple_tableprinter.py | 2 ++ Doc/includes/sqlite3/text_factory.py | 2 ++ Doc/library/sqlite3.rst | 6 +++++- 26 files changed, 52 insertions(+), 19 deletions(-) delete mode 100644 Doc/includes/sqlite3/connect_db_1.py delete mode 100644 Doc/includes/sqlite3/connect_db_2.py delete mode 100644 Doc/includes/sqlite3/execute_3.py diff --git a/Doc/includes/sqlite3/adapter_datetime.py b/Doc/includes/sqlite3/adapter_datetime.py index be33395100c325..d5221d80c35c8a 100644 --- a/Doc/includes/sqlite3/adapter_datetime.py +++ b/Doc/includes/sqlite3/adapter_datetime.py @@ -13,3 +13,5 @@ def adapt_datetime(ts): now = datetime.datetime.now() cur.execute("select ?", (now,)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/adapter_point_1.py b/Doc/includes/sqlite3/adapter_point_1.py index 6b1af8415648a4..77daf8f16d227b 100644 --- a/Doc/includes/sqlite3/adapter_point_1.py +++ b/Doc/includes/sqlite3/adapter_point_1.py @@ -14,3 +14,5 @@ def __conform__(self, protocol): p = Point(4.0, -3.2) cur.execute("select ?", (p,)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/adapter_point_2.py b/Doc/includes/sqlite3/adapter_point_2.py index d670700f0491b1..cb86331692b61d 100644 --- a/Doc/includes/sqlite3/adapter_point_2.py +++ b/Doc/includes/sqlite3/adapter_point_2.py @@ -15,3 +15,5 @@ def adapt_point(point): p = Point(4.0, -3.2) cur.execute("select ?", (p,)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/connect_db_1.py b/Doc/includes/sqlite3/connect_db_1.py deleted file mode 100644 index 1b975232865aef..00000000000000 --- a/Doc/includes/sqlite3/connect_db_1.py +++ /dev/null @@ -1,3 +0,0 @@ -import sqlite3 - -con = sqlite3.connect("mydb") diff --git a/Doc/includes/sqlite3/connect_db_2.py b/Doc/includes/sqlite3/connect_db_2.py deleted file mode 100644 index f9728b36135ed7..00000000000000 --- a/Doc/includes/sqlite3/connect_db_2.py +++ /dev/null @@ -1,3 +0,0 @@ -import sqlite3 - -con = sqlite3.connect(":memory:") diff --git a/Doc/includes/sqlite3/countcursors.py b/Doc/includes/sqlite3/countcursors.py index ef3e70a2a9cfc5..112f47703a2ff4 100644 --- a/Doc/includes/sqlite3/countcursors.py +++ b/Doc/includes/sqlite3/countcursors.py @@ -13,3 +13,5 @@ def cursor(self, *args, **kwargs): cur1 = con.cursor() cur2 = con.cursor() print(con.numcursors) + +con.close() diff --git a/Doc/includes/sqlite3/ctx_manager.py b/Doc/includes/sqlite3/ctx_manager.py index 7af4ad1ecfbcca..6db77d45046e1f 100644 --- a/Doc/includes/sqlite3/ctx_manager.py +++ b/Doc/includes/sqlite3/ctx_manager.py @@ -14,3 +14,7 @@ con.execute("insert into person(firstname) values (?)", ("Joe",)) except sqlite3.IntegrityError: print("couldn't add Joe twice") + +# Connection object used as context manager only commits or rollbacks transactions, +# so the connection object should be closed manually +con.close() diff --git a/Doc/includes/sqlite3/execsql_fetchonerow.py b/Doc/includes/sqlite3/execsql_fetchonerow.py index 078873bfc979a9..115bcb50c7c754 100644 --- a/Doc/includes/sqlite3/execsql_fetchonerow.py +++ b/Doc/includes/sqlite3/execsql_fetchonerow.py @@ -15,3 +15,5 @@ cur.execute(SELECT) for row in cur: print('%s is %d years old.' % (row[0], row[1])) + +con.close() diff --git a/Doc/includes/sqlite3/execsql_printall_1.py b/Doc/includes/sqlite3/execsql_printall_1.py index a4ce5c528149c5..19306e6e3ca7d1 100644 --- a/Doc/includes/sqlite3/execsql_printall_1.py +++ b/Doc/includes/sqlite3/execsql_printall_1.py @@ -11,3 +11,5 @@ # Retrieve all rows as a sequence and print that sequence: print(cur.fetchall()) + +con.close() diff --git a/Doc/includes/sqlite3/execute_1.py b/Doc/includes/sqlite3/execute_1.py index f864a8984e4e90..3466b1265a5bf2 100644 --- a/Doc/includes/sqlite3/execute_1.py +++ b/Doc/includes/sqlite3/execute_1.py @@ -14,3 +14,5 @@ cur.execute("select * from people where name_last=:who and age=:age", {"who": who, "age": age}) print(cur.fetchone()) + +con.close() diff --git a/Doc/includes/sqlite3/execute_3.py b/Doc/includes/sqlite3/execute_3.py deleted file mode 100644 index 0353683fc70476..00000000000000 --- a/Doc/includes/sqlite3/execute_3.py +++ /dev/null @@ -1,12 +0,0 @@ -import sqlite3 - -con = sqlite3.connect("mydb") - -cur = con.cursor() - -who = "Yeltsin" -age = 72 - -cur.execute("select name_last, age from people where name_last=:who and age=:age", - locals()) -print(cur.fetchone()) diff --git a/Doc/includes/sqlite3/executemany_1.py b/Doc/includes/sqlite3/executemany_1.py index efae10637c7e8f..edf6f8b7ebe61a 100644 --- a/Doc/includes/sqlite3/executemany_1.py +++ b/Doc/includes/sqlite3/executemany_1.py @@ -22,3 +22,5 @@ def __next__(self): cur.execute("select c from characters") print(cur.fetchall()) + +con.close() diff --git a/Doc/includes/sqlite3/executemany_2.py b/Doc/includes/sqlite3/executemany_2.py index 527358ebc28e1f..02a594c861e15b 100644 --- a/Doc/includes/sqlite3/executemany_2.py +++ b/Doc/includes/sqlite3/executemany_2.py @@ -13,3 +13,5 @@ def char_generator(): cur.execute("select c from characters") print(cur.fetchall()) + +con.close() diff --git a/Doc/includes/sqlite3/executescript.py b/Doc/includes/sqlite3/executescript.py index 7e5358178d4c0a..aea8943fbee598 100644 --- a/Doc/includes/sqlite3/executescript.py +++ b/Doc/includes/sqlite3/executescript.py @@ -22,3 +22,4 @@ 1987 ); """) +con.close() diff --git a/Doc/includes/sqlite3/insert_more_people.py b/Doc/includes/sqlite3/insert_more_people.py index edbc79e7e5b6cc..10cf937243f6da 100644 --- a/Doc/includes/sqlite3/insert_more_people.py +++ b/Doc/includes/sqlite3/insert_more_people.py @@ -14,3 +14,5 @@ # The changes will not be saved unless the transaction is committed explicitly: con.commit() + +con.close() diff --git a/Doc/includes/sqlite3/load_extension.py b/Doc/includes/sqlite3/load_extension.py index b997c70668ace4..624cfe262f38b3 100644 --- a/Doc/includes/sqlite3/load_extension.py +++ b/Doc/includes/sqlite3/load_extension.py @@ -24,3 +24,5 @@ """) for row in con.execute("select rowid, name, ingredients from recipe where name match 'pie'"): print(row) + +con.close() diff --git a/Doc/includes/sqlite3/md5func.py b/Doc/includes/sqlite3/md5func.py index 0056b2d6ce84ef..16dc348bf001e2 100644 --- a/Doc/includes/sqlite3/md5func.py +++ b/Doc/includes/sqlite3/md5func.py @@ -9,3 +9,5 @@ def md5sum(t): cur = con.cursor() cur.execute("select md5(?)", (b"foo",)) print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/mysumaggr.py b/Doc/includes/sqlite3/mysumaggr.py index d2dfd2c0b98d3b..11f96395b6c485 100644 --- a/Doc/includes/sqlite3/mysumaggr.py +++ b/Doc/includes/sqlite3/mysumaggr.py @@ -18,3 +18,5 @@ def finalize(self): cur.execute("insert into test(i) values (2)") cur.execute("select mysum(i) from test") print(cur.fetchone()[0]) + +con.close() diff --git a/Doc/includes/sqlite3/parse_colnames.py b/Doc/includes/sqlite3/parse_colnames.py index cc68c76459ecea..5f01dbfe1cb524 100644 --- a/Doc/includes/sqlite3/parse_colnames.py +++ b/Doc/includes/sqlite3/parse_colnames.py @@ -6,3 +6,5 @@ cur.execute('select ? as "x [timestamp]"', (datetime.datetime.now(),)) dt = cur.fetchone()[0] print(dt, type(dt)) + +con.close() diff --git a/Doc/includes/sqlite3/pysqlite_datetime.py b/Doc/includes/sqlite3/pysqlite_datetime.py index 68d49358a578b3..5d843f906b3062 100644 --- a/Doc/includes/sqlite3/pysqlite_datetime.py +++ b/Doc/includes/sqlite3/pysqlite_datetime.py @@ -18,3 +18,5 @@ row = cur.fetchone() print("current_date", row[0], type(row[0])) print("current_timestamp", row[1], type(row[1])) + +con.close() diff --git a/Doc/includes/sqlite3/row_factory.py b/Doc/includes/sqlite3/row_factory.py index e436ffc6c80225..9de6e7b1b9052a 100644 --- a/Doc/includes/sqlite3/row_factory.py +++ b/Doc/includes/sqlite3/row_factory.py @@ -11,3 +11,5 @@ def dict_factory(cursor, row): cur = con.cursor() cur.execute("select 1 as a") print(cur.fetchone()["a"]) + +con.close() diff --git a/Doc/includes/sqlite3/rowclass.py b/Doc/includes/sqlite3/rowclass.py index 92b5ad60cb5791..fc60287069a854 100644 --- a/Doc/includes/sqlite3/rowclass.py +++ b/Doc/includes/sqlite3/rowclass.py @@ -10,3 +10,5 @@ assert row["name"] == row["nAmE"] assert row[1] == row["age"] assert row[1] == row["AgE"] + +con.close() diff --git a/Doc/includes/sqlite3/shortcut_methods.py b/Doc/includes/sqlite3/shortcut_methods.py index 71600d4f60c55e..98a39411495cba 100644 --- a/Doc/includes/sqlite3/shortcut_methods.py +++ b/Doc/includes/sqlite3/shortcut_methods.py @@ -18,3 +18,7 @@ print(row) print("I just deleted", con.execute("delete from person").rowcount, "rows") + +# close is not a shortcut method and it's not called automatically, +# so the connection object should be closed manually +con.close() diff --git a/Doc/includes/sqlite3/simple_tableprinter.py b/Doc/includes/sqlite3/simple_tableprinter.py index 231d8726cd436e..148a1707f948bc 100644 --- a/Doc/includes/sqlite3/simple_tableprinter.py +++ b/Doc/includes/sqlite3/simple_tableprinter.py @@ -24,3 +24,5 @@ print(fieldValue.ljust(FIELD_MAX_WIDTH), end=' ') print() # Finish the row with a newline. + +con.close() diff --git a/Doc/includes/sqlite3/text_factory.py b/Doc/includes/sqlite3/text_factory.py index 5f96cdb58da1ab..a857a155cdd4ff 100644 --- a/Doc/includes/sqlite3/text_factory.py +++ b/Doc/includes/sqlite3/text_factory.py @@ -25,3 +25,5 @@ cur.execute("select ?", ("bar",)) row = cur.fetchone() assert row[0] == "barfoo" + +con.close() diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 37087ac5af492a..20fca54aab144f 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -537,6 +537,7 @@ Connection Objects with open('dump.sql', 'w') as f: for line in con.iterdump(): f.write('%s\n' % line) + con.close() .. method:: backup(target, *, pages=0, progress=None, name="main", sleep=0.250) @@ -573,8 +574,11 @@ Connection Objects print(f'Copied {total-remaining} of {total} pages...') con = sqlite3.connect('existing_db.db') - with sqlite3.connect('backup.db') as bck: + bck = sqlite3.connect('backup.db') + with bck: con.backup(bck, pages=1, progress=progress) + bck.close() + con.close() Example 2, copy an existing database into a transient copy:: From d673810b9d9df6fbd29f5b7db3973d5adae10fd3 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Mon, 20 May 2019 00:11:21 +0200 Subject: [PATCH 020/441] bpo-35252: Remove FIXME from test_functools (GH-10551) --- Lib/functools.py | 8 +++++--- Lib/test/test_functools.py | 11 +++++------ .../Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst diff --git a/Lib/functools.py b/Lib/functools.py index 28d9f6f75fdb8b..c863341eec5f21 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -861,9 +861,11 @@ def register(cls, func=None): # only import typing if annotation parsing is necessary from typing import get_type_hints argname, cls = next(iter(get_type_hints(func).items())) - assert isinstance(cls, type), ( - f"Invalid annotation for {argname!r}. {cls!r} is not a class." - ) + if not isinstance(cls, type): + raise TypeError( + f"Invalid annotation for {argname!r}. " + f"{cls!r} is not a class." + ) registry[cls] = func if cache_token is None and hasattr(cls, '__abstractmethods__'): cache_token = get_cache_token() diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 85c65d18326067..b89d77967a0df2 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2355,9 +2355,6 @@ def _(arg): )) self.assertTrue(str(exc.exception).endswith(msg_suffix)) - # FIXME: The following will only work after PEP 560 is implemented. - return - with self.assertRaises(TypeError) as exc: @i.register def _(arg: typing.Iterable[str]): @@ -2366,10 +2363,12 @@ def _(arg: typing.Iterable[str]): # types from `typing`. Instead, annotate with regular types # or ABCs. return "I annotated with a generic collection" - self.assertTrue(str(exc.exception).startswith(msg_prefix + - "._" + self.assertTrue(str(exc.exception).startswith( + "Invalid annotation for 'arg'." + )) + self.assertTrue(str(exc.exception).endswith( + 'typing.Iterable[str] is not a class.' )) - self.assertTrue(str(exc.exception).endswith(msg_suffix)) def test_invalid_positional_argument(self): @functools.singledispatch diff --git a/Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst b/Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst new file mode 100644 index 00000000000000..c8f3e7d5f5fb18 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst @@ -0,0 +1 @@ +Throw a TypeError instead of an AssertionError when using an invalid type annotation with singledispatch. From ed48866c55b8e4ee14faa8b5ad97819e8e74c98b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 20 May 2019 00:14:57 +0200 Subject: [PATCH 021/441] bpo-35134: Split traceback.h header (GH-13430) Add new Include/cpython/traceback.h and Include/internal/traceback.h header files. --- Include/cpython/traceback.h | 22 +++++++ Include/frameobject.h | 1 - Include/genobject.h | 2 + Include/internal/pycore_traceback.h | 92 +++++++++++++++++++++++++++ Include/traceback.h | 99 ++--------------------------- Modules/_tracemalloc.c | 1 + Modules/faulthandler.c | 1 + Python/pylifecycle.c | 1 + 8 files changed, 123 insertions(+), 96 deletions(-) create mode 100644 Include/cpython/traceback.h create mode 100644 Include/internal/pycore_traceback.h diff --git a/Include/cpython/traceback.h b/Include/cpython/traceback.h new file mode 100644 index 00000000000000..746097daaf9400 --- /dev/null +++ b/Include/cpython/traceback.h @@ -0,0 +1,22 @@ +#ifndef Py_CPYTHON_TRACEBACK_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _traceback { + PyObject_HEAD + struct _traceback *tb_next; + struct _frame *tb_frame; + int tb_lasti; + int tb_lineno; +} PyTracebackObject; + +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); +PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); + +#ifdef __cplusplus +} +#endif diff --git a/Include/frameobject.h b/Include/frameobject.h index a95baf8867a360..3bad86a66f752d 100644 --- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -1,4 +1,3 @@ - /* Frame object interface */ #ifndef Py_LIMITED_API diff --git a/Include/genobject.h b/Include/genobject.h index 16b983339cc649..6755963f332f76 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -8,6 +8,8 @@ extern "C" { #endif +#include "pystate.h" /* _PyErr_StackItem */ + struct _frame; /* Avoid including frameobject.h */ /* _PyGenObject_HEAD defines the initial segment of generator diff --git a/Include/internal/pycore_traceback.h b/Include/internal/pycore_traceback.h new file mode 100644 index 00000000000000..a96199bda5f9f3 --- /dev/null +++ b/Include/internal/pycore_traceback.h @@ -0,0 +1,92 @@ +#ifndef Py_INTERNAL_TRACEBACK_H +#define Py_INTERNAL_TRACEBACK_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pystate.h" /* PyInterpreterState */ + +/* Write the Python traceback into the file 'fd'. For example: + + Traceback (most recent call first): + File "xxx", line xxx in + File "xxx", line xxx in + ... + File "xxx", line xxx in + + This function is written for debug purpose only, to dump the traceback in + the worst case: after a segmentation fault, at fatal error, etc. That's why, + it is very limited. Strings are truncated to 100 characters and encoded to + ASCII with backslashreplace. It doesn't write the source code, only the + function name, filename and line number of each frame. Write only the first + 100 frames: if the traceback is truncated, write the line " ...". + + This function is signal safe. */ + +PyAPI_FUNC(void) _Py_DumpTraceback( + int fd, + PyThreadState *tstate); + +/* Write the traceback of all threads into the file 'fd'. current_thread can be + NULL. + + Return NULL on success, or an error message on error. + + This function is written for debug purpose only. It calls + _Py_DumpTraceback() for each thread, and so has the same limitations. It + only write the traceback of the first 100 threads: write "..." if there are + more threads. + + If current_tstate is NULL, the function tries to get the Python thread state + of the current thread. It is not an error if the function is unable to get + the current Python thread state. + + If interp is NULL, the function tries to get the interpreter state from + the current Python thread state, or from + _PyGILState_GetInterpreterStateUnsafe() in last resort. + + It is better to pass NULL to interp and current_tstate, the function tries + different options to retrieve these informations. + + This function is signal safe. */ + +PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( + int fd, + PyInterpreterState *interp, + PyThreadState *current_tstate); + +/* Write a Unicode object into the file descriptor fd. Encode the string to + ASCII using the backslashreplace error handler. + + Do nothing if text is not a Unicode object. The function accepts Unicode + string which is not ready (PyUnicode_WCHAR_KIND). + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text); + +/* Format an integer as decimal into the file descriptor fd. + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpDecimal( + int fd, + unsigned long value); + +/* Format an integer as hexadecimal into the file descriptor fd with at least + width digits. + + The maximum width is sizeof(unsigned long)*2 digits. + + This function is signal safe. */ +PyAPI_FUNC(void) _Py_DumpHexadecimal( + int fd, + unsigned long value, + Py_ssize_t width); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TRACEBACK_H */ diff --git a/Include/traceback.h b/Include/traceback.h index b5874100f477a5..b451927fafa3a8 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -1,117 +1,26 @@ - #ifndef Py_TRACEBACK_H #define Py_TRACEBACK_H #ifdef __cplusplus extern "C" { #endif -#include "pystate.h" - struct _frame; /* Traceback interface */ -#ifndef Py_LIMITED_API -typedef struct _traceback { - PyObject_HEAD - struct _traceback *tb_next; - struct _frame *tb_frame; - int tb_lasti; - int tb_lineno; -} PyTracebackObject; -#endif PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); -PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); -#endif /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; #define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type) -#ifndef Py_LIMITED_API -/* Write the Python traceback into the file 'fd'. For example: - - Traceback (most recent call first): - File "xxx", line xxx in - File "xxx", line xxx in - ... - File "xxx", line xxx in - - This function is written for debug purpose only, to dump the traceback in - the worst case: after a segmentation fault, at fatal error, etc. That's why, - it is very limited. Strings are truncated to 100 characters and encoded to - ASCII with backslashreplace. It doesn't write the source code, only the - function name, filename and line number of each frame. Write only the first - 100 frames: if the traceback is truncated, write the line " ...". - - This function is signal safe. */ - -PyAPI_FUNC(void) _Py_DumpTraceback( - int fd, - PyThreadState *tstate); - -/* Write the traceback of all threads into the file 'fd'. current_thread can be - NULL. - - Return NULL on success, or an error message on error. - - This function is written for debug purpose only. It calls - _Py_DumpTraceback() for each thread, and so has the same limitations. It - only write the traceback of the first 100 threads: write "..." if there are - more threads. - - If current_tstate is NULL, the function tries to get the Python thread state - of the current thread. It is not an error if the function is unable to get - the current Python thread state. - - If interp is NULL, the function tries to get the interpreter state from - the current Python thread state, or from - _PyGILState_GetInterpreterStateUnsafe() in last resort. - - It is better to pass NULL to interp and current_tstate, the function tries - different options to retrieve these informations. - - This function is signal safe. */ - -PyAPI_FUNC(const char*) _Py_DumpTracebackThreads( - int fd, - PyInterpreterState *interp, - PyThreadState *current_tstate); -#endif /* !Py_LIMITED_API */ #ifndef Py_LIMITED_API - -/* Write a Unicode object into the file descriptor fd. Encode the string to - ASCII using the backslashreplace error handler. - - Do nothing if text is not a Unicode object. The function accepts Unicode - string which is not ready (PyUnicode_WCHAR_KIND). - - This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text); - -/* Format an integer as decimal into the file descriptor fd. - - This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpDecimal( - int fd, - unsigned long value); - -/* Format an integer as hexadecimal into the file descriptor fd with at least - width digits. - - The maximum width is sizeof(unsigned long)*2 digits. - - This function is signal safe. */ -PyAPI_FUNC(void) _Py_DumpHexadecimal( - int fd, - unsigned long value, - Py_ssize_t width); - -#endif /* !Py_LIMITED_API */ +# define Py_CPYTHON_TRACEBACK_H +# include "cpython/traceback.h" +# undef Py_CPYTHON_TRACEBACK_H +#endif #ifdef __cplusplus } diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index c5d5671032ebf1..ee32ac29b7eea2 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_traceback.h" #include "hashtable.h" #include "frameobject.h" #include "pythread.h" diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 2083a03198febd..aa466c46ccff12 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1,5 +1,6 @@ #include "Python.h" #include "pycore_coreconfig.h" +#include "pycore_traceback.h" #include "pythread.h" #include #include diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index d29b293b79eb44..0781dc8046b106 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -13,6 +13,7 @@ #include "pycore_pylifecycle.h" #include "pycore_pymem.h" #include "pycore_pystate.h" +#include "pycore_traceback.h" #include "grammar.h" #include "node.h" #include "token.h" From fd1e0e93b15af018184476ea0b3af0eabef37d89 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 20 May 2019 02:22:32 +0200 Subject: [PATCH 022/441] bpo-35134: Register new traceback.h header files (GH-13431) Add new cpython/traceback.h and pycore_traceback.h header files to Makefile.pre.in and PCbuild/ project. --- Makefile.pre.in | 2 ++ PCbuild/pythoncore.vcxproj | 2 ++ PCbuild/pythoncore.vcxproj.filters | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/Makefile.pre.in b/Makefile.pre.in index 4924dedc357c72..9f70cd515ebaba 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1059,6 +1059,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/pylifecycle.h \ $(srcdir)/Include/cpython/pymem.h \ $(srcdir)/Include/cpython/pystate.h \ + $(srcdir)/Include/cpython/traceback.h \ $(srcdir)/Include/cpython/tupleobject.h \ $(srcdir)/Include/cpython/unicodeobject.h \ \ @@ -1078,6 +1079,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ $(srcdir)/Include/internal/pycore_pymem.h \ $(srcdir)/Include/internal/pycore_pystate.h \ + $(srcdir)/Include/internal/pycore_traceback.h \ $(srcdir)/Include/internal/pycore_tupleobject.h \ $(srcdir)/Include/internal/pycore_warnings.h \ $(DTRACE_HEADERS) diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index a71fce6bb60977..df57adcfd6050c 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -135,6 +135,7 @@ + @@ -169,6 +170,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 9134646567954e..5515d9bedeb166 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -108,6 +108,9 @@ Include + + Include + Include @@ -210,6 +213,9 @@ Include + + Include + Include From 53d378c81286644138415cb56da52a7351e1a477 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sun, 19 May 2019 18:26:35 -0600 Subject: [PATCH 023/441] closes bpo-36951: Correct some types in the type_members struct in typeobject.c. (GH-13403) --- Objects/typeobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index bfbd320b1f54d8..c086f182aa958a 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -369,11 +369,11 @@ assign_version_tag(PyTypeObject *type) static PyMemberDef type_members[] = { {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY}, - {"__flags__", T_LONG, offsetof(PyTypeObject, tp_flags), READONLY}, - {"__weakrefoffset__", T_LONG, + {"__flags__", T_ULONG, offsetof(PyTypeObject, tp_flags), READONLY}, + {"__weakrefoffset__", T_PYSSIZET, offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY}, - {"__dictoffset__", T_LONG, + {"__dictoffset__", T_PYSSIZET, offsetof(PyTypeObject, tp_dictoffset), READONLY}, {"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY}, {0} From 6d965b39b7a486dd9e96a60b19ee92382d668299 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 19 May 2019 22:52:22 -0400 Subject: [PATCH 024/441] bpo-36958: In IDLE, print exit message (GH-13435) Print any argument other than None or int passed to SystemExit or sys.exit(). --- Doc/library/idle.rst | 3 +++ Lib/idlelib/NEWS.txt | 6 ++++++ Lib/idlelib/help.html | 4 +++- Lib/idlelib/run.py | 11 ++++++----- .../IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst | 2 ++ 5 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index f511d64b550be6..c51cf19e97bd05 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -700,6 +700,9 @@ If ``sys`` is reset by user code, such as with ``importlib.reload(sys)``, IDLE's changes are lost and input from the keyboard and output to the screen will not work correctly. +When user code raises SystemExit either directly or by calling sys.exit, IDLE +returns to a Shell prompt instead of exiting. + User output in Shell ^^^^^^^^^^^^^^^^^^^^ diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index be855bc4671852..3f19ce73739630 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,12 @@ Released on 2019-10-20? ====================================== +bpo-36958: Print any argument other than None or int passed to +SystemExit or sys.exit(). + +bpo-36807: When saving a file, call file.flush() and os.fsync() +so bits are flushed to e.g. a USB drive. + bpo-36429: Fix starting IDLE with pyshell. Add idlelib.pyshell alias at top; remove pyshell alias at bottom. Remove obsolete __name__=='__main__' command. diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 56f9ca503daac2..bc287d637ab738 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -659,6 +659,8 @@

Running user codesys is reset by user code, such as with importlib.reload(sys), IDLE’s changes are lost and input from the keyboard and output to the screen will not work correctly.

+

When user code raises SystemExit either directly or by calling sys.exit, IDLE +returns to a Shell prompt instead of exiting.

User output in Shell

@@ -941,7 +943,7 @@

Navigation



- Last updated on May 16, 2019. + Last updated on May 19, 2019. Found a bug?
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 6fa373f2584c27..b4a2b54a33c850 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -474,15 +474,16 @@ def runcode(self, code): exec(code, self.locals) finally: interruptable = False - except SystemExit: - # Scripts that raise SystemExit should just - # return to the interactive prompt - pass + except SystemExit as e: + if e.args: # SystemExit called with an argument. + ob = e.args[0] + if not isinstance(ob, (type(None), int)): + print('SystemExit: ' + str(ob), file=sys.stderr) + # Return to the interactive prompt. except: self.usr_exc_info = sys.exc_info() if quitting: exit() - # even print a user code SystemExit exception, continue print_exception() jit = self.rpchandler.console.getvar("<>") if jit: diff --git a/Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst b/Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst new file mode 100644 index 00000000000000..c5a675d6781ae9 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst @@ -0,0 +1,2 @@ +Print any argument other than None or int passed to SystemExit or +sys.exit(). From 6d1c46746e17367caf8a24623cb5c9a9c4e3e036 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 20 May 2019 11:02:00 +0200 Subject: [PATCH 025/441] bpo-36763: Fix Python preinitialization (GH-13432) * Add _PyPreConfig.parse_argv * Add _PyCoreConfig._config_init field and _PyCoreConfigInitEnum enum type * Initialization functions: reject preconfig=NULL and config=NULL * Add config parameter to _PyCoreConfig_DecodeLocaleErr(): pass config->argv to _Py_PreInitializeFromPyArgv(), to parse config command line arguments in preinitialization. * Add config parameter to _PyCoreConfig_SetString(). It now preinitializes Python. * _PyCoreConfig_SetPyArgv() now also preinitializes Python for wide argv * Fix _Py_PreInitializeFromCoreConfig(): don't pass args to _Py_PreInitializeFromPyArgv() if config.parse_argv=0. * Use "char * const *" and "wchar_t * const *" types for 'argv' parameters and _PyArgv.argv. * Add unit test on preinitialization from argv. * _PyPreConfig.allocator type becomes int * Add _PyPreConfig_InitFromPreConfig() and _PyPreConfig_InitFromCoreConfig() helper functions --- Include/cpython/coreconfig.h | 22 ++- Include/cpython/pylifecycle.h | 4 +- Include/internal/pycore_coreconfig.h | 10 +- Lib/test/test_embed.py | 96 +++++++--- Programs/_testembed.c | 262 +++++++++++++++++++++++---- Python/coreconfig.c | 123 +++++++------ Python/preconfig.c | 80 +++++--- Python/pylifecycle.c | 57 ++++-- 8 files changed, 476 insertions(+), 178 deletions(-) diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index a71f16171b7334..decfb70e7345c5 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -44,6 +44,10 @@ typedef struct { int _config_version; /* Internal configuration version, used for ABI compatibility */ + /* Parse _Py_PreInitializeFromArgs() arguments? + See _PyCoreConfig.parse_argv */ + int parse_argv; + /* If greater than 0, enable isolated mode: sys.path contains neither the script's directory nor the user's site-packages directory. @@ -111,8 +115,9 @@ typedef struct { int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */ - /* Memory allocator: PYTHONMALLOC env var */ - PyMemAllocatorName allocator; + /* Memory allocator: PYTHONMALLOC env var. + See PyMemAllocatorName for valid values. */ + int allocator; } _PyPreConfig; PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config); @@ -121,9 +126,16 @@ PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config); /* --- _PyCoreConfig ---------------------------------------------- */ +typedef enum { + _PyCoreConfig_INIT = 0, + _PyCoreConfig_INIT_PYTHON = 1, + _PyCoreConfig_INIT_ISOLATED = 2 +} _PyCoreConfigInitEnum; + typedef struct { int _config_version; /* Internal configuration version, used for ABI compatibility */ + int _config_init; /* _PyCoreConfigInitEnum value */ int isolated; /* Isolated mode? see _PyPreConfig.isolated */ int use_environment; /* Use environment variables? see _PyPreConfig.use_environment */ @@ -401,19 +413,21 @@ PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config); PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString( + _PyCoreConfig *config, wchar_t **config_str, const wchar_t *str); PyAPI_FUNC(_PyInitError) _PyCoreConfig_DecodeLocale( + _PyCoreConfig *config, wchar_t **config_str, const char *str); PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetArgv( _PyCoreConfig *config, Py_ssize_t argc, - char **argv); + char * const *argv); PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, - wchar_t **argv); + wchar_t * const *argv); #ifdef __cplusplus } diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 8fc809d30d8278..1e1dabe59ff556 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -35,11 +35,11 @@ PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig( PyAPI_FUNC(_PyInitError) _Py_InitializeFromArgs( const _PyCoreConfig *config, Py_ssize_t argc, - char **argv); + char * const *argv); PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs( const _PyCoreConfig *config, Py_ssize_t argc, - wchar_t **argv); + wchar_t * const *argv); PyAPI_FUNC(_PyInitError) _Py_InitializeMain(void); PyAPI_FUNC(int) _Py_RunMain(void); diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index edde7b1d8d8817..324e0b82b90c60 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -63,8 +63,8 @@ PyAPI_FUNC(int) _PyWstrList_Extend(_PyWstrList *list, typedef struct { Py_ssize_t argc; int use_bytes_argv; - char **bytes_argv; - wchar_t **wchar_argv; + char * const *bytes_argv; + wchar_t * const *wchar_argv; } _PyArgv; PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args, @@ -121,6 +121,12 @@ PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline, /* --- _PyPreConfig ----------------------------------------------- */ PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config); +PyAPI_FUNC(void) _PyPreConfig_InitFromCoreConfig( + _PyPreConfig *config, + const _PyCoreConfig *coreconfig); +PyAPI_FUNC(void) _PyPreConfig_InitFromPreConfig( + _PyPreConfig *config, + const _PyPreConfig *config2); PyAPI_FUNC(void) _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2); PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config); diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 5a5419dcfcf57e..5be179a266ba5d 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -17,6 +17,10 @@ PYMEM_ALLOCATOR_DEBUG = 2 PYMEM_ALLOCATOR_MALLOC = 3 +CONFIG_INIT = 0 +CONFIG_INIT_PYTHON = 1 +CONFIG_INIT_ISOLATED = 2 + class EmbeddingTestsMixin: def setUp(self): @@ -280,11 +284,19 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): DEFAULT_PRE_CONFIG = { 'allocator': PYMEM_ALLOCATOR_NOT_SET, + 'parse_argv': 0, 'configure_locale': 1, 'coerce_c_locale': 0, 'coerce_c_locale_warn': 0, 'utf8_mode': 0, } + if MS_WINDOWS: + DEFAULT_PRE_CONFIG.update({ + 'legacy_windows_fs_encoding': 0, + }) + PYTHON_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG, + parse_argv=1, + ) ISOLATED_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG, configure_locale=0, isolated=1, @@ -292,8 +304,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): utf8_mode=0, dev_mode=0, ) - if MS_WINDOWS: - ISOLATED_PRE_CONFIG['legacy_windows_fs_encoding'] = 0 COPY_PRE_CONFIG = [ 'dev_mode', @@ -302,6 +312,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ] DEFAULT_CORE_CONFIG = { + '_config_init': CONFIG_INIT, 'isolated': 0, 'use_environment': 1, 'dev_mode': 0, @@ -365,9 +376,6 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): '_init_main': 1, } if MS_WINDOWS: - DEFAULT_PRE_CONFIG.update({ - 'legacy_windows_fs_encoding': 0, - }) DEFAULT_CORE_CONFIG.update({ 'legacy_windows_stdio': 0, }) @@ -439,13 +447,14 @@ def main_xoptions(self, xoptions_list): def get_expected_config(self, expected_preconfig, expected, env, api, add_path=None): - if api == "python": + if api == CONFIG_INIT_PYTHON: default_config = self.PYTHON_CORE_CONFIG - elif api == "isolated": + elif api == CONFIG_INIT_ISOLATED: default_config = self.ISOLATED_CORE_CONFIG else: default_config = self.DEFAULT_CORE_CONFIG expected = dict(default_config, **expected) + expected['_config_init'] = api code = textwrap.dedent(''' import json @@ -519,9 +528,7 @@ def get_expected_config(self, expected_preconfig, expected, env, api, return expected def check_pre_config(self, config, expected): - pre_config = dict(config['pre_config']) - core_config = dict(config['core_config']) - self.assertEqual(pre_config, expected) + self.assertEqual(config['pre_config'], expected) def check_core_config(self, config, expected): core_config = dict(config['core_config']) @@ -554,7 +561,7 @@ def check_global_config(self, config): self.assertEqual(config['global_config'], expected) def check_config(self, testname, expected_config=None, expected_preconfig=None, - add_path=None, stderr=None, api="default"): + add_path=None, stderr=None, api=CONFIG_INIT): env = dict(os.environ) # Remove PYTHON* environment variables to get deterministic environment for key in list(env): @@ -565,8 +572,10 @@ def check_config(self, testname, expected_config=None, expected_preconfig=None, env['PYTHONCOERCECLOCALE'] = '0' env['PYTHONUTF8'] = '0' - if api == "isolated": + if api == CONFIG_INIT_ISOLATED: default_preconfig = self.ISOLATED_PRE_CONFIG + elif api == CONFIG_INIT_PYTHON: + default_preconfig = self.PYTHON_PRE_CONFIG else: default_preconfig = self.DEFAULT_PRE_CONFIG if expected_preconfig is None: @@ -719,7 +728,38 @@ def test_init_dev_mode(self): 'dev_mode': 1, 'warnoptions': ['default'], } - self.check_config("init_dev_mode", config, preconfig, api="python") + self.check_config("init_dev_mode", config, preconfig, + api=CONFIG_INIT_PYTHON) + + def test_preinit_parse_argv(self): + # Pre-initialize implicitly using argv: make sure that -X dev + # is used to configure the allocation in preinitialization + preconfig = { + 'allocator': PYMEM_ALLOCATOR_DEBUG, + } + config = { + 'argv': ['script.py'], + 'run_filename': 'script.py', + 'dev_mode': 1, + 'faulthandler': 1, + 'warnoptions': ['default'], + 'xoptions': ['dev'], + } + self.check_config("preinit_parse_argv", config, preconfig, + api=CONFIG_INIT_PYTHON) + + def test_preinit_dont_parse_argv(self): + # -X dev must be ignored by isolated preconfiguration + preconfig = { + 'isolated': 0, + } + config = { + 'argv': ["python3", "-E", "-I", + "-X", "dev", "-X", "utf8", "script.py"], + 'isolated': 0, + } + self.check_config("preinit_dont_parse_argv", config, preconfig, + api=CONFIG_INIT_ISOLATED) def test_init_isolated_flag(self): config = { @@ -727,7 +767,7 @@ def test_init_isolated_flag(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("init_isolated_flag", config, api="python") + self.check_config("init_isolated_flag", config, api=CONFIG_INIT_PYTHON) def test_preinit_isolated1(self): # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set @@ -747,25 +787,30 @@ def test_preinit_isolated2(self): } self.check_config("preinit_isolated2", config) + def test_preinit_isolated_config(self): + self.check_config("preinit_isolated_config", api=CONFIG_INIT_ISOLATED) + def test_init_isolated_config(self): - self.check_config("init_isolated_config", api="isolated") + self.check_config("init_isolated_config", api=CONFIG_INIT_ISOLATED) def test_init_python_config(self): - self.check_config("init_python_config", api="python") + self.check_config("init_python_config", api=CONFIG_INIT_PYTHON) def test_init_dont_configure_locale(self): # _PyPreConfig.configure_locale=0 preconfig = { 'configure_locale': 0, } - self.check_config("init_dont_configure_locale", {}, preconfig, api="python") + self.check_config("init_dont_configure_locale", {}, preconfig, + api=CONFIG_INIT_PYTHON) def test_init_read_set(self): core_config = { 'program_name': './init_read_set', 'executable': 'my_executable', } - self.check_config("init_read_set", core_config, api="python", + self.check_config("init_read_set", core_config, + api=CONFIG_INIT_PYTHON, add_path="init_read_set_path") def test_init_run_main(self): @@ -777,7 +822,8 @@ def test_init_run_main(self): 'run_command': code + '\n', 'parse_argv': 1, } - self.check_config("init_run_main", core_config, api="python") + self.check_config("init_run_main", core_config, + api=CONFIG_INIT_PYTHON) def test_init_main(self): code = ('import _testinternalcapi, json; ' @@ -789,7 +835,8 @@ def test_init_main(self): 'parse_argv': 1, '_init_main': 0, } - self.check_config("init_main", core_config, api="python", + self.check_config("init_main", core_config, + api=CONFIG_INIT_PYTHON, stderr="Run Python code before _Py_InitializeMain") def test_init_parse_argv(self): @@ -800,15 +847,20 @@ def test_init_parse_argv(self): 'run_command': 'pass\n', 'use_environment': 0, } - self.check_config("init_parse_argv", core_config, api="python") + self.check_config("init_parse_argv", core_config, + api=CONFIG_INIT_PYTHON) def test_init_dont_parse_argv(self): + pre_config = { + 'parse_argv': 0, + } core_config = { 'parse_argv': 0, 'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], 'program_name': './argv0', } - self.check_config("init_dont_parse_argv", core_config, api="python") + self.check_config("init_dont_parse_argv", core_config, pre_config, + api=CONFIG_INIT_PYTHON) if __name__ == "__main__": diff --git a/Programs/_testembed.c b/Programs/_testembed.c index f1bb731dcba2b7..3dabf66de15afa 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -527,7 +527,10 @@ static int check_init_parse_argv(int parse_argv) _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } static wchar_t* argv[] = { L"./argv0", @@ -565,7 +568,7 @@ static int test_init_dont_parse_argv(void) } -static void test_init_env_putenvs(void) +static void set_all_env_vars(void) { putenv("PYTHONHASHSEED=42"); putenv("PYTHONMALLOC=malloc"); @@ -596,7 +599,7 @@ static int test_init_env(void) { /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; - test_init_env_putenvs(); + set_all_env_vars(); _testembed_Py_Initialize(); dump_config(); Py_Finalize(); @@ -604,9 +607,9 @@ static int test_init_env(void) } -static void set_all_env_vars(void) +static void set_all_env_vars_dev_mode(void) { - test_init_env_putenvs(); + set_all_env_vars(); putenv("PYTHONMALLOC="); putenv("PYTHONFAULTHANDLER="); putenv("PYTHONDEVMODE=1"); @@ -617,7 +620,7 @@ static int test_init_env_dev_mode(void) { /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; - set_all_env_vars(); + set_all_env_vars_dev_mode(); _testembed_Py_Initialize(); dump_config(); Py_Finalize(); @@ -629,7 +632,7 @@ static int test_init_env_dev_mode_alloc(void) { /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; - set_all_env_vars(); + set_all_env_vars_dev_mode(); putenv("PYTHONMALLOC=malloc"); _testembed_Py_Initialize(); dump_config(); @@ -644,7 +647,10 @@ static int test_init_isolated_flag(void) /* Test _PyCoreConfig.isolated=1 */ _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } Py_IsolatedFlag = 0; config.isolated = 1; @@ -727,6 +733,107 @@ static int test_preinit_isolated2(void) } +static int test_preinit_dont_parse_argv(void) +{ + _PyInitError err; + + _PyPreConfig preconfig; + _PyPreConfig_InitIsolatedConfig(&preconfig); + + preconfig.isolated = 0; + + /* -X dev must be ignored by isolated preconfiguration */ + wchar_t *argv[] = {L"python3", + L"-E", + L"-I", + L"-X", L"dev", + L"-X", L"utf8", + L"script.py"}; + err = _Py_PreInitializeFromWideArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv); + if (_PyInitError_Failed(err)) { + goto failed; + } + + _PyCoreConfig config; + + err = _PyCoreConfig_InitIsolatedConfig(&config); + if (_PyInitError_Failed(err)) { + goto failed; + } + + config.isolated = 0; + + /* Pre-initialize implicitly using argv: make sure that -X dev + is used to configure the allocation in preinitialization */ + err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv); + if (_PyInitError_Failed(err)) { + goto failed; + } + + err = _PyCoreConfig_SetString(&config, &config.program_name, + L"./_testembed"); + if (_PyInitError_Failed(err)) { + goto failed; + } + + err = _Py_InitializeFromConfig(&config); + if (_PyInitError_Failed(err)) { + goto failed; + } + _PyCoreConfig_Clear(&config); + + dump_config(); + Py_Finalize(); + return 0; + +failed: + _PyCoreConfig_Clear(&config); + _Py_ExitInitError(err); +} + + +static int test_preinit_parse_argv(void) +{ + _PyInitError err; + _PyCoreConfig config; + + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + goto failed; + } + + /* Pre-initialize implicitly using argv: make sure that -X dev + is used to configure the allocation in preinitialization */ + wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"}; + err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv); + if (_PyInitError_Failed(err)) { + goto failed; + } + + err = _PyCoreConfig_SetString(&config, &config.program_name, + L"./_testembed"); + if (_PyInitError_Failed(err)) { + goto failed; + } + + err = _Py_InitializeFromConfig(&config); + if (_PyInitError_Failed(err)) { + goto failed; + } + _PyCoreConfig_Clear(&config); + + dump_config(); + Py_Finalize(); + return 0; + +failed: + _PyCoreConfig_Clear(&config); + _Py_ExitInitError(err); +} + + + + static void set_all_global_config_variables(void) { Py_IsolatedFlag = 0; @@ -749,9 +856,10 @@ static void set_all_global_config_variables(void) } -static int test_init_isolated_config(void) +static int check_preinit_isolated_config(int preinit) { _PyInitError err; + _PyPreConfig *rt_preconfig; /* environment variables must be ignored */ set_all_env_vars(); @@ -759,17 +867,19 @@ static int test_init_isolated_config(void) /* global configuration variables must be ignored */ set_all_global_config_variables(); - _PyPreConfig preconfig; - _PyPreConfig_InitIsolatedConfig(&preconfig); + if (preinit) { + _PyPreConfig preconfig; + _PyPreConfig_InitIsolatedConfig(&preconfig); - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); - } + err = _Py_PreInitialize(&preconfig); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } - _PyPreConfig *rt_preconfig = &_PyRuntime.preconfig; - assert(rt_preconfig->isolated == 1); - assert(rt_preconfig->use_environment == 0); + rt_preconfig = &_PyRuntime.preconfig; + assert(rt_preconfig->isolated == 1); + assert(rt_preconfig->use_environment == 0); + } _PyCoreConfig config; err = _PyCoreConfig_InitIsolatedConfig(&config); @@ -782,13 +892,30 @@ static int test_init_isolated_config(void) if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } + + rt_preconfig = &_PyRuntime.preconfig; + assert(rt_preconfig->isolated == 1); + assert(rt_preconfig->use_environment == 0); + dump_config(); Py_Finalize(); return 0; } -static int test_init_python_config(void) +static int test_preinit_isolated_config(void) +{ + return check_preinit_isolated_config(1); +} + + +static int test_init_isolated_config(void) +{ + return check_preinit_isolated_config(0); +} + + +static int check_init_python_config(int preinit) { _PyInitError err; @@ -805,12 +932,14 @@ static int test_init_python_config(void) Py_LegacyWindowsStdioFlag = 1; #endif - _PyPreConfig preconfig; - _PyPreConfig_InitPythonConfig(&preconfig); + if (preinit) { + _PyPreConfig preconfig; + _PyPreConfig_InitPythonConfig(&preconfig); - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + err = _Py_PreInitialize(&preconfig); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } } _PyCoreConfig config; @@ -830,6 +959,18 @@ static int test_init_python_config(void) } +static int test_preinit_python_config(void) +{ + return check_init_python_config(1); +} + + +static int test_init_python_config(void) +{ + return check_init_python_config(0); +} + + static int test_init_dont_configure_locale(void) { _PyInitError err; @@ -846,7 +987,10 @@ static int test_init_dont_configure_locale(void) } _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } config.program_name = L"./_testembed"; err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { @@ -861,13 +1005,17 @@ static int test_init_dont_configure_locale(void) static int test_init_dev_mode(void) { + _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } putenv("PYTHONFAULTHANDLER="); putenv("PYTHONMALLOC="); config.dev_mode = 1; config.program_name = L"./_testembed"; - _PyInitError err = _Py_InitializeFromConfig(&config); + err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -881,9 +1029,13 @@ static int test_init_read_set(void) { _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } - err = _PyCoreConfig_DecodeLocale(&config.program_name, "./init_read_set"); + err = _PyCoreConfig_DecodeLocale(&config, &config.program_name, + "./init_read_set"); if (_PyInitError_Failed(err)) { goto fail; } @@ -900,7 +1052,7 @@ static int test_init_read_set(void) } /* override executable computed by _PyCoreConfig_Read() */ - err = _PyCoreConfig_SetString(&config.executable, L"my_executable"); + err = _PyCoreConfig_SetString(&config, &config.executable, L"my_executable"); if (_PyInitError_Failed(err)) { goto fail; } @@ -937,11 +1089,15 @@ static void configure_init_main(_PyCoreConfig *config) static int test_init_run_main(void) { + _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } configure_init_main(&config); - _PyInitError err = _Py_InitializeFromConfig(&config); + err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -952,12 +1108,17 @@ static int test_init_run_main(void) static int test_init_main(void) { + _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } configure_init_main(&config); config._init_main = 0; - _PyInitError err = _Py_InitializeFromConfig(&config); + err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } @@ -982,23 +1143,40 @@ static int test_init_main(void) static int test_run_main(void) { + _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + goto failed; + } wchar_t *argv[] = {L"python3", L"-c", (L"import sys; " L"print(f'_Py_RunMain(): sys.argv={sys.argv}')"), L"arg2"}; - config.argv.length = Py_ARRAY_LENGTH(argv); - config.argv.items = argv; - config.program_name = L"./python3"; + err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv); + if (_PyInitError_Failed(err)) { + goto failed; + } - _PyInitError err = _Py_InitializeFromConfig(&config); + err = _PyCoreConfig_SetString(&config, &config.program_name, + L"./python3"); if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + goto failed; + } + + err = _Py_InitializeFromConfig(&config); + if (_PyInitError_Failed(err)) { + goto failed; } + _PyCoreConfig_Clear(&config); return _Py_RunMain(); + +failed: + _PyCoreConfig_Clear(&config); + _Py_ExitInitError(err); } @@ -1039,10 +1217,14 @@ static struct TestCase TestCases[] = { { "init_dont_configure_locale", test_init_dont_configure_locale }, { "init_dev_mode", test_init_dev_mode }, { "init_isolated_flag", test_init_isolated_flag }, + { "preinit_isolated_config", test_preinit_isolated_config }, { "init_isolated_config", test_init_isolated_config }, + { "preinit_python_config", test_preinit_python_config }, { "init_python_config", test_init_python_config }, { "preinit_isolated1", test_preinit_isolated1 }, { "preinit_isolated2", test_preinit_isolated2 }, + { "preinit_parse_argv", test_preinit_parse_argv }, + { "preinit_dont_parse_argv", test_preinit_dont_parse_argv }, { "init_read_set", test_init_read_set }, { "init_run_main", test_init_run_main }, { "init_main", test_init_main }, diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 470bda870288b5..958845e488d7f2 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -551,6 +551,7 @@ _PyCoreConfig_Init(_PyCoreConfig *config) memset(config, 0, sizeof(*config)); config->_config_version = _Py_CONFIG_VERSION; + config->_config_init = (int)_PyCoreConfig_INIT; config->isolated = -1; config->use_environment = -1; config->dev_mode = -1; @@ -612,6 +613,7 @@ _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config) { _PyCoreConfig_InitDefaults(config); + config->_config_init = (int)_PyCoreConfig_INIT_PYTHON; config->configure_c_stdio = 1; config->parse_argv = 1; @@ -624,6 +626,7 @@ _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config) { _PyCoreConfig_InitDefaults(config); + config->_config_init = (int)_PyCoreConfig_INIT_ISOLATED; config->isolated = 1; config->use_environment = 0; config->user_site_directory = 0; @@ -643,8 +646,14 @@ _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config) /* Copy str into *config_str (duplicate the string) */ _PyInitError -_PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str) +_PyCoreConfig_SetString(_PyCoreConfig *config, wchar_t **config_str, + const wchar_t *str) { + _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL); + if (_Py_INIT_FAILED(err)) { + return err; + } + wchar_t *str2; if (str != NULL) { str2 = _PyMem_RawWcsdup(str); @@ -662,10 +671,10 @@ _PyCoreConfig_SetString(wchar_t **config_str, const wchar_t *str) static _PyInitError -_PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str, - const char *decode_err_msg) +_PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str, + const char *str, const char *decode_err_msg) { - _PyInitError err = _Py_PreInitialize(NULL); + _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL); if (_Py_INIT_FAILED(err)) { return err; } @@ -692,17 +701,18 @@ _PyCoreConfig_DecodeLocaleErr(wchar_t **config_str, const char *str, } -#define CONFIG_DECODE_LOCALE(config_str, str, NAME) \ - _PyCoreConfig_DecodeLocaleErr(config_str, str, "cannot decode " NAME) +#define CONFIG_DECODE_LOCALE(config, config_str, str, NAME) \ + _PyCoreConfig_DecodeLocaleErr(config, config_str, str, "cannot decode " NAME) /* Decode str using Py_DecodeLocale() and set the result into *config_str. Pre-initialize Python if needed to ensure that encodings are properly configured. */ _PyInitError -_PyCoreConfig_DecodeLocale(wchar_t **config_str, const char *str) +_PyCoreConfig_DecodeLocale(_PyCoreConfig *config, wchar_t **config_str, + const char *str) { - return CONFIG_DECODE_LOCALE(config_str, str, "string"); + return CONFIG_DECODE_LOCALE(config, config_str, str, "string"); } @@ -715,7 +725,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR #define COPY_WSTR_ATTR(ATTR) \ do { \ - err = _PyCoreConfig_SetString(&config->ATTR, config2->ATTR); \ + err = _PyCoreConfig_SetString(config, &config->ATTR, config2->ATTR); \ if (_Py_INIT_FAILED(err)) { \ return err; \ } \ @@ -727,6 +737,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) } \ } while (0) + COPY_ATTR(_config_init); COPY_ATTR(isolated); COPY_ATTR(use_environment); COPY_ATTR(dev_mode); @@ -829,6 +840,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) #define SET_ITEM_WSTRLIST(LIST) \ SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST)) + SET_ITEM_INT(_config_init); SET_ITEM_INT(isolated); SET_ITEM_INT(use_environment); SET_ITEM_INT(dev_mode); @@ -910,7 +922,7 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) Return 0 on success, but *dest can be NULL. Return -1 on memory allocation failure. Return -2 on decoding error. */ static _PyInitError -_PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, +_PyCoreConfig_GetEnvDup(_PyCoreConfig *config, wchar_t **dest, wchar_t *wname, char *name, const char *decode_err_msg) @@ -930,7 +942,7 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, return _Py_INIT_OK(); } - return _PyCoreConfig_SetString(dest, var); + return _PyCoreConfig_SetString(config, dest, var); #else const char *var = getenv(name); if (!var || var[0] == '\0') { @@ -938,7 +950,7 @@ _PyCoreConfig_GetEnvDup(const _PyCoreConfig *config, return _Py_INIT_OK(); } - return _PyCoreConfig_DecodeLocaleErr(dest, var, decode_err_msg); + return _PyCoreConfig_DecodeLocaleErr(config, dest, var, decode_err_msg); #endif } @@ -1053,7 +1065,7 @@ config_init_program_name(_PyCoreConfig *config) script. */ const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE"); if (p != NULL) { - err = CONFIG_DECODE_LOCALE(&config->program_name, p, + err = CONFIG_DECODE_LOCALE(config, &config->program_name, p, "PYTHONEXECUTABLE environment variable"); if (_Py_INIT_FAILED(err)) { return err; @@ -1067,7 +1079,8 @@ config_init_program_name(_PyCoreConfig *config) /* Used by Mac/Tools/pythonw.c to forward * the argv0 of the stub executable */ - err = CONFIG_DECODE_LOCALE(&config->program_name, pyvenv_launcher, + err = CONFIG_DECODE_LOCALE(config, + &config->program_name, pyvenv_launcher, "__PYVENV_LAUNCHER__ environment variable"); if (_Py_INIT_FAILED(err)) { return err; @@ -1094,7 +1107,8 @@ config_init_program_name(_PyCoreConfig *config) #else const wchar_t *default_program_name = L"python3"; #endif - err = _PyCoreConfig_SetString(&config->program_name, default_program_name); + err = _PyCoreConfig_SetString(config, &config->program_name, + default_program_name); if (_Py_INIT_FAILED(err)) { return err; } @@ -1109,7 +1123,8 @@ config_init_executable(_PyCoreConfig *config) /* If Py_SetProgramFullPath() was called, use its value */ const wchar_t *program_full_path = _Py_path_config.program_full_path; if (program_full_path != NULL) { - _PyInitError err = _PyCoreConfig_SetString(&config->executable, + _PyInitError err = _PyCoreConfig_SetString(config, + &config->executable, program_full_path); if (_Py_INIT_FAILED(err)) { return err; @@ -1135,7 +1150,7 @@ config_init_home(_PyCoreConfig *config) /* If Py_SetPythonHome() was called, use its value */ wchar_t *home = _Py_path_config.home; if (home) { - _PyInitError err = _PyCoreConfig_SetString(&config->home, home); + _PyInitError err = _PyCoreConfig_SetString(config, &config->home, home); if (_Py_INIT_FAILED(err)) { return err; } @@ -1392,14 +1407,14 @@ config_get_stdio_errors(const _PyCoreConfig *config) static _PyInitError -config_get_locale_encoding(wchar_t **locale_encoding) +config_get_locale_encoding(_PyCoreConfig *config, wchar_t **locale_encoding) { #ifdef MS_WINDOWS char encoding[20]; PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); - return _PyCoreConfig_DecodeLocale(locale_encoding, encoding); + return _PyCoreConfig_DecodeLocale(config, locale_encoding, encoding); #elif defined(_Py_FORCE_UTF8_LOCALE) - return _PyCoreConfig_SetString(locale_encoding, L"utf-8"); + return _PyCoreConfig_SetString(config, locale_encoding, L"utf-8"); #else const char *encoding = nl_langinfo(CODESET); if (!encoding || encoding[0] == '\0') { @@ -1407,7 +1422,8 @@ config_get_locale_encoding(wchar_t **locale_encoding) "nl_langinfo(CODESET) failed"); } /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */ - return CONFIG_DECODE_LOCALE(locale_encoding, encoding, + return CONFIG_DECODE_LOCALE(config, + locale_encoding, encoding, "nl_langinfo(CODESET)"); #endif } @@ -1422,7 +1438,7 @@ config_init_stdio_encoding(_PyCoreConfig *config, /* If Py_SetStandardStreamEncoding() have been called, use these parameters. */ if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { - err = CONFIG_DECODE_LOCALE(&config->stdio_encoding, + err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding, _Py_StandardStreamEncoding, "_Py_StandardStreamEncoding"); if (_Py_INIT_FAILED(err)) { @@ -1431,7 +1447,7 @@ config_init_stdio_encoding(_PyCoreConfig *config, } if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) { - err = CONFIG_DECODE_LOCALE(&config->stdio_errors, + err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors, _Py_StandardStreamErrors, "_Py_StandardStreamErrors"); if (_Py_INIT_FAILED(err)) { @@ -1463,7 +1479,7 @@ config_init_stdio_encoding(_PyCoreConfig *config, /* Does PYTHONIOENCODING contain an encoding? */ if (pythonioencoding[0]) { if (config->stdio_encoding == NULL) { - err = CONFIG_DECODE_LOCALE(&config->stdio_encoding, + err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding, pythonioencoding, "PYTHONIOENCODING environment variable"); if (_Py_INIT_FAILED(err)) { @@ -1482,7 +1498,7 @@ config_init_stdio_encoding(_PyCoreConfig *config, } if (config->stdio_errors == NULL && errors != NULL) { - err = CONFIG_DECODE_LOCALE(&config->stdio_errors, + err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors, errors, "PYTHONIOENCODING environment variable"); if (_Py_INIT_FAILED(err)) { @@ -1497,13 +1513,13 @@ config_init_stdio_encoding(_PyCoreConfig *config, /* UTF-8 Mode uses UTF-8/surrogateescape */ if (preconfig->utf8_mode) { if (config->stdio_encoding == NULL) { - err = _PyCoreConfig_SetString(&config->stdio_encoding, L"utf-8"); + err = _PyCoreConfig_SetString(config, &config->stdio_encoding, L"utf-8"); if (_Py_INIT_FAILED(err)) { return err; } } if (config->stdio_errors == NULL) { - err = _PyCoreConfig_SetString(&config->stdio_errors, + err = _PyCoreConfig_SetString(config, &config->stdio_errors, L"surrogateescape"); if (_Py_INIT_FAILED(err)) { return err; @@ -1513,7 +1529,7 @@ config_init_stdio_encoding(_PyCoreConfig *config, /* Choose the default error handler based on the current locale. */ if (config->stdio_encoding == NULL) { - err = config_get_locale_encoding(&config->stdio_encoding); + err = config_get_locale_encoding(config, &config->stdio_encoding); if (_Py_INIT_FAILED(err)) { return err; } @@ -1522,7 +1538,7 @@ config_init_stdio_encoding(_PyCoreConfig *config, const wchar_t *errors = config_get_stdio_errors(config); assert(errors != NULL); - err = _PyCoreConfig_SetString(&config->stdio_errors, errors); + err = _PyCoreConfig_SetString(config, &config->stdio_errors, errors); if (_Py_INIT_FAILED(err)) { return err; } @@ -1539,34 +1555,35 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) if (config->filesystem_encoding == NULL) { #ifdef _Py_FORCE_UTF8_FS_ENCODING - err = _PyCoreConfig_SetString(&config->filesystem_encoding, L"utf-8"); + err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"utf-8"); #else #ifdef MS_WINDOWS if (preconfig->legacy_windows_fs_encoding) { /* Legacy Windows filesystem encoding: mbcs/replace */ - err = _PyCoreConfig_SetString(&config->filesystem_encoding, + err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"mbcs"); } else #endif if (preconfig->utf8_mode) { - err = _PyCoreConfig_SetString(&config->filesystem_encoding, + err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"utf-8"); } #ifndef MS_WINDOWS else if (_Py_GetForceASCII()) { - err = _PyCoreConfig_SetString(&config->filesystem_encoding, + err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"ascii"); } #endif else { #ifdef MS_WINDOWS /* Windows defaults to utf-8/surrogatepass (PEP 529). */ - err = _PyCoreConfig_SetString(&config->filesystem_encoding, + err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"utf-8"); #else - err = config_get_locale_encoding(&config->filesystem_encoding); + err = config_get_locale_encoding(config, + &config->filesystem_encoding); #endif } #endif /* !_Py_FORCE_UTF8_FS_ENCODING */ @@ -1588,7 +1605,7 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) #else errors = L"surrogateescape"; #endif - err = _PyCoreConfig_SetString(&config->filesystem_errors, errors); + err = _PyCoreConfig_SetString(config, &config->filesystem_errors, errors); if (_Py_INIT_FAILED(err)) { return err; } @@ -1681,7 +1698,7 @@ config_read(_PyCoreConfig *config) } if (config->check_hash_pycs_mode == NULL) { - err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode, + err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode, L"default"); if (_Py_INIT_FAILED(err)) { return err; @@ -1832,7 +1849,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, || wcscmp(_PyOS_optarg, L"never") == 0 || wcscmp(_PyOS_optarg, L"default") == 0) { - err = _PyCoreConfig_SetString(&config->check_hash_pycs_mode, + err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode, _PyOS_optarg); if (_Py_INIT_FAILED(err)) { return err; @@ -1966,7 +1983,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, /* Get warning options from PYTHONWARNINGS environment variable. */ static _PyInitError -config_init_env_warnoptions(const _PyCoreConfig *config, _PyWstrList *warnoptions) +config_init_env_warnoptions(_PyCoreConfig *config, _PyWstrList *warnoptions) { _PyInitError err; /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */ @@ -2136,8 +2153,7 @@ core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline) } _PyPreConfig preconfig; - _PyPreConfig_Init(&preconfig); - _PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig); + _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig); _PyPreConfig_GetCoreConfig(&preconfig, config); @@ -2211,24 +2227,11 @@ config_read_cmdline(_PyCoreConfig *config) _PyInitError _PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args) { - if (args->use_bytes_argv) { - _PyInitError err; - - err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; - } - _PyRuntimeState *runtime = &_PyRuntime; - - /* do nothing if Python is already pre-initialized: - _PyCoreConfig_Write() will update _PyRuntime.preconfig later */ - if (!runtime->pre_initialized) { - err = _Py_PreInitializeFromCoreConfig(config, args); - if (_Py_INIT_FAILED(err)) { - return err; - } - } + _PyInitError err = _Py_PreInitializeFromCoreConfig(config, args); + if (_Py_INIT_FAILED(err)) { + return err; } + return _PyArgv_AsWstrList(args, &config->argv); } @@ -2236,7 +2239,7 @@ _PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args) /* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python if needed to ensure that encodings are properly configured. */ _PyInitError -_PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char **argv) +_PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char * const *argv) { _PyArgv args = { .argc = argc, @@ -2248,7 +2251,7 @@ _PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char **argv) _PyInitError -_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, wchar_t **argv) +_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, wchar_t * const *argv) { _PyArgv args = { .argc = argc, diff --git a/Python/preconfig.c b/Python/preconfig.c index 0f4bd8ece534c0..71a6ee6c072ef0 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -95,7 +95,7 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list) } else { wargv.length = args->argc; - wargv.items = args->wchar_argv; + wargv.items = (wchar_t **)args->wchar_argv; if (_PyWstrList_Copy(list, &wargv) < 0) { return _Py_INIT_NO_MEMORY(); } @@ -217,16 +217,15 @@ precmdline_parse_cmdline(_PyPreCmdline *cmdline) _PyInitError -_PyPreCmdline_Read(_PyPreCmdline *cmdline, - const _PyPreConfig *preconfig) +_PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig) { - if (preconfig) { - _PyPreCmdline_GetPreConfig(cmdline, preconfig); - } + _PyPreCmdline_GetPreConfig(cmdline, preconfig); - _PyInitError err = precmdline_parse_cmdline(cmdline); - if (_Py_INIT_FAILED(err)) { - return err; + if (preconfig->parse_argv) { + _PyInitError err = precmdline_parse_cmdline(cmdline); + if (_Py_INIT_FAILED(err)) { + return err; + } } /* isolated, use_environment */ @@ -268,6 +267,7 @@ _PyPreConfig_Init(_PyPreConfig *config) memset(config, 0, sizeof(*config)); config->_config_version = _Py_CONFIG_VERSION; + config->parse_argv = 0; config->isolated = -1; config->use_environment = -1; config->configure_locale = 1; @@ -285,6 +285,7 @@ _PyPreConfig_InitPythonConfig(_PyPreConfig *config) { _PyPreConfig_Init(config); + config->parse_argv = 1; /* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540) depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE environment variables. */ @@ -310,11 +311,41 @@ _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config) } +void +_PyPreConfig_InitFromPreConfig(_PyPreConfig *config, + const _PyPreConfig *config2) +{ + _PyPreConfig_Init(config); + _PyPreConfig_Copy(config, config2); +} + + +void +_PyPreConfig_InitFromCoreConfig(_PyPreConfig *config, + const _PyCoreConfig *coreconfig) +{ + _PyCoreConfigInitEnum config_init = (_PyCoreConfigInitEnum)coreconfig->_config_init; + switch (config_init) { + case _PyCoreConfig_INIT_PYTHON: + _PyPreConfig_InitPythonConfig(config); + break; + case _PyCoreConfig_INIT_ISOLATED: + _PyPreConfig_InitIsolatedConfig(config); + break; + case _PyCoreConfig_INIT: + default: + _PyPreConfig_Init(config); + } + _PyPreConfig_GetCoreConfig(config, coreconfig); +} + + void _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) { #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR + COPY_ATTR(parse_argv); COPY_ATTR(isolated); COPY_ATTR(use_environment); COPY_ATTR(configure_locale); @@ -341,27 +372,20 @@ _PyPreConfig_AsDict(const _PyPreConfig *config) return NULL; } -#define SET_ITEM(KEY, EXPR) \ +#define SET_ITEM_INT(ATTR) \ do { \ - PyObject *obj = (EXPR); \ + PyObject *obj = PyLong_FromLong(config->ATTR); \ if (obj == NULL) { \ goto fail; \ } \ - int res = PyDict_SetItemString(dict, (KEY), obj); \ + int res = PyDict_SetItemString(dict, #ATTR, obj); \ Py_DECREF(obj); \ if (res < 0) { \ goto fail; \ } \ } while (0) -#define SET_ITEM_INT(ATTR) \ - SET_ITEM(#ATTR, PyLong_FromLong(config->ATTR)) -#define FROM_STRING(STR) \ - ((STR != NULL) ? \ - PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) -#define SET_ITEM_STR(ATTR) \ - SET_ITEM(#ATTR, FROM_STRING(config->ATTR)) + SET_ITEM_INT(parse_argv); SET_ITEM_INT(isolated); SET_ITEM_INT(use_environment); SET_ITEM_INT(configure_locale); @@ -379,10 +403,7 @@ _PyPreConfig_AsDict(const _PyPreConfig *config) Py_DECREF(dict); return NULL; -#undef FROM_STRING -#undef SET_ITEM #undef SET_ITEM_INT -#undef SET_ITEM_STR } @@ -395,6 +416,7 @@ _PyPreConfig_GetCoreConfig(_PyPreConfig *config, config->ATTR = core_config->ATTR; \ } + COPY_ATTR(parse_argv); COPY_ATTR(isolated); COPY_ATTR(use_environment); COPY_ATTR(dev_mode); @@ -662,9 +684,11 @@ preconfig_init_allocator(_PyPreConfig *config) allocators to "malloc" (and not to "debug"). */ const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC"); if (envvar) { - if (_PyMem_GetAllocatorName(envvar, &config->allocator) < 0) { + PyMemAllocatorName name; + if (_PyMem_GetAllocatorName(envvar, &name) < 0) { return _Py_INIT_ERR("PYTHONMALLOC: unknown allocator"); } + config->allocator = (int)name; } } @@ -751,8 +775,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) /* Save the config to be able to restore it if encodings change */ _PyPreConfig save_config; - _PyPreConfig_Init(&save_config); - _PyPreConfig_Copy(&save_config, config); + _PyPreConfig_InitFromPreConfig(&save_config, config); /* Set LC_CTYPE to the user preferred locale */ if (config->configure_locale) { @@ -879,8 +902,9 @@ _PyPreConfig_Write(const _PyPreConfig *config) return _Py_INIT_OK(); } - if (config->allocator != PYMEM_ALLOCATOR_NOT_SET) { - if (_PyMem_SetupAllocators(config->allocator) < 0) { + PyMemAllocatorName name = (PyMemAllocatorName)config->allocator; + if (name != PYMEM_ALLOCATOR_NOT_SET) { + if (_PyMem_SetupAllocators(name) < 0) { return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator"); } } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 0781dc8046b106..01f725f8f45a73 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -691,6 +691,10 @@ _Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args) { _PyInitError err; + if (src_config == NULL) { + return _Py_INIT_ERR("preinitialization config is NULL"); + } + err = _PyRuntime_Initialize(); if (_Py_INIT_FAILED(err)) { return err; @@ -703,11 +707,7 @@ _Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args) } _PyPreConfig config; - _PyPreConfig_Init(&config); - - if (src_config) { - _PyPreConfig_Copy(&config, src_config); - } + _PyPreConfig_InitFromPreConfig(&config, src_config); err = _PyPreConfig_Read(&config, args); if (_Py_INIT_FAILED(err)) { @@ -751,21 +751,34 @@ _PyInitError _Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig, const _PyArgv *args) { - _PyPreConfig config; - _PyPreConfig_Init(&config); - if (coreconfig != NULL) { - _PyPreConfig_GetCoreConfig(&config, coreconfig); + assert(coreconfig != NULL); + + _PyInitError err = _PyRuntime_Initialize(); + if (_Py_INIT_FAILED(err)) { + return err; + } + _PyRuntimeState *runtime = &_PyRuntime; + + if (runtime->pre_initialized) { + /* Already initialized: do nothing */ + return _Py_INIT_OK(); } - if (args == NULL && coreconfig != NULL && coreconfig->parse_argv) { + _PyPreConfig preconfig; + _PyPreConfig_InitFromCoreConfig(&preconfig, coreconfig); + + if (!coreconfig->parse_argv) { + return _Py_PreInitialize(&preconfig); + } + else if (args == NULL) { _PyArgv config_args = { .use_bytes_argv = 0, .argc = coreconfig->argv.length, .wchar_argv = coreconfig->argv.items}; - return _Py_PreInitializeFromPyArgv(&config, &config_args); + return _Py_PreInitializeFromPyArgv(&preconfig, &config_args); } else { - return _Py_PreInitializeFromPyArgv(&config, args); + return _Py_PreInitializeFromPyArgv(&preconfig, args); } } @@ -777,13 +790,11 @@ pyinit_coreconfig(_PyRuntimeState *runtime, const _PyArgv *args, PyInterpreterState **interp_p) { - _PyInitError err; + assert(src_config != NULL); - if (src_config) { - err = _PyCoreConfig_Copy(config, src_config); - if (_Py_INIT_FAILED(err)) { - return err; - } + _PyInitError err = _PyCoreConfig_Copy(config, src_config); + if (_Py_INIT_FAILED(err)) { + return err; } if (args) { @@ -995,6 +1006,10 @@ _Py_InitializeMain(void) static _PyInitError init_python(const _PyCoreConfig *config, const _PyArgv *args) { + if (config == NULL) { + return _Py_INIT_ERR("initialization config is NULL"); + } + _PyInitError err; err = _PyRuntime_Initialize(); @@ -1022,7 +1037,8 @@ init_python(const _PyCoreConfig *config, const _PyArgv *args) _PyInitError -_Py_InitializeFromArgs(const _PyCoreConfig *config, Py_ssize_t argc, char **argv) +_Py_InitializeFromArgs(const _PyCoreConfig *config, + Py_ssize_t argc, char * const *argv) { _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; return init_python(config, &args); @@ -1030,7 +1046,8 @@ _Py_InitializeFromArgs(const _PyCoreConfig *config, Py_ssize_t argc, char **argv _PyInitError -_Py_InitializeFromWideArgs(const _PyCoreConfig *config, Py_ssize_t argc, wchar_t **argv) +_Py_InitializeFromWideArgs(const _PyCoreConfig *config, + Py_ssize_t argc, wchar_t * const *argv) { _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; return init_python(config, &args); From 9932fd91e878b740704ff599522e945a4bbe2ae1 Mon Sep 17 00:00:00 2001 From: Niklas Fiekas Date: Mon, 20 May 2019 14:02:17 +0200 Subject: [PATCH 026/441] bpo-35721: Close socket pair if Popen in _UnixSubprocessTransport fails (GH-11553) This slightly expands an existing test case `test_popen_error` to trigger a `ResourceWarning` and fixes it. https://bugs.python.org/issue35721 --- Lib/asyncio/unix_events.py | 18 ++++++++++++------ Lib/test/test_asyncio/test_subprocess.py | 17 +++++++++++++---- Misc/ACKS | 1 + .../2019-01-18-16-23-00.bpo-35721.d8djAJ.rst | 3 +++ 4 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 73d4bda7c2341b..1aa3b396086c59 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -757,12 +757,18 @@ def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): # other end). Notably this is needed on AIX, and works # just fine on other platforms. stdin, stdin_w = socket.socketpair() - self._proc = subprocess.Popen( - args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr, - universal_newlines=False, bufsize=bufsize, **kwargs) - if stdin_w is not None: - stdin.close() - self._proc.stdin = open(stdin_w.detach(), 'wb', buffering=bufsize) + try: + self._proc = subprocess.Popen( + args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr, + universal_newlines=False, bufsize=bufsize, **kwargs) + if stdin_w is not None: + stdin.close() + self._proc.stdin = open(stdin_w.detach(), 'wb', buffering=bufsize) + stdin_w = None + finally: + if stdin_w is not None: + stdin.close() + stdin_w.close() class AbstractChildWatcher: diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 3908aabf5a1321..551974a1806a84 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -468,9 +468,7 @@ async def kill_running(): isinstance(self, SubprocessFastWatcherTests)): asyncio.get_child_watcher()._callbacks.clear() - def test_popen_error(self): - # Issue #24763: check that the subprocess transport is closed - # when BaseSubprocessTransport fails + def _test_popen_error(self, stdin): if sys.platform == 'win32': target = 'asyncio.windows_utils.Popen' else: @@ -480,12 +478,23 @@ def test_popen_error(self): popen.side_effect = exc create = asyncio.create_subprocess_exec(sys.executable, '-c', - 'pass', loop=self.loop) + 'pass', stdin=stdin, + loop=self.loop) with warnings.catch_warnings(record=True) as warns: with self.assertRaises(exc): self.loop.run_until_complete(create) self.assertEqual(warns, []) + def test_popen_error(self): + # Issue #24763: check that the subprocess transport is closed + # when BaseSubprocessTransport fails + self._test_popen_error(stdin=None) + + def test_popen_error_with_stdin_pipe(self): + # Issue #35721: check that newly created socket pair is closed when + # Popen fails + self._test_popen_error(stdin=subprocess.PIPE) + def test_read_stdout_after_process_exit(self): async def execute(): diff --git a/Misc/ACKS b/Misc/ACKS index 8b3232551e1b09..77f19909b3005b 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -486,6 +486,7 @@ Florian Festi John Feuerstein Carl Feynman Vincent Fiack +Niklas Fiekas Anastasia Filatova Tomer Filiba Segev Finer diff --git a/Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst b/Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst new file mode 100644 index 00000000000000..5af4b1b8999419 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst @@ -0,0 +1,3 @@ +Fix :meth:`asyncio.SelectorEventLoop.subprocess_exec()` leaks file descriptors +if ``Popen`` fails and called with ``stdin=subprocess.PIPE``. +Patch by Niklas Fiekas. From 425717fee1c72df464c9f85b9a8d32b9197d1035 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 20 May 2019 16:38:48 +0200 Subject: [PATCH 027/441] bpo-36763: Fix encoding/locale tests in test_embed (GH-13443) * Fix encoding and locale tests in test_embed.InitConfigTests. * InitConfigTests now only computes EXPECTED_CONFIG once. * Add tests for PYTHONWARNINGS and PYTHONPATH env vars --- Lib/test/test_embed.py | 190 ++++++++++++++++++++++------------------- Programs/_testembed.c | 19 +++-- 2 files changed, 113 insertions(+), 96 deletions(-) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 5be179a266ba5d..4fe005dfa130e3 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -296,6 +296,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): }) PYTHON_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG, parse_argv=1, + coerce_c_locale=GET_DEFAULT_CONFIG, + utf8_mode=GET_DEFAULT_CONFIG, ) ISOLATED_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG, configure_locale=0, @@ -303,6 +305,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): use_environment=0, utf8_mode=0, dev_mode=0, + coerce_c_locale=0, ) COPY_PRE_CONFIG = [ @@ -435,6 +438,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): ('Py_LegacyWindowsStdioFlag', 'legacy_windows_stdio'), )) + EXPECTED_CONFIG = None + def main_xoptions(self, xoptions_list): xoptions = {} for opt in xoptions_list: @@ -445,37 +450,15 @@ def main_xoptions(self, xoptions_list): xoptions[opt] = True return xoptions - def get_expected_config(self, expected_preconfig, expected, env, api, - add_path=None): - if api == CONFIG_INIT_PYTHON: - default_config = self.PYTHON_CORE_CONFIG - elif api == CONFIG_INIT_ISOLATED: - default_config = self.ISOLATED_CORE_CONFIG - else: - default_config = self.DEFAULT_CORE_CONFIG - expected = dict(default_config, **expected) - expected['_config_init'] = api - + def _get_expected_config(self, env): code = textwrap.dedent(''' import json import sys import _testinternalcapi configs = _testinternalcapi.get_configs() - core_config = configs['core_config'] - data = { - 'stdio_encoding': sys.stdout.encoding, - 'stdio_errors': sys.stdout.errors, - 'prefix': sys.prefix, - 'base_prefix': sys.base_prefix, - 'exec_prefix': sys.exec_prefix, - 'base_exec_prefix': sys.base_exec_prefix, - 'filesystem_encoding': sys.getfilesystemencoding(), - 'filesystem_errors': sys.getfilesystemencodeerrors(), - 'module_search_paths': core_config['module_search_paths'], - } - - data = json.dumps(data) + + data = json.dumps(configs) data = data.encode('utf-8') sys.stdout.buffer.write(data) sys.stdout.buffer.flush() @@ -484,10 +467,6 @@ def get_expected_config(self, expected_preconfig, expected, env, api, # Use -S to not import the site module: get the proper configuration # when test_embed is run from a venv (bpo-35313) args = [sys.executable, '-S', '-c', code] - env = dict(env) - if not expected['isolated']: - env['PYTHONCOERCECLOCALE'] = '0' - env['PYTHONUTF8'] = '0' proc = subprocess.run(args, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) @@ -496,10 +475,46 @@ def get_expected_config(self, expected_preconfig, expected, env, api, f"stdout={proc.stdout!r} stderr={proc.stderr!r}") stdout = proc.stdout.decode('utf-8') try: - config = json.loads(stdout) + return json.loads(stdout) except json.JSONDecodeError: self.fail(f"fail to decode stdout: {stdout!r}") + def get_expected_config(self, expected_preconfig, expected, env, api, + add_path=None): + cls = self.__class__ + if cls.EXPECTED_CONFIG is None: + cls.EXPECTED_CONFIG = self._get_expected_config(env) + configs = {key: dict(value) + for key, value in self.EXPECTED_CONFIG.items()} + + pre_config = configs['pre_config'] + for key, value in expected_preconfig.items(): + if value is self.GET_DEFAULT_CONFIG: + expected_preconfig[key] = pre_config[key] + + if not expected_preconfig['configure_locale'] or api == CONFIG_INIT: + # there is no easy way to get the locale encoding before + # setlocale(LC_CTYPE, "") is called: don't test encodings + for key in ('filesystem_encoding', 'filesystem_errors', + 'stdio_encoding', 'stdio_errors'): + expected[key] = self.IGNORE_CONFIG + + if not expected_preconfig['configure_locale']: + # UTF-8 Mode depends on the locale. There is no easy way + # to guess if UTF-8 Mode will be enabled or not if the locale + # is not configured. + expected_preconfig['utf8_mode'] = self.IGNORE_CONFIG + + if expected_preconfig['utf8_mode'] == 1: + if expected['filesystem_encoding'] is self.GET_DEFAULT_CONFIG: + expected['filesystem_encoding'] = 'utf-8' + if expected['filesystem_errors'] is self.GET_DEFAULT_CONFIG: + expected['filesystem_errors'] = self.UTF8_MODE_ERRORS + if expected['stdio_encoding'] is self.GET_DEFAULT_CONFIG: + expected['stdio_encoding'] = 'utf-8' + if expected['stdio_errors'] is self.GET_DEFAULT_CONFIG: + expected['stdio_errors'] = 'surrogateescape' + if expected['executable'] is self.GET_DEFAULT_CONFIG: if sys.platform == 'win32': expected['executable'] = self.test_exe @@ -511,24 +526,28 @@ def get_expected_config(self, expected_preconfig, expected, env, api, if expected['program_name'] is self.GET_DEFAULT_CONFIG: expected['program_name'] = './_testembed' + core_config = configs['core_config'] for key, value in expected.items(): if value is self.GET_DEFAULT_CONFIG: - expected[key] = config[key] + expected[key] = core_config[key] + prepend_path = expected['module_search_path_env'] + if prepend_path is not None: + expected['module_search_paths'] = [prepend_path, *expected['module_search_paths']] if add_path is not None: - expected['module_search_paths'].append(add_path) - - if not expected_preconfig['configure_locale']: - # there is no easy way to get the locale encoding before - # setlocale(LC_CTYPE, "") is called: don't test encodings - for key in ('filesystem_encoding', 'filesystem_errors', - 'stdio_encoding', 'stdio_errors'): - expected[key] = self.IGNORE_CONFIG + expected['module_search_paths'] = [*expected['module_search_paths'], add_path] - return expected + for key in self.COPY_PRE_CONFIG: + if key not in expected_preconfig: + expected_preconfig[key] = expected[key] def check_pre_config(self, config, expected): - self.assertEqual(config['pre_config'], expected) + pre_config = dict(config['pre_config']) + for key, value in list(expected.items()): + if value is self.IGNORE_CONFIG: + del pre_config[key] + del expected[key] + self.assertEqual(pre_config, expected) def check_core_config(self, config, expected): core_config = dict(config['core_config']) @@ -567,10 +586,6 @@ def check_config(self, testname, expected_config=None, expected_preconfig=None, for key in list(env): if key.startswith('PYTHON'): del env[key] - # Disable C locale coercion and UTF-8 mode to not depend - # on the current locale - env['PYTHONCOERCECLOCALE'] = '0' - env['PYTHONUTF8'] = '0' if api == CONFIG_INIT_ISOLATED: default_preconfig = self.ISOLATED_PRE_CONFIG @@ -583,12 +598,19 @@ def check_config(self, testname, expected_config=None, expected_preconfig=None, expected_preconfig = dict(default_preconfig, **expected_preconfig) if expected_config is None: expected_config = {} - expected_config = self.get_expected_config(expected_preconfig, - expected_config, env, - api, add_path) - for key in self.COPY_PRE_CONFIG: - if key not in expected_preconfig: - expected_preconfig[key] = expected_config[key] + + if api == CONFIG_INIT_PYTHON: + default_config = self.PYTHON_CORE_CONFIG + elif api == CONFIG_INIT_ISOLATED: + default_config = self.ISOLATED_CORE_CONFIG + else: + default_config = self.DEFAULT_CORE_CONFIG + expected_config = dict(default_config, **expected_config) + expected_config['_config_init'] = api + + self.get_expected_config(expected_preconfig, + expected_config, env, + api, add_path) out, err = self.run_embedded_interpreter(testname, env=env) if stderr is None and not expected_config['verbose']: @@ -624,10 +646,6 @@ def test_init_global_config(self): 'quiet': 1, 'buffered_stdio': 0, - 'stdio_encoding': 'utf-8', - 'stdio_errors': 'surrogateescape', - 'filesystem_encoding': 'utf-8', - 'filesystem_errors': self.UTF8_MODE_ERRORS, 'user_site_directory': 0, 'pathconfig_warnings': 0, } @@ -650,8 +668,6 @@ def test_init_from_config(self): 'stdio_encoding': 'iso8859-1', 'stdio_errors': 'replace', - 'filesystem_encoding': 'utf-8', - 'filesystem_errors': self.UTF8_MODE_ERRORS, 'pycache_prefix': 'conf_pycache_prefix', 'program_name': './conf_program_name', @@ -679,43 +695,42 @@ def test_init_from_config(self): } self.check_config("init_from_config", config, preconfig) - INIT_ENV_PRECONFIG = { - 'allocator': PYMEM_ALLOCATOR_MALLOC, - } - INIT_ENV_CONFIG = { - 'use_hash_seed': 1, - 'hash_seed': 42, - 'tracemalloc': 2, - 'import_time': 1, - 'malloc_stats': 1, - 'inspect': 1, - 'optimization_level': 2, - 'pycache_prefix': 'env_pycache_prefix', - 'write_bytecode': 0, - 'verbose': 1, - 'buffered_stdio': 0, - 'stdio_encoding': 'iso8859-1', - 'stdio_errors': 'replace', - 'user_site_directory': 0, - 'faulthandler': 1, - } - def test_init_env(self): - self.check_config("init_env", self.INIT_ENV_CONFIG, self.INIT_ENV_PRECONFIG) + preconfig = { + 'allocator': PYMEM_ALLOCATOR_MALLOC, + } + config = { + 'use_hash_seed': 1, + 'hash_seed': 42, + 'tracemalloc': 2, + 'import_time': 1, + 'malloc_stats': 1, + 'inspect': 1, + 'optimization_level': 2, + 'module_search_path_env': '/my/path', + 'pycache_prefix': 'env_pycache_prefix', + 'write_bytecode': 0, + 'verbose': 1, + 'buffered_stdio': 0, + 'stdio_encoding': 'iso8859-1', + 'stdio_errors': 'replace', + 'user_site_directory': 0, + 'faulthandler': 1, + 'warnoptions': ['EnvVar'], + } + self.check_config("init_env", config, preconfig) def test_init_env_dev_mode(self): - preconfig = dict(self.INIT_ENV_PRECONFIG, - allocator=PYMEM_ALLOCATOR_DEBUG) - config = dict(self.INIT_ENV_CONFIG, - dev_mode=1, + preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG) + config = dict(dev_mode=1, + faulthandler=1, warnoptions=['default']) self.check_config("init_env_dev_mode", config, preconfig) def test_init_env_dev_mode_alloc(self): - preconfig = dict(self.INIT_ENV_PRECONFIG, - allocator=PYMEM_ALLOCATOR_MALLOC) - config = dict(self.INIT_ENV_CONFIG, - dev_mode=1, + preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC) + config = dict(dev_mode=1, + faulthandler=1, warnoptions=['default']) self.check_config("init_env_dev_mode_alloc", config, preconfig) @@ -800,6 +815,7 @@ def test_init_dont_configure_locale(self): # _PyPreConfig.configure_locale=0 preconfig = { 'configure_locale': 0, + 'coerce_c_locale': 0, } self.check_config("init_dont_configure_locale", {}, preconfig, api=CONFIG_INIT_PYTHON) diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 3dabf66de15afa..bc549369393fc7 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -568,7 +568,7 @@ static int test_init_dont_parse_argv(void) } -static void set_all_env_vars(void) +static void set_most_env_vars(void) { putenv("PYTHONHASHSEED=42"); putenv("PYTHONMALLOC=malloc"); @@ -585,13 +585,15 @@ static void set_all_env_vars(void) putenv("PYTHONNOUSERSITE=1"); putenv("PYTHONFAULTHANDLER=1"); putenv("PYTHONIOENCODING=iso8859-1:replace"); - /* FIXME: test PYTHONWARNINGS */ - /* FIXME: test PYTHONEXECUTABLE */ - /* FIXME: test PYTHONHOME */ - /* FIXME: test PYTHONDEBUG */ - /* FIXME: test PYTHONDUMPREFS */ - /* FIXME: test PYTHONCOERCECLOCALE */ - /* FIXME: test PYTHONPATH */ +} + + +static void set_all_env_vars(void) +{ + set_most_env_vars(); + + putenv("PYTHONWARNINGS=EnvVar"); + putenv("PYTHONPATH=/my/path"); } @@ -609,7 +611,6 @@ static int test_init_env(void) static void set_all_env_vars_dev_mode(void) { - set_all_env_vars(); putenv("PYTHONMALLOC="); putenv("PYTHONFAULTHANDLER="); putenv("PYTHONDEVMODE=1"); From 45a24b85f328ad07296123ebc994553983c7a915 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 20 May 2019 17:38:57 +0300 Subject: [PATCH 028/441] Pass _asyncio_internal=True into stream tests on windows (#13442) --- Lib/test/test_asyncio/test_windows_events.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 05f85159be0cd5..e201a0696796d6 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -100,9 +100,11 @@ async def _test_pipe(self): clients = [] for i in range(5): - stream_reader = asyncio.StreamReader(loop=self.loop) + stream_reader = asyncio.StreamReader(loop=self.loop, + _asyncio_internal=True) protocol = asyncio.StreamReaderProtocol(stream_reader, - loop=self.loop) + loop=self.loop, + _asyncio_internal=True) trans, proto = await self.loop.create_pipe_connection( lambda: protocol, ADDRESS) self.assertIsInstance(trans, asyncio.Transport) From 522ccef8690970fc4f78f51a3adb995f2547871a Mon Sep 17 00:00:00 2001 From: Geoff Shannon Date: Mon, 20 May 2019 08:06:16 -0700 Subject: [PATCH 029/441] bpo-22865: Expand on documentation for the pty.spawn function (GH-11980) --- Doc/library/pty.rst | 29 ++++++++++++++++--- Misc/ACKS | 1 + .../2019-02-21-18-13-50.bpo-22865.6hg6J8.rst | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 0ab766065d6e81..12268437d07e98 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -43,11 +43,32 @@ The :mod:`pty` module defines the following functions: Spawn a process, and connect its controlling terminal with the current process's standard io. This is often used to baffle programs which insist on - reading from the controlling terminal. + reading from the controlling terminal. It is expected that the process + spawned behind the pty will eventually terminate, and when it does *spawn* + will return. + + The functions *master_read* and *stdin_read* are passed a file descriptor + which they should read from, and they should always return a byte string. In + order to force spawn to return before the child process exits an + :exc:`OSError` should be thrown. + + The default implementation for both functions will read and return up to 1024 + bytes each time the function is called. The *master_read* callback is passed + the pseudoterminal’s master file descriptor to read output from the child + process, and *stdin_read* is passed file descriptor 0, to read from the + parent process's standard input. + + Returning an empty byte string from either callback is interpreted as an + end-of-file (EOF) condition, and that callback will not be called after + that. If *stdin_read* signals EOF the controlling terminal can no longer + communicate with the parent process OR the child process. Unless the child + process will quit without any input, *spawn* will then loop forever. If + *master_read* signals EOF the same behavior results (on linux at least). + + If both callbacks signal EOF then *spawn* will probably never return, unless + *select* throws an error on your platform when passed three empty lists. This + is a bug, documented in `issue 26228 `_. - The functions *master_read* and *stdin_read* should be functions which read from - a file descriptor. The defaults try to read 1024 bytes each time they are - called. .. versionchanged:: 3.4 :func:`spawn` now returns the status value from :func:`os.waitpid` diff --git a/Misc/ACKS b/Misc/ACKS index 77f19909b3005b..f9d01d00867999 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1859,3 +1859,4 @@ Zheao Li Carsten Klein Diego Rojas Edison Abahurire +Geoff Shannon diff --git a/Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst b/Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst new file mode 100644 index 00000000000000..67a4ed26bede37 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst @@ -0,0 +1 @@ +Add detail to the documentation on the `pty.spawn` function. \ No newline at end of file From 0f72147ce2b3d65235b41eddc6a57be40237b5c7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 20 May 2019 17:16:38 +0200 Subject: [PATCH 030/441] bpo-36763: Fix _PyRuntime.preconfig.coerce_c_locale (GH-13444) _PyRuntime.preconfig.coerce_c_locale can now be used to check if the C locale has been coerced. * Fix _Py_LegacyLocaleDetected(): don't attempt to coerce the C locale if LC_ALL environment variable is set. Add 'warn' parameter: emit_stderr_warning_for_legacy_locale() must not the LC_ALL env var. * _PyPreConfig_Write() sets coerce_c_locale to 0 if _Py_CoerceLegacyLocale() fails. --- Include/cpython/pylifecycle.h | 4 ++-- Python/preconfig.c | 26 ++++++++++++++++---------- Python/pylifecycle.c | 26 +++++++++++++++++++------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 1e1dabe59ff556..ba5666465d7e75 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -69,8 +69,8 @@ PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size); PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size); /* Legacy locale support */ -PyAPI_FUNC(void) _Py_CoerceLegacyLocale(int warn); -PyAPI_FUNC(int) _Py_LegacyLocaleDetected(void); +PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn); +PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); #ifdef __cplusplus diff --git a/Python/preconfig.c b/Python/preconfig.c index 71a6ee6c072ef0..4df6208cadb841 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -660,7 +660,7 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config) It is only coerced if if the LC_CTYPE locale is "C". */ if (config->coerce_c_locale < 0 || config->coerce_c_locale == 1) { /* The C locale enables the C locale coercion (PEP 538) */ - if (_Py_LegacyLocaleDetected()) { + if (_Py_LegacyLocaleDetected(0)) { config->coerce_c_locale = 2; } else { @@ -888,32 +888,38 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) - set the LC_CTYPE locale (coerce C locale, PEP 538) and set the UTF-8 mode (PEP 540) - If the memory allocator is changed, config is re-allocated with new - allocator. So calling _PyPreConfig_Clear(config) is safe after this call. + The applied configuration is written into _PyRuntime.preconfig. + If the C locale cannot be coerced, set coerce_c_locale to 0. Do nothing if called after Py_Initialize(): ignore the new pre-configuration. */ _PyInitError -_PyPreConfig_Write(const _PyPreConfig *config) +_PyPreConfig_Write(const _PyPreConfig *src_config) { + _PyPreConfig config; + _PyPreConfig_InitFromPreConfig(&config, src_config); + if (_PyRuntime.core_initialized) { /* bpo-34008: Calling this functions after Py_Initialize() ignores the new configuration. */ return _Py_INIT_OK(); } - PyMemAllocatorName name = (PyMemAllocatorName)config->allocator; + PyMemAllocatorName name = (PyMemAllocatorName)config.allocator; if (name != PYMEM_ALLOCATOR_NOT_SET) { if (_PyMem_SetupAllocators(name) < 0) { return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator"); } } - _PyPreConfig_SetGlobalConfig(config); + _PyPreConfig_SetGlobalConfig(&config); - if (config->configure_locale) { - if (config->coerce_c_locale) { - _Py_CoerceLegacyLocale(config->coerce_c_locale_warn); + if (config.configure_locale) { + if (config.coerce_c_locale) { + if (!_Py_CoerceLegacyLocale(config.coerce_c_locale_warn)) { + /* C locale not coerced */ + config.coerce_c_locale = 0; + } } /* Set LC_CTYPE to the user preferred locale */ @@ -921,7 +927,7 @@ _PyPreConfig_Write(const _PyPreConfig *config) } /* Write the new pre-configuration into _PyRuntime */ - _PyPreConfig_Copy(&_PyRuntime.preconfig, config); + _PyPreConfig_Copy(&_PyRuntime.preconfig, &config); return _Py_INIT_OK(); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 01f725f8f45a73..01344db410a0f1 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -231,9 +231,18 @@ init_importlib_external(PyInterpreterState *interp) */ int -_Py_LegacyLocaleDetected(void) +_Py_LegacyLocaleDetected(int warn) { #ifndef MS_WINDOWS + if (!warn) { + const char *locale_override = getenv("LC_ALL"); + if (locale_override != NULL && *locale_override != '\0') { + /* Don't coerce C locale if the LC_ALL environment variable + is set */ + return 0; + } + } + /* On non-Windows systems, the C locale is considered a legacy locale */ /* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat * the POSIX locale as a simple alias for the C locale, so @@ -257,7 +266,7 @@ static void emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) { const _PyPreConfig *preconfig = &runtime->preconfig; - if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected()) { + if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) { PySys_FormatStderr("%s", _C_LOCALE_WARNING); } } @@ -292,7 +301,7 @@ static const char C_LOCALE_COERCION_WARNING[] = "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale " "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n"; -static void +static int _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target) { const char *newloc = target->locale_name; @@ -304,7 +313,7 @@ _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target) if (setenv("LC_CTYPE", newloc, 1)) { fprintf(stderr, "Error setting LC_CTYPE, skipping C locale coercion\n"); - return; + return 0; } if (warn) { fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc); @@ -312,18 +321,20 @@ _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target) /* Reconfigure with the overridden environment variables */ _Py_SetLocaleFromEnv(LC_ALL); + return 1; } #endif -void +int _Py_CoerceLegacyLocale(int warn) { + int coerced = 0; #ifdef PY_COERCE_C_LOCALE char *oldloc = NULL; oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL)); if (oldloc == NULL) { - return; + return coerced; } const char *locale_override = getenv("LC_ALL"); @@ -345,7 +356,7 @@ _Py_CoerceLegacyLocale(int warn) } #endif /* Successfully configured locale, so make it the default */ - _coerce_default_locale_settings(warn, target); + coerced = _coerce_default_locale_settings(warn, target); goto done; } } @@ -357,6 +368,7 @@ _Py_CoerceLegacyLocale(int warn) done: PyMem_RawFree(oldloc); #endif + return coerced; } /* _Py_SetLocaleFromEnv() is a wrapper around setlocale(category, "") to From 77b3b7701a34ecf6316469e05b79bb91de2addfa Mon Sep 17 00:00:00 2001 From: Lisa Roach Date: Mon, 20 May 2019 09:19:53 -0700 Subject: [PATCH 031/441] bpo-26467: Adds AsyncMock for asyncio Mock library support (GH-9296) --- Doc/library/unittest.mock.rst | 215 ++++++- Doc/whatsnew/3.8.rst | 4 + Lib/unittest/mock.py | 406 ++++++++++++- Lib/unittest/test/testmock/testasync.py | 549 ++++++++++++++++++ Lib/unittest/test/testmock/testmock.py | 5 +- .../2018-09-13-20-33-24.bpo-26467.cahAk3.rst | 2 + 6 files changed, 1161 insertions(+), 20 deletions(-) create mode 100644 Lib/unittest/test/testmock/testasync.py create mode 100644 Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index ed00ee6d0c2d83..21e4709f81609e 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -201,9 +201,11 @@ The Mock Class .. testsetup:: + import asyncio + import inspect import unittest from unittest.mock import sentinel, DEFAULT, ANY - from unittest.mock import patch, call, Mock, MagicMock, PropertyMock + from unittest.mock import patch, call, Mock, MagicMock, PropertyMock, AsyncMock from unittest.mock import mock_open :class:`Mock` is a flexible mock object intended to replace the use of stubs and @@ -851,6 +853,217 @@ object:: >>> p.assert_called_once_with() +.. class:: AsyncMock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs) + + An asynchronous version of :class:`Mock`. The :class:`AsyncMock` object will + behave so the object is recognized as an async function, and the result of a + call is an awaitable. + + >>> mock = AsyncMock() + >>> asyncio.iscoroutinefunction(mock) + True + >>> inspect.isawaitable(mock()) + True + + The result of ``mock()`` is an async function which will have the outcome + of ``side_effect`` or ``return_value``: + + - if ``side_effect`` is a function, the async function will return the + result of that function, + - if ``side_effect`` is an exception, the async function will raise the + exception, + - if ``side_effect`` is an iterable, the async function will return the + next value of the iterable, however, if the sequence of result is + exhausted, ``StopIteration`` is raised immediately, + - if ``side_effect`` is not defined, the async function will return the + value defined by ``return_value``, hence, by default, the async function + returns a new :class:`AsyncMock` object. + + + Setting the *spec* of a :class:`Mock` or :class:`MagicMock` to an async function + will result in a coroutine object being returned after calling. + + >>> async def async_func(): pass + ... + >>> mock = MagicMock(async_func) + >>> mock + + >>> mock() + + + .. method:: assert_awaited() + + Assert that the mock was awaited at least once. + + >>> mock = AsyncMock() + >>> async def main(): + ... await mock() + ... + >>> asyncio.run(main()) + >>> mock.assert_awaited() + >>> mock_2 = AsyncMock() + >>> mock_2.assert_awaited() + Traceback (most recent call last): + ... + AssertionError: Expected mock to have been awaited. + + .. method:: assert_awaited_once() + + Assert that the mock was awaited exactly once. + + >>> mock = AsyncMock() + >>> async def main(): + ... await mock() + ... + >>> asyncio.run(main()) + >>> mock.assert_awaited_once() + >>> asyncio.run(main()) + >>> mock.method.assert_awaited_once() + Traceback (most recent call last): + ... + AssertionError: Expected mock to have been awaited once. Awaited 2 times. + + .. method:: assert_awaited_with(*args, **kwargs) + + Assert that the last await was with the specified arguments. + + >>> mock = AsyncMock() + >>> async def main(*args, **kwargs): + ... await mock(*args, **kwargs) + ... + >>> asyncio.run(main('foo', bar='bar')) + >>> mock.assert_awaited_with('foo', bar='bar') + >>> mock.assert_awaited_with('other') + Traceback (most recent call last): + ... + AssertionError: expected call not found. + Expected: mock('other') + Actual: mock('foo', bar='bar') + + .. method:: assert_awaited_once_with(*args, **kwargs) + + Assert that the mock was awaited exactly once and with the specified + arguments. + + >>> mock = AsyncMock() + >>> async def main(*args, **kwargs): + ... await mock(*args, **kwargs) + ... + >>> asyncio.run(main('foo', bar='bar')) + >>> mock.assert_awaited_once_with('foo', bar='bar') + >>> asyncio.run(main('foo', bar='bar')) + >>> mock.assert_awaited_once_with('foo', bar='bar') + Traceback (most recent call last): + ... + AssertionError: Expected mock to have been awaited once. Awaited 2 times. + + .. method:: assert_any_await(*args, **kwargs) + + Assert the mock has ever been awaited with the specified arguments. + + >>> mock = AsyncMock() + >>> async def main(*args, **kwargs): + ... await mock(*args, **kwargs) + ... + >>> asyncio.run(main('foo', bar='bar')) + >>> asyncio.run(main('hello')) + >>> mock.assert_any_await('foo', bar='bar') + >>> mock.assert_any_await('other') + Traceback (most recent call last): + ... + AssertionError: mock('other') await not found + + .. method:: assert_has_awaits(calls, any_order=False) + + Assert the mock has been awaited with the specified calls. + The :attr:`await_args_list` list is checked for the awaits. + + If *any_order* is False (the default) then the awaits must be + sequential. There can be extra calls before or after the + specified awaits. + + If *any_order* is True then the awaits can be in any order, but + they must all appear in :attr:`await_args_list`. + + >>> mock = AsyncMock() + >>> async def main(*args, **kwargs): + ... await mock(*args, **kwargs) + ... + >>> calls = [call("foo"), call("bar")] + >>> mock.assert_has_calls(calls) + Traceback (most recent call last): + ... + AssertionError: Calls not found. + Expected: [call('foo'), call('bar')] + >>> asyncio.run(main('foo')) + >>> asyncio.run(main('bar')) + >>> mock.assert_has_calls(calls) + + .. method:: assert_not_awaited() + + Assert that the mock was never awaited. + + >>> mock = AsyncMock() + >>> mock.assert_not_awaited() + + .. method:: reset_mock(*args, **kwargs) + + See :func:`Mock.reset_mock`. Also sets :attr:`await_count` to 0, + :attr:`await_args` to None, and clears the :attr:`await_args_list`. + + .. attribute:: await_count + + An integer keeping track of how many times the mock object has been awaited. + + >>> mock = AsyncMock() + >>> async def main(): + ... await mock() + ... + >>> asyncio.run(main()) + >>> mock.await_count + 1 + >>> asyncio.run(main()) + >>> mock.await_count + 2 + + .. attribute:: await_args + + This is either ``None`` (if the mock hasn’t been awaited), or the arguments that + the mock was last awaited with. Functions the same as :attr:`Mock.call_args`. + + >>> mock = AsyncMock() + >>> async def main(*args): + ... await mock(*args) + ... + >>> mock.await_args + >>> asyncio.run(main('foo')) + >>> mock.await_args + call('foo') + >>> asyncio.run(main('bar')) + >>> mock.await_args + call('bar') + + + .. attribute:: await_args_list + + This is a list of all the awaits made to the mock object in sequence (so the + length of the list is the number of times it has been awaited). Before any + awaits have been made it is an empty list. + + >>> mock = AsyncMock() + >>> async def main(*args): + ... await mock(*args) + ... + >>> mock.await_args_list + [] + >>> asyncio.run(main('foo')) + >>> mock.await_args_list + [call('foo')] + >>> asyncio.run(main('bar')) + >>> mock.await_args_list + [call('foo'), call('bar')] + + Calling ~~~~~~~ diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 07da4047a383a7..0a79b6ce1a652c 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -538,6 +538,10 @@ unicodedata unittest -------- +* XXX Added :class:`AsyncMock` to support an asynchronous version of :class:`Mock`. + Appropriate new assert functions for testing have been added as well. + (Contributed by Lisa Roach in :issue:`26467`). + * Added :func:`~unittest.addModuleCleanup()` and :meth:`~unittest.TestCase.addClassCleanup()` to unittest to support cleanups for :func:`~unittest.setUpModule()` and diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 47ed06c6f486af..166c1003769848 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -13,6 +13,7 @@ 'ANY', 'call', 'create_autospec', + 'AsyncMock', 'FILTER_DIR', 'NonCallableMock', 'NonCallableMagicMock', @@ -24,13 +25,13 @@ __version__ = '1.0' - +import asyncio import io import inspect import pprint import sys import builtins -from types import ModuleType, MethodType +from types import CodeType, ModuleType, MethodType from unittest.util import safe_repr from functools import wraps, partial @@ -43,6 +44,13 @@ # Without this, the __class__ properties wouldn't be set correctly _safe_super = super +def _is_async_obj(obj): + if getattr(obj, '__code__', None): + return asyncio.iscoroutinefunction(obj) or inspect.isawaitable(obj) + else: + return False + + def _is_instance_mock(obj): # can't use isinstance on Mock objects because they override __class__ # The base class for all mocks is NonCallableMock @@ -355,7 +363,20 @@ def __new__(cls, *args, **kw): # every instance has its own class # so we can create magic methods on the # class without stomping on other mocks - new = type(cls.__name__, (cls,), {'__doc__': cls.__doc__}) + bases = (cls,) + if not issubclass(cls, AsyncMock): + # Check if spec is an async object or function + sig = inspect.signature(NonCallableMock.__init__) + bound_args = sig.bind_partial(cls, *args, **kw).arguments + spec_arg = [ + arg for arg in bound_args.keys() + if arg.startswith('spec') + ] + if spec_arg: + # what if spec_set is different than spec? + if _is_async_obj(bound_args[spec_arg[0]]): + bases = (AsyncMockMixin, cls,) + new = type(cls.__name__, bases, {'__doc__': cls.__doc__}) instance = object.__new__(new) return instance @@ -431,6 +452,11 @@ def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False, _eat_self=False): _spec_class = None _spec_signature = None + _spec_asyncs = [] + + for attr in dir(spec): + if asyncio.iscoroutinefunction(getattr(spec, attr, None)): + _spec_asyncs.append(attr) if spec is not None and not _is_list(spec): if isinstance(spec, type): @@ -448,7 +474,7 @@ def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False, __dict__['_spec_set'] = spec_set __dict__['_spec_signature'] = _spec_signature __dict__['_mock_methods'] = spec - + __dict__['_spec_asyncs'] = _spec_asyncs def __get_return_value(self): ret = self._mock_return_value @@ -886,7 +912,15 @@ def _get_child_mock(self, **kw): For non-callable mocks the callable variant will be used (rather than any custom subclass).""" + _new_name = kw.get("_new_name") + if _new_name in self.__dict__['_spec_asyncs']: + return AsyncMock(**kw) + _type = type(self) + if issubclass(_type, MagicMock) and _new_name in _async_method_magics: + klass = AsyncMock + if issubclass(_type, AsyncMockMixin): + klass = MagicMock if not issubclass(_type, CallableMixin): if issubclass(_type, NonCallableMagicMock): klass = MagicMock @@ -932,14 +966,12 @@ def _try_iter(obj): return obj - class CallableMixin(Base): def __init__(self, spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, **kwargs): self.__dict__['_mock_return_value'] = return_value - _safe_super(CallableMixin, self).__init__( spec, wraps, name, spec_set, parent, _spec_state, _new_name, _new_parent, **kwargs @@ -1081,7 +1113,6 @@ class or instance) that acts as the specification for the mock object. If """ - def _dot_lookup(thing, comp, import_path): try: return getattr(thing, comp) @@ -1279,8 +1310,10 @@ def __enter__(self): if isinstance(original, type): # If we're patching out a class and there is a spec inherit = True - - Klass = MagicMock + if spec is None and _is_async_obj(original): + Klass = AsyncMock + else: + Klass = MagicMock _kwargs = {} if new_callable is not None: Klass = new_callable @@ -1292,7 +1325,9 @@ def __enter__(self): not_callable = '__call__' not in this_spec else: not_callable = not callable(this_spec) - if not_callable: + if _is_async_obj(this_spec): + Klass = AsyncMock + elif not_callable: Klass = NonCallableMagicMock if spec is not None: @@ -1733,7 +1768,7 @@ def _patch_stopall(): '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__', '__getstate__', '__setstate__', '__getformat__', '__setformat__', '__repr__', '__dir__', '__subclasses__', '__format__', - '__getnewargs_ex__', + '__getnewargs_ex__', '__aenter__', '__aexit__', '__anext__', '__aiter__', } @@ -1750,6 +1785,11 @@ def method(self, *args, **kw): ' '.join([magic_methods, numerics, inplace, right]).split() } +# Magic methods used for async `with` statements +_async_method_magics = {"__aenter__", "__aexit__", "__anext__"} +# `__aiter__` is a plain function but used with async calls +_async_magics = _async_method_magics | {"__aiter__"} + _all_magics = _magics | _non_defaults _unsupported_magics = { @@ -1779,6 +1819,7 @@ def method(self, *args, **kw): '__float__': 1.0, '__bool__': True, '__index__': 1, + '__aexit__': False, } @@ -1811,10 +1852,19 @@ def __iter__(): return iter(ret_val) return __iter__ +def _get_async_iter(self): + def __aiter__(): + ret_val = self.__aiter__._mock_return_value + if ret_val is DEFAULT: + return _AsyncIterator(iter([])) + return _AsyncIterator(iter(ret_val)) + return __aiter__ + _side_effect_methods = { '__eq__': _get_eq, '__ne__': _get_ne, '__iter__': _get_iter, + '__aiter__': _get_async_iter } @@ -1879,8 +1929,33 @@ def mock_add_spec(self, spec, spec_set=False): self._mock_set_magics() +class AsyncMagicMixin: + def __init__(self, *args, **kw): + self._mock_set_async_magics() # make magic work for kwargs in init + _safe_super(AsyncMagicMixin, self).__init__(*args, **kw) + self._mock_set_async_magics() # fix magic broken by upper level init + + def _mock_set_async_magics(self): + these_magics = _async_magics -class MagicMock(MagicMixin, Mock): + if getattr(self, "_mock_methods", None) is not None: + these_magics = _async_magics.intersection(self._mock_methods) + remove_magics = _async_magics - these_magics + + for entry in remove_magics: + if entry in type(self).__dict__: + # remove unneeded magic methods + delattr(self, entry) + + # don't overwrite existing attributes if called a second time + these_magics = these_magics - set(type(self).__dict__) + + _type = type(self) + for entry in these_magics: + setattr(_type, entry, MagicProxy(entry, self)) + + +class MagicMock(MagicMixin, AsyncMagicMixin, Mock): """ MagicMock is a subclass of Mock with default implementations of most of the magic methods. You can use MagicMock without having to @@ -1920,6 +1995,218 @@ def __get__(self, obj, _type=None): return self.create_mock() +class AsyncMockMixin(Base): + awaited = _delegating_property('awaited') + await_count = _delegating_property('await_count') + await_args = _delegating_property('await_args') + await_args_list = _delegating_property('await_args_list') + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # asyncio.iscoroutinefunction() checks _is_coroutine property to say if an + # object is a coroutine. Without this check it looks to see if it is a + # function/method, which in this case it is not (since it is an + # AsyncMock). + # It is set through __dict__ because when spec_set is True, this + # attribute is likely undefined. + self.__dict__['_is_coroutine'] = asyncio.coroutines._is_coroutine + self.__dict__['_mock_awaited'] = _AwaitEvent(self) + self.__dict__['_mock_await_count'] = 0 + self.__dict__['_mock_await_args'] = None + self.__dict__['_mock_await_args_list'] = _CallList() + code_mock = NonCallableMock(spec_set=CodeType) + code_mock.co_flags = inspect.CO_COROUTINE + self.__dict__['__code__'] = code_mock + + async def _mock_call(_mock_self, *args, **kwargs): + self = _mock_self + try: + result = super()._mock_call(*args, **kwargs) + except (BaseException, StopIteration) as e: + side_effect = self.side_effect + if side_effect is not None and not callable(side_effect): + raise + return await _raise(e) + + _call = self.call_args + + async def proxy(): + try: + if inspect.isawaitable(result): + return await result + else: + return result + finally: + self.await_count += 1 + self.await_args = _call + self.await_args_list.append(_call) + await self.awaited._notify() + + return await proxy() + + def assert_awaited(_mock_self): + """ + Assert that the mock was awaited at least once. + """ + self = _mock_self + if self.await_count == 0: + msg = f"Expected {self._mock_name or 'mock'} to have been awaited." + raise AssertionError(msg) + + def assert_awaited_once(_mock_self): + """ + Assert that the mock was awaited exactly once. + """ + self = _mock_self + if not self.await_count == 1: + msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once." + f" Awaited {self.await_count} times.") + raise AssertionError(msg) + + def assert_awaited_with(_mock_self, *args, **kwargs): + """ + Assert that the last await was with the specified arguments. + """ + self = _mock_self + if self.await_args is None: + expected = self._format_mock_call_signature(args, kwargs) + raise AssertionError(f'Expected await: {expected}\nNot awaited') + + def _error_message(): + msg = self._format_mock_failure_message(args, kwargs) + return msg + + expected = self._call_matcher((args, kwargs)) + actual = self._call_matcher(self.await_args) + if expected != actual: + cause = expected if isinstance(expected, Exception) else None + raise AssertionError(_error_message()) from cause + + def assert_awaited_once_with(_mock_self, *args, **kwargs): + """ + Assert that the mock was awaited exactly once and with the specified + arguments. + """ + self = _mock_self + if not self.await_count == 1: + msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once." + f" Awaited {self.await_count} times.") + raise AssertionError(msg) + return self.assert_awaited_with(*args, **kwargs) + + def assert_any_await(_mock_self, *args, **kwargs): + """ + Assert the mock has ever been awaited with the specified arguments. + """ + self = _mock_self + expected = self._call_matcher((args, kwargs)) + actual = [self._call_matcher(c) for c in self.await_args_list] + if expected not in actual: + cause = expected if isinstance(expected, Exception) else None + expected_string = self._format_mock_call_signature(args, kwargs) + raise AssertionError( + '%s await not found' % expected_string + ) from cause + + def assert_has_awaits(_mock_self, calls, any_order=False): + """ + Assert the mock has been awaited with the specified calls. + The :attr:`await_args_list` list is checked for the awaits. + + If `any_order` is False (the default) then the awaits must be + sequential. There can be extra calls before or after the + specified awaits. + + If `any_order` is True then the awaits can be in any order, but + they must all appear in :attr:`await_args_list`. + """ + self = _mock_self + expected = [self._call_matcher(c) for c in calls] + cause = expected if isinstance(expected, Exception) else None + all_awaits = _CallList(self._call_matcher(c) for c in self.await_args_list) + if not any_order: + if expected not in all_awaits: + raise AssertionError( + f'Awaits not found.\nExpected: {_CallList(calls)}\n', + f'Actual: {self.await_args_list}' + ) from cause + return + + all_awaits = list(all_awaits) + + not_found = [] + for kall in expected: + try: + all_awaits.remove(kall) + except ValueError: + not_found.append(kall) + if not_found: + raise AssertionError( + '%r not all found in await list' % (tuple(not_found),) + ) from cause + + def assert_not_awaited(_mock_self): + """ + Assert that the mock was never awaited. + """ + self = _mock_self + if self.await_count != 0: + msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once." + f" Awaited {self.await_count} times.") + raise AssertionError(msg) + + def reset_mock(self, *args, **kwargs): + """ + See :func:`.Mock.reset_mock()` + """ + super().reset_mock(*args, **kwargs) + self.await_count = 0 + self.await_args = None + self.await_args_list = _CallList() + + +class AsyncMock(AsyncMockMixin, AsyncMagicMixin, Mock): + """ + Enhance :class:`Mock` with features allowing to mock + an async function. + + The :class:`AsyncMock` object will behave so the object is + recognized as an async function, and the result of a call is an awaitable: + + >>> mock = AsyncMock() + >>> asyncio.iscoroutinefunction(mock) + True + >>> inspect.isawaitable(mock()) + True + + + The result of ``mock()`` is an async function which will have the outcome + of ``side_effect`` or ``return_value``: + + - if ``side_effect`` is a function, the async function will return the + result of that function, + - if ``side_effect`` is an exception, the async function will raise the + exception, + - if ``side_effect`` is an iterable, the async function will return the + next value of the iterable, however, if the sequence of result is + exhausted, ``StopIteration`` is raised immediately, + - if ``side_effect`` is not defined, the async function will return the + value defined by ``return_value``, hence, by default, the async function + returns a new :class:`AsyncMock` object. + + If the outcome of ``side_effect`` or ``return_value`` is an async function, + the mock async function obtained when the mock object is called will be this + async function itself (and not an async function returning an async + function). + + The test author can also specify a wrapped object with ``wraps``. In this + case, the :class:`Mock` object behavior is the same as with an + :class:`.Mock` object: the wrapped object may have methods + defined as async function functions. + + Based on Martin Richard's asyntest project. + """ + class _ANY(object): "A helper object that compares equal to everything." @@ -2145,7 +2432,6 @@ def call_list(self): call = _Call(from_kall=False) - def create_autospec(spec, spec_set=False, instance=False, _parent=None, _name=None, **kwargs): """Create a mock object using another object as a spec. Attributes on the @@ -2171,7 +2457,10 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, spec = type(spec) is_type = isinstance(spec, type) - + if getattr(spec, '__code__', None): + is_async_func = asyncio.iscoroutinefunction(spec) + else: + is_async_func = False _kwargs = {'spec': spec} if spec_set: _kwargs = {'spec_set': spec} @@ -2188,6 +2477,11 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, # descriptors don't have a spec # because we don't know what type they return _kwargs = {} + elif is_async_func: + if instance: + raise RuntimeError("Instance can not be True when create_autospec " + "is mocking an async function") + Klass = AsyncMock elif not _callable(spec): Klass = NonCallableMagicMock elif is_type and instance and not _instance_callable(spec): @@ -2204,9 +2498,26 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, name=_name, **_kwargs) if isinstance(spec, FunctionTypes): + wrapped_mock = mock # should only happen at the top level because we don't # recurse for functions mock = _set_signature(mock, spec) + if is_async_func: + mock._is_coroutine = asyncio.coroutines._is_coroutine + mock.await_count = 0 + mock.await_args = None + mock.await_args_list = _CallList() + + for a in ('assert_awaited', + 'assert_awaited_once', + 'assert_awaited_with', + 'assert_awaited_once_with', + 'assert_any_await', + 'assert_has_awaits', + 'assert_not_awaited'): + def f(*args, **kwargs): + return getattr(wrapped_mock, a)(*args, **kwargs) + setattr(mock, a, f) else: _check_signature(spec, mock, is_type, instance) @@ -2250,9 +2561,13 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, skipfirst = _must_skip(spec, entry, is_type) kwargs['_eat_self'] = skipfirst - new = MagicMock(parent=parent, name=entry, _new_name=entry, - _new_parent=parent, - **kwargs) + if asyncio.iscoroutinefunction(original): + child_klass = AsyncMock + else: + child_klass = MagicMock + new = child_klass(parent=parent, name=entry, _new_name=entry, + _new_parent=parent, + **kwargs) mock._mock_children[entry] = new _check_signature(original, new, skipfirst=skipfirst) @@ -2438,3 +2753,60 @@ def seal(mock): continue if m._mock_new_parent is mock: seal(m) + + +async def _raise(exception): + raise exception + + +class _AsyncIterator: + """ + Wraps an iterator in an asynchronous iterator. + """ + def __init__(self, iterator): + self.iterator = iterator + code_mock = NonCallableMock(spec_set=CodeType) + code_mock.co_flags = inspect.CO_ITERABLE_COROUTINE + self.__dict__['__code__'] = code_mock + + def __aiter__(self): + return self + + async def __anext__(self): + try: + return next(self.iterator) + except StopIteration: + pass + raise StopAsyncIteration + + +class _AwaitEvent: + def __init__(self, mock): + self._mock = mock + self._condition = None + + async def _notify(self): + condition = self._get_condition() + try: + await condition.acquire() + condition.notify_all() + finally: + condition.release() + + def _get_condition(self): + """ + Creation of condition is delayed, to minimize the chance of using the + wrong loop. + A user may create a mock with _AwaitEvent before selecting the + execution loop. Requiring a user to delay creation is error-prone and + inflexible. Instead, condition is created when user actually starts to + use the mock. + """ + # No synchronization is needed: + # - asyncio is thread unsafe + # - there are no awaits here, method will be executed without + # switching asyncio context. + if self._condition is None: + self._condition = asyncio.Condition() + + return self._condition diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py new file mode 100644 index 00000000000000..a9aa1434b963f1 --- /dev/null +++ b/Lib/unittest/test/testmock/testasync.py @@ -0,0 +1,549 @@ +import asyncio +import inspect +import unittest + +from unittest.mock import call, AsyncMock, patch, MagicMock, create_autospec + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +class AsyncClass: + def __init__(self): + pass + async def async_method(self): + pass + def normal_method(self): + pass + +async def async_func(): + pass + +def normal_func(): + pass + +class NormalClass(object): + def a(self): + pass + + +async_foo_name = f'{__name__}.AsyncClass' +normal_foo_name = f'{__name__}.NormalClass' + + +class AsyncPatchDecoratorTest(unittest.TestCase): + def test_is_coroutine_function_patch(self): + @patch.object(AsyncClass, 'async_method') + def test_async(mock_method): + self.assertTrue(asyncio.iscoroutinefunction(mock_method)) + test_async() + + def test_is_async_patch(self): + @patch.object(AsyncClass, 'async_method') + def test_async(mock_method): + m = mock_method() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + @patch(f'{async_foo_name}.async_method') + def test_no_parent_attribute(mock_method): + m = mock_method() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + test_async() + test_no_parent_attribute() + + def test_is_AsyncMock_patch(self): + @patch.object(AsyncClass, 'async_method') + def test_async(mock_method): + self.assertIsInstance(mock_method, AsyncMock) + + test_async() + + +class AsyncPatchCMTest(unittest.TestCase): + def test_is_async_function_cm(self): + def test_async(): + with patch.object(AsyncClass, 'async_method') as mock_method: + self.assertTrue(asyncio.iscoroutinefunction(mock_method)) + + test_async() + + def test_is_async_cm(self): + def test_async(): + with patch.object(AsyncClass, 'async_method') as mock_method: + m = mock_method() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + test_async() + + def test_is_AsyncMock_cm(self): + def test_async(): + with patch.object(AsyncClass, 'async_method') as mock_method: + self.assertIsInstance(mock_method, AsyncMock) + + test_async() + + +class AsyncMockTest(unittest.TestCase): + def test_iscoroutinefunction_default(self): + mock = AsyncMock() + self.assertTrue(asyncio.iscoroutinefunction(mock)) + + def test_iscoroutinefunction_function(self): + async def foo(): pass + mock = AsyncMock(foo) + self.assertTrue(asyncio.iscoroutinefunction(mock)) + self.assertTrue(inspect.iscoroutinefunction(mock)) + + def test_isawaitable(self): + mock = AsyncMock() + m = mock() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + self.assertIn('assert_awaited', dir(mock)) + + def test_iscoroutinefunction_normal_function(self): + def foo(): pass + mock = AsyncMock(foo) + self.assertTrue(asyncio.iscoroutinefunction(mock)) + self.assertTrue(inspect.iscoroutinefunction(mock)) + + def test_future_isfuture(self): + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + fut = asyncio.Future() + loop.stop() + loop.close() + mock = AsyncMock(fut) + self.assertIsInstance(mock, asyncio.Future) + + +class AsyncAutospecTest(unittest.TestCase): + def test_is_AsyncMock_patch(self): + @patch(async_foo_name, autospec=True) + def test_async(mock_method): + self.assertIsInstance(mock_method.async_method, AsyncMock) + self.assertIsInstance(mock_method, MagicMock) + + @patch(async_foo_name, autospec=True) + def test_normal_method(mock_method): + self.assertIsInstance(mock_method.normal_method, MagicMock) + + test_async() + test_normal_method() + + def test_create_autospec_instance(self): + with self.assertRaises(RuntimeError): + create_autospec(async_func, instance=True) + + def test_create_autospec(self): + spec = create_autospec(async_func) + self.assertTrue(asyncio.iscoroutinefunction(spec)) + + +class AsyncSpecTest(unittest.TestCase): + def test_spec_as_async_positional_magicmock(self): + mock = MagicMock(async_func) + self.assertIsInstance(mock, MagicMock) + m = mock() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + def test_spec_as_async_kw_magicmock(self): + mock = MagicMock(spec=async_func) + self.assertIsInstance(mock, MagicMock) + m = mock() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + def test_spec_as_async_kw_AsyncMock(self): + mock = AsyncMock(spec=async_func) + self.assertIsInstance(mock, AsyncMock) + m = mock() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + def test_spec_as_async_positional_AsyncMock(self): + mock = AsyncMock(async_func) + self.assertIsInstance(mock, AsyncMock) + m = mock() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + def test_spec_as_normal_kw_AsyncMock(self): + mock = AsyncMock(spec=normal_func) + self.assertIsInstance(mock, AsyncMock) + m = mock() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + def test_spec_as_normal_positional_AsyncMock(self): + mock = AsyncMock(normal_func) + self.assertIsInstance(mock, AsyncMock) + m = mock() + self.assertTrue(inspect.isawaitable(m)) + asyncio.run(m) + + def test_spec_async_mock(self): + @patch.object(AsyncClass, 'async_method', spec=True) + def test_async(mock_method): + self.assertIsInstance(mock_method, AsyncMock) + + test_async() + + def test_spec_parent_not_async_attribute_is(self): + @patch(async_foo_name, spec=True) + def test_async(mock_method): + self.assertIsInstance(mock_method, MagicMock) + self.assertIsInstance(mock_method.async_method, AsyncMock) + + test_async() + + def test_target_async_spec_not(self): + @patch.object(AsyncClass, 'async_method', spec=NormalClass.a) + def test_async_attribute(mock_method): + self.assertIsInstance(mock_method, MagicMock) + self.assertFalse(inspect.iscoroutine(mock_method)) + self.assertFalse(inspect.isawaitable(mock_method)) + + test_async_attribute() + + def test_target_not_async_spec_is(self): + @patch.object(NormalClass, 'a', spec=async_func) + def test_attribute_not_async_spec_is(mock_async_func): + self.assertIsInstance(mock_async_func, AsyncMock) + test_attribute_not_async_spec_is() + + def test_spec_async_attributes(self): + @patch(normal_foo_name, spec=AsyncClass) + def test_async_attributes_coroutines(MockNormalClass): + self.assertIsInstance(MockNormalClass.async_method, AsyncMock) + self.assertIsInstance(MockNormalClass, MagicMock) + + test_async_attributes_coroutines() + + +class AsyncSpecSetTest(unittest.TestCase): + def test_is_AsyncMock_patch(self): + @patch.object(AsyncClass, 'async_method', spec_set=True) + def test_async(async_method): + self.assertIsInstance(async_method, AsyncMock) + + def test_is_async_AsyncMock(self): + mock = AsyncMock(spec_set=AsyncClass.async_method) + self.assertTrue(asyncio.iscoroutinefunction(mock)) + self.assertIsInstance(mock, AsyncMock) + + def test_is_child_AsyncMock(self): + mock = MagicMock(spec_set=AsyncClass) + self.assertTrue(asyncio.iscoroutinefunction(mock.async_method)) + self.assertFalse(asyncio.iscoroutinefunction(mock.normal_method)) + self.assertIsInstance(mock.async_method, AsyncMock) + self.assertIsInstance(mock.normal_method, MagicMock) + self.assertIsInstance(mock, MagicMock) + + +class AsyncArguments(unittest.TestCase): + def test_add_return_value(self): + async def addition(self, var): + return var + 1 + + mock = AsyncMock(addition, return_value=10) + output = asyncio.run(mock(5)) + + self.assertEqual(output, 10) + + def test_add_side_effect_exception(self): + async def addition(var): + return var + 1 + mock = AsyncMock(addition, side_effect=Exception('err')) + with self.assertRaises(Exception): + asyncio.run(mock(5)) + + def test_add_side_effect_function(self): + async def addition(var): + return var + 1 + mock = AsyncMock(side_effect=addition) + result = asyncio.run(mock(5)) + self.assertEqual(result, 6) + + def test_add_side_effect_iterable(self): + vals = [1, 2, 3] + mock = AsyncMock(side_effect=vals) + for item in vals: + self.assertEqual(item, asyncio.run(mock())) + + with self.assertRaises(RuntimeError) as e: + asyncio.run(mock()) + self.assertEqual( + e.exception, + RuntimeError('coroutine raised StopIteration') + ) + + +class AsyncContextManagerTest(unittest.TestCase): + class WithAsyncContextManager: + def __init__(self): + self.entered = False + self.exited = False + + async def __aenter__(self, *args, **kwargs): + self.entered = True + return self + + async def __aexit__(self, *args, **kwargs): + self.exited = True + + def test_magic_methods_are_async_mocks(self): + mock = MagicMock(self.WithAsyncContextManager()) + self.assertIsInstance(mock.__aenter__, AsyncMock) + self.assertIsInstance(mock.__aexit__, AsyncMock) + + def test_mock_supports_async_context_manager(self): + called = False + instance = self.WithAsyncContextManager() + mock_instance = MagicMock(instance) + + async def use_context_manager(): + nonlocal called + async with mock_instance as result: + called = True + return result + + result = asyncio.run(use_context_manager()) + self.assertFalse(instance.entered) + self.assertFalse(instance.exited) + self.assertTrue(called) + self.assertTrue(mock_instance.entered) + self.assertTrue(mock_instance.exited) + self.assertTrue(mock_instance.__aenter__.called) + self.assertTrue(mock_instance.__aexit__.called) + self.assertIsNot(mock_instance, result) + self.assertIsInstance(result, AsyncMock) + + def test_mock_customize_async_context_manager(self): + instance = self.WithAsyncContextManager() + mock_instance = MagicMock(instance) + + expected_result = object() + mock_instance.__aenter__.return_value = expected_result + + async def use_context_manager(): + async with mock_instance as result: + return result + + self.assertIs(asyncio.run(use_context_manager()), expected_result) + + def test_mock_customize_async_context_manager_with_coroutine(self): + enter_called = False + exit_called = False + + async def enter_coroutine(*args): + nonlocal enter_called + enter_called = True + + async def exit_coroutine(*args): + nonlocal exit_called + exit_called = True + + instance = self.WithAsyncContextManager() + mock_instance = MagicMock(instance) + + mock_instance.__aenter__ = enter_coroutine + mock_instance.__aexit__ = exit_coroutine + + async def use_context_manager(): + async with mock_instance: + pass + + asyncio.run(use_context_manager()) + self.assertTrue(enter_called) + self.assertTrue(exit_called) + + def test_context_manager_raise_exception_by_default(self): + async def raise_in(context_manager): + async with context_manager: + raise TypeError() + + instance = self.WithAsyncContextManager() + mock_instance = MagicMock(instance) + with self.assertRaises(TypeError): + asyncio.run(raise_in(mock_instance)) + + +class AsyncIteratorTest(unittest.TestCase): + class WithAsyncIterator(object): + def __init__(self): + self.items = ["foo", "NormalFoo", "baz"] + + def __aiter__(self): + return self + + async def __anext__(self): + try: + return self.items.pop() + except IndexError: + pass + + raise StopAsyncIteration + + def test_mock_aiter_and_anext(self): + instance = self.WithAsyncIterator() + mock_instance = MagicMock(instance) + + self.assertEqual(asyncio.iscoroutine(instance.__aiter__), + asyncio.iscoroutine(mock_instance.__aiter__)) + self.assertEqual(asyncio.iscoroutine(instance.__anext__), + asyncio.iscoroutine(mock_instance.__anext__)) + + iterator = instance.__aiter__() + if asyncio.iscoroutine(iterator): + iterator = asyncio.run(iterator) + + mock_iterator = mock_instance.__aiter__() + if asyncio.iscoroutine(mock_iterator): + mock_iterator = asyncio.run(mock_iterator) + + self.assertEqual(asyncio.iscoroutine(iterator.__aiter__), + asyncio.iscoroutine(mock_iterator.__aiter__)) + self.assertEqual(asyncio.iscoroutine(iterator.__anext__), + asyncio.iscoroutine(mock_iterator.__anext__)) + + def test_mock_async_for(self): + async def iterate(iterator): + accumulator = [] + async for item in iterator: + accumulator.append(item) + + return accumulator + + expected = ["FOO", "BAR", "BAZ"] + with self.subTest("iterate through default value"): + mock_instance = MagicMock(self.WithAsyncIterator()) + self.assertEqual([], asyncio.run(iterate(mock_instance))) + + with self.subTest("iterate through set return_value"): + mock_instance = MagicMock(self.WithAsyncIterator()) + mock_instance.__aiter__.return_value = expected[:] + self.assertEqual(expected, asyncio.run(iterate(mock_instance))) + + with self.subTest("iterate through set return_value iterator"): + mock_instance = MagicMock(self.WithAsyncIterator()) + mock_instance.__aiter__.return_value = iter(expected[:]) + self.assertEqual(expected, asyncio.run(iterate(mock_instance))) + + +class AsyncMockAssert(unittest.TestCase): + def setUp(self): + self.mock = AsyncMock() + + async def _runnable_test(self, *args): + if not args: + await self.mock() + else: + await self.mock(*args) + + def test_assert_awaited(self): + with self.assertRaises(AssertionError): + self.mock.assert_awaited() + + asyncio.run(self._runnable_test()) + self.mock.assert_awaited() + + def test_assert_awaited_once(self): + with self.assertRaises(AssertionError): + self.mock.assert_awaited_once() + + asyncio.run(self._runnable_test()) + self.mock.assert_awaited_once() + + asyncio.run(self._runnable_test()) + with self.assertRaises(AssertionError): + self.mock.assert_awaited_once() + + def test_assert_awaited_with(self): + asyncio.run(self._runnable_test()) + with self.assertRaises(AssertionError): + self.mock.assert_awaited_with('foo') + + asyncio.run(self._runnable_test('foo')) + self.mock.assert_awaited_with('foo') + + asyncio.run(self._runnable_test('SomethingElse')) + with self.assertRaises(AssertionError): + self.mock.assert_awaited_with('foo') + + def test_assert_awaited_once_with(self): + with self.assertRaises(AssertionError): + self.mock.assert_awaited_once_with('foo') + + asyncio.run(self._runnable_test('foo')) + self.mock.assert_awaited_once_with('foo') + + asyncio.run(self._runnable_test('foo')) + with self.assertRaises(AssertionError): + self.mock.assert_awaited_once_with('foo') + + def test_assert_any_wait(self): + with self.assertRaises(AssertionError): + self.mock.assert_any_await('NormalFoo') + + asyncio.run(self._runnable_test('foo')) + with self.assertRaises(AssertionError): + self.mock.assert_any_await('NormalFoo') + + asyncio.run(self._runnable_test('NormalFoo')) + self.mock.assert_any_await('NormalFoo') + + asyncio.run(self._runnable_test('SomethingElse')) + self.mock.assert_any_await('NormalFoo') + + def test_assert_has_awaits_no_order(self): + calls = [call('NormalFoo'), call('baz')] + + with self.assertRaises(AssertionError): + self.mock.assert_has_awaits(calls) + + asyncio.run(self._runnable_test('foo')) + with self.assertRaises(AssertionError): + self.mock.assert_has_awaits(calls) + + asyncio.run(self._runnable_test('NormalFoo')) + with self.assertRaises(AssertionError): + self.mock.assert_has_awaits(calls) + + asyncio.run(self._runnable_test('baz')) + self.mock.assert_has_awaits(calls) + + asyncio.run(self._runnable_test('SomethingElse')) + self.mock.assert_has_awaits(calls) + + def test_assert_has_awaits_ordered(self): + calls = [call('NormalFoo'), call('baz')] + with self.assertRaises(AssertionError): + self.mock.assert_has_awaits(calls, any_order=True) + + asyncio.run(self._runnable_test('baz')) + with self.assertRaises(AssertionError): + self.mock.assert_has_awaits(calls, any_order=True) + + asyncio.run(self._runnable_test('foo')) + with self.assertRaises(AssertionError): + self.mock.assert_has_awaits(calls, any_order=True) + + asyncio.run(self._runnable_test('NormalFoo')) + self.mock.assert_has_awaits(calls, any_order=True) + + asyncio.run(self._runnable_test('qux')) + self.mock.assert_has_awaits(calls, any_order=True) + + def test_assert_not_awaited(self): + self.mock.assert_not_awaited() + + asyncio.run(self._runnable_test()) + with self.assertRaises(AssertionError): + self.mock.assert_not_awaited() diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index b20b8e20e7e6fd..307b8b7657afa1 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -9,7 +9,7 @@ from unittest.mock import ( call, DEFAULT, patch, sentinel, MagicMock, Mock, NonCallableMock, - NonCallableMagicMock, _Call, _CallList, + NonCallableMagicMock, AsyncMock, _Call, _CallList, create_autospec ) @@ -1618,7 +1618,8 @@ def test_mock_add_spec_magic_methods(self): def test_adding_child_mock(self): - for Klass in NonCallableMock, Mock, MagicMock, NonCallableMagicMock: + for Klass in (NonCallableMock, Mock, MagicMock, NonCallableMagicMock, + AsyncMock): mock = Klass() mock.foo = Mock() diff --git a/Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst b/Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst new file mode 100644 index 00000000000000..4cf3f2ae7ef7e6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst @@ -0,0 +1,2 @@ +Added AsyncMock to support using unittest to mock asyncio coroutines. +Patch by Lisa Roach. From 5ae1c84bcd13b766989fc3f1e1c851e7bd4c1faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= <47358913+isidentical@users.noreply.github.com> Date: Mon, 20 May 2019 20:01:07 +0300 Subject: [PATCH 032/441] bpo-36949: Implement __repr__ on WeakSet (GH-13415) --- Lib/_weakrefset.py | 3 +++ Lib/test/test_weakset.py | 3 +++ .../next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst | 1 + 3 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py index 304c66f59bd1be..7a84823622ee7c 100644 --- a/Lib/_weakrefset.py +++ b/Lib/_weakrefset.py @@ -194,3 +194,6 @@ def union(self, other): def isdisjoint(self, other): return len(self.intersection(other)) == 0 + + def __repr__(self): + return repr(self.data) diff --git a/Lib/test/test_weakset.py b/Lib/test/test_weakset.py index 691b95e77c6af9..569facdd30c11c 100644 --- a/Lib/test/test_weakset.py +++ b/Lib/test/test_weakset.py @@ -434,6 +434,9 @@ def test_len_race(self): self.assertGreaterEqual(n2, 0) self.assertLessEqual(n2, n1) + def test_repr(self): + assert repr(self.s) == repr(self.s.data) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst b/Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst new file mode 100644 index 00000000000000..e4eeb4010a231d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst @@ -0,0 +1 @@ +Implement __repr__ for WeakSet objects. From c09a9f56c08d80567454cae6f78f738a89e1ae94 Mon Sep 17 00:00:00 2001 From: Thomas Moreau Date: Mon, 20 May 2019 21:37:05 +0200 Subject: [PATCH 033/441] bpo-36888: Add multiprocessing.parent_process() (GH-13247) --- Doc/library/multiprocessing.rst | 8 +++ Lib/multiprocessing/context.py | 1 + Lib/multiprocessing/forkserver.py | 3 +- Lib/multiprocessing/popen_fork.py | 8 ++- Lib/multiprocessing/popen_forkserver.py | 6 +- Lib/multiprocessing/popen_spawn_posix.py | 10 +++- Lib/multiprocessing/process.py | 52 +++++++++++++++- Lib/multiprocessing/spawn.py | 19 +++--- Lib/multiprocessing/util.py | 6 ++ Lib/test/_test_multiprocessing.py | 59 +++++++++++++++++++ .../2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst | 2 + Modules/_winapi.c | 1 + 12 files changed, 155 insertions(+), 20 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index c6ffb00819c32c..cc6dd4e9d70226 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -944,6 +944,14 @@ Miscellaneous An analogue of :func:`threading.current_thread`. +.. function:: parent_process() + + Return the :class:`Process` object corresponding to the parent process of + the :func:`current_process`. For the main process, ``parent_process`` will + be ``None``. + + .. versionadded:: 3.8 + .. function:: freeze_support() Add support for when a program which uses :mod:`multiprocessing` has been diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index 871746b1a047b3..5a4865751c2272 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -35,6 +35,7 @@ class BaseContext(object): AuthenticationError = AuthenticationError current_process = staticmethod(process.current_process) + parent_process = staticmethod(process.parent_process) active_children = staticmethod(process.active_children) def cpu_count(self): diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py index dabf7bcbe6d785..9b6398671dbc5e 100644 --- a/Lib/multiprocessing/forkserver.py +++ b/Lib/multiprocessing/forkserver.py @@ -294,7 +294,8 @@ def _serve_one(child_r, fds, unused_fds, handlers): *_forkserver._inherited_fds) = fds # Run process object received over pipe - code = spawn._main(child_r) + parent_sentinel = os.dup(child_r) + code = spawn._main(child_r, parent_sentinel) return code diff --git a/Lib/multiprocessing/popen_fork.py b/Lib/multiprocessing/popen_fork.py index 685e8daf77ca1f..11e216072d0919 100644 --- a/Lib/multiprocessing/popen_fork.py +++ b/Lib/multiprocessing/popen_fork.py @@ -66,16 +66,20 @@ def kill(self): def _launch(self, process_obj): code = 1 parent_r, child_w = os.pipe() + child_r, parent_w = os.pipe() self.pid = os.fork() if self.pid == 0: try: os.close(parent_r) - code = process_obj._bootstrap() + os.close(parent_w) + code = process_obj._bootstrap(parent_sentinel=child_r) finally: os._exit(code) else: os.close(child_w) - self.finalizer = util.Finalize(self, os.close, (parent_r,)) + os.close(child_r) + self.finalizer = util.Finalize(self, util.close_fds, + (parent_r, parent_w,)) self.sentinel = parent_r def close(self): diff --git a/Lib/multiprocessing/popen_forkserver.py b/Lib/multiprocessing/popen_forkserver.py index a51a2771aed8cc..a56eb9bf11080b 100644 --- a/Lib/multiprocessing/popen_forkserver.py +++ b/Lib/multiprocessing/popen_forkserver.py @@ -49,7 +49,11 @@ def _launch(self, process_obj): set_spawning_popen(None) self.sentinel, w = forkserver.connect_to_new_process(self._fds) - self.finalizer = util.Finalize(self, os.close, (self.sentinel,)) + # Keep a duplicate of the data pipe's write end as a sentinel of the + # parent process used by the child process. + _parent_w = os.dup(w) + self.finalizer = util.Finalize(self, util.close_fds, + (_parent_w, self.sentinel)) with open(w, 'wb', closefd=True) as f: f.write(buf.getbuffer()) self.pid = forkserver.read_signed(self.sentinel) diff --git a/Lib/multiprocessing/popen_spawn_posix.py b/Lib/multiprocessing/popen_spawn_posix.py index 59f8e452cae1d5..24b8634523e5f2 100644 --- a/Lib/multiprocessing/popen_spawn_posix.py +++ b/Lib/multiprocessing/popen_spawn_posix.py @@ -61,8 +61,12 @@ def _launch(self, process_obj): with open(parent_w, 'wb', closefd=False) as f: f.write(fp.getbuffer()) finally: - if parent_r is not None: - self.finalizer = util.Finalize(self, os.close, (parent_r,)) - for fd in (child_r, child_w, parent_w): + fds_to_close = [] + for fd in (parent_r, parent_w): + if fd is not None: + fds_to_close.append(fd) + self.finalizer = util.Finalize(self, util.close_fds, fds_to_close) + + for fd in (child_r, child_w): if fd is not None: os.close(fd) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index 780f2d0c273472..c62c826cff9580 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -7,7 +7,8 @@ # Licensed to PSF under a Contributor Agreement. # -__all__ = ['BaseProcess', 'current_process', 'active_children'] +__all__ = ['BaseProcess', 'current_process', 'active_children', + 'parent_process'] # # Imports @@ -46,6 +47,13 @@ def active_children(): _cleanup() return list(_children) + +def parent_process(): + ''' + Return process object representing the parent process + ''' + return _parent_process + # # # @@ -76,6 +84,7 @@ def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, self._identity = _current_process._identity + (count,) self._config = _current_process._config.copy() self._parent_pid = os.getpid() + self._parent_name = _current_process.name self._popen = None self._closed = False self._target = target @@ -278,9 +287,9 @@ def __repr__(self): ## - def _bootstrap(self): + def _bootstrap(self, parent_sentinel=None): from . import util, context - global _current_process, _process_counter, _children + global _current_process, _parent_process, _process_counter, _children try: if self._start_method is not None: @@ -290,6 +299,8 @@ def _bootstrap(self): util._close_stdin() old_process = _current_process _current_process = self + _parent_process = _ParentProcess( + self._parent_name, self._parent_pid, parent_sentinel) try: util._finalizer_registry.clear() util._run_after_forkers() @@ -337,6 +348,40 @@ def __reduce__(self): ) return AuthenticationString, (bytes(self),) + +# +# Create object representing the parent process +# + +class _ParentProcess(BaseProcess): + + def __init__(self, name, pid, sentinel): + self._identity = () + self._name = name + self._pid = pid + self._parent_pid = None + self._popen = None + self._closed = False + self._sentinel = sentinel + self._config = {} + + def is_alive(self): + from multiprocessing.connection import wait + return not wait([self._sentinel], timeout=0) + + @property + def ident(self): + return self._pid + + def join(self, timeout=None): + ''' + Wait until parent process terminates + ''' + from multiprocessing.connection import wait + wait([self._sentinel], timeout=timeout) + + pid = ident + # # Create object representing the main process # @@ -365,6 +410,7 @@ def close(self): pass +_parent_process = None _current_process = _MainProcess() _process_counter = itertools.count(1) _children = set() diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index f66b5aa9267b6d..7cc129e2610761 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -100,25 +100,24 @@ def spawn_main(pipe_handle, parent_pid=None, tracker_fd=None): if parent_pid is not None: source_process = _winapi.OpenProcess( - _winapi.PROCESS_DUP_HANDLE, False, parent_pid) + _winapi.SYNCHRONIZE | _winapi.PROCESS_DUP_HANDLE, + False, parent_pid) else: source_process = None - try: - new_handle = reduction.duplicate(pipe_handle, - source_process=source_process) - finally: - if source_process is not None: - _winapi.CloseHandle(source_process) + new_handle = reduction.duplicate(pipe_handle, + source_process=source_process) fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY) + parent_sentinel = source_process else: from . import resource_tracker resource_tracker._resource_tracker._fd = tracker_fd fd = pipe_handle - exitcode = _main(fd) + parent_sentinel = os.dup(pipe_handle) + exitcode = _main(fd, parent_sentinel) sys.exit(exitcode) -def _main(fd): +def _main(fd, parent_sentinel): with os.fdopen(fd, 'rb', closefd=True) as from_parent: process.current_process()._inheriting = True try: @@ -127,7 +126,7 @@ def _main(fd): self = reduction.pickle.load(from_parent) finally: del process.current_process()._inheriting - return self._bootstrap() + return self._bootstrap(parent_sentinel) def _check_not_importing_main(): diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index 0c4eb2473273b4..5674ad773f9764 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -421,3 +421,9 @@ def spawnv_passfds(path, args, passfds): finally: os.close(errpipe_read) os.close(errpipe_write) + + +def close_fds(*fds): + """Close each file descriptor given as an argument""" + for fd in fds: + os.close(fd) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 78ec53beb0f01d..071b54a713e2d8 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -269,6 +269,64 @@ def _test(cls, q, *args, **kwds): q.put(bytes(current.authkey)) q.put(current.pid) + def test_parent_process_attributes(self): + if self.TYPE == "threads": + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + self.assertIsNone(self.parent_process()) + + rconn, wconn = self.Pipe(duplex=False) + p = self.Process(target=self._test_send_parent_process, args=(wconn,)) + p.start() + p.join() + parent_pid, parent_name = rconn.recv() + self.assertEqual(parent_pid, self.current_process().pid) + self.assertEqual(parent_pid, os.getpid()) + self.assertEqual(parent_name, self.current_process().name) + + @classmethod + def _test_send_parent_process(cls, wconn): + from multiprocessing.process import parent_process + wconn.send([parent_process().pid, parent_process().name]) + + def test_parent_process(self): + if self.TYPE == "threads": + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + # Launch a child process. Make it launch a grandchild process. Kill the + # child process and make sure that the grandchild notices the death of + # its parent (a.k.a the child process). + rconn, wconn = self.Pipe(duplex=False) + p = self.Process( + target=self._test_create_grandchild_process, args=(wconn, )) + p.start() + + if not rconn.poll(timeout=5): + raise AssertionError("Could not communicate with child process") + parent_process_status = rconn.recv() + self.assertEqual(parent_process_status, "alive") + + p.terminate() + p.join() + + if not rconn.poll(timeout=5): + raise AssertionError("Could not communicate with child process") + parent_process_status = rconn.recv() + self.assertEqual(parent_process_status, "not alive") + + @classmethod + def _test_create_grandchild_process(cls, wconn): + p = cls.Process(target=cls._test_report_parent_status, args=(wconn, )) + p.start() + time.sleep(100) + + @classmethod + def _test_report_parent_status(cls, wconn): + from multiprocessing.process import parent_process + wconn.send("alive" if parent_process().is_alive() else "not alive") + parent_process().join(timeout=5) + wconn.send("alive" if parent_process().is_alive() else "not alive") + def test_process(self): q = self.Queue(1) e = self.Event() @@ -5398,6 +5456,7 @@ class ProcessesMixin(BaseMixin): Process = multiprocessing.Process connection = multiprocessing.connection current_process = staticmethod(multiprocessing.current_process) + parent_process = staticmethod(multiprocessing.parent_process) active_children = staticmethod(multiprocessing.active_children) Pool = staticmethod(multiprocessing.Pool) Pipe = staticmethod(multiprocessing.Pipe) diff --git a/Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst b/Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst new file mode 100644 index 00000000000000..e7b54677280c9f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst @@ -0,0 +1,2 @@ +Python child processes can now access the status of their parent process +using multiprocessing.process.parent_process diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 2eb708e9073e91..8873519e6ce5df 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -1955,6 +1955,7 @@ PyInit__winapi(void) WINAPI_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES); WINAPI_CONSTANT(F_DWORD, PIPE_WAIT); WINAPI_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS); + WINAPI_CONSTANT(F_DWORD, SYNCHRONIZE); WINAPI_CONSTANT(F_DWORD, PROCESS_DUP_HANDLE); WINAPI_CONSTANT(F_DWORD, SEC_COMMIT); WINAPI_CONSTANT(F_DWORD, SEC_IMAGE); From 4011d865d0572a3dd9988f2935cd835cc8fb792a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= <47358913+isidentical@users.noreply.github.com> Date: Mon, 20 May 2019 23:27:10 +0300 Subject: [PATCH 034/441] bpo-23896: Add a grammar where exec isn't a stmt (#13272) https://bugs.python.org/issue23896 --- Lib/lib2to3/pygram.py | 3 +++ Misc/ACKS | 1 + .../next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst | 2 ++ 3 files changed, 6 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst diff --git a/Lib/lib2to3/pygram.py b/Lib/lib2to3/pygram.py index 919624eb399706..24d9db9217f131 100644 --- a/Lib/lib2to3/pygram.py +++ b/Lib/lib2to3/pygram.py @@ -36,5 +36,8 @@ def __init__(self, grammar): python_grammar_no_print_statement = python_grammar.copy() del python_grammar_no_print_statement.keywords["print"] +python_grammar_no_print_and_exec_statement = python_grammar_no_print_statement.copy() +del python_grammar_no_print_and_exec_statement.keywords["exec"] + pattern_grammar = driver.load_packaged_grammar("lib2to3", _PATTERN_GRAMMAR_FILE) pattern_symbols = Symbols(pattern_grammar) diff --git a/Misc/ACKS b/Misc/ACKS index f9d01d00867999..87107b9cfc7d2b 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1860,3 +1860,4 @@ Carsten Klein Diego Rojas Edison Abahurire Geoff Shannon +Batuhan Taskaya diff --git a/Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst b/Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst new file mode 100644 index 00000000000000..3c154822c9acdb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst @@ -0,0 +1,2 @@ +Adds a grammar to lib2to3.pygram that contains exec as a function not as +statement. From 1a3faf9d9740a8c7505c61839ef09929a7ff9e35 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Mon, 20 May 2019 13:44:11 -0700 Subject: [PATCH 035/441] bpo-36952: Remove the bufsize parameter in fileinput.input(). (GH-13400) This parameter is marked as deprecated since 3.6 and for removal in 3.8. It already had no effects. --- Doc/library/fileinput.rst | 17 ++++--- Doc/whatsnew/3.8.rst | 4 ++ Lib/fileinput.py | 13 ++--- Lib/test/test_fileinput.py | 50 +++++++------------ .../2019-05-20-11-01-28.bpo-36952.MgZi7-.rst | 4 ++ 5 files changed, 41 insertions(+), 47 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index af9dff34a80827..14be492f55a67f 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -54,7 +54,7 @@ provided by this module. The following function is the primary interface of this module: -.. function:: input(files=None, inplace=False, backup='', bufsize=0, mode='r', openhook=None) +.. function:: input(files=None, inplace=False, backup='', *, mode='r', openhook=None) Create an instance of the :class:`FileInput` class. The instance will be used as global state for the functions of this module, and is also returned to use @@ -72,8 +72,9 @@ The following function is the primary interface of this module: .. versionchanged:: 3.2 Can be used as a context manager. - .. deprecated-removed:: 3.6 3.8 - The *bufsize* parameter. + .. versionchanged:: 3.8 + The keyword parameters *mode* and *openhook* are now keyword-only. + The following functions use the global state created by :func:`fileinput.input`; if there is no active state, :exc:`RuntimeError` is raised. @@ -135,7 +136,7 @@ The class which implements the sequence behavior provided by the module is available for subclassing as well: -.. class:: FileInput(files=None, inplace=False, backup='', bufsize=0, mode='r', openhook=None) +.. class:: FileInput(files=None, inplace=False, backup='', *, mode='r', openhook=None) Class :class:`FileInput` is the implementation; its methods :meth:`filename`, :meth:`fileno`, :meth:`lineno`, :meth:`filelineno`, :meth:`isfirstline`, @@ -160,18 +161,20 @@ available for subclassing as well: with FileInput(files=('spam.txt', 'eggs.txt')) as input: process(input) + .. versionchanged:: 3.2 Can be used as a context manager. .. deprecated:: 3.4 The ``'rU'`` and ``'U'`` modes. - .. deprecated-removed:: 3.6 3.8 - The *bufsize* parameter. - .. deprecated:: 3.8 Support for :meth:`__getitem__` method is deprecated. + .. versionchanged:: 3.8 + The keyword parameter *mode* and *openhook* are now keyword-only. + + **Optional in-place filtering:** if the keyword argument ``inplace=True`` is passed to :func:`fileinput.input` or to the :class:`FileInput` constructor, the diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 0a79b6ce1a652c..5f8208d5bf4a5e 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -828,6 +828,10 @@ The following features and APIs have been removed from Python 3.8: exposed to the user. (Contributed by Aviv Palivoda in :issue:`30262`.) +* The ``bufsize`` keyword argument of :func:`fileinput.input` and + :func:`fileinput.FileInput` which was ignored and deprecated since Python 3.6 + has been removed. :issue:`36952` (Contributed by Matthias Bussonnier) + Porting to Python 3.8 ===================== diff --git a/Lib/fileinput.py b/Lib/fileinput.py index 0764aa5e4d2480..d868e74cd5e969 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -80,8 +80,7 @@ _state = None -def input(files=None, inplace=False, backup="", bufsize=0, - mode="r", openhook=None): +def input(files=None, inplace=False, backup="", *, mode="r", openhook=None): """Return an instance of the FileInput class, which can be iterated. The parameters are passed to the constructor of the FileInput class. @@ -91,7 +90,7 @@ def input(files=None, inplace=False, backup="", bufsize=0, global _state if _state and _state._file: raise RuntimeError("input() already active") - _state = FileInput(files, inplace, backup, bufsize, mode, openhook) + _state = FileInput(files, inplace, backup, mode=mode, openhook=openhook) return _state def close(): @@ -173,7 +172,7 @@ def isstdin(): return _state.isstdin() class FileInput: - """FileInput([files[, inplace[, backup[, bufsize, [, mode[, openhook]]]]]]) + """FileInput([files[, inplace[, backup]]], *, mode=None, openhook=None) Class FileInput is the implementation of the module; its methods filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(), @@ -185,7 +184,7 @@ class FileInput: sequential order; random access and readline() cannot be mixed. """ - def __init__(self, files=None, inplace=False, backup="", bufsize=0, + def __init__(self, files=None, inplace=False, backup="", *, mode="r", openhook=None): if isinstance(files, str): files = (files,) @@ -201,10 +200,6 @@ def __init__(self, files=None, inplace=False, backup="", bufsize=0, self._files = files self._inplace = inplace self._backup = backup - if bufsize: - import warnings - warnings.warn('bufsize is deprecated and ignored', - DeprecationWarning, stacklevel=2) self._savestdout = None self._output = None self._filename = None diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py index 8b7577b0205cde..014f19e6cbdb1a 100644 --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -82,25 +82,17 @@ def close(self): class BufferSizesTests(BaseTests, unittest.TestCase): def test_buffer_sizes(self): - # First, run the tests with default and teeny buffer size. - for round, bs in (0, 0), (1, 30): - t1 = self.writeTmp(''.join("Line %s of file 1\n" % (i+1) for i in range(15))) - t2 = self.writeTmp(''.join("Line %s of file 2\n" % (i+1) for i in range(10))) - t3 = self.writeTmp(''.join("Line %s of file 3\n" % (i+1) for i in range(5))) - t4 = self.writeTmp(''.join("Line %s of file 4\n" % (i+1) for i in range(1))) - if bs: - with self.assertWarns(DeprecationWarning): - self.buffer_size_test(t1, t2, t3, t4, bs, round) - else: - self.buffer_size_test(t1, t2, t3, t4, bs, round) - - def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0): + + t1 = self.writeTmp(''.join("Line %s of file 1\n" % (i+1) for i in range(15))) + t2 = self.writeTmp(''.join("Line %s of file 2\n" % (i+1) for i in range(10))) + t3 = self.writeTmp(''.join("Line %s of file 3\n" % (i+1) for i in range(5))) + t4 = self.writeTmp(''.join("Line %s of file 4\n" % (i+1) for i in range(1))) + pat = re.compile(r'LINE (\d+) OF FILE (\d+)') - start = 1 + round*6 if verbose: - print('%s. Simple iteration (bs=%s)' % (start+0, bs)) - fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) + print('1. Simple iteration') + fi = FileInput(files=(t1, t2, t3, t4)) lines = list(fi) fi.close() self.assertEqual(len(lines), 31) @@ -110,8 +102,8 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0): self.assertEqual(fi.filename(), t4) if verbose: - print('%s. Status variables (bs=%s)' % (start+1, bs)) - fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) + print('2. Status variables') + fi = FileInput(files=(t1, t2, t3, t4)) s = "x" while s and s != 'Line 6 of file 2\n': s = fi.readline() @@ -122,15 +114,15 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0): self.assertFalse(fi.isstdin()) if verbose: - print('%s. Nextfile (bs=%s)' % (start+2, bs)) + print('3. Nextfile') fi.nextfile() self.assertEqual(fi.readline(), 'Line 1 of file 3\n') self.assertEqual(fi.lineno(), 22) fi.close() if verbose: - print('%s. Stdin (bs=%s)' % (start+3, bs)) - fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs) + print('4. Stdin') + fi = FileInput(files=(t1, t2, t3, t4, '-')) savestdin = sys.stdin try: sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n") @@ -143,8 +135,8 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0): sys.stdin = savestdin if verbose: - print('%s. Boundary conditions (bs=%s)' % (start+4, bs)) - fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) + print('5. Boundary conditions') + fi = FileInput(files=(t1, t2, t3, t4)) self.assertEqual(fi.lineno(), 0) self.assertEqual(fi.filename(), None) fi.nextfile() @@ -152,10 +144,10 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0): self.assertEqual(fi.filename(), None) if verbose: - print('%s. Inplace (bs=%s)' % (start+5, bs)) + print('6. Inplace') savestdout = sys.stdout try: - fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs) + fi = FileInput(files=(t1, t2, t3, t4), inplace=1) for line in fi: line = line[:-1].upper() print(line) @@ -163,7 +155,7 @@ def buffer_size_test(self, t1, t2, t3, t4, bs=0, round=0): finally: sys.stdout = savestdout - fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs) + fi = FileInput(files=(t1, t2, t3, t4)) for line in fi: self.assertEqual(line[-1], '\n') m = pat.match(line[:-1]) @@ -533,12 +525,11 @@ def test_pathlib_file_inplace(self): class MockFileInput: """A class that mocks out fileinput.FileInput for use during unit tests""" - def __init__(self, files=None, inplace=False, backup="", bufsize=0, + def __init__(self, files=None, inplace=False, backup="", *, mode="r", openhook=None): self.files = files self.inplace = inplace self.backup = backup - self.bufsize = bufsize self.mode = mode self.openhook = openhook self._file = None @@ -641,13 +632,11 @@ def do_test_call_input(self): files = object() inplace = object() backup = object() - bufsize = object() mode = object() openhook = object() # call fileinput.input() with different values for each argument result = fileinput.input(files=files, inplace=inplace, backup=backup, - bufsize=bufsize, mode=mode, openhook=openhook) # ensure fileinput._state was set to the returned object @@ -658,7 +647,6 @@ def do_test_call_input(self): self.assertIs(files, result.files, "files") self.assertIs(inplace, result.inplace, "inplace") self.assertIs(backup, result.backup, "backup") - self.assertIs(bufsize, result.bufsize, "bufsize") self.assertIs(mode, result.mode, "mode") self.assertIs(openhook, result.openhook, "openhook") diff --git a/Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst b/Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst new file mode 100644 index 00000000000000..f5ce2aadf4a18c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst @@ -0,0 +1,4 @@ +:func:`fileinput.input` and :class:`fileinput.FileInput` **bufsize** +argument has been removed (was deprecated and ignored since Python 3.6), +and as a result the **mode** and **openhook** arguments have been made +keyword-only. From bf457c7d8224179a023957876e757f2a7ffc3d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Tue, 21 May 2019 00:17:30 +0200 Subject: [PATCH 036/441] bpo-36969: Make PDB args command display keyword only arguments (GH-13452) --- Lib/pdb.py | 6 ++--- Lib/test/test_pdb.py | 25 ++++++++++++++++--- .../2019-05-20-23-31-20.bpo-36969.JkZORP.rst | 2 ++ 3 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index f5d33c27fc1d91..0e7609e43d4eea 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1132,9 +1132,9 @@ def do_args(self, arg): """ co = self.curframe.f_code dict = self.curframe_locals - n = co.co_argcount - if co.co_flags & 4: n = n+1 - if co.co_flags & 8: n = n+1 + n = co.co_argcount + co.co_kwonlyargcount + if co.co_flags & inspect.CO_VARARGS: n = n+1 + if co.co_flags & inspect.CO_VARKEYWORDS: n = n+1 for i in range(n): name = co.co_varnames[i] if name in dict: diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 56d823249544ae..a33494d6d878dd 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -77,9 +77,13 @@ def test_pdb_basic_commands(): ... print('...') ... return foo.upper() + >>> def test_function3(arg=None, *, kwonly=None): + ... pass + >>> def test_function(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... ret = test_function_2('baz') + ... test_function3(kwonly=True) ... print(ret) >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE @@ -97,10 +101,13 @@ def test_pdb_basic_commands(): ... 'jump 8', # jump over second for loop ... 'return', # return out of function ... 'retval', # display return value + ... 'next', # step to test_function3() + ... 'step', # stepping into test_function3() + ... 'args', # display function args ... 'continue', ... ]): ... test_function() - > (3)test_function() + > (3)test_function() -> ret = test_function_2('baz') (Pdb) step --Call-- @@ -123,14 +130,14 @@ def test_pdb_basic_commands(): [EOF] (Pdb) bt ... - (18)() + (21)() -> test_function() - (3)test_function() + (3)test_function() -> ret = test_function_2('baz') > (1)test_function_2() -> def test_function_2(foo, bar='default'): (Pdb) up - > (3)test_function() + > (3)test_function() -> ret = test_function_2('baz') (Pdb) down > (1)test_function_2() @@ -168,6 +175,16 @@ def test_pdb_basic_commands(): -> return foo.upper() (Pdb) retval 'BAZ' + (Pdb) next + > (4)test_function() + -> test_function3(kwonly=True) + (Pdb) step + --Call-- + > (1)test_function3() + -> def test_function3(arg=None, *, kwonly=None): + (Pdb) args + arg = None + kwonly = True (Pdb) continue BAZ """ diff --git a/Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst b/Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst new file mode 100644 index 00000000000000..9253ab92f1fb6e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst @@ -0,0 +1,2 @@ +PDB command `args` now display keyword only arguments. Patch contributed by +Rémi Lapeyre. From 6220c02e09e9f3a7458d32ad774ada0ba1571cb8 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Mon, 20 May 2019 18:45:05 -0400 Subject: [PATCH 037/441] bpo-35563: Add reference links to warnings.rst (GH-11289) --- Doc/library/warnings.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index d121f320d6a3eb..a481a3509d4ec8 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -19,10 +19,10 @@ Python programmers issue warnings by calling the :func:`warn` function defined in this module. (C programmers use :c:func:`PyErr_WarnEx`; see :ref:`exceptionhandling` for details). -Warning messages are normally written to ``sys.stderr``, but their disposition +Warning messages are normally written to :data:`sys.stderr`, but their disposition can be changed flexibly, from ignoring all warnings to turning them into -exceptions. The disposition of warnings can vary based on the warning category -(see below), the text of the warning message, and the source location where it +exceptions. The disposition of warnings can vary based on the :ref:`warning category +`, the text of the warning message, and the source location where it is issued. Repetitions of a particular warning for the same source location are typically suppressed. @@ -31,7 +31,7 @@ determination is made whether a message should be issued or not; next, if a message is to be issued, it is formatted and printed using a user-settable hook. The determination whether to issue a warning message is controlled by the -warning filter, which is a sequence of matching rules and actions. Rules can be +:ref:`warning filter `, which is a sequence of matching rules and actions. Rules can be added to the filter by calling :func:`filterwarnings` and reset to its default state by calling :func:`resetwarnings`. @@ -181,9 +181,9 @@ Describing Warning Filters The warnings filter is initialized by :option:`-W` options passed to the Python interpreter command line and the :envvar:`PYTHONWARNINGS` environment variable. The interpreter saves the arguments for all supplied entries without -interpretation in ``sys.warnoptions``; the :mod:`warnings` module parses these +interpretation in :data:`sys.warnoptions`; the :mod:`warnings` module parses these when it is first imported (invalid options are ignored, after printing a -message to ``sys.stderr``). +message to :data:`sys.stderr`). Individual warnings filters are specified as a sequence of fields separated by colons:: @@ -192,7 +192,7 @@ colons:: The meaning of each of these fields is as described in :ref:`warning-filter`. When listing multiple filters on a single line (as for -:envvar:`PYTHONWARNINGS`), the individual filters are separated by commas,and +:envvar:`PYTHONWARNINGS`), the individual filters are separated by commas and the filters listed later take precedence over those listed before them (as they're applied left-to-right, and the most recently applied filters take precedence over earlier ones). @@ -395,12 +395,12 @@ Available Functions .. function:: warn(message, category=None, stacklevel=1, source=None) Issue a warning, or maybe ignore it or raise an exception. The *category* - argument, if given, must be a warning category class (see above); it defaults to - :exc:`UserWarning`. Alternatively *message* can be a :exc:`Warning` instance, + argument, if given, must be a :ref:`warning category class `; it + defaults to :exc:`UserWarning`. Alternatively, *message* can be a :exc:`Warning` instance, in which case *category* will be ignored and ``message.__class__`` will be used. - In this case the message text will be ``str(message)``. This function raises an + In this case, the message text will be ``str(message)``. This function raises an exception if the particular warning issued is changed into an error by the - warnings filter see above. The *stacklevel* argument can be used by wrapper + :ref:`warnings filter `. The *stacklevel* argument can be used by wrapper functions written in Python, like this:: def deprecation(message): @@ -444,7 +444,7 @@ Available Functions Write a warning to a file. The default implementation calls ``formatwarning(message, category, filename, lineno, line)`` and writes the - resulting string to *file*, which defaults to ``sys.stderr``. You may replace + resulting string to *file*, which defaults to :data:`sys.stderr`. You may replace this function with any callable by assigning to ``warnings.showwarning``. *line* is a line of source code to be included in the warning message; if *line* is not supplied, :func:`showwarning` will From 3099ae407541b63249657b971fb35ff217508d86 Mon Sep 17 00:00:00 2001 From: Andre Delfino Date: Mon, 20 May 2019 21:52:17 -0300 Subject: [PATCH 038/441] Remove workaround for defaults in namedtuple now that we have the defaults parameter (GH-13263) --- Doc/library/collections.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index e0469c20810006..ae21db216fdebe 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -1017,15 +1017,6 @@ fields: .. versionchanged:: 3.5 Property docstrings became writeable. -Default values can be implemented by using :meth:`~somenamedtuple._replace` to -customize a prototype instance: - - >>> Account = namedtuple('Account', 'owner balance transaction_count') - >>> default_account = Account('', 0.0, 0) - >>> johns_account = default_account._replace(owner='John') - >>> janes_account = default_account._replace(owner='Jane') - - .. seealso:: * See :class:`typing.NamedTuple` for a way to add type hints for named From d0ebf13e50dd736cdb355fa42c23837abbb88127 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Mon, 20 May 2019 23:20:10 -0700 Subject: [PATCH 039/441] bpo-36932: use proper deprecation-removed directive (GH-13349) .. And update some deprecation warnings with version numbers. https://bugs.python.org/issue36932 --- Doc/library/asyncio-task.rst | 37 +++++++++++++++++++++--------------- Doc/library/sys.rst | 2 +- Lib/asyncio/tasks.py | 16 ++++++++-------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index bb064bd93deaf7..d94fa587cd3a47 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -279,8 +279,8 @@ Sleeping ``sleep()`` always suspends the current task, allowing other tasks to run. - The *loop* argument is deprecated and scheduled for removal - in Python 3.10. + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. .. _asyncio_example_sleep: @@ -437,8 +437,8 @@ Timeouts If the wait is cancelled, the future *aw* is also cancelled. - The *loop* argument is deprecated and scheduled for removal - in Python 3.10. + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. .. _asyncio_example_waitfor: @@ -478,10 +478,12 @@ Waiting Primitives set concurrently and block until the condition specified by *return_when*. - If any awaitable in *aws* is a coroutine, it is automatically - scheduled as a Task. Passing coroutines objects to - ``wait()`` directly is deprecated as it leads to - :ref:`confusing behavior `. + .. deprecated:: 3.8 + + If any awaitable in *aws* is a coroutine, it is automatically + scheduled as a Task. Passing coroutines objects to + ``wait()`` directly is deprecated as it leads to + :ref:`confusing behavior `. Returns two sets of Tasks/Futures: ``(done, pending)``. @@ -489,8 +491,8 @@ Waiting Primitives done, pending = await asyncio.wait(aws) - The *loop* argument is deprecated and scheduled for removal - in Python 3.10. + .. deprecated-removed:: 3.8 3.10 + The *loop* parameter. *timeout* (a float or int), if specified, can be used to control the maximum number of seconds to wait before returning. @@ -550,6 +552,8 @@ Waiting Primitives if task in done: # Everything will work as expected now. + .. deprecated:: 3.8 + Passing coroutine objects to ``wait()`` directly is deprecated. @@ -868,8 +872,10 @@ Task Object If *loop* is ``None``, the :func:`get_event_loop` function is used to get the current loop. - This method is **deprecated** and will be removed in - Python 3.9. Use the :func:`asyncio.all_tasks` function instead. + .. deprecated-removed:: 3.7 3.9 + + Do not call this as a task method. Use the :func:`asyncio.all_tasks` + function instead. .. classmethod:: current_task(loop=None) @@ -878,9 +884,10 @@ Task Object If *loop* is ``None``, the :func:`get_event_loop` function is used to get the current loop. - This method is **deprecated** and will be removed in - Python 3.9. Use the :func:`asyncio.current_task` function - instead. + .. deprecated-removed:: 3.7 3.9 + + Do not call this as a task method. Use the + :func:`asyncio.current_task` function instead. .. _asyncio_generator_based_coro: diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 5039ffa933ac54..7d27c89fac9572 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1353,7 +1353,7 @@ always available. This function has been added on a provisional basis (see :pep:`411` for details.) Use it only for debugging purposes. - .. deprecated:: 3.7 + .. deprecated-removed:: 3.7 3.8 The coroutine wrapper functionality has been deprecated, and will be removed in 3.8. See :issue:`32591` for details. diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index b274b9bd332994..1dc595298c556d 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -95,7 +95,7 @@ def current_task(cls, loop=None): None is returned when called not in the context of a Task. """ - warnings.warn("Task.current_task() is deprecated, " + warnings.warn("Task.current_task() is deprecated since Python 3.7, " "use asyncio.current_task() instead", DeprecationWarning, stacklevel=2) @@ -109,7 +109,7 @@ def all_tasks(cls, loop=None): By default all tasks for the current event loop are returned. """ - warnings.warn("Task.all_tasks() is deprecated, " + warnings.warn("Task.all_tasks() is deprecated since Python 3.7, " "use asyncio.all_tasks() instead", DeprecationWarning, stacklevel=2) @@ -388,8 +388,8 @@ async def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED): if loop is None: loop = events.get_running_loop() else: - warnings.warn("The loop argument is deprecated and scheduled for " - "removal in Python 3.10.", + warnings.warn("The loop argument is deprecated since Python 3.8, " + "and scheduled for removal in Python 3.10.", DeprecationWarning, stacklevel=2) fs = {ensure_future(f, loop=loop) for f in set(fs)} @@ -418,8 +418,8 @@ async def wait_for(fut, timeout, *, loop=None): if loop is None: loop = events.get_running_loop() else: - warnings.warn("The loop argument is deprecated and scheduled for " - "removal in Python 3.10.", + warnings.warn("The loop argument is deprecated since Python 3.8, " + "and scheduled for removal in Python 3.10.", DeprecationWarning, stacklevel=2) if timeout is None: @@ -600,8 +600,8 @@ async def sleep(delay, result=None, *, loop=None): if loop is None: loop = events.get_running_loop() else: - warnings.warn("The loop argument is deprecated and scheduled for " - "removal in Python 3.10.", + warnings.warn("The loop argument is deprecated since Python 3.8, " + "and scheduled for removal in Python 3.10.", DeprecationWarning, stacklevel=2) future = loop.create_future() From e7cb23bf2079087068a08502f96fdf20b317d69c Mon Sep 17 00:00:00 2001 From: Xtreak Date: Tue, 21 May 2019 14:17:17 +0530 Subject: [PATCH 040/441] Fix RuntimeWarning in unittest.mock asyncio example (GH-13449) * This PR fixes the `RuntimeWarning` in `inspect.isawaitable(mock())` where `mock()` was not awaited. * Fix typo in asynctest project. --- Doc/library/unittest.mock.rst | 4 ++-- Lib/unittest/mock.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 21e4709f81609e..163da9aecdbbc5 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -862,7 +862,7 @@ object:: >>> mock = AsyncMock() >>> asyncio.iscoroutinefunction(mock) True - >>> inspect.isawaitable(mock()) + >>> inspect.isawaitable(mock()) # doctest: +SKIP True The result of ``mock()`` is an async function which will have the outcome @@ -888,7 +888,7 @@ object:: >>> mock = MagicMock(async_func) >>> mock - >>> mock() + >>> mock() # doctest: +SKIP .. method:: assert_awaited() diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 166c1003769848..654462cbf7e792 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -2204,7 +2204,7 @@ class AsyncMock(AsyncMockMixin, AsyncMagicMixin, Mock): :class:`.Mock` object: the wrapped object may have methods defined as async function functions. - Based on Martin Richard's asyntest project. + Based on Martin Richard's asynctest project. """ From 925af1d99b69bf3e229411022ad840c5a0cfdcf8 Mon Sep 17 00:00:00 2001 From: Erik Janssens Date: Tue, 21 May 2019 12:11:11 +0200 Subject: [PATCH 041/441] bpo-36965: Fix includes in main.c on Windows with non-MSC compilers (GH-13421) Include windows.h rather than crtdbg.h to get STATUS_CONTROL_C_EXIT constant. Moreover, include windows.h on Windows, not only when MSC is used. --- .../next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst | 1 + Modules/main.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst diff --git a/Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst b/Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst new file mode 100644 index 00000000000000..2a531d2c14d9a2 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst @@ -0,0 +1 @@ +include of STATUS_CONTROL_C_EXIT without depending on MSC compiler diff --git a/Modules/main.c b/Modules/main.c index 6d4b351e5e177d..08fb0e0417d038 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -18,8 +18,8 @@ #if defined(HAVE_GETPID) && defined(HAVE_UNISTD_H) # include /* getpid() */ #endif -#ifdef _MSC_VER -# include /* STATUS_CONTROL_C_EXIT */ +#ifdef MS_WINDOWS +# include /* STATUS_CONTROL_C_EXIT */ #endif /* End of includes for exit_sigint() */ From d12e75734d46ecde588c5de65e6d64146911d20c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 21 May 2019 12:44:57 +0200 Subject: [PATCH 042/441] Revert "bpo-36084: Add native thread ID to threading.Thread objects (GH-11993)" (GH-13458) This reverts commit 4959c33d2555b89b494c678d99be81a65ee864b0. --- Doc/library/_thread.rst | 12 ------- Doc/library/threading.rst | 31 ------------------- Include/pythread.h | 1 - Lib/_dummy_thread.py | 4 --- Lib/test/test_threading.py | 4 --- Lib/threading.py | 23 ++------------ .../2019-02-22-23-03-20.bpo-36084.86Eh4X.rst | 1 - Modules/_threadmodule.c | 16 ---------- Python/thread_nt.h | 16 ---------- Python/thread_pthread.h | 27 ---------------- 10 files changed, 2 insertions(+), 133 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index d7814f218b502f..acffabf24bad5f 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -85,18 +85,6 @@ This module defines the following constants and functions: may be recycled when a thread exits and another thread is created. -.. function:: get_native_id() - - Return the native integral Thread ID of the current thread assigned by the kernel. - This is a non-negative integer. - Its value may be used to uniquely identify this particular thread system-wide - (until the thread terminates, after which the value may be recycled by the OS). - - .. availability:: Windows, FreeBSD, Linux, macOS. - - .. versionadded:: 3.8 - - .. function:: stack_size([size]) Return the thread stack size used when creating new threads. The optional diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 715940c1c52bfc..22342803e5e6d6 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -49,18 +49,6 @@ This module defines the following functions: .. versionadded:: 3.3 -.. function:: get_native_id() - - Return the native integral Thread ID of the current thread assigned by the kernel. - This is a non-negative integer. - Its value may be used to uniquely identify this particular thread system-wide - (until the thread terminates, after which the value may be recycled by the OS). - - .. availability:: Windows, FreeBSD, Linux, macOS. - - .. versionadded:: 3.8 - - .. function:: enumerate() Return a list of all :class:`Thread` objects currently alive. The list @@ -309,25 +297,6 @@ since it is impossible to detect the termination of alien threads. another thread is created. The identifier is available even after the thread has exited. - .. attribute:: native_id - - The native integral thread ID of this thread or ``0`` if the thread has not - been started. This is a non-negative integer. See the - :func:`get_native_id` function. - This represents the Thread ID (``TID``) as assigned to the - thread by the OS (kernel). Its value may be used to uniquely identify - this particular thread system-wide. - - .. note:: - - Similar to Process IDs, Thread IDs are only valid (guaranteed unique - system-wide) from the time the thread is created until the thread - has been terminated. - - .. availability:: Windows, FreeBSD, Linux, macOS. - - .. versionadded:: 3.8 - .. method:: is_alive() Return whether the thread is alive. diff --git a/Include/pythread.h b/Include/pythread.h index e083383af80b47..bc1d92cd1ff199 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -25,7 +25,6 @@ PyAPI_FUNC(void) PyThread_init_thread(void); PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); -PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py index 0a877e1fa16905..a2cae54b0580db 100644 --- a/Lib/_dummy_thread.py +++ b/Lib/_dummy_thread.py @@ -71,10 +71,6 @@ def get_ident(): """ return 1 -def get_native_id(): - """Dummy implementation of _thread.get_native_id().""" - return 0 - def allocate_lock(): """Dummy implementation of _thread.allocate_lock().""" return LockType() diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 6ac6e9de7a5d10..2ddc77b266b542 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -104,10 +104,6 @@ def test_various_ops(self): self.assertRegex(repr(t), r'^$') t.start() - native_ids = set(t.native_id for t in threads) | {threading.get_native_id()} - self.assertNotIn(None, native_ids) - self.assertEqual(len(native_ids), NUMTASKS + 1) - if verbose: print('waiting for all tasks to complete') for t in threads: diff --git a/Lib/threading.py b/Lib/threading.py index 3137e495b2504c..0ebbd6776ef40f 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -23,8 +23,8 @@ # with the multiprocessing module, which doesn't provide the old # Java inspired names. -__all__ = ['get_ident', 'get_native_id', 'active_count', 'Condition', - 'current_thread', 'enumerate', 'main_thread', 'TIMEOUT_MAX', +__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread', + 'enumerate', 'main_thread', 'TIMEOUT_MAX', 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError', 'setprofile', 'settrace', 'local', 'stack_size'] @@ -34,7 +34,6 @@ _allocate_lock = _thread.allocate_lock _set_sentinel = _thread._set_sentinel get_ident = _thread.get_ident -get_native_id = _thread.get_native_id ThreadError = _thread.error try: _CRLock = _thread.RLock @@ -791,7 +790,6 @@ class is implemented. else: self._daemonic = current_thread().daemon self._ident = None - self._native_id = 0 self._tstate_lock = None self._started = Event() self._is_stopped = False @@ -893,9 +891,6 @@ def _bootstrap(self): def _set_ident(self): self._ident = get_ident() - def _set_native_id(self): - self._native_id = get_native_id() - def _set_tstate_lock(self): """ Set a lock object which will be released by the interpreter when @@ -908,7 +903,6 @@ def _bootstrap_inner(self): try: self._set_ident() self._set_tstate_lock() - self._set_native_id() self._started.set() with _active_limbo_lock: _active[self._ident] = self @@ -1083,17 +1077,6 @@ def ident(self): assert self._initialized, "Thread.__init__() not called" return self._ident - @property - def native_id(self): - """Native integral thread ID of this thread or 0 if it has not been started. - - This is a non-negative integer. See the get_native_id() function. - This represents the Thread ID as reported by the kernel. - - """ - assert self._initialized, "Thread.__init__() not called" - return self._native_id - def is_alive(self): """Return whether the thread is alive. @@ -1193,7 +1176,6 @@ def __init__(self): self._set_tstate_lock() self._started.set() self._set_ident() - self._set_native_id() with _active_limbo_lock: _active[self._ident] = self @@ -1213,7 +1195,6 @@ def __init__(self): self._started.set() self._set_ident() - self._set_native_id() with _active_limbo_lock: _active[self._ident] = self diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst deleted file mode 100644 index 4a612964de0f5f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst +++ /dev/null @@ -1 +0,0 @@ -Add native thread ID (TID) to threading.Thread objects \ No newline at end of file diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index a123cd0efd6279..3c02d8dd514571 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1159,20 +1159,6 @@ allocated consecutive numbers starting at 1, this behavior should not\n\ be relied upon, and the number should be seen purely as a magic cookie.\n\ A thread's identity may be reused for another thread after it exits."); -static PyObject * -thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - unsigned long native_id = PyThread_get_thread_native_id(); - return PyLong_FromUnsignedLong(native_id); -} - -PyDoc_STRVAR(get_native_id_doc, -"get_native_id() -> integer\n\ -\n\ -Return a non-negative integer identifying the thread as reported\n\ -by the OS (kernel). This may be used to uniquely identify a\n\ -particular thread within a system."); - static PyObject * thread__count(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1324,8 +1310,6 @@ static PyMethodDef thread_methods[] = { METH_NOARGS, interrupt_doc}, {"get_ident", thread_get_ident, METH_NOARGS, get_ident_doc}, - {"get_native_id", thread_get_native_id, - METH_NOARGS, get_native_id_doc}, {"_count", thread__count, METH_NOARGS, _count_doc}, {"stack_size", (PyCFunction)thread_stack_size, diff --git a/Python/thread_nt.h b/Python/thread_nt.h index d3dc2bec6ffebb..5e00c351146055 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -143,8 +143,6 @@ LeaveNonRecursiveMutex(PNRMUTEX mutex) unsigned long PyThread_get_thread_ident(void); -unsigned long PyThread_get_thread_native_id(void); - /* * Initialization of the C package, should not be needed. */ @@ -229,20 +227,6 @@ PyThread_get_thread_ident(void) return GetCurrentThreadId(); } -/* - * Return the native Thread ID (TID) of the calling thread. - * The native ID of a thread is valid and guaranteed to be unique system-wide - * from the time the thread is created until the thread has been terminated. - */ -unsigned long -PyThread_get_thread_native_id(void) -{ - if (!initialized) - PyThread_init_thread(); - - return GetCurrentThreadId(); -} - void _Py_NO_RETURN PyThread_exit_thread(void) { diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 87c98d3e93cb77..4c106d9959c10b 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -12,12 +12,6 @@ #endif #include -#if defined(__linux__) -#include -#elif defined(__FreeBSD__) -#include -#endif - /* The POSIX spec requires that use of pthread_attr_setstacksize be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */ #ifdef _POSIX_THREAD_ATTR_STACKSIZE @@ -308,27 +302,6 @@ PyThread_get_thread_ident(void) return (unsigned long) threadid; } -unsigned long -PyThread_get_thread_native_id(void) -{ - if (!initialized) - PyThread_init_thread(); -#ifdef __APPLE__ - uint64_t native_id; - pthread_threadid_np(NULL, &native_id); -#elif defined(__linux__) - pid_t native_id; - native_id = syscall(__NR_gettid); -#elif defined(__FreeBSD__) - pid_t native_id; - native_id = pthread_getthreadid_np(); -#else - unsigned long native_id; - native_id = 0; -#endif - return (unsigned long) native_id; -} - void _Py_NO_RETURN PyThread_exit_thread(void) { From f2d7ac7e5bd821e29e0fcb78a760a282059ae000 Mon Sep 17 00:00:00 2001 From: pxinwr Date: Tue, 21 May 2019 18:46:37 +0800 Subject: [PATCH 043/441] bpo-31904: Add posix module support for VxWorks (GH-12118) --- Doc/library/os.rst | 4 ++ Lib/test/test_os.py | 5 +- .../2019-03-01-17-59-39.bpo-31904.38djdk.rst | 1 + Modules/clinic/posixmodule.c.h | 10 +-- Modules/posixmodule.c | 72 +++++++++++++++++-- configure | 2 +- configure.ac | 2 +- pyconfig.h.in | 3 + 8 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index e77a8fed377ad6..0bbfce97c54ba6 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -32,6 +32,7 @@ Notes on the availability of these functions: objects, and result in an object of the same type, if a path or file name is returned. +* On VxWorks, os.fork, os.execv and os.spawn*p* are not supported. .. note:: @@ -3578,6 +3579,9 @@ written in Python, such as a mail server's external command delivery program. process. On Windows, the process id will actually be the process handle, so can be used with the :func:`waitpid` function. + Note on VxWorks, this function doesn't return ``-signal`` when the new process is + killed. Instead it raises OSError exception. + The "l" and "v" variants of the :func:`spawn\* ` functions differ in how command-line arguments are passed. The "l" variants are perhaps the easiest to work with if the number of parameters is fixed when the code is written; the diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index a2021b1eba068f..353b9a50a2b7fb 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1407,6 +1407,8 @@ def test_getrandom_value(self): @unittest.skipIf(OS_URANDOM_DONT_USE_FD , "os.random() does not use a file descriptor") +@unittest.skipIf(sys.platform == "vxworks", + "VxWorks can't set RLIMIT_NOFILE to 1") class URandomFDTests(unittest.TestCase): @unittest.skipUnless(resource, "test requires the resource module") def test_urandom_failure(self): @@ -1517,7 +1519,8 @@ def mock_execve(name, *args): os.execve = orig_execve os.defpath = orig_defpath - +@unittest.skipUnless(hasattr(os, 'execv'), + "need os.execv()") class ExecTests(unittest.TestCase): @unittest.skipIf(USING_LINUXTHREADS, "avoid triggering a linuxthreads bug: see issue #4970") diff --git a/Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst b/Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst new file mode 100644 index 00000000000000..319c0a319f8c34 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst @@ -0,0 +1 @@ +Add posix module support for VxWorks. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 43f8ba6b4e6161..f2745591b2353d 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2491,7 +2491,7 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj #endif /* defined(HAVE_POSIX_SPAWNP) */ -#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) +#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) PyDoc_STRVAR(os_spawnv__doc__, "spawnv($module, mode, path, argv, /)\n" @@ -2545,9 +2545,9 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) */ +#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) */ -#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) +#if (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) PyDoc_STRVAR(os_spawnve__doc__, "spawnve($module, mode, path, argv, env, /)\n" @@ -2606,7 +2606,7 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs) return return_value; } -#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)) */ +#endif /* (defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN)) */ #if defined(HAVE_FORK) @@ -8576,4 +8576,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=ab36ec0376a422ae input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5ee9420fb2e7aa2c input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index aca64efeb1e37f..9f15866d9d3db4 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -191,11 +191,13 @@ corresponding Unix manual entries for more information on calls."); #define fsync _commit #else /* Unix functions that the configure script doesn't check for */ +#ifndef __VXWORKS__ #define HAVE_EXECV 1 #define HAVE_FORK 1 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ #define HAVE_FORK1 1 #endif +#endif #define HAVE_GETEGID 1 #define HAVE_GETEUID 1 #define HAVE_GETGID 1 @@ -227,6 +229,18 @@ extern char *ctermid_r(char *); #endif /* !_MSC_VER */ +#if defined(__VXWORKS__) +#include +#include +#include +#include +#ifndef _P_WAIT +#define _P_WAIT 0 +#define _P_NOWAIT 1 +#define _P_NOWAITO 1 +#endif +#endif /* __VXWORKS__ */ + #ifdef HAVE_POSIX_SPAWN #include #endif @@ -1353,7 +1367,7 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) */ #include static char **environ; -#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) +#elif !defined(_MSC_VER) && (!defined(__WATCOMC__) || defined(__QNX__) || defined(__VXWORKS__)) extern char **environ; #endif /* !_MSC_VER */ @@ -4870,7 +4884,7 @@ os__exit_impl(PyObject *module, int status) #define EXECV_CHAR char #endif -#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) +#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) || defined(HAVE_RTPSPAWN) static void free_string_array(EXECV_CHAR **array, Py_ssize_t count) { @@ -4908,7 +4922,7 @@ fsconvert_strdup(PyObject *o, EXECV_CHAR **out) } #endif -#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) +#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) || defined(HAVE_RTPSPAWN) static EXECV_CHAR** parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) { @@ -5632,8 +5646,41 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, } #endif /* HAVE_POSIX_SPAWNP */ - -#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) +#ifdef HAVE_RTPSPAWN +static intptr_t +_rtp_spawn(int mode, const char *rtpFileName, const char *argv[], + const char *envp[]) +{ + RTP_ID rtpid; + int status; + pid_t res; + int async_err = 0; + + /* Set priority=100 and uStackSize=16 MiB (0x1000000) for new processes. + uStackSize=0 cannot be used, the default stack size is too small for + Python. */ + if (envp) { + rtpid = rtpSpawn(rtpFileName, argv, envp, + 100, 0x1000000, 0, VX_FP_TASK); + } + else { + rtpid = rtpSpawn(rtpFileName, argv, (const char **)environ, + 100, 0x1000000, 0, VX_FP_TASK); + } + if ((rtpid != RTP_ID_ERROR) && (mode == _P_WAIT)) { + do { + res = waitpid((pid_t)rtpid, &status, 0); + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (res < 0) + return RTP_ID_ERROR; + return ((intptr_t)status); + } + return ((intptr_t)rtpid); +} +#endif + +#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) || defined(HAVE_RTPSPAWN) /*[clinic input] os.spawnv @@ -5703,13 +5750,17 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) } argvlist[argc] = NULL; +#if !defined(HAVE_RTPSPAWN) if (mode == _OLD_P_OVERLAY) mode = _P_OVERLAY; +#endif Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WSPAWNV spawnval = _wspawnv(mode, path->wide, argvlist); +#elif defined(HAVE_RTPSPAWN) + spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, NULL); #else spawnval = _spawnv(mode, path->narrow, argvlist); #endif @@ -5808,13 +5859,18 @@ os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, if (envlist == NULL) goto fail_1; +#if !defined(HAVE_RTPSPAWN) if (mode == _OLD_P_OVERLAY) mode = _P_OVERLAY; +#endif Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef HAVE_WSPAWNV spawnval = _wspawnve(mode, path->wide, argvlist, envlist); +#elif defined(HAVE_RTPSPAWN) + spawnval = _rtp_spawn(mode, path->narrow, (const char **)argvlist, + (const char **)envlist); #else spawnval = _spawnve(mode, path->narrow, argvlist, envlist); #endif @@ -13844,11 +13900,13 @@ all_ins(PyObject *m) if (PyModule_AddIntConstant(m, "POSIX_SPAWN_DUP2", POSIX_SPAWN_DUP2)) return -1; #endif -#ifdef HAVE_SPAWNV +#if defined(HAVE_SPAWNV) || defined (HAVE_RTPSPAWN) if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; - if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1; if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1; +#endif +#ifdef HAVE_SPAWNV + if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1; if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1; #endif diff --git a/configure b/configure index 6da65ddbba50cc..a0767b97136308 100755 --- a/configure +++ b/configure @@ -11484,7 +11484,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ - wcscoll wcsftime wcsxfrm wmemcmp writev _getpty + wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.ac b/configure.ac index e673e136be8a53..3a915eb5577c28 100644 --- a/configure.ac +++ b/configure.ac @@ -3541,7 +3541,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy strsignal symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ - wcscoll wcsftime wcsxfrm wmemcmp writev _getpty) + wcscoll wcsftime wcsxfrm wmemcmp writev _getpty rtpSpawn) # Force lchmod off for Linux. Linux disallows changing the mode of symbolic # links. Some libc implementations have a stub lchmod implementation that always diff --git a/pyconfig.h.in b/pyconfig.h.in index 4b779614727406..1cafb9ae42ddb8 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -835,6 +835,9 @@ /* Define to 1 if you have the `round' function. */ #undef HAVE_ROUND +/* Define to 1 if you have the `rtpSpawn' function. */ +#undef HAVE_RTPSPAWN + /* Define to 1 if you have the `sched_get_priority_max' function. */ #undef HAVE_SCHED_GET_PRIORITY_MAX From 4fb15021890d327023aefd95f5a84ac33b037d19 Mon Sep 17 00:00:00 2001 From: Lihua Zhao <44661095+LihuaZhao@users.noreply.github.com> Date: Tue, 21 May 2019 18:50:14 +0800 Subject: [PATCH 044/441] bpo-36648: fix mmap issue for VxWorks (GH-12394) The mmap module set MAP_SHARED flag when map anonymous memory, however VxWorks only support MAP_PRIVATE when map anonymous memory, this commit clear MAP_SHARED and set MAP_PRIVATE. --- .../next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst | 1 + Modules/mmapmodule.c | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst diff --git a/Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst b/Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst new file mode 100644 index 00000000000000..fd82fe086f068f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst @@ -0,0 +1 @@ +Fix mmap fail for VxWorks diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 33366b2d933194..917c6362c11d9a 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1164,6 +1164,13 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) #ifdef MAP_ANONYMOUS /* BSD way to map anonymous memory */ flags |= MAP_ANONYMOUS; + + /* VxWorks only supports MAP_ANONYMOUS with MAP_PRIVATE flag */ +#ifdef __VXWORKS__ + flags &= ~MAP_SHARED; + flags |= MAP_PRIVATE; +#endif + #else /* SVR4 method to map anonymous memory is to open /dev/zero */ fd = devzero = _Py_open("/dev/zero", O_RDWR); From ad098b6750f4d74387ac21c8e23ae1ee7ff13571 Mon Sep 17 00:00:00 2001 From: Chris Angelico Date: Tue, 21 May 2019 23:34:19 +1000 Subject: [PATCH 045/441] Annotate the unexplained assignment in exception unbinding (GH-11448) --- Python/compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/compile.c b/Python/compile.c index b20548c777246c..63b2456bb3e850 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2931,7 +2931,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) try: # body finally: - name = None + name = None # in case body contains "del name" del name */ From ccb7ca728e09b307f9e9fd36ec40353137e68a3b Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Tue, 21 May 2019 10:09:21 -0700 Subject: [PATCH 046/441] bpo-36929: Modify io/re tests to allow for missing mod name (#13392) * bpo-36929: Modify io/re tests to allow for missing mod name For a vanishingly small number of internal types, CPython sets the tp_name slot to mod_name.type_name, either in the PyTypeObject or the PyType_Spec. There are a few minor places where this surfaces: * Custom repr functions for those types (some of which ignore the tp_name in favor of using a string literal, such as _io.TextIOWrapper) * Pickling error messages The test suite only tests the former. This commit modifies the test suite to allow Python implementations to omit the module prefix. https://bugs.python.org/issue36929 --- Lib/test/test_io.py | 34 +++++++++++++++++----------------- Lib/test/test_re.py | 28 ++++++++++++++++------------ Misc/ACKS | 1 + 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 5406a2891bb251..dc44e506b1d0f4 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1119,12 +1119,12 @@ def f(): def test_repr(self): raw = self.MockRawIO() b = self.tp(raw) - clsname = "%s.%s" % (self.tp.__module__, self.tp.__qualname__) - self.assertEqual(repr(b), "<%s>" % clsname) + clsname = r"(%s\.)?%s" % (self.tp.__module__, self.tp.__qualname__) + self.assertRegex(repr(b), "<%s>" % clsname) raw.name = "dummy" - self.assertEqual(repr(b), "<%s name='dummy'>" % clsname) + self.assertRegex(repr(b), "<%s name='dummy'>" % clsname) raw.name = b"dummy" - self.assertEqual(repr(b), "<%s name=b'dummy'>" % clsname) + self.assertRegex(repr(b), "<%s name=b'dummy'>" % clsname) def test_recursive_repr(self): # Issue #25455 @@ -2598,17 +2598,17 @@ def test_repr(self): b = self.BufferedReader(raw) t = self.TextIOWrapper(b, encoding="utf-8") modname = self.TextIOWrapper.__module__ - self.assertEqual(repr(t), - "<%s.TextIOWrapper encoding='utf-8'>" % modname) + self.assertRegex(repr(t), + r"<(%s\.)?TextIOWrapper encoding='utf-8'>" % modname) raw.name = "dummy" - self.assertEqual(repr(t), - "<%s.TextIOWrapper name='dummy' encoding='utf-8'>" % modname) + self.assertRegex(repr(t), + r"<(%s\.)?TextIOWrapper name='dummy' encoding='utf-8'>" % modname) t.mode = "r" - self.assertEqual(repr(t), - "<%s.TextIOWrapper name='dummy' mode='r' encoding='utf-8'>" % modname) + self.assertRegex(repr(t), + r"<(%s\.)?TextIOWrapper name='dummy' mode='r' encoding='utf-8'>" % modname) raw.name = b"dummy" - self.assertEqual(repr(t), - "<%s.TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" % modname) + self.assertRegex(repr(t), + r"<(%s\.)?TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" % modname) t.buffer.detach() repr(t) # Should not raise an exception @@ -4174,11 +4174,11 @@ def run(): err = res.err.decode() if res.rc != 0: # Failure: should be a fatal error - self.assertIn("Fatal Python error: could not acquire lock " - "for <_io.BufferedWriter name='<{stream_name}>'> " - "at interpreter shutdown, possibly due to " - "daemon threads".format_map(locals()), - err) + pattern = (r"Fatal Python error: could not acquire lock " + r"for <(_io\.)?BufferedWriter name='<{stream_name}>'> " + r"at interpreter shutdown, possibly due to " + r"daemon threads".format_map(locals())) + self.assertRegex(err, pattern) else: self.assertFalse(err.strip('.!')) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 0a77e6fe9edc03..137c31de59ae4a 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1761,24 +1761,28 @@ def test_issue17998(self): def test_match_repr(self): for string in '[abracadabra]', S('[abracadabra]'): m = re.search(r'(.+)(.*?)\1', string) - self.assertEqual(repr(m), "<%s.%s object; " - "span=(1, 12), match='abracadabra'>" % - (type(m).__module__, type(m).__qualname__)) + pattern = r"<(%s\.)?%s object; span=\(1, 12\), match='abracadabra'>" % ( + type(m).__module__, type(m).__qualname__ + ) + self.assertRegex(repr(m), pattern) for string in (b'[abracadabra]', B(b'[abracadabra]'), bytearray(b'[abracadabra]'), memoryview(b'[abracadabra]')): m = re.search(br'(.+)(.*?)\1', string) - self.assertEqual(repr(m), "<%s.%s object; " - "span=(1, 12), match=b'abracadabra'>" % - (type(m).__module__, type(m).__qualname__)) + pattern = r"<(%s\.)?%s object; span=\(1, 12\), match=b'abracadabra'>" % ( + type(m).__module__, type(m).__qualname__ + ) + self.assertRegex(repr(m), pattern) first, second = list(re.finditer("(aa)|(bb)", "aa bb")) - self.assertEqual(repr(first), "<%s.%s object; " - "span=(0, 2), match='aa'>" % - (type(second).__module__, type(first).__qualname__)) - self.assertEqual(repr(second), "<%s.%s object; " - "span=(3, 5), match='bb'>" % - (type(second).__module__, type(second).__qualname__)) + pattern = r"<(%s\.)?%s object; span=\(0, 2\), match='aa'>" % ( + type(second).__module__, type(second).__qualname__ + ) + self.assertRegex(repr(first), pattern) + pattern = r"<(%s\.)?%s object; span=\(3, 5\), match='bb'>" % ( + type(second).__module__, type(second).__qualname__ + ) + self.assertRegex(repr(second), pattern) def test_zerowidth(self): # Issues 852532, 1647489, 3262, 25054. diff --git a/Misc/ACKS b/Misc/ACKS index 87107b9cfc7d2b..6b1fdbc37fa934 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -143,6 +143,7 @@ Michel Van den Bergh Julian Berman Brice Berna Olivier Bernard +Maxwell Bernstein Eric Beser Steven Bethard Stephen Bevan From d5c120f7eb6f2a9cdab282a5d588afed307a23df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Stucke?= Date: Tue, 21 May 2019 19:44:40 +0200 Subject: [PATCH 047/441] bpo-36035: fix Path.rglob for broken links (GH-11988) Links creating an infinite symlink loop would raise an exception. --- Lib/pathlib.py | 13 ++++++++++--- Lib/test/test_pathlib.py | 8 ++++++-- .../2019-02-22-14-30-19.bpo-36035.-6dy1y.rst | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst diff --git a/Lib/pathlib.py b/Lib/pathlib.py index b5bab1fe8f5acb..6369c4b2218d33 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -7,7 +7,7 @@ import re import sys from _collections_abc import Sequence -from errno import EINVAL, ENOENT, ENOTDIR, EBADF +from errno import EINVAL, ENOENT, ENOTDIR, EBADF, ELOOP from operator import attrgetter from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO from urllib.parse import quote_from_bytes as urlquote_from_bytes @@ -35,10 +35,11 @@ # # EBADF - guard against macOS `stat` throwing EBADF -_IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF) +_IGNORED_ERROS = (ENOENT, ENOTDIR, EBADF, ELOOP) _IGNORED_WINERRORS = ( 21, # ERROR_NOT_READY - drive exists but is not accessible + 1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself ) def _ignore_error(exception): @@ -520,7 +521,13 @@ def _select_from(self, parent_path, is_dir, exists, scandir): cf = parent_path._flavour.casefold entries = list(scandir(parent_path)) for entry in entries: - if not self.dironly or entry.is_dir(): + entry_is_dir = False + try: + entry_is_dir = entry.is_dir() + except OSError as e: + if not _ignore_error(e): + raise + if not self.dironly or entry_is_dir: name = entry.name casefolded = cf(name) if self.pat.match(casefolded): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index caad1c23876abd..069467a8459f00 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1221,7 +1221,8 @@ class _BasePathTest(object): # |-- dirE # No permissions # |-- fileA # |-- linkA -> fileA - # `-- linkB -> dirB + # |-- linkB -> dirB + # `-- brokenLinkLoop -> brokenLinkLoop # def setUp(self): @@ -1252,6 +1253,8 @@ def cleanup(): self.dirlink(os.path.join('..', 'dirB'), join('dirA', 'linkC')) # This one goes upwards, creating a loop. self.dirlink(os.path.join('..', 'dirB'), join('dirB', 'linkD')) + # Broken symlink (pointing to itself). + os.symlink('brokenLinkLoop', join('brokenLinkLoop')) if os.name == 'nt': # Workaround for http://bugs.python.org/issue13772. @@ -1384,7 +1387,7 @@ def test_iterdir(self): paths = set(it) expected = ['dirA', 'dirB', 'dirC', 'dirE', 'fileA'] if support.can_symlink(): - expected += ['linkA', 'linkB', 'brokenLink'] + expected += ['linkA', 'linkB', 'brokenLink', 'brokenLinkLoop'] self.assertEqual(paths, { P(BASE, q) for q in expected }) @support.skip_unless_symlink @@ -1465,6 +1468,7 @@ def test_rglob_symlink_loop(self): 'fileA', 'linkA', 'linkB', + 'brokenLinkLoop', } self.assertEqual(given, {p / x for x in expect}) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst new file mode 100644 index 00000000000000..1e4f7ac71f3395 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst @@ -0,0 +1 @@ +Added fix for broken symlinks in combination with pathlib \ No newline at end of file From aa32a7e1116f7aaaef9fec453db910e90ab7b101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= <47358913+isidentical@users.noreply.github.com> Date: Tue, 21 May 2019 20:47:42 +0300 Subject: [PATCH 048/441] bpo-23378: Add an extend action to argparse (GH-13305) Add an extend action to argparse https://bugs.python.org/issue23378 --- Doc/library/argparse.rst | 9 +++++++++ Lib/argparse.py | 7 +++++++ Lib/test/test_argparse.py | 9 +++++++++ .../Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst | 1 + 4 files changed, 26 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index cef197f3055581..b77a38ccd48577 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -797,6 +797,15 @@ how the command-line arguments should be handled. The supplied actions are: >>> parser.parse_args(['--version']) PROG 2.0 +* ``'extend'`` - This stores a list, and extends each argument value to the + list. + Example usage:: + + >>> parser = argparse.ArgumentParser() + >>> parser.add_argument("--foo", action="extend", nargs="+", type=str) + >>> parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"]) + Namespace(foo=['f1', 'f2', 'f3', 'f4']) + You may also specify an arbitrary action by passing an Action subclass or other object that implements the same interface. The recommended way to do this is to extend :class:`Action`, overriding the ``__call__`` method diff --git a/Lib/argparse.py b/Lib/argparse.py index 798766f6c4086a..ef888f063b3286 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1154,6 +1154,12 @@ def __call__(self, parser, namespace, values, option_string=None): vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) +class _ExtendAction(_AppendAction): + def __call__(self, parser, namespace, values, option_string=None): + items = getattr(namespace, self.dest, None) + items = _copy_items(items) + items.extend(values) + setattr(namespace, self.dest, items) # ============== # Type classes @@ -1262,6 +1268,7 @@ def __init__(self, self.register('action', 'help', _HelpAction) self.register('action', 'version', _VersionAction) self.register('action', 'parsers', _SubParsersAction) + self.register('action', 'extend', _ExtendAction) # raise an exception if the conflict handler is invalid self._get_handler() diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index e849c7ba49bcd2..9d68f40571fe6f 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1786,6 +1786,15 @@ def test(self): self.assertEqual(parser.parse_args(['42']), NS(badger='foo[42]')) +class TestActionExtend(ParserTestCase): + argument_signatures = [ + Sig('--foo', action="extend", nargs="+", type=str), + ] + failures = () + successes = [ + ('--foo f1 --foo f2 f3 f4', NS(foo=['f1', 'f2', 'f3', 'f4'])), + ] + # ================ # Subparsers tests # ================ diff --git a/Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst b/Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst new file mode 100644 index 00000000000000..c7c3f174d637e4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst @@ -0,0 +1 @@ +Add an extend action to argparser. From 565b4f1ac7304d1e690c404ca8316f383ba60862 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 21 May 2019 13:12:03 -0700 Subject: [PATCH 049/441] bpo-34616: Add PyCF_ALLOW_TOP_LEVEL_AWAIT to allow top-level await (GH-13148) Co-Authored-By: Yury Selivanov --- Doc/library/functions.rst | 10 +++ Include/compile.h | 1 + Lib/test/test_builtin.py | 73 ++++++++++++++++++- .../2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst | 1 + Parser/asdl_c.py | 2 + Python/Python-ast.c | 2 + Python/compile.c | 28 +++++-- 7 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 613e4f74ac4176..1a9a8b5beeeebe 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -257,6 +257,12 @@ are always available. They are listed here in alphabetical order. can be found as the :attr:`~__future__._Feature.compiler_flag` attribute on the :class:`~__future__._Feature` instance in the :mod:`__future__` module. + The optional argument *flags* also controls whether the compiled source is + allowed to contain top-level ``await``, ``async for`` and ``async with``. + When the bit ``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` is set, the return code + object has ``CO_COROUTINE`` set in ``co_code``, and can be interactively + executed via ``await eval(code_object)``. + The argument *optimize* specifies the optimization level of the compiler; the default value of ``-1`` selects the optimization level of the interpreter as given by :option:`-O` options. Explicit levels are ``0`` (no optimization; @@ -290,6 +296,10 @@ are always available. They are listed here in alphabetical order. Previously, :exc:`TypeError` was raised when null bytes were encountered in *source*. + .. versionadded:: 3.8 + ``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` can now be passed in flags to enable + support for top-level ``await``, ``async for``, and ``async with``. + .. class:: complex([real[, imag]]) diff --git a/Include/compile.h b/Include/compile.h index 13708678675f7b..a833caa06b9dad 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -23,6 +23,7 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); #define PyCF_ONLY_AST 0x0400 #define PyCF_IGNORE_COOKIE 0x0800 #define PyCF_TYPE_COMMENTS 0x1000 +#define PyCF_ALLOW_TOP_LEVEL_AWAIT 0x2000 #ifndef Py_LIMITED_API typedef struct { diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 5674ea89b1c408..4a358e89d1c2e5 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1,6 +1,7 @@ # Python test set -- built-in functions import ast +import asyncio import builtins import collections import decimal @@ -18,9 +19,14 @@ import unittest import warnings from contextlib import ExitStack +from inspect import CO_COROUTINE +from itertools import product +from textwrap import dedent +from types import AsyncGeneratorType, FunctionType from operator import neg from test.support import ( - EnvironmentVarGuard, TESTFN, check_warnings, swap_attr, unlink) + EnvironmentVarGuard, TESTFN, check_warnings, swap_attr, unlink, + maybe_get_event_loop_policy) from test.support.script_helper import assert_python_ok from unittest.mock import MagicMock, patch try: @@ -358,6 +364,71 @@ def f(): """doc""" rv = ns['f']() self.assertEqual(rv, tuple(expected)) + def test_compile_top_level_await(self): + """Test whether code some top level await can be compiled. + + Make sure it compiles only with the PyCF_ALLOW_TOP_LEVEL_AWAIT flag set, + and make sure the generated code object has the CO_COROUTINE flag set in + order to execute it with `await eval(.....)` instead of exec, or via a + FunctionType. + """ + + # helper function just to check we can run top=level async-for + async def arange(n): + for i in range(n): + yield i + + modes = ('single', 'exec') + code_samples = ['''a = await asyncio.sleep(0, result=1)''', + '''async for i in arange(1): + a = 1''', + '''async with asyncio.Lock() as l: + a = 1'''] + policy = maybe_get_event_loop_policy() + try: + for mode, code_sample in product(modes,code_samples): + source = dedent(code_sample) + with self.assertRaises(SyntaxError, msg=f"{source=} {mode=}"): + compile(source, '?' , mode) + + co = compile(source, + '?', + mode, + flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) + + self.assertEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE, + msg=f"{source=} {mode=}") + + + # test we can create and advance a function type + globals_ = {'asyncio': asyncio, 'a':0, 'arange': arange} + async_f = FunctionType(co, globals_) + asyncio.run(async_f()) + self.assertEqual(globals_['a'], 1) + + # test we can await-eval, + globals_ = {'asyncio': asyncio, 'a':0, 'arange': arange} + asyncio.run(eval(co, globals_)) + self.assertEqual(globals_['a'], 1) + finally: + asyncio.set_event_loop_policy(policy) + + def test_compile_async_generator(self): + """ + With the PyCF_ALLOW_TOP_LEVEL_AWAIT flag added in 3.8, we want to + make sure AsyncGenerators are still properly not marked with CO_COROUTINE + """ + code = dedent("""async def ticker(): + for i in range(10): + yield i + await asyncio.sleep(0)""") + + co = compile(code, '?', 'exec', flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) + glob = {} + exec(co, glob) + self.assertEqual(type(glob['ticker']()), AsyncGeneratorType) + + def test_delattr(self): sys.spam = 1 delattr(sys, 'spam') diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst new file mode 100644 index 00000000000000..c264d21bd01610 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst @@ -0,0 +1 @@ +The ``compile()`` builtin functions now support the ``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag, which allow to compile sources that contains top-level ``await``, ``async with`` or ``async for``. This is useful to evaluate async-code from with an already async functions; for example in a custom REPL. \ No newline at end of file diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 4091b6db638cd6..cb0e6d7f9df26a 100644 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1000,6 +1000,8 @@ def visitModule(self, mod): self.emit("if (!m) return NULL;", 1) self.emit("d = PyModule_GetDict(m);", 1) self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL;', 1) + self.emit('if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0)', 1) + self.emit("return NULL;", 2) self.emit('if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0)', 1) self.emit("return NULL;", 2) self.emit('if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0)', 1) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index cb53a41cdf35bd..552750584480b7 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -8776,6 +8776,8 @@ PyInit__ast(void) if (!m) return NULL; d = PyModule_GetDict(m); if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL; + if (PyModule_AddIntMacro(m, PyCF_ALLOW_TOP_LEVEL_AWAIT) < 0) + return NULL; if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0) return NULL; if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0) diff --git a/Python/compile.c b/Python/compile.c index 63b2456bb3e850..734e8401ff0247 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2609,7 +2609,9 @@ static int compiler_async_for(struct compiler *c, stmt_ty s) { basicblock *start, *except, *end; - if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { + if (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT){ + c->u->u_ste->ste_coroutine = 1; + } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { return compiler_error(c, "'async for' outside async function"); } @@ -4564,7 +4566,9 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos); assert(s->kind == AsyncWith_kind); - if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { + if (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT){ + c->u->u_ste->ste_coroutine = 1; + } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){ return compiler_error(c, "'async with' outside async function"); } @@ -4773,12 +4777,16 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) ADDOP(c, YIELD_FROM); break; case Await_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'await' outside function"); + if (!(c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT)){ + if (c->u->u_ste->ste_type != FunctionBlock){ + return compiler_error(c, "'await' outside function"); + } - if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && - c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION) - return compiler_error(c, "'await' outside async function"); + if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && + c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){ + return compiler_error(c, "'await' outside async function"); + } + } VISIT(c, expr, e->v.Await.value); ADDOP(c, GET_AWAITABLE); @@ -5712,6 +5720,12 @@ compute_code_flags(struct compiler *c) /* (Only) inherit compilerflags in PyCF_MASK */ flags |= (c->c_flags->cf_flags & PyCF_MASK); + if ((c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) && + ste->ste_coroutine && + !ste->ste_generator) { + flags |= CO_COROUTINE; + } + return flags; } From 7abf8c60819d5749e6225b371df51a9c5f1ea8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= <47358913+isidentical@users.noreply.github.com> Date: Tue, 21 May 2019 23:27:36 +0300 Subject: [PATCH 050/441] bpo-25652: Fix __rmod__ of UserString (GH-13326) The ``__rmod__`` method of ``collections.UserString`` class had a bug that made it unusable. https://bugs.python.org/issue25652 --- Lib/collections/__init__.py | 5 ++--- Lib/test/test_userstring.py | 12 ++++++++++++ .../Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 960d82a5dcfbf5..cb7f1bb1fcfe41 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1214,9 +1214,8 @@ def __mul__(self, n): __rmul__ = __mul__ def __mod__(self, args): return self.__class__(self.data % args) - def __rmod__(self, format): - return self.__class__(format % args) - + def __rmod__(self, template): + return self.__class__(str(template) % self) # the following methods are defined in alphabetical order: def capitalize(self): return self.__class__(self.data.capitalize()) def casefold(self): diff --git a/Lib/test/test_userstring.py b/Lib/test/test_userstring.py index 71528223d35bb5..19b0acfc760fa4 100644 --- a/Lib/test/test_userstring.py +++ b/Lib/test/test_userstring.py @@ -39,6 +39,18 @@ def checkcall(self, object, methodname, *args): # we don't fix the arguments, because UserString can't cope with it getattr(object, methodname)(*args) + def test_rmod(self): + class ustr2(UserString): + pass + + class ustr3(ustr2): + def __rmod__(self, other): + return super().__rmod__(other) + + fmt2 = ustr2('value is %s') + str3 = ustr3('TEST') + self.assertEqual(fmt2 % str3, 'value is TEST') + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst b/Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst new file mode 100644 index 00000000000000..421fccfe8c73a6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst @@ -0,0 +1 @@ +Fix bug in ``__rmod__`` of ``UserString`` - by Batuhan Taskaya. From eca18aac7b5952d23854d27dc8e502dfb0bb0505 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Tue, 21 May 2019 17:20:21 -0400 Subject: [PATCH 051/441] bpo-34616: Fix code style and unbreak buildbots (GH-13473) See also PR GH-13148. --- Lib/test/test_builtin.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 4a358e89d1c2e5..e32fb75d81912d 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -367,10 +367,10 @@ def f(): """doc""" def test_compile_top_level_await(self): """Test whether code some top level await can be compiled. - Make sure it compiles only with the PyCF_ALLOW_TOP_LEVEL_AWAIT flag set, - and make sure the generated code object has the CO_COROUTINE flag set in - order to execute it with `await eval(.....)` instead of exec, or via a - FunctionType. + Make sure it compiles only with the PyCF_ALLOW_TOP_LEVEL_AWAIT flag + set, and make sure the generated code object has the CO_COROUTINE flag + set in order to execute it with `await eval(.....)` instead of exec, + or via a FunctionType. """ # helper function just to check we can run top=level async-for @@ -379,17 +379,20 @@ async def arange(n): yield i modes = ('single', 'exec') - code_samples = ['''a = await asyncio.sleep(0, result=1)''', - '''async for i in arange(1): - a = 1''', - '''async with asyncio.Lock() as l: - a = 1'''] + code_samples = [ + '''a = await asyncio.sleep(0, result=1)''', + '''async for i in arange(1): + a = 1''', + '''async with asyncio.Lock() as l: + a = 1''' + ] policy = maybe_get_event_loop_policy() try: - for mode, code_sample in product(modes,code_samples): + for mode, code_sample in product(modes, code_samples): source = dedent(code_sample) - with self.assertRaises(SyntaxError, msg=f"{source=} {mode=}"): - compile(source, '?' , mode) + with self.assertRaises( + SyntaxError, msg=f"source={source} mode={mode}"): + compile(source, '?', mode) co = compile(source, '?', @@ -397,17 +400,16 @@ async def arange(n): flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) self.assertEqual(co.co_flags & CO_COROUTINE, CO_COROUTINE, - msg=f"{source=} {mode=}") - + msg=f"source={source} mode={mode}") # test we can create and advance a function type - globals_ = {'asyncio': asyncio, 'a':0, 'arange': arange} + globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange} async_f = FunctionType(co, globals_) asyncio.run(async_f()) self.assertEqual(globals_['a'], 1) # test we can await-eval, - globals_ = {'asyncio': asyncio, 'a':0, 'arange': arange} + globals_ = {'asyncio': asyncio, 'a': 0, 'arange': arange} asyncio.run(eval(co, globals_)) self.assertEqual(globals_['a'], 1) finally: @@ -416,7 +418,8 @@ async def arange(n): def test_compile_async_generator(self): """ With the PyCF_ALLOW_TOP_LEVEL_AWAIT flag added in 3.8, we want to - make sure AsyncGenerators are still properly not marked with CO_COROUTINE + make sure AsyncGenerators are still properly not marked with the + CO_COROUTINE flag. """ code = dedent("""async def ticker(): for i in range(10): @@ -428,7 +431,6 @@ def test_compile_async_generator(self): exec(co, glob) self.assertEqual(type(glob['ticker']()), AsyncGeneratorType) - def test_delattr(self): sys.spam = 1 delattr(sys, 'spam') From 2725cb01d7cbf5caecb51cc20d97ba324b09ce96 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Wed, 22 May 2019 02:00:35 +0300 Subject: [PATCH 052/441] bpo-36948: Fix test_urlopener_retrieve_file on Windows (GH-13476) --- Lib/test/test_urllib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 74b19fbdcd8dbe..6b995fef8cb561 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1470,7 +1470,8 @@ def test_urlopener_retrieve_file(self): os.close(fd) fileurl = "file:" + urllib.request.pathname2url(tmpfile) filename, _ = urllib.request.URLopener().retrieve(fileurl) - self.assertEqual(filename, tmpfile) + # Some buildbots have TEMP folder that uses a lowercase drive letter. + self.assertEqual(os.path.normcase(filename), os.path.normcase(tmpfile)) @support.ignore_warnings(category=DeprecationWarning) def test_urlopener_retrieve_remote(self): From ef9d9b63129a2f243591db70e9a2dd53fab95d86 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 22 May 2019 11:28:22 +0200 Subject: [PATCH 053/441] bpo-36829: Add sys.unraisablehook() (GH-13187) Add new sys.unraisablehook() function which can be overridden to control how "unraisable exceptions" are handled. It is called when an exception has occurred but there is no way for Python to handle it. For example, when a destructor raises an exception or during garbage collection (gc.collect()). Changes: * Add an internal UnraisableHookArgs type used to pass arguments to sys.unraisablehook. * Add _PyErr_WriteUnraisableDefaultHook(). * The default hook now ignores exception on writing the traceback. * test_sys now uses unittest.main() to automatically discover tests: remove test_main(). * Add _PyErr_Init(). * Fix PyErr_WriteUnraisable(): hold a strong reference to sys.stderr while using it --- Doc/c-api/exceptions.rst | 5 + Doc/library/sys.rst | 33 ++- Doc/whatsnew/3.8.rst | 10 + Include/internal/pycore_pylifecycle.h | 4 + Lib/test/test_sys.py | 80 ++++- .../2019-05-08-12-51-37.bpo-36829.8enFMA.rst | 5 + Modules/_testcapimodule.c | 15 + Python/clinic/sysmodule.c.h | 18 +- Python/errors.c | 278 +++++++++++++++--- Python/importlib.h | 120 ++++---- Python/pylifecycle.c | 12 + Python/sysmodule.c | 28 ++ 12 files changed, 491 insertions(+), 117 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 00ef00526bc5f8..18ff697a2325eb 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -72,6 +72,9 @@ Printing and clearing .. c:function:: void PyErr_WriteUnraisable(PyObject *obj) + Call :func:`sys.unraisablehook` using the current exception and *obj* + argument. + This utility function prints a warning message to ``sys.stderr`` when an exception has been set but it is impossible for the interpreter to actually raise the exception. It is used, for example, when an exception occurs in an @@ -81,6 +84,8 @@ Printing and clearing in which the unraisable exception occurred. If possible, the repr of *obj* will be printed in the warning message. + An exception must be set when calling this function. + Raising exceptions ================== diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 7d27c89fac9572..3b754bd4e27677 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -248,16 +248,19 @@ always available. before the program exits. The handling of such top-level exceptions can be customized by assigning another three-argument function to ``sys.excepthook``. + See also :func:`unraisablehook` which handles unraisable exceptions. + .. data:: __breakpointhook__ __displayhook__ __excepthook__ + __unraisablehook__ These objects contain the original values of ``breakpointhook``, - ``displayhook``, and ``excepthook`` at the start of the program. They are - saved so that ``breakpointhook``, ``displayhook`` and ``excepthook`` can be - restored in case they happen to get replaced with broken or alternative - objects. + ``displayhook``, ``excepthook``, and ``unraisablehook`` at the start of the + program. They are saved so that ``breakpointhook``, ``displayhook`` and + ``excepthook``, ``unraisablehook`` can be restored in case they happen to + get replaced with broken or alternative objects. .. versionadded:: 3.7 __breakpointhook__ @@ -1487,6 +1490,28 @@ always available. is suppressed and only the exception type and value are printed. +.. function:: unraisablehook(unraisable, /) + + Handle an unraisable exception. + + Called when an exception has occurred but there is no way for Python to + handle it. For example, when a destructor raises an exception or during + garbage collection (:func:`gc.collect`). + + The *unraisable* argument has the following attributes: + + * *exc_type*: Exception type. + * *exc_value*: Exception value, can be ``None``. + * *exc_traceback*: Exception traceback, can be ``None``. + * *object*: Object causing the exception, can be ``None``. + + :func:`sys.unraisablehook` can be overridden to control how unraisable + exceptions are handled. + + See also :func:`excepthook` which handles uncaught exceptions. + + .. versionadded:: 3.8 + .. data:: version A string containing the version number of the Python interpreter plus additional diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 5f8208d5bf4a5e..63b8200a1528f0 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -481,6 +481,16 @@ and manipulating normal distributions of a random variable. [7.672102882379219, 12.000027119750287, 4.647488369766392] +sys +--- + +Add new :func:`sys.unraisablehook` function which can be overridden to control +how "unraisable exceptions" are handled. It is called when an exception has +occurred but there is no way for Python to handle it. For example, when a +destructor raises an exception or during garbage collection +(:func:`gc.collect`). + + tarfile ------- diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 4684ebea44a683..07cf815363b779 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -48,6 +48,7 @@ extern int _PySys_InitMain( PyInterpreterState *interp); extern _PyInitError _PyImport_Init(PyInterpreterState *interp); extern _PyInitError _PyExc_Init(void); +extern _PyInitError _PyErr_Init(void); extern _PyInitError _PyBuiltins_AddExceptions(PyObject * bltinmod); extern _PyInitError _PyImportHooks_Init(void); extern int _PyFloat_Init(void); @@ -100,8 +101,11 @@ PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig( const _PyCoreConfig *coreconfig, const _PyArgv *args); + PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p); +PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index d1c7daad7bba48..2b358ca0466e6e 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -876,6 +876,81 @@ def test__enablelegacywindowsfsencoding(self): self.assertEqual(out, 'mbcs replace') +@test.support.cpython_only +class UnraisableHookTest(unittest.TestCase): + def write_unraisable_exc(self, exc, obj): + import _testcapi + import types + try: + # raise the exception to get a traceback in the except block + try: + raise exc + except Exception as exc2: + _testcapi.write_unraisable_exc(exc2, obj) + return types.SimpleNamespace(exc_type=type(exc2), + exc_value=exc2, + exc_traceback=exc2.__traceback__, + object=obj) + finally: + # Explicitly break any reference cycle + exc = None + exc2 = None + + def test_original_unraisablehook(self): + obj = "an object" + + with test.support.captured_output("stderr") as stderr: + with test.support.swap_attr(sys, 'unraisablehook', + sys.__unraisablehook__): + self.write_unraisable_exc(ValueError(42), obj) + + err = stderr.getvalue() + self.assertIn(f'Exception ignored in: {obj!r}\n', err) + self.assertIn('Traceback (most recent call last):\n', err) + self.assertIn('ValueError: 42\n', err) + + def test_original_unraisablehook_wrong_type(self): + exc = ValueError(42) + with test.support.swap_attr(sys, 'unraisablehook', + sys.__unraisablehook__): + with self.assertRaises(TypeError): + sys.unraisablehook(exc) + + def test_custom_unraisablehook(self): + hook_args = None + + def hook_func(args): + nonlocal hook_args + hook_args = args + + obj = object() + try: + with test.support.swap_attr(sys, 'unraisablehook', hook_func): + expected = self.write_unraisable_exc(ValueError(42), obj) + for attr in "exc_type exc_value exc_traceback object".split(): + self.assertEqual(getattr(hook_args, attr), + getattr(expected, attr), + (hook_args, expected)) + finally: + # expected and hook_args contain an exception: break reference cycle + expected = None + hook_args = None + + def test_custom_unraisablehook_fail(self): + def hook_func(*args): + raise Exception("hook_func failed") + + with test.support.captured_output("stderr") as stderr: + with test.support.swap_attr(sys, 'unraisablehook', hook_func): + self.write_unraisable_exc(ValueError(42), None) + + err = stderr.getvalue() + self.assertIn(f'Exception ignored in: {hook_func!r}\n', + err) + self.assertIn('Traceback (most recent call last):\n', err) + self.assertIn('Exception: hook_func failed\n', err) + + @test.support.cpython_only class SizeofTest(unittest.TestCase): @@ -1277,8 +1352,5 @@ def test_asyncgen_hooks(self): self.assertIsNone(cur.finalizer) -def test_main(): - test.support.run_unittest(SysModuleTest, SizeofTest) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst b/Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst new file mode 100644 index 00000000000000..0b04efcb7e2f0e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst @@ -0,0 +1,5 @@ +Add new :func:`sys.unraisablehook` function which can be overridden to +control how "unraisable exceptions" are handled. It is called when an +exception has occurred but there is no way for Python to handle it. For +example, when a destructor raises an exception or during garbage collection +(:func:`gc.collect`). diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 2af553960cc7da..7945f498f9e2e7 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4982,6 +4982,20 @@ negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) #endif +static PyObject* +test_write_unraisable_exc(PyObject *self, PyObject *args) +{ + PyObject *exc, *obj; + if (!PyArg_ParseTuple(args, "OO", &exc, &obj)) { + return NULL; + } + + PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); + PyErr_WriteUnraisable(obj); + Py_RETURN_NONE; +} + + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", raise_memoryerror, METH_NOARGS}, @@ -5221,6 +5235,7 @@ static PyMethodDef TestMethods[] = { #ifdef Py_REF_DEBUG {"negative_refcount", negative_refcount, METH_NOARGS}, #endif + {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index c70b721983c1c4..aede60ac85b519 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -65,6 +65,22 @@ sys_exc_info(PyObject *module, PyObject *Py_UNUSED(ignored)) return sys_exc_info_impl(module); } +PyDoc_STRVAR(sys_unraisablehook__doc__, +"unraisablehook($module, unraisable, /)\n" +"--\n" +"\n" +"Handle an unraisable exception.\n" +"\n" +"The unraisable argument has the following attributes:\n" +"\n" +"* exc_type: Exception type.\n" +"* exc_value: Exception value.\n" +"* exc_tb: Exception traceback, can be None.\n" +"* obj: Object causing the exception, can be None."); + +#define SYS_UNRAISABLEHOOK_METHODDEF \ + {"unraisablehook", (PyCFunction)sys_unraisablehook, METH_O, sys_unraisablehook__doc__}, + PyDoc_STRVAR(sys_exit__doc__, "exit($module, status=None, /)\n" "--\n" @@ -1060,4 +1076,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=3ba4c194d00f1866 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=603e4d5a453dc769 input=a9049054013a1b77]*/ diff --git a/Python/errors.c b/Python/errors.c index b8af1df4161d57..9622b5a1067df9 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -2,6 +2,7 @@ /* Error handling */ #include "Python.h" +#include "pycore_coreconfig.h" #include "pycore_pystate.h" #ifndef __STDC__ @@ -944,90 +945,271 @@ PyErr_NewExceptionWithDoc(const char *name, const char *doc, } -/* Call when an exception has occurred but there is no way for Python - to handle it. Examples: exception in __del__ or during GC. */ -void -PyErr_WriteUnraisable(PyObject *obj) +PyDoc_STRVAR(UnraisableHookArgs__doc__, +"UnraisableHookArgs\n\ +\n\ +Type used to pass arguments to sys.unraisablehook."); + +static PyTypeObject UnraisableHookArgsType; + +static PyStructSequence_Field UnraisableHookArgs_fields[] = { + {"exc_type", "Exception type"}, + {"exc_value", "Exception value"}, + {"exc_traceback", "Exception traceback"}, + {"object", "Object causing the exception"}, + {0} +}; + +static PyStructSequence_Desc UnraisableHookArgs_desc = { + .name = "UnraisableHookArgs", + .doc = UnraisableHookArgs__doc__, + .fields = UnraisableHookArgs_fields, + .n_in_sequence = 4 +}; + + +_PyInitError +_PyErr_Init(void) { - _Py_IDENTIFIER(__module__); - PyObject *f, *t, *v, *tb; - PyObject *moduleName = NULL; - const char *className; + if (UnraisableHookArgsType.tp_name == NULL) { + if (PyStructSequence_InitType2(&UnraisableHookArgsType, + &UnraisableHookArgs_desc) < 0) { + return _Py_INIT_ERR("failed to initialize UnraisableHookArgs type"); + } + } + return _Py_INIT_OK(); +} - PyErr_Fetch(&t, &v, &tb); - f = _PySys_GetObjectId(&PyId_stderr); - if (f == NULL || f == Py_None) - goto done; +static PyObject * +make_unraisable_hook_args(PyObject *exc_type, PyObject *exc_value, + PyObject *exc_tb, PyObject *obj) +{ + PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); + if (args == NULL) { + return NULL; + } + + Py_ssize_t pos = 0; +#define ADD_ITEM(exc_type) \ + do { \ + if (exc_type == NULL) { \ + exc_type = Py_None; \ + } \ + Py_INCREF(exc_type); \ + PyStructSequence_SET_ITEM(args, pos++, exc_type); \ + } while (0) + + + ADD_ITEM(exc_type); + ADD_ITEM(exc_value); + ADD_ITEM(exc_tb); + ADD_ITEM(obj); +#undef ADD_ITEM + + if (PyErr_Occurred()) { + Py_DECREF(args); + return NULL; + } + return args; +} + + + +/* Default implementation of sys.unraisablehook. + + It can be called to log the exception of a custom sys.unraisablehook. - if (obj) { - if (PyFile_WriteString("Exception ignored in: ", f) < 0) - goto done; - if (PyFile_WriteObject(obj, f, 0) < 0) { + Do nothing if sys.stderr attribute doesn't exist or is set to None. */ +static int +write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, + PyObject *exc_tb, PyObject *obj, PyObject *file) +{ + if (obj != NULL && obj != Py_None) { + if (PyFile_WriteString("Exception ignored in: ", file) < 0) { + return -1; + } + + if (PyFile_WriteObject(obj, file, 0) < 0) { PyErr_Clear(); - if (PyFile_WriteString("", f) < 0) { - goto done; + if (PyFile_WriteString("", file) < 0) { + return -1; } } - if (PyFile_WriteString("\n", f) < 0) - goto done; + if (PyFile_WriteString("\n", file) < 0) { + return -1; + } } - if (PyTraceBack_Print(tb, f) < 0) - goto done; + if (exc_tb != NULL && exc_tb != Py_None) { + if (PyTraceBack_Print(exc_tb, file) < 0) { + /* continue even if writing the traceback failed */ + PyErr_Clear(); + } + } - if (!t) - goto done; + if (!exc_type) { + return -1; + } - assert(PyExceptionClass_Check(t)); - className = PyExceptionClass_Name(t); + assert(PyExceptionClass_Check(exc_type)); + const char *className = PyExceptionClass_Name(exc_type); if (className != NULL) { const char *dot = strrchr(className, '.'); if (dot != NULL) className = dot+1; } - moduleName = _PyObject_GetAttrId(t, &PyId___module__); + _Py_IDENTIFIER(__module__); + PyObject *moduleName = _PyObject_GetAttrId(exc_type, &PyId___module__); if (moduleName == NULL || !PyUnicode_Check(moduleName)) { + Py_XDECREF(moduleName); PyErr_Clear(); - if (PyFile_WriteString("", f) < 0) - goto done; + if (PyFile_WriteString("", file) < 0) { + return -1; + } } else { if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) { - if (PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) < 0) - goto done; - if (PyFile_WriteString(".", f) < 0) - goto done; + if (PyFile_WriteObject(moduleName, file, Py_PRINT_RAW) < 0) { + Py_DECREF(moduleName); + return -1; + } + Py_DECREF(moduleName); + if (PyFile_WriteString(".", file) < 0) { + return -1; + } + } + else { + Py_DECREF(moduleName); } } if (className == NULL) { - if (PyFile_WriteString("", f) < 0) - goto done; + if (PyFile_WriteString("", file) < 0) { + return -1; + } } else { - if (PyFile_WriteString(className, f) < 0) - goto done; + if (PyFile_WriteString(className, file) < 0) { + return -1; + } } - if (v && v != Py_None) { - if (PyFile_WriteString(": ", f) < 0) - goto done; - if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) { + if (exc_value && exc_value != Py_None) { + if (PyFile_WriteString(": ", file) < 0) { + return -1; + } + if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) { PyErr_Clear(); - if (PyFile_WriteString("", f) < 0) { + if (PyFile_WriteString("", file) < 0) { + return -1; + } + } + } + if (PyFile_WriteString("\n", file) < 0) { + return -1; + } + return 0; +} + + +static int +write_unraisable_exc(PyObject *exc_type, PyObject *exc_value, + PyObject *exc_tb, PyObject *obj) +{ + PyObject *file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL || file == Py_None) { + return 0; + } + + /* Hold a strong reference to ensure that sys.stderr doesn't go away + while we use it */ + Py_INCREF(file); + int res = write_unraisable_exc_file(exc_type, exc_value, exc_tb, + obj, file); + Py_DECREF(file); + + return res; +} + + +PyObject* +_PyErr_WriteUnraisableDefaultHook(PyObject *args) +{ + if (Py_TYPE(args) != &UnraisableHookArgsType) { + PyErr_SetString(PyExc_TypeError, + "sys.unraisablehook argument type " + "must be UnraisableHookArgs"); + return NULL; + } + + /* Borrowed references */ + PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); + PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); + PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); + PyObject *obj = PyStructSequence_GET_ITEM(args, 3); + + if (write_unraisable_exc(exc_type, exc_value, exc_tb, obj) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +/* Call sys.unraisablehook(). + + This function can be used when an exception has occurred but there is no way + for Python to handle it. For example, when a destructor raises an exception + or during garbage collection (gc.collect()). + + An exception must be set when calling this function. */ +void +PyErr_WriteUnraisable(PyObject *obj) +{ + PyObject *exc_type, *exc_value, *exc_tb; + + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + + assert(exc_type != NULL); + + if (exc_type == NULL) { + /* sys.unraisablehook requires that at least exc_type is set */ + goto default_hook; + } + + _Py_IDENTIFIER(unraisablehook); + PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); + if (hook != NULL && hook != Py_None) { + PyObject *hook_args; + + hook_args = make_unraisable_hook_args(exc_type, exc_value, exc_tb, obj); + if (hook_args != NULL) { + PyObject *args[1] = {hook_args}; + PyObject *res = _PyObject_FastCall(hook, args, 1); + Py_DECREF(hook_args); + if (res != NULL) { + Py_DECREF(res); goto done; } } + + /* sys.unraisablehook failed: log its error using default hook */ + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + + obj = hook; } - if (PyFile_WriteString("\n", f) < 0) - goto done; + +default_hook: + /* Call the default unraisable hook (ignore failure) */ + (void)write_unraisable_exc(exc_type, exc_value, exc_tb, obj); done: - Py_XDECREF(moduleName); - Py_XDECREF(t); - Py_XDECREF(v); - Py_XDECREF(tb); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); PyErr_Clear(); /* Just in case */ } diff --git a/Python/importlib.h b/Python/importlib.h index 694984af8060f8..5bd1d179e2f0c8 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -1326,8 +1326,8 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 97,114,100,108,101,115,115,32,111,102,32,97,110,121,32,114, 97,105,115,101,100,32,101,120,99,101,112,116,105,111,110,115, 46,78,41,2,114,57,0,0,0,114,60,0,0,0,41,4, - 114,30,0,0,0,90,8,101,120,99,95,116,121,112,101,90, - 9,101,120,99,95,118,97,108,117,101,90,13,101,120,99,95, + 114,30,0,0,0,218,8,101,120,99,95,116,121,112,101,218, + 9,101,120,99,95,118,97,108,117,101,218,13,101,120,99,95, 116,114,97,99,101,98,97,99,107,114,10,0,0,0,114,10, 0,0,0,114,11,0,0,0,114,56,0,0,0,99,3,0, 0,115,2,0,0,0,0,2,122,27,95,73,109,112,111,114, @@ -1358,7 +1358,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 98,97,115,101,114,10,0,0,0,114,10,0,0,0,114,11, 0,0,0,218,13,95,114,101,115,111,108,118,101,95,110,97, 109,101,104,3,0,0,115,10,0,0,0,0,2,16,1,12, - 1,8,1,8,1,114,185,0,0,0,99,3,0,0,0,0, + 1,8,1,8,1,114,188,0,0,0,99,3,0,0,0,0, 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, 0,0,0,115,34,0,0,0,124,0,160,0,124,1,124,2, 161,2,125,3,124,3,100,0,107,8,114,24,100,0,83,0, @@ -1368,7 +1368,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 109,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, 0,0,0,218,17,95,102,105,110,100,95,115,112,101,99,95, 108,101,103,97,99,121,113,3,0,0,115,8,0,0,0,0, - 3,12,1,8,1,4,1,114,187,0,0,0,99,3,0,0, + 3,12,1,8,1,4,1,114,190,0,0,0,99,3,0,0, 0,0,0,0,0,0,0,0,0,10,0,0,0,10,0,0, 0,67,0,0,0,115,12,1,0,0,116,0,106,1,125,3, 124,3,100,1,107,8,114,22,116,2,100,2,131,1,130,1, @@ -1398,17 +1398,17 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 104,114,79,0,0,0,218,9,95,119,97,114,110,105,110,103, 115,218,4,119,97,114,110,218,13,73,109,112,111,114,116,87, 97,114,110,105,110,103,114,92,0,0,0,114,178,0,0,0, - 114,166,0,0,0,114,106,0,0,0,114,187,0,0,0,114, + 114,166,0,0,0,114,106,0,0,0,114,190,0,0,0,114, 105,0,0,0,41,10,114,17,0,0,0,114,164,0,0,0, - 114,165,0,0,0,114,188,0,0,0,90,9,105,115,95,114, - 101,108,111,97,100,114,186,0,0,0,114,166,0,0,0,114, + 114,165,0,0,0,114,191,0,0,0,90,9,105,115,95,114, + 101,108,111,97,100,114,189,0,0,0,114,166,0,0,0,114, 95,0,0,0,114,96,0,0,0,114,105,0,0,0,114,10, 0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,95, 102,105,110,100,95,115,112,101,99,122,3,0,0,115,54,0, 0,0,0,2,6,1,8,2,8,3,4,1,12,5,10,1, 8,1,8,1,2,1,10,1,14,1,12,1,8,1,20,2, 22,1,8,2,18,1,10,1,2,1,10,1,14,4,14,2, - 8,1,8,2,10,2,10,2,114,192,0,0,0,99,3,0, + 8,1,8,2,10,2,10,2,114,195,0,0,0,99,3,0, 0,0,0,0,0,0,0,0,0,0,3,0,0,0,5,0, 0,0,67,0,0,0,115,108,0,0,0,116,0,124,0,116, 1,131,2,115,28,116,2,100,1,160,3,116,4,124,0,131, @@ -1432,12 +1432,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 121,32,109,111,100,117,108,101,32,110,97,109,101,78,41,7, 218,10,105,115,105,110,115,116,97,110,99,101,218,3,115,116, 114,218,9,84,121,112,101,69,114,114,111,114,114,45,0,0, - 0,114,14,0,0,0,114,182,0,0,0,114,79,0,0,0, - 169,3,114,17,0,0,0,114,183,0,0,0,114,184,0,0, + 0,114,14,0,0,0,114,185,0,0,0,114,79,0,0,0, + 169,3,114,17,0,0,0,114,186,0,0,0,114,187,0,0, 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, 218,13,95,115,97,110,105,116,121,95,99,104,101,99,107,169, 3,0,0,115,22,0,0,0,0,2,10,1,18,1,8,1, - 8,1,8,1,10,1,10,1,4,1,8,2,12,1,114,197, + 8,1,8,1,10,1,10,1,4,1,8,2,12,1,114,200, 0,0,0,122,16,78,111,32,109,111,100,117,108,101,32,110, 97,109,101,100,32,122,4,123,33,114,125,99,2,0,0,0, 0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0, @@ -1462,7 +1462,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,114,92,0,0,0,114,67,0,0,0,114,141,0,0,0, 114,106,0,0,0,218,8,95,69,82,82,95,77,83,71,114, 45,0,0,0,218,19,77,111,100,117,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,114,192,0,0,0,114,159, + 111,117,110,100,69,114,114,111,114,114,195,0,0,0,114,159, 0,0,0,114,5,0,0,0,41,8,114,17,0,0,0,218, 7,105,109,112,111,114,116,95,114,164,0,0,0,114,130,0, 0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108, @@ -1472,7 +1472,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 117,110,108,111,99,107,101,100,188,3,0,0,115,42,0,0, 0,0,1,4,1,14,1,4,1,10,1,10,2,10,1,10, 1,10,1,2,1,10,1,14,1,16,1,20,1,10,1,8, - 1,20,2,8,1,4,2,10,1,22,1,114,202,0,0,0, + 1,20,2,8,1,4,2,10,1,22,1,114,205,0,0,0, 99,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0, 0,10,0,0,0,67,0,0,0,115,106,0,0,0,116,0, 124,0,131,1,143,50,1,0,116,1,106,2,160,3,124,0, @@ -1488,14 +1488,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 101,32,105,110,32,115,121,115,46,109,111,100,117,108,101,115, 114,16,0,0,0,41,9,114,50,0,0,0,114,15,0,0, 0,114,92,0,0,0,114,34,0,0,0,218,14,95,78,69, - 69,68,83,95,76,79,65,68,73,78,71,114,202,0,0,0, - 114,45,0,0,0,114,200,0,0,0,114,65,0,0,0,41, - 4,114,17,0,0,0,114,201,0,0,0,114,96,0,0,0, + 69,68,83,95,76,79,65,68,73,78,71,114,205,0,0,0, + 114,45,0,0,0,114,203,0,0,0,114,65,0,0,0,41, + 4,114,17,0,0,0,114,204,0,0,0,114,96,0,0,0, 114,75,0,0,0,114,10,0,0,0,114,10,0,0,0,114, 11,0,0,0,218,14,95,102,105,110,100,95,97,110,100,95, 108,111,97,100,218,3,0,0,115,22,0,0,0,0,2,10, 1,14,1,8,1,32,2,8,1,4,1,2,255,4,2,12, - 2,8,1,114,204,0,0,0,114,22,0,0,0,99,3,0, + 2,8,1,114,207,0,0,0,114,22,0,0,0,99,3,0, 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, 0,0,67,0,0,0,115,42,0,0,0,116,0,124,0,124, 1,124,2,131,3,1,0,124,2,100,1,107,4,114,32,116, @@ -1520,11 +1520,11 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 103,32,95,95,112,97,99,107,97,103,101,95,95,32,105,102, 10,32,32,32,32,116,104,101,32,108,111,97,100,101,114,32, 100,105,100,32,110,111,116,46,10,10,32,32,32,32,114,22, - 0,0,0,41,4,114,197,0,0,0,114,185,0,0,0,114, - 204,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114, - 116,114,196,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,205,0,0,0,234,3,0,0,115,8, - 0,0,0,0,9,12,1,8,1,12,1,114,205,0,0,0, + 0,0,0,41,4,114,200,0,0,0,114,188,0,0,0,114, + 207,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114, + 116,114,199,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,208,0,0,0,234,3,0,0,115,8, + 0,0,0,0,9,12,1,8,1,12,1,114,208,0,0,0, 169,1,218,9,114,101,99,117,114,115,105,118,101,99,3,0, 0,0,0,0,0,0,1,0,0,0,8,0,0,0,11,0, 0,0,67,0,0,0,115,226,0,0,0,124,1,68,0,93, @@ -1561,21 +1561,21 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 109,32,108,105,115,116,39,39,122,8,73,116,101,109,32,105, 110,32,122,18,32,109,117,115,116,32,98,101,32,115,116,114, 44,32,110,111,116,32,250,1,42,218,7,95,95,97,108,108, - 95,95,84,114,206,0,0,0,114,179,0,0,0,78,41,16, - 114,193,0,0,0,114,194,0,0,0,114,1,0,0,0,114, - 195,0,0,0,114,14,0,0,0,114,4,0,0,0,218,16, + 95,95,84,114,209,0,0,0,114,182,0,0,0,78,41,16, + 114,196,0,0,0,114,197,0,0,0,114,1,0,0,0,114, + 198,0,0,0,114,14,0,0,0,114,4,0,0,0,218,16, 95,104,97,110,100,108,101,95,102,114,111,109,108,105,115,116, - 114,209,0,0,0,114,45,0,0,0,114,67,0,0,0,114, - 200,0,0,0,114,17,0,0,0,114,15,0,0,0,114,92, - 0,0,0,114,34,0,0,0,114,203,0,0,0,41,8,114, - 96,0,0,0,218,8,102,114,111,109,108,105,115,116,114,201, - 0,0,0,114,207,0,0,0,218,1,120,90,5,119,104,101, + 114,212,0,0,0,114,45,0,0,0,114,67,0,0,0,114, + 203,0,0,0,114,17,0,0,0,114,15,0,0,0,114,92, + 0,0,0,114,34,0,0,0,114,206,0,0,0,41,8,114, + 96,0,0,0,218,8,102,114,111,109,108,105,115,116,114,204, + 0,0,0,114,210,0,0,0,218,1,120,90,5,119,104,101, 114,101,90,9,102,114,111,109,95,110,97,109,101,90,3,101, 120,99,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,210,0,0,0,249,3,0,0,115,44,0,0,0,0, + 0,114,213,0,0,0,249,3,0,0,115,44,0,0,0,0, 10,8,1,10,1,4,1,12,2,4,1,28,2,8,1,14, 1,10,1,2,255,8,2,10,1,14,1,2,1,14,1,16, - 4,10,1,16,255,2,2,8,1,22,1,114,210,0,0,0, + 4,10,1,16,255,2,2,8,1,22,1,114,213,0,0,0, 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, 0,6,0,0,0,67,0,0,0,115,146,0,0,0,124,0, 160,0,100,1,161,1,125,1,124,0,160,0,100,2,161,1, @@ -1610,14 +1610,14 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 95,95,32,97,110,100,32,95,95,112,97,116,104,95,95,114, 1,0,0,0,114,141,0,0,0,114,128,0,0,0,114,22, 0,0,0,41,6,114,34,0,0,0,114,130,0,0,0,114, - 189,0,0,0,114,190,0,0,0,114,191,0,0,0,114,129, - 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,183, + 192,0,0,0,114,193,0,0,0,114,194,0,0,0,114,129, + 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,186, 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, 0,0,114,11,0,0,0,218,17,95,99,97,108,99,95,95, 95,112,97,99,107,97,103,101,95,95,30,4,0,0,115,38, 0,0,0,0,7,10,1,10,1,8,1,18,1,22,2,2, 0,2,254,6,3,4,1,8,1,6,2,6,2,2,0,2, - 254,6,3,8,1,8,1,14,1,114,216,0,0,0,114,10, + 254,6,3,8,1,8,1,14,1,114,219,0,0,0,114,10, 0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0, 9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,0, 0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125, @@ -1662,18 +1662,18 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 96,32,119,111,117,108,100,32,104,97,118,101,32,97,32,39, 108,101,118,101,108,39,32,111,102,32,50,41,46,10,10,32, 32,32,32,114,22,0,0,0,78,114,128,0,0,0,114,141, - 0,0,0,41,9,114,205,0,0,0,114,216,0,0,0,218, - 9,112,97,114,116,105,116,105,111,110,114,181,0,0,0,114, + 0,0,0,41,9,114,208,0,0,0,114,219,0,0,0,218, + 9,112,97,114,116,105,116,105,111,110,114,184,0,0,0,114, 15,0,0,0,114,92,0,0,0,114,1,0,0,0,114,4, - 0,0,0,114,210,0,0,0,41,9,114,17,0,0,0,114, - 215,0,0,0,218,6,108,111,99,97,108,115,114,211,0,0, - 0,114,184,0,0,0,114,96,0,0,0,90,8,103,108,111, - 98,97,108,115,95,114,183,0,0,0,90,7,99,117,116,95, + 0,0,0,114,213,0,0,0,41,9,114,17,0,0,0,114, + 218,0,0,0,218,6,108,111,99,97,108,115,114,214,0,0, + 0,114,187,0,0,0,114,96,0,0,0,90,8,103,108,111, + 98,97,108,115,95,114,186,0,0,0,90,7,99,117,116,95, 111,102,102,114,10,0,0,0,114,10,0,0,0,114,11,0, 0,0,218,10,95,95,105,109,112,111,114,116,95,95,57,4, 0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,8, 1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,32, - 1,10,1,12,2,114,219,0,0,0,99,1,0,0,0,0, + 1,10,1,12,2,114,222,0,0,0,99,1,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, 0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,1, 125,1,124,1,100,0,107,8,114,30,116,2,100,1,124,0, @@ -1685,7 +1685,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, 98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,109, 101,94,4,0,0,115,8,0,0,0,0,1,10,1,8,1, - 12,1,114,220,0,0,0,99,2,0,0,0,0,0,0,0, + 12,1,114,223,0,0,0,99,2,0,0,0,0,0,0,0, 0,0,0,0,10,0,0,0,5,0,0,0,67,0,0,0, 115,166,0,0,0,124,1,97,0,124,0,97,1,116,2,116, 1,131,1,125,2,116,1,106,3,160,4,161,0,68,0,93, @@ -1714,12 +1714,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 100,117,108,101,115,32,109,117,115,116,32,98,101,32,101,120, 112,108,105,99,105,116,108,121,32,112,97,115,115,101,100,32, 105,110,46,10,10,32,32,32,32,41,3,114,23,0,0,0, - 114,189,0,0,0,114,64,0,0,0,78,41,15,114,57,0, + 114,192,0,0,0,114,64,0,0,0,78,41,15,114,57,0, 0,0,114,15,0,0,0,114,14,0,0,0,114,92,0,0, - 0,218,5,105,116,101,109,115,114,193,0,0,0,114,78,0, + 0,218,5,105,116,101,109,115,114,196,0,0,0,114,78,0, 0,0,114,160,0,0,0,114,88,0,0,0,114,173,0,0, 0,114,142,0,0,0,114,148,0,0,0,114,1,0,0,0, - 114,220,0,0,0,114,5,0,0,0,41,10,218,10,115,121, + 114,223,0,0,0,114,5,0,0,0,41,10,218,10,115,121, 115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,109, 111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,121, 112,101,114,17,0,0,0,114,96,0,0,0,114,109,0,0, @@ -1730,7 +1730,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 218,6,95,115,101,116,117,112,101,4,0,0,115,36,0,0, 0,0,9,4,1,4,3,8,1,18,1,10,1,10,1,6, 1,10,1,6,2,2,1,10,1,12,3,10,1,8,1,10, - 1,10,2,10,1,114,224,0,0,0,99,2,0,0,0,0, + 1,10,2,10,1,114,227,0,0,0,99,2,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, 0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,2, 1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1, @@ -1738,12 +1738,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116, 101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32, 97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,78,41,6,114,224,0,0,0,114,15,0,0,0,114, - 188,0,0,0,114,120,0,0,0,114,160,0,0,0,114,173, - 0,0,0,41,2,114,222,0,0,0,114,223,0,0,0,114, + 101,115,78,41,6,114,227,0,0,0,114,15,0,0,0,114, + 191,0,0,0,114,120,0,0,0,114,160,0,0,0,114,173, + 0,0,0,41,2,114,225,0,0,0,114,226,0,0,0,114, 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, 95,105,110,115,116,97,108,108,136,4,0,0,115,6,0,0, - 0,0,2,10,2,12,1,114,225,0,0,0,99,0,0,0, + 0,0,2,10,2,12,1,114,228,0,0,0,99,0,0,0, 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, 0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,0, 125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,5, @@ -1754,12 +1754,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 32,97,99,99,101,115,115,114,22,0,0,0,78,41,6,218, 26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, 105,98,95,101,120,116,101,114,110,97,108,114,126,0,0,0, - 114,225,0,0,0,114,15,0,0,0,114,92,0,0,0,114, - 1,0,0,0,41,1,114,226,0,0,0,114,10,0,0,0, + 114,228,0,0,0,114,15,0,0,0,114,92,0,0,0,114, + 1,0,0,0,41,1,114,229,0,0,0,114,10,0,0,0, 114,10,0,0,0,114,11,0,0,0,218,27,95,105,110,115, 116,97,108,108,95,101,120,116,101,114,110,97,108,95,105,109, 112,111,114,116,101,114,115,144,4,0,0,115,6,0,0,0, - 0,3,8,1,4,1,114,227,0,0,0,41,2,78,78,41, + 0,3,8,1,4,1,114,230,0,0,0,41,2,78,78,41, 1,78,41,2,78,114,22,0,0,0,41,4,78,78,114,10, 0,0,0,114,22,0,0,0,41,50,114,3,0,0,0,114, 126,0,0,0,114,12,0,0,0,114,18,0,0,0,114,59, @@ -1771,13 +1771,13 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,0,114,142,0,0,0,114,148,0,0,0,114,152,0, 0,0,114,107,0,0,0,114,93,0,0,0,114,158,0,0, 0,114,159,0,0,0,114,94,0,0,0,114,160,0,0,0, - 114,173,0,0,0,114,178,0,0,0,114,185,0,0,0,114, - 187,0,0,0,114,192,0,0,0,114,197,0,0,0,90,15, + 114,173,0,0,0,114,178,0,0,0,114,188,0,0,0,114, + 190,0,0,0,114,195,0,0,0,114,200,0,0,0,90,15, 95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,114, - 199,0,0,0,114,202,0,0,0,218,6,111,98,106,101,99, - 116,114,203,0,0,0,114,204,0,0,0,114,205,0,0,0, - 114,210,0,0,0,114,216,0,0,0,114,219,0,0,0,114, - 220,0,0,0,114,224,0,0,0,114,225,0,0,0,114,227, + 202,0,0,0,114,205,0,0,0,218,6,111,98,106,101,99, + 116,114,206,0,0,0,114,207,0,0,0,114,208,0,0,0, + 114,213,0,0,0,114,219,0,0,0,114,222,0,0,0,114, + 223,0,0,0,114,227,0,0,0,114,228,0,0,0,114,230, 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, 0,0,114,11,0,0,0,218,8,60,109,111,100,117,108,101, 62,1,0,0,0,115,94,0,0,0,4,24,4,2,8,8, diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 01344db410a0f1..6dc684bfcebb84 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -587,6 +587,12 @@ pycore_init_types(void) if (!_PyContext_Init()) { return _Py_INIT_ERR("can't init context"); } + + err = _PyErr_Init(); + if (_Py_INIT_FAILED(err)) { + return err; + } + return _Py_INIT_OK(); } @@ -1462,6 +1468,12 @@ new_interpreter(PyThreadState **tstate_p) return err; } + err = _PyErr_Init(); + if (_Py_INIT_FAILED(err)) { + return err; + } + + /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); if (modules == NULL) { diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 1290164edbf68d..1735b90b33b955 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -374,6 +374,30 @@ sys_exc_info_impl(PyObject *module) } +/*[clinic input] +sys.unraisablehook + + unraisable: object + / + +Handle an unraisable exception. + +The unraisable argument has the following attributes: + +* exc_type: Exception type. +* exc_value: Exception value. +* exc_tb: Exception traceback, can be None. +* obj: Object causing the exception, can be None. +[clinic start generated code]*/ + +static PyObject * +sys_unraisablehook(PyObject *module, PyObject *unraisable) +/*[clinic end generated code: output=bb92838b32abaa14 input=fdbdb47fdd0bee06]*/ +{ + return _PyErr_WriteUnraisableDefaultHook(unraisable); +} + + /*[clinic input] sys.exit @@ -1672,6 +1696,7 @@ static PyMethodDef sys_methods[] = { METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, SYS_GET_ASYNCGEN_HOOKS_METHODDEF SYS_GETANDROIDAPILEVEL_METHODDEF + SYS_UNRAISABLEHOOK_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -2369,6 +2394,9 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, SET_SYS_FROM_STRING_BORROW( "__breakpointhook__", PyDict_GetItemString(sysdict, "breakpointhook")); + SET_SYS_FROM_STRING_BORROW("__unraisablehook__", + PyDict_GetItemString(sysdict, "unraisablehook")); + SET_SYS_FROM_STRING("version", PyUnicode_FromString(Py_GetVersion())); SET_SYS_FROM_STRING("hexversion", From b892d3ea468101d35e2fb081002fa693bd86eca9 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 22 May 2019 12:05:02 +0200 Subject: [PATCH 054/441] bpo-36994: add test for profiling method_descriptor with **kwargs (GH-13461) It adds a missing testcase for bpo-34125. This is testing code which is affected by PEP 590, so missing this test might accidentally break CPython if we screw up with implementing PEP 590. --- Lib/test/test_sys_setprofile.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index b64bcbc5b6862b..21a09b51926e68 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -334,6 +334,15 @@ def j(p): (1, 'return', j_ident), ]) + # bpo-34125: profiling method_descriptor with **kwargs + def test_unbound_method(self): + kwargs = {} + def f(p): + dict.get({}, 42, **kwargs) + f_ident = ident(f) + self.check_events(f, [(1, 'call', f_ident), + (1, 'return', f_ident)]) + # Test an invalid call (bpo-34126) def test_unbound_method_no_args(self): def f(p): From 77aa396bb9415428de09112ddf6b34bb843811eb Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 22 May 2019 13:09:35 +0200 Subject: [PATCH 055/441] bpo-36907: fix refcount bug in _PyStack_UnpackDict() (GH-13381) --- Lib/test/test_call.py | 17 +++++++++++++++++ .../2019-05-17-12-28-24.bpo-36907.rk7kgp.rst | 2 ++ Objects/call.c | 17 ++++++++++++----- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 0da0719457f55b..e4ab33cbc16b58 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -8,6 +8,7 @@ import struct import collections import itertools +import gc class FunctionCalls(unittest.TestCase): @@ -457,6 +458,22 @@ def test_fastcall_keywords(self): result = _testcapi.pyobject_fastcallkeywords(func, args, kwnames) self.check_result(result, expected) + def test_fastcall_clearing_dict(self): + # Test bpo-36907: the point of the test is just checking that this + # does not crash. + class IntWithDict: + __slots__ = ["kwargs"] + def __init__(self, **kwargs): + self.kwargs = kwargs + def __index__(self): + self.kwargs.clear() + gc.collect() + return 0 + x = IntWithDict(dont_inherit=IntWithDict()) + # We test the argument handling of "compile" here, the compilation + # itself is not relevant. When we pass flags=x below, x.__index__() is + # called, which changes the keywords dict. + compile("pass", "", "exec", x, **x.kwargs) if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst new file mode 100644 index 00000000000000..ae502e83ef6843 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst @@ -0,0 +1,2 @@ +Fix a crash when calling a C function with a keyword dict (``f(**kwargs)``) +and changing the dict ``kwargs`` while that function is running. diff --git a/Objects/call.c b/Objects/call.c index 337ca811080939..cb9ccd9c2caef4 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -544,10 +544,14 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, } result = (*fastmeth) (self, stack, nargs, kwnames); - if (stack != args) { + if (kwnames != NULL) { + Py_ssize_t i, n = nargs + PyTuple_GET_SIZE(kwnames); + for (i = 0; i < n; i++) { + Py_DECREF(stack[i]); + } PyMem_Free((PyObject **)stack); + Py_DECREF(kwnames); } - Py_XDECREF(kwnames); break; } @@ -1334,8 +1338,11 @@ _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, return -1; } - /* Copy position arguments (borrowed references) */ - memcpy(stack, args, nargs * sizeof(stack[0])); + /* Copy positional arguments */ + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + stack[i] = args[i]; + } kwstack = stack + nargs; pos = i = 0; @@ -1344,8 +1351,8 @@ _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, called in the performance critical hot code. */ while (PyDict_Next(kwargs, &pos, &key, &value)) { Py_INCREF(key); + Py_INCREF(value); PyTuple_SET_ITEM(kwnames, i, key); - /* The stack contains borrowed references */ kwstack[i] = value; i++; } From 33e71e01e95506cf8d93fd68251fc56352bc7b39 Mon Sep 17 00:00:00 2001 From: Marcel Plch Date: Wed, 22 May 2019 13:51:26 +0200 Subject: [PATCH 056/441] bpo-31862: Port binascii to PEP 489 multiphase initialization (GH-4108) --- Lib/test/test_capi.py | 13 ++ .../2017-10-24-17-26-58.bpo-31862.5Gea8L.rst | 2 + Modules/binascii.c | 137 +++++++++++++----- 3 files changed, 118 insertions(+), 34 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 8bcbd82b2d9ded..a062a6563fa2b6 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -473,6 +473,19 @@ def test_subinterps(self): self.assertNotEqual(pickle.load(f), id(sys.modules)) self.assertNotEqual(pickle.load(f), id(builtins)) + def test_mutate_exception(self): + """ + Exceptions saved in global module state get shared between + individual module instances. This test checks whether or not + a change in one interpreter's module gets reflected into the + other ones. + """ + import binascii + + support.run_in_subinterp("import binascii; binascii.Error.foobar = 'foobar'") + + self.assertFalse(hasattr(binascii.Error, "foobar")) + class TestThreadState(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst new file mode 100644 index 00000000000000..0e80cdc6924fcb --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst @@ -0,0 +1,2 @@ +Port binascii to PEP 489 multiphase initialization. +Patch by Marcel Plch. diff --git a/Modules/binascii.c b/Modules/binascii.c index 2e71ab97b05ae2..d22ab7b4683887 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -61,8 +61,10 @@ #include "zlib.h" #endif -static PyObject *Error; -static PyObject *Incomplete; +typedef struct binascii_state { + PyObject *Error; + PyObject *Incomplete; +} binascii_state; /* ** hqx lookup table, ascii->binary. @@ -263,6 +265,7 @@ binascii_a2b_uu_impl(PyObject *module, Py_buffer *data) unsigned int leftchar = 0; PyObject *rv; Py_ssize_t ascii_len, bin_len; + binascii_state *state; ascii_data = data->buf; ascii_len = data->len; @@ -294,7 +297,11 @@ binascii_a2b_uu_impl(PyObject *module, Py_buffer *data) ** '`' as zero instead of space. */ if ( this_ch < ' ' || this_ch > (' ' + 64)) { - PyErr_SetString(Error, "Illegal char"); + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Illegal char"); Py_DECREF(rv); return NULL; } @@ -322,7 +329,11 @@ binascii_a2b_uu_impl(PyObject *module, Py_buffer *data) /* Extra '`' may be written as padding in some cases */ if ( this_ch != ' ' && this_ch != ' '+64 && this_ch != '\n' && this_ch != '\r' ) { - PyErr_SetString(Error, "Trailing garbage"); + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Trailing garbage"); Py_DECREF(rv); return NULL; } @@ -350,6 +361,7 @@ binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick) int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; + binascii_state *state; Py_ssize_t bin_len, out_len; _PyBytesWriter writer; @@ -358,7 +370,11 @@ binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick) bin_len = data->len; if ( bin_len > 45 ) { /* The 45 is a limit that appears in all uuencode's */ - PyErr_SetString(Error, "At most 45 bytes at once"); + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "At most 45 bytes at once"); return NULL; } @@ -445,6 +461,7 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) Py_ssize_t ascii_len, bin_len; int quad_pos = 0; _PyBytesWriter writer; + binascii_state *state; ascii_data = data->buf; ascii_len = data->len; @@ -512,19 +529,23 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data) } if (leftbits != 0) { + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } if (leftbits == 6) { /* ** There is exactly one extra valid, non-padding, base64 character. ** This is an invalid length, as there is no possible input that ** could encoded into such a base64 string. */ - PyErr_Format(Error, + PyErr_Format(state->Error, "Invalid base64-encoded string: " "number of data characters (%zd) cannot be 1 more " "than a multiple of 4", (bin_data - bin_data_start) / 3 * 4 + 1); } else { - PyErr_SetString(Error, "Incorrect padding"); + PyErr_SetString(state->Error, "Incorrect padding"); } _PyBytesWriter_Dealloc(&writer); return NULL; @@ -556,6 +577,7 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline) unsigned int leftchar = 0; Py_ssize_t bin_len, out_len; _PyBytesWriter writer; + binascii_state *state; bin_data = data->buf; bin_len = data->len; @@ -564,7 +586,11 @@ binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline) assert(bin_len >= 0); if ( bin_len > BASE64_MAXBIN ) { - PyErr_SetString(Error, "Too much data for base64 line"); + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Too much data for base64 line"); return NULL; } @@ -626,6 +652,7 @@ binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) Py_ssize_t len; int done = 0; _PyBytesWriter writer; + binascii_state *state; ascii_data = data->buf; len = data->len; @@ -649,7 +676,11 @@ binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) if ( this_ch == SKIP ) continue; if ( this_ch == FAIL ) { - PyErr_SetString(Error, "Illegal char"); + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Illegal char"); _PyBytesWriter_Dealloc(&writer); return NULL; } @@ -670,7 +701,11 @@ binascii_a2b_hqx_impl(PyObject *module, Py_buffer *data) } if ( leftbits && !done ) { - PyErr_SetString(Incomplete, + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Incomplete, "String has incomplete number of bytes"); _PyBytesWriter_Dealloc(&writer); return NULL; @@ -822,6 +857,7 @@ binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) in_data = data->buf; in_len = data->len; _PyBytesWriter_Init(&writer); + binascii_state *state; assert(in_len >= 0); @@ -846,7 +882,11 @@ binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) #define INBYTE(b) \ do { \ if ( --in_len < 0 ) { \ - PyErr_SetString(Incomplete, ""); \ + state = PyModule_GetState(module); \ + if (state == NULL) { \ + return NULL; \ + } \ + PyErr_SetString(state->Incomplete, ""); \ goto error; \ } \ b = *in_data++; \ @@ -868,7 +908,11 @@ binascii_rledecode_hqx_impl(PyObject *module, Py_buffer *data) /* Note Error, not Incomplete (which is at the end ** of the string only). This is a programmer error. */ - PyErr_SetString(Error, "Orphaned RLE code at start"); + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Orphaned RLE code at start"); goto error; } *out_data++ = RUNCHAR; @@ -1166,6 +1210,7 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) PyObject *retval; char* retbuf; Py_ssize_t i, j; + binascii_state *state; argbuf = hexstr->buf; arglen = hexstr->len; @@ -1177,7 +1222,11 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) * raise an exception. */ if (arglen % 2) { - PyErr_SetString(Error, "Odd-length string"); + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Odd-length string"); return NULL; } @@ -1190,7 +1239,11 @@ binascii_a2b_hex_impl(PyObject *module, Py_buffer *hexstr) unsigned int top = _PyLong_DigitValue[Py_CHARMASK(argbuf[i])]; unsigned int bot = _PyLong_DigitValue[Py_CHARMASK(argbuf[i+1])]; if (top >= 16 || bot >= 16) { - PyErr_SetString(Error, + state = PyModule_GetState(module); + if (state == NULL) { + return NULL; + } + PyErr_SetString(state->Error, "Non-hexadecimal digit found"); goto finally; } @@ -1545,14 +1598,47 @@ static struct PyMethodDef binascii_module_methods[] = { /* Initialization function for the module (*must* be called PyInit_binascii) */ PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII"); +static int +binascii_exec(PyObject *m) { + int result; + binascii_state *state = PyModule_GetState(m); + if (state == NULL) { + return -1; + } + + state->Error = PyErr_NewException("binascii.Error", PyExc_ValueError, NULL); + if (state->Error == NULL) { + return -1; + } + result = PyModule_AddObject(m, "Error", state->Error); + if (result == -1) { + return -1; + } + + state->Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL); + if (state->Incomplete == NULL) { + return -1; + } + result = PyModule_AddObject(m, "Incomplete", state->Incomplete); + if (result == -1) { + return -1; + } + + return 0; +} + +static PyModuleDef_Slot binascii_slots[] = { + {Py_mod_exec, binascii_exec}, + {0, NULL} +}; static struct PyModuleDef binasciimodule = { PyModuleDef_HEAD_INIT, "binascii", doc_binascii, - -1, + sizeof(binascii_state), binascii_module_methods, - NULL, + binascii_slots, NULL, NULL, NULL @@ -1561,22 +1647,5 @@ static struct PyModuleDef binasciimodule = { PyMODINIT_FUNC PyInit_binascii(void) { - PyObject *m, *d; - - /* Create the module and add the functions */ - m = PyModule_Create(&binasciimodule); - if (m == NULL) - return NULL; - - d = PyModule_GetDict(m); - - Error = PyErr_NewException("binascii.Error", PyExc_ValueError, NULL); - PyDict_SetItemString(d, "Error", Error); - Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL); - PyDict_SetItemString(d, "Incomplete", Incomplete); - if (PyErr_Occurred()) { - Py_DECREF(m); - m = NULL; - } - return m; + return PyModuleDef_Init(&binasciimodule); } From 4c7a46eb3c009c85ddf2eb315d94d804745187d4 Mon Sep 17 00:00:00 2001 From: Paul Dagnelie Date: Wed, 22 May 2019 07:23:01 -0700 Subject: [PATCH 057/441] bpo-36972: Add SupportsIndex (GH-13448) In order to support typing checks calling hex(), oct() and bin() on user-defined classes, a SupportIndex protocol is required. The ability to check these at runtime would be good to add for completeness sake. This is pretty much just a copy of SupportsInt with the names tweaked. --- Doc/library/typing.rst | 6 ++++++ Lib/test/test_typing.py | 4 ++++ Lib/typing.py | 9 +++++++++ Misc/ACKS | 1 + .../Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst | 1 + 5 files changed, 21 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index c2523ed5296003..86a3db8467ec74 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -529,6 +529,12 @@ The module defines the following classes, functions and decorators: An ABC with one abstract method ``__bytes__``. +.. class:: SupportsIndex + + An ABC with one abstract method ``__index__``. + + .. versionadded:: 3.8 + .. class:: SupportsAbs An ABC with one abstract method ``__abs__`` that is covariant diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index a547fe274c8780..c9bfd0c7ed720d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -568,6 +568,10 @@ def test_reversible(self): self.assertIsSubclass(list, typing.Reversible) self.assertNotIsSubclass(int, typing.Reversible) + def test_supports_index(self): + self.assertIsSubclass(int, typing.SupportsIndex) + self.assertNotIsSubclass(str, typing.SupportsIndex) + def test_protocol_instance_type_error(self): with self.assertRaises(TypeError): isinstance(0, typing.SupportsAbs) diff --git a/Lib/typing.py b/Lib/typing.py index 530d4633fe4c22..7aab1628a3192b 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -74,6 +74,7 @@ 'SupportsBytes', 'SupportsComplex', 'SupportsFloat', + 'SupportsIndex', 'SupportsInt', 'SupportsRound', @@ -1304,6 +1305,14 @@ def __bytes__(self) -> bytes: pass +class SupportsIndex(_Protocol): + __slots__ = () + + @abstractmethod + def __index__(self) -> int: + pass + + class SupportsAbs(_Protocol[T_co]): __slots__ = () diff --git a/Misc/ACKS b/Misc/ACKS index 6b1fdbc37fa934..8f0ecb7f1c3758 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -355,6 +355,7 @@ Tom Culliton Raúl Cumplido Antonio Cuni Brian Curtin +Paul Dagnelie Lisandro Dalcin Darren Dale Andrew Dalke diff --git a/Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst b/Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst new file mode 100644 index 00000000000000..da650e8944dfc7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst @@ -0,0 +1 @@ +Add SupportsIndex protocol to the typing module to allow type checking to detect classes that can be passed to `hex()`, `oct()` and `bin()`. From 933e1509ec6efa8e6ab8c8c7ce02059ce2b6d9b9 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Wed, 22 May 2019 07:54:20 -0700 Subject: [PATCH 058/441] bpo-36878: Track extra text added to 'type: ignore' in the AST (GH-13479) GH-13238 made extra text after a # type: ignore accepted by the parser. This finishes the job and actually plumbs the extra text through the parser and makes it available in the AST. --- Include/Python-ast.h | 5 ++- Lib/test/test_type_comments.py | 11 ++++- Misc/ACKS | 1 + .../2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst | 3 ++ Parser/Python.asdl | 3 +- Parser/parsetok.c | 43 ++++++++++++------- Parser/tokenizer.c | 8 +++- Python/Python-ast.c | 33 ++++++++++++-- Python/ast.c | 5 ++- 9 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 08d50ffcddf609..2fc50e3f53a21f 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -467,6 +467,7 @@ struct _type_ignore { union { struct { int lineno; + string tag; } TypeIgnore; } v; @@ -702,8 +703,8 @@ alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); #define withitem(a0, a1, a2) _Py_withitem(a0, a1, a2) withitem_ty _Py_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena); -#define TypeIgnore(a0, a1) _Py_TypeIgnore(a0, a1) -type_ignore_ty _Py_TypeIgnore(int lineno, PyArena *arena); +#define TypeIgnore(a0, a1, a2) _Py_TypeIgnore(a0, a1, a2) +type_ignore_ty _Py_TypeIgnore(int lineno, string tag, PyArena *arena); PyObject* PyAST_mod2obj(mod_ty t); mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index b4318902ee344e..c62894fa4255d6 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -272,7 +272,16 @@ def test_vardecl(self): def test_ignores(self): for tree in self.parse_all(ignores): - self.assertEqual([ti.lineno for ti in tree.type_ignores], [2, 5, 8, 9, 10, 11]) + self.assertEqual( + [(ti.lineno, ti.tag) for ti in tree.type_ignores], + [ + (2, ''), + (5, ''), + (8, '[excuse]'), + (9, '=excuse'), + (10, ' [excuse]'), + (11, ' whatever'), + ]) tree = self.classic_parse(ignores) self.assertEqual(tree.type_ignores, []) diff --git a/Misc/ACKS b/Misc/ACKS index 8f0ecb7f1c3758..fbed14684b3134 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1594,6 +1594,7 @@ Daniel Stutzbach Andreas Stührk Colin Su Pal Subbiah +Michael J. Sullivan Nathan Sullivan Mark Summerfield Reuben Sumner diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst new file mode 100644 index 00000000000000..00c8b904ac2a41 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst @@ -0,0 +1,3 @@ +Store text appearing after a `# type: ignore` comment in the AST. For +example a type ignore like `# type: ignore[E1000]` will have the string +`"[E1000]"` stored in its AST node. diff --git a/Parser/Python.asdl b/Parser/Python.asdl index 626fa4fede476b..882f5d1eba35bf 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -125,6 +125,5 @@ module Python withitem = (expr context_expr, expr? optional_vars) - type_ignore = TypeIgnore(int lineno) + type_ignore = TypeIgnore(int lineno, string tag) } - diff --git a/Parser/parsetok.c b/Parser/parsetok.c index 31be0ebbde2d27..55fd7f7db3da81 100644 --- a/Parser/parsetok.c +++ b/Parser/parsetok.c @@ -16,13 +16,16 @@ static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *); static int initerr(perrdetail *err_ret, PyObject * filename); typedef struct { - int *items; + struct { + int lineno; + char *comment; + } *items; size_t size; size_t num_items; -} growable_int_array; +} growable_comment_array; static int -growable_int_array_init(growable_int_array *arr, size_t initial_size) { +growable_comment_array_init(growable_comment_array *arr, size_t initial_size) { assert(initial_size > 0); arr->items = malloc(initial_size * sizeof(*arr->items)); arr->size = initial_size; @@ -32,7 +35,7 @@ growable_int_array_init(growable_int_array *arr, size_t initial_size) { } static int -growable_int_array_add(growable_int_array *arr, int item) { +growable_comment_array_add(growable_comment_array *arr, int lineno, char *comment) { if (arr->num_items >= arr->size) { arr->size *= 2; arr->items = realloc(arr->items, arr->size * sizeof(*arr->items)); @@ -41,13 +44,17 @@ growable_int_array_add(growable_int_array *arr, int item) { } } - arr->items[arr->num_items] = item; + arr->items[arr->num_items].lineno = lineno; + arr->items[arr->num_items].comment = comment; arr->num_items++; return 1; } static void -growable_int_array_deallocate(growable_int_array *arr) { +growable_comment_array_deallocate(growable_comment_array *arr) { + for (unsigned i = 0; i < arr->num_items; i++) { + PyObject_FREE(arr->items[i].comment); + } free(arr->items); } @@ -220,9 +227,9 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, node *n; int started = 0; int col_offset, end_col_offset; - growable_int_array type_ignores; + growable_comment_array type_ignores; - if (!growable_int_array_init(&type_ignores, 10)) { + if (!growable_comment_array_init(&type_ignores, 10)) { err_ret->error = E_NOMEM; PyTokenizer_Free(tok); return NULL; @@ -320,8 +327,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, } if (type == TYPE_IGNORE) { - PyObject_FREE(str); - if (!growable_int_array_add(&type_ignores, tok->lineno)) { + if (!growable_comment_array_add(&type_ignores, tok->lineno, str)) { err_ret->error = E_NOMEM; break; } @@ -355,9 +361,16 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, REQ(ch, ENDMARKER); for (i = 0; i < type_ignores.num_items; i++) { - PyNode_AddChild(ch, TYPE_IGNORE, NULL, - type_ignores.items[i], 0, - type_ignores.items[i], 0); + int res = PyNode_AddChild(ch, TYPE_IGNORE, type_ignores.items[i].comment, + type_ignores.items[i].lineno, 0, + type_ignores.items[i].lineno, 0); + if (res != 0) { + err_ret->error = res; + PyNode_Free(n); + n = NULL; + break; + } + type_ignores.items[i].comment = NULL; } } @@ -365,7 +378,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, is a single statement by looking at what is left in the buffer after parsing. Trailing whitespace and comments are OK. */ - if (start == single_input) { + if (err_ret->error == E_DONE && start == single_input) { char *cur = tok->cur; char c = *tok->cur; @@ -392,7 +405,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, else n = NULL; - growable_int_array_deallocate(&type_ignores); + growable_comment_array_deallocate(&type_ignores); #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD *flags = ps->p_flags; diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index e52d498d5542d5..9b269afc429bc1 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1269,6 +1269,7 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) /* This is a type comment if we matched all of type_comment_prefix. */ if (!*prefix) { int is_type_ignore = 1; + const char *ignore_end = p + 6; tok_backup(tok, c); /* don't eat the newline or EOF */ type_start = p; @@ -1276,10 +1277,13 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) /* A TYPE_IGNORE is "type: ignore" followed by the end of the token * or anything non-alphanumeric. */ is_type_ignore = ( - tok->cur >= p + 6 && memcmp(p, "ignore", 6) == 0 - && !(tok->cur > p + 6 && isalnum(p[6]))); + tok->cur >= ignore_end && memcmp(p, "ignore", 6) == 0 + && !(tok->cur > ignore_end && isalnum(p[6]))); if (is_type_ignore) { + *p_start = (char *) ignore_end; + *p_end = tok->cur; + /* If this type ignore is the only thing on the line, consume the newline also. */ if (blankline) { tok_nextc(tok); diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 552750584480b7..e84a7586a70723 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -524,8 +524,10 @@ static char *withitem_fields[]={ static PyTypeObject *type_ignore_type; static PyObject* ast2obj_type_ignore(void*); static PyTypeObject *TypeIgnore_type; +_Py_IDENTIFIER(tag); static char *TypeIgnore_fields[]={ "lineno", + "tag", }; @@ -1164,7 +1166,7 @@ static int init_types(void) if (!type_ignore_type) return 0; if (!add_attributes(type_ignore_type, NULL, 0)) return 0; TypeIgnore_type = make_type("TypeIgnore", type_ignore_type, - TypeIgnore_fields, 1); + TypeIgnore_fields, 2); if (!TypeIgnore_type) return 0; initialized = 1; return 1; @@ -2667,14 +2669,20 @@ withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) } type_ignore_ty -TypeIgnore(int lineno, PyArena *arena) +TypeIgnore(int lineno, string tag, PyArena *arena) { type_ignore_ty p; + if (!tag) { + PyErr_SetString(PyExc_ValueError, + "field tag is required for TypeIgnore"); + return NULL; + } p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = TypeIgnore_kind; p->v.TypeIgnore.lineno = lineno; + p->v.TypeIgnore.tag = tag; return p; } @@ -4158,6 +4166,11 @@ ast2obj_type_ignore(void* _o) if (_PyObject_SetAttrId(result, &PyId_lineno, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_string(o->v.TypeIgnore.tag); + if (!value) goto failed; + if (_PyObject_SetAttrId(result, &PyId_tag, value) == -1) + goto failed; + Py_DECREF(value); break; } return result; @@ -8738,6 +8751,7 @@ obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* arena) } if (isinstance) { int lineno; + string tag; if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) { return 1; @@ -8752,7 +8766,20 @@ obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = TypeIgnore(lineno, arena); + if (_PyObject_LookupAttrId(obj, &PyId_tag, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"tag\" missing from TypeIgnore"); + return 1; + } + else { + int res; + res = obj2ast_string(tmp, &tag, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = TypeIgnore(lineno, tag, arena); if (*out == NULL) goto failed; return 0; } diff --git a/Python/ast.c b/Python/ast.c index abc8d89c8a381c..625982735775b8 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -830,7 +830,10 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags, goto out; for (i = 0; i < num; i++) { - type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), arena); + string type_comment = new_type_comment(STR(CHILD(ch, i)), &c); + if (!type_comment) + goto out; + type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), type_comment, arena); if (!ti) goto out; asdl_seq_SET(type_ignores, i, ti); From b3be4072888a4ce054993c2801802721466ea02d Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 22 May 2019 08:18:26 -0700 Subject: [PATCH 059/441] bpo-33482: fix codecs.StreamRecoder.writelines (GH-6779) A very simple fix. I found this while writing typeshed stubs for StreamRecoder. https://bugs.python.org/issue33482 --- Lib/codecs.py | 2 +- Lib/test/test_codecs.py | 21 +++++++++++++++++++ .../2018-05-13-10-36-37.bpo-33482.jalAaQ.rst | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst diff --git a/Lib/codecs.py b/Lib/codecs.py index 6b028adb1d28e6..884be0b2c02e43 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -838,7 +838,7 @@ def write(self, data): def writelines(self, list): - data = ''.join(list) + data = b''.join(list) data, bytesdecoded = self.decode(data, self.errors) return self.writer.write(data) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 8c14f5981d0bce..f665febfc90a21 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -3146,6 +3146,27 @@ def test_decode(self): self.assertEqual(data.decode('latin1'), expected) +class StreamRecoderTest(unittest.TestCase): + def test_writelines(self): + bio = io.BytesIO() + codec = codecs.lookup('ascii') + sr = codecs.StreamRecoder(bio, codec.encode, codec.decode, + encodings.ascii.StreamReader, encodings.ascii.StreamWriter) + sr.writelines([b'a', b'b']) + self.assertEqual(bio.getvalue(), b'ab') + + def test_write(self): + bio = io.BytesIO() + codec = codecs.lookup('latin1') + # Recode from Latin-1 to utf-8. + sr = codecs.StreamRecoder(bio, codec.encode, codec.decode, + encodings.utf_8.StreamReader, encodings.utf_8.StreamWriter) + + text = 'àñé' + sr.write(text.encode('latin1')) + self.assertEqual(bio.getvalue(), text.encode('utf-8')) + + @unittest.skipIf(_testcapi is None, 'need _testcapi module') class LocaleCodecTest(unittest.TestCase): """ diff --git a/Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst b/Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst new file mode 100644 index 00000000000000..bda5be87723d45 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst @@ -0,0 +1 @@ +Make `codecs.StreamRecoder.writelines` take a list of bytes. From b121f63155d8e3c7c42ab6122e36eaf7f5e9f7f5 Mon Sep 17 00:00:00 2001 From: Jake Tesler Date: Wed, 22 May 2019 08:43:17 -0700 Subject: [PATCH 060/441] bpo-36084: Add native thread ID (TID) to threading.Thread (GH-13463) Add native thread ID (TID) to threading.Thread objects (supported platforms: Windows, FreeBSD, Linux, macOS). --- Doc/library/_thread.rst | 12 +++++++ Doc/library/threading.rst | 32 +++++++++++++++++++ Include/pythread.h | 5 +++ Lib/test/test_threading.py | 5 +++ Lib/threading.py | 30 +++++++++++++++++ .../2019-02-22-23-03-20.bpo-36084.86Eh4X.rst | 1 + Modules/_threadmodule.c | 20 ++++++++++++ Python/thread_nt.h | 23 +++++++++++++ Python/thread_pthread.h | 26 +++++++++++++++ 9 files changed, 154 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index acffabf24bad5f..d7814f218b502f 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -85,6 +85,18 @@ This module defines the following constants and functions: may be recycled when a thread exits and another thread is created. +.. function:: get_native_id() + + Return the native integral Thread ID of the current thread assigned by the kernel. + This is a non-negative integer. + Its value may be used to uniquely identify this particular thread system-wide + (until the thread terminates, after which the value may be recycled by the OS). + + .. availability:: Windows, FreeBSD, Linux, macOS. + + .. versionadded:: 3.8 + + .. function:: stack_size([size]) Return the thread stack size used when creating new threads. The optional diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 22342803e5e6d6..1df512f1d63265 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -49,6 +49,18 @@ This module defines the following functions: .. versionadded:: 3.3 +.. function:: get_native_id() + + Return the native integral Thread ID of the current thread assigned by the kernel. + This is a non-negative integer. + Its value may be used to uniquely identify this particular thread system-wide + (until the thread terminates, after which the value may be recycled by the OS). + + .. availability:: Windows, FreeBSD, Linux, macOS. + + .. versionadded:: 3.8 + + .. function:: enumerate() Return a list of all :class:`Thread` objects currently alive. The list @@ -297,6 +309,26 @@ since it is impossible to detect the termination of alien threads. another thread is created. The identifier is available even after the thread has exited. + .. attribute:: native_id + + The native integral thread ID of this thread. + This is a non-negative integer, or ``None`` if the thread has not + been started. See the :func:`get_native_id` function. + This represents the Thread ID (``TID``) as assigned to the + thread by the OS (kernel). Its value may be used to uniquely identify + this particular thread system-wide (until the thread terminates, + after which the value may be recycled by the OS). + + .. note:: + + Similar to Process IDs, Thread IDs are only valid (guaranteed unique + system-wide) from the time the thread is created until the thread + has been terminated. + + .. availability:: Windows, FreeBSD, Linux, macOS. + + .. versionadded:: 3.8 + .. method:: is_alive() Return whether the thread is alive. diff --git a/Include/pythread.h b/Include/pythread.h index bc1d92cd1ff199..40f12d257c14ab 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -26,6 +26,11 @@ PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); +#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(_WIN32) +#define PY_HAVE_THREAD_NATIVE_ID +PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); +#endif + PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 2ddc77b266b542..33a25f3b9d235d 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -104,6 +104,11 @@ def test_various_ops(self): self.assertRegex(repr(t), r'^$') t.start() + if hasattr(threading, 'get_native_id'): + native_ids = set(t.native_id for t in threads) | {threading.get_native_id()} + self.assertNotIn(None, native_ids) + self.assertEqual(len(native_ids), NUMTASKS + 1) + if verbose: print('waiting for all tasks to complete') for t in threads: diff --git a/Lib/threading.py b/Lib/threading.py index 0ebbd6776ef40f..77a2baec2accb5 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -34,6 +34,12 @@ _allocate_lock = _thread.allocate_lock _set_sentinel = _thread._set_sentinel get_ident = _thread.get_ident +try: + get_native_id = _thread.get_native_id + _HAVE_THREAD_NATIVE_ID = True + __all__.append('get_native_id') +except AttributeError: + _HAVE_THREAD_NATIVE_ID = False ThreadError = _thread.error try: _CRLock = _thread.RLock @@ -790,6 +796,8 @@ class is implemented. else: self._daemonic = current_thread().daemon self._ident = None + if _HAVE_THREAD_NATIVE_ID: + self._native_id = None self._tstate_lock = None self._started = Event() self._is_stopped = False @@ -891,6 +899,10 @@ def _bootstrap(self): def _set_ident(self): self._ident = get_ident() + if _HAVE_THREAD_NATIVE_ID: + def _set_native_id(self): + self._native_id = get_native_id() + def _set_tstate_lock(self): """ Set a lock object which will be released by the interpreter when @@ -903,6 +915,8 @@ def _bootstrap_inner(self): try: self._set_ident() self._set_tstate_lock() + if _HAVE_THREAD_NATIVE_ID: + self._set_native_id() self._started.set() with _active_limbo_lock: _active[self._ident] = self @@ -1077,6 +1091,18 @@ def ident(self): assert self._initialized, "Thread.__init__() not called" return self._ident + if _HAVE_THREAD_NATIVE_ID: + @property + def native_id(self): + """Native integral thread ID of this thread, or None if it has not been started. + + This is a non-negative integer. See the get_native_id() function. + This represents the Thread ID as reported by the kernel. + + """ + assert self._initialized, "Thread.__init__() not called" + return self._native_id + def is_alive(self): """Return whether the thread is alive. @@ -1176,6 +1202,8 @@ def __init__(self): self._set_tstate_lock() self._started.set() self._set_ident() + if _HAVE_THREAD_NATIVE_ID: + self._set_native_id() with _active_limbo_lock: _active[self._ident] = self @@ -1195,6 +1223,8 @@ def __init__(self): self._started.set() self._set_ident() + if _HAVE_THREAD_NATIVE_ID: + self._set_native_id() with _active_limbo_lock: _active[self._ident] = self diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst new file mode 100644 index 00000000000000..fb28a6fec77a5d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst @@ -0,0 +1 @@ +Add native thread ID (TID) to threading.Thread objects (supported platforms: Windows, FreeBSD, Linux, macOS) \ No newline at end of file diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 3c02d8dd514571..fee25abe283a8d 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1159,6 +1159,22 @@ allocated consecutive numbers starting at 1, this behavior should not\n\ be relied upon, and the number should be seen purely as a magic cookie.\n\ A thread's identity may be reused for another thread after it exits."); +#ifdef PY_HAVE_THREAD_NATIVE_ID +static PyObject * +thread_get_native_id(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + unsigned long native_id = PyThread_get_thread_native_id(); + return PyLong_FromUnsignedLong(native_id); +} + +PyDoc_STRVAR(get_native_id_doc, +"get_native_id() -> integer\n\ +\n\ +Return a non-negative integer identifying the thread as reported\n\ +by the OS (kernel). This may be used to uniquely identify a\n\ +particular thread within a system."); +#endif + static PyObject * thread__count(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1310,6 +1326,10 @@ static PyMethodDef thread_methods[] = { METH_NOARGS, interrupt_doc}, {"get_ident", thread_get_ident, METH_NOARGS, get_ident_doc}, +#ifdef PY_HAVE_THREAD_NATIVE_ID + {"get_native_id", thread_get_native_id, + METH_NOARGS, get_native_id_doc}, +#endif {"_count", thread__count, METH_NOARGS, _count_doc}, {"stack_size", (PyCFunction)thread_stack_size, diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 5e00c351146055..a5246dd0504dbb 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -143,6 +143,10 @@ LeaveNonRecursiveMutex(PNRMUTEX mutex) unsigned long PyThread_get_thread_ident(void); +#ifdef PY_HAVE_THREAD_NATIVE_ID +unsigned long PyThread_get_thread_native_id(void); +#endif + /* * Initialization of the C package, should not be needed. */ @@ -227,6 +231,25 @@ PyThread_get_thread_ident(void) return GetCurrentThreadId(); } +#ifdef PY_HAVE_THREAD_NATIVE_ID +/* + * Return the native Thread ID (TID) of the calling thread. + * The native ID of a thread is valid and guaranteed to be unique system-wide + * from the time the thread is created until the thread has been terminated. + */ +unsigned long +PyThread_get_thread_native_id(void) +{ + if (!initialized) { + PyThread_init_thread(); + } + + DWORD native_id; + native_id = GetCurrentThreadId(); + return (unsigned long) native_id; +} +#endif + void _Py_NO_RETURN PyThread_exit_thread(void) { diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 4c106d9959c10b..f57a1e7bb78baf 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -12,6 +12,12 @@ #endif #include +#if defined(__linux__) +# include /* syscall(SYS_gettid) */ +#elif defined(__FreeBSD__) +# include /* pthread_getthreadid_np() */ +#endif + /* The POSIX spec requires that use of pthread_attr_setstacksize be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */ #ifdef _POSIX_THREAD_ATTR_STACKSIZE @@ -302,6 +308,26 @@ PyThread_get_thread_ident(void) return (unsigned long) threadid; } +#ifdef PY_HAVE_THREAD_NATIVE_ID +unsigned long +PyThread_get_thread_native_id(void) +{ + if (!initialized) + PyThread_init_thread(); +#ifdef __APPLE__ + uint64_t native_id; + (void) pthread_threadid_np(NULL, &native_id); +#elif defined(__linux__) + pid_t native_id; + native_id = syscall(SYS_gettid); +#elif defined(__FreeBSD__) + int native_id; + native_id = pthread_getthreadid_np(); +#endif + return (unsigned long) native_id; +} +#endif + void _Py_NO_RETURN PyThread_exit_thread(void) { From 2ddbd21aec7f0e2f237a1073d3e0b313e673413f Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Wed, 22 May 2019 12:07:45 -0700 Subject: [PATCH 061/441] bpo-34616: Document top level async in whatsnew/3.8. (GH-13484) https://bugs.python.org/issue34616 --- Doc/whatsnew/3.8.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 63b8200a1528f0..68843e2d9ed157 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -237,6 +237,16 @@ asyncio On Windows, the default event loop is now :class:`~asyncio.ProactorEventLoop`. +builtins +-------- + +The :func:`compile` built-in has been improved to accept the +``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag. With this new flag passed, +:func:`compile` will allow top-level ``await``, ``async for`` and ``async with`` +constructs that are usually considered invalid syntax. Asynchronous code object +marked with the ``CO_COROUTINE`` flag may then be returned. + +(Contributed by Matthias Bussonnier in :issue:`34616`) collections ----------- From 0c2b6a3943aa7b022e8eb4bfd9bffcddebf9a587 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 22 May 2019 22:15:01 +0200 Subject: [PATCH 062/441] bpo-35907, CVE-2019-9948: urllib rejects local_file:// scheme (GH-13474) CVE-2019-9948: Avoid file reading as disallowing the unnecessary URL scheme in URLopener().open() and URLopener().retrieve() of urllib.request. Co-Authored-By: SH --- Lib/test/test_urllib.py | 13 +++++++++++++ Lib/urllib/request.py | 2 +- .../2019-05-21-23-20-18.bpo-35907.NC_zNK.rst | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 6b995fef8cb561..f9b2799d25bfd0 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1481,6 +1481,19 @@ def test_urlopener_retrieve_remote(self): filename, _ = urllib.request.URLopener().retrieve(url) self.assertEqual(os.path.splitext(filename)[1], ".txt") + @support.ignore_warnings(category=DeprecationWarning) + def test_local_file_open(self): + # bpo-35907, CVE-2019-9948: urllib must reject local_file:// scheme + class DummyURLopener(urllib.request.URLopener): + def open_local_file(self, url): + return url + for url in ('local_file://example', 'local-file://example'): + self.assertRaises(OSError, urllib.request.urlopen, url) + self.assertRaises(OSError, urllib.request.URLopener().open, url) + self.assertRaises(OSError, urllib.request.URLopener().retrieve, url) + self.assertRaises(OSError, DummyURLopener().open, url) + self.assertRaises(OSError, DummyURLopener().retrieve, url) + # Just commented them out. # Can't really tell why keep failing in windows and sparc. diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 230ac390abb332..9b21afb74e6e27 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1745,7 +1745,7 @@ def open(self, fullurl, data=None): name = 'open_' + urltype self.type = urltype name = name.replace('-', '_') - if not hasattr(self, name): + if not hasattr(self, name) or name == 'open_local_file': if proxy: return self.open_unknown_proxy(proxy, fullurl, data) else: diff --git a/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst b/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst new file mode 100644 index 00000000000000..42aca0bbd1b7f1 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst @@ -0,0 +1,2 @@ +CVE-2019-9948: Avoid file reading as disallowing the unnecessary URL scheme in +``URLopener().open()`` ``URLopener().retrieve()`` of :mod:`urllib.request`. From d8a82e2897b735e2b7e9e086f1d709365a2ad72c Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Wed, 22 May 2019 13:43:37 -0700 Subject: [PATCH 063/441] bpo-36878: Only allow text after `# type: ignore` if first character ASCII (GH-13504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This disallows things like `# type: ignoreé`, which seems wrong. Also switch to using Py_ISALNUM for the alnum check, for consistency with other code (and maybe correctness re: locale issues?). https://bugs.python.org/issue36878 --- Lib/test/test_type_comments.py | 1 + .../2019-05-22-11-16-16.bpo-36878.QwLa3P.rst | 2 ++ Parser/tokenizer.c | 5 +++-- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index c62894fa4255d6..83d8717247aab0 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -334,6 +334,7 @@ def check_both_ways(source): check_both_ways("try: # type: int\n pass\nfinally:\n pass\n") check_both_ways("try:\n pass\nfinally: # type: int\n pass\n") check_both_ways("pass # type: ignorewhatever\n") + check_both_ways("pass # type: ignoreé\n") def test_func_type_input(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst new file mode 100644 index 00000000000000..2d9f014119db8d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst @@ -0,0 +1,2 @@ +Only accept text after `# type: ignore` if the first character is ASCII. +This is to disallow things like `# type: ignoreé`. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 9b269afc429bc1..c2ec659fed888f 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -1275,10 +1275,11 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) type_start = p; /* A TYPE_IGNORE is "type: ignore" followed by the end of the token - * or anything non-alphanumeric. */ + * or anything ASCII and non-alphanumeric. */ is_type_ignore = ( tok->cur >= ignore_end && memcmp(p, "ignore", 6) == 0 - && !(tok->cur > ignore_end && isalnum(p[6]))); + && !(tok->cur > ignore_end + && ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0])))); if (is_type_ignore) { *p_start = (char *) ignore_end; From 2a3a2ece502c05ea33c95dd0db497189e0354bfd Mon Sep 17 00:00:00 2001 From: Sam Martin Date: Wed, 22 May 2019 22:29:02 +0100 Subject: [PATCH 064/441] bpo-33110: Catch errors raised when running add_done_callback on already completed futures (GH-13141) Wrap the callback call within the `add_done_callback` function within concurrent.futures, in order to behave in an identical manner to callbacks added to a running future are triggered once it has completed. --- Lib/concurrent/futures/_base.py | 5 ++++- Lib/test/test_concurrent_futures.py | 16 ++++++++++++++++ .../2019-05-06-22-34-47.bpo-33110.rSJSCh.rst | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index 8f155f0ea82bdc..6001e3bdb81bb3 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -404,7 +404,10 @@ def add_done_callback(self, fn): if self._state not in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]: self._done_callbacks.append(fn) return - fn(self) + try: + fn(self) + except Exception: + LOGGER.exception('exception calling callback for %r', self) def result(self, timeout=None): """Return the result of the call that the future represents. diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 3c963dff1db2c9..212ccd8d5320a7 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -1087,6 +1087,22 @@ def fn(callback_future): f.add_done_callback(fn) self.assertTrue(was_cancelled) + def test_done_callback_raises_already_succeeded(self): + with test.support.captured_stderr() as stderr: + def raising_fn(callback_future): + raise Exception('doh!') + + f = Future() + + # Set the result first to simulate a future that runs instantly, + # effectively allowing the callback to be run immediately. + f.set_result(5) + f.add_done_callback(raising_fn) + + self.assertIn('exception calling callback for', stderr.getvalue()) + self.assertIn('doh!', stderr.getvalue()) + + def test_repr(self): self.assertRegex(repr(PENDING_FUTURE), '') diff --git a/Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst b/Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst new file mode 100644 index 00000000000000..f1e2460c4927c8 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst @@ -0,0 +1 @@ +Handle exceptions raised by functions added by concurrent.futures add_done_callback correctly when the Future has already completed. From 904e34d4e6b6007986dcc585d5c553ee8ae06f95 Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 22 May 2019 14:29:58 -0700 Subject: [PATCH 065/441] bpo-24882: Let ThreadPoolExecutor reuse idle threads before creating new thread (#6375) * Fixes issue 24882 * Add news file entry for change. * Change test_concurrent_futures.ThreadPoolShutdownTest Adjust the shutdown test so that, after submitting three jobs to the executor, the test checks for less than three threads, instead of looking for exactly three threads. If idle threads are being recycled properly, then we should have less than three threads. * Switched idle count to semaphor, Updated tests As suggested by reviewer tomMoral, swapped lock-protected counter with a semaphore to track the number of unused threads. Adjusted test_threads_terminate to wait for completiton of the previous future before submitting a new one (and checking the number of threads used). Also added a new test to confirm the thread pool can be saturated. * Updates tests as requested by pitrou. * Correct minor whitespace error. * Make test_saturation faster --- Lib/concurrent/futures/thread.py | 15 +++++++-- Lib/test/test_concurrent_futures.py | 32 +++++++++++++++++-- .../2018-04-04-14-54-30.bpo-24882.urybpa.rst | 1 + 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 2af31a106dd914..ad6b4c20b56681 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -80,7 +80,14 @@ def _worker(executor_reference, work_queue, initializer, initargs): work_item.run() # Delete references to object. See issue16284 del work_item + + # attempt to increment idle count + executor = executor_reference() + if executor is not None: + executor._idle_semaphore.release() + del executor continue + executor = executor_reference() # Exit if: # - The interpreter is shutting down OR @@ -133,6 +140,7 @@ def __init__(self, max_workers=None, thread_name_prefix='', self._max_workers = max_workers self._work_queue = queue.SimpleQueue() + self._idle_semaphore = threading.Semaphore(0) self._threads = set() self._broken = False self._shutdown = False @@ -178,12 +186,15 @@ def submit(*args, **kwargs): submit.__doc__ = _base.Executor.submit.__doc__ def _adjust_thread_count(self): + # if idle threads are available, don't spin new threads + if self._idle_semaphore.acquire(timeout=0): + return + # When the executor gets lost, the weakref callback will wake up # the worker threads. def weakref_cb(_, q=self._work_queue): q.put(None) - # TODO(bquinlan): Should avoid creating new threads if there are more - # idle threads than items in the work queue. + num_threads = len(self._threads) if num_threads < self._max_workers: thread_name = '%s_%d' % (self._thread_name_prefix or self, diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 212ccd8d5320a7..de6ad8f2aa1202 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -346,10 +346,15 @@ def _prime_executor(self): pass def test_threads_terminate(self): - self.executor.submit(mul, 21, 2) - self.executor.submit(mul, 6, 7) - self.executor.submit(mul, 3, 14) + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(3): + self.executor.submit(acquire_lock, sem) self.assertEqual(len(self.executor._threads), 3) + for i in range(3): + sem.release() self.executor.shutdown() for t in self.executor._threads: t.join() @@ -753,6 +758,27 @@ def test_default_workers(self): self.assertEqual(executor._max_workers, (os.cpu_count() or 1) * 5) + def test_saturation(self): + executor = self.executor_type(4) + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(15 * executor._max_workers): + executor.submit(acquire_lock, sem) + self.assertEqual(len(executor._threads), executor._max_workers) + for i in range(15 * executor._max_workers): + sem.release() + executor.shutdown(wait=True) + + def test_idle_thread_reuse(self): + executor = self.executor_type() + executor.submit(mul, 21, 2).result() + executor.submit(mul, 6, 7).result() + executor.submit(mul, 3, 14).result() + self.assertEqual(len(executor._threads), 1) + executor.shutdown(wait=True) + class ProcessPoolExecutorTest(ExecutorTest): diff --git a/Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst b/Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst new file mode 100644 index 00000000000000..8c418824a99d96 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst @@ -0,0 +1 @@ +Change ThreadPoolExecutor to use existing idle threads before spinning up new ones. \ No newline at end of file From e4d300e07c33a9a77549c62d8687d8fe130c53d5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 22 May 2019 23:44:02 +0200 Subject: [PATCH 066/441] bpo-36829: Add test.support.catch_unraisable_exception() (GH-13490) * Copy test_exceptions.test_unraisable() to test_sys.UnraisableHookTest(). * Use catch_unraisable_exception() in test_coroutines, test_exceptions, test_generators. --- Lib/test/support/__init__.py | 33 +++++++++++++++ Lib/test/test_coroutines.py | 17 +++++--- Lib/test/test_exceptions.py | 30 ++++---------- Lib/test/test_generators.py | 28 ++++++------- Lib/test/test_sys.py | 41 +++++++++++++++++++ .../2019-05-22-12-57-15.bpo-36829.e9mRWC.rst | 2 + 6 files changed, 108 insertions(+), 43 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 9e60d960ab12f4..2fe9d9dc80998f 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3034,3 +3034,36 @@ def collision_stats(nbins, nballs): collisions = k - occupied var = dn*(dn-1)*((dn-2)/dn)**k + meanempty * (1 - meanempty) return float(collisions), float(var.sqrt()) + + +class catch_unraisable_exception: + """ + Context manager catching unraisable exception using sys.unraisablehook. + + Usage: + + with support.catch_unraisable_exception() as cm: + ... + + # check the expected unraisable exception: use cm.unraisable + ... + + # cm.unraisable is None here (to break a reference cycle) + """ + + def __init__(self): + self.unraisable = None + self._old_hook = None + + def _hook(self, unraisable): + self.unraisable = unraisable + + def __enter__(self): + self._old_hook = sys.unraisablehook + sys.unraisablehook = self._hook + return self + + def __exit__(self, *exc_info): + # Clear the unraisable exception to explicitly break a reference cycle + self.unraisable = None + sys.unraisablehook = self._old_hook diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 8443e658a620b9..036f13fa50e9ae 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2342,12 +2342,19 @@ async def corofn(): orig_wuc = warnings._warn_unawaited_coroutine try: warnings._warn_unawaited_coroutine = lambda coro: 1/0 - with support.captured_stderr() as stream: - corofn() + with support.catch_unraisable_exception() as cm, \ + support.captured_stderr() as stream: + # only store repr() to avoid keeping the coroutine alive + coro = corofn() + coro_repr = repr(coro) + + # clear reference to the coroutine without awaiting for it + del coro support.gc_collect() - self.assertIn("Exception ignored in", stream.getvalue()) - self.assertIn("ZeroDivisionError", stream.getvalue()) - self.assertIn("was never awaited", stream.getvalue()) + + self.assertEqual(repr(cm.unraisable.object), coro_repr) + self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError) + self.assertIn("was never awaited", stream.getvalue()) del warnings._warn_unawaited_coroutine with support.captured_stderr() as stream: diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 6ef529e2b015be..d7e11d2d30a87c 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -12,6 +12,9 @@ check_warnings, cpython_only, gc_collect, run_unittest, no_tracing, unlink, import_module, script_helper, SuppressCrashReport) +from test import support + + class NaiveException(Exception): def __init__(self, x): self.x = x @@ -1181,29 +1184,12 @@ def __del__(self): # The following line is included in the traceback report: raise exc - class BrokenExceptionDel: - def __del__(self): - exc = BrokenStrException() - # The following line is included in the traceback report: - raise exc + obj = BrokenDel() + with support.catch_unraisable_exception() as cm: + del obj - for test_class in (BrokenDel, BrokenExceptionDel): - with self.subTest(test_class): - obj = test_class() - with captured_stderr() as stderr: - del obj - report = stderr.getvalue() - self.assertIn("Exception ignored", report) - self.assertIn(test_class.__del__.__qualname__, report) - self.assertIn("test_exceptions.py", report) - self.assertIn("raise exc", report) - if test_class is BrokenExceptionDel: - self.assertIn("BrokenStrException", report) - self.assertIn("", report) - else: - self.assertIn("ValueError", report) - self.assertIn("del is broken", report) - self.assertTrue(report.endswith("\n")) + self.assertEqual(cm.unraisable.object, BrokenDel.__del__) + self.assertIsNotNone(cm.unraisable.exc_traceback) def test_unhandled(self): # Check for sensible reporting of unhandled exceptions diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 320793c7dab69b..7f1472fa03ac30 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -2156,25 +2156,21 @@ def printsolution(self, x): printing warnings and to doublecheck that we actually tested what we wanted to test. ->>> import sys, io ->>> old = sys.stderr ->>> try: -... sys.stderr = io.StringIO() -... class Leaker: -... def __del__(self): -... def invoke(message): -... raise RuntimeError(message) -... invoke("test") +>>> from test import support +>>> class Leaker: +... def __del__(self): +... def invoke(message): +... raise RuntimeError(message) +... invoke("del failed") ... +>>> with support.catch_unraisable_exception() as cm: ... l = Leaker() ... del l -... err = sys.stderr.getvalue().strip() -... "Exception ignored in" in err -... "RuntimeError: test" in err -... "Traceback" in err -... "in invoke" in err -... finally: -... sys.stderr = old +... +... cm.unraisable.object == Leaker.__del__ +... cm.unraisable.exc_type == RuntimeError +... str(cm.unraisable.exc_value) == "del failed" +... cm.unraisable.exc_traceback is not None True True True diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 2b358ca0466e6e..67a952d9b4544c 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -909,6 +909,47 @@ def test_original_unraisablehook(self): self.assertIn('Traceback (most recent call last):\n', err) self.assertIn('ValueError: 42\n', err) + def test_original_unraisablehook_err(self): + # bpo-22836: PyErr_WriteUnraisable() should give sensible reports + class BrokenDel: + def __del__(self): + exc = ValueError("del is broken") + # The following line is included in the traceback report: + raise exc + + class BrokenStrException(Exception): + def __str__(self): + raise Exception("str() is broken") + + class BrokenExceptionDel: + def __del__(self): + exc = BrokenStrException() + # The following line is included in the traceback report: + raise exc + + for test_class in (BrokenDel, BrokenExceptionDel): + with self.subTest(test_class): + obj = test_class() + with test.support.captured_stderr() as stderr, \ + test.support.swap_attr(sys, 'unraisablehook', + sys.__unraisablehook__): + # Trigger obj.__del__() + del obj + + report = stderr.getvalue() + self.assertIn("Exception ignored", report) + self.assertIn(test_class.__del__.__qualname__, report) + self.assertIn("test_sys.py", report) + self.assertIn("raise exc", report) + if test_class is BrokenExceptionDel: + self.assertIn("BrokenStrException", report) + self.assertIn("", report) + else: + self.assertIn("ValueError", report) + self.assertIn("del is broken", report) + self.assertTrue(report.endswith("\n")) + + def test_original_unraisablehook_wrong_type(self): exc = ValueError(42) with test.support.swap_attr(sys, 'unraisablehook', diff --git a/Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst b/Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst new file mode 100644 index 00000000000000..4ab342b8a2b364 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst @@ -0,0 +1,2 @@ +Add :func:`test.support.catch_unraisable_exception`: context manager +catching unraisable exception using :func:`sys.unraisablehook`. From 022be02dcfdfd9011415804bb4553a33fa7ec8f3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 22 May 2019 23:58:50 +0200 Subject: [PATCH 067/441] bpo-36763: Add _PyPreConfig._config_init (GH-13481) * _PyPreConfig_GetGlobalConfig() and _PyCoreConfig_GetGlobalConfig() now do nothing if the configuration was not initialized with _PyPreConfig_InitCompatConfig() and _PyCoreConfig_InitCompatConfig() * Remove utf8_mode=-2 special case: use utf8_mode=-1 instead. * Fix _PyPreConfig_InitPythonConfig(): * isolated = 0 instead of -1 * use_environment = 1 instead of -1 * Rename _PyConfig_INIT to _PyConfig_INIT_COMPAT * Rename _PyPreConfig_Init() to _PyPreConfig_InitCompatConfig() * Rename _PyCoreConfig_Init() to _PyCoreConfig_InitCompatConfig() * PyInterpreterState_New() now uses _PyCoreConfig_InitPythonConfig() as default configuration, but it's very quickly overriden anyway. * _freeze_importlib.c uses _PyCoreConfig_SetString() to set program_name. * Cleanup preconfig_init_utf8_mode(): cmdline is always non-NULL. --- Include/cpython/coreconfig.h | 22 +++--- Include/internal/pycore_coreconfig.h | 4 +- Lib/test/test_embed.py | 113 +++++++++++++++------------ Programs/_freeze_importlib.c | 22 ++++-- Programs/_testembed.c | 61 +++++++++++++-- Python/coreconfig.c | 17 ++-- Python/frozenmain.c | 9 ++- Python/pathconfig.c | 2 +- Python/preconfig.c | 44 ++++++----- Python/pylifecycle.c | 4 +- Python/pystate.c | 10 ++- 11 files changed, 200 insertions(+), 108 deletions(-) diff --git a/Include/cpython/coreconfig.h b/Include/cpython/coreconfig.h index decfb70e7345c5..ef5fde20e88d67 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/coreconfig.h @@ -40,9 +40,18 @@ typedef struct { #define _Py_CONFIG_VERSION 1 +typedef enum { + /* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */ + _PyConfig_INIT_COMPAT = 1, + _PyConfig_INIT_PYTHON = 2, + _PyConfig_INIT_ISOLATED = 3 +} _PyConfigInitEnum; + + typedef struct { int _config_version; /* Internal configuration version, used for ABI compatibility */ + int _config_init; /* _PyConfigInitEnum value */ /* Parse _Py_PreInitializeFromArgs() arguments? See _PyCoreConfig.parse_argv */ @@ -107,10 +116,7 @@ typedef struct { Set to 0 by "-X utf8=0" and PYTHONUTF8=0. If equals to -1, it is set to 1 if the LC_CTYPE locale is "C" or - "POSIX", otherwise it is set to 0. - - If equals to -2, inherit Py_UTF8Mode value value (which is equal to 0 - by default). */ + "POSIX", otherwise it is set to 0. Inherit Py_UTF8Mode value value. */ int utf8_mode; int dev_mode; /* Development mode. PYTHONDEVMODE, -X dev */ @@ -126,16 +132,10 @@ PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config); /* --- _PyCoreConfig ---------------------------------------------- */ -typedef enum { - _PyCoreConfig_INIT = 0, - _PyCoreConfig_INIT_PYTHON = 1, - _PyCoreConfig_INIT_ISOLATED = 2 -} _PyCoreConfigInitEnum; - typedef struct { int _config_version; /* Internal configuration version, used for ABI compatibility */ - int _config_init; /* _PyCoreConfigInitEnum value */ + int _config_init; /* _PyConfigInitEnum value */ int isolated; /* Isolated mode? see _PyPreConfig.isolated */ int use_environment; /* Use environment variables? see _PyPreConfig.use_environment */ diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h index 324e0b82b90c60..b17737a90ba325 100644 --- a/Include/internal/pycore_coreconfig.h +++ b/Include/internal/pycore_coreconfig.h @@ -120,7 +120,7 @@ PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline, /* --- _PyPreConfig ----------------------------------------------- */ -PyAPI_FUNC(void) _PyPreConfig_Init(_PyPreConfig *config); +PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(_PyPreConfig *config); PyAPI_FUNC(void) _PyPreConfig_InitFromCoreConfig( _PyPreConfig *config, const _PyCoreConfig *coreconfig); @@ -139,7 +139,7 @@ PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(const _PyPreConfig *config); /* --- _PyCoreConfig ---------------------------------------------- */ -PyAPI_FUNC(void) _PyCoreConfig_Init(_PyCoreConfig *config); +PyAPI_FUNC(void) _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config); PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy( _PyCoreConfig *config, const _PyCoreConfig *config2); diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 4fe005dfa130e3..8101e70f9bc9d0 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -13,13 +13,17 @@ MS_WINDOWS = (os.name == 'nt') + PYMEM_ALLOCATOR_NOT_SET = 0 PYMEM_ALLOCATOR_DEBUG = 2 PYMEM_ALLOCATOR_MALLOC = 3 -CONFIG_INIT = 0 -CONFIG_INIT_PYTHON = 1 -CONFIG_INIT_ISOLATED = 2 +# _PyCoreConfig_InitCompatConfig() +API_COMPAT = 1 +# _PyCoreConfig_InitPythonConfig() +API_PYTHON = 2 +# _PyCoreConfig_InitIsolatedConfig() +API_ISOLATED = 3 class EmbeddingTestsMixin: @@ -282,7 +286,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): # Marker to ignore a configuration parameter IGNORE_CONFIG = object() - DEFAULT_PRE_CONFIG = { + PRE_CONFIG_COMPAT = { 'allocator': PYMEM_ALLOCATOR_NOT_SET, 'parse_argv': 0, 'configure_locale': 1, @@ -291,15 +295,15 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'utf8_mode': 0, } if MS_WINDOWS: - DEFAULT_PRE_CONFIG.update({ + PRE_CONFIG_COMPAT.update({ 'legacy_windows_fs_encoding': 0, }) - PYTHON_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG, + PRE_CONFIG_PYTHON = dict(PRE_CONFIG_COMPAT, parse_argv=1, coerce_c_locale=GET_DEFAULT_CONFIG, utf8_mode=GET_DEFAULT_CONFIG, ) - ISOLATED_PRE_CONFIG = dict(DEFAULT_PRE_CONFIG, + PRE_CONFIG_ISOLATED = dict(PRE_CONFIG_COMPAT, configure_locale=0, isolated=1, use_environment=0, @@ -314,8 +318,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_environment', ] - DEFAULT_CORE_CONFIG = { - '_config_init': CONFIG_INIT, + CORE_CONFIG_COMPAT = { + '_config_init': API_COMPAT, 'isolated': 0, 'use_environment': 1, 'dev_mode': 0, @@ -379,15 +383,15 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): '_init_main': 1, } if MS_WINDOWS: - DEFAULT_CORE_CONFIG.update({ + CORE_CONFIG_COMPAT.update({ 'legacy_windows_stdio': 0, }) - PYTHON_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG, + CORE_CONFIG_PYTHON = dict(CORE_CONFIG_COMPAT, configure_c_stdio=1, parse_argv=1, ) - ISOLATED_CORE_CONFIG = dict(DEFAULT_CORE_CONFIG, + CORE_CONFIG_ISOLATED = dict(CORE_CONFIG_COMPAT, isolated=1, use_environment=0, user_site_directory=0, @@ -399,7 +403,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): pathconfig_warnings=0, ) if MS_WINDOWS: - ISOLATED_CORE_CONFIG['legacy_windows_stdio'] = 0 + CORE_CONFIG_ISOLATED['legacy_windows_stdio'] = 0 # global config DEFAULT_GLOBAL_CONFIG = { @@ -492,7 +496,7 @@ def get_expected_config(self, expected_preconfig, expected, env, api, if value is self.GET_DEFAULT_CONFIG: expected_preconfig[key] = pre_config[key] - if not expected_preconfig['configure_locale'] or api == CONFIG_INIT: + if not expected_preconfig['configure_locale'] or api == API_COMPAT: # there is no easy way to get the locale encoding before # setlocale(LC_CTYPE, "") is called: don't test encodings for key in ('filesystem_encoding', 'filesystem_errors', @@ -579,32 +583,33 @@ def check_global_config(self, config): self.assertEqual(config['global_config'], expected) - def check_config(self, testname, expected_config=None, expected_preconfig=None, - add_path=None, stderr=None, api=CONFIG_INIT): + def check_config(self, testname, expected_config=None, + expected_preconfig=None, add_path=None, stderr=None, + *, api): env = dict(os.environ) # Remove PYTHON* environment variables to get deterministic environment for key in list(env): if key.startswith('PYTHON'): del env[key] - if api == CONFIG_INIT_ISOLATED: - default_preconfig = self.ISOLATED_PRE_CONFIG - elif api == CONFIG_INIT_PYTHON: - default_preconfig = self.PYTHON_PRE_CONFIG + if api == API_ISOLATED: + default_preconfig = self.PRE_CONFIG_ISOLATED + elif api == API_PYTHON: + default_preconfig = self.PRE_CONFIG_PYTHON else: - default_preconfig = self.DEFAULT_PRE_CONFIG + default_preconfig = self.PRE_CONFIG_COMPAT if expected_preconfig is None: expected_preconfig = {} expected_preconfig = dict(default_preconfig, **expected_preconfig) if expected_config is None: expected_config = {} - if api == CONFIG_INIT_PYTHON: - default_config = self.PYTHON_CORE_CONFIG - elif api == CONFIG_INIT_ISOLATED: - default_config = self.ISOLATED_CORE_CONFIG + if api == API_PYTHON: + default_config = self.CORE_CONFIG_PYTHON + elif api == API_ISOLATED: + default_config = self.CORE_CONFIG_ISOLATED else: - default_config = self.DEFAULT_CORE_CONFIG + default_config = self.CORE_CONFIG_COMPAT expected_config = dict(default_config, **expected_config) expected_config['_config_init'] = api @@ -627,7 +632,13 @@ def check_config(self, testname, expected_config=None, expected_preconfig=None, self.check_global_config(config) def test_init_default_config(self): - self.check_config("init_default_config", {}, {}) + self.check_config("init_initialize_config", api=API_COMPAT) + + def test_preinit_compat_config(self): + self.check_config("preinit_compat_config", api=API_COMPAT) + + def test_init_compat_config(self): + self.check_config("init_compat_config", api=API_COMPAT) def test_init_global_config(self): preconfig = { @@ -649,7 +660,8 @@ def test_init_global_config(self): 'user_site_directory': 0, 'pathconfig_warnings': 0, } - self.check_config("init_global_config", config, preconfig) + self.check_config("init_global_config", config, preconfig, + api=API_COMPAT) def test_init_from_config(self): preconfig = { @@ -693,11 +705,13 @@ def test_init_from_config(self): 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, } - self.check_config("init_from_config", config, preconfig) + self.check_config("init_from_config", config, preconfig, + api=API_COMPAT) def test_init_env(self): preconfig = { 'allocator': PYMEM_ALLOCATOR_MALLOC, + 'utf8_mode': 1, } config = { 'use_hash_seed': 1, @@ -718,21 +732,24 @@ def test_init_env(self): 'faulthandler': 1, 'warnoptions': ['EnvVar'], } - self.check_config("init_env", config, preconfig) + self.check_config("init_env", config, preconfig, + api=API_COMPAT) def test_init_env_dev_mode(self): preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG) config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("init_env_dev_mode", config, preconfig) + self.check_config("init_env_dev_mode", config, preconfig, + api=API_COMPAT) def test_init_env_dev_mode_alloc(self): preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC) config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("init_env_dev_mode_alloc", config, preconfig) + self.check_config("init_env_dev_mode_alloc", config, preconfig, + api=API_COMPAT) def test_init_dev_mode(self): preconfig = { @@ -744,7 +761,7 @@ def test_init_dev_mode(self): 'warnoptions': ['default'], } self.check_config("init_dev_mode", config, preconfig, - api=CONFIG_INIT_PYTHON) + api=API_PYTHON) def test_preinit_parse_argv(self): # Pre-initialize implicitly using argv: make sure that -X dev @@ -761,7 +778,7 @@ def test_preinit_parse_argv(self): 'xoptions': ['dev'], } self.check_config("preinit_parse_argv", config, preconfig, - api=CONFIG_INIT_PYTHON) + api=API_PYTHON) def test_preinit_dont_parse_argv(self): # -X dev must be ignored by isolated preconfiguration @@ -774,7 +791,7 @@ def test_preinit_dont_parse_argv(self): 'isolated': 0, } self.check_config("preinit_dont_parse_argv", config, preconfig, - api=CONFIG_INIT_ISOLATED) + api=API_ISOLATED) def test_init_isolated_flag(self): config = { @@ -782,7 +799,7 @@ def test_init_isolated_flag(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("init_isolated_flag", config, api=CONFIG_INIT_PYTHON) + self.check_config("init_isolated_flag", config, api=API_PYTHON) def test_preinit_isolated1(self): # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set @@ -791,7 +808,7 @@ def test_preinit_isolated1(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated1", config) + self.check_config("preinit_isolated1", config, api=API_COMPAT) def test_preinit_isolated2(self): # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 @@ -800,16 +817,16 @@ def test_preinit_isolated2(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated2", config) + self.check_config("preinit_isolated2", config, api=API_COMPAT) def test_preinit_isolated_config(self): - self.check_config("preinit_isolated_config", api=CONFIG_INIT_ISOLATED) + self.check_config("preinit_isolated_config", api=API_ISOLATED) def test_init_isolated_config(self): - self.check_config("init_isolated_config", api=CONFIG_INIT_ISOLATED) + self.check_config("init_isolated_config", api=API_ISOLATED) def test_init_python_config(self): - self.check_config("init_python_config", api=CONFIG_INIT_PYTHON) + self.check_config("init_python_config", api=API_PYTHON) def test_init_dont_configure_locale(self): # _PyPreConfig.configure_locale=0 @@ -818,7 +835,7 @@ def test_init_dont_configure_locale(self): 'coerce_c_locale': 0, } self.check_config("init_dont_configure_locale", {}, preconfig, - api=CONFIG_INIT_PYTHON) + api=API_PYTHON) def test_init_read_set(self): core_config = { @@ -826,7 +843,7 @@ def test_init_read_set(self): 'executable': 'my_executable', } self.check_config("init_read_set", core_config, - api=CONFIG_INIT_PYTHON, + api=API_PYTHON, add_path="init_read_set_path") def test_init_run_main(self): @@ -838,8 +855,7 @@ def test_init_run_main(self): 'run_command': code + '\n', 'parse_argv': 1, } - self.check_config("init_run_main", core_config, - api=CONFIG_INIT_PYTHON) + self.check_config("init_run_main", core_config, api=API_PYTHON) def test_init_main(self): code = ('import _testinternalcapi, json; ' @@ -852,7 +868,7 @@ def test_init_main(self): '_init_main': 0, } self.check_config("init_main", core_config, - api=CONFIG_INIT_PYTHON, + api=API_PYTHON, stderr="Run Python code before _Py_InitializeMain") def test_init_parse_argv(self): @@ -863,8 +879,7 @@ def test_init_parse_argv(self): 'run_command': 'pass\n', 'use_environment': 0, } - self.check_config("init_parse_argv", core_config, - api=CONFIG_INIT_PYTHON) + self.check_config("init_parse_argv", core_config, api=API_PYTHON) def test_init_dont_parse_argv(self): pre_config = { @@ -876,7 +891,7 @@ def test_init_dont_parse_argv(self): 'program_name': './argv0', } self.check_config("init_dont_parse_argv", core_config, pre_config, - api=CONFIG_INIT_PYTHON) + api=API_PYTHON) if __name__ == "__main__": diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c index 1a719e2f96735e..8cf44d33bc02d9 100644 --- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -76,18 +76,30 @@ main(int argc, char *argv[]) } text[text_size] = '\0'; + _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_InitIsolatedConfig(&config); + + err = _PyCoreConfig_InitIsolatedConfig(&config); + if (_PyInitError_Failed(err)) { + _PyCoreConfig_Clear(&config); + _Py_ExitInitError(err); + } config.site_import = 0; - config.program_name = L"./_freeze_importlib"; + + err = _PyCoreConfig_SetString(&config, &config.program_name, + L"./_freeze_importlib"); + if (_PyInitError_Failed(err)) { + _PyCoreConfig_Clear(&config); + _Py_ExitInitError(err); + } + /* Don't install importlib, since it could execute outdated bytecode. */ config._install_importlib = 0; config._init_main = 0; - _PyInitError err = _Py_InitializeFromConfig(&config); - /* No need to call _PyCoreConfig_Clear() since we didn't allocate any - memory: program_name is a constant string. */ + err = _Py_InitializeFromConfig(&config); + _PyCoreConfig_Clear(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } diff --git a/Programs/_testembed.c b/Programs/_testembed.c index bc549369393fc7..a273930e10aef2 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -317,7 +317,7 @@ dump_config(void) } -static int test_init_default_config(void) +static int test_init_initialize_config(void) { _testembed_Py_Initialize(); dump_config(); @@ -326,6 +326,47 @@ static int test_init_default_config(void) } +static int check_init_compat_config(int preinit) +{ + _PyInitError err; + + if (preinit) { + _PyPreConfig preconfig; + _PyPreConfig_InitCompatConfig(&preconfig); + + err = _Py_PreInitialize(&preconfig); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } + } + + _PyCoreConfig config; + _PyCoreConfig_InitCompatConfig(&config); + config.program_name = L"./_testembed"; + + err = _Py_InitializeFromConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } + + dump_config(); + Py_Finalize(); + return 0; +} + + +static int test_preinit_compat_config(void) +{ + return check_init_compat_config(1); +} + + +static int test_init_compat_config(void) +{ + return check_init_compat_config(0); +} + + static int test_init_global_config(void) { /* FIXME: test Py_IgnoreEnvironmentFlag */ @@ -380,7 +421,7 @@ static int test_init_from_config(void) _PyInitError err; _PyPreConfig preconfig; - _PyPreConfig_Init(&preconfig); + _PyPreConfig_InitCompatConfig(&preconfig); putenv("PYTHONMALLOC=malloc_debug"); preconfig.allocator = PYMEM_ALLOCATOR_MALLOC; @@ -396,7 +437,7 @@ static int test_init_from_config(void) /* Test _Py_InitializeFromConfig() */ _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitCompatConfig(&config); config.install_signal_handlers = 0; /* FIXME: test use_environment */ @@ -676,7 +717,7 @@ static int test_preinit_isolated1(void) _PyInitError err; _PyPreConfig preconfig; - _PyPreConfig_Init(&preconfig); + _PyPreConfig_InitCompatConfig(&preconfig); preconfig.isolated = 1; err = _Py_PreInitialize(&preconfig); @@ -685,7 +726,7 @@ static int test_preinit_isolated1(void) } _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitCompatConfig(&config); config.program_name = L"./_testembed"; set_all_env_vars(); @@ -705,7 +746,7 @@ static int test_preinit_isolated2(void) _PyInitError err; _PyPreConfig preconfig; - _PyPreConfig_Init(&preconfig); + _PyPreConfig_InitCompatConfig(&preconfig); preconfig.isolated = 0; err = _Py_PreInitialize(&preconfig); @@ -715,7 +756,7 @@ static int test_preinit_isolated2(void) /* Test _PyCoreConfig.isolated=1 */ _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitCompatConfig(&config); Py_IsolatedFlag = 0; config.isolated = 1; @@ -885,12 +926,14 @@ static int check_preinit_isolated_config(int preinit) _PyCoreConfig config; err = _PyCoreConfig_InitIsolatedConfig(&config); if (_PyInitError_Failed(err)) { + _PyCoreConfig_Clear(&config); _Py_ExitInitError(err); } config.program_name = L"./_testembed"; err = _Py_InitializeFromConfig(&config); if (_PyInitError_Failed(err)) { + _PyCoreConfig_Clear(&config); _Py_ExitInitError(err); } @@ -1207,7 +1250,9 @@ static struct TestCase TestCases[] = { { "bpo20891", test_bpo20891 }, { "initialize_twice", test_initialize_twice }, { "initialize_pymain", test_initialize_pymain }, - { "init_default_config", test_init_default_config }, + { "init_initialize_config", test_init_initialize_config }, + { "preinit_compat_config", test_preinit_compat_config }, + { "init_compat_config", test_init_compat_config }, { "init_global_config", test_init_global_config }, { "init_from_config", test_init_from_config }, { "init_parse_argv", test_init_parse_argv }, diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 958845e488d7f2..40dba4ee5e5e54 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -109,7 +109,7 @@ static const char usage_6[] = /* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change stdin and stdout error handler to "surrogateescape". It is equal to -1 by default: unknown, will be set by Py_Main() */ -int Py_UTF8Mode = 0; +int Py_UTF8Mode = -1; int Py_DebugFlag = 0; /* Needed by parser.c */ int Py_VerboseFlag = 0; /* Needed by import.c */ int Py_QuietFlag = 0; /* Needed by sysmodule.c */ @@ -546,12 +546,12 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) void -_PyCoreConfig_Init(_PyCoreConfig *config) +_PyCoreConfig_InitCompatConfig(_PyCoreConfig *config) { memset(config, 0, sizeof(*config)); config->_config_version = _Py_CONFIG_VERSION; - config->_config_init = (int)_PyCoreConfig_INIT; + config->_config_init = (int)_PyConfig_INIT_COMPAT; config->isolated = -1; config->use_environment = -1; config->dev_mode = -1; @@ -586,7 +586,7 @@ _PyCoreConfig_Init(_PyCoreConfig *config) static void _PyCoreConfig_InitDefaults(_PyCoreConfig *config) { - _PyCoreConfig_Init(config); + _PyCoreConfig_InitCompatConfig(config); config->isolated = 0; config->use_environment = 1; @@ -613,7 +613,7 @@ _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config) { _PyCoreConfig_InitDefaults(config); - config->_config_init = (int)_PyCoreConfig_INIT_PYTHON; + config->_config_init = (int)_PyConfig_INIT_PYTHON; config->configure_c_stdio = 1; config->parse_argv = 1; @@ -626,7 +626,7 @@ _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config) { _PyCoreConfig_InitDefaults(config); - config->_config_init = (int)_PyCoreConfig_INIT_ISOLATED; + config->_config_init = (int)_PyConfig_INIT_ISOLATED; config->isolated = 1; config->use_environment = 0; config->user_site_directory = 0; @@ -962,6 +962,11 @@ _PyCoreConfig_GetEnvDup(_PyCoreConfig *config, static void _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) { + if (config->_config_init != _PyConfig_INIT_COMPAT) { + /* Python and Isolated configuration ignore global variables */ + return; + } + #define COPY_FLAG(ATTR, VALUE) \ if (config->ATTR == -1) { \ config->ATTR = VALUE; \ diff --git a/Python/frozenmain.c b/Python/frozenmain.c index a51fb5800127d8..c3af080401e9b9 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -40,7 +40,11 @@ Py_FrozenMain(int argc, char **argv) } _PyCoreConfig config; - _PyCoreConfig_InitPythonConfig(&config); + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _PyCoreConfig_Clear(&config); + _Py_ExitInitError(err); + } config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') @@ -82,8 +86,7 @@ Py_FrozenMain(int argc, char **argv) Py_SetProgramName(argv_copy[0]); err = _Py_InitializeFromConfig(&config); - /* No need to call _PyCoreConfig_Clear() since we didn't allocate any - memory: program_name is a constant string. */ + _PyCoreConfig_Clear(&config); if (_PyInitError_Failed(err)) { _Py_ExitInitError(err); } diff --git a/Python/pathconfig.c b/Python/pathconfig.c index 3d9d3b1b205fc9..bbf29b2fa59819 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -383,7 +383,7 @@ pathconfig_global_init(void) _PyInitError err; _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitCompatConfig(&config); err = _PyCoreConfig_Read(&config); if (_Py_INIT_FAILED(err)) { diff --git a/Python/preconfig.c b/Python/preconfig.c index 4df6208cadb841..392324ff201a33 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -262,16 +262,17 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig) void -_PyPreConfig_Init(_PyPreConfig *config) +_PyPreConfig_InitCompatConfig(_PyPreConfig *config) { memset(config, 0, sizeof(*config)); config->_config_version = _Py_CONFIG_VERSION; + config->_config_init = (int)_PyConfig_INIT_COMPAT; config->parse_argv = 0; config->isolated = -1; config->use_environment = -1; config->configure_locale = 1; - config->utf8_mode = -2; + config->utf8_mode = -1; config->dev_mode = -1; config->allocator = PYMEM_ALLOCATOR_NOT_SET; #ifdef MS_WINDOWS @@ -283,23 +284,30 @@ _PyPreConfig_Init(_PyPreConfig *config) void _PyPreConfig_InitPythonConfig(_PyPreConfig *config) { - _PyPreConfig_Init(config); + _PyPreConfig_InitCompatConfig(config); + config->_config_init = (int)_PyConfig_INIT_PYTHON; + config->isolated = 0; config->parse_argv = 1; + config->use_environment = 1; /* Set to -1 to enable C locale coercion (PEP 538) and UTF-8 Mode (PEP 540) depending on the LC_CTYPE locale, PYTHONUTF8 and PYTHONCOERCECLOCALE environment variables. */ config->coerce_c_locale = -1; config->coerce_c_locale_warn = -1; config->utf8_mode = -1; +#ifdef MS_WINDOWS + config->legacy_windows_fs_encoding = 0; +#endif } void _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config) { - _PyPreConfig_Init(config); + _PyPreConfig_InitCompatConfig(config); + config->_config_init = (int)_PyConfig_INIT_ISOLATED; config->configure_locale = 0; config->isolated = 1; config->use_environment = 0; @@ -315,7 +323,7 @@ void _PyPreConfig_InitFromPreConfig(_PyPreConfig *config, const _PyPreConfig *config2) { - _PyPreConfig_Init(config); + _PyPreConfig_InitCompatConfig(config); _PyPreConfig_Copy(config, config2); } @@ -324,17 +332,17 @@ void _PyPreConfig_InitFromCoreConfig(_PyPreConfig *config, const _PyCoreConfig *coreconfig) { - _PyCoreConfigInitEnum config_init = (_PyCoreConfigInitEnum)coreconfig->_config_init; + _PyConfigInitEnum config_init = (_PyConfigInitEnum)coreconfig->_config_init; switch (config_init) { - case _PyCoreConfig_INIT_PYTHON: + case _PyConfig_INIT_PYTHON: _PyPreConfig_InitPythonConfig(config); break; - case _PyCoreConfig_INIT_ISOLATED: + case _PyConfig_INIT_ISOLATED: _PyPreConfig_InitIsolatedConfig(config); break; - case _PyCoreConfig_INIT: + case _PyConfig_INIT_COMPAT: default: - _PyPreConfig_Init(config); + _PyPreConfig_InitCompatConfig(config); } _PyPreConfig_GetCoreConfig(config, coreconfig); } @@ -428,6 +436,11 @@ _PyPreConfig_GetCoreConfig(_PyPreConfig *config, static void _PyPreConfig_GetGlobalConfig(_PyPreConfig *config) { + if (config->_config_init != _PyConfig_INIT_COMPAT) { + /* Python and Isolated configuration ignore global variables */ + return; + } + #define COPY_FLAG(ATTR, VALUE) \ if (config->ATTR < 0) { \ config->ATTR = VALUE; \ @@ -439,12 +452,10 @@ _PyPreConfig_GetGlobalConfig(_PyPreConfig *config) COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); + COPY_FLAG(utf8_mode, Py_UTF8Mode); #ifdef MS_WINDOWS COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); #endif - if (config->utf8_mode == -2) { - config->utf8_mode = Py_UTF8Mode; - } #undef COPY_FLAG #undef COPY_NOT_FLAG @@ -565,12 +576,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) } const wchar_t *xopt; - if (cmdline) { - xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); - } - else { - xopt = NULL; - } + xopt = _Py_get_xoption(&cmdline->xoptions, L"utf8"); if (xopt) { wchar_t *sep = wcschr(xopt, L'='); if (sep) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 6dc684bfcebb84..21c386bb4a3edd 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -867,7 +867,7 @@ _Py_InitializeCore(_PyRuntimeState *runtime, } _PyCoreConfig local_config; - _PyCoreConfig_Init(&local_config); + _PyCoreConfig_InitCompatConfig(&local_config); err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p); _PyCoreConfig_Clear(&local_config); return err; @@ -1096,7 +1096,7 @@ Py_InitializeEx(int install_sigs) } _PyCoreConfig config; - _PyCoreConfig_Init(&config); + _PyCoreConfig_InitCompatConfig(&config); config.install_signal_handlers = install_sigs; err = _Py_InitializeFromConfig(&config); diff --git a/Python/pystate.c b/Python/pystate.c index 2f80aa253b5aae..879a5a91f8a3b0 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -49,7 +49,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) _PyGC_Initialize(&runtime->gc); _PyEval_Initialize(&runtime->ceval); - _PyPreConfig_Init(&runtime->preconfig); + _PyPreConfig_InitPythonConfig(&runtime->preconfig); runtime->gilstate.check_enabled = 1; @@ -189,7 +189,13 @@ PyInterpreterState_New(void) memset(interp, 0, sizeof(*interp)); interp->id_refcount = -1; interp->check_interval = 100; - _PyCoreConfig_Init(&interp->core_config); + + _PyInitError err = _PyCoreConfig_InitPythonConfig(&interp->core_config); + if (_Py_INIT_FAILED(err)) { + PyMem_RawFree(interp); + return NULL; + } + interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN #if HAVE_DECL_RTLD_NOW From cfb241bd29a94fd825a317a78322e3cdba0e75a7 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Wed, 22 May 2019 15:16:21 -0700 Subject: [PATCH 068/441] bpo-36941: Project file fixups for Windows ARM64 (GH-13477) --- PCbuild/pcbuild.sln | 21 +++++++++++++++++---- PCbuild/python.vcxproj | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index dea6799a5e5582..6dc0139bc42af4 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -478,6 +478,7 @@ Global {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM.ActiveCfg = Debug|ARM {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM.Build.0 = Debug|ARM {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM64.Build.0 = Debug|ARM64 {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32 {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32 {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64 @@ -501,6 +502,7 @@ Global {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM.ActiveCfg = Release|ARM {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM.Build.0 = Release|ARM {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM64.ActiveCfg = Release|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM64.Build.0 = Release|ARM64 {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32 {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32 {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64 @@ -539,28 +541,32 @@ Global {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.ActiveCfg = Debug|ARM {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.Build.0 = Debug|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.ActiveCfg = Debug|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.Build.0 = Debug|ARM64 {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|Win32.ActiveCfg = Debug|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|Win32.Build.0 = Debug|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|x64.ActiveCfg = Debug|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|x64.Build.0 = Debug|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|x64.Build.0 = PGInstrument|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|x64.Build.0 = PGUpdate|x64 {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM.ActiveCfg = Release|ARM {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM.Build.0 = Release|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM64.ActiveCfg = Release|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM64.ActiveCfg = Release|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM64.Build.0 = Release|ARM64 {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|Win32.ActiveCfg = Release|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|Win32.Build.0 = Release|Win32 {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|x64.ActiveCfg = Release|x64 @@ -934,13 +940,17 @@ Global {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Release|Win32 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Release|x64 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM.Build.0 = PGInstrument|ARM {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = PGInstrument|x64 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM.Build.0 = PGUpdate|ARM {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64 @@ -1182,7 +1192,9 @@ Global {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.ActiveCfg = Release|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.Build.0 = Release|ARM {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.ActiveCfg = Release|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.Build.0 = Release|ARM64 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32 {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64 @@ -1404,6 +1416,7 @@ Global {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|x64.ActiveCfg = Release|x64 {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|x64.Build.0 = Release|x64 {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM.ActiveCfg = Debug|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM.Build.0 = Debug|Win32 {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM64.ActiveCfg = Debug|Win32 {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|Win32.ActiveCfg = Debug|Win32 {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|Win32.Build.0 = Debug|Win32 diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index 919b79d986d0fa..bd051461e9cd3e 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -55,7 +55,7 @@ Release - ARM + ARM64 Release From 5edcf263581c70f6a6c2206db679e51e9418bb38 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 23 May 2019 00:57:57 +0200 Subject: [PATCH 069/441] bpo-36763: Rename private Python initialization functions (GH-13511) * Rename private C functions: * _Py_Initialize_ReconfigureCore => pyinit_core_reconfigure * _Py_InitializeCore_impl => pyinit_core_config * _Py_InitializeCore = > pyinit_core * _Py_InitializeMainInterpreter => pyinit_main * init_python => pyinit_python * Rename _testembed.c commands: add "test_" prefix. --- Lib/test/test_embed.py | 65 +++++++++++++------------ Programs/_testembed.c | 66 ++++++++++++------------- Python/pylifecycle.c | 108 +++++++++++++++++++---------------------- 3 files changed, 117 insertions(+), 122 deletions(-) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 8101e70f9bc9d0..bd0451a43b95bc 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -82,7 +82,7 @@ def run_embedded_interpreter(self, *args, env=None): return out, err def run_repeated_init_and_subinterpreters(self): - out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters") + out, err = self.run_embedded_interpreter("test_repeated_init_and_subinterpreters") self.assertEqual(err, "") # The output from _testembed looks like this: @@ -172,7 +172,7 @@ def test_subinterps_distinct_state(self): def test_forced_io_encoding(self): # Checks forced configuration of embedded interpreter IO streams env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape") - out, err = self.run_embedded_interpreter("forced_io_encoding", env=env) + out, err = self.run_embedded_interpreter("test_forced_io_encoding", env=env) if support.verbose > 1: print() print(out) @@ -218,7 +218,7 @@ def test_pre_initialization_api(self): is initialized (via Py_Initialize()). """ env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path)) - out, err = self.run_embedded_interpreter("pre_initialization_api", env=env) + out, err = self.run_embedded_interpreter("test_pre_initialization_api", env=env) if MS_WINDOWS: expected_path = self.test_exe else: @@ -234,7 +234,7 @@ def test_pre_initialization_sys_options(self): """ env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path)) out, err = self.run_embedded_interpreter( - "pre_initialization_sys_options", env=env) + "test_pre_initialization_sys_options", env=env) expected_output = ( "sys.warnoptions: ['once', 'module', 'default']\n" "sys._xoptions: {'not_an_option': '1', 'also_not_an_option': '2'}\n" @@ -249,7 +249,7 @@ def test_bpo20891(self): calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must call PyEval_InitThreads() for us in this case. """ - out, err = self.run_embedded_interpreter("bpo20891") + out, err = self.run_embedded_interpreter("test_bpo20891") self.assertEqual(out, '') self.assertEqual(err, '') @@ -258,7 +258,7 @@ def test_initialize_twice(self): bpo-33932: Calling Py_Initialize() twice should do nothing (and not crash!). """ - out, err = self.run_embedded_interpreter("initialize_twice") + out, err = self.run_embedded_interpreter("test_initialize_twice") self.assertEqual(out, '') self.assertEqual(err, '') @@ -266,12 +266,12 @@ def test_initialize_pymain(self): """ bpo-34008: Calling Py_Main() after Py_Initialize() must not fail. """ - out, err = self.run_embedded_interpreter("initialize_pymain") + out, err = self.run_embedded_interpreter("test_initialize_pymain") self.assertEqual(out.rstrip(), "Py_Main() after Py_Initialize: sys.argv=['-c', 'arg2']") self.assertEqual(err, '') def test_run_main(self): - out, err = self.run_embedded_interpreter("run_main") + out, err = self.run_embedded_interpreter("test_run_main") self.assertEqual(out.rstrip(), "_Py_RunMain(): sys.argv=['-c', 'arg2']") self.assertEqual(err, '') @@ -632,13 +632,13 @@ def check_config(self, testname, expected_config=None, self.check_global_config(config) def test_init_default_config(self): - self.check_config("init_initialize_config", api=API_COMPAT) + self.check_config("test_init_initialize_config", api=API_COMPAT) def test_preinit_compat_config(self): - self.check_config("preinit_compat_config", api=API_COMPAT) + self.check_config("test_preinit_compat_config", api=API_COMPAT) def test_init_compat_config(self): - self.check_config("init_compat_config", api=API_COMPAT) + self.check_config("test_init_compat_config", api=API_COMPAT) def test_init_global_config(self): preconfig = { @@ -660,7 +660,7 @@ def test_init_global_config(self): 'user_site_directory': 0, 'pathconfig_warnings': 0, } - self.check_config("init_global_config", config, preconfig, + self.check_config("test_init_global_config", config, preconfig, api=API_COMPAT) def test_init_from_config(self): @@ -705,7 +705,7 @@ def test_init_from_config(self): 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, } - self.check_config("init_from_config", config, preconfig, + self.check_config("test_init_from_config", config, preconfig, api=API_COMPAT) def test_init_env(self): @@ -732,7 +732,7 @@ def test_init_env(self): 'faulthandler': 1, 'warnoptions': ['EnvVar'], } - self.check_config("init_env", config, preconfig, + self.check_config("test_init_env", config, preconfig, api=API_COMPAT) def test_init_env_dev_mode(self): @@ -740,7 +740,7 @@ def test_init_env_dev_mode(self): config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("init_env_dev_mode", config, preconfig, + self.check_config("test_init_env_dev_mode", config, preconfig, api=API_COMPAT) def test_init_env_dev_mode_alloc(self): @@ -748,7 +748,7 @@ def test_init_env_dev_mode_alloc(self): config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("init_env_dev_mode_alloc", config, preconfig, + self.check_config("test_init_env_dev_mode_alloc", config, preconfig, api=API_COMPAT) def test_init_dev_mode(self): @@ -760,7 +760,7 @@ def test_init_dev_mode(self): 'dev_mode': 1, 'warnoptions': ['default'], } - self.check_config("init_dev_mode", config, preconfig, + self.check_config("test_init_dev_mode", config, preconfig, api=API_PYTHON) def test_preinit_parse_argv(self): @@ -777,7 +777,7 @@ def test_preinit_parse_argv(self): 'warnoptions': ['default'], 'xoptions': ['dev'], } - self.check_config("preinit_parse_argv", config, preconfig, + self.check_config("test_preinit_parse_argv", config, preconfig, api=API_PYTHON) def test_preinit_dont_parse_argv(self): @@ -790,7 +790,7 @@ def test_preinit_dont_parse_argv(self): "-X", "dev", "-X", "utf8", "script.py"], 'isolated': 0, } - self.check_config("preinit_dont_parse_argv", config, preconfig, + self.check_config("test_preinit_dont_parse_argv", config, preconfig, api=API_ISOLATED) def test_init_isolated_flag(self): @@ -799,7 +799,7 @@ def test_init_isolated_flag(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("init_isolated_flag", config, api=API_PYTHON) + self.check_config("test_init_isolated_flag", config, api=API_PYTHON) def test_preinit_isolated1(self): # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set @@ -808,7 +808,7 @@ def test_preinit_isolated1(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated1", config, api=API_COMPAT) + self.check_config("test_preinit_isolated1", config, api=API_COMPAT) def test_preinit_isolated2(self): # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 @@ -817,16 +817,19 @@ def test_preinit_isolated2(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("preinit_isolated2", config, api=API_COMPAT) + self.check_config("test_preinit_isolated2", config, api=API_COMPAT) def test_preinit_isolated_config(self): - self.check_config("preinit_isolated_config", api=API_ISOLATED) + self.check_config("test_preinit_isolated_config", api=API_ISOLATED) def test_init_isolated_config(self): - self.check_config("init_isolated_config", api=API_ISOLATED) + self.check_config("test_init_isolated_config", api=API_ISOLATED) + + def test_preinit_python_config(self): + self.check_config("test_preinit_python_config", api=API_PYTHON) def test_init_python_config(self): - self.check_config("init_python_config", api=API_PYTHON) + self.check_config("test_init_python_config", api=API_PYTHON) def test_init_dont_configure_locale(self): # _PyPreConfig.configure_locale=0 @@ -834,7 +837,7 @@ def test_init_dont_configure_locale(self): 'configure_locale': 0, 'coerce_c_locale': 0, } - self.check_config("init_dont_configure_locale", {}, preconfig, + self.check_config("test_init_dont_configure_locale", {}, preconfig, api=API_PYTHON) def test_init_read_set(self): @@ -842,7 +845,7 @@ def test_init_read_set(self): 'program_name': './init_read_set', 'executable': 'my_executable', } - self.check_config("init_read_set", core_config, + self.check_config("test_init_read_set", core_config, api=API_PYTHON, add_path="init_read_set_path") @@ -855,7 +858,7 @@ def test_init_run_main(self): 'run_command': code + '\n', 'parse_argv': 1, } - self.check_config("init_run_main", core_config, api=API_PYTHON) + self.check_config("test_init_run_main", core_config, api=API_PYTHON) def test_init_main(self): code = ('import _testinternalcapi, json; ' @@ -867,7 +870,7 @@ def test_init_main(self): 'parse_argv': 1, '_init_main': 0, } - self.check_config("init_main", core_config, + self.check_config("test_init_main", core_config, api=API_PYTHON, stderr="Run Python code before _Py_InitializeMain") @@ -879,7 +882,7 @@ def test_init_parse_argv(self): 'run_command': 'pass\n', 'use_environment': 0, } - self.check_config("init_parse_argv", core_config, api=API_PYTHON) + self.check_config("test_init_parse_argv", core_config, api=API_PYTHON) def test_init_dont_parse_argv(self): pre_config = { @@ -890,7 +893,7 @@ def test_init_dont_parse_argv(self): 'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], 'program_name': './argv0', } - self.check_config("init_dont_parse_argv", core_config, pre_config, + self.check_config("test_init_dont_parse_argv", core_config, pre_config, api=API_PYTHON) diff --git a/Programs/_testembed.c b/Programs/_testembed.c index a273930e10aef2..7f8ea07ee3e2c6 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1243,39 +1243,39 @@ struct TestCase }; static struct TestCase TestCases[] = { - { "forced_io_encoding", test_forced_io_encoding }, - { "repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters }, - { "pre_initialization_api", test_pre_initialization_api }, - { "pre_initialization_sys_options", test_pre_initialization_sys_options }, - { "bpo20891", test_bpo20891 }, - { "initialize_twice", test_initialize_twice }, - { "initialize_pymain", test_initialize_pymain }, - { "init_initialize_config", test_init_initialize_config }, - { "preinit_compat_config", test_preinit_compat_config }, - { "init_compat_config", test_init_compat_config }, - { "init_global_config", test_init_global_config }, - { "init_from_config", test_init_from_config }, - { "init_parse_argv", test_init_parse_argv }, - { "init_dont_parse_argv", test_init_dont_parse_argv }, - { "init_env", test_init_env }, - { "init_env_dev_mode", test_init_env_dev_mode }, - { "init_env_dev_mode_alloc", test_init_env_dev_mode_alloc }, - { "init_dont_configure_locale", test_init_dont_configure_locale }, - { "init_dev_mode", test_init_dev_mode }, - { "init_isolated_flag", test_init_isolated_flag }, - { "preinit_isolated_config", test_preinit_isolated_config }, - { "init_isolated_config", test_init_isolated_config }, - { "preinit_python_config", test_preinit_python_config }, - { "init_python_config", test_init_python_config }, - { "preinit_isolated1", test_preinit_isolated1 }, - { "preinit_isolated2", test_preinit_isolated2 }, - { "preinit_parse_argv", test_preinit_parse_argv }, - { "preinit_dont_parse_argv", test_preinit_dont_parse_argv }, - { "init_read_set", test_init_read_set }, - { "init_run_main", test_init_run_main }, - { "init_main", test_init_main }, - { "run_main", test_run_main }, - { NULL, NULL } + {"test_forced_io_encoding", test_forced_io_encoding}, + {"test_repeated_init_and_subinterpreters", test_repeated_init_and_subinterpreters}, + {"test_pre_initialization_api", test_pre_initialization_api}, + {"test_pre_initialization_sys_options", test_pre_initialization_sys_options}, + {"test_bpo20891", test_bpo20891}, + {"test_initialize_twice", test_initialize_twice}, + {"test_initialize_pymain", test_initialize_pymain}, + {"test_init_initialize_config", test_init_initialize_config}, + {"test_preinit_compat_config", test_preinit_compat_config}, + {"test_init_compat_config", test_init_compat_config}, + {"test_init_global_config", test_init_global_config}, + {"test_init_from_config", test_init_from_config}, + {"test_init_parse_argv", test_init_parse_argv}, + {"test_init_dont_parse_argv", test_init_dont_parse_argv}, + {"test_init_env", test_init_env}, + {"test_init_env_dev_mode", test_init_env_dev_mode}, + {"test_init_env_dev_mode_alloc", test_init_env_dev_mode_alloc}, + {"test_init_dont_configure_locale", test_init_dont_configure_locale}, + {"test_init_dev_mode", test_init_dev_mode}, + {"test_init_isolated_flag", test_init_isolated_flag}, + {"test_preinit_isolated_config", test_preinit_isolated_config}, + {"test_init_isolated_config", test_init_isolated_config}, + {"test_preinit_python_config", test_preinit_python_config}, + {"test_init_python_config", test_init_python_config}, + {"test_preinit_isolated1", test_preinit_isolated1}, + {"test_preinit_isolated2", test_preinit_isolated2}, + {"test_preinit_parse_argv", test_preinit_parse_argv}, + {"test_preinit_dont_parse_argv", test_preinit_dont_parse_argv}, + {"test_init_read_set", test_init_read_set}, + {"test_init_run_main", test_init_run_main}, + {"test_init_main", test_init_main}, + {"test_run_main", test_run_main}, + {NULL, NULL} }; int main(int argc, char *argv[]) diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 21c386bb4a3edd..1084def9ce03fc 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -447,9 +447,9 @@ _Py_SetLocaleFromEnv(int category) */ static _PyInitError -_Py_Initialize_ReconfigureCore(_PyRuntimeState *runtime, - PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) +pyinit_core_reconfigure(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, + const _PyCoreConfig *core_config) { _PyInitError err; PyThreadState *tstate = _PyThreadState_GET(); @@ -657,9 +657,9 @@ pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) static _PyInitError -_Py_InitializeCore_impl(_PyRuntimeState *runtime, - PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) +pyinit_core_config(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, + const _PyCoreConfig *core_config) { PyInterpreterState *interp; @@ -801,41 +801,6 @@ _Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig, } -static _PyInitError -pyinit_coreconfig(_PyRuntimeState *runtime, - _PyCoreConfig *config, - const _PyCoreConfig *src_config, - const _PyArgv *args, - PyInterpreterState **interp_p) -{ - assert(src_config != NULL); - - _PyInitError err = _PyCoreConfig_Copy(config, src_config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (args) { - err = _PyCoreConfig_SetPyArgv(config, args); - if (_Py_INIT_FAILED(err)) { - return err; - } - } - - err = _PyCoreConfig_Read(config); - if (_Py_INIT_FAILED(err)) { - return err; - } - - if (!runtime->core_initialized) { - return _Py_InitializeCore_impl(runtime, interp_p, config); - } - else { - return _Py_Initialize_ReconfigureCore(runtime, interp_p, config); - } -} - - /* Begin interpreter initialization * * On return, the first thread and interpreter state have been created, @@ -854,10 +819,10 @@ pyinit_coreconfig(_PyRuntimeState *runtime, * safe to call without calling Py_Initialize first) */ static _PyInitError -_Py_InitializeCore(_PyRuntimeState *runtime, - const _PyCoreConfig *src_config, - const _PyArgv *args, - PyInterpreterState **interp_p) +pyinit_core(_PyRuntimeState *runtime, + const _PyCoreConfig *src_config, + const _PyArgv *args, + PyInterpreterState **interp_p) { _PyInitError err; @@ -866,10 +831,38 @@ _Py_InitializeCore(_PyRuntimeState *runtime, return err; } - _PyCoreConfig local_config; - _PyCoreConfig_InitCompatConfig(&local_config); - err = pyinit_coreconfig(runtime, &local_config, src_config, args, interp_p); - _PyCoreConfig_Clear(&local_config); + _PyCoreConfig config; + _PyCoreConfig_InitCompatConfig(&config); + + err = _PyCoreConfig_Copy(&config, src_config); + if (_Py_INIT_FAILED(err)) { + goto done; + } + + if (args) { + err = _PyCoreConfig_SetPyArgv(&config, args); + if (_Py_INIT_FAILED(err)) { + goto done; + } + } + + err = _PyCoreConfig_Read(&config); + if (_Py_INIT_FAILED(err)) { + goto done; + } + + if (!runtime->core_initialized) { + err = pyinit_core_config(runtime, interp_p, &config); + } + else { + err = pyinit_core_reconfigure(runtime, interp_p, &config); + } + if (_Py_INIT_FAILED(err)) { + goto done; + } + +done: + _PyCoreConfig_Clear(&config); return err; } @@ -907,8 +900,7 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * non-zero return code. */ static _PyInitError -_Py_InitializeMainInterpreter(_PyRuntimeState *runtime, - PyInterpreterState *interp) +pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) { if (!runtime->core_initialized) { return _Py_INIT_ERR("runtime core not initialized"); @@ -1015,14 +1007,14 @@ _Py_InitializeMain(void) _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - return _Py_InitializeMainInterpreter(runtime, interp); + return pyinit_main(runtime, interp); } #undef _INIT_DEBUG_PRINT static _PyInitError -init_python(const _PyCoreConfig *config, const _PyArgv *args) +pyinit_python(const _PyCoreConfig *config, const _PyArgv *args) { if (config == NULL) { return _Py_INIT_ERR("initialization config is NULL"); @@ -1037,14 +1029,14 @@ init_python(const _PyCoreConfig *config, const _PyArgv *args) _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = NULL; - err = _Py_InitializeCore(runtime, config, args, &interp); + err = pyinit_core(runtime, config, args, &interp); if (_Py_INIT_FAILED(err)) { return err; } config = &interp->core_config; if (config->_init_main) { - err = _Py_InitializeMainInterpreter(runtime, interp); + err = pyinit_main(runtime, interp); if (_Py_INIT_FAILED(err)) { return err; } @@ -1059,7 +1051,7 @@ _Py_InitializeFromArgs(const _PyCoreConfig *config, Py_ssize_t argc, char * const *argv) { _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; - return init_python(config, &args); + return pyinit_python(config, &args); } @@ -1068,14 +1060,14 @@ _Py_InitializeFromWideArgs(const _PyCoreConfig *config, Py_ssize_t argc, wchar_t * const *argv) { _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; - return init_python(config, &args); + return pyinit_python(config, &args); } _PyInitError _Py_InitializeFromConfig(const _PyCoreConfig *config) { - return init_python(config, NULL); + return pyinit_python(config, NULL); } From df22c03b93ea4620fdf4a0b3cbbbfa7c645af783 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 23 May 2019 01:00:58 +0200 Subject: [PATCH 070/441] bpo-36829: PyErr_WriteUnraisable() normalizes exception (GH-13507) PyErr_WriteUnraisable() now creates a traceback object if there is no current traceback. Moreover, call PyErr_NormalizeException() and PyException_SetTraceback() to normalize the exception value. Ignore silently any error. --- Include/internal/pycore_traceback.h | 4 ++++ Lib/test/test_sys.py | 15 +++++-------- .../2019-05-22-23-01-29.bpo-36829.MfOcUg.rst | 4 ++++ Python/errors.c | 22 ++++++++++++++++++- Python/traceback.c | 15 +++++++++++-- 5 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst diff --git a/Include/internal/pycore_traceback.h b/Include/internal/pycore_traceback.h index a96199bda5f9f3..bf4d7fe5851f96 100644 --- a/Include/internal/pycore_traceback.h +++ b/Include/internal/pycore_traceback.h @@ -86,6 +86,10 @@ PyAPI_FUNC(void) _Py_DumpHexadecimal( unsigned long value, Py_ssize_t width); +PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame( + PyObject *tb_next, + struct _frame *frame); + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 67a952d9b4544c..1e5f168f30bdf1 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -882,19 +882,14 @@ def write_unraisable_exc(self, exc, obj): import _testcapi import types try: - # raise the exception to get a traceback in the except block - try: - raise exc - except Exception as exc2: - _testcapi.write_unraisable_exc(exc2, obj) - return types.SimpleNamespace(exc_type=type(exc2), - exc_value=exc2, - exc_traceback=exc2.__traceback__, - object=obj) + _testcapi.write_unraisable_exc(exc, obj) + return types.SimpleNamespace(exc_type=type(exc), + exc_value=exc, + exc_traceback=exc.__traceback__, + object=obj) finally: # Explicitly break any reference cycle exc = None - exc2 = None def test_original_unraisablehook(self): obj = "an object" diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst new file mode 100644 index 00000000000000..957a4857e408f3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst @@ -0,0 +1,4 @@ +:c:func:`PyErr_WriteUnraisable` now creates a traceback object if there is +no current traceback. Moreover, call :c:func:`PyErr_NormalizeException` and +:c:func:`PyException_SetTraceback` to normalize the exception value. Ignore any +error. diff --git a/Python/errors.c b/Python/errors.c index 9622b5a1067df9..1b8b7eeb0e743f 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_coreconfig.h" #include "pycore_pystate.h" +#include "pycore_traceback.h" #ifndef __STDC__ #ifndef MS_WINDOWS @@ -1048,7 +1049,7 @@ write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, } } - if (!exc_type) { + if (exc_type == NULL || exc_type == Py_None) { return -1; } @@ -1106,6 +1107,7 @@ write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, } } } + if (PyFile_WriteString("\n", file) < 0) { return -1; } @@ -1177,6 +1179,24 @@ PyErr_WriteUnraisable(PyObject *obj) goto default_hook; } + if (exc_tb == NULL) { + struct _frame *frame = _PyThreadState_GET()->frame; + if (frame != NULL) { + exc_tb = _PyTraceBack_FromFrame(NULL, frame); + if (exc_tb == NULL) { + PyErr_Clear(); + } + } + } + + PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); + + if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) { + if (PyException_SetTraceback(exc_value, exc_tb) < 0) { + PyErr_Clear(); + } + } + _Py_IDENTIFIER(unraisablehook); PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); if (hook != NULL && hook != Py_None) { diff --git a/Python/traceback.c b/Python/traceback.c index 18bd0bf7341ffa..04b52ad7680a11 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -227,13 +227,24 @@ PyTypeObject PyTraceBack_Type = { tb_new, /* tp_new */ }; + +PyObject* +_PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) +{ + assert(tb_next == NULL || PyTraceBack_Check(tb_next)); + assert(frame != NULL); + + return tb_create_raw((PyTracebackObject *)tb_next, frame, frame->f_lasti, + PyFrame_GetLineNumber(frame)); +} + + int PyTraceBack_Here(PyFrameObject *frame) { PyObject *exc, *val, *tb, *newtb; PyErr_Fetch(&exc, &val, &tb); - newtb = tb_create_raw((PyTracebackObject *)tb, frame, frame->f_lasti, - PyFrame_GetLineNumber(frame)); + newtb = _PyTraceBack_FromFrame(tb, frame); if (newtb == NULL) { _PyErr_ChainExceptions(exc, val, tb); return -1; From 6bc5917903b722bdd0e5d3020949f26fec5dfe9a Mon Sep 17 00:00:00 2001 From: Alexey Izbyshev Date: Thu, 23 May 2019 03:01:08 +0300 Subject: [PATCH 071/441] =?UTF-8?q?bpo-35091:=20Objects/listobject.c:=20Re?= =?UTF-8?q?place=20overflow=20checks=20in=20gallop=20fu=E2=80=A6=20(GH-102?= =?UTF-8?q?02)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …nctions with asserts The actual overflow can never happen because of the following: * The size of a list can't be greater than PY_SSIZE_T_MAX / sizeof(PyObject*). * The size of a pointer on all supported plaftorms is at least 4 bytes. * ofs is positive and less than the list size at the beginning of each iteration. https://bugs.python.org/issue35091 --- Objects/listobject.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 08b3e89a957fb9..3185957453d721 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1380,9 +1380,8 @@ gallop_left(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_ while (ofs < maxofs) { IFLT(a[ofs], key) { lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); ofs = (ofs << 1) + 1; - if (ofs <= 0) /* int overflow */ - ofs = maxofs; } else /* key <= a[hint + ofs] */ break; @@ -1403,9 +1402,8 @@ gallop_left(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize_ break; /* key <= a[hint - ofs] */ lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); ofs = (ofs << 1) + 1; - if (ofs <= 0) /* int overflow */ - ofs = maxofs; } if (ofs > maxofs) ofs = maxofs; @@ -1471,9 +1469,8 @@ gallop_right(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize while (ofs < maxofs) { IFLT(key, *(a-ofs)) { lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); ofs = (ofs << 1) + 1; - if (ofs <= 0) /* int overflow */ - ofs = maxofs; } else /* a[hint - ofs] <= key */ break; @@ -1495,9 +1492,8 @@ gallop_right(MergeState *ms, PyObject *key, PyObject **a, Py_ssize_t n, Py_ssize break; /* a[hint + ofs] <= key */ lastofs = ofs; + assert(ofs <= (PY_SSIZE_T_MAX - 1) / 2); ofs = (ofs << 1) + 1; - if (ofs <= 0) /* int overflow */ - ofs = maxofs; } if (ofs > maxofs) ofs = maxofs; From ef5bb25e2d6147cd44be9c9b166525fb30485be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= <47358913+isidentical@users.noreply.github.com> Date: Thu, 23 May 2019 04:13:16 +0300 Subject: [PATCH 072/441] bpo-27737: Allow whitespace only headers encoding (#13478) --- Lib/email/header.py | 2 +- Lib/test/test_email/test_email.py | 3 +++ .../next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst diff --git a/Lib/email/header.py b/Lib/email/header.py index 7b30a039da1c46..4ab0032bc66123 100644 --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -431,7 +431,7 @@ def newline(self): if end_of_line != (' ', ''): self._current_line.push(*end_of_line) if len(self._current_line) > 0: - if self._current_line.is_onlyws(): + if self._current_line.is_onlyws() and self._lines: self._lines[-1] += str(self._current_line) else: self._lines.append(str(self._current_line)) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 621754cf753daa..dfb3be84384a8b 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -4964,6 +4964,9 @@ def test_encode_preserves_leading_ws_on_value(self): msg['SomeHeader'] = ' value with leading ws' self.assertEqual(str(msg), "SomeHeader: value with leading ws\n\n") + def test_whitespace_header(self): + self.assertEqual(Header(' ').encode(), ' ') + # Test RFC 2231 header parameters (en/de)coding diff --git a/Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst b/Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst new file mode 100644 index 00000000000000..02d0ef891becde --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst @@ -0,0 +1,2 @@ +Allow whitespace only header encoding in ``email.header`` - by Batuhan +Taskaya From 0a8e57248b913851640c64375600f05157c997df Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 23 May 2019 03:30:23 +0200 Subject: [PATCH 073/441] bpo-36721: Add --embed option to python-config (GH-13500) To embed Python into an application, a new --embed option must be passed to "python3-config --libs --embed" to get "-lpython3.8" (link the application to libpython). To support both 3.8 and older, try "python3-config --libs --embed" first and fallback to "python3-config --libs" (without --embed) if the previous command fails. Add a pkg-config "python-3.8-embed" module to embed Python into an application: "pkg-config python-3.8-embed --libs" includes "-lpython3.8". To support both 3.8 and older, try "pkg-config python-X.Y-embed --libs" first and fallback to "pkg-config python-X.Y --libs" (without --embed) if the previous command fails (replace "X.Y" with the Python version). On the other hand, "pkg-config python3.8 --libs" no longer contains "-lpython3.8". C extensions must not be linked to libpython (except on Android, case handled by the script); this change is backward incompatible on purpose. "make install" now also installs "python-3.8-embed.pc". --- .gitignore | 1 + Doc/whatsnew/3.8.rst | 18 ++++++++++++++++++ Makefile.pre.in | 7 ++++++- .../2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst | 16 ++++++++++++++++ Misc/python-config.in | 12 +++++++++--- Misc/python-config.sh.in | 9 +++++++++ Misc/python-embed.pc.in | 13 +++++++++++++ Misc/python.pc.in | 6 +++--- configure | 3 ++- configure.ac | 2 +- 10 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst create mode 100644 Misc/python-embed.pc.in diff --git a/.gitignore b/.gitignore index e3c5809579239c..9445ef1e2c5252 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ Lib/test/data/* Makefile Makefile.pre Misc/python.pc +Misc/python-embed.pc Misc/python-config.sh Modules/Setup Modules/Setup.config diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 68843e2d9ed157..8c2b40de1142f5 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -149,6 +149,24 @@ extensions compiled in release mode and for C extensions compiled with the stable ABI. (Contributed by Victor Stinner in :issue:`36722`.) +To embed Python into an application, a new ``--embed`` option must be passed to +``python3-config --libs --embed`` to get ``-lpython3.8`` (link the application +to libpython). To support both 3.8 and older, try ``python3-config --libs +--embed`` first and fallback to ``python3-config --libs`` (without ``--embed``) +if the previous command fails. + +Add a pkg-config ``python-3.8-embed`` module to embed Python into an +application: ``pkg-config python-3.8-embed --libs`` includes ``-lpython3.8``. +To support both 3.8 and older, try ``pkg-config python-X.Y-embed --libs`` first +and fallback to ``pkg-config python-X.Y --libs`` (without ``--embed``) if the +previous command fails (replace ``X.Y`` with the Python version). + +On the other hand, ``pkg-config python3.8 --libs`` no longer contains +``-lpython3.8``. C extensions must not be linked to libpython (except on +Android, case handled by the script); this change is backward incompatible on +purpose. +(Contributed by Victor Stinner in :issue:`36721`.) + f-strings now support = for quick and easy debugging ----------------------------------------------------- diff --git a/Makefile.pre.in b/Makefile.pre.in index 9f70cd515ebaba..d006a73c38bed6 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1258,11 +1258,15 @@ bininstall: altbininstall (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(LDVERSION)-config python$(VERSION)-config); \ rm -f $(DESTDIR)$(LIBPC)/python-$(LDVERSION).pc; \ (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python-$(LDVERSION).pc); \ + rm -f $(DESTDIR)$(LIBPC)/python-embed-$(LDVERSION).pc; \ + (cd $(DESTDIR)$(LIBPC); $(LN) -s python-embed-$(VERSION).pc python-embed-$(LDVERSION).pc); \ fi -rm -f $(DESTDIR)$(BINDIR)/python3-config (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python3-config) -rm -f $(DESTDIR)$(LIBPC)/python3.pc (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python3.pc) + -rm -f $(DESTDIR)$(LIBPC)/python3-embed.pc + (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION)-embed.pc python3-embed.pc) -rm -f $(DESTDIR)$(BINDIR)/idle3 (cd $(DESTDIR)$(BINDIR); $(LN) -s idle$(VERSION) idle3) -rm -f $(DESTDIR)$(BINDIR)/pydoc3 @@ -1552,6 +1556,7 @@ libainstall: @DEF_MAKE_RULE@ python-config $(INSTALL_DATA) $(srcdir)/Modules/Setup $(DESTDIR)$(LIBPL)/Setup $(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local $(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION).pc + $(INSTALL_DATA) Misc/python-embed.pc $(DESTDIR)$(LIBPC)/python-$(VERSION)-embed.pc $(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh $(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py @@ -1766,7 +1771,7 @@ distclean: clobber done -rm -f core Makefile Makefile.pre config.status Modules/Setup.local \ Modules/ld_so_aix Modules/python.exp Misc/python.pc \ - Misc/python-config.sh + Misc/python-embed.pc Misc/python-config.sh -rm -f python*-gdb.py # Issue #28258: set LC_ALL to avoid issues with Estonian locale. # Expansion is performed here by shell (spawned by make) itself before diff --git a/Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst b/Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst new file mode 100644 index 00000000000000..1c266586a33b76 --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst @@ -0,0 +1,16 @@ +To embed Python into an application, a new ``--embed`` option must be passed to +``python3-config --libs --embed`` to get ``-lpython3.8`` (link the application +to libpython). To support both 3.8 and older, try ``python3-config --libs +--embed`` first and fallback to ``python3-config --libs`` (without ``--embed``) +if the previous command fails. + +Add a pkg-config ``python-3.8-embed`` module to embed Python into an +application: ``pkg-config python-3.8-embed --libs`` includes ``-lpython3.8``. +To support both 3.8 and older, try ``pkg-config python-X.Y-embed --libs`` first +and fallback to ``pkg-config python-X.Y --libs`` (without ``--embed``) if the +previous command fails (replace ``X.Y`` with the Python version). + +On the other hand, ``pkg-config python3.8 --libs`` no longer contains +``-lpython3.8``. C extensions must not be linked to libpython (except on +Android, case handled by the script); this change is backward incompatible on +purpose. diff --git a/Misc/python-config.in b/Misc/python-config.in index 1df30d261d8ebb..727c4a8682270f 100644 --- a/Misc/python-config.in +++ b/Misc/python-config.in @@ -9,7 +9,8 @@ import sys import sysconfig valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', - 'ldflags', 'extension-suffix', 'help', 'abiflags', 'configdir'] + 'ldflags', 'extension-suffix', 'help', 'abiflags', 'configdir', + 'embed'] def exit_with_usage(code=1): print("Usage: {0} [{1}]".format( @@ -47,8 +48,13 @@ for opt in opt_flags: print(' '.join(flags)) elif opt in ('--libs', '--ldflags'): - libpython = getvar('LIBPYTHON') - libs = [libpython] if libpython else [] + libs = [] + if '--embed' in opt_flags: + libs.append('-lpython' + pyver + sys.abiflags) + else: + libpython = getvar('LIBPYTHON') + if libpython: + libs.append(libpython) libs.extend(getvar('LIBS').split() + getvar('SYSLIBS').split()) # add the prefix/lib/pythonX.Y/config dir, but only if there is no diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in index 33991ef0c5d49a..59101d5a5580b5 100644 --- a/Misc/python-config.sh.in +++ b/Misc/python-config.sh.in @@ -42,6 +42,7 @@ LIBC="@LIBC@" SYSLIBS="$LIBM $LIBC" ABIFLAGS="@ABIFLAGS@" LIBS="@LIBPYTHON@ @LIBS@ $SYSLIBS" +LIBS_EMBED="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" BASECFLAGS="@BASECFLAGS@" LDLIBRARY="@LDLIBRARY@" OPT="@OPT@" @@ -53,6 +54,7 @@ SO="@EXT_SUFFIX@" PYTHONFRAMEWORK="@PYTHONFRAMEWORK@" INCDIR="-I$includedir/python${VERSION}${ABIFLAGS}" PLATINCDIR="-I$includedir/python${VERSION}${ABIFLAGS}" +PY_EMBED=0 # Scan for --help or unknown argument. for ARG in $* @@ -61,6 +63,9 @@ do --help) exit_with_usage 0 ;; + --embed) + PY_EMBED=1 + ;; --prefix|--exec-prefix|--includes|--libs|--cflags|--ldflags|--extension-suffix|--abiflags|--configdir) ;; *) @@ -69,6 +74,10 @@ do esac done +if [ $PY_EMBED = 1 ] ; then + LIBS="$LIBS_EMBED" +fi + for ARG in "$@" do case "$ARG" in diff --git a/Misc/python-embed.pc.in b/Misc/python-embed.pc.in new file mode 100644 index 00000000000000..2be9df8143fa1a --- /dev/null +++ b/Misc/python-embed.pc.in @@ -0,0 +1,13 @@ +# See: man pkg-config +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Python +Description: Embed Python into an application +Requires: +Version: @VERSION@ +Libs.private: @LIBS@ +Libs: -L${libdir} -lpython@VERSION@@ABIFLAGS@ +Cflags: -I${includedir}/python@VERSION@@ABIFLAGS@ diff --git a/Misc/python.pc.in b/Misc/python.pc.in index ae698674bbc8ad..87e04decc2a2d5 100644 --- a/Misc/python.pc.in +++ b/Misc/python.pc.in @@ -5,9 +5,9 @@ libdir=@libdir@ includedir=@includedir@ Name: Python -Description: Python library -Requires: +Description: Build a C extension for Python +Requires: Version: @VERSION@ Libs.private: @LIBS@ -Libs: -L${libdir} -lpython@VERSION@@ABIFLAGS@ +Libs: Cflags: -I${includedir}/python@VERSION@@ABIFLAGS@ diff --git a/configure b/configure index a0767b97136308..72889b9d2efcdf 100755 --- a/configure +++ b/configure @@ -17315,7 +17315,7 @@ fi # generate output files -ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-config.sh" +ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh" ac_config_files="$ac_config_files Modules/ld_so_aix" @@ -18018,6 +18018,7 @@ do "Mac/Resources/app/Info.plist") CONFIG_FILES="$CONFIG_FILES Mac/Resources/app/Info.plist" ;; "Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;; "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; + "Misc/python-embed.pc") CONFIG_FILES="$CONFIG_FILES Misc/python-embed.pc" ;; "Misc/python-config.sh") CONFIG_FILES="$CONFIG_FILES Misc/python-config.sh" ;; "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;; diff --git a/configure.ac b/configure.ac index 3a915eb5577c28..f548d644327a59 100644 --- a/configure.ac +++ b/configure.ac @@ -5589,7 +5589,7 @@ AC_DEFINE(PY_SSL_DEFAULT_CIPHERS, 1) # generate output files -AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-config.sh) +AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh) AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) AC_OUTPUT From bc2aa816620c5e02ad8e94d8514b7e8f3f551ca1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 23 May 2019 03:45:09 +0200 Subject: [PATCH 074/441] bpo-18748: _pyio.IOBase emits unraisable exception (GH-13512) In development (-X dev) mode and in a debug build, IOBase finalizer of the _pyio module now logs the exception if the close() method fails. The exception is ignored silently by default in release build. test_io: test_error_through_destructor() now uses support.catch_unraisable_exception() rather than capturing stderr. --- Doc/whatsnew/3.8.rst | 9 +++++++ Lib/_pyio.py | 23 ++++++++++------ Lib/test/test_io.py | 64 +++++++++++++++++++------------------------- 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 8c2b40de1142f5..b91f7bca63c9f2 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -318,6 +318,15 @@ for :func:`property`, :func:`classmethod`, and :func:`staticmethod`:: self.bit_rate = round(bit_rate / 1000.0, 1) self.duration = ceil(duration) +io +-- + +In development mode (:option:`-X` ``env``) and in debug build, the +:class:`io.IOBase` finalizer now logs the exception if the ``close()`` method +fails. The exception is ignored silently by default in release build. +(Contributed by Victor Stinner in :issue:`18748`.) + + gc -- diff --git a/Lib/_pyio.py b/Lib/_pyio.py index af2ce30c278062..be5e4266daffd8 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -33,6 +33,10 @@ # Rebind for compatibility BlockingIOError = BlockingIOError +# Does io.IOBase finalizer log the exception if the close() method fails? +# The exception is ignored silently by default in release build. +_IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) + def open(file, mode="r", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None): @@ -378,15 +382,18 @@ def close(self): def __del__(self): """Destructor. Calls close().""" - # The try/except block is in case this is called at program - # exit time, when it's possible that globals have already been - # deleted, and then the close() call might fail. Since - # there's nothing we can do about such failures and they annoy - # the end users, we suppress the traceback. - try: + if _IOBASE_EMITS_UNRAISABLE: self.close() - except: - pass + else: + # The try/except block is in case this is called at program + # exit time, when it's possible that globals have already been + # deleted, and then the close() call might fail. Since + # there's nothing we can do about such failures and they annoy + # the end users, we suppress the traceback. + try: + self.close() + except: + pass ### Inquiries ### diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index dc44e506b1d0f4..2c3bf890667997 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -67,9 +67,9 @@ class EmptyStruct(ctypes.Structure): '--with-memory-sanitizer' in _config_args ) -# Does io.IOBase logs unhandled exceptions on calling close()? -# They are silenced by default in release build. -DESTRUCTOR_LOG_ERRORS = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) +# Does io.IOBase finalizer log the exception if the close() method fails? +# The exception is ignored silently by default in release build. +IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) def _default_chunk_size(): @@ -1098,23 +1098,18 @@ def test_error_through_destructor(self): # Test that the exception state is not modified by a destructor, # even if close() fails. rawio = self.CloseFailureIO() - def f(): - self.tp(rawio).xyzzy - with support.captured_output("stderr") as s: - self.assertRaises(AttributeError, f) - s = s.getvalue().strip() - if s: - # The destructor *may* have printed an unraisable error, check it - lines = s.splitlines() - if DESTRUCTOR_LOG_ERRORS: - self.assertEqual(len(lines), 5) - self.assertTrue(lines[0].startswith("Exception ignored in: "), lines) - self.assertEqual(lines[1], "Traceback (most recent call last):", lines) - self.assertEqual(lines[4], 'OSError:', lines) - else: - self.assertEqual(len(lines), 1) - self.assertTrue(lines[-1].startswith("Exception OSError: "), lines) - self.assertTrue(lines[-1].endswith(" ignored"), lines) + try: + with support.catch_unraisable_exception() as cm: + with self.assertRaises(AttributeError): + self.tp(rawio).xyzzy + + if not IOBASE_EMITS_UNRAISABLE: + self.assertIsNone(cm.unraisable) + elif cm.unraisable is not None: + self.assertEqual(cm.unraisable.exc_type, OSError) + finally: + # Explicitly break reference cycle + cm = None def test_repr(self): raw = self.MockRawIO() @@ -2859,23 +2854,18 @@ def test_error_through_destructor(self): # Test that the exception state is not modified by a destructor, # even if close() fails. rawio = self.CloseFailureIO() - def f(): - self.TextIOWrapper(rawio).xyzzy - with support.captured_output("stderr") as s: - self.assertRaises(AttributeError, f) - s = s.getvalue().strip() - if s: - # The destructor *may* have printed an unraisable error, check it - lines = s.splitlines() - if DESTRUCTOR_LOG_ERRORS: - self.assertEqual(len(lines), 5) - self.assertTrue(lines[0].startswith("Exception ignored in: "), lines) - self.assertEqual(lines[1], "Traceback (most recent call last):", lines) - self.assertEqual(lines[4], 'OSError:', lines) - else: - self.assertEqual(len(lines), 1) - self.assertTrue(lines[-1].startswith("Exception OSError: "), lines) - self.assertTrue(lines[-1].endswith(" ignored"), lines) + try: + with support.catch_unraisable_exception() as cm: + with self.assertRaises(AttributeError): + self.TextIOWrapper(rawio).xyzzy + + if not IOBASE_EMITS_UNRAISABLE: + self.assertIsNone(cm.unraisable) + elif cm.unraisable is not None: + self.assertEqual(cm.unraisable.exc_type, OSError) + finally: + # Explicitly break reference cycle + cm = None # Systematic tests of the text I/O API From 20e1e2582e5e69e43af88ff58699c8883d146acb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 23 May 2019 04:12:27 +0200 Subject: [PATCH 075/441] bpo-36763: Fix _PyPreConfig_InitCompatConfig() utf8_mode (GH-13518) * _PyPreConfig_InitCompatConfig() sets utf8_mode to 0. * Change Py_UTF8Mode default value to 0. * Fix _PyPreConfig_Copy(): copy also _config_init attrbibute. * _PyPreConfig_AsDict() exports _config_init * Fix _PyPreConfig_GetGlobalConfig(): use Py_UTF8Mode if it's greater than 0, even if utf8_mode >= 0. * Add unit tests on environment variables using Python API. --- Lib/test/test_embed.py | 38 ++++++++++++++++++++++++++++++++++---- Programs/_testembed.c | 28 ++++++++++++++++++++++++++-- Python/coreconfig.c | 5 ++--- Python/preconfig.c | 17 +++++++++++++++-- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index bd0451a43b95bc..32aabe30a5c8c3 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -287,6 +287,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): IGNORE_CONFIG = object() PRE_CONFIG_COMPAT = { + '_config_init': API_COMPAT, 'allocator': PYMEM_ALLOCATOR_NOT_SET, 'parse_argv': 0, 'configure_locale': 1, @@ -299,11 +300,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'legacy_windows_fs_encoding': 0, }) PRE_CONFIG_PYTHON = dict(PRE_CONFIG_COMPAT, + _config_init=API_PYTHON, parse_argv=1, coerce_c_locale=GET_DEFAULT_CONFIG, utf8_mode=GET_DEFAULT_CONFIG, ) PRE_CONFIG_ISOLATED = dict(PRE_CONFIG_COMPAT, + _config_init=API_ISOLATED, configure_locale=0, isolated=1, use_environment=0, @@ -388,10 +391,12 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): }) CORE_CONFIG_PYTHON = dict(CORE_CONFIG_COMPAT, + _config_init=API_PYTHON, configure_c_stdio=1, parse_argv=1, ) CORE_CONFIG_ISOLATED = dict(CORE_CONFIG_COMPAT, + _config_init=API_ISOLATED, isolated=1, use_environment=0, user_site_directory=0, @@ -611,7 +616,6 @@ def check_config(self, testname, expected_config=None, else: default_config = self.CORE_CONFIG_COMPAT expected_config = dict(default_config, **expected_config) - expected_config['_config_init'] = api self.get_expected_config(expected_preconfig, expected_config, env, @@ -708,10 +712,9 @@ def test_init_from_config(self): self.check_config("test_init_from_config", config, preconfig, api=API_COMPAT) - def test_init_env(self): + def test_init_compat_env(self): preconfig = { 'allocator': PYMEM_ALLOCATOR_MALLOC, - 'utf8_mode': 1, } config = { 'use_hash_seed': 1, @@ -732,9 +735,36 @@ def test_init_env(self): 'faulthandler': 1, 'warnoptions': ['EnvVar'], } - self.check_config("test_init_env", config, preconfig, + self.check_config("test_init_compat_env", config, preconfig, api=API_COMPAT) + def test_init_python_env(self): + preconfig = { + 'allocator': PYMEM_ALLOCATOR_MALLOC, + 'utf8_mode': 1, + } + config = { + 'use_hash_seed': 1, + 'hash_seed': 42, + 'tracemalloc': 2, + 'import_time': 1, + 'malloc_stats': 1, + 'inspect': 1, + 'optimization_level': 2, + 'module_search_path_env': '/my/path', + 'pycache_prefix': 'env_pycache_prefix', + 'write_bytecode': 0, + 'verbose': 1, + 'buffered_stdio': 0, + 'stdio_encoding': 'iso8859-1', + 'stdio_errors': 'replace', + 'user_site_directory': 0, + 'faulthandler': 1, + 'warnoptions': ['EnvVar'], + } + self.check_config("test_init_python_env", config, preconfig, + api=API_PYTHON) + def test_init_env_dev_mode(self): preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG) config = dict(dev_mode=1, diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 7f8ea07ee3e2c6..6bd55deab4012a 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -638,7 +638,7 @@ static void set_all_env_vars(void) } -static int test_init_env(void) +static int test_init_compat_env(void) { /* Test initialization from environment variables */ Py_IgnoreEnvironmentFlag = 0; @@ -650,6 +650,29 @@ static int test_init_env(void) } +static int test_init_python_env(void) +{ + _PyInitError err; + + set_all_env_vars(); + + _PyCoreConfig config; + err = _PyCoreConfig_InitPythonConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } + config.program_name = L"./_testembed"; + + err = _Py_InitializeFromConfig(&config); + if (_PyInitError_Failed(err)) { + _Py_ExitInitError(err); + } + dump_config(); + Py_Finalize(); + return 0; +} + + static void set_all_env_vars_dev_mode(void) { putenv("PYTHONMALLOC="); @@ -1257,7 +1280,8 @@ static struct TestCase TestCases[] = { {"test_init_from_config", test_init_from_config}, {"test_init_parse_argv", test_init_parse_argv}, {"test_init_dont_parse_argv", test_init_dont_parse_argv}, - {"test_init_env", test_init_env}, + {"test_init_compat_env", test_init_compat_env}, + {"test_init_python_env", test_init_python_env}, {"test_init_env_dev_mode", test_init_env_dev_mode}, {"test_init_env_dev_mode_alloc", test_init_env_dev_mode_alloc}, {"test_init_dont_configure_locale", test_init_dont_configure_locale}, diff --git a/Python/coreconfig.c b/Python/coreconfig.c index 40dba4ee5e5e54..89ccff4c9b762e 100644 --- a/Python/coreconfig.c +++ b/Python/coreconfig.c @@ -107,9 +107,8 @@ static const char usage_6[] = /* --- Global configuration variables ----------------------------- */ /* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change - stdin and stdout error handler to "surrogateescape". It is equal to - -1 by default: unknown, will be set by Py_Main() */ -int Py_UTF8Mode = -1; + stdin and stdout error handler to "surrogateescape". */ +int Py_UTF8Mode = 0; int Py_DebugFlag = 0; /* Needed by parser.c */ int Py_VerboseFlag = 0; /* Needed by import.c */ int Py_QuietFlag = 0; /* Needed by sysmodule.c */ diff --git a/Python/preconfig.c b/Python/preconfig.c index 392324ff201a33..a6d1346eb4e1f7 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -272,7 +272,16 @@ _PyPreConfig_InitCompatConfig(_PyPreConfig *config) config->isolated = -1; config->use_environment = -1; config->configure_locale = 1; - config->utf8_mode = -1; + + /* bpo-36443: C locale coercion (PEP 538) and UTF-8 Mode (PEP 540) + are disabled by default using the Compat configuration. + + Py_UTF8Mode=1 enables the UTF-8 mode. PYTHONUTF8 environment variable + is ignored (even if use_environment=1). */ + config->utf8_mode = 0; + config->coerce_c_locale = 0; + config->coerce_c_locale_warn = 0; + config->dev_mode = -1; config->allocator = PYMEM_ALLOCATOR_NOT_SET; #ifdef MS_WINDOWS @@ -353,6 +362,7 @@ _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) { #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR + COPY_ATTR(_config_init); COPY_ATTR(parse_argv); COPY_ATTR(isolated); COPY_ATTR(use_environment); @@ -393,6 +403,7 @@ _PyPreConfig_AsDict(const _PyPreConfig *config) } \ } while (0) + SET_ITEM_INT(_config_init); SET_ITEM_INT(parse_argv); SET_ITEM_INT(isolated); SET_ITEM_INT(use_environment); @@ -452,7 +463,9 @@ _PyPreConfig_GetGlobalConfig(_PyPreConfig *config) COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); - COPY_FLAG(utf8_mode, Py_UTF8Mode); + if (Py_UTF8Mode > 0) { + config->utf8_mode = Py_UTF8Mode; + } #ifdef MS_WINDOWS COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); #endif From 51aa35e9e17eef60d04add9619fe2a7eb938358c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 23 May 2019 04:32:44 +0000 Subject: [PATCH 076/441] bpo-33164: update blake2 implementation (GH-6286) --- .../2018-03-30-12-26-47.bpo-33164.aO29Cx.rst | 1 + Modules/_blake2/impl/blake2-config.h | 23 +- Modules/_blake2/impl/blake2-dispatch.c | 577 + Modules/_blake2/impl/blake2-impl.h | 80 +- Modules/_blake2/impl/blake2-kat.h | 16467 ++++++++++++++++ Modules/_blake2/impl/blake2.h | 191 +- Modules/_blake2/impl/blake2b-load-sse2.h | 20 +- Modules/_blake2/impl/blake2b-load-sse41.h | 20 +- Modules/_blake2/impl/blake2b-ref.c | 181 +- Modules/_blake2/impl/blake2b-round.h | 27 +- Modules/_blake2/impl/blake2b-test.c | 43 + Modules/_blake2/impl/blake2b.c | 222 +- Modules/_blake2/impl/blake2bp-test.c | 44 + Modules/_blake2/impl/blake2bp.c | 274 + Modules/_blake2/impl/blake2s-load-sse2.h | 20 +- Modules/_blake2/impl/blake2s-load-sse41.h | 20 +- Modules/_blake2/impl/blake2s-load-xop.h | 30 +- Modules/_blake2/impl/blake2s-ref.c | 195 +- Modules/_blake2/impl/blake2s-round.h | 27 +- Modules/_blake2/impl/blake2s-test.c | 43 + Modules/_blake2/impl/blake2s.c | 215 +- Modules/_blake2/impl/blake2sp-test.c | 43 + Modules/_blake2/impl/blake2sp.c | 274 + aclocal.m4 | 10 +- configure | 4 +- configure.ac | 4 +- pyconfig.h.in | 9 + 27 files changed, 18379 insertions(+), 685 deletions(-) create mode 100644 Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst create mode 100644 Modules/_blake2/impl/blake2-dispatch.c create mode 100644 Modules/_blake2/impl/blake2-kat.h create mode 100644 Modules/_blake2/impl/blake2b-test.c create mode 100644 Modules/_blake2/impl/blake2bp-test.c create mode 100644 Modules/_blake2/impl/blake2bp.c create mode 100644 Modules/_blake2/impl/blake2s-test.c create mode 100644 Modules/_blake2/impl/blake2sp-test.c create mode 100644 Modules/_blake2/impl/blake2sp.c diff --git a/Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst b/Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst new file mode 100644 index 00000000000000..654494cb349815 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst @@ -0,0 +1 @@ +Updated blake2 implementation which uses secure memset implementation provided by platform. diff --git a/Modules/_blake2/impl/blake2-config.h b/Modules/_blake2/impl/blake2-config.h index 40455b120ff051..f5dd6faa9e6867 100644 --- a/Modules/_blake2/impl/blake2-config.h +++ b/Modules/_blake2/impl/blake2-config.h @@ -1,23 +1,20 @@ /* BLAKE2 reference source code package - optimized C implementations - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: + Written in 2012 by Samuel Neves - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. - More information about the BLAKE2 hash function can be found at - https://blake2.net. + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2_CONFIG_H__ #define __BLAKE2_CONFIG_H__ -/* These don't work everywhere */ -#if defined(__SSE2__) || defined(__x86_64__) || defined(__amd64__) +#if defined(__SSE2__) #define HAVE_SSE2 #endif @@ -26,7 +23,7 @@ #endif #if defined(__SSE4_1__) -#define HAVE_SSE41 +#define HAVE_SSE4_1 #endif #if defined(__AVX__) @@ -51,8 +48,8 @@ #endif #ifdef HAVE_AVX -#ifndef HAVE_SSE41 -#define HAVE_SSE41 +#ifndef HAVE_SSE4_1 +#define HAVE_SSE4_1 #endif #endif diff --git a/Modules/_blake2/impl/blake2-dispatch.c b/Modules/_blake2/impl/blake2-dispatch.c new file mode 100644 index 00000000000000..96bb3408bb1e20 --- /dev/null +++ b/Modules/_blake2/impl/blake2-dispatch.c @@ -0,0 +1,577 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +#include +#if defined(WIN32) +#include +#endif +#include "blake2.h" + +#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64) +#define HAVE_X86 +#endif + +typedef enum +{ + NONE = 0, +#if defined(HAVE_X86) + SSE2 = 1, + SSSE3 = 2, + SSE41 = 3, + AVX = 4, + XOP = 5, + /* AVX2 = 6, */ +#endif +} cpu_feature_t; + +static const char feature_names[][8] = +{ + "none", +#if defined(HAVE_X86) + "sse2", + "ssse3", + "sse41", + "avx", + "xop", + /* "avx2" */ +#endif +}; + +#if defined(HAVE_X86) + +#if defined(__GNUC__) +static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) +{ + __asm__ __volatile__( +#if defined(__i386__) /* This is needed for -fPIC to work on i386 */ + "movl %%ebx, %%esi\n\t" +#endif + "cpuid\n\t" +#if defined(__i386__) + "xchgl %%ebx, %%esi\n\t" + : "=a"( *eax ), "=S"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); +#else + : "=a"( *eax ), "=b"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) ); +#endif +} + +static inline uint64_t xgetbv(uint32_t xcr) +{ + uint32_t a, d; + __asm__ __volatile__( + "xgetbv" + : "=a"(a),"=d"(d) + : "c"(xcr) + ); + return ((uint64_t)d << 32) | a; +} + +#elif defined(_MSC_VER) +#include +static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx ) +{ + int regs[4]; + __cpuid( regs, *eax ); + *eax = regs[0]; + *ebx = regs[1]; + *ecx = regs[2]; + *edx = regs[3]; +} +#else +#error "Don't know how to call cpuid on this compiler!" +#endif + +#endif /* HAVE_X86 */ + +static inline cpu_feature_t get_cpu_features( void ) +{ +#if defined(HAVE_X86) + static volatile int initialized = 0; + static cpu_feature_t feature = NONE; // Safe default + uint32_t eax, ecx, edx, ebx; + + if( initialized ) + return feature; + + eax = 1; + cpuid( &eax, &ebx, &ecx, &edx ); + + if( 1 & ( edx >> 26 ) ) + feature = SSE2; + + if( 1 & ( ecx >> 9 ) ) + feature = SSSE3; + + if( 1 & ( ecx >> 19 ) ) + feature = SSE41; + +#if defined(WIN32) /* Work around the fact that Windows <7 does NOT support AVX... */ + if( IsProcessorFeaturePresent(17) ) /* Some environments don't know about PF_XSAVE_ENABLED */ +#endif + { + /* check for AVX and OSXSAVE bits */ + if( 1 & ( ecx >> 28 ) & (ecx >> 27) ) { +#if !defined(WIN32) /* Already checked for this in WIN32 */ + if( (xgetbv(0) & 6) == 6 ) /* XCR0 */ +#endif + feature = AVX; + } + + + eax = 0x80000001; + cpuid( &eax, &ebx, &ecx, &edx ); + + if( 1 & ( ecx >> 11 ) ) + feature = XOP; + } + + /* For future architectures */ + /* + eax = 7; ecx = 0; + cpuid(&eax, &ebx, &ecx, &edx); + + if(1&(ebx >> 5)) + feature = AVX2; + */ + /* fprintf( stderr, "Using %s engine\n", feature_names[feature] ); */ + initialized = 1; + return feature; +#else + return NONE; +#endif +} + + + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init_ref( blake2b_state *S, size_t outlen ); + int blake2b_init_key_ref( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_ref( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_ref( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_ref( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#if defined(HAVE_X86) + + int blake2b_init_sse2( blake2b_state *S, size_t outlen ); + int blake2b_init_key_sse2( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_sse2( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_sse2( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_sse2( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_ssse3( blake2b_state *S, size_t outlen ); + int blake2b_init_key_ssse3( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_ssse3( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_ssse3( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_ssse3( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_sse41( blake2b_state *S, size_t outlen ); + int blake2b_init_key_sse41( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_sse41( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_sse41( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_sse41( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_avx( blake2b_state *S, size_t outlen ); + int blake2b_init_key_avx( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_avx( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_avx( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_avx( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2b_init_xop( blake2b_state *S, size_t outlen ); + int blake2b_init_key_xop( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_xop( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_xop( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_xop( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#endif /* HAVE_X86 */ + + int blake2s_init_ref( blake2s_state *S, size_t outlen ); + int blake2s_init_key_ref( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_ref( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_ref( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_ref( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#if defined(HAVE_X86) + + int blake2s_init_sse2( blake2s_state *S, size_t outlen ); + int blake2s_init_key_sse2( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_sse2( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_sse2( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_sse2( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_ssse3( blake2s_state *S, size_t outlen ); + int blake2s_init_key_ssse3( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_ssse3( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_ssse3( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_ssse3( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_sse41( blake2s_state *S, size_t outlen ); + int blake2s_init_key_sse41( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_sse41( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_sse41( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_sse41( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_avx( blake2s_state *S, size_t outlen ); + int blake2s_init_key_avx( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_avx( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_avx( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_avx( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_xop( blake2s_state *S, size_t outlen ); + int blake2s_init_key_xop( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_xop( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_xop( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_xop( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + +#endif /* HAVE_X86 */ + +#if defined(__cplusplus) +} +#endif + +typedef int ( *blake2b_init_fn )( blake2b_state *, size_t ); +typedef int ( *blake2b_init_key_fn )( blake2b_state *, size_t, const void *, size_t ); +typedef int ( *blake2b_init_param_fn )( blake2b_state *, const blake2b_param * ); +typedef int ( *blake2b_update_fn )( blake2b_state *, const uint8_t *, size_t ); +typedef int ( *blake2b_final_fn )( blake2b_state *, uint8_t *, size_t ); +typedef int ( *blake2b_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); + +typedef int ( *blake2s_init_fn )( blake2s_state *, size_t ); +typedef int ( *blake2s_init_key_fn )( blake2s_state *, size_t, const void *, size_t ); +typedef int ( *blake2s_init_param_fn )( blake2s_state *, const blake2s_param * ); +typedef int ( *blake2s_update_fn )( blake2s_state *, const uint8_t *, size_t ); +typedef int ( *blake2s_final_fn )( blake2s_state *, uint8_t *, size_t ); +typedef int ( *blake2s_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t ); + +static const blake2b_init_fn blake2b_init_table[] = +{ + blake2b_init_ref, +#if defined(HAVE_X86) + blake2b_init_sse2, + blake2b_init_ssse3, + blake2b_init_sse41, + blake2b_init_avx, + blake2b_init_xop +#endif +}; + +static const blake2b_init_key_fn blake2b_init_key_table[] = +{ + blake2b_init_key_ref, +#if defined(HAVE_X86) + blake2b_init_key_sse2, + blake2b_init_key_ssse3, + blake2b_init_key_sse41, + blake2b_init_key_avx, + blake2b_init_key_xop +#endif +}; + +static const blake2b_init_param_fn blake2b_init_param_table[] = +{ + blake2b_init_param_ref, +#if defined(HAVE_X86) + blake2b_init_param_sse2, + blake2b_init_param_ssse3, + blake2b_init_param_sse41, + blake2b_init_param_avx, + blake2b_init_param_xop +#endif +}; + +static const blake2b_update_fn blake2b_update_table[] = +{ + blake2b_update_ref, +#if defined(HAVE_X86) + blake2b_update_sse2, + blake2b_update_ssse3, + blake2b_update_sse41, + blake2b_update_avx, + blake2b_update_xop +#endif +}; + +static const blake2b_final_fn blake2b_final_table[] = +{ + blake2b_final_ref, +#if defined(HAVE_X86) + blake2b_final_sse2, + blake2b_final_ssse3, + blake2b_final_sse41, + blake2b_final_avx, + blake2b_final_xop +#endif +}; + +static const blake2b_fn blake2b_table[] = +{ + blake2b_ref, +#if defined(HAVE_X86) + blake2b_sse2, + blake2b_ssse3, + blake2b_sse41, + blake2b_avx, + blake2b_xop +#endif +}; + +static const blake2s_init_fn blake2s_init_table[] = +{ + blake2s_init_ref, +#if defined(HAVE_X86) + blake2s_init_sse2, + blake2s_init_ssse3, + blake2s_init_sse41, + blake2s_init_avx, + blake2s_init_xop +#endif +}; + +static const blake2s_init_key_fn blake2s_init_key_table[] = +{ + blake2s_init_key_ref, +#if defined(HAVE_X86) + blake2s_init_key_sse2, + blake2s_init_key_ssse3, + blake2s_init_key_sse41, + blake2s_init_key_avx, + blake2s_init_key_xop +#endif +}; + +static const blake2s_init_param_fn blake2s_init_param_table[] = +{ + blake2s_init_param_ref, +#if defined(HAVE_X86) + blake2s_init_param_sse2, + blake2s_init_param_ssse3, + blake2s_init_param_sse41, + blake2s_init_param_avx, + blake2s_init_param_xop +#endif +}; + +static const blake2s_update_fn blake2s_update_table[] = +{ + blake2s_update_ref, +#if defined(HAVE_X86) + blake2s_update_sse2, + blake2s_update_ssse3, + blake2s_update_sse41, + blake2s_update_avx, + blake2s_update_xop +#endif +}; + +static const blake2s_final_fn blake2s_final_table[] = +{ + blake2s_final_ref, +#if defined(HAVE_X86) + blake2s_final_sse2, + blake2s_final_ssse3, + blake2s_final_sse41, + blake2s_final_avx, + blake2s_final_xop +#endif +}; + +static const blake2s_fn blake2s_table[] = +{ + blake2s_ref, +#if defined(HAVE_X86) + blake2s_sse2, + blake2s_ssse3, + blake2s_sse41, + blake2s_avx, + blake2s_xop +#endif +}; + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init_dispatch( blake2b_state *S, size_t outlen ); + int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ); + int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + int blake2s_init_dispatch( blake2s_state *S, size_t outlen ); + int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ); + int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + +static blake2b_init_fn blake2b_init_ptr = blake2b_init_dispatch; +static blake2b_init_key_fn blake2b_init_key_ptr = blake2b_init_key_dispatch; +static blake2b_init_param_fn blake2b_init_param_ptr = blake2b_init_param_dispatch; +static blake2b_update_fn blake2b_update_ptr = blake2b_update_dispatch; +static blake2b_final_fn blake2b_final_ptr = blake2b_final_dispatch; +static blake2b_fn blake2b_ptr = blake2b_dispatch; + +static blake2s_init_fn blake2s_init_ptr = blake2s_init_dispatch; +static blake2s_init_key_fn blake2s_init_key_ptr = blake2s_init_key_dispatch; +static blake2s_init_param_fn blake2s_init_param_ptr = blake2s_init_param_dispatch; +static blake2s_update_fn blake2s_update_ptr = blake2s_update_dispatch; +static blake2s_final_fn blake2s_final_ptr = blake2s_final_dispatch; +static blake2s_fn blake2s_ptr = blake2s_dispatch; + +int blake2b_init_dispatch( blake2b_state *S, size_t outlen ) +{ + blake2b_init_ptr = blake2b_init_table[get_cpu_features()]; + return blake2b_init_ptr( S, outlen ); +} + +int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2b_init_key_ptr = blake2b_init_key_table[get_cpu_features()]; + return blake2b_init_key_ptr( S, outlen, key, keylen ); +} + +int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P ) +{ + blake2b_init_param_ptr = blake2b_init_param_table[get_cpu_features()]; + return blake2b_init_param_ptr( S, P ); +} + +int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen ) +{ + blake2b_update_ptr = blake2b_update_table[get_cpu_features()]; + return blake2b_update_ptr( S, in, inlen ); +} + +int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen ) +{ + blake2b_final_ptr = blake2b_final_table[get_cpu_features()]; + return blake2b_final_ptr( S, out, outlen ); +} + +int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + blake2b_ptr = blake2b_table[get_cpu_features()]; + return blake2b_ptr( out, in, key, outlen, inlen, keylen ); +} + +BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen ) +{ + return blake2b_init_ptr( S, outlen ); +} + +BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) +{ + return blake2b_init_key_ptr( S, outlen, key, keylen ); +} + +BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) +{ + return blake2b_init_param_ptr( S, P ); +} + +BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) +{ + return blake2b_update_ptr( S, in, inlen ); +} + +BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) +{ + return blake2b_final_ptr( S, out, outlen ); +} + +BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + return blake2b_ptr( out, in, key, outlen, inlen, keylen ); +} + +int blake2s_init_dispatch( blake2s_state *S, size_t outlen ) +{ + blake2s_init_ptr = blake2s_init_table[get_cpu_features()]; + return blake2s_init_ptr( S, outlen ); +} + +int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) +{ + blake2s_init_key_ptr = blake2s_init_key_table[get_cpu_features()]; + return blake2s_init_key_ptr( S, outlen, key, keylen ); +} + +int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P ) +{ + blake2s_init_param_ptr = blake2s_init_param_table[get_cpu_features()]; + return blake2s_init_param_ptr( S, P ); +} + +int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen ) +{ + blake2s_update_ptr = blake2s_update_table[get_cpu_features()]; + return blake2s_update_ptr( S, in, inlen ); +} + +int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen ) +{ + blake2s_final_ptr = blake2s_final_table[get_cpu_features()]; + return blake2s_final_ptr( S, out, outlen ); +} + +int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + blake2s_ptr = blake2s_table[get_cpu_features()]; + return blake2s_ptr( out, in, key, outlen, inlen, keylen ); +} + +BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen ) +{ + return blake2s_init_ptr( S, outlen ); +} + +BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) +{ + return blake2s_init_key_ptr( S, outlen, key, keylen ); +} + +BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) +{ + return blake2s_init_param_ptr( S, P ); +} + +BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) +{ + return blake2s_update_ptr( S, in, inlen ); +} + +BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) +{ + return blake2s_final_ptr( S, out, outlen ); +} + +BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + return blake2s_ptr( out, in, key, outlen, inlen, keylen ); +} + diff --git a/Modules/_blake2/impl/blake2-impl.h b/Modules/_blake2/impl/blake2-impl.h index bbe3c0f1cfcfa5..5bebd83a2b7dd3 100644 --- a/Modules/_blake2/impl/blake2-impl.h +++ b/Modules/_blake2/impl/blake2-impl.h @@ -1,32 +1,39 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2_IMPL_H__ #define __BLAKE2_IMPL_H__ +#if defined(_WIN32) || defined(WIN32) +#include +#endif + +#include #include #include -BLAKE2_LOCAL_INLINE(uint32_t) load32( const void *src ) +#define BLAKE2_IMPL_CAT(x,y) x ## y +#define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y) +#define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX) + +static inline uint32_t load32( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint32_t w; - memcpy(&w, src, sizeof w); + memcpy( &w, src, sizeof( w ) ); return w; #else - const uint8_t *p = ( const uint8_t * )src; + const uint8_t *p = ( uint8_t * )src; uint32_t w = *p++; w |= ( uint32_t )( *p++ ) << 8; w |= ( uint32_t )( *p++ ) << 16; @@ -35,14 +42,14 @@ BLAKE2_LOCAL_INLINE(uint32_t) load32( const void *src ) #endif } -BLAKE2_LOCAL_INLINE(uint64_t) load64( const void *src ) +static inline uint64_t load64( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint64_t w; - memcpy(&w, src, sizeof w); + memcpy( &w, src, sizeof( w ) ); return w; #else - const uint8_t *p = ( const uint8_t * )src; + const uint8_t *p = ( uint8_t * )src; uint64_t w = *p++; w |= ( uint64_t )( *p++ ) << 8; w |= ( uint64_t )( *p++ ) << 16; @@ -55,10 +62,10 @@ BLAKE2_LOCAL_INLINE(uint64_t) load64( const void *src ) #endif } -BLAKE2_LOCAL_INLINE(void) store32( void *dst, uint32_t w ) +static inline void store32( void *dst, uint32_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); + memcpy( dst, &w, sizeof( w ) ); #else uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8; @@ -68,10 +75,10 @@ BLAKE2_LOCAL_INLINE(void) store32( void *dst, uint32_t w ) #endif } -BLAKE2_LOCAL_INLINE(void) store64( void *dst, uint64_t w ) +static inline void store64( void *dst, uint64_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); + memcpy( dst, &w, sizeof( w ) ); #else uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8; @@ -85,7 +92,7 @@ BLAKE2_LOCAL_INLINE(void) store64( void *dst, uint64_t w ) #endif } -BLAKE2_LOCAL_INLINE(uint64_t) load48( const void *src ) +static inline uint64_t load48( const void *src ) { const uint8_t *p = ( const uint8_t * )src; uint64_t w = *p++; @@ -97,7 +104,7 @@ BLAKE2_LOCAL_INLINE(uint64_t) load48( const void *src ) return w; } -BLAKE2_LOCAL_INLINE(void) store48( void *dst, uint64_t w ) +static inline void store48( void *dst, uint64_t w ) { uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8; @@ -108,31 +115,44 @@ BLAKE2_LOCAL_INLINE(void) store48( void *dst, uint64_t w ) *p++ = ( uint8_t )w; } -BLAKE2_LOCAL_INLINE(uint32_t) rotl32( const uint32_t w, const unsigned c ) +static inline uint32_t rotl32( const uint32_t w, const unsigned c ) { return ( w << c ) | ( w >> ( 32 - c ) ); } -BLAKE2_LOCAL_INLINE(uint64_t) rotl64( const uint64_t w, const unsigned c ) +static inline uint64_t rotl64( const uint64_t w, const unsigned c ) { return ( w << c ) | ( w >> ( 64 - c ) ); } -BLAKE2_LOCAL_INLINE(uint32_t) rotr32( const uint32_t w, const unsigned c ) +static inline uint32_t rotr32( const uint32_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 32 - c ) ); } -BLAKE2_LOCAL_INLINE(uint64_t) rotr64( const uint64_t w, const unsigned c ) +static inline uint64_t rotr64( const uint64_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 64 - c ) ); } /* prevents compiler optimizing out memset() */ -BLAKE2_LOCAL_INLINE(void) secure_zero_memory(void *v, size_t n) +static inline void secure_zero_memory(void *v, size_t n) { - static void *(*const volatile memset_v)(void *, int, size_t) = &memset; - memset_v(v, 0, n); +#if defined(_WIN32) || defined(WIN32) + SecureZeroMemory(v, n); +#else +// prioritize first the general C11 call +#if defined(HAVE_MEMSET_S) + memset_s(v, n, 0, n); +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(v, n); +#elif defined(HAVE_EXPLICIT_MEMSET) + explicit_memset(v, 0, n); +#else + memset(v, 0, n); + __asm__ __volatile__("" :: "r"(v) : "memory"); +#endif +#endif } #endif diff --git a/Modules/_blake2/impl/blake2-kat.h b/Modules/_blake2/impl/blake2-kat.h new file mode 100644 index 00000000000000..3d2072763aa935 --- /dev/null +++ b/Modules/_blake2/impl/blake2-kat.h @@ -0,0 +1,16467 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +#pragma once +#ifndef __BLAKE2_KAT_H__ +#define __BLAKE2_KAT_H__ + + +#include + +#define KAT_LENGTH 256 + + + +static const uint8_t blake2s_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0x69, 0x21, 0x7A, 0x30, 0x79, 0x90, 0x80, 0x94, + 0xE1, 0x11, 0x21, 0xD0, 0x42, 0x35, 0x4A, 0x7C, + 0x1F, 0x55, 0xB6, 0x48, 0x2C, 0xA1, 0xA5, 0x1E, + 0x1B, 0x25, 0x0D, 0xFD, 0x1E, 0xD0, 0xEE, 0xF9 + }, + { + 0xE3, 0x4D, 0x74, 0xDB, 0xAF, 0x4F, 0xF4, 0xC6, + 0xAB, 0xD8, 0x71, 0xCC, 0x22, 0x04, 0x51, 0xD2, + 0xEA, 0x26, 0x48, 0x84, 0x6C, 0x77, 0x57, 0xFB, + 0xAA, 0xC8, 0x2F, 0xE5, 0x1A, 0xD6, 0x4B, 0xEA + }, + { + 0xDD, 0xAD, 0x9A, 0xB1, 0x5D, 0xAC, 0x45, 0x49, + 0xBA, 0x42, 0xF4, 0x9D, 0x26, 0x24, 0x96, 0xBE, + 0xF6, 0xC0, 0xBA, 0xE1, 0xDD, 0x34, 0x2A, 0x88, + 0x08, 0xF8, 0xEA, 0x26, 0x7C, 0x6E, 0x21, 0x0C + }, + { + 0xE8, 0xF9, 0x1C, 0x6E, 0xF2, 0x32, 0xA0, 0x41, + 0x45, 0x2A, 0xB0, 0xE1, 0x49, 0x07, 0x0C, 0xDD, + 0x7D, 0xD1, 0x76, 0x9E, 0x75, 0xB3, 0xA5, 0x92, + 0x1B, 0xE3, 0x78, 0x76, 0xC4, 0x5C, 0x99, 0x00 + }, + { + 0x0C, 0xC7, 0x0E, 0x00, 0x34, 0x8B, 0x86, 0xBA, + 0x29, 0x44, 0xD0, 0xC3, 0x20, 0x38, 0xB2, 0x5C, + 0x55, 0x58, 0x4F, 0x90, 0xDF, 0x23, 0x04, 0xF5, + 0x5F, 0xA3, 0x32, 0xAF, 0x5F, 0xB0, 0x1E, 0x20 + }, + { + 0xEC, 0x19, 0x64, 0x19, 0x10, 0x87, 0xA4, 0xFE, + 0x9D, 0xF1, 0xC7, 0x95, 0x34, 0x2A, 0x02, 0xFF, + 0xC1, 0x91, 0xA5, 0xB2, 0x51, 0x76, 0x48, 0x56, + 0xAE, 0x5B, 0x8B, 0x57, 0x69, 0xF0, 0xC6, 0xCD + }, + { + 0xE1, 0xFA, 0x51, 0x61, 0x8D, 0x7D, 0xF4, 0xEB, + 0x70, 0xCF, 0x0D, 0x5A, 0x9E, 0x90, 0x6F, 0x80, + 0x6E, 0x9D, 0x19, 0xF7, 0xF4, 0xF0, 0x1E, 0x3B, + 0x62, 0x12, 0x88, 0xE4, 0x12, 0x04, 0x05, 0xD6 + }, + { + 0x59, 0x80, 0x01, 0xFA, 0xFB, 0xE8, 0xF9, 0x4E, + 0xC6, 0x6D, 0xC8, 0x27, 0xD0, 0x12, 0xCF, 0xCB, + 0xBA, 0x22, 0x28, 0x56, 0x9F, 0x44, 0x8E, 0x89, + 0xEA, 0x22, 0x08, 0xC8, 0xBF, 0x76, 0x92, 0x93 + }, + { + 0xC7, 0xE8, 0x87, 0xB5, 0x46, 0x62, 0x36, 0x35, + 0xE9, 0x3E, 0x04, 0x95, 0x59, 0x8F, 0x17, 0x26, + 0x82, 0x19, 0x96, 0xC2, 0x37, 0x77, 0x05, 0xB9, + 0x3A, 0x1F, 0x63, 0x6F, 0x87, 0x2B, 0xFA, 0x2D + }, + { + 0xC3, 0x15, 0xA4, 0x37, 0xDD, 0x28, 0x06, 0x2A, + 0x77, 0x0D, 0x48, 0x19, 0x67, 0x13, 0x6B, 0x1B, + 0x5E, 0xB8, 0x8B, 0x21, 0xEE, 0x53, 0xD0, 0x32, + 0x9C, 0x58, 0x97, 0x12, 0x6E, 0x9D, 0xB0, 0x2C + }, + { + 0xBB, 0x47, 0x3D, 0xED, 0xDC, 0x05, 0x5F, 0xEA, + 0x62, 0x28, 0xF2, 0x07, 0xDA, 0x57, 0x53, 0x47, + 0xBB, 0x00, 0x40, 0x4C, 0xD3, 0x49, 0xD3, 0x8C, + 0x18, 0x02, 0x63, 0x07, 0xA2, 0x24, 0xCB, 0xFF + }, + { + 0x68, 0x7E, 0x18, 0x73, 0xA8, 0x27, 0x75, 0x91, + 0xBB, 0x33, 0xD9, 0xAD, 0xF9, 0xA1, 0x39, 0x12, + 0xEF, 0xEF, 0xE5, 0x57, 0xCA, 0xFC, 0x39, 0xA7, + 0x95, 0x26, 0x23, 0xE4, 0x72, 0x55, 0xF1, 0x6D + }, + { + 0x1A, 0xC7, 0xBA, 0x75, 0x4D, 0x6E, 0x2F, 0x94, + 0xE0, 0xE8, 0x6C, 0x46, 0xBF, 0xB2, 0x62, 0xAB, + 0xBB, 0x74, 0xF4, 0x50, 0xEF, 0x45, 0x6D, 0x6B, + 0x4D, 0x97, 0xAA, 0x80, 0xCE, 0x6D, 0xA7, 0x67 + }, + { + 0x01, 0x2C, 0x97, 0x80, 0x96, 0x14, 0x81, 0x6B, + 0x5D, 0x94, 0x94, 0x47, 0x7D, 0x4B, 0x68, 0x7D, + 0x15, 0xB9, 0x6E, 0xB6, 0x9C, 0x0E, 0x80, 0x74, + 0xA8, 0x51, 0x6F, 0x31, 0x22, 0x4B, 0x5C, 0x98 + }, + { + 0x91, 0xFF, 0xD2, 0x6C, 0xFA, 0x4D, 0xA5, 0x13, + 0x4C, 0x7E, 0xA2, 0x62, 0xF7, 0x88, 0x9C, 0x32, + 0x9F, 0x61, 0xF6, 0xA6, 0x57, 0x22, 0x5C, 0xC2, + 0x12, 0xF4, 0x00, 0x56, 0xD9, 0x86, 0xB3, 0xF4 + }, + { + 0xD9, 0x7C, 0x82, 0x8D, 0x81, 0x82, 0xA7, 0x21, + 0x80, 0xA0, 0x6A, 0x78, 0x26, 0x83, 0x30, 0x67, + 0x3F, 0x7C, 0x4E, 0x06, 0x35, 0x94, 0x7C, 0x04, + 0xC0, 0x23, 0x23, 0xFD, 0x45, 0xC0, 0xA5, 0x2D + }, + { + 0xEF, 0xC0, 0x4C, 0xDC, 0x39, 0x1C, 0x7E, 0x91, + 0x19, 0xBD, 0x38, 0x66, 0x8A, 0x53, 0x4E, 0x65, + 0xFE, 0x31, 0x03, 0x6D, 0x6A, 0x62, 0x11, 0x2E, + 0x44, 0xEB, 0xEB, 0x11, 0xF9, 0xC5, 0x70, 0x80 + }, + { + 0x99, 0x2C, 0xF5, 0xC0, 0x53, 0x44, 0x2A, 0x5F, + 0xBC, 0x4F, 0xAF, 0x58, 0x3E, 0x04, 0xE5, 0x0B, + 0xB7, 0x0D, 0x2F, 0x39, 0xFB, 0xB6, 0xA5, 0x03, + 0xF8, 0x9E, 0x56, 0xA6, 0x3E, 0x18, 0x57, 0x8A + }, + { + 0x38, 0x64, 0x0E, 0x9F, 0x21, 0x98, 0x3E, 0x67, + 0xB5, 0x39, 0xCA, 0xCC, 0xAE, 0x5E, 0xCF, 0x61, + 0x5A, 0xE2, 0x76, 0x4F, 0x75, 0xA0, 0x9C, 0x9C, + 0x59, 0xB7, 0x64, 0x83, 0xC1, 0xFB, 0xC7, 0x35 + }, + { + 0x21, 0x3D, 0xD3, 0x4C, 0x7E, 0xFE, 0x4F, 0xB2, + 0x7A, 0x6B, 0x35, 0xF6, 0xB4, 0x00, 0x0D, 0x1F, + 0xE0, 0x32, 0x81, 0xAF, 0x3C, 0x72, 0x3E, 0x5C, + 0x9F, 0x94, 0x74, 0x7A, 0x5F, 0x31, 0xCD, 0x3B + }, + { + 0xEC, 0x24, 0x6E, 0xEE, 0xB9, 0xCE, 0xD3, 0xF7, + 0xAD, 0x33, 0xED, 0x28, 0x66, 0x0D, 0xD9, 0xBB, + 0x07, 0x32, 0x51, 0x3D, 0xB4, 0xE2, 0xFA, 0x27, + 0x8B, 0x60, 0xCD, 0xE3, 0x68, 0x2A, 0x4C, 0xCD + }, + { + 0xAC, 0x9B, 0x61, 0xD4, 0x46, 0x64, 0x8C, 0x30, + 0x05, 0xD7, 0x89, 0x2B, 0xF3, 0xA8, 0x71, 0x9F, + 0x4C, 0x81, 0x81, 0xCF, 0xDC, 0xBC, 0x2B, 0x79, + 0xFE, 0xF1, 0x0A, 0x27, 0x9B, 0x91, 0x10, 0x95 + }, + { + 0x7B, 0xF8, 0xB2, 0x29, 0x59, 0xE3, 0x4E, 0x3A, + 0x43, 0xF7, 0x07, 0x92, 0x23, 0xE8, 0x3A, 0x97, + 0x54, 0x61, 0x7D, 0x39, 0x1E, 0x21, 0x3D, 0xFD, + 0x80, 0x8E, 0x41, 0xB9, 0xBE, 0xAD, 0x4C, 0xE7 + }, + { + 0x68, 0xD4, 0xB5, 0xD4, 0xFA, 0x0E, 0x30, 0x2B, + 0x64, 0xCC, 0xC5, 0xAF, 0x79, 0x29, 0x13, 0xAC, + 0x4C, 0x88, 0xEC, 0x95, 0xC0, 0x7D, 0xDF, 0x40, + 0x69, 0x42, 0x56, 0xEB, 0x88, 0xCE, 0x9F, 0x3D + }, + { + 0xB2, 0xC2, 0x42, 0x0F, 0x05, 0xF9, 0xAB, 0xE3, + 0x63, 0x15, 0x91, 0x93, 0x36, 0xB3, 0x7E, 0x4E, + 0x0F, 0xA3, 0x3F, 0xF7, 0xE7, 0x6A, 0x49, 0x27, + 0x67, 0x00, 0x6F, 0xDB, 0x5D, 0x93, 0x54, 0x62 + }, + { + 0x13, 0x4F, 0x61, 0xBB, 0xD0, 0xBB, 0xB6, 0x9A, + 0xED, 0x53, 0x43, 0x90, 0x45, 0x51, 0xA3, 0xE6, + 0xC1, 0xAA, 0x7D, 0xCD, 0xD7, 0x7E, 0x90, 0x3E, + 0x70, 0x23, 0xEB, 0x7C, 0x60, 0x32, 0x0A, 0xA7 + }, + { + 0x46, 0x93, 0xF9, 0xBF, 0xF7, 0xD4, 0xF3, 0x98, + 0x6A, 0x7D, 0x17, 0x6E, 0x6E, 0x06, 0xF7, 0x2A, + 0xD1, 0x49, 0x0D, 0x80, 0x5C, 0x99, 0xE2, 0x53, + 0x47, 0xB8, 0xDE, 0x77, 0xB4, 0xDB, 0x6D, 0x9B + }, + { + 0x85, 0x3E, 0x26, 0xF7, 0x41, 0x95, 0x3B, 0x0F, + 0xD5, 0xBD, 0xB4, 0x24, 0xE8, 0xAB, 0x9E, 0x8B, + 0x37, 0x50, 0xEA, 0xA8, 0xEF, 0x61, 0xE4, 0x79, + 0x02, 0xC9, 0x1E, 0x55, 0x4E, 0x9C, 0x73, 0xB9 + }, + { + 0xF7, 0xDE, 0x53, 0x63, 0x61, 0xAB, 0xAA, 0x0E, + 0x15, 0x81, 0x56, 0xCF, 0x0E, 0xA4, 0xF6, 0x3A, + 0x99, 0xB5, 0xE4, 0x05, 0x4F, 0x8F, 0xA4, 0xC9, + 0xD4, 0x5F, 0x62, 0x85, 0xCA, 0xD5, 0x56, 0x94 + }, + { + 0x4C, 0x23, 0x06, 0x08, 0x86, 0x0A, 0x99, 0xAE, + 0x8D, 0x7B, 0xD5, 0xC2, 0xCC, 0x17, 0xFA, 0x52, + 0x09, 0x6B, 0x9A, 0x61, 0xBE, 0xDB, 0x17, 0xCB, + 0x76, 0x17, 0x86, 0x4A, 0xD2, 0x9C, 0xA7, 0xA6 + }, + { + 0xAE, 0xB9, 0x20, 0xEA, 0x87, 0x95, 0x2D, 0xAD, + 0xB1, 0xFB, 0x75, 0x92, 0x91, 0xE3, 0x38, 0x81, + 0x39, 0xA8, 0x72, 0x86, 0x50, 0x01, 0x88, 0x6E, + 0xD8, 0x47, 0x52, 0xE9, 0x3C, 0x25, 0x0C, 0x2A + }, + { + 0xAB, 0xA4, 0xAD, 0x9B, 0x48, 0x0B, 0x9D, 0xF3, + 0xD0, 0x8C, 0xA5, 0xE8, 0x7B, 0x0C, 0x24, 0x40, + 0xD4, 0xE4, 0xEA, 0x21, 0x22, 0x4C, 0x2E, 0xB4, + 0x2C, 0xBA, 0xE4, 0x69, 0xD0, 0x89, 0xB9, 0x31 + }, + { + 0x05, 0x82, 0x56, 0x07, 0xD7, 0xFD, 0xF2, 0xD8, + 0x2E, 0xF4, 0xC3, 0xC8, 0xC2, 0xAE, 0xA9, 0x61, + 0xAD, 0x98, 0xD6, 0x0E, 0xDF, 0xF7, 0xD0, 0x18, + 0x98, 0x3E, 0x21, 0x20, 0x4C, 0x0D, 0x93, 0xD1 + }, + { + 0xA7, 0x42, 0xF8, 0xB6, 0xAF, 0x82, 0xD8, 0xA6, + 0xCA, 0x23, 0x57, 0xC5, 0xF1, 0xCF, 0x91, 0xDE, + 0xFB, 0xD0, 0x66, 0x26, 0x7D, 0x75, 0xC0, 0x48, + 0xB3, 0x52, 0x36, 0x65, 0x85, 0x02, 0x59, 0x62 + }, + { + 0x2B, 0xCA, 0xC8, 0x95, 0x99, 0x00, 0x0B, 0x42, + 0xC9, 0x5A, 0xE2, 0x38, 0x35, 0xA7, 0x13, 0x70, + 0x4E, 0xD7, 0x97, 0x89, 0xC8, 0x4F, 0xEF, 0x14, + 0x9A, 0x87, 0x4F, 0xF7, 0x33, 0xF0, 0x17, 0xA2 + }, + { + 0xAC, 0x1E, 0xD0, 0x7D, 0x04, 0x8F, 0x10, 0x5A, + 0x9E, 0x5B, 0x7A, 0xB8, 0x5B, 0x09, 0xA4, 0x92, + 0xD5, 0xBA, 0xFF, 0x14, 0xB8, 0xBF, 0xB0, 0xE9, + 0xFD, 0x78, 0x94, 0x86, 0xEE, 0xA2, 0xB9, 0x74 + }, + { + 0xE4, 0x8D, 0x0E, 0xCF, 0xAF, 0x49, 0x7D, 0x5B, + 0x27, 0xC2, 0x5D, 0x99, 0xE1, 0x56, 0xCB, 0x05, + 0x79, 0xD4, 0x40, 0xD6, 0xE3, 0x1F, 0xB6, 0x24, + 0x73, 0x69, 0x6D, 0xBF, 0x95, 0xE0, 0x10, 0xE4 + }, + { + 0x12, 0xA9, 0x1F, 0xAD, 0xF8, 0xB2, 0x16, 0x44, + 0xFD, 0x0F, 0x93, 0x4F, 0x3C, 0x4A, 0x8F, 0x62, + 0xBA, 0x86, 0x2F, 0xFD, 0x20, 0xE8, 0xE9, 0x61, + 0x15, 0x4C, 0x15, 0xC1, 0x38, 0x84, 0xED, 0x3D + }, + { + 0x7C, 0xBE, 0xE9, 0x6E, 0x13, 0x98, 0x97, 0xDC, + 0x98, 0xFB, 0xEF, 0x3B, 0xE8, 0x1A, 0xD4, 0xD9, + 0x64, 0xD2, 0x35, 0xCB, 0x12, 0x14, 0x1F, 0xB6, + 0x67, 0x27, 0xE6, 0xE5, 0xDF, 0x73, 0xA8, 0x78 + }, + { + 0xEB, 0xF6, 0x6A, 0xBB, 0x59, 0x7A, 0xE5, 0x72, + 0xA7, 0x29, 0x7C, 0xB0, 0x87, 0x1E, 0x35, 0x5A, + 0xCC, 0xAF, 0xAD, 0x83, 0x77, 0xB8, 0xE7, 0x8B, + 0xF1, 0x64, 0xCE, 0x2A, 0x18, 0xDE, 0x4B, 0xAF + }, + { + 0x71, 0xB9, 0x33, 0xB0, 0x7E, 0x4F, 0xF7, 0x81, + 0x8C, 0xE0, 0x59, 0xD0, 0x08, 0x82, 0x9E, 0x45, + 0x3C, 0x6F, 0xF0, 0x2E, 0xC0, 0xA7, 0xDB, 0x39, + 0x3F, 0xC2, 0xD8, 0x70, 0xF3, 0x7A, 0x72, 0x86 + }, + { + 0x7C, 0xF7, 0xC5, 0x13, 0x31, 0x22, 0x0B, 0x8D, + 0x3E, 0xBA, 0xED, 0x9C, 0x29, 0x39, 0x8A, 0x16, + 0xD9, 0x81, 0x56, 0xE2, 0x61, 0x3C, 0xB0, 0x88, + 0xF2, 0xB0, 0xE0, 0x8A, 0x1B, 0xE4, 0xCF, 0x4F + }, + { + 0x3E, 0x41, 0xA1, 0x08, 0xE0, 0xF6, 0x4A, 0xD2, + 0x76, 0xB9, 0x79, 0xE1, 0xCE, 0x06, 0x82, 0x79, + 0xE1, 0x6F, 0x7B, 0xC7, 0xE4, 0xAA, 0x1D, 0x21, + 0x1E, 0x17, 0xB8, 0x11, 0x61, 0xDF, 0x16, 0x02 + }, + { + 0x88, 0x65, 0x02, 0xA8, 0x2A, 0xB4, 0x7B, 0xA8, + 0xD8, 0x67, 0x10, 0xAA, 0x9D, 0xE3, 0xD4, 0x6E, + 0xA6, 0x5C, 0x47, 0xAF, 0x6E, 0xE8, 0xDE, 0x45, + 0x0C, 0xCE, 0xB8, 0xB1, 0x1B, 0x04, 0x5F, 0x50 + }, + { + 0xC0, 0x21, 0xBC, 0x5F, 0x09, 0x54, 0xFE, 0xE9, + 0x4F, 0x46, 0xEA, 0x09, 0x48, 0x7E, 0x10, 0xA8, + 0x48, 0x40, 0xD0, 0x2F, 0x64, 0x81, 0x0B, 0xC0, + 0x8D, 0x9E, 0x55, 0x1F, 0x7D, 0x41, 0x68, 0x14 + }, + { + 0x20, 0x30, 0x51, 0x6E, 0x8A, 0x5F, 0xE1, 0x9A, + 0xE7, 0x9C, 0x33, 0x6F, 0xCE, 0x26, 0x38, 0x2A, + 0x74, 0x9D, 0x3F, 0xD0, 0xEC, 0x91, 0xE5, 0x37, + 0xD4, 0xBD, 0x23, 0x58, 0xC1, 0x2D, 0xFB, 0x22 + }, + { + 0x55, 0x66, 0x98, 0xDA, 0xC8, 0x31, 0x7F, 0xD3, + 0x6D, 0xFB, 0xDF, 0x25, 0xA7, 0x9C, 0xB1, 0x12, + 0xD5, 0x42, 0x58, 0x60, 0x60, 0x5C, 0xBA, 0xF5, + 0x07, 0xF2, 0x3B, 0xF7, 0xE9, 0xF4, 0x2A, 0xFE + }, + { + 0x2F, 0x86, 0x7B, 0xA6, 0x77, 0x73, 0xFD, 0xC3, + 0xE9, 0x2F, 0xCE, 0xD9, 0x9A, 0x64, 0x09, 0xAD, + 0x39, 0xD0, 0xB8, 0x80, 0xFD, 0xE8, 0xF1, 0x09, + 0xA8, 0x17, 0x30, 0xC4, 0x45, 0x1D, 0x01, 0x78 + }, + { + 0x17, 0x2E, 0xC2, 0x18, 0xF1, 0x19, 0xDF, 0xAE, + 0x98, 0x89, 0x6D, 0xFF, 0x29, 0xDD, 0x98, 0x76, + 0xC9, 0x4A, 0xF8, 0x74, 0x17, 0xF9, 0xAE, 0x4C, + 0x70, 0x14, 0xBB, 0x4E, 0x4B, 0x96, 0xAF, 0xC7 + }, + { + 0x3F, 0x85, 0x81, 0x4A, 0x18, 0x19, 0x5F, 0x87, + 0x9A, 0xA9, 0x62, 0xF9, 0x5D, 0x26, 0xBD, 0x82, + 0xA2, 0x78, 0xF2, 0xB8, 0x23, 0x20, 0x21, 0x8F, + 0x6B, 0x3B, 0xD6, 0xF7, 0xF6, 0x67, 0xA6, 0xD9 + }, + { + 0x1B, 0x61, 0x8F, 0xBA, 0xA5, 0x66, 0xB3, 0xD4, + 0x98, 0xC1, 0x2E, 0x98, 0x2C, 0x9E, 0xC5, 0x2E, + 0x4D, 0xA8, 0x5A, 0x8C, 0x54, 0xF3, 0x8F, 0x34, + 0xC0, 0x90, 0x39, 0x4F, 0x23, 0xC1, 0x84, 0xC1 + }, + { + 0x0C, 0x75, 0x8F, 0xB5, 0x69, 0x2F, 0xFD, 0x41, + 0xA3, 0x57, 0x5D, 0x0A, 0xF0, 0x0C, 0xC7, 0xFB, + 0xF2, 0xCB, 0xE5, 0x90, 0x5A, 0x58, 0x32, 0x3A, + 0x88, 0xAE, 0x42, 0x44, 0xF6, 0xE4, 0xC9, 0x93 + }, + { + 0xA9, 0x31, 0x36, 0x0C, 0xAD, 0x62, 0x8C, 0x7F, + 0x12, 0xA6, 0xC1, 0xC4, 0xB7, 0x53, 0xB0, 0xF4, + 0x06, 0x2A, 0xEF, 0x3C, 0xE6, 0x5A, 0x1A, 0xE3, + 0xF1, 0x93, 0x69, 0xDA, 0xDF, 0x3A, 0xE2, 0x3D + }, + { + 0xCB, 0xAC, 0x7D, 0x77, 0x3B, 0x1E, 0x3B, 0x3C, + 0x66, 0x91, 0xD7, 0xAB, 0xB7, 0xE9, 0xDF, 0x04, + 0x5C, 0x8B, 0xA1, 0x92, 0x68, 0xDE, 0xD1, 0x53, + 0x20, 0x7F, 0x5E, 0x80, 0x43, 0x52, 0xEC, 0x5D + }, + { + 0x23, 0xA1, 0x96, 0xD3, 0x80, 0x2E, 0xD3, 0xC1, + 0xB3, 0x84, 0x01, 0x9A, 0x82, 0x32, 0x58, 0x40, + 0xD3, 0x2F, 0x71, 0x95, 0x0C, 0x45, 0x80, 0xB0, + 0x34, 0x45, 0xE0, 0x89, 0x8E, 0x14, 0x05, 0x3C + }, + { + 0xF4, 0x49, 0x54, 0x70, 0xF2, 0x26, 0xC8, 0xC2, + 0x14, 0xBE, 0x08, 0xFD, 0xFA, 0xD4, 0xBC, 0x4A, + 0x2A, 0x9D, 0xBE, 0xA9, 0x13, 0x6A, 0x21, 0x0D, + 0xF0, 0xD4, 0xB6, 0x49, 0x29, 0xE6, 0xFC, 0x14 + }, + { + 0xE2, 0x90, 0xDD, 0x27, 0x0B, 0x46, 0x7F, 0x34, + 0xAB, 0x1C, 0x00, 0x2D, 0x34, 0x0F, 0xA0, 0x16, + 0x25, 0x7F, 0xF1, 0x9E, 0x58, 0x33, 0xFD, 0xBB, + 0xF2, 0xCB, 0x40, 0x1C, 0x3B, 0x28, 0x17, 0xDE + }, + { + 0x9F, 0xC7, 0xB5, 0xDE, 0xD3, 0xC1, 0x50, 0x42, + 0xB2, 0xA6, 0x58, 0x2D, 0xC3, 0x9B, 0xE0, 0x16, + 0xD2, 0x4A, 0x68, 0x2D, 0x5E, 0x61, 0xAD, 0x1E, + 0xFF, 0x9C, 0x63, 0x30, 0x98, 0x48, 0xF7, 0x06 + }, + { + 0x8C, 0xCA, 0x67, 0xA3, 0x6D, 0x17, 0xD5, 0xE6, + 0x34, 0x1C, 0xB5, 0x92, 0xFD, 0x7B, 0xEF, 0x99, + 0x26, 0xC9, 0xE3, 0xAA, 0x10, 0x27, 0xEA, 0x11, + 0xA7, 0xD8, 0xBD, 0x26, 0x0B, 0x57, 0x6E, 0x04 + }, + { + 0x40, 0x93, 0x92, 0xF5, 0x60, 0xF8, 0x68, 0x31, + 0xDA, 0x43, 0x73, 0xEE, 0x5E, 0x00, 0x74, 0x26, + 0x05, 0x95, 0xD7, 0xBC, 0x24, 0x18, 0x3B, 0x60, + 0xED, 0x70, 0x0D, 0x45, 0x83, 0xD3, 0xF6, 0xF0 + }, + { + 0x28, 0x02, 0x16, 0x5D, 0xE0, 0x90, 0x91, 0x55, + 0x46, 0xF3, 0x39, 0x8C, 0xD8, 0x49, 0x16, 0x4A, + 0x19, 0xF9, 0x2A, 0xDB, 0xC3, 0x61, 0xAD, 0xC9, + 0x9B, 0x0F, 0x20, 0xC8, 0xEA, 0x07, 0x10, 0x54 + }, + { + 0xAD, 0x83, 0x91, 0x68, 0xD9, 0xF8, 0xA4, 0xBE, + 0x95, 0xBA, 0x9E, 0xF9, 0xA6, 0x92, 0xF0, 0x72, + 0x56, 0xAE, 0x43, 0xFE, 0x6F, 0x98, 0x64, 0xE2, + 0x90, 0x69, 0x1B, 0x02, 0x56, 0xCE, 0x50, 0xA9 + }, + { + 0x75, 0xFD, 0xAA, 0x50, 0x38, 0xC2, 0x84, 0xB8, + 0x6D, 0x6E, 0x8A, 0xFF, 0xE8, 0xB2, 0x80, 0x7E, + 0x46, 0x7B, 0x86, 0x60, 0x0E, 0x79, 0xAF, 0x36, + 0x89, 0xFB, 0xC0, 0x63, 0x28, 0xCB, 0xF8, 0x94 + }, + { + 0xE5, 0x7C, 0xB7, 0x94, 0x87, 0xDD, 0x57, 0x90, + 0x24, 0x32, 0xB2, 0x50, 0x73, 0x38, 0x13, 0xBD, + 0x96, 0xA8, 0x4E, 0xFC, 0xE5, 0x9F, 0x65, 0x0F, + 0xAC, 0x26, 0xE6, 0x69, 0x6A, 0xEF, 0xAF, 0xC3 + }, + { + 0x56, 0xF3, 0x4E, 0x8B, 0x96, 0x55, 0x7E, 0x90, + 0xC1, 0xF2, 0x4B, 0x52, 0xD0, 0xC8, 0x9D, 0x51, + 0x08, 0x6A, 0xCF, 0x1B, 0x00, 0xF6, 0x34, 0xCF, + 0x1D, 0xDE, 0x92, 0x33, 0xB8, 0xEA, 0xAA, 0x3E + }, + { + 0x1B, 0x53, 0xEE, 0x94, 0xAA, 0xF3, 0x4E, 0x4B, + 0x15, 0x9D, 0x48, 0xDE, 0x35, 0x2C, 0x7F, 0x06, + 0x61, 0xD0, 0xA4, 0x0E, 0xDF, 0xF9, 0x5A, 0x0B, + 0x16, 0x39, 0xB4, 0x09, 0x0E, 0x97, 0x44, 0x72 + }, + { + 0x05, 0x70, 0x5E, 0x2A, 0x81, 0x75, 0x7C, 0x14, + 0xBD, 0x38, 0x3E, 0xA9, 0x8D, 0xDA, 0x54, 0x4E, + 0xB1, 0x0E, 0x6B, 0xC0, 0x7B, 0xAE, 0x43, 0x5E, + 0x25, 0x18, 0xDB, 0xE1, 0x33, 0x52, 0x53, 0x75 + }, + { + 0xD8, 0xB2, 0x86, 0x6E, 0x8A, 0x30, 0x9D, 0xB5, + 0x3E, 0x52, 0x9E, 0xC3, 0x29, 0x11, 0xD8, 0x2F, + 0x5C, 0xA1, 0x6C, 0xFF, 0x76, 0x21, 0x68, 0x91, + 0xA9, 0x67, 0x6A, 0xA3, 0x1A, 0xAA, 0x6C, 0x42 + }, + { + 0xF5, 0x04, 0x1C, 0x24, 0x12, 0x70, 0xEB, 0x04, + 0xC7, 0x1E, 0xC2, 0xC9, 0x5D, 0x4C, 0x38, 0xD8, + 0x03, 0xB1, 0x23, 0x7B, 0x0F, 0x29, 0xFD, 0x4D, + 0xB3, 0xEB, 0x39, 0x76, 0x69, 0xE8, 0x86, 0x99 + }, + { + 0x9A, 0x4C, 0xE0, 0x77, 0xC3, 0x49, 0x32, 0x2F, + 0x59, 0x5E, 0x0E, 0xE7, 0x9E, 0xD0, 0xDA, 0x5F, + 0xAB, 0x66, 0x75, 0x2C, 0xBF, 0xEF, 0x8F, 0x87, + 0xD0, 0xE9, 0xD0, 0x72, 0x3C, 0x75, 0x30, 0xDD + }, + { + 0x65, 0x7B, 0x09, 0xF3, 0xD0, 0xF5, 0x2B, 0x5B, + 0x8F, 0x2F, 0x97, 0x16, 0x3A, 0x0E, 0xDF, 0x0C, + 0x04, 0xF0, 0x75, 0x40, 0x8A, 0x07, 0xBB, 0xEB, + 0x3A, 0x41, 0x01, 0xA8, 0x91, 0x99, 0x0D, 0x62 + }, + { + 0x1E, 0x3F, 0x7B, 0xD5, 0xA5, 0x8F, 0xA5, 0x33, + 0x34, 0x4A, 0xA8, 0xED, 0x3A, 0xC1, 0x22, 0xBB, + 0x9E, 0x70, 0xD4, 0xEF, 0x50, 0xD0, 0x04, 0x53, + 0x08, 0x21, 0x94, 0x8F, 0x5F, 0xE6, 0x31, 0x5A + }, + { + 0x80, 0xDC, 0xCF, 0x3F, 0xD8, 0x3D, 0xFD, 0x0D, + 0x35, 0xAA, 0x28, 0x58, 0x59, 0x22, 0xAB, 0x89, + 0xD5, 0x31, 0x39, 0x97, 0x67, 0x3E, 0xAF, 0x90, + 0x5C, 0xEA, 0x9C, 0x0B, 0x22, 0x5C, 0x7B, 0x5F + }, + { + 0x8A, 0x0D, 0x0F, 0xBF, 0x63, 0x77, 0xD8, 0x3B, + 0xB0, 0x8B, 0x51, 0x4B, 0x4B, 0x1C, 0x43, 0xAC, + 0xC9, 0x5D, 0x75, 0x17, 0x14, 0xF8, 0x92, 0x56, + 0x45, 0xCB, 0x6B, 0xC8, 0x56, 0xCA, 0x15, 0x0A + }, + { + 0x9F, 0xA5, 0xB4, 0x87, 0x73, 0x8A, 0xD2, 0x84, + 0x4C, 0xC6, 0x34, 0x8A, 0x90, 0x19, 0x18, 0xF6, + 0x59, 0xA3, 0xB8, 0x9E, 0x9C, 0x0D, 0xFE, 0xEA, + 0xD3, 0x0D, 0xD9, 0x4B, 0xCF, 0x42, 0xEF, 0x8E + }, + { + 0x80, 0x83, 0x2C, 0x4A, 0x16, 0x77, 0xF5, 0xEA, + 0x25, 0x60, 0xF6, 0x68, 0xE9, 0x35, 0x4D, 0xD3, + 0x69, 0x97, 0xF0, 0x37, 0x28, 0xCF, 0xA5, 0x5E, + 0x1B, 0x38, 0x33, 0x7C, 0x0C, 0x9E, 0xF8, 0x18 + }, + { + 0xAB, 0x37, 0xDD, 0xB6, 0x83, 0x13, 0x7E, 0x74, + 0x08, 0x0D, 0x02, 0x6B, 0x59, 0x0B, 0x96, 0xAE, + 0x9B, 0xB4, 0x47, 0x72, 0x2F, 0x30, 0x5A, 0x5A, + 0xC5, 0x70, 0xEC, 0x1D, 0xF9, 0xB1, 0x74, 0x3C + }, + { + 0x3E, 0xE7, 0x35, 0xA6, 0x94, 0xC2, 0x55, 0x9B, + 0x69, 0x3A, 0xA6, 0x86, 0x29, 0x36, 0x1E, 0x15, + 0xD1, 0x22, 0x65, 0xAD, 0x6A, 0x3D, 0xED, 0xF4, + 0x88, 0xB0, 0xB0, 0x0F, 0xAC, 0x97, 0x54, 0xBA + }, + { + 0xD6, 0xFC, 0xD2, 0x32, 0x19, 0xB6, 0x47, 0xE4, + 0xCB, 0xD5, 0xEB, 0x2D, 0x0A, 0xD0, 0x1E, 0xC8, + 0x83, 0x8A, 0x4B, 0x29, 0x01, 0xFC, 0x32, 0x5C, + 0xC3, 0x70, 0x19, 0x81, 0xCA, 0x6C, 0x88, 0x8B + }, + { + 0x05, 0x20, 0xEC, 0x2F, 0x5B, 0xF7, 0xA7, 0x55, + 0xDA, 0xCB, 0x50, 0xC6, 0xBF, 0x23, 0x3E, 0x35, + 0x15, 0x43, 0x47, 0x63, 0xDB, 0x01, 0x39, 0xCC, + 0xD9, 0xFA, 0xEF, 0xBB, 0x82, 0x07, 0x61, 0x2D + }, + { + 0xAF, 0xF3, 0xB7, 0x5F, 0x3F, 0x58, 0x12, 0x64, + 0xD7, 0x66, 0x16, 0x62, 0xB9, 0x2F, 0x5A, 0xD3, + 0x7C, 0x1D, 0x32, 0xBD, 0x45, 0xFF, 0x81, 0xA4, + 0xED, 0x8A, 0xDC, 0x9E, 0xF3, 0x0D, 0xD9, 0x89 + }, + { + 0xD0, 0xDD, 0x65, 0x0B, 0xEF, 0xD3, 0xBA, 0x63, + 0xDC, 0x25, 0x10, 0x2C, 0x62, 0x7C, 0x92, 0x1B, + 0x9C, 0xBE, 0xB0, 0xB1, 0x30, 0x68, 0x69, 0x35, + 0xB5, 0xC9, 0x27, 0xCB, 0x7C, 0xCD, 0x5E, 0x3B + }, + { + 0xE1, 0x14, 0x98, 0x16, 0xB1, 0x0A, 0x85, 0x14, + 0xFB, 0x3E, 0x2C, 0xAB, 0x2C, 0x08, 0xBE, 0xE9, + 0xF7, 0x3C, 0xE7, 0x62, 0x21, 0x70, 0x12, 0x46, + 0xA5, 0x89, 0xBB, 0xB6, 0x73, 0x02, 0xD8, 0xA9 + }, + { + 0x7D, 0xA3, 0xF4, 0x41, 0xDE, 0x90, 0x54, 0x31, + 0x7E, 0x72, 0xB5, 0xDB, 0xF9, 0x79, 0xDA, 0x01, + 0xE6, 0xBC, 0xEE, 0xBB, 0x84, 0x78, 0xEA, 0xE6, + 0xA2, 0x28, 0x49, 0xD9, 0x02, 0x92, 0x63, 0x5C + }, + { + 0x12, 0x30, 0xB1, 0xFC, 0x8A, 0x7D, 0x92, 0x15, + 0xED, 0xC2, 0xD4, 0xA2, 0xDE, 0xCB, 0xDD, 0x0A, + 0x6E, 0x21, 0x6C, 0x92, 0x42, 0x78, 0xC9, 0x1F, + 0xC5, 0xD1, 0x0E, 0x7D, 0x60, 0x19, 0x2D, 0x94 + }, + { + 0x57, 0x50, 0xD7, 0x16, 0xB4, 0x80, 0x8F, 0x75, + 0x1F, 0xEB, 0xC3, 0x88, 0x06, 0xBA, 0x17, 0x0B, + 0xF6, 0xD5, 0x19, 0x9A, 0x78, 0x16, 0xBE, 0x51, + 0x4E, 0x3F, 0x93, 0x2F, 0xBE, 0x0C, 0xB8, 0x71 + }, + { + 0x6F, 0xC5, 0x9B, 0x2F, 0x10, 0xFE, 0xBA, 0x95, + 0x4A, 0xA6, 0x82, 0x0B, 0x3C, 0xA9, 0x87, 0xEE, + 0x81, 0xD5, 0xCC, 0x1D, 0xA3, 0xC6, 0x3C, 0xE8, + 0x27, 0x30, 0x1C, 0x56, 0x9D, 0xFB, 0x39, 0xCE + }, + { + 0xC7, 0xC3, 0xFE, 0x1E, 0xEB, 0xDC, 0x7B, 0x5A, + 0x93, 0x93, 0x26, 0xE8, 0xDD, 0xB8, 0x3E, 0x8B, + 0xF2, 0xB7, 0x80, 0xB6, 0x56, 0x78, 0xCB, 0x62, + 0xF2, 0x08, 0xB0, 0x40, 0xAB, 0xDD, 0x35, 0xE2 + }, + { + 0x0C, 0x75, 0xC1, 0xA1, 0x5C, 0xF3, 0x4A, 0x31, + 0x4E, 0xE4, 0x78, 0xF4, 0xA5, 0xCE, 0x0B, 0x8A, + 0x6B, 0x36, 0x52, 0x8E, 0xF7, 0xA8, 0x20, 0x69, + 0x6C, 0x3E, 0x42, 0x46, 0xC5, 0xA1, 0x58, 0x64 + }, + { + 0x21, 0x6D, 0xC1, 0x2A, 0x10, 0x85, 0x69, 0xA3, + 0xC7, 0xCD, 0xDE, 0x4A, 0xED, 0x43, 0xA6, 0xC3, + 0x30, 0x13, 0x9D, 0xDA, 0x3C, 0xCC, 0x4A, 0x10, + 0x89, 0x05, 0xDB, 0x38, 0x61, 0x89, 0x90, 0x50 + }, + { + 0xA5, 0x7B, 0xE6, 0xAE, 0x67, 0x56, 0xF2, 0x8B, + 0x02, 0xF5, 0x9D, 0xAD, 0xF7, 0xE0, 0xD7, 0xD8, + 0x80, 0x7F, 0x10, 0xFA, 0x15, 0xCE, 0xD1, 0xAD, + 0x35, 0x85, 0x52, 0x1A, 0x1D, 0x99, 0x5A, 0x89 + }, + { + 0x81, 0x6A, 0xEF, 0x87, 0x59, 0x53, 0x71, 0x6C, + 0xD7, 0xA5, 0x81, 0xF7, 0x32, 0xF5, 0x3D, 0xD4, + 0x35, 0xDA, 0xB6, 0x6D, 0x09, 0xC3, 0x61, 0xD2, + 0xD6, 0x59, 0x2D, 0xE1, 0x77, 0x55, 0xD8, 0xA8 + }, + { + 0x9A, 0x76, 0x89, 0x32, 0x26, 0x69, 0x3B, 0x6E, + 0xA9, 0x7E, 0x6A, 0x73, 0x8F, 0x9D, 0x10, 0xFB, + 0x3D, 0x0B, 0x43, 0xAE, 0x0E, 0x8B, 0x7D, 0x81, + 0x23, 0xEA, 0x76, 0xCE, 0x97, 0x98, 0x9C, 0x7E + }, + { + 0x8D, 0xAE, 0xDB, 0x9A, 0x27, 0x15, 0x29, 0xDB, + 0xB7, 0xDC, 0x3B, 0x60, 0x7F, 0xE5, 0xEB, 0x2D, + 0x32, 0x11, 0x77, 0x07, 0x58, 0xDD, 0x3B, 0x0A, + 0x35, 0x93, 0xD2, 0xD7, 0x95, 0x4E, 0x2D, 0x5B + }, + { + 0x16, 0xDB, 0xC0, 0xAA, 0x5D, 0xD2, 0xC7, 0x74, + 0xF5, 0x05, 0x10, 0x0F, 0x73, 0x37, 0x86, 0xD8, + 0xA1, 0x75, 0xFC, 0xBB, 0xB5, 0x9C, 0x43, 0xE1, + 0xFB, 0xFF, 0x3E, 0x1E, 0xAF, 0x31, 0xCB, 0x4A + }, + { + 0x86, 0x06, 0xCB, 0x89, 0x9C, 0x6A, 0xEA, 0xF5, + 0x1B, 0x9D, 0xB0, 0xFE, 0x49, 0x24, 0xA9, 0xFD, + 0x5D, 0xAB, 0xC1, 0x9F, 0x88, 0x26, 0xF2, 0xBC, + 0x1C, 0x1D, 0x7D, 0xA1, 0x4D, 0x2C, 0x2C, 0x99 + }, + { + 0x84, 0x79, 0x73, 0x1A, 0xED, 0xA5, 0x7B, 0xD3, + 0x7E, 0xAD, 0xB5, 0x1A, 0x50, 0x7E, 0x30, 0x7F, + 0x3B, 0xD9, 0x5E, 0x69, 0xDB, 0xCA, 0x94, 0xF3, + 0xBC, 0x21, 0x72, 0x60, 0x66, 0xAD, 0x6D, 0xFD + }, + { + 0x58, 0x47, 0x3A, 0x9E, 0xA8, 0x2E, 0xFA, 0x3F, + 0x3B, 0x3D, 0x8F, 0xC8, 0x3E, 0xD8, 0x86, 0x31, + 0x27, 0xB3, 0x3A, 0xE8, 0xDE, 0xAE, 0x63, 0x07, + 0x20, 0x1E, 0xDB, 0x6D, 0xDE, 0x61, 0xDE, 0x29 + }, + { + 0x9A, 0x92, 0x55, 0xD5, 0x3A, 0xF1, 0x16, 0xDE, + 0x8B, 0xA2, 0x7C, 0xE3, 0x5B, 0x4C, 0x7E, 0x15, + 0x64, 0x06, 0x57, 0xA0, 0xFC, 0xB8, 0x88, 0xC7, + 0x0D, 0x95, 0x43, 0x1D, 0xAC, 0xD8, 0xF8, 0x30 + }, + { + 0x9E, 0xB0, 0x5F, 0xFB, 0xA3, 0x9F, 0xD8, 0x59, + 0x6A, 0x45, 0x49, 0x3E, 0x18, 0xD2, 0x51, 0x0B, + 0xF3, 0xEF, 0x06, 0x5C, 0x51, 0xD6, 0xE1, 0x3A, + 0xBE, 0x66, 0xAA, 0x57, 0xE0, 0x5C, 0xFD, 0xB7 + }, + { + 0x81, 0xDC, 0xC3, 0xA5, 0x05, 0xEA, 0xCE, 0x3F, + 0x87, 0x9D, 0x8F, 0x70, 0x27, 0x76, 0x77, 0x0F, + 0x9D, 0xF5, 0x0E, 0x52, 0x1D, 0x14, 0x28, 0xA8, + 0x5D, 0xAF, 0x04, 0xF9, 0xAD, 0x21, 0x50, 0xE0 + }, + { + 0xE3, 0xE3, 0xC4, 0xAA, 0x3A, 0xCB, 0xBC, 0x85, + 0x33, 0x2A, 0xF9, 0xD5, 0x64, 0xBC, 0x24, 0x16, + 0x5E, 0x16, 0x87, 0xF6, 0xB1, 0xAD, 0xCB, 0xFA, + 0xE7, 0x7A, 0x8F, 0x03, 0xC7, 0x2A, 0xC2, 0x8C + }, + { + 0x67, 0x46, 0xC8, 0x0B, 0x4E, 0xB5, 0x6A, 0xEA, + 0x45, 0xE6, 0x4E, 0x72, 0x89, 0xBB, 0xA3, 0xED, + 0xBF, 0x45, 0xEC, 0xF8, 0x20, 0x64, 0x81, 0xFF, + 0x63, 0x02, 0x12, 0x29, 0x84, 0xCD, 0x52, 0x6A + }, + { + 0x2B, 0x62, 0x8E, 0x52, 0x76, 0x4D, 0x7D, 0x62, + 0xC0, 0x86, 0x8B, 0x21, 0x23, 0x57, 0xCD, 0xD1, + 0x2D, 0x91, 0x49, 0x82, 0x2F, 0x4E, 0x98, 0x45, + 0xD9, 0x18, 0xA0, 0x8D, 0x1A, 0xE9, 0x90, 0xC0 + }, + { + 0xE4, 0xBF, 0xE8, 0x0D, 0x58, 0xC9, 0x19, 0x94, + 0x61, 0x39, 0x09, 0xDC, 0x4B, 0x1A, 0x12, 0x49, + 0x68, 0x96, 0xC0, 0x04, 0xAF, 0x7B, 0x57, 0x01, + 0x48, 0x3D, 0xE4, 0x5D, 0x28, 0x23, 0xD7, 0x8E + }, + { + 0xEB, 0xB4, 0xBA, 0x15, 0x0C, 0xEF, 0x27, 0x34, + 0x34, 0x5B, 0x5D, 0x64, 0x1B, 0xBE, 0xD0, 0x3A, + 0x21, 0xEA, 0xFA, 0xE9, 0x33, 0xC9, 0x9E, 0x00, + 0x92, 0x12, 0xEF, 0x04, 0x57, 0x4A, 0x85, 0x30 + }, + { + 0x39, 0x66, 0xEC, 0x73, 0xB1, 0x54, 0xAC, 0xC6, + 0x97, 0xAC, 0x5C, 0xF5, 0xB2, 0x4B, 0x40, 0xBD, + 0xB0, 0xDB, 0x9E, 0x39, 0x88, 0x36, 0xD7, 0x6D, + 0x4B, 0x88, 0x0E, 0x3B, 0x2A, 0xF1, 0xAA, 0x27 + }, + { + 0xEF, 0x7E, 0x48, 0x31, 0xB3, 0xA8, 0x46, 0x36, + 0x51, 0x8D, 0x6E, 0x4B, 0xFC, 0xE6, 0x4A, 0x43, + 0xDB, 0x2A, 0x5D, 0xDA, 0x9C, 0xCA, 0x2B, 0x44, + 0xF3, 0x90, 0x33, 0xBD, 0xC4, 0x0D, 0x62, 0x43 + }, + { + 0x7A, 0xBF, 0x6A, 0xCF, 0x5C, 0x8E, 0x54, 0x9D, + 0xDB, 0xB1, 0x5A, 0xE8, 0xD8, 0xB3, 0x88, 0xC1, + 0xC1, 0x97, 0xE6, 0x98, 0x73, 0x7C, 0x97, 0x85, + 0x50, 0x1E, 0xD1, 0xF9, 0x49, 0x30, 0xB7, 0xD9 + }, + { + 0x88, 0x01, 0x8D, 0xED, 0x66, 0x81, 0x3F, 0x0C, + 0xA9, 0x5D, 0xEF, 0x47, 0x4C, 0x63, 0x06, 0x92, + 0x01, 0x99, 0x67, 0xB9, 0xE3, 0x68, 0x88, 0xDA, + 0xDD, 0x94, 0x12, 0x47, 0x19, 0xB6, 0x82, 0xF6 + }, + { + 0x39, 0x30, 0x87, 0x6B, 0x9F, 0xC7, 0x52, 0x90, + 0x36, 0xB0, 0x08, 0xB1, 0xB8, 0xBB, 0x99, 0x75, + 0x22, 0xA4, 0x41, 0x63, 0x5A, 0x0C, 0x25, 0xEC, + 0x02, 0xFB, 0x6D, 0x90, 0x26, 0xE5, 0x5A, 0x97 + }, + { + 0x0A, 0x40, 0x49, 0xD5, 0x7E, 0x83, 0x3B, 0x56, + 0x95, 0xFA, 0xC9, 0x3D, 0xD1, 0xFB, 0xEF, 0x31, + 0x66, 0xB4, 0x4B, 0x12, 0xAD, 0x11, 0x24, 0x86, + 0x62, 0x38, 0x3A, 0xE0, 0x51, 0xE1, 0x58, 0x27 + }, + { + 0x81, 0xDC, 0xC0, 0x67, 0x8B, 0xB6, 0xA7, 0x65, + 0xE4, 0x8C, 0x32, 0x09, 0x65, 0x4F, 0xE9, 0x00, + 0x89, 0xCE, 0x44, 0xFF, 0x56, 0x18, 0x47, 0x7E, + 0x39, 0xAB, 0x28, 0x64, 0x76, 0xDF, 0x05, 0x2B + }, + { + 0xE6, 0x9B, 0x3A, 0x36, 0xA4, 0x46, 0x19, 0x12, + 0xDC, 0x08, 0x34, 0x6B, 0x11, 0xDD, 0xCB, 0x9D, + 0xB7, 0x96, 0xF8, 0x85, 0xFD, 0x01, 0x93, 0x6E, + 0x66, 0x2F, 0xE2, 0x92, 0x97, 0xB0, 0x99, 0xA4 + }, + { + 0x5A, 0xC6, 0x50, 0x3B, 0x0D, 0x8D, 0xA6, 0x91, + 0x76, 0x46, 0xE6, 0xDC, 0xC8, 0x7E, 0xDC, 0x58, + 0xE9, 0x42, 0x45, 0x32, 0x4C, 0xC2, 0x04, 0xF4, + 0xDD, 0x4A, 0xF0, 0x15, 0x63, 0xAC, 0xD4, 0x27 + }, + { + 0xDF, 0x6D, 0xDA, 0x21, 0x35, 0x9A, 0x30, 0xBC, + 0x27, 0x17, 0x80, 0x97, 0x1C, 0x1A, 0xBD, 0x56, + 0xA6, 0xEF, 0x16, 0x7E, 0x48, 0x08, 0x87, 0x88, + 0x8E, 0x73, 0xA8, 0x6D, 0x3B, 0xF6, 0x05, 0xE9 + }, + { + 0xE8, 0xE6, 0xE4, 0x70, 0x71, 0xE7, 0xB7, 0xDF, + 0x25, 0x80, 0xF2, 0x25, 0xCF, 0xBB, 0xED, 0xF8, + 0x4C, 0xE6, 0x77, 0x46, 0x62, 0x66, 0x28, 0xD3, + 0x30, 0x97, 0xE4, 0xB7, 0xDC, 0x57, 0x11, 0x07 + }, + { + 0x53, 0xE4, 0x0E, 0xAD, 0x62, 0x05, 0x1E, 0x19, + 0xCB, 0x9B, 0xA8, 0x13, 0x3E, 0x3E, 0x5C, 0x1C, + 0xE0, 0x0D, 0xDC, 0xAD, 0x8A, 0xCF, 0x34, 0x2A, + 0x22, 0x43, 0x60, 0xB0, 0xAC, 0xC1, 0x47, 0x77 + }, + { + 0x9C, 0xCD, 0x53, 0xFE, 0x80, 0xBE, 0x78, 0x6A, + 0xA9, 0x84, 0x63, 0x84, 0x62, 0xFB, 0x28, 0xAF, + 0xDF, 0x12, 0x2B, 0x34, 0xD7, 0x8F, 0x46, 0x87, + 0xEC, 0x63, 0x2B, 0xB1, 0x9D, 0xE2, 0x37, 0x1A + }, + { + 0xCB, 0xD4, 0x80, 0x52, 0xC4, 0x8D, 0x78, 0x84, + 0x66, 0xA3, 0xE8, 0x11, 0x8C, 0x56, 0xC9, 0x7F, + 0xE1, 0x46, 0xE5, 0x54, 0x6F, 0xAA, 0xF9, 0x3E, + 0x2B, 0xC3, 0xC4, 0x7E, 0x45, 0x93, 0x97, 0x53 + }, + { + 0x25, 0x68, 0x83, 0xB1, 0x4E, 0x2A, 0xF4, 0x4D, + 0xAD, 0xB2, 0x8E, 0x1B, 0x34, 0xB2, 0xAC, 0x0F, + 0x0F, 0x4C, 0x91, 0xC3, 0x4E, 0xC9, 0x16, 0x9E, + 0x29, 0x03, 0x61, 0x58, 0xAC, 0xAA, 0x95, 0xB9 + }, + { + 0x44, 0x71, 0xB9, 0x1A, 0xB4, 0x2D, 0xB7, 0xC4, + 0xDD, 0x84, 0x90, 0xAB, 0x95, 0xA2, 0xEE, 0x8D, + 0x04, 0xE3, 0xEF, 0x5C, 0x3D, 0x6F, 0xC7, 0x1A, + 0xC7, 0x4B, 0x2B, 0x26, 0x91, 0x4D, 0x16, 0x41 + }, + { + 0xA5, 0xEB, 0x08, 0x03, 0x8F, 0x8F, 0x11, 0x55, + 0xED, 0x86, 0xE6, 0x31, 0x90, 0x6F, 0xC1, 0x30, + 0x95, 0xF6, 0xBB, 0xA4, 0x1D, 0xE5, 0xD4, 0xE7, + 0x95, 0x75, 0x8E, 0xC8, 0xC8, 0xDF, 0x8A, 0xF1 + }, + { + 0xDC, 0x1D, 0xB6, 0x4E, 0xD8, 0xB4, 0x8A, 0x91, + 0x0E, 0x06, 0x0A, 0x6B, 0x86, 0x63, 0x74, 0xC5, + 0x78, 0x78, 0x4E, 0x9A, 0xC4, 0x9A, 0xB2, 0x77, + 0x40, 0x92, 0xAC, 0x71, 0x50, 0x19, 0x34, 0xAC + }, + { + 0x28, 0x54, 0x13, 0xB2, 0xF2, 0xEE, 0x87, 0x3D, + 0x34, 0x31, 0x9E, 0xE0, 0xBB, 0xFB, 0xB9, 0x0F, + 0x32, 0xDA, 0x43, 0x4C, 0xC8, 0x7E, 0x3D, 0xB5, + 0xED, 0x12, 0x1B, 0xB3, 0x98, 0xED, 0x96, 0x4B + }, + { + 0x02, 0x16, 0xE0, 0xF8, 0x1F, 0x75, 0x0F, 0x26, + 0xF1, 0x99, 0x8B, 0xC3, 0x93, 0x4E, 0x3E, 0x12, + 0x4C, 0x99, 0x45, 0xE6, 0x85, 0xA6, 0x0B, 0x25, + 0xE8, 0xFB, 0xD9, 0x62, 0x5A, 0xB6, 0xB5, 0x99 + }, + { + 0x38, 0xC4, 0x10, 0xF5, 0xB9, 0xD4, 0x07, 0x20, + 0x50, 0x75, 0x5B, 0x31, 0xDC, 0xA8, 0x9F, 0xD5, + 0x39, 0x5C, 0x67, 0x85, 0xEE, 0xB3, 0xD7, 0x90, + 0xF3, 0x20, 0xFF, 0x94, 0x1C, 0x5A, 0x93, 0xBF + }, + { + 0xF1, 0x84, 0x17, 0xB3, 0x9D, 0x61, 0x7A, 0xB1, + 0xC1, 0x8F, 0xDF, 0x91, 0xEB, 0xD0, 0xFC, 0x6D, + 0x55, 0x16, 0xBB, 0x34, 0xCF, 0x39, 0x36, 0x40, + 0x37, 0xBC, 0xE8, 0x1F, 0xA0, 0x4C, 0xEC, 0xB1 + }, + { + 0x1F, 0xA8, 0x77, 0xDE, 0x67, 0x25, 0x9D, 0x19, + 0x86, 0x3A, 0x2A, 0x34, 0xBC, 0xC6, 0x96, 0x2A, + 0x2B, 0x25, 0xFC, 0xBF, 0x5C, 0xBE, 0xCD, 0x7E, + 0xDE, 0x8F, 0x1F, 0xA3, 0x66, 0x88, 0xA7, 0x96 + }, + { + 0x5B, 0xD1, 0x69, 0xE6, 0x7C, 0x82, 0xC2, 0xC2, + 0xE9, 0x8E, 0xF7, 0x00, 0x8B, 0xDF, 0x26, 0x1F, + 0x2D, 0xDF, 0x30, 0xB1, 0xC0, 0x0F, 0x9E, 0x7F, + 0x27, 0x5B, 0xB3, 0xE8, 0xA2, 0x8D, 0xC9, 0xA2 + }, + { + 0xC8, 0x0A, 0xBE, 0xEB, 0xB6, 0x69, 0xAD, 0x5D, + 0xEE, 0xB5, 0xF5, 0xEC, 0x8E, 0xA6, 0xB7, 0xA0, + 0x5D, 0xDF, 0x7D, 0x31, 0xEC, 0x4C, 0x0A, 0x2E, + 0xE2, 0x0B, 0x0B, 0x98, 0xCA, 0xEC, 0x67, 0x46 + }, + { + 0xE7, 0x6D, 0x3F, 0xBD, 0xA5, 0xBA, 0x37, 0x4E, + 0x6B, 0xF8, 0xE5, 0x0F, 0xAD, 0xC3, 0xBB, 0xB9, + 0xBA, 0x5C, 0x20, 0x6E, 0xBD, 0xEC, 0x89, 0xA3, + 0xA5, 0x4C, 0xF3, 0xDD, 0x84, 0xA0, 0x70, 0x16 + }, + { + 0x7B, 0xBA, 0x9D, 0xC5, 0xB5, 0xDB, 0x20, 0x71, + 0xD1, 0x77, 0x52, 0xB1, 0x04, 0x4C, 0x1E, 0xCE, + 0xD9, 0x6A, 0xAF, 0x2D, 0xD4, 0x6E, 0x9B, 0x43, + 0x37, 0x50, 0xE8, 0xEA, 0x0D, 0xCC, 0x18, 0x70 + }, + { + 0xF2, 0x9B, 0x1B, 0x1A, 0xB9, 0xBA, 0xB1, 0x63, + 0x01, 0x8E, 0xE3, 0xDA, 0x15, 0x23, 0x2C, 0xCA, + 0x78, 0xEC, 0x52, 0xDB, 0xC3, 0x4E, 0xDA, 0x5B, + 0x82, 0x2E, 0xC1, 0xD8, 0x0F, 0xC2, 0x1B, 0xD0 + }, + { + 0x9E, 0xE3, 0xE3, 0xE7, 0xE9, 0x00, 0xF1, 0xE1, + 0x1D, 0x30, 0x8C, 0x4B, 0x2B, 0x30, 0x76, 0xD2, + 0x72, 0xCF, 0x70, 0x12, 0x4F, 0x9F, 0x51, 0xE1, + 0xDA, 0x60, 0xF3, 0x78, 0x46, 0xCD, 0xD2, 0xF4 + }, + { + 0x70, 0xEA, 0x3B, 0x01, 0x76, 0x92, 0x7D, 0x90, + 0x96, 0xA1, 0x85, 0x08, 0xCD, 0x12, 0x3A, 0x29, + 0x03, 0x25, 0x92, 0x0A, 0x9D, 0x00, 0xA8, 0x9B, + 0x5D, 0xE0, 0x42, 0x73, 0xFB, 0xC7, 0x6B, 0x85 + }, + { + 0x67, 0xDE, 0x25, 0xC0, 0x2A, 0x4A, 0xAB, 0xA2, + 0x3B, 0xDC, 0x97, 0x3C, 0x8B, 0xB0, 0xB5, 0x79, + 0x6D, 0x47, 0xCC, 0x06, 0x59, 0xD4, 0x3D, 0xFF, + 0x1F, 0x97, 0xDE, 0x17, 0x49, 0x63, 0xB6, 0x8E + }, + { + 0xB2, 0x16, 0x8E, 0x4E, 0x0F, 0x18, 0xB0, 0xE6, + 0x41, 0x00, 0xB5, 0x17, 0xED, 0x95, 0x25, 0x7D, + 0x73, 0xF0, 0x62, 0x0D, 0xF8, 0x85, 0xC1, 0x3D, + 0x2E, 0xCF, 0x79, 0x36, 0x7B, 0x38, 0x4C, 0xEE + }, + { + 0x2E, 0x7D, 0xEC, 0x24, 0x28, 0x85, 0x3B, 0x2C, + 0x71, 0x76, 0x07, 0x45, 0x54, 0x1F, 0x7A, 0xFE, + 0x98, 0x25, 0xB5, 0xDD, 0x77, 0xDF, 0x06, 0x51, + 0x1D, 0x84, 0x41, 0xA9, 0x4B, 0xAC, 0xC9, 0x27 + }, + { + 0xCA, 0x9F, 0xFA, 0xC4, 0xC4, 0x3F, 0x0B, 0x48, + 0x46, 0x1D, 0xC5, 0xC2, 0x63, 0xBE, 0xA3, 0xF6, + 0xF0, 0x06, 0x11, 0xCE, 0xAC, 0xAB, 0xF6, 0xF8, + 0x95, 0xBA, 0x2B, 0x01, 0x01, 0xDB, 0xB6, 0x8D + }, + { + 0x74, 0x10, 0xD4, 0x2D, 0x8F, 0xD1, 0xD5, 0xE9, + 0xD2, 0xF5, 0x81, 0x5C, 0xB9, 0x34, 0x17, 0x99, + 0x88, 0x28, 0xEF, 0x3C, 0x42, 0x30, 0xBF, 0xBD, + 0x41, 0x2D, 0xF0, 0xA4, 0xA7, 0xA2, 0x50, 0x7A + }, + { + 0x50, 0x10, 0xF6, 0x84, 0x51, 0x6D, 0xCC, 0xD0, + 0xB6, 0xEE, 0x08, 0x52, 0xC2, 0x51, 0x2B, 0x4D, + 0xC0, 0x06, 0x6C, 0xF0, 0xD5, 0x6F, 0x35, 0x30, + 0x29, 0x78, 0xDB, 0x8A, 0xE3, 0x2C, 0x6A, 0x81 + }, + { + 0xAC, 0xAA, 0xB5, 0x85, 0xF7, 0xB7, 0x9B, 0x71, + 0x99, 0x35, 0xCE, 0xB8, 0x95, 0x23, 0xDD, 0xC5, + 0x48, 0x27, 0xF7, 0x5C, 0x56, 0x88, 0x38, 0x56, + 0x15, 0x4A, 0x56, 0xCD, 0xCD, 0x5E, 0xE9, 0x88 + }, + { + 0x66, 0x6D, 0xE5, 0xD1, 0x44, 0x0F, 0xEE, 0x73, + 0x31, 0xAA, 0xF0, 0x12, 0x3A, 0x62, 0xEF, 0x2D, + 0x8B, 0xA5, 0x74, 0x53, 0xA0, 0x76, 0x96, 0x35, + 0xAC, 0x6C, 0xD0, 0x1E, 0x63, 0x3F, 0x77, 0x12 + }, + { + 0xA6, 0xF9, 0x86, 0x58, 0xF6, 0xEA, 0xBA, 0xF9, + 0x02, 0xD8, 0xB3, 0x87, 0x1A, 0x4B, 0x10, 0x1D, + 0x16, 0x19, 0x6E, 0x8A, 0x4B, 0x24, 0x1E, 0x15, + 0x58, 0xFE, 0x29, 0x96, 0x6E, 0x10, 0x3E, 0x8D + }, + { + 0x89, 0x15, 0x46, 0xA8, 0xB2, 0x9F, 0x30, 0x47, + 0xDD, 0xCF, 0xE5, 0xB0, 0x0E, 0x45, 0xFD, 0x55, + 0x75, 0x63, 0x73, 0x10, 0x5E, 0xA8, 0x63, 0x7D, + 0xFC, 0xFF, 0x54, 0x7B, 0x6E, 0xA9, 0x53, 0x5F + }, + { + 0x18, 0xDF, 0xBC, 0x1A, 0xC5, 0xD2, 0x5B, 0x07, + 0x61, 0x13, 0x7D, 0xBD, 0x22, 0xC1, 0x7C, 0x82, + 0x9D, 0x0F, 0x0E, 0xF1, 0xD8, 0x23, 0x44, 0xE9, + 0xC8, 0x9C, 0x28, 0x66, 0x94, 0xDA, 0x24, 0xE8 + }, + { + 0xB5, 0x4B, 0x9B, 0x67, 0xF8, 0xFE, 0xD5, 0x4B, + 0xBF, 0x5A, 0x26, 0x66, 0xDB, 0xDF, 0x4B, 0x23, + 0xCF, 0xF1, 0xD1, 0xB6, 0xF4, 0xAF, 0xC9, 0x85, + 0xB2, 0xE6, 0xD3, 0x30, 0x5A, 0x9F, 0xF8, 0x0F + }, + { + 0x7D, 0xB4, 0x42, 0xE1, 0x32, 0xBA, 0x59, 0xBC, + 0x12, 0x89, 0xAA, 0x98, 0xB0, 0xD3, 0xE8, 0x06, + 0x00, 0x4F, 0x8E, 0xC1, 0x28, 0x11, 0xAF, 0x1E, + 0x2E, 0x33, 0xC6, 0x9B, 0xFD, 0xE7, 0x29, 0xE1 + }, + { + 0x25, 0x0F, 0x37, 0xCD, 0xC1, 0x5E, 0x81, 0x7D, + 0x2F, 0x16, 0x0D, 0x99, 0x56, 0xC7, 0x1F, 0xE3, + 0xEB, 0x5D, 0xB7, 0x45, 0x56, 0xE4, 0xAD, 0xF9, + 0xA4, 0xFF, 0xAF, 0xBA, 0x74, 0x01, 0x03, 0x96 + }, + { + 0x4A, 0xB8, 0xA3, 0xDD, 0x1D, 0xDF, 0x8A, 0xD4, + 0x3D, 0xAB, 0x13, 0xA2, 0x7F, 0x66, 0xA6, 0x54, + 0x4F, 0x29, 0x05, 0x97, 0xFA, 0x96, 0x04, 0x0E, + 0x0E, 0x1D, 0xB9, 0x26, 0x3A, 0xA4, 0x79, 0xF8 + }, + { + 0xEE, 0x61, 0x72, 0x7A, 0x07, 0x66, 0xDF, 0x93, + 0x9C, 0xCD, 0xC8, 0x60, 0x33, 0x40, 0x44, 0xC7, + 0x9A, 0x3C, 0x9B, 0x15, 0x62, 0x00, 0xBC, 0x3A, + 0xA3, 0x29, 0x73, 0x48, 0x3D, 0x83, 0x41, 0xAE + }, + { + 0x3F, 0x68, 0xC7, 0xEC, 0x63, 0xAC, 0x11, 0xEB, + 0xB9, 0x8F, 0x94, 0xB3, 0x39, 0xB0, 0x5C, 0x10, + 0x49, 0x84, 0xFD, 0xA5, 0x01, 0x03, 0x06, 0x01, + 0x44, 0xE5, 0xA2, 0xBF, 0xCC, 0xC9, 0xDA, 0x95 + }, + { + 0x05, 0x6F, 0x29, 0x81, 0x6B, 0x8A, 0xF8, 0xF5, + 0x66, 0x82, 0xBC, 0x4D, 0x7C, 0xF0, 0x94, 0x11, + 0x1D, 0xA7, 0x73, 0x3E, 0x72, 0x6C, 0xD1, 0x3D, + 0x6B, 0x3E, 0x8E, 0xA0, 0x3E, 0x92, 0xA0, 0xD5 + }, + { + 0xF5, 0xEC, 0x43, 0xA2, 0x8A, 0xCB, 0xEF, 0xF1, + 0xF3, 0x31, 0x8A, 0x5B, 0xCA, 0xC7, 0xC6, 0x6D, + 0xDB, 0x52, 0x30, 0xB7, 0x9D, 0xB2, 0xD1, 0x05, + 0xBC, 0xBE, 0x15, 0xF3, 0xC1, 0x14, 0x8D, 0x69 + }, + { + 0x2A, 0x69, 0x60, 0xAD, 0x1D, 0x8D, 0xD5, 0x47, + 0x55, 0x5C, 0xFB, 0xD5, 0xE4, 0x60, 0x0F, 0x1E, + 0xAA, 0x1C, 0x8E, 0xDA, 0x34, 0xDE, 0x03, 0x74, + 0xEC, 0x4A, 0x26, 0xEA, 0xAA, 0xA3, 0x3B, 0x4E + }, + { + 0xDC, 0xC1, 0xEA, 0x7B, 0xAA, 0xB9, 0x33, 0x84, + 0xF7, 0x6B, 0x79, 0x68, 0x66, 0x19, 0x97, 0x54, + 0x74, 0x2F, 0x7B, 0x96, 0xD6, 0xB4, 0xC1, 0x20, + 0x16, 0x5C, 0x04, 0xA6, 0xC4, 0xF5, 0xCE, 0x10 + }, + { + 0x13, 0xD5, 0xDF, 0x17, 0x92, 0x21, 0x37, 0x9C, + 0x6A, 0x78, 0xC0, 0x7C, 0x79, 0x3F, 0xF5, 0x34, + 0x87, 0xCA, 0xE6, 0xBF, 0x9F, 0xE8, 0x82, 0x54, + 0x1A, 0xB0, 0xE7, 0x35, 0xE3, 0xEA, 0xDA, 0x3B + }, + { + 0x8C, 0x59, 0xE4, 0x40, 0x76, 0x41, 0xA0, 0x1E, + 0x8F, 0xF9, 0x1F, 0x99, 0x80, 0xDC, 0x23, 0x6F, + 0x4E, 0xCD, 0x6F, 0xCF, 0x52, 0x58, 0x9A, 0x09, + 0x9A, 0x96, 0x16, 0x33, 0x96, 0x77, 0x14, 0xE1 + }, + { + 0x83, 0x3B, 0x1A, 0xC6, 0xA2, 0x51, 0xFD, 0x08, + 0xFD, 0x6D, 0x90, 0x8F, 0xEA, 0x2A, 0x4E, 0xE1, + 0xE0, 0x40, 0xBC, 0xA9, 0x3F, 0xC1, 0xA3, 0x8E, + 0xC3, 0x82, 0x0E, 0x0C, 0x10, 0xBD, 0x82, 0xEA + }, + { + 0xA2, 0x44, 0xF9, 0x27, 0xF3, 0xB4, 0x0B, 0x8F, + 0x6C, 0x39, 0x15, 0x70, 0xC7, 0x65, 0x41, 0x8F, + 0x2F, 0x6E, 0x70, 0x8E, 0xAC, 0x90, 0x06, 0xC5, + 0x1A, 0x7F, 0xEF, 0xF4, 0xAF, 0x3B, 0x2B, 0x9E + }, + { + 0x3D, 0x99, 0xED, 0x95, 0x50, 0xCF, 0x11, 0x96, + 0xE6, 0xC4, 0xD2, 0x0C, 0x25, 0x96, 0x20, 0xF8, + 0x58, 0xC3, 0xD7, 0x03, 0x37, 0x4C, 0x12, 0x8C, + 0xE7, 0xB5, 0x90, 0x31, 0x0C, 0x83, 0x04, 0x6D + }, + { + 0x2B, 0x35, 0xC4, 0x7D, 0x7B, 0x87, 0x76, 0x1F, + 0x0A, 0xE4, 0x3A, 0xC5, 0x6A, 0xC2, 0x7B, 0x9F, + 0x25, 0x83, 0x03, 0x67, 0xB5, 0x95, 0xBE, 0x8C, + 0x24, 0x0E, 0x94, 0x60, 0x0C, 0x6E, 0x33, 0x12 + }, + { + 0x5D, 0x11, 0xED, 0x37, 0xD2, 0x4D, 0xC7, 0x67, + 0x30, 0x5C, 0xB7, 0xE1, 0x46, 0x7D, 0x87, 0xC0, + 0x65, 0xAC, 0x4B, 0xC8, 0xA4, 0x26, 0xDE, 0x38, + 0x99, 0x1F, 0xF5, 0x9A, 0xA8, 0x73, 0x5D, 0x02 + }, + { + 0xB8, 0x36, 0x47, 0x8E, 0x1C, 0xA0, 0x64, 0x0D, + 0xCE, 0x6F, 0xD9, 0x10, 0xA5, 0x09, 0x62, 0x72, + 0xC8, 0x33, 0x09, 0x90, 0xCD, 0x97, 0x86, 0x4A, + 0xC2, 0xBF, 0x14, 0xEF, 0x6B, 0x23, 0x91, 0x4A + }, + { + 0x91, 0x00, 0xF9, 0x46, 0xD6, 0xCC, 0xDE, 0x3A, + 0x59, 0x7F, 0x90, 0xD3, 0x9F, 0xC1, 0x21, 0x5B, + 0xAD, 0xDC, 0x74, 0x13, 0x64, 0x3D, 0x85, 0xC2, + 0x1C, 0x3E, 0xEE, 0x5D, 0x2D, 0xD3, 0x28, 0x94 + }, + { + 0xDA, 0x70, 0xEE, 0xDD, 0x23, 0xE6, 0x63, 0xAA, + 0x1A, 0x74, 0xB9, 0x76, 0x69, 0x35, 0xB4, 0x79, + 0x22, 0x2A, 0x72, 0xAF, 0xBA, 0x5C, 0x79, 0x51, + 0x58, 0xDA, 0xD4, 0x1A, 0x3B, 0xD7, 0x7E, 0x40 + }, + { + 0xF0, 0x67, 0xED, 0x6A, 0x0D, 0xBD, 0x43, 0xAA, + 0x0A, 0x92, 0x54, 0xE6, 0x9F, 0xD6, 0x6B, 0xDD, + 0x8A, 0xCB, 0x87, 0xDE, 0x93, 0x6C, 0x25, 0x8C, + 0xFB, 0x02, 0x28, 0x5F, 0x2C, 0x11, 0xFA, 0x79 + }, + { + 0x71, 0x5C, 0x99, 0xC7, 0xD5, 0x75, 0x80, 0xCF, + 0x97, 0x53, 0xB4, 0xC1, 0xD7, 0x95, 0xE4, 0x5A, + 0x83, 0xFB, 0xB2, 0x28, 0xC0, 0xD3, 0x6F, 0xBE, + 0x20, 0xFA, 0xF3, 0x9B, 0xDD, 0x6D, 0x4E, 0x85 + }, + { + 0xE4, 0x57, 0xD6, 0xAD, 0x1E, 0x67, 0xCB, 0x9B, + 0xBD, 0x17, 0xCB, 0xD6, 0x98, 0xFA, 0x6D, 0x7D, + 0xAE, 0x0C, 0x9B, 0x7A, 0xD6, 0xCB, 0xD6, 0x53, + 0x96, 0x34, 0xE3, 0x2A, 0x71, 0x9C, 0x84, 0x92 + }, + { + 0xEC, 0xE3, 0xEA, 0x81, 0x03, 0xE0, 0x24, 0x83, + 0xC6, 0x4A, 0x70, 0xA4, 0xBD, 0xCE, 0xE8, 0xCE, + 0xB6, 0x27, 0x8F, 0x25, 0x33, 0xF3, 0xF4, 0x8D, + 0xBE, 0xED, 0xFB, 0xA9, 0x45, 0x31, 0xD4, 0xAE + }, + { + 0x38, 0x8A, 0xA5, 0xD3, 0x66, 0x7A, 0x97, 0xC6, + 0x8D, 0x3D, 0x56, 0xF8, 0xF3, 0xEE, 0x8D, 0x3D, + 0x36, 0x09, 0x1F, 0x17, 0xFE, 0x5D, 0x1B, 0x0D, + 0x5D, 0x84, 0xC9, 0x3B, 0x2F, 0xFE, 0x40, 0xBD + }, + { + 0x8B, 0x6B, 0x31, 0xB9, 0xAD, 0x7C, 0x3D, 0x5C, + 0xD8, 0x4B, 0xF9, 0x89, 0x47, 0xB9, 0xCD, 0xB5, + 0x9D, 0xF8, 0xA2, 0x5F, 0xF7, 0x38, 0x10, 0x10, + 0x13, 0xBE, 0x4F, 0xD6, 0x5E, 0x1D, 0xD1, 0xA3 + }, + { + 0x06, 0x62, 0x91, 0xF6, 0xBB, 0xD2, 0x5F, 0x3C, + 0x85, 0x3D, 0xB7, 0xD8, 0xB9, 0x5C, 0x9A, 0x1C, + 0xFB, 0x9B, 0xF1, 0xC1, 0xC9, 0x9F, 0xB9, 0x5A, + 0x9B, 0x78, 0x69, 0xD9, 0x0F, 0x1C, 0x29, 0x03 + }, + { + 0xA7, 0x07, 0xEF, 0xBC, 0xCD, 0xCE, 0xED, 0x42, + 0x96, 0x7A, 0x66, 0xF5, 0x53, 0x9B, 0x93, 0xED, + 0x75, 0x60, 0xD4, 0x67, 0x30, 0x40, 0x16, 0xC4, + 0x78, 0x0D, 0x77, 0x55, 0xA5, 0x65, 0xD4, 0xC4 + }, + { + 0x38, 0xC5, 0x3D, 0xFB, 0x70, 0xBE, 0x7E, 0x79, + 0x2B, 0x07, 0xA6, 0xA3, 0x5B, 0x8A, 0x6A, 0x0A, + 0xBA, 0x02, 0xC5, 0xC5, 0xF3, 0x8B, 0xAF, 0x5C, + 0x82, 0x3F, 0xDF, 0xD9, 0xE4, 0x2D, 0x65, 0x7E + }, + { + 0xF2, 0x91, 0x13, 0x86, 0x50, 0x1D, 0x9A, 0xB9, + 0xD7, 0x20, 0xCF, 0x8A, 0xD1, 0x05, 0x03, 0xD5, + 0x63, 0x4B, 0xF4, 0xB7, 0xD1, 0x2B, 0x56, 0xDF, + 0xB7, 0x4F, 0xEC, 0xC6, 0xE4, 0x09, 0x3F, 0x68 + }, + { + 0xC6, 0xF2, 0xBD, 0xD5, 0x2B, 0x81, 0xE6, 0xE4, + 0xF6, 0x59, 0x5A, 0xBD, 0x4D, 0x7F, 0xB3, 0x1F, + 0x65, 0x11, 0x69, 0xD0, 0x0F, 0xF3, 0x26, 0x92, + 0x6B, 0x34, 0x94, 0x7B, 0x28, 0xA8, 0x39, 0x59 + }, + { + 0x29, 0x3D, 0x94, 0xB1, 0x8C, 0x98, 0xBB, 0x32, + 0x23, 0x36, 0x6B, 0x8C, 0xE7, 0x4C, 0x28, 0xFB, + 0xDF, 0x28, 0xE1, 0xF8, 0x4A, 0x33, 0x50, 0xB0, + 0xEB, 0x2D, 0x18, 0x04, 0xA5, 0x77, 0x57, 0x9B + }, + { + 0x2C, 0x2F, 0xA5, 0xC0, 0xB5, 0x15, 0x33, 0x16, + 0x5B, 0xC3, 0x75, 0xC2, 0x2E, 0x27, 0x81, 0x76, + 0x82, 0x70, 0xA3, 0x83, 0x98, 0x5D, 0x13, 0xBD, + 0x6B, 0x67, 0xB6, 0xFD, 0x67, 0xF8, 0x89, 0xEB + }, + { + 0xCA, 0xA0, 0x9B, 0x82, 0xB7, 0x25, 0x62, 0xE4, + 0x3F, 0x4B, 0x22, 0x75, 0xC0, 0x91, 0x91, 0x8E, + 0x62, 0x4D, 0x91, 0x16, 0x61, 0xCC, 0x81, 0x1B, + 0xB5, 0xFA, 0xEC, 0x51, 0xF6, 0x08, 0x8E, 0xF7 + }, + { + 0x24, 0x76, 0x1E, 0x45, 0xE6, 0x74, 0x39, 0x53, + 0x79, 0xFB, 0x17, 0x72, 0x9C, 0x78, 0xCB, 0x93, + 0x9E, 0x6F, 0x74, 0xC5, 0xDF, 0xFB, 0x9C, 0x96, + 0x1F, 0x49, 0x59, 0x82, 0xC3, 0xED, 0x1F, 0xE3 + }, + { + 0x55, 0xB7, 0x0A, 0x82, 0x13, 0x1E, 0xC9, 0x48, + 0x88, 0xD7, 0xAB, 0x54, 0xA7, 0xC5, 0x15, 0x25, + 0x5C, 0x39, 0x38, 0xBB, 0x10, 0xBC, 0x78, 0x4D, + 0xC9, 0xB6, 0x7F, 0x07, 0x6E, 0x34, 0x1A, 0x73 + }, + { + 0x6A, 0xB9, 0x05, 0x7B, 0x97, 0x7E, 0xBC, 0x3C, + 0xA4, 0xD4, 0xCE, 0x74, 0x50, 0x6C, 0x25, 0xCC, + 0xCD, 0xC5, 0x66, 0x49, 0x7C, 0x45, 0x0B, 0x54, + 0x15, 0xA3, 0x94, 0x86, 0xF8, 0x65, 0x7A, 0x03 + }, + { + 0x24, 0x06, 0x6D, 0xEE, 0xE0, 0xEC, 0xEE, 0x15, + 0xA4, 0x5F, 0x0A, 0x32, 0x6D, 0x0F, 0x8D, 0xBC, + 0x79, 0x76, 0x1E, 0xBB, 0x93, 0xCF, 0x8C, 0x03, + 0x77, 0xAF, 0x44, 0x09, 0x78, 0xFC, 0xF9, 0x94 + }, + { + 0x20, 0x00, 0x0D, 0x3F, 0x66, 0xBA, 0x76, 0x86, + 0x0D, 0x5A, 0x95, 0x06, 0x88, 0xB9, 0xAA, 0x0D, + 0x76, 0xCF, 0xEA, 0x59, 0xB0, 0x05, 0xD8, 0x59, + 0x91, 0x4B, 0x1A, 0x46, 0x65, 0x3A, 0x93, 0x9B + }, + { + 0xB9, 0x2D, 0xAA, 0x79, 0x60, 0x3E, 0x3B, 0xDB, + 0xC3, 0xBF, 0xE0, 0xF4, 0x19, 0xE4, 0x09, 0xB2, + 0xEA, 0x10, 0xDC, 0x43, 0x5B, 0xEE, 0xFE, 0x29, + 0x59, 0xDA, 0x16, 0x89, 0x5D, 0x5D, 0xCA, 0x1C + }, + { + 0xE9, 0x47, 0x94, 0x87, 0x05, 0xB2, 0x06, 0xD5, + 0x72, 0xB0, 0xE8, 0xF6, 0x2F, 0x66, 0xA6, 0x55, + 0x1C, 0xBD, 0x6B, 0xC3, 0x05, 0xD2, 0x6C, 0xE7, + 0x53, 0x9A, 0x12, 0xF9, 0xAA, 0xDF, 0x75, 0x71 + }, + { + 0x3D, 0x67, 0xC1, 0xB3, 0xF9, 0xB2, 0x39, 0x10, + 0xE3, 0xD3, 0x5E, 0x6B, 0x0F, 0x2C, 0xCF, 0x44, + 0xA0, 0xB5, 0x40, 0xA4, 0x5C, 0x18, 0xBA, 0x3C, + 0x36, 0x26, 0x4D, 0xD4, 0x8E, 0x96, 0xAF, 0x6A + }, + { + 0xC7, 0x55, 0x8B, 0xAB, 0xDA, 0x04, 0xBC, 0xCB, + 0x76, 0x4D, 0x0B, 0xBF, 0x33, 0x58, 0x42, 0x51, + 0x41, 0x90, 0x2D, 0x22, 0x39, 0x1D, 0x9F, 0x8C, + 0x59, 0x15, 0x9F, 0xEC, 0x9E, 0x49, 0xB1, 0x51 + }, + { + 0x0B, 0x73, 0x2B, 0xB0, 0x35, 0x67, 0x5A, 0x50, + 0xFF, 0x58, 0xF2, 0xC2, 0x42, 0xE4, 0x71, 0x0A, + 0xEC, 0xE6, 0x46, 0x70, 0x07, 0x9C, 0x13, 0x04, + 0x4C, 0x79, 0xC9, 0xB7, 0x49, 0x1F, 0x70, 0x00 + }, + { + 0xD1, 0x20, 0xB5, 0xEF, 0x6D, 0x57, 0xEB, 0xF0, + 0x6E, 0xAF, 0x96, 0xBC, 0x93, 0x3C, 0x96, 0x7B, + 0x16, 0xCB, 0xE6, 0xE2, 0xBF, 0x00, 0x74, 0x1C, + 0x30, 0xAA, 0x1C, 0x54, 0xBA, 0x64, 0x80, 0x1F + }, + { + 0x58, 0xD2, 0x12, 0xAD, 0x6F, 0x58, 0xAE, 0xF0, + 0xF8, 0x01, 0x16, 0xB4, 0x41, 0xE5, 0x7F, 0x61, + 0x95, 0xBF, 0xEF, 0x26, 0xB6, 0x14, 0x63, 0xED, + 0xEC, 0x11, 0x83, 0xCD, 0xB0, 0x4F, 0xE7, 0x6D + }, + { + 0xB8, 0x83, 0x6F, 0x51, 0xD1, 0xE2, 0x9B, 0xDF, + 0xDB, 0xA3, 0x25, 0x56, 0x53, 0x60, 0x26, 0x8B, + 0x8F, 0xAD, 0x62, 0x74, 0x73, 0xED, 0xEC, 0xEF, + 0x7E, 0xAE, 0xFE, 0xE8, 0x37, 0xC7, 0x40, 0x03 + }, + { + 0xC5, 0x47, 0xA3, 0xC1, 0x24, 0xAE, 0x56, 0x85, + 0xFF, 0xA7, 0xB8, 0xED, 0xAF, 0x96, 0xEC, 0x86, + 0xF8, 0xB2, 0xD0, 0xD5, 0x0C, 0xEE, 0x8B, 0xE3, + 0xB1, 0xF0, 0xC7, 0x67, 0x63, 0x06, 0x9D, 0x9C + }, + { + 0x5D, 0x16, 0x8B, 0x76, 0x9A, 0x2F, 0x67, 0x85, + 0x3D, 0x62, 0x95, 0xF7, 0x56, 0x8B, 0xE4, 0x0B, + 0xB7, 0xA1, 0x6B, 0x8D, 0x65, 0xBA, 0x87, 0x63, + 0x5D, 0x19, 0x78, 0xD2, 0xAB, 0x11, 0xBA, 0x2A + }, + { + 0xA2, 0xF6, 0x75, 0xDC, 0x73, 0x02, 0x63, 0x8C, + 0xB6, 0x02, 0x01, 0x06, 0x4C, 0xA5, 0x50, 0x77, + 0x71, 0x4D, 0x71, 0xFE, 0x09, 0x6A, 0x31, 0x5F, + 0x2F, 0xE7, 0x40, 0x12, 0x77, 0xCA, 0xA5, 0xAF + }, + { + 0xC8, 0xAA, 0xB5, 0xCD, 0x01, 0x60, 0xAE, 0x78, + 0xCD, 0x2E, 0x8A, 0xC5, 0xFB, 0x0E, 0x09, 0x3C, + 0xDB, 0x5C, 0x4B, 0x60, 0x52, 0xA0, 0xA9, 0x7B, + 0xB0, 0x42, 0x16, 0x82, 0x6F, 0xA7, 0xA4, 0x37 + }, + { + 0xFF, 0x68, 0xCA, 0x40, 0x35, 0xBF, 0xEB, 0x43, + 0xFB, 0xF1, 0x45, 0xFD, 0xDD, 0x5E, 0x43, 0xF1, + 0xCE, 0xA5, 0x4F, 0x11, 0xF7, 0xBE, 0xE1, 0x30, + 0x58, 0xF0, 0x27, 0x32, 0x9A, 0x4A, 0x5F, 0xA4 + }, + { + 0x1D, 0x4E, 0x54, 0x87, 0xAE, 0x3C, 0x74, 0x0F, + 0x2B, 0xA6, 0xE5, 0x41, 0xAC, 0x91, 0xBC, 0x2B, + 0xFC, 0xD2, 0x99, 0x9C, 0x51, 0x8D, 0x80, 0x7B, + 0x42, 0x67, 0x48, 0x80, 0x3A, 0x35, 0x0F, 0xD4 + }, + { + 0x6D, 0x24, 0x4E, 0x1A, 0x06, 0xCE, 0x4E, 0xF5, + 0x78, 0xDD, 0x0F, 0x63, 0xAF, 0xF0, 0x93, 0x67, + 0x06, 0x73, 0x51, 0x19, 0xCA, 0x9C, 0x8D, 0x22, + 0xD8, 0x6C, 0x80, 0x14, 0x14, 0xAB, 0x97, 0x41 + }, + { + 0xDE, 0xCF, 0x73, 0x29, 0xDB, 0xCC, 0x82, 0x7B, + 0x8F, 0xC5, 0x24, 0xC9, 0x43, 0x1E, 0x89, 0x98, + 0x02, 0x9E, 0xCE, 0x12, 0xCE, 0x93, 0xB7, 0xB2, + 0xF3, 0xE7, 0x69, 0xA9, 0x41, 0xFB, 0x8C, 0xEA + }, + { + 0x2F, 0xAF, 0xCC, 0x0F, 0x2E, 0x63, 0xCB, 0xD0, + 0x77, 0x55, 0xBE, 0x7B, 0x75, 0xEC, 0xEA, 0x0A, + 0xDF, 0xF9, 0xAA, 0x5E, 0xDE, 0x2A, 0x52, 0xFD, + 0xAB, 0x4D, 0xFD, 0x03, 0x74, 0xCD, 0x48, 0x3F + }, + { + 0xAA, 0x85, 0x01, 0x0D, 0xD4, 0x6A, 0x54, 0x6B, + 0x53, 0x5E, 0xF4, 0xCF, 0x5F, 0x07, 0xD6, 0x51, + 0x61, 0xE8, 0x98, 0x28, 0xF3, 0xA7, 0x7D, 0xB7, + 0xB9, 0xB5, 0x6F, 0x0D, 0xF5, 0x9A, 0xAE, 0x45 + }, + { + 0x07, 0xE8, 0xE1, 0xEE, 0x73, 0x2C, 0xB0, 0xD3, + 0x56, 0xC9, 0xC0, 0xD1, 0x06, 0x9C, 0x89, 0xD1, + 0x7A, 0xDF, 0x6A, 0x9A, 0x33, 0x4F, 0x74, 0x5E, + 0xC7, 0x86, 0x73, 0x32, 0x54, 0x8C, 0xA8, 0xE9 + }, + { + 0x0E, 0x01, 0xE8, 0x1C, 0xAD, 0xA8, 0x16, 0x2B, + 0xFD, 0x5F, 0x8A, 0x8C, 0x81, 0x8A, 0x6C, 0x69, + 0xFE, 0xDF, 0x02, 0xCE, 0xB5, 0x20, 0x85, 0x23, + 0xCB, 0xE5, 0x31, 0x3B, 0x89, 0xCA, 0x10, 0x53 + }, + { + 0x6B, 0xB6, 0xC6, 0x47, 0x26, 0x55, 0x08, 0x43, + 0x99, 0x85, 0x2E, 0x00, 0x24, 0x9F, 0x8C, 0xB2, + 0x47, 0x89, 0x6D, 0x39, 0x2B, 0x02, 0xD7, 0x3B, + 0x7F, 0x0D, 0xD8, 0x18, 0xE1, 0xE2, 0x9B, 0x07 + }, + { + 0x42, 0xD4, 0x63, 0x6E, 0x20, 0x60, 0xF0, 0x8F, + 0x41, 0xC8, 0x82, 0xE7, 0x6B, 0x39, 0x6B, 0x11, + 0x2E, 0xF6, 0x27, 0xCC, 0x24, 0xC4, 0x3D, 0xD5, + 0xF8, 0x3A, 0x1D, 0x1A, 0x7E, 0xAD, 0x71, 0x1A + }, + { + 0x48, 0x58, 0xC9, 0xA1, 0x88, 0xB0, 0x23, 0x4F, + 0xB9, 0xA8, 0xD4, 0x7D, 0x0B, 0x41, 0x33, 0x65, + 0x0A, 0x03, 0x0B, 0xD0, 0x61, 0x1B, 0x87, 0xC3, + 0x89, 0x2E, 0x94, 0x95, 0x1F, 0x8D, 0xF8, 0x52 + }, + { + 0x3F, 0xAB, 0x3E, 0x36, 0x98, 0x8D, 0x44, 0x5A, + 0x51, 0xC8, 0x78, 0x3E, 0x53, 0x1B, 0xE3, 0xA0, + 0x2B, 0xE4, 0x0C, 0xD0, 0x47, 0x96, 0xCF, 0xB6, + 0x1D, 0x40, 0x34, 0x74, 0x42, 0xD3, 0xF7, 0x94 + }, + { + 0xEB, 0xAB, 0xC4, 0x96, 0x36, 0xBD, 0x43, 0x3D, + 0x2E, 0xC8, 0xF0, 0xE5, 0x18, 0x73, 0x2E, 0xF8, + 0xFA, 0x21, 0xD4, 0xD0, 0x71, 0xCC, 0x3B, 0xC4, + 0x6C, 0xD7, 0x9F, 0xA3, 0x8A, 0x28, 0xB8, 0x10 + }, + { + 0xA1, 0xD0, 0x34, 0x35, 0x23, 0xB8, 0x93, 0xFC, + 0xA8, 0x4F, 0x47, 0xFE, 0xB4, 0xA6, 0x4D, 0x35, + 0x0A, 0x17, 0xD8, 0xEE, 0xF5, 0x49, 0x7E, 0xCE, + 0x69, 0x7D, 0x02, 0xD7, 0x91, 0x78, 0xB5, 0x91 + }, + { + 0x26, 0x2E, 0xBF, 0xD9, 0x13, 0x0B, 0x7D, 0x28, + 0x76, 0x0D, 0x08, 0xEF, 0x8B, 0xFD, 0x3B, 0x86, + 0xCD, 0xD3, 0xB2, 0x11, 0x3D, 0x2C, 0xAE, 0xF7, + 0xEA, 0x95, 0x1A, 0x30, 0x3D, 0xFA, 0x38, 0x46 + }, + { + 0xF7, 0x61, 0x58, 0xED, 0xD5, 0x0A, 0x15, 0x4F, + 0xA7, 0x82, 0x03, 0xED, 0x23, 0x62, 0x93, 0x2F, + 0xCB, 0x82, 0x53, 0xAA, 0xE3, 0x78, 0x90, 0x3E, + 0xDE, 0xD1, 0xE0, 0x3F, 0x70, 0x21, 0xA2, 0x57 + }, + { + 0x26, 0x17, 0x8E, 0x95, 0x0A, 0xC7, 0x22, 0xF6, + 0x7A, 0xE5, 0x6E, 0x57, 0x1B, 0x28, 0x4C, 0x02, + 0x07, 0x68, 0x4A, 0x63, 0x34, 0xA1, 0x77, 0x48, + 0xA9, 0x4D, 0x26, 0x0B, 0xC5, 0xF5, 0x52, 0x74 + }, + { + 0xC3, 0x78, 0xD1, 0xE4, 0x93, 0xB4, 0x0E, 0xF1, + 0x1F, 0xE6, 0xA1, 0x5D, 0x9C, 0x27, 0x37, 0xA3, + 0x78, 0x09, 0x63, 0x4C, 0x5A, 0xBA, 0xD5, 0xB3, + 0x3D, 0x7E, 0x39, 0x3B, 0x4A, 0xE0, 0x5D, 0x03 + }, + { + 0x98, 0x4B, 0xD8, 0x37, 0x91, 0x01, 0xBE, 0x8F, + 0xD8, 0x06, 0x12, 0xD8, 0xEA, 0x29, 0x59, 0xA7, + 0x86, 0x5E, 0xC9, 0x71, 0x85, 0x23, 0x55, 0x01, + 0x07, 0xAE, 0x39, 0x38, 0xDF, 0x32, 0x01, 0x1B + }, + { + 0xC6, 0xF2, 0x5A, 0x81, 0x2A, 0x14, 0x48, 0x58, + 0xAC, 0x5C, 0xED, 0x37, 0xA9, 0x3A, 0x9F, 0x47, + 0x59, 0xBA, 0x0B, 0x1C, 0x0F, 0xDC, 0x43, 0x1D, + 0xCE, 0x35, 0xF9, 0xEC, 0x1F, 0x1F, 0x4A, 0x99 + }, + { + 0x92, 0x4C, 0x75, 0xC9, 0x44, 0x24, 0xFF, 0x75, + 0xE7, 0x4B, 0x8B, 0x4E, 0x94, 0x35, 0x89, 0x58, + 0xB0, 0x27, 0xB1, 0x71, 0xDF, 0x5E, 0x57, 0x89, + 0x9A, 0xD0, 0xD4, 0xDA, 0xC3, 0x73, 0x53, 0xB6 + }, + { + 0x0A, 0xF3, 0x58, 0x92, 0xA6, 0x3F, 0x45, 0x93, + 0x1F, 0x68, 0x46, 0xED, 0x19, 0x03, 0x61, 0xCD, + 0x07, 0x30, 0x89, 0xE0, 0x77, 0x16, 0x57, 0x14, + 0xB5, 0x0B, 0x81, 0xA2, 0xE3, 0xDD, 0x9B, 0xA1 + }, + { + 0xCC, 0x80, 0xCE, 0xFB, 0x26, 0xC3, 0xB2, 0xB0, + 0xDA, 0xEF, 0x23, 0x3E, 0x60, 0x6D, 0x5F, 0xFC, + 0x80, 0xFA, 0x17, 0x42, 0x7D, 0x18, 0xE3, 0x04, + 0x89, 0x67, 0x3E, 0x06, 0xEF, 0x4B, 0x87, 0xF7 + }, + { + 0xC2, 0xF8, 0xC8, 0x11, 0x74, 0x47, 0xF3, 0x97, + 0x8B, 0x08, 0x18, 0xDC, 0xF6, 0xF7, 0x01, 0x16, + 0xAC, 0x56, 0xFD, 0x18, 0x4D, 0xD1, 0x27, 0x84, + 0x94, 0xE1, 0x03, 0xFC, 0x6D, 0x74, 0xA8, 0x87 + }, + { + 0xBD, 0xEC, 0xF6, 0xBF, 0xC1, 0xBA, 0x0D, 0xF6, + 0xE8, 0x62, 0xC8, 0x31, 0x99, 0x22, 0x07, 0x79, + 0x6A, 0xCC, 0x79, 0x79, 0x68, 0x35, 0x88, 0x28, + 0xC0, 0x6E, 0x7A, 0x51, 0xE0, 0x90, 0x09, 0x8F + }, + { + 0x24, 0xD1, 0xA2, 0x6E, 0x3D, 0xAB, 0x02, 0xFE, + 0x45, 0x72, 0xD2, 0xAA, 0x7D, 0xBD, 0x3E, 0xC3, + 0x0F, 0x06, 0x93, 0xDB, 0x26, 0xF2, 0x73, 0xD0, + 0xAB, 0x2C, 0xB0, 0xC1, 0x3B, 0x5E, 0x64, 0x51 + }, + { + 0xEC, 0x56, 0xF5, 0x8B, 0x09, 0x29, 0x9A, 0x30, + 0x0B, 0x14, 0x05, 0x65, 0xD7, 0xD3, 0xE6, 0x87, + 0x82, 0xB6, 0xE2, 0xFB, 0xEB, 0x4B, 0x7E, 0xA9, + 0x7A, 0xC0, 0x57, 0x98, 0x90, 0x61, 0xDD, 0x3F + }, + { + 0x11, 0xA4, 0x37, 0xC1, 0xAB, 0xA3, 0xC1, 0x19, + 0xDD, 0xFA, 0xB3, 0x1B, 0x3E, 0x8C, 0x84, 0x1D, + 0xEE, 0xEB, 0x91, 0x3E, 0xF5, 0x7F, 0x7E, 0x48, + 0xF2, 0xC9, 0xCF, 0x5A, 0x28, 0xFA, 0x42, 0xBC + }, + { + 0x53, 0xC7, 0xE6, 0x11, 0x4B, 0x85, 0x0A, 0x2C, + 0xB4, 0x96, 0xC9, 0xB3, 0xC6, 0x9A, 0x62, 0x3E, + 0xAE, 0xA2, 0xCB, 0x1D, 0x33, 0xDD, 0x81, 0x7E, + 0x47, 0x65, 0xED, 0xAA, 0x68, 0x23, 0xC2, 0x28 + }, + { + 0x15, 0x4C, 0x3E, 0x96, 0xFE, 0xE5, 0xDB, 0x14, + 0xF8, 0x77, 0x3E, 0x18, 0xAF, 0x14, 0x85, 0x79, + 0x13, 0x50, 0x9D, 0xA9, 0x99, 0xB4, 0x6C, 0xDD, + 0x3D, 0x4C, 0x16, 0x97, 0x60, 0xC8, 0x3A, 0xD2 + }, + { + 0x40, 0xB9, 0x91, 0x6F, 0x09, 0x3E, 0x02, 0x7A, + 0x87, 0x86, 0x64, 0x18, 0x18, 0x92, 0x06, 0x20, + 0x47, 0x2F, 0xBC, 0xF6, 0x8F, 0x70, 0x1D, 0x1B, + 0x68, 0x06, 0x32, 0xE6, 0x99, 0x6B, 0xDE, 0xD3 + }, + { + 0x24, 0xC4, 0xCB, 0xBA, 0x07, 0x11, 0x98, 0x31, + 0xA7, 0x26, 0xB0, 0x53, 0x05, 0xD9, 0x6D, 0xA0, + 0x2F, 0xF8, 0xB1, 0x48, 0xF0, 0xDA, 0x44, 0x0F, + 0xE2, 0x33, 0xBC, 0xAA, 0x32, 0xC7, 0x2F, 0x6F + }, + { + 0x5D, 0x20, 0x15, 0x10, 0x25, 0x00, 0x20, 0xB7, + 0x83, 0x68, 0x96, 0x88, 0xAB, 0xBF, 0x8E, 0xCF, + 0x25, 0x94, 0xA9, 0x6A, 0x08, 0xF2, 0xBF, 0xEC, + 0x6C, 0xE0, 0x57, 0x44, 0x65, 0xDD, 0xED, 0x71 + }, + { + 0x04, 0x3B, 0x97, 0xE3, 0x36, 0xEE, 0x6F, 0xDB, + 0xBE, 0x2B, 0x50, 0xF2, 0x2A, 0xF8, 0x32, 0x75, + 0xA4, 0x08, 0x48, 0x05, 0xD2, 0xD5, 0x64, 0x59, + 0x62, 0x45, 0x4B, 0x6C, 0x9B, 0x80, 0x53, 0xA0 + }, + { + 0x56, 0x48, 0x35, 0xCB, 0xAE, 0xA7, 0x74, 0x94, + 0x85, 0x68, 0xBE, 0x36, 0xCF, 0x52, 0xFC, 0xDD, + 0x83, 0x93, 0x4E, 0xB0, 0xA2, 0x75, 0x12, 0xDB, + 0xE3, 0xE2, 0xDB, 0x47, 0xB9, 0xE6, 0x63, 0x5A + }, + { + 0xF2, 0x1C, 0x33, 0xF4, 0x7B, 0xDE, 0x40, 0xA2, + 0xA1, 0x01, 0xC9, 0xCD, 0xE8, 0x02, 0x7A, 0xAF, + 0x61, 0xA3, 0x13, 0x7D, 0xE2, 0x42, 0x2B, 0x30, + 0x03, 0x5A, 0x04, 0xC2, 0x70, 0x89, 0x41, 0x83 + }, + { + 0x9D, 0xB0, 0xEF, 0x74, 0xE6, 0x6C, 0xBB, 0x84, + 0x2E, 0xB0, 0xE0, 0x73, 0x43, 0xA0, 0x3C, 0x5C, + 0x56, 0x7E, 0x37, 0x2B, 0x3F, 0x23, 0xB9, 0x43, + 0xC7, 0x88, 0xA4, 0xF2, 0x50, 0xF6, 0x78, 0x91 + }, + { + 0xAB, 0x8D, 0x08, 0x65, 0x5F, 0xF1, 0xD3, 0xFE, + 0x87, 0x58, 0xD5, 0x62, 0x23, 0x5F, 0xD2, 0x3E, + 0x7C, 0xF9, 0xDC, 0xAA, 0xD6, 0x58, 0x87, 0x2A, + 0x49, 0xE5, 0xD3, 0x18, 0x3B, 0x6C, 0xCE, 0xBD + }, + { + 0x6F, 0x27, 0xF7, 0x7E, 0x7B, 0xCF, 0x46, 0xA1, + 0xE9, 0x63, 0xAD, 0xE0, 0x30, 0x97, 0x33, 0x54, + 0x30, 0x31, 0xDC, 0xCD, 0xD4, 0x7C, 0xAA, 0xC1, + 0x74, 0xD7, 0xD2, 0x7C, 0xE8, 0x07, 0x7E, 0x8B + }, + { + 0xE3, 0xCD, 0x54, 0xDA, 0x7E, 0x44, 0x4C, 0xAA, + 0x62, 0x07, 0x56, 0x95, 0x25, 0xA6, 0x70, 0xEB, + 0xAE, 0x12, 0x78, 0xDE, 0x4E, 0x3F, 0xE2, 0x68, + 0x4B, 0x3E, 0x33, 0xF5, 0xEF, 0x90, 0xCC, 0x1B + }, + { + 0xB2, 0xC3, 0xE3, 0x3A, 0x51, 0xD2, 0x2C, 0x4C, + 0x08, 0xFC, 0x09, 0x89, 0xC8, 0x73, 0xC9, 0xCC, + 0x41, 0x50, 0x57, 0x9B, 0x1E, 0x61, 0x63, 0xFA, + 0x69, 0x4A, 0xD5, 0x1D, 0x53, 0xD7, 0x12, 0xDC + }, + { + 0xBE, 0x7F, 0xDA, 0x98, 0x3E, 0x13, 0x18, 0x9B, + 0x4C, 0x77, 0xE0, 0xA8, 0x09, 0x20, 0xB6, 0xE0, + 0xE0, 0xEA, 0x80, 0xC3, 0xB8, 0x4D, 0xBE, 0x7E, + 0x71, 0x17, 0xD2, 0x53, 0xF4, 0x81, 0x12, 0xF4 + }, + { + 0xB6, 0x00, 0x8C, 0x28, 0xFA, 0xE0, 0x8A, 0xA4, + 0x27, 0xE5, 0xBD, 0x3A, 0xAD, 0x36, 0xF1, 0x00, + 0x21, 0xF1, 0x6C, 0x77, 0xCF, 0xEA, 0xBE, 0xD0, + 0x7F, 0x97, 0xCC, 0x7D, 0xC1, 0xF1, 0x28, 0x4A + }, + { + 0x6E, 0x4E, 0x67, 0x60, 0xC5, 0x38, 0xF2, 0xE9, + 0x7B, 0x3A, 0xDB, 0xFB, 0xBC, 0xDE, 0x57, 0xF8, + 0x96, 0x6B, 0x7E, 0xA8, 0xFC, 0xB5, 0xBF, 0x7E, + 0xFE, 0xC9, 0x13, 0xFD, 0x2A, 0x2B, 0x0C, 0x55 + }, + { + 0x4A, 0xE5, 0x1F, 0xD1, 0x83, 0x4A, 0xA5, 0xBD, + 0x9A, 0x6F, 0x7E, 0xC3, 0x9F, 0xC6, 0x63, 0x33, + 0x8D, 0xC5, 0xD2, 0xE2, 0x07, 0x61, 0x56, 0x6D, + 0x90, 0xCC, 0x68, 0xB1, 0xCB, 0x87, 0x5E, 0xD8 + }, + { + 0xB6, 0x73, 0xAA, 0xD7, 0x5A, 0xB1, 0xFD, 0xB5, + 0x40, 0x1A, 0xBF, 0xA1, 0xBF, 0x89, 0xF3, 0xAD, + 0xD2, 0xEB, 0xC4, 0x68, 0xDF, 0x36, 0x24, 0xA4, + 0x78, 0xF4, 0xFE, 0x85, 0x9D, 0x8D, 0x55, 0xE2 + }, + { + 0x13, 0xC9, 0x47, 0x1A, 0x98, 0x55, 0x91, 0x35, + 0x39, 0x83, 0x66, 0x60, 0x39, 0x8D, 0xA0, 0xF3, + 0xF9, 0x9A, 0xDA, 0x08, 0x47, 0x9C, 0x69, 0xD1, + 0xB7, 0xFC, 0xAA, 0x34, 0x61, 0xDD, 0x7E, 0x59 + }, + { + 0x2C, 0x11, 0xF4, 0xA7, 0xF9, 0x9A, 0x1D, 0x23, + 0xA5, 0x8B, 0xB6, 0x36, 0x35, 0x0F, 0xE8, 0x49, + 0xF2, 0x9C, 0xBA, 0xC1, 0xB2, 0xA1, 0x11, 0x2D, + 0x9F, 0x1E, 0xD5, 0xBC, 0x5B, 0x31, 0x3C, 0xCD + }, + { + 0xC7, 0xD3, 0xC0, 0x70, 0x6B, 0x11, 0xAE, 0x74, + 0x1C, 0x05, 0xA1, 0xEF, 0x15, 0x0D, 0xD6, 0x5B, + 0x54, 0x94, 0xD6, 0xD5, 0x4C, 0x9A, 0x86, 0xE2, + 0x61, 0x78, 0x54, 0xE6, 0xAE, 0xEE, 0xBB, 0xD9 + }, + { + 0x19, 0x4E, 0x10, 0xC9, 0x38, 0x93, 0xAF, 0xA0, + 0x64, 0xC3, 0xAC, 0x04, 0xC0, 0xDD, 0x80, 0x8D, + 0x79, 0x1C, 0x3D, 0x4B, 0x75, 0x56, 0xE8, 0x9D, + 0x8D, 0x9C, 0xB2, 0x25, 0xC4, 0xB3, 0x33, 0x39 + }, + { + 0x6F, 0xC4, 0x98, 0x8B, 0x8F, 0x78, 0x54, 0x6B, + 0x16, 0x88, 0x99, 0x18, 0x45, 0x90, 0x8F, 0x13, + 0x4B, 0x6A, 0x48, 0x2E, 0x69, 0x94, 0xB3, 0xD4, + 0x83, 0x17, 0xBF, 0x08, 0xDB, 0x29, 0x21, 0x85 + }, + { + 0x56, 0x65, 0xBE, 0xB8, 0xB0, 0x95, 0x55, 0x25, + 0x81, 0x3B, 0x59, 0x81, 0xCD, 0x14, 0x2E, 0xD4, + 0xD0, 0x3F, 0xBA, 0x38, 0xA6, 0xF3, 0xE5, 0xAD, + 0x26, 0x8E, 0x0C, 0xC2, 0x70, 0xD1, 0xCD, 0x11 + }, + { + 0xB8, 0x83, 0xD6, 0x8F, 0x5F, 0xE5, 0x19, 0x36, + 0x43, 0x1B, 0xA4, 0x25, 0x67, 0x38, 0x05, 0x3B, + 0x1D, 0x04, 0x26, 0xD4, 0xCB, 0x64, 0xB1, 0x6E, + 0x83, 0xBA, 0xDC, 0x5E, 0x9F, 0xBE, 0x3B, 0x81 + }, + { + 0x53, 0xE7, 0xB2, 0x7E, 0xA5, 0x9C, 0x2F, 0x6D, + 0xBB, 0x50, 0x76, 0x9E, 0x43, 0x55, 0x4D, 0xF3, + 0x5A, 0xF8, 0x9F, 0x48, 0x22, 0xD0, 0x46, 0x6B, + 0x00, 0x7D, 0xD6, 0xF6, 0xDE, 0xAF, 0xFF, 0x02 + }, + { + 0x1F, 0x1A, 0x02, 0x29, 0xD4, 0x64, 0x0F, 0x01, + 0x90, 0x15, 0x88, 0xD9, 0xDE, 0xC2, 0x2D, 0x13, + 0xFC, 0x3E, 0xB3, 0x4A, 0x61, 0xB3, 0x29, 0x38, + 0xEF, 0xBF, 0x53, 0x34, 0xB2, 0x80, 0x0A, 0xFA + }, + { + 0xC2, 0xB4, 0x05, 0xAF, 0xA0, 0xFA, 0x66, 0x68, + 0x85, 0x2A, 0xEE, 0x4D, 0x88, 0x04, 0x08, 0x53, + 0xFA, 0xB8, 0x00, 0xE7, 0x2B, 0x57, 0x58, 0x14, + 0x18, 0xE5, 0x50, 0x6F, 0x21, 0x4C, 0x7D, 0x1F + }, + { + 0xC0, 0x8A, 0xA1, 0xC2, 0x86, 0xD7, 0x09, 0xFD, + 0xC7, 0x47, 0x37, 0x44, 0x97, 0x71, 0x88, 0xC8, + 0x95, 0xBA, 0x01, 0x10, 0x14, 0x24, 0x7E, 0x4E, + 0xFA, 0x8D, 0x07, 0xE7, 0x8F, 0xEC, 0x69, 0x5C + }, + { + 0xF0, 0x3F, 0x57, 0x89, 0xD3, 0x33, 0x6B, 0x80, + 0xD0, 0x02, 0xD5, 0x9F, 0xDF, 0x91, 0x8B, 0xDB, + 0x77, 0x5B, 0x00, 0x95, 0x6E, 0xD5, 0x52, 0x8E, + 0x86, 0xAA, 0x99, 0x4A, 0xCB, 0x38, 0xFE, 0x2D + }, +}; + + + + +static const uint8_t blake2s_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0x48, 0xA8, 0x99, 0x7D, 0xA4, 0x07, 0x87, 0x6B, + 0x3D, 0x79, 0xC0, 0xD9, 0x23, 0x25, 0xAD, 0x3B, + 0x89, 0xCB, 0xB7, 0x54, 0xD8, 0x6A, 0xB7, 0x1A, + 0xEE, 0x04, 0x7A, 0xD3, 0x45, 0xFD, 0x2C, 0x49 + }, + { + 0x40, 0xD1, 0x5F, 0xEE, 0x7C, 0x32, 0x88, 0x30, + 0x16, 0x6A, 0xC3, 0xF9, 0x18, 0x65, 0x0F, 0x80, + 0x7E, 0x7E, 0x01, 0xE1, 0x77, 0x25, 0x8C, 0xDC, + 0x0A, 0x39, 0xB1, 0x1F, 0x59, 0x80, 0x66, 0xF1 + }, + { + 0x6B, 0xB7, 0x13, 0x00, 0x64, 0x4C, 0xD3, 0x99, + 0x1B, 0x26, 0xCC, 0xD4, 0xD2, 0x74, 0xAC, 0xD1, + 0xAD, 0xEA, 0xB8, 0xB1, 0xD7, 0x91, 0x45, 0x46, + 0xC1, 0x19, 0x8B, 0xBE, 0x9F, 0xC9, 0xD8, 0x03 + }, + { + 0x1D, 0x22, 0x0D, 0xBE, 0x2E, 0xE1, 0x34, 0x66, + 0x1F, 0xDF, 0x6D, 0x9E, 0x74, 0xB4, 0x17, 0x04, + 0x71, 0x05, 0x56, 0xF2, 0xF6, 0xE5, 0xA0, 0x91, + 0xB2, 0x27, 0x69, 0x74, 0x45, 0xDB, 0xEA, 0x6B + }, + { + 0xF6, 0xC3, 0xFB, 0xAD, 0xB4, 0xCC, 0x68, 0x7A, + 0x00, 0x64, 0xA5, 0xBE, 0x6E, 0x79, 0x1B, 0xEC, + 0x63, 0xB8, 0x68, 0xAD, 0x62, 0xFB, 0xA6, 0x1B, + 0x37, 0x57, 0xEF, 0x9C, 0xA5, 0x2E, 0x05, 0xB2 + }, + { + 0x49, 0xC1, 0xF2, 0x11, 0x88, 0xDF, 0xD7, 0x69, + 0xAE, 0xA0, 0xE9, 0x11, 0xDD, 0x6B, 0x41, 0xF1, + 0x4D, 0xAB, 0x10, 0x9D, 0x2B, 0x85, 0x97, 0x7A, + 0xA3, 0x08, 0x8B, 0x5C, 0x70, 0x7E, 0x85, 0x98 + }, + { + 0xFD, 0xD8, 0x99, 0x3D, 0xCD, 0x43, 0xF6, 0x96, + 0xD4, 0x4F, 0x3C, 0xEA, 0x0F, 0xF3, 0x53, 0x45, + 0x23, 0x4E, 0xC8, 0xEE, 0x08, 0x3E, 0xB3, 0xCA, + 0xDA, 0x01, 0x7C, 0x7F, 0x78, 0xC1, 0x71, 0x43 + }, + { + 0xE6, 0xC8, 0x12, 0x56, 0x37, 0x43, 0x8D, 0x09, + 0x05, 0xB7, 0x49, 0xF4, 0x65, 0x60, 0xAC, 0x89, + 0xFD, 0x47, 0x1C, 0xF8, 0x69, 0x2E, 0x28, 0xFA, + 0xB9, 0x82, 0xF7, 0x3F, 0x01, 0x9B, 0x83, 0xA9 + }, + { + 0x19, 0xFC, 0x8C, 0xA6, 0x97, 0x9D, 0x60, 0xE6, + 0xED, 0xD3, 0xB4, 0x54, 0x1E, 0x2F, 0x96, 0x7C, + 0xED, 0x74, 0x0D, 0xF6, 0xEC, 0x1E, 0xAE, 0xBB, + 0xFE, 0x81, 0x38, 0x32, 0xE9, 0x6B, 0x29, 0x74 + }, + { + 0xA6, 0xAD, 0x77, 0x7C, 0xE8, 0x81, 0xB5, 0x2B, + 0xB5, 0xA4, 0x42, 0x1A, 0xB6, 0xCD, 0xD2, 0xDF, + 0xBA, 0x13, 0xE9, 0x63, 0x65, 0x2D, 0x4D, 0x6D, + 0x12, 0x2A, 0xEE, 0x46, 0x54, 0x8C, 0x14, 0xA7 + }, + { + 0xF5, 0xC4, 0xB2, 0xBA, 0x1A, 0x00, 0x78, 0x1B, + 0x13, 0xAB, 0xA0, 0x42, 0x52, 0x42, 0xC6, 0x9C, + 0xB1, 0x55, 0x2F, 0x3F, 0x71, 0xA9, 0xA3, 0xBB, + 0x22, 0xB4, 0xA6, 0xB4, 0x27, 0x7B, 0x46, 0xDD + }, + { + 0xE3, 0x3C, 0x4C, 0x9B, 0xD0, 0xCC, 0x7E, 0x45, + 0xC8, 0x0E, 0x65, 0xC7, 0x7F, 0xA5, 0x99, 0x7F, + 0xEC, 0x70, 0x02, 0x73, 0x85, 0x41, 0x50, 0x9E, + 0x68, 0xA9, 0x42, 0x38, 0x91, 0xE8, 0x22, 0xA3 + }, + { + 0xFB, 0xA1, 0x61, 0x69, 0xB2, 0xC3, 0xEE, 0x10, + 0x5B, 0xE6, 0xE1, 0xE6, 0x50, 0xE5, 0xCB, 0xF4, + 0x07, 0x46, 0xB6, 0x75, 0x3D, 0x03, 0x6A, 0xB5, + 0x51, 0x79, 0x01, 0x4A, 0xD7, 0xEF, 0x66, 0x51 + }, + { + 0xF5, 0xC4, 0xBE, 0xC6, 0xD6, 0x2F, 0xC6, 0x08, + 0xBF, 0x41, 0xCC, 0x11, 0x5F, 0x16, 0xD6, 0x1C, + 0x7E, 0xFD, 0x3F, 0xF6, 0xC6, 0x56, 0x92, 0xBB, + 0xE0, 0xAF, 0xFF, 0xB1, 0xFE, 0xDE, 0x74, 0x75 + }, + { + 0xA4, 0x86, 0x2E, 0x76, 0xDB, 0x84, 0x7F, 0x05, + 0xBA, 0x17, 0xED, 0xE5, 0xDA, 0x4E, 0x7F, 0x91, + 0xB5, 0x92, 0x5C, 0xF1, 0xAD, 0x4B, 0xA1, 0x27, + 0x32, 0xC3, 0x99, 0x57, 0x42, 0xA5, 0xCD, 0x6E + }, + { + 0x65, 0xF4, 0xB8, 0x60, 0xCD, 0x15, 0xB3, 0x8E, + 0xF8, 0x14, 0xA1, 0xA8, 0x04, 0x31, 0x4A, 0x55, + 0xBE, 0x95, 0x3C, 0xAA, 0x65, 0xFD, 0x75, 0x8A, + 0xD9, 0x89, 0xFF, 0x34, 0xA4, 0x1C, 0x1E, 0xEA + }, + { + 0x19, 0xBA, 0x23, 0x4F, 0x0A, 0x4F, 0x38, 0x63, + 0x7D, 0x18, 0x39, 0xF9, 0xD9, 0xF7, 0x6A, 0xD9, + 0x1C, 0x85, 0x22, 0x30, 0x71, 0x43, 0xC9, 0x7D, + 0x5F, 0x93, 0xF6, 0x92, 0x74, 0xCE, 0xC9, 0xA7 + }, + { + 0x1A, 0x67, 0x18, 0x6C, 0xA4, 0xA5, 0xCB, 0x8E, + 0x65, 0xFC, 0xA0, 0xE2, 0xEC, 0xBC, 0x5D, 0xDC, + 0x14, 0xAE, 0x38, 0x1B, 0xB8, 0xBF, 0xFE, 0xB9, + 0xE0, 0xA1, 0x03, 0x44, 0x9E, 0x3E, 0xF0, 0x3C + }, + { + 0xAF, 0xBE, 0xA3, 0x17, 0xB5, 0xA2, 0xE8, 0x9C, + 0x0B, 0xD9, 0x0C, 0xCF, 0x5D, 0x7F, 0xD0, 0xED, + 0x57, 0xFE, 0x58, 0x5E, 0x4B, 0xE3, 0x27, 0x1B, + 0x0A, 0x6B, 0xF0, 0xF5, 0x78, 0x6B, 0x0F, 0x26 + }, + { + 0xF1, 0xB0, 0x15, 0x58, 0xCE, 0x54, 0x12, 0x62, + 0xF5, 0xEC, 0x34, 0x29, 0x9D, 0x6F, 0xB4, 0x09, + 0x00, 0x09, 0xE3, 0x43, 0x4B, 0xE2, 0xF4, 0x91, + 0x05, 0xCF, 0x46, 0xAF, 0x4D, 0x2D, 0x41, 0x24 + }, + { + 0x13, 0xA0, 0xA0, 0xC8, 0x63, 0x35, 0x63, 0x5E, + 0xAA, 0x74, 0xCA, 0x2D, 0x5D, 0x48, 0x8C, 0x79, + 0x7B, 0xBB, 0x4F, 0x47, 0xDC, 0x07, 0x10, 0x50, + 0x15, 0xED, 0x6A, 0x1F, 0x33, 0x09, 0xEF, 0xCE + }, + { + 0x15, 0x80, 0xAF, 0xEE, 0xBE, 0xBB, 0x34, 0x6F, + 0x94, 0xD5, 0x9F, 0xE6, 0x2D, 0xA0, 0xB7, 0x92, + 0x37, 0xEA, 0xD7, 0xB1, 0x49, 0x1F, 0x56, 0x67, + 0xA9, 0x0E, 0x45, 0xED, 0xF6, 0xCA, 0x8B, 0x03 + }, + { + 0x20, 0xBE, 0x1A, 0x87, 0x5B, 0x38, 0xC5, 0x73, + 0xDD, 0x7F, 0xAA, 0xA0, 0xDE, 0x48, 0x9D, 0x65, + 0x5C, 0x11, 0xEF, 0xB6, 0xA5, 0x52, 0x69, 0x8E, + 0x07, 0xA2, 0xD3, 0x31, 0xB5, 0xF6, 0x55, 0xC3 + }, + { + 0xBE, 0x1F, 0xE3, 0xC4, 0xC0, 0x40, 0x18, 0xC5, + 0x4C, 0x4A, 0x0F, 0x6B, 0x9A, 0x2E, 0xD3, 0xC5, + 0x3A, 0xBE, 0x3A, 0x9F, 0x76, 0xB4, 0xD2, 0x6D, + 0xE5, 0x6F, 0xC9, 0xAE, 0x95, 0x05, 0x9A, 0x99 + }, + { + 0xE3, 0xE3, 0xAC, 0xE5, 0x37, 0xEB, 0x3E, 0xDD, + 0x84, 0x63, 0xD9, 0xAD, 0x35, 0x82, 0xE1, 0x3C, + 0xF8, 0x65, 0x33, 0xFF, 0xDE, 0x43, 0xD6, 0x68, + 0xDD, 0x2E, 0x93, 0xBB, 0xDB, 0xD7, 0x19, 0x5A + }, + { + 0x11, 0x0C, 0x50, 0xC0, 0xBF, 0x2C, 0x6E, 0x7A, + 0xEB, 0x7E, 0x43, 0x5D, 0x92, 0xD1, 0x32, 0xAB, + 0x66, 0x55, 0x16, 0x8E, 0x78, 0xA2, 0xDE, 0xCD, + 0xEC, 0x33, 0x30, 0x77, 0x76, 0x84, 0xD9, 0xC1 + }, + { + 0xE9, 0xBA, 0x8F, 0x50, 0x5C, 0x9C, 0x80, 0xC0, + 0x86, 0x66, 0xA7, 0x01, 0xF3, 0x36, 0x7E, 0x6C, + 0xC6, 0x65, 0xF3, 0x4B, 0x22, 0xE7, 0x3C, 0x3C, + 0x04, 0x17, 0xEB, 0x1C, 0x22, 0x06, 0x08, 0x2F + }, + { + 0x26, 0xCD, 0x66, 0xFC, 0xA0, 0x23, 0x79, 0xC7, + 0x6D, 0xF1, 0x23, 0x17, 0x05, 0x2B, 0xCA, 0xFD, + 0x6C, 0xD8, 0xC3, 0xA7, 0xB8, 0x90, 0xD8, 0x05, + 0xF3, 0x6C, 0x49, 0x98, 0x97, 0x82, 0x43, 0x3A + }, + { + 0x21, 0x3F, 0x35, 0x96, 0xD6, 0xE3, 0xA5, 0xD0, + 0xE9, 0x93, 0x2C, 0xD2, 0x15, 0x91, 0x46, 0x01, + 0x5E, 0x2A, 0xBC, 0x94, 0x9F, 0x47, 0x29, 0xEE, + 0x26, 0x32, 0xFE, 0x1E, 0xDB, 0x78, 0xD3, 0x37 + }, + { + 0x10, 0x15, 0xD7, 0x01, 0x08, 0xE0, 0x3B, 0xE1, + 0xC7, 0x02, 0xFE, 0x97, 0x25, 0x36, 0x07, 0xD1, + 0x4A, 0xEE, 0x59, 0x1F, 0x24, 0x13, 0xEA, 0x67, + 0x87, 0x42, 0x7B, 0x64, 0x59, 0xFF, 0x21, 0x9A + }, + { + 0x3C, 0xA9, 0x89, 0xDE, 0x10, 0xCF, 0xE6, 0x09, + 0x90, 0x94, 0x72, 0xC8, 0xD3, 0x56, 0x10, 0x80, + 0x5B, 0x2F, 0x97, 0x77, 0x34, 0xCF, 0x65, 0x2C, + 0xC6, 0x4B, 0x3B, 0xFC, 0x88, 0x2D, 0x5D, 0x89 + }, + { + 0xB6, 0x15, 0x6F, 0x72, 0xD3, 0x80, 0xEE, 0x9E, + 0xA6, 0xAC, 0xD1, 0x90, 0x46, 0x4F, 0x23, 0x07, + 0xA5, 0xC1, 0x79, 0xEF, 0x01, 0xFD, 0x71, 0xF9, + 0x9F, 0x2D, 0x0F, 0x7A, 0x57, 0x36, 0x0A, 0xEA + }, + { + 0xC0, 0x3B, 0xC6, 0x42, 0xB2, 0x09, 0x59, 0xCB, + 0xE1, 0x33, 0xA0, 0x30, 0x3E, 0x0C, 0x1A, 0xBF, + 0xF3, 0xE3, 0x1E, 0xC8, 0xE1, 0xA3, 0x28, 0xEC, + 0x85, 0x65, 0xC3, 0x6D, 0xEC, 0xFF, 0x52, 0x65 + }, + { + 0x2C, 0x3E, 0x08, 0x17, 0x6F, 0x76, 0x0C, 0x62, + 0x64, 0xC3, 0xA2, 0xCD, 0x66, 0xFE, 0xC6, 0xC3, + 0xD7, 0x8D, 0xE4, 0x3F, 0xC1, 0x92, 0x45, 0x7B, + 0x2A, 0x4A, 0x66, 0x0A, 0x1E, 0x0E, 0xB2, 0x2B + }, + { + 0xF7, 0x38, 0xC0, 0x2F, 0x3C, 0x1B, 0x19, 0x0C, + 0x51, 0x2B, 0x1A, 0x32, 0xDE, 0xAB, 0xF3, 0x53, + 0x72, 0x8E, 0x0E, 0x9A, 0xB0, 0x34, 0x49, 0x0E, + 0x3C, 0x34, 0x09, 0x94, 0x6A, 0x97, 0xAE, 0xEC + }, + { + 0x8B, 0x18, 0x80, 0xDF, 0x30, 0x1C, 0xC9, 0x63, + 0x41, 0x88, 0x11, 0x08, 0x89, 0x64, 0x83, 0x92, + 0x87, 0xFF, 0x7F, 0xE3, 0x1C, 0x49, 0xEA, 0x6E, + 0xBD, 0x9E, 0x48, 0xBD, 0xEE, 0xE4, 0x97, 0xC5 + }, + { + 0x1E, 0x75, 0xCB, 0x21, 0xC6, 0x09, 0x89, 0x02, + 0x03, 0x75, 0xF1, 0xA7, 0xA2, 0x42, 0x83, 0x9F, + 0x0B, 0x0B, 0x68, 0x97, 0x3A, 0x4C, 0x2A, 0x05, + 0xCF, 0x75, 0x55, 0xED, 0x5A, 0xAE, 0xC4, 0xC1 + }, + { + 0x62, 0xBF, 0x8A, 0x9C, 0x32, 0xA5, 0xBC, 0xCF, + 0x29, 0x0B, 0x6C, 0x47, 0x4D, 0x75, 0xB2, 0xA2, + 0xA4, 0x09, 0x3F, 0x1A, 0x9E, 0x27, 0x13, 0x94, + 0x33, 0xA8, 0xF2, 0xB3, 0xBC, 0xE7, 0xB8, 0xD7 + }, + { + 0x16, 0x6C, 0x83, 0x50, 0xD3, 0x17, 0x3B, 0x5E, + 0x70, 0x2B, 0x78, 0x3D, 0xFD, 0x33, 0xC6, 0x6E, + 0xE0, 0x43, 0x27, 0x42, 0xE9, 0xB9, 0x2B, 0x99, + 0x7F, 0xD2, 0x3C, 0x60, 0xDC, 0x67, 0x56, 0xCA + }, + { + 0x04, 0x4A, 0x14, 0xD8, 0x22, 0xA9, 0x0C, 0xAC, + 0xF2, 0xF5, 0xA1, 0x01, 0x42, 0x8A, 0xDC, 0x8F, + 0x41, 0x09, 0x38, 0x6C, 0xCB, 0x15, 0x8B, 0xF9, + 0x05, 0xC8, 0x61, 0x8B, 0x8E, 0xE2, 0x4E, 0xC3 + }, + { + 0x38, 0x7D, 0x39, 0x7E, 0xA4, 0x3A, 0x99, 0x4B, + 0xE8, 0x4D, 0x2D, 0x54, 0x4A, 0xFB, 0xE4, 0x81, + 0xA2, 0x00, 0x0F, 0x55, 0x25, 0x26, 0x96, 0xBB, + 0xA2, 0xC5, 0x0C, 0x8E, 0xBD, 0x10, 0x13, 0x47 + }, + { + 0x56, 0xF8, 0xCC, 0xF1, 0xF8, 0x64, 0x09, 0xB4, + 0x6C, 0xE3, 0x61, 0x66, 0xAE, 0x91, 0x65, 0x13, + 0x84, 0x41, 0x57, 0x75, 0x89, 0xDB, 0x08, 0xCB, + 0xC5, 0xF6, 0x6C, 0xA2, 0x97, 0x43, 0xB9, 0xFD + }, + { + 0x97, 0x06, 0xC0, 0x92, 0xB0, 0x4D, 0x91, 0xF5, + 0x3D, 0xFF, 0x91, 0xFA, 0x37, 0xB7, 0x49, 0x3D, + 0x28, 0xB5, 0x76, 0xB5, 0xD7, 0x10, 0x46, 0x9D, + 0xF7, 0x94, 0x01, 0x66, 0x22, 0x36, 0xFC, 0x03 + }, + { + 0x87, 0x79, 0x68, 0x68, 0x6C, 0x06, 0x8C, 0xE2, + 0xF7, 0xE2, 0xAD, 0xCF, 0xF6, 0x8B, 0xF8, 0x74, + 0x8E, 0xDF, 0x3C, 0xF8, 0x62, 0xCF, 0xB4, 0xD3, + 0x94, 0x7A, 0x31, 0x06, 0x95, 0x80, 0x54, 0xE3 + }, + { + 0x88, 0x17, 0xE5, 0x71, 0x98, 0x79, 0xAC, 0xF7, + 0x02, 0x47, 0x87, 0xEC, 0xCD, 0xB2, 0x71, 0x03, + 0x55, 0x66, 0xCF, 0xA3, 0x33, 0xE0, 0x49, 0x40, + 0x7C, 0x01, 0x78, 0xCC, 0xC5, 0x7A, 0x5B, 0x9F + }, + { + 0x89, 0x38, 0x24, 0x9E, 0x4B, 0x50, 0xCA, 0xDA, + 0xCC, 0xDF, 0x5B, 0x18, 0x62, 0x13, 0x26, 0xCB, + 0xB1, 0x52, 0x53, 0xE3, 0x3A, 0x20, 0xF5, 0x63, + 0x6E, 0x99, 0x5D, 0x72, 0x47, 0x8D, 0xE4, 0x72 + }, + { + 0xF1, 0x64, 0xAB, 0xBA, 0x49, 0x63, 0xA4, 0x4D, + 0x10, 0x72, 0x57, 0xE3, 0x23, 0x2D, 0x90, 0xAC, + 0xA5, 0xE6, 0x6A, 0x14, 0x08, 0x24, 0x8C, 0x51, + 0x74, 0x1E, 0x99, 0x1D, 0xB5, 0x22, 0x77, 0x56 + }, + { + 0xD0, 0x55, 0x63, 0xE2, 0xB1, 0xCB, 0xA0, 0xC4, + 0xA2, 0xA1, 0xE8, 0xBD, 0xE3, 0xA1, 0xA0, 0xD9, + 0xF5, 0xB4, 0x0C, 0x85, 0xA0, 0x70, 0xD6, 0xF5, + 0xFB, 0x21, 0x06, 0x6E, 0xAD, 0x5D, 0x06, 0x01 + }, + { + 0x03, 0xFB, 0xB1, 0x63, 0x84, 0xF0, 0xA3, 0x86, + 0x6F, 0x4C, 0x31, 0x17, 0x87, 0x76, 0x66, 0xEF, + 0xBF, 0x12, 0x45, 0x97, 0x56, 0x4B, 0x29, 0x3D, + 0x4A, 0xAB, 0x0D, 0x26, 0x9F, 0xAB, 0xDD, 0xFA + }, + { + 0x5F, 0xA8, 0x48, 0x6A, 0xC0, 0xE5, 0x29, 0x64, + 0xD1, 0x88, 0x1B, 0xBE, 0x33, 0x8E, 0xB5, 0x4B, + 0xE2, 0xF7, 0x19, 0x54, 0x92, 0x24, 0x89, 0x20, + 0x57, 0xB4, 0xDA, 0x04, 0xBA, 0x8B, 0x34, 0x75 + }, + { + 0xCD, 0xFA, 0xBC, 0xEE, 0x46, 0x91, 0x11, 0x11, + 0x23, 0x6A, 0x31, 0x70, 0x8B, 0x25, 0x39, 0xD7, + 0x1F, 0xC2, 0x11, 0xD9, 0xB0, 0x9C, 0x0D, 0x85, + 0x30, 0xA1, 0x1E, 0x1D, 0xBF, 0x6E, 0xED, 0x01 + }, + { + 0x4F, 0x82, 0xDE, 0x03, 0xB9, 0x50, 0x47, 0x93, + 0xB8, 0x2A, 0x07, 0xA0, 0xBD, 0xCD, 0xFF, 0x31, + 0x4D, 0x75, 0x9E, 0x7B, 0x62, 0xD2, 0x6B, 0x78, + 0x49, 0x46, 0xB0, 0xD3, 0x6F, 0x91, 0x6F, 0x52 + }, + { + 0x25, 0x9E, 0xC7, 0xF1, 0x73, 0xBC, 0xC7, 0x6A, + 0x09, 0x94, 0xC9, 0x67, 0xB4, 0xF5, 0xF0, 0x24, + 0xC5, 0x60, 0x57, 0xFB, 0x79, 0xC9, 0x65, 0xC4, + 0xFA, 0xE4, 0x18, 0x75, 0xF0, 0x6A, 0x0E, 0x4C + }, + { + 0x19, 0x3C, 0xC8, 0xE7, 0xC3, 0xE0, 0x8B, 0xB3, + 0x0F, 0x54, 0x37, 0xAA, 0x27, 0xAD, 0xE1, 0xF1, + 0x42, 0x36, 0x9B, 0x24, 0x6A, 0x67, 0x5B, 0x23, + 0x83, 0xE6, 0xDA, 0x9B, 0x49, 0xA9, 0x80, 0x9E + }, + { + 0x5C, 0x10, 0x89, 0x6F, 0x0E, 0x28, 0x56, 0xB2, + 0xA2, 0xEE, 0xE0, 0xFE, 0x4A, 0x2C, 0x16, 0x33, + 0x56, 0x5D, 0x18, 0xF0, 0xE9, 0x3E, 0x1F, 0xAB, + 0x26, 0xC3, 0x73, 0xE8, 0xF8, 0x29, 0x65, 0x4D + }, + { + 0xF1, 0x60, 0x12, 0xD9, 0x3F, 0x28, 0x85, 0x1A, + 0x1E, 0xB9, 0x89, 0xF5, 0xD0, 0xB4, 0x3F, 0x3F, + 0x39, 0xCA, 0x73, 0xC9, 0xA6, 0x2D, 0x51, 0x81, + 0xBF, 0xF2, 0x37, 0x53, 0x6B, 0xD3, 0x48, 0xC3 + }, + { + 0x29, 0x66, 0xB3, 0xCF, 0xAE, 0x1E, 0x44, 0xEA, + 0x99, 0x6D, 0xC5, 0xD6, 0x86, 0xCF, 0x25, 0xFA, + 0x05, 0x3F, 0xB6, 0xF6, 0x72, 0x01, 0xB9, 0xE4, + 0x6E, 0xAD, 0xE8, 0x5D, 0x0A, 0xD6, 0xB8, 0x06 + }, + { + 0xDD, 0xB8, 0x78, 0x24, 0x85, 0xE9, 0x00, 0xBC, + 0x60, 0xBC, 0xF4, 0xC3, 0x3A, 0x6F, 0xD5, 0x85, + 0x68, 0x0C, 0xC6, 0x83, 0xD5, 0x16, 0xEF, 0xA0, + 0x3E, 0xB9, 0x98, 0x5F, 0xAD, 0x87, 0x15, 0xFB + }, + { + 0x4C, 0x4D, 0x6E, 0x71, 0xAE, 0xA0, 0x57, 0x86, + 0x41, 0x31, 0x48, 0xFC, 0x7A, 0x78, 0x6B, 0x0E, + 0xCA, 0xF5, 0x82, 0xCF, 0xF1, 0x20, 0x9F, 0x5A, + 0x80, 0x9F, 0xBA, 0x85, 0x04, 0xCE, 0x66, 0x2C + }, + { + 0xFB, 0x4C, 0x5E, 0x86, 0xD7, 0xB2, 0x22, 0x9B, + 0x99, 0xB8, 0xBA, 0x6D, 0x94, 0xC2, 0x47, 0xEF, + 0x96, 0x4A, 0xA3, 0xA2, 0xBA, 0xE8, 0xED, 0xC7, + 0x75, 0x69, 0xF2, 0x8D, 0xBB, 0xFF, 0x2D, 0x4E + }, + { + 0xE9, 0x4F, 0x52, 0x6D, 0xE9, 0x01, 0x96, 0x33, + 0xEC, 0xD5, 0x4A, 0xC6, 0x12, 0x0F, 0x23, 0x95, + 0x8D, 0x77, 0x18, 0xF1, 0xE7, 0x71, 0x7B, 0xF3, + 0x29, 0x21, 0x1A, 0x4F, 0xAE, 0xED, 0x4E, 0x6D + }, + { + 0xCB, 0xD6, 0x66, 0x0A, 0x10, 0xDB, 0x3F, 0x23, + 0xF7, 0xA0, 0x3D, 0x4B, 0x9D, 0x40, 0x44, 0xC7, + 0x93, 0x2B, 0x28, 0x01, 0xAC, 0x89, 0xD6, 0x0B, + 0xC9, 0xEB, 0x92, 0xD6, 0x5A, 0x46, 0xC2, 0xA0 + }, + { + 0x88, 0x18, 0xBB, 0xD3, 0xDB, 0x4D, 0xC1, 0x23, + 0xB2, 0x5C, 0xBB, 0xA5, 0xF5, 0x4C, 0x2B, 0xC4, + 0xB3, 0xFC, 0xF9, 0xBF, 0x7D, 0x7A, 0x77, 0x09, + 0xF4, 0xAE, 0x58, 0x8B, 0x26, 0x7C, 0x4E, 0xCE + }, + { + 0xC6, 0x53, 0x82, 0x51, 0x3F, 0x07, 0x46, 0x0D, + 0xA3, 0x98, 0x33, 0xCB, 0x66, 0x6C, 0x5E, 0xD8, + 0x2E, 0x61, 0xB9, 0xE9, 0x98, 0xF4, 0xB0, 0xC4, + 0x28, 0x7C, 0xEE, 0x56, 0xC3, 0xCC, 0x9B, 0xCD + }, + { + 0x89, 0x75, 0xB0, 0x57, 0x7F, 0xD3, 0x55, 0x66, + 0xD7, 0x50, 0xB3, 0x62, 0xB0, 0x89, 0x7A, 0x26, + 0xC3, 0x99, 0x13, 0x6D, 0xF0, 0x7B, 0xAB, 0xAB, + 0xBD, 0xE6, 0x20, 0x3F, 0xF2, 0x95, 0x4E, 0xD4 + }, + { + 0x21, 0xFE, 0x0C, 0xEB, 0x00, 0x52, 0xBE, 0x7F, + 0xB0, 0xF0, 0x04, 0x18, 0x7C, 0xAC, 0xD7, 0xDE, + 0x67, 0xFA, 0x6E, 0xB0, 0x93, 0x8D, 0x92, 0x76, + 0x77, 0xF2, 0x39, 0x8C, 0x13, 0x23, 0x17, 0xA8 + }, + { + 0x2E, 0xF7, 0x3F, 0x3C, 0x26, 0xF1, 0x2D, 0x93, + 0x88, 0x9F, 0x3C, 0x78, 0xB6, 0xA6, 0x6C, 0x1D, + 0x52, 0xB6, 0x49, 0xDC, 0x9E, 0x85, 0x6E, 0x2C, + 0x17, 0x2E, 0xA7, 0xC5, 0x8A, 0xC2, 0xB5, 0xE3 + }, + { + 0x38, 0x8A, 0x3C, 0xD5, 0x6D, 0x73, 0x86, 0x7A, + 0xBB, 0x5F, 0x84, 0x01, 0x49, 0x2B, 0x6E, 0x26, + 0x81, 0xEB, 0x69, 0x85, 0x1E, 0x76, 0x7F, 0xD8, + 0x42, 0x10, 0xA5, 0x60, 0x76, 0xFB, 0x3D, 0xD3 + }, + { + 0xAF, 0x53, 0x3E, 0x02, 0x2F, 0xC9, 0x43, 0x9E, + 0x4E, 0x3C, 0xB8, 0x38, 0xEC, 0xD1, 0x86, 0x92, + 0x23, 0x2A, 0xDF, 0x6F, 0xE9, 0x83, 0x95, 0x26, + 0xD3, 0xC3, 0xDD, 0x1B, 0x71, 0x91, 0x0B, 0x1A + }, + { + 0x75, 0x1C, 0x09, 0xD4, 0x1A, 0x93, 0x43, 0x88, + 0x2A, 0x81, 0xCD, 0x13, 0xEE, 0x40, 0x81, 0x8D, + 0x12, 0xEB, 0x44, 0xC6, 0xC7, 0xF4, 0x0D, 0xF1, + 0x6E, 0x4A, 0xEA, 0x8F, 0xAB, 0x91, 0x97, 0x2A + }, + { + 0x5B, 0x73, 0xDD, 0xB6, 0x8D, 0x9D, 0x2B, 0x0A, + 0xA2, 0x65, 0xA0, 0x79, 0x88, 0xD6, 0xB8, 0x8A, + 0xE9, 0xAA, 0xC5, 0x82, 0xAF, 0x83, 0x03, 0x2F, + 0x8A, 0x9B, 0x21, 0xA2, 0xE1, 0xB7, 0xBF, 0x18 + }, + { + 0x3D, 0xA2, 0x91, 0x26, 0xC7, 0xC5, 0xD7, 0xF4, + 0x3E, 0x64, 0x24, 0x2A, 0x79, 0xFE, 0xAA, 0x4E, + 0xF3, 0x45, 0x9C, 0xDE, 0xCC, 0xC8, 0x98, 0xED, + 0x59, 0xA9, 0x7F, 0x6E, 0xC9, 0x3B, 0x9D, 0xAB + }, + { + 0x56, 0x6D, 0xC9, 0x20, 0x29, 0x3D, 0xA5, 0xCB, + 0x4F, 0xE0, 0xAA, 0x8A, 0xBD, 0xA8, 0xBB, 0xF5, + 0x6F, 0x55, 0x23, 0x13, 0xBF, 0xF1, 0x90, 0x46, + 0x64, 0x1E, 0x36, 0x15, 0xC1, 0xE3, 0xED, 0x3F + }, + { + 0x41, 0x15, 0xBE, 0xA0, 0x2F, 0x73, 0xF9, 0x7F, + 0x62, 0x9E, 0x5C, 0x55, 0x90, 0x72, 0x0C, 0x01, + 0xE7, 0xE4, 0x49, 0xAE, 0x2A, 0x66, 0x97, 0xD4, + 0xD2, 0x78, 0x33, 0x21, 0x30, 0x36, 0x92, 0xF9 + }, + { + 0x4C, 0xE0, 0x8F, 0x47, 0x62, 0x46, 0x8A, 0x76, + 0x70, 0x01, 0x21, 0x64, 0x87, 0x8D, 0x68, 0x34, + 0x0C, 0x52, 0xA3, 0x5E, 0x66, 0xC1, 0x88, 0x4D, + 0x5C, 0x86, 0x48, 0x89, 0xAB, 0xC9, 0x66, 0x77 + }, + { + 0x81, 0xEA, 0x0B, 0x78, 0x04, 0x12, 0x4E, 0x0C, + 0x22, 0xEA, 0x5F, 0xC7, 0x11, 0x04, 0xA2, 0xAF, + 0xCB, 0x52, 0xA1, 0xFA, 0x81, 0x6F, 0x3E, 0xCB, + 0x7D, 0xCB, 0x5D, 0x9D, 0xEA, 0x17, 0x86, 0xD0 + }, + { + 0xFE, 0x36, 0x27, 0x33, 0xB0, 0x5F, 0x6B, 0xED, + 0xAF, 0x93, 0x79, 0xD7, 0xF7, 0x93, 0x6E, 0xDE, + 0x20, 0x9B, 0x1F, 0x83, 0x23, 0xC3, 0x92, 0x25, + 0x49, 0xD9, 0xE7, 0x36, 0x81, 0xB5, 0xDB, 0x7B + }, + { + 0xEF, 0xF3, 0x7D, 0x30, 0xDF, 0xD2, 0x03, 0x59, + 0xBE, 0x4E, 0x73, 0xFD, 0xF4, 0x0D, 0x27, 0x73, + 0x4B, 0x3D, 0xF9, 0x0A, 0x97, 0xA5, 0x5E, 0xD7, + 0x45, 0x29, 0x72, 0x94, 0xCA, 0x85, 0xD0, 0x9F + }, + { + 0x17, 0x2F, 0xFC, 0x67, 0x15, 0x3D, 0x12, 0xE0, + 0xCA, 0x76, 0xA8, 0xB6, 0xCD, 0x5D, 0x47, 0x31, + 0x88, 0x5B, 0x39, 0xCE, 0x0C, 0xAC, 0x93, 0xA8, + 0x97, 0x2A, 0x18, 0x00, 0x6C, 0x8B, 0x8B, 0xAF + }, + { + 0xC4, 0x79, 0x57, 0xF1, 0xCC, 0x88, 0xE8, 0x3E, + 0xF9, 0x44, 0x58, 0x39, 0x70, 0x9A, 0x48, 0x0A, + 0x03, 0x6B, 0xED, 0x5F, 0x88, 0xAC, 0x0F, 0xCC, + 0x8E, 0x1E, 0x70, 0x3F, 0xFA, 0xAC, 0x13, 0x2C + }, + { + 0x30, 0xF3, 0x54, 0x83, 0x70, 0xCF, 0xDC, 0xED, + 0xA5, 0xC3, 0x7B, 0x56, 0x9B, 0x61, 0x75, 0xE7, + 0x99, 0xEE, 0xF1, 0xA6, 0x2A, 0xAA, 0x94, 0x32, + 0x45, 0xAE, 0x76, 0x69, 0xC2, 0x27, 0xA7, 0xB5 + }, + { + 0xC9, 0x5D, 0xCB, 0x3C, 0xF1, 0xF2, 0x7D, 0x0E, + 0xEF, 0x2F, 0x25, 0xD2, 0x41, 0x38, 0x70, 0x90, + 0x4A, 0x87, 0x7C, 0x4A, 0x56, 0xC2, 0xDE, 0x1E, + 0x83, 0xE2, 0xBC, 0x2A, 0xE2, 0xE4, 0x68, 0x21 + }, + { + 0xD5, 0xD0, 0xB5, 0xD7, 0x05, 0x43, 0x4C, 0xD4, + 0x6B, 0x18, 0x57, 0x49, 0xF6, 0x6B, 0xFB, 0x58, + 0x36, 0xDC, 0xDF, 0x6E, 0xE5, 0x49, 0xA2, 0xB7, + 0xA4, 0xAE, 0xE7, 0xF5, 0x80, 0x07, 0xCA, 0xAF + }, + { + 0xBB, 0xC1, 0x24, 0xA7, 0x12, 0xF1, 0x5D, 0x07, + 0xC3, 0x00, 0xE0, 0x5B, 0x66, 0x83, 0x89, 0xA4, + 0x39, 0xC9, 0x17, 0x77, 0xF7, 0x21, 0xF8, 0x32, + 0x0C, 0x1C, 0x90, 0x78, 0x06, 0x6D, 0x2C, 0x7E + }, + { + 0xA4, 0x51, 0xB4, 0x8C, 0x35, 0xA6, 0xC7, 0x85, + 0x4C, 0xFA, 0xAE, 0x60, 0x26, 0x2E, 0x76, 0x99, + 0x08, 0x16, 0x38, 0x2A, 0xC0, 0x66, 0x7E, 0x5A, + 0x5C, 0x9E, 0x1B, 0x46, 0xC4, 0x34, 0x2D, 0xDF + }, + { + 0xB0, 0xD1, 0x50, 0xFB, 0x55, 0xE7, 0x78, 0xD0, + 0x11, 0x47, 0xF0, 0xB5, 0xD8, 0x9D, 0x99, 0xEC, + 0xB2, 0x0F, 0xF0, 0x7E, 0x5E, 0x67, 0x60, 0xD6, + 0xB6, 0x45, 0xEB, 0x5B, 0x65, 0x4C, 0x62, 0x2B + }, + { + 0x34, 0xF7, 0x37, 0xC0, 0xAB, 0x21, 0x99, 0x51, + 0xEE, 0xE8, 0x9A, 0x9F, 0x8D, 0xAC, 0x29, 0x9C, + 0x9D, 0x4C, 0x38, 0xF3, 0x3F, 0xA4, 0x94, 0xC5, + 0xC6, 0xEE, 0xFC, 0x92, 0xB6, 0xDB, 0x08, 0xBC + }, + { + 0x1A, 0x62, 0xCC, 0x3A, 0x00, 0x80, 0x0D, 0xCB, + 0xD9, 0x98, 0x91, 0x08, 0x0C, 0x1E, 0x09, 0x84, + 0x58, 0x19, 0x3A, 0x8C, 0xC9, 0xF9, 0x70, 0xEA, + 0x99, 0xFB, 0xEF, 0xF0, 0x03, 0x18, 0xC2, 0x89 + }, + { + 0xCF, 0xCE, 0x55, 0xEB, 0xAF, 0xC8, 0x40, 0xD7, + 0xAE, 0x48, 0x28, 0x1C, 0x7F, 0xD5, 0x7E, 0xC8, + 0xB4, 0x82, 0xD4, 0xB7, 0x04, 0x43, 0x74, 0x95, + 0x49, 0x5A, 0xC4, 0x14, 0xCF, 0x4A, 0x37, 0x4B + }, + { + 0x67, 0x46, 0xFA, 0xCF, 0x71, 0x14, 0x6D, 0x99, + 0x9D, 0xAB, 0xD0, 0x5D, 0x09, 0x3A, 0xE5, 0x86, + 0x64, 0x8D, 0x1E, 0xE2, 0x8E, 0x72, 0x61, 0x7B, + 0x99, 0xD0, 0xF0, 0x08, 0x6E, 0x1E, 0x45, 0xBF + }, + { + 0x57, 0x1C, 0xED, 0x28, 0x3B, 0x3F, 0x23, 0xB4, + 0xE7, 0x50, 0xBF, 0x12, 0xA2, 0xCA, 0xF1, 0x78, + 0x18, 0x47, 0xBD, 0x89, 0x0E, 0x43, 0x60, 0x3C, + 0xDC, 0x59, 0x76, 0x10, 0x2B, 0x7B, 0xB1, 0x1B + }, + { + 0xCF, 0xCB, 0x76, 0x5B, 0x04, 0x8E, 0x35, 0x02, + 0x2C, 0x5D, 0x08, 0x9D, 0x26, 0xE8, 0x5A, 0x36, + 0xB0, 0x05, 0xA2, 0xB8, 0x04, 0x93, 0xD0, 0x3A, + 0x14, 0x4E, 0x09, 0xF4, 0x09, 0xB6, 0xAF, 0xD1 + }, + { + 0x40, 0x50, 0xC7, 0xA2, 0x77, 0x05, 0xBB, 0x27, + 0xF4, 0x20, 0x89, 0xB2, 0x99, 0xF3, 0xCB, 0xE5, + 0x05, 0x4E, 0xAD, 0x68, 0x72, 0x7E, 0x8E, 0xF9, + 0x31, 0x8C, 0xE6, 0xF2, 0x5C, 0xD6, 0xF3, 0x1D + }, + { + 0x18, 0x40, 0x70, 0xBD, 0x5D, 0x26, 0x5F, 0xBD, + 0xC1, 0x42, 0xCD, 0x1C, 0x5C, 0xD0, 0xD7, 0xE4, + 0x14, 0xE7, 0x03, 0x69, 0xA2, 0x66, 0xD6, 0x27, + 0xC8, 0xFB, 0xA8, 0x4F, 0xA5, 0xE8, 0x4C, 0x34 + }, + { + 0x9E, 0xDD, 0xA9, 0xA4, 0x44, 0x39, 0x02, 0xA9, + 0x58, 0x8C, 0x0D, 0x0C, 0xCC, 0x62, 0xB9, 0x30, + 0x21, 0x84, 0x79, 0xA6, 0x84, 0x1E, 0x6F, 0xE7, + 0xD4, 0x30, 0x03, 0xF0, 0x4B, 0x1F, 0xD6, 0x43 + }, + { + 0xE4, 0x12, 0xFE, 0xEF, 0x79, 0x08, 0x32, 0x4A, + 0x6D, 0xA1, 0x84, 0x16, 0x29, 0xF3, 0x5D, 0x3D, + 0x35, 0x86, 0x42, 0x01, 0x93, 0x10, 0xEC, 0x57, + 0xC6, 0x14, 0x83, 0x6B, 0x63, 0xD3, 0x07, 0x63 + }, + { + 0x1A, 0x2B, 0x8E, 0xDF, 0xF3, 0xF9, 0xAC, 0xC1, + 0x55, 0x4F, 0xCB, 0xAE, 0x3C, 0xF1, 0xD6, 0x29, + 0x8C, 0x64, 0x62, 0xE2, 0x2E, 0x5E, 0xB0, 0x25, + 0x96, 0x84, 0xF8, 0x35, 0x01, 0x2B, 0xD1, 0x3F + }, + { + 0x28, 0x8C, 0x4A, 0xD9, 0xB9, 0x40, 0x97, 0x62, + 0xEA, 0x07, 0xC2, 0x4A, 0x41, 0xF0, 0x4F, 0x69, + 0xA7, 0xD7, 0x4B, 0xEE, 0x2D, 0x95, 0x43, 0x53, + 0x74, 0xBD, 0xE9, 0x46, 0xD7, 0x24, 0x1C, 0x7B + }, + { + 0x80, 0x56, 0x91, 0xBB, 0x28, 0x67, 0x48, 0xCF, + 0xB5, 0x91, 0xD3, 0xAE, 0xBE, 0x7E, 0x6F, 0x4E, + 0x4D, 0xC6, 0xE2, 0x80, 0x8C, 0x65, 0x14, 0x3C, + 0xC0, 0x04, 0xE4, 0xEB, 0x6F, 0xD0, 0x9D, 0x43 + }, + { + 0xD4, 0xAC, 0x8D, 0x3A, 0x0A, 0xFC, 0x6C, 0xFA, + 0x7B, 0x46, 0x0A, 0xE3, 0x00, 0x1B, 0xAE, 0xB3, + 0x6D, 0xAD, 0xB3, 0x7D, 0xA0, 0x7D, 0x2E, 0x8A, + 0xC9, 0x18, 0x22, 0xDF, 0x34, 0x8A, 0xED, 0x3D + }, + { + 0xC3, 0x76, 0x61, 0x70, 0x14, 0xD2, 0x01, 0x58, + 0xBC, 0xED, 0x3D, 0x3B, 0xA5, 0x52, 0xB6, 0xEC, + 0xCF, 0x84, 0xE6, 0x2A, 0xA3, 0xEB, 0x65, 0x0E, + 0x90, 0x02, 0x9C, 0x84, 0xD1, 0x3E, 0xEA, 0x69 + }, + { + 0xC4, 0x1F, 0x09, 0xF4, 0x3C, 0xEC, 0xAE, 0x72, + 0x93, 0xD6, 0x00, 0x7C, 0xA0, 0xA3, 0x57, 0x08, + 0x7D, 0x5A, 0xE5, 0x9B, 0xE5, 0x00, 0xC1, 0xCD, + 0x5B, 0x28, 0x9E, 0xE8, 0x10, 0xC7, 0xB0, 0x82 + }, + { + 0x03, 0xD1, 0xCE, 0xD1, 0xFB, 0xA5, 0xC3, 0x91, + 0x55, 0xC4, 0x4B, 0x77, 0x65, 0xCB, 0x76, 0x0C, + 0x78, 0x70, 0x8D, 0xCF, 0xC8, 0x0B, 0x0B, 0xD8, + 0xAD, 0xE3, 0xA5, 0x6D, 0xA8, 0x83, 0x0B, 0x29 + }, + { + 0x09, 0xBD, 0xE6, 0xF1, 0x52, 0x21, 0x8D, 0xC9, + 0x2C, 0x41, 0xD7, 0xF4, 0x53, 0x87, 0xE6, 0x3E, + 0x58, 0x69, 0xD8, 0x07, 0xEC, 0x70, 0xB8, 0x21, + 0x40, 0x5D, 0xBD, 0x88, 0x4B, 0x7F, 0xCF, 0x4B + }, + { + 0x71, 0xC9, 0x03, 0x6E, 0x18, 0x17, 0x9B, 0x90, + 0xB3, 0x7D, 0x39, 0xE9, 0xF0, 0x5E, 0xB8, 0x9C, + 0xC5, 0xFC, 0x34, 0x1F, 0xD7, 0xC4, 0x77, 0xD0, + 0xD7, 0x49, 0x32, 0x85, 0xFA, 0xCA, 0x08, 0xA4 + }, + { + 0x59, 0x16, 0x83, 0x3E, 0xBB, 0x05, 0xCD, 0x91, + 0x9C, 0xA7, 0xFE, 0x83, 0xB6, 0x92, 0xD3, 0x20, + 0x5B, 0xEF, 0x72, 0x39, 0x2B, 0x2C, 0xF6, 0xBB, + 0x0A, 0x6D, 0x43, 0xF9, 0x94, 0xF9, 0x5F, 0x11 + }, + { + 0xF6, 0x3A, 0xAB, 0x3E, 0xC6, 0x41, 0xB3, 0xB0, + 0x24, 0x96, 0x4C, 0x2B, 0x43, 0x7C, 0x04, 0xF6, + 0x04, 0x3C, 0x4C, 0x7E, 0x02, 0x79, 0x23, 0x99, + 0x95, 0x40, 0x19, 0x58, 0xF8, 0x6B, 0xBE, 0x54 + }, + { + 0xF1, 0x72, 0xB1, 0x80, 0xBF, 0xB0, 0x97, 0x40, + 0x49, 0x31, 0x20, 0xB6, 0x32, 0x6C, 0xBD, 0xC5, + 0x61, 0xE4, 0x77, 0xDE, 0xF9, 0xBB, 0xCF, 0xD2, + 0x8C, 0xC8, 0xC1, 0xC5, 0xE3, 0x37, 0x9A, 0x31 + }, + { + 0xCB, 0x9B, 0x89, 0xCC, 0x18, 0x38, 0x1D, 0xD9, + 0x14, 0x1A, 0xDE, 0x58, 0x86, 0x54, 0xD4, 0xE6, + 0xA2, 0x31, 0xD5, 0xBF, 0x49, 0xD4, 0xD5, 0x9A, + 0xC2, 0x7D, 0x86, 0x9C, 0xBE, 0x10, 0x0C, 0xF3 + }, + { + 0x7B, 0xD8, 0x81, 0x50, 0x46, 0xFD, 0xD8, 0x10, + 0xA9, 0x23, 0xE1, 0x98, 0x4A, 0xAE, 0xBD, 0xCD, + 0xF8, 0x4D, 0x87, 0xC8, 0x99, 0x2D, 0x68, 0xB5, + 0xEE, 0xB4, 0x60, 0xF9, 0x3E, 0xB3, 0xC8, 0xD7 + }, + { + 0x60, 0x7B, 0xE6, 0x68, 0x62, 0xFD, 0x08, 0xEE, + 0x5B, 0x19, 0xFA, 0xCA, 0xC0, 0x9D, 0xFD, 0xBC, + 0xD4, 0x0C, 0x31, 0x21, 0x01, 0xD6, 0x6E, 0x6E, + 0xBD, 0x2B, 0x84, 0x1F, 0x1B, 0x9A, 0x93, 0x25 + }, + { + 0x9F, 0xE0, 0x3B, 0xBE, 0x69, 0xAB, 0x18, 0x34, + 0xF5, 0x21, 0x9B, 0x0D, 0xA8, 0x8A, 0x08, 0xB3, + 0x0A, 0x66, 0xC5, 0x91, 0x3F, 0x01, 0x51, 0x96, + 0x3C, 0x36, 0x05, 0x60, 0xDB, 0x03, 0x87, 0xB3 + }, + { + 0x90, 0xA8, 0x35, 0x85, 0x71, 0x7B, 0x75, 0xF0, + 0xE9, 0xB7, 0x25, 0xE0, 0x55, 0xEE, 0xEE, 0xB9, + 0xE7, 0xA0, 0x28, 0xEA, 0x7E, 0x6C, 0xBC, 0x07, + 0xB2, 0x09, 0x17, 0xEC, 0x03, 0x63, 0xE3, 0x8C + }, + { + 0x33, 0x6E, 0xA0, 0x53, 0x0F, 0x4A, 0x74, 0x69, + 0x12, 0x6E, 0x02, 0x18, 0x58, 0x7E, 0xBB, 0xDE, + 0x33, 0x58, 0xA0, 0xB3, 0x1C, 0x29, 0xD2, 0x00, + 0xF7, 0xDC, 0x7E, 0xB1, 0x5C, 0x6A, 0xAD, 0xD8 + }, + { + 0xA7, 0x9E, 0x76, 0xDC, 0x0A, 0xBC, 0xA4, 0x39, + 0x6F, 0x07, 0x47, 0xCD, 0x7B, 0x74, 0x8D, 0xF9, + 0x13, 0x00, 0x76, 0x26, 0xB1, 0xD6, 0x59, 0xDA, + 0x0C, 0x1F, 0x78, 0xB9, 0x30, 0x3D, 0x01, 0xA3 + }, + { + 0x44, 0xE7, 0x8A, 0x77, 0x37, 0x56, 0xE0, 0x95, + 0x15, 0x19, 0x50, 0x4D, 0x70, 0x38, 0xD2, 0x8D, + 0x02, 0x13, 0xA3, 0x7E, 0x0C, 0xE3, 0x75, 0x37, + 0x17, 0x57, 0xBC, 0x99, 0x63, 0x11, 0xE3, 0xB8 + }, + { + 0x77, 0xAC, 0x01, 0x2A, 0x3F, 0x75, 0x4D, 0xCF, + 0xEA, 0xB5, 0xEB, 0x99, 0x6B, 0xE9, 0xCD, 0x2D, + 0x1F, 0x96, 0x11, 0x1B, 0x6E, 0x49, 0xF3, 0x99, + 0x4D, 0xF1, 0x81, 0xF2, 0x85, 0x69, 0xD8, 0x25 + }, + { + 0xCE, 0x5A, 0x10, 0xDB, 0x6F, 0xCC, 0xDA, 0xF1, + 0x40, 0xAA, 0xA4, 0xDE, 0xD6, 0x25, 0x0A, 0x9C, + 0x06, 0xE9, 0x22, 0x2B, 0xC9, 0xF9, 0xF3, 0x65, + 0x8A, 0x4A, 0xFF, 0x93, 0x5F, 0x2B, 0x9F, 0x3A + }, + { + 0xEC, 0xC2, 0x03, 0xA7, 0xFE, 0x2B, 0xE4, 0xAB, + 0xD5, 0x5B, 0xB5, 0x3E, 0x6E, 0x67, 0x35, 0x72, + 0xE0, 0x07, 0x8D, 0xA8, 0xCD, 0x37, 0x5E, 0xF4, + 0x30, 0xCC, 0x97, 0xF9, 0xF8, 0x00, 0x83, 0xAF + }, + { + 0x14, 0xA5, 0x18, 0x6D, 0xE9, 0xD7, 0xA1, 0x8B, + 0x04, 0x12, 0xB8, 0x56, 0x3E, 0x51, 0xCC, 0x54, + 0x33, 0x84, 0x0B, 0x4A, 0x12, 0x9A, 0x8F, 0xF9, + 0x63, 0xB3, 0x3A, 0x3C, 0x4A, 0xFE, 0x8E, 0xBB + }, + { + 0x13, 0xF8, 0xEF, 0x95, 0xCB, 0x86, 0xE6, 0xA6, + 0x38, 0x93, 0x1C, 0x8E, 0x10, 0x76, 0x73, 0xEB, + 0x76, 0xBA, 0x10, 0xD7, 0xC2, 0xCD, 0x70, 0xB9, + 0xD9, 0x92, 0x0B, 0xBE, 0xED, 0x92, 0x94, 0x09 + }, + { + 0x0B, 0x33, 0x8F, 0x4E, 0xE1, 0x2F, 0x2D, 0xFC, + 0xB7, 0x87, 0x13, 0x37, 0x79, 0x41, 0xE0, 0xB0, + 0x63, 0x21, 0x52, 0x58, 0x1D, 0x13, 0x32, 0x51, + 0x6E, 0x4A, 0x2C, 0xAB, 0x19, 0x42, 0xCC, 0xA4 + }, + { + 0xEA, 0xAB, 0x0E, 0xC3, 0x7B, 0x3B, 0x8A, 0xB7, + 0x96, 0xE9, 0xF5, 0x72, 0x38, 0xDE, 0x14, 0xA2, + 0x64, 0xA0, 0x76, 0xF3, 0x88, 0x7D, 0x86, 0xE2, + 0x9B, 0xB5, 0x90, 0x6D, 0xB5, 0xA0, 0x0E, 0x02 + }, + { + 0x23, 0xCB, 0x68, 0xB8, 0xC0, 0xE6, 0xDC, 0x26, + 0xDC, 0x27, 0x76, 0x6D, 0xDC, 0x0A, 0x13, 0xA9, + 0x94, 0x38, 0xFD, 0x55, 0x61, 0x7A, 0xA4, 0x09, + 0x5D, 0x8F, 0x96, 0x97, 0x20, 0xC8, 0x72, 0xDF + }, + { + 0x09, 0x1D, 0x8E, 0xE3, 0x0D, 0x6F, 0x29, 0x68, + 0xD4, 0x6B, 0x68, 0x7D, 0xD6, 0x52, 0x92, 0x66, + 0x57, 0x42, 0xDE, 0x0B, 0xB8, 0x3D, 0xCC, 0x00, + 0x04, 0xC7, 0x2C, 0xE1, 0x00, 0x07, 0xA5, 0x49 + }, + { + 0x7F, 0x50, 0x7A, 0xBC, 0x6D, 0x19, 0xBA, 0x00, + 0xC0, 0x65, 0xA8, 0x76, 0xEC, 0x56, 0x57, 0x86, + 0x88, 0x82, 0xD1, 0x8A, 0x22, 0x1B, 0xC4, 0x6C, + 0x7A, 0x69, 0x12, 0x54, 0x1F, 0x5B, 0xC7, 0xBA + }, + { + 0xA0, 0x60, 0x7C, 0x24, 0xE1, 0x4E, 0x8C, 0x22, + 0x3D, 0xB0, 0xD7, 0x0B, 0x4D, 0x30, 0xEE, 0x88, + 0x01, 0x4D, 0x60, 0x3F, 0x43, 0x7E, 0x9E, 0x02, + 0xAA, 0x7D, 0xAF, 0xA3, 0xCD, 0xFB, 0xAD, 0x94 + }, + { + 0xDD, 0xBF, 0xEA, 0x75, 0xCC, 0x46, 0x78, 0x82, + 0xEB, 0x34, 0x83, 0xCE, 0x5E, 0x2E, 0x75, 0x6A, + 0x4F, 0x47, 0x01, 0xB7, 0x6B, 0x44, 0x55, 0x19, + 0xE8, 0x9F, 0x22, 0xD6, 0x0F, 0xA8, 0x6E, 0x06 + }, + { + 0x0C, 0x31, 0x1F, 0x38, 0xC3, 0x5A, 0x4F, 0xB9, + 0x0D, 0x65, 0x1C, 0x28, 0x9D, 0x48, 0x68, 0x56, + 0xCD, 0x14, 0x13, 0xDF, 0x9B, 0x06, 0x77, 0xF5, + 0x3E, 0xCE, 0x2C, 0xD9, 0xE4, 0x77, 0xC6, 0x0A + }, + { + 0x46, 0xA7, 0x3A, 0x8D, 0xD3, 0xE7, 0x0F, 0x59, + 0xD3, 0x94, 0x2C, 0x01, 0xDF, 0x59, 0x9D, 0xEF, + 0x78, 0x3C, 0x9D, 0xA8, 0x2F, 0xD8, 0x32, 0x22, + 0xCD, 0x66, 0x2B, 0x53, 0xDC, 0xE7, 0xDB, 0xDF + }, + { + 0xAD, 0x03, 0x8F, 0xF9, 0xB1, 0x4D, 0xE8, 0x4A, + 0x80, 0x1E, 0x4E, 0x62, 0x1C, 0xE5, 0xDF, 0x02, + 0x9D, 0xD9, 0x35, 0x20, 0xD0, 0xC2, 0xFA, 0x38, + 0xBF, 0xF1, 0x76, 0xA8, 0xB1, 0xD1, 0x69, 0x8C + }, + { + 0xAB, 0x70, 0xC5, 0xDF, 0xBD, 0x1E, 0xA8, 0x17, + 0xFE, 0xD0, 0xCD, 0x06, 0x72, 0x93, 0xAB, 0xF3, + 0x19, 0xE5, 0xD7, 0x90, 0x1C, 0x21, 0x41, 0xD5, + 0xD9, 0x9B, 0x23, 0xF0, 0x3A, 0x38, 0xE7, 0x48 + }, + { + 0x1F, 0xFF, 0xDA, 0x67, 0x93, 0x2B, 0x73, 0xC8, + 0xEC, 0xAF, 0x00, 0x9A, 0x34, 0x91, 0xA0, 0x26, + 0x95, 0x3B, 0xAB, 0xFE, 0x1F, 0x66, 0x3B, 0x06, + 0x97, 0xC3, 0xC4, 0xAE, 0x8B, 0x2E, 0x7D, 0xCB + }, + { + 0xB0, 0xD2, 0xCC, 0x19, 0x47, 0x2D, 0xD5, 0x7F, + 0x2B, 0x17, 0xEF, 0xC0, 0x3C, 0x8D, 0x58, 0xC2, + 0x28, 0x3D, 0xBB, 0x19, 0xDA, 0x57, 0x2F, 0x77, + 0x55, 0x85, 0x5A, 0xA9, 0x79, 0x43, 0x17, 0xA0 + }, + { + 0xA0, 0xD1, 0x9A, 0x6E, 0xE3, 0x39, 0x79, 0xC3, + 0x25, 0x51, 0x0E, 0x27, 0x66, 0x22, 0xDF, 0x41, + 0xF7, 0x15, 0x83, 0xD0, 0x75, 0x01, 0xB8, 0x70, + 0x71, 0x12, 0x9A, 0x0A, 0xD9, 0x47, 0x32, 0xA5 + }, + { + 0x72, 0x46, 0x42, 0xA7, 0x03, 0x2D, 0x10, 0x62, + 0xB8, 0x9E, 0x52, 0xBE, 0xA3, 0x4B, 0x75, 0xDF, + 0x7D, 0x8F, 0xE7, 0x72, 0xD9, 0xFE, 0x3C, 0x93, + 0xDD, 0xF3, 0xC4, 0x54, 0x5A, 0xB5, 0xA9, 0x9B + }, + { + 0xAD, 0xE5, 0xEA, 0xA7, 0xE6, 0x1F, 0x67, 0x2D, + 0x58, 0x7E, 0xA0, 0x3D, 0xAE, 0x7D, 0x7B, 0x55, + 0x22, 0x9C, 0x01, 0xD0, 0x6B, 0xC0, 0xA5, 0x70, + 0x14, 0x36, 0xCB, 0xD1, 0x83, 0x66, 0xA6, 0x26 + }, + { + 0x01, 0x3B, 0x31, 0xEB, 0xD2, 0x28, 0xFC, 0xDD, + 0xA5, 0x1F, 0xAB, 0xB0, 0x3B, 0xB0, 0x2D, 0x60, + 0xAC, 0x20, 0xCA, 0x21, 0x5A, 0xAF, 0xA8, 0x3B, + 0xDD, 0x85, 0x5E, 0x37, 0x55, 0xA3, 0x5F, 0x0B + }, + { + 0x33, 0x2E, 0xD4, 0x0B, 0xB1, 0x0D, 0xDE, 0x3C, + 0x95, 0x4A, 0x75, 0xD7, 0xB8, 0x99, 0x9D, 0x4B, + 0x26, 0xA1, 0xC0, 0x63, 0xC1, 0xDC, 0x6E, 0x32, + 0xC1, 0xD9, 0x1B, 0xAB, 0x7B, 0xBB, 0x7D, 0x16 + }, + { + 0xC7, 0xA1, 0x97, 0xB3, 0xA0, 0x5B, 0x56, 0x6B, + 0xCC, 0x9F, 0xAC, 0xD2, 0x0E, 0x44, 0x1D, 0x6F, + 0x6C, 0x28, 0x60, 0xAC, 0x96, 0x51, 0xCD, 0x51, + 0xD6, 0xB9, 0xD2, 0xCD, 0xEE, 0xEA, 0x03, 0x90 + }, + { + 0xBD, 0x9C, 0xF6, 0x4E, 0xA8, 0x95, 0x3C, 0x03, + 0x71, 0x08, 0xE6, 0xF6, 0x54, 0x91, 0x4F, 0x39, + 0x58, 0xB6, 0x8E, 0x29, 0xC1, 0x67, 0x00, 0xDC, + 0x18, 0x4D, 0x94, 0xA2, 0x17, 0x08, 0xFF, 0x60 + }, + { + 0x88, 0x35, 0xB0, 0xAC, 0x02, 0x11, 0x51, 0xDF, + 0x71, 0x64, 0x74, 0xCE, 0x27, 0xCE, 0x4D, 0x3C, + 0x15, 0xF0, 0xB2, 0xDA, 0xB4, 0x80, 0x03, 0xCF, + 0x3F, 0x3E, 0xFD, 0x09, 0x45, 0x10, 0x6B, 0x9A + }, + { + 0x3B, 0xFE, 0xFA, 0x33, 0x01, 0xAA, 0x55, 0xC0, + 0x80, 0x19, 0x0C, 0xFF, 0xDA, 0x8E, 0xAE, 0x51, + 0xD9, 0xAF, 0x48, 0x8B, 0x4C, 0x1F, 0x24, 0xC3, + 0xD9, 0xA7, 0x52, 0x42, 0xFD, 0x8E, 0xA0, 0x1D + }, + { + 0x08, 0x28, 0x4D, 0x14, 0x99, 0x3C, 0xD4, 0x7D, + 0x53, 0xEB, 0xAE, 0xCF, 0x0D, 0xF0, 0x47, 0x8C, + 0xC1, 0x82, 0xC8, 0x9C, 0x00, 0xE1, 0x85, 0x9C, + 0x84, 0x85, 0x16, 0x86, 0xDD, 0xF2, 0xC1, 0xB7 + }, + { + 0x1E, 0xD7, 0xEF, 0x9F, 0x04, 0xC2, 0xAC, 0x8D, + 0xB6, 0xA8, 0x64, 0xDB, 0x13, 0x10, 0x87, 0xF2, + 0x70, 0x65, 0x09, 0x8E, 0x69, 0xC3, 0xFE, 0x78, + 0x71, 0x8D, 0x9B, 0x94, 0x7F, 0x4A, 0x39, 0xD0 + }, + { + 0xC1, 0x61, 0xF2, 0xDC, 0xD5, 0x7E, 0x9C, 0x14, + 0x39, 0xB3, 0x1A, 0x9D, 0xD4, 0x3D, 0x8F, 0x3D, + 0x7D, 0xD8, 0xF0, 0xEB, 0x7C, 0xFA, 0xC6, 0xFB, + 0x25, 0xA0, 0xF2, 0x8E, 0x30, 0x6F, 0x06, 0x61 + }, + { + 0xC0, 0x19, 0x69, 0xAD, 0x34, 0xC5, 0x2C, 0xAF, + 0x3D, 0xC4, 0xD8, 0x0D, 0x19, 0x73, 0x5C, 0x29, + 0x73, 0x1A, 0xC6, 0xE7, 0xA9, 0x20, 0x85, 0xAB, + 0x92, 0x50, 0xC4, 0x8D, 0xEA, 0x48, 0xA3, 0xFC + }, + { + 0x17, 0x20, 0xB3, 0x65, 0x56, 0x19, 0xD2, 0xA5, + 0x2B, 0x35, 0x21, 0xAE, 0x0E, 0x49, 0xE3, 0x45, + 0xCB, 0x33, 0x89, 0xEB, 0xD6, 0x20, 0x8A, 0xCA, + 0xF9, 0xF1, 0x3F, 0xDA, 0xCC, 0xA8, 0xBE, 0x49 + }, + { + 0x75, 0x62, 0x88, 0x36, 0x1C, 0x83, 0xE2, 0x4C, + 0x61, 0x7C, 0xF9, 0x5C, 0x90, 0x5B, 0x22, 0xD0, + 0x17, 0xCD, 0xC8, 0x6F, 0x0B, 0xF1, 0xD6, 0x58, + 0xF4, 0x75, 0x6C, 0x73, 0x79, 0x87, 0x3B, 0x7F + }, + { + 0xE7, 0xD0, 0xED, 0xA3, 0x45, 0x26, 0x93, 0xB7, + 0x52, 0xAB, 0xCD, 0xA1, 0xB5, 0x5E, 0x27, 0x6F, + 0x82, 0x69, 0x8F, 0x5F, 0x16, 0x05, 0x40, 0x3E, + 0xFF, 0x83, 0x0B, 0xEA, 0x00, 0x71, 0xA3, 0x94 + }, + { + 0x2C, 0x82, 0xEC, 0xAA, 0x6B, 0x84, 0x80, 0x3E, + 0x04, 0x4A, 0xF6, 0x31, 0x18, 0xAF, 0xE5, 0x44, + 0x68, 0x7C, 0xB6, 0xE6, 0xC7, 0xDF, 0x49, 0xED, + 0x76, 0x2D, 0xFD, 0x7C, 0x86, 0x93, 0xA1, 0xBC + }, + { + 0x61, 0x36, 0xCB, 0xF4, 0xB4, 0x41, 0x05, 0x6F, + 0xA1, 0xE2, 0x72, 0x24, 0x98, 0x12, 0x5D, 0x6D, + 0xED, 0x45, 0xE1, 0x7B, 0x52, 0x14, 0x39, 0x59, + 0xC7, 0xF4, 0xD4, 0xE3, 0x95, 0x21, 0x8A, 0xC2 + }, + { + 0x72, 0x1D, 0x32, 0x45, 0xAA, 0xFE, 0xF2, 0x7F, + 0x6A, 0x62, 0x4F, 0x47, 0x95, 0x4B, 0x6C, 0x25, + 0x50, 0x79, 0x52, 0x6F, 0xFA, 0x25, 0xE9, 0xFF, + 0x77, 0xE5, 0xDC, 0xFF, 0x47, 0x3B, 0x15, 0x97 + }, + { + 0x9D, 0xD2, 0xFB, 0xD8, 0xCE, 0xF1, 0x6C, 0x35, + 0x3C, 0x0A, 0xC2, 0x11, 0x91, 0xD5, 0x09, 0xEB, + 0x28, 0xDD, 0x9E, 0x3E, 0x0D, 0x8C, 0xEA, 0x5D, + 0x26, 0xCA, 0x83, 0x93, 0x93, 0x85, 0x1C, 0x3A + }, + { + 0xB2, 0x39, 0x4C, 0xEA, 0xCD, 0xEB, 0xF2, 0x1B, + 0xF9, 0xDF, 0x2C, 0xED, 0x98, 0xE5, 0x8F, 0x1C, + 0x3A, 0x4B, 0xBB, 0xFF, 0x66, 0x0D, 0xD9, 0x00, + 0xF6, 0x22, 0x02, 0xD6, 0x78, 0x5C, 0xC4, 0x6E + }, + { + 0x57, 0x08, 0x9F, 0x22, 0x27, 0x49, 0xAD, 0x78, + 0x71, 0x76, 0x5F, 0x06, 0x2B, 0x11, 0x4F, 0x43, + 0xBA, 0x20, 0xEC, 0x56, 0x42, 0x2A, 0x8B, 0x1E, + 0x3F, 0x87, 0x19, 0x2C, 0x0E, 0xA7, 0x18, 0xC6 + }, + { + 0xE4, 0x9A, 0x94, 0x59, 0x96, 0x1C, 0xD3, 0x3C, + 0xDF, 0x4A, 0xAE, 0x1B, 0x10, 0x78, 0xA5, 0xDE, + 0xA7, 0xC0, 0x40, 0xE0, 0xFE, 0xA3, 0x40, 0xC9, + 0x3A, 0x72, 0x48, 0x72, 0xFC, 0x4A, 0xF8, 0x06 + }, + { + 0xED, 0xE6, 0x7F, 0x72, 0x0E, 0xFF, 0xD2, 0xCA, + 0x9C, 0x88, 0x99, 0x41, 0x52, 0xD0, 0x20, 0x1D, + 0xEE, 0x6B, 0x0A, 0x2D, 0x2C, 0x07, 0x7A, 0xCA, + 0x6D, 0xAE, 0x29, 0xF7, 0x3F, 0x8B, 0x63, 0x09 + }, + { + 0xE0, 0xF4, 0x34, 0xBF, 0x22, 0xE3, 0x08, 0x80, + 0x39, 0xC2, 0x1F, 0x71, 0x9F, 0xFC, 0x67, 0xF0, + 0xF2, 0xCB, 0x5E, 0x98, 0xA7, 0xA0, 0x19, 0x4C, + 0x76, 0xE9, 0x6B, 0xF4, 0xE8, 0xE1, 0x7E, 0x61 + }, + { + 0x27, 0x7C, 0x04, 0xE2, 0x85, 0x34, 0x84, 0xA4, + 0xEB, 0xA9, 0x10, 0xAD, 0x33, 0x6D, 0x01, 0xB4, + 0x77, 0xB6, 0x7C, 0xC2, 0x00, 0xC5, 0x9F, 0x3C, + 0x8D, 0x77, 0xEE, 0xF8, 0x49, 0x4F, 0x29, 0xCD + }, + { + 0x15, 0x6D, 0x57, 0x47, 0xD0, 0xC9, 0x9C, 0x7F, + 0x27, 0x09, 0x7D, 0x7B, 0x7E, 0x00, 0x2B, 0x2E, + 0x18, 0x5C, 0xB7, 0x2D, 0x8D, 0xD7, 0xEB, 0x42, + 0x4A, 0x03, 0x21, 0x52, 0x81, 0x61, 0x21, 0x9F + }, + { + 0x20, 0xDD, 0xD1, 0xED, 0x9B, 0x1C, 0xA8, 0x03, + 0x94, 0x6D, 0x64, 0xA8, 0x3A, 0xE4, 0x65, 0x9D, + 0xA6, 0x7F, 0xBA, 0x7A, 0x1A, 0x3E, 0xDD, 0xB1, + 0xE1, 0x03, 0xC0, 0xF5, 0xE0, 0x3E, 0x3A, 0x2C + }, + { + 0xF0, 0xAF, 0x60, 0x4D, 0x3D, 0xAB, 0xBF, 0x9A, + 0x0F, 0x2A, 0x7D, 0x3D, 0xDA, 0x6B, 0xD3, 0x8B, + 0xBA, 0x72, 0xC6, 0xD0, 0x9B, 0xE4, 0x94, 0xFC, + 0xEF, 0x71, 0x3F, 0xF1, 0x01, 0x89, 0xB6, 0xE6 + }, + { + 0x98, 0x02, 0xBB, 0x87, 0xDE, 0xF4, 0xCC, 0x10, + 0xC4, 0xA5, 0xFD, 0x49, 0xAA, 0x58, 0xDF, 0xE2, + 0xF3, 0xFD, 0xDB, 0x46, 0xB4, 0x70, 0x88, 0x14, + 0xEA, 0xD8, 0x1D, 0x23, 0xBA, 0x95, 0x13, 0x9B + }, + { + 0x4F, 0x8C, 0xE1, 0xE5, 0x1D, 0x2F, 0xE7, 0xF2, + 0x40, 0x43, 0xA9, 0x04, 0xD8, 0x98, 0xEB, 0xFC, + 0x91, 0x97, 0x54, 0x18, 0x75, 0x34, 0x13, 0xAA, + 0x09, 0x9B, 0x79, 0x5E, 0xCB, 0x35, 0xCE, 0xDB + }, + { + 0xBD, 0xDC, 0x65, 0x14, 0xD7, 0xEE, 0x6A, 0xCE, + 0x0A, 0x4A, 0xC1, 0xD0, 0xE0, 0x68, 0x11, 0x22, + 0x88, 0xCB, 0xCF, 0x56, 0x04, 0x54, 0x64, 0x27, + 0x05, 0x63, 0x01, 0x77, 0xCB, 0xA6, 0x08, 0xBD + }, + { + 0xD6, 0x35, 0x99, 0x4F, 0x62, 0x91, 0x51, 0x7B, + 0x02, 0x81, 0xFF, 0xDD, 0x49, 0x6A, 0xFA, 0x86, + 0x27, 0x12, 0xE5, 0xB3, 0xC4, 0xE5, 0x2E, 0x4C, + 0xD5, 0xFD, 0xAE, 0x8C, 0x0E, 0x72, 0xFB, 0x08 + }, + { + 0x87, 0x8D, 0x9C, 0xA6, 0x00, 0xCF, 0x87, 0xE7, + 0x69, 0xCC, 0x30, 0x5C, 0x1B, 0x35, 0x25, 0x51, + 0x86, 0x61, 0x5A, 0x73, 0xA0, 0xDA, 0x61, 0x3B, + 0x5F, 0x1C, 0x98, 0xDB, 0xF8, 0x12, 0x83, 0xEA + }, + { + 0xA6, 0x4E, 0xBE, 0x5D, 0xC1, 0x85, 0xDE, 0x9F, + 0xDD, 0xE7, 0x60, 0x7B, 0x69, 0x98, 0x70, 0x2E, + 0xB2, 0x34, 0x56, 0x18, 0x49, 0x57, 0x30, 0x7D, + 0x2F, 0xA7, 0x2E, 0x87, 0xA4, 0x77, 0x02, 0xD6 + }, + { + 0xCE, 0x50, 0xEA, 0xB7, 0xB5, 0xEB, 0x52, 0xBD, + 0xC9, 0xAD, 0x8E, 0x5A, 0x48, 0x0A, 0xB7, 0x80, + 0xCA, 0x93, 0x20, 0xE4, 0x43, 0x60, 0xB1, 0xFE, + 0x37, 0xE0, 0x3F, 0x2F, 0x7A, 0xD7, 0xDE, 0x01 + }, + { + 0xEE, 0xDD, 0xB7, 0xC0, 0xDB, 0x6E, 0x30, 0xAB, + 0xE6, 0x6D, 0x79, 0xE3, 0x27, 0x51, 0x1E, 0x61, + 0xFC, 0xEB, 0xBC, 0x29, 0xF1, 0x59, 0xB4, 0x0A, + 0x86, 0xB0, 0x46, 0xEC, 0xF0, 0x51, 0x38, 0x23 + }, + { + 0x78, 0x7F, 0xC9, 0x34, 0x40, 0xC1, 0xEC, 0x96, + 0xB5, 0xAD, 0x01, 0xC1, 0x6C, 0xF7, 0x79, 0x16, + 0xA1, 0x40, 0x5F, 0x94, 0x26, 0x35, 0x6E, 0xC9, + 0x21, 0xD8, 0xDF, 0xF3, 0xEA, 0x63, 0xB7, 0xE0 + }, + { + 0x7F, 0x0D, 0x5E, 0xAB, 0x47, 0xEE, 0xFD, 0xA6, + 0x96, 0xC0, 0xBF, 0x0F, 0xBF, 0x86, 0xAB, 0x21, + 0x6F, 0xCE, 0x46, 0x1E, 0x93, 0x03, 0xAB, 0xA6, + 0xAC, 0x37, 0x41, 0x20, 0xE8, 0x90, 0xE8, 0xDF + }, + { + 0xB6, 0x80, 0x04, 0xB4, 0x2F, 0x14, 0xAD, 0x02, + 0x9F, 0x4C, 0x2E, 0x03, 0xB1, 0xD5, 0xEB, 0x76, + 0xD5, 0x71, 0x60, 0xE2, 0x64, 0x76, 0xD2, 0x11, + 0x31, 0xBE, 0xF2, 0x0A, 0xDA, 0x7D, 0x27, 0xF4 + }, + { + 0xB0, 0xC4, 0xEB, 0x18, 0xAE, 0x25, 0x0B, 0x51, + 0xA4, 0x13, 0x82, 0xEA, 0xD9, 0x2D, 0x0D, 0xC7, + 0x45, 0x5F, 0x93, 0x79, 0xFC, 0x98, 0x84, 0x42, + 0x8E, 0x47, 0x70, 0x60, 0x8D, 0xB0, 0xFA, 0xEC + }, + { + 0xF9, 0x2B, 0x7A, 0x87, 0x0C, 0x05, 0x9F, 0x4D, + 0x46, 0x46, 0x4C, 0x82, 0x4E, 0xC9, 0x63, 0x55, + 0x14, 0x0B, 0xDC, 0xE6, 0x81, 0x32, 0x2C, 0xC3, + 0xA9, 0x92, 0xFF, 0x10, 0x3E, 0x3F, 0xEA, 0x52 + }, + { + 0x53, 0x64, 0x31, 0x26, 0x14, 0x81, 0x33, 0x98, + 0xCC, 0x52, 0x5D, 0x4C, 0x4E, 0x14, 0x6E, 0xDE, + 0xB3, 0x71, 0x26, 0x5F, 0xBA, 0x19, 0x13, 0x3A, + 0x2C, 0x3D, 0x21, 0x59, 0x29, 0x8A, 0x17, 0x42 + }, + { + 0xF6, 0x62, 0x0E, 0x68, 0xD3, 0x7F, 0xB2, 0xAF, + 0x50, 0x00, 0xFC, 0x28, 0xE2, 0x3B, 0x83, 0x22, + 0x97, 0xEC, 0xD8, 0xBC, 0xE9, 0x9E, 0x8B, 0xE4, + 0xD0, 0x4E, 0x85, 0x30, 0x9E, 0x3D, 0x33, 0x74 + }, + { + 0x53, 0x16, 0xA2, 0x79, 0x69, 0xD7, 0xFE, 0x04, + 0xFF, 0x27, 0xB2, 0x83, 0x96, 0x1B, 0xFF, 0xC3, + 0xBF, 0x5D, 0xFB, 0x32, 0xFB, 0x6A, 0x89, 0xD1, + 0x01, 0xC6, 0xC3, 0xB1, 0x93, 0x7C, 0x28, 0x71 + }, + { + 0x81, 0xD1, 0x66, 0x4F, 0xDF, 0x3C, 0xB3, 0x3C, + 0x24, 0xEE, 0xBA, 0xC0, 0xBD, 0x64, 0x24, 0x4B, + 0x77, 0xC4, 0xAB, 0xEA, 0x90, 0xBB, 0xE8, 0xB5, + 0xEE, 0x0B, 0x2A, 0xAF, 0xCF, 0x2D, 0x6A, 0x53 + }, + { + 0x34, 0x57, 0x82, 0xF2, 0x95, 0xB0, 0x88, 0x03, + 0x52, 0xE9, 0x24, 0xA0, 0x46, 0x7B, 0x5F, 0xBC, + 0x3E, 0x8F, 0x3B, 0xFB, 0xC3, 0xC7, 0xE4, 0x8B, + 0x67, 0x09, 0x1F, 0xB5, 0xE8, 0x0A, 0x94, 0x42 + }, + { + 0x79, 0x41, 0x11, 0xEA, 0x6C, 0xD6, 0x5E, 0x31, + 0x1F, 0x74, 0xEE, 0x41, 0xD4, 0x76, 0xCB, 0x63, + 0x2C, 0xE1, 0xE4, 0xB0, 0x51, 0xDC, 0x1D, 0x9E, + 0x9D, 0x06, 0x1A, 0x19, 0xE1, 0xD0, 0xBB, 0x49 + }, + { + 0x2A, 0x85, 0xDA, 0xF6, 0x13, 0x88, 0x16, 0xB9, + 0x9B, 0xF8, 0xD0, 0x8B, 0xA2, 0x11, 0x4B, 0x7A, + 0xB0, 0x79, 0x75, 0xA7, 0x84, 0x20, 0xC1, 0xA3, + 0xB0, 0x6A, 0x77, 0x7C, 0x22, 0xDD, 0x8B, 0xCB + }, + { + 0x89, 0xB0, 0xD5, 0xF2, 0x89, 0xEC, 0x16, 0x40, + 0x1A, 0x06, 0x9A, 0x96, 0x0D, 0x0B, 0x09, 0x3E, + 0x62, 0x5D, 0xA3, 0xCF, 0x41, 0xEE, 0x29, 0xB5, + 0x9B, 0x93, 0x0C, 0x58, 0x20, 0x14, 0x54, 0x55 + }, + { + 0xD0, 0xFD, 0xCB, 0x54, 0x39, 0x43, 0xFC, 0x27, + 0xD2, 0x08, 0x64, 0xF5, 0x21, 0x81, 0x47, 0x1B, + 0x94, 0x2C, 0xC7, 0x7C, 0xA6, 0x75, 0xBC, 0xB3, + 0x0D, 0xF3, 0x1D, 0x35, 0x8E, 0xF7, 0xB1, 0xEB + }, + { + 0xB1, 0x7E, 0xA8, 0xD7, 0x70, 0x63, 0xC7, 0x09, + 0xD4, 0xDC, 0x6B, 0x87, 0x94, 0x13, 0xC3, 0x43, + 0xE3, 0x79, 0x0E, 0x9E, 0x62, 0xCA, 0x85, 0xB7, + 0x90, 0x0B, 0x08, 0x6F, 0x6B, 0x75, 0xC6, 0x72 + }, + { + 0xE7, 0x1A, 0x3E, 0x2C, 0x27, 0x4D, 0xB8, 0x42, + 0xD9, 0x21, 0x14, 0xF2, 0x17, 0xE2, 0xC0, 0xEA, + 0xC8, 0xB4, 0x50, 0x93, 0xFD, 0xFD, 0x9D, 0xF4, + 0xCA, 0x71, 0x62, 0x39, 0x48, 0x62, 0xD5, 0x01 + }, + { + 0xC0, 0x47, 0x67, 0x59, 0xAB, 0x7A, 0xA3, 0x33, + 0x23, 0x4F, 0x6B, 0x44, 0xF5, 0xFD, 0x85, 0x83, + 0x90, 0xEC, 0x23, 0x69, 0x4C, 0x62, 0x2C, 0xB9, + 0x86, 0xE7, 0x69, 0xC7, 0x8E, 0xDD, 0x73, 0x3E + }, + { + 0x9A, 0xB8, 0xEA, 0xBB, 0x14, 0x16, 0x43, 0x4D, + 0x85, 0x39, 0x13, 0x41, 0xD5, 0x69, 0x93, 0xC5, + 0x54, 0x58, 0x16, 0x7D, 0x44, 0x18, 0xB1, 0x9A, + 0x0F, 0x2A, 0xD8, 0xB7, 0x9A, 0x83, 0xA7, 0x5B + }, + { + 0x79, 0x92, 0xD0, 0xBB, 0xB1, 0x5E, 0x23, 0x82, + 0x6F, 0x44, 0x3E, 0x00, 0x50, 0x5D, 0x68, 0xD3, + 0xED, 0x73, 0x72, 0x99, 0x5A, 0x5C, 0x3E, 0x49, + 0x86, 0x54, 0x10, 0x2F, 0xBC, 0xD0, 0x96, 0x4E + }, + { + 0xC0, 0x21, 0xB3, 0x00, 0x85, 0x15, 0x14, 0x35, + 0xDF, 0x33, 0xB0, 0x07, 0xCC, 0xEC, 0xC6, 0x9D, + 0xF1, 0x26, 0x9F, 0x39, 0xBA, 0x25, 0x09, 0x2B, + 0xED, 0x59, 0xD9, 0x32, 0xAC, 0x0F, 0xDC, 0x28 + }, + { + 0x91, 0xA2, 0x5E, 0xC0, 0xEC, 0x0D, 0x9A, 0x56, + 0x7F, 0x89, 0xC4, 0xBF, 0xE1, 0xA6, 0x5A, 0x0E, + 0x43, 0x2D, 0x07, 0x06, 0x4B, 0x41, 0x90, 0xE2, + 0x7D, 0xFB, 0x81, 0x90, 0x1F, 0xD3, 0x13, 0x9B + }, + { + 0x59, 0x50, 0xD3, 0x9A, 0x23, 0xE1, 0x54, 0x5F, + 0x30, 0x12, 0x70, 0xAA, 0x1A, 0x12, 0xF2, 0xE6, + 0xC4, 0x53, 0x77, 0x6E, 0x4D, 0x63, 0x55, 0xDE, + 0x42, 0x5C, 0xC1, 0x53, 0xF9, 0x81, 0x88, 0x67 + }, + { + 0xD7, 0x9F, 0x14, 0x72, 0x0C, 0x61, 0x0A, 0xF1, + 0x79, 0xA3, 0x76, 0x5D, 0x4B, 0x7C, 0x09, 0x68, + 0xF9, 0x77, 0x96, 0x2D, 0xBF, 0x65, 0x5B, 0x52, + 0x12, 0x72, 0xB6, 0xF1, 0xE1, 0x94, 0x48, 0x8E + }, + { + 0xE9, 0x53, 0x1B, 0xFC, 0x8B, 0x02, 0x99, 0x5A, + 0xEA, 0xA7, 0x5B, 0xA2, 0x70, 0x31, 0xFA, 0xDB, + 0xCB, 0xF4, 0xA0, 0xDA, 0xB8, 0x96, 0x1D, 0x92, + 0x96, 0xCD, 0x7E, 0x84, 0xD2, 0x5D, 0x60, 0x06 + }, + { + 0x34, 0xE9, 0xC2, 0x6A, 0x01, 0xD7, 0xF1, 0x61, + 0x81, 0xB4, 0x54, 0xA9, 0xD1, 0x62, 0x3C, 0x23, + 0x3C, 0xB9, 0x9D, 0x31, 0xC6, 0x94, 0x65, 0x6E, + 0x94, 0x13, 0xAC, 0xA3, 0xE9, 0x18, 0x69, 0x2F + }, + { + 0xD9, 0xD7, 0x42, 0x2F, 0x43, 0x7B, 0xD4, 0x39, + 0xDD, 0xD4, 0xD8, 0x83, 0xDA, 0xE2, 0xA0, 0x83, + 0x50, 0x17, 0x34, 0x14, 0xBE, 0x78, 0x15, 0x51, + 0x33, 0xFF, 0xF1, 0x96, 0x4C, 0x3D, 0x79, 0x72 + }, + { + 0x4A, 0xEE, 0x0C, 0x7A, 0xAF, 0x07, 0x54, 0x14, + 0xFF, 0x17, 0x93, 0xEA, 0xD7, 0xEA, 0xCA, 0x60, + 0x17, 0x75, 0xC6, 0x15, 0xDB, 0xD6, 0x0B, 0x64, + 0x0B, 0x0A, 0x9F, 0x0C, 0xE5, 0x05, 0xD4, 0x35 + }, + { + 0x6B, 0xFD, 0xD1, 0x54, 0x59, 0xC8, 0x3B, 0x99, + 0xF0, 0x96, 0xBF, 0xB4, 0x9E, 0xE8, 0x7B, 0x06, + 0x3D, 0x69, 0xC1, 0x97, 0x4C, 0x69, 0x28, 0xAC, + 0xFC, 0xFB, 0x40, 0x99, 0xF8, 0xC4, 0xEF, 0x67 + }, + { + 0x9F, 0xD1, 0xC4, 0x08, 0xFD, 0x75, 0xC3, 0x36, + 0x19, 0x3A, 0x2A, 0x14, 0xD9, 0x4F, 0x6A, 0xF5, + 0xAD, 0xF0, 0x50, 0xB8, 0x03, 0x87, 0xB4, 0xB0, + 0x10, 0xFB, 0x29, 0xF4, 0xCC, 0x72, 0x70, 0x7C + }, + { + 0x13, 0xC8, 0x84, 0x80, 0xA5, 0xD0, 0x0D, 0x6C, + 0x8C, 0x7A, 0xD2, 0x11, 0x0D, 0x76, 0xA8, 0x2D, + 0x9B, 0x70, 0xF4, 0xFA, 0x66, 0x96, 0xD4, 0xE5, + 0xDD, 0x42, 0xA0, 0x66, 0xDC, 0xAF, 0x99, 0x20 + }, + { + 0x82, 0x0E, 0x72, 0x5E, 0xE2, 0x5F, 0xE8, 0xFD, + 0x3A, 0x8D, 0x5A, 0xBE, 0x4C, 0x46, 0xC3, 0xBA, + 0x88, 0x9D, 0xE6, 0xFA, 0x91, 0x91, 0xAA, 0x22, + 0xBA, 0x67, 0xD5, 0x70, 0x54, 0x21, 0x54, 0x2B + }, + { + 0x32, 0xD9, 0x3A, 0x0E, 0xB0, 0x2F, 0x42, 0xFB, + 0xBC, 0xAF, 0x2B, 0xAD, 0x00, 0x85, 0xB2, 0x82, + 0xE4, 0x60, 0x46, 0xA4, 0xDF, 0x7A, 0xD1, 0x06, + 0x57, 0xC9, 0xD6, 0x47, 0x63, 0x75, 0xB9, 0x3E + }, + { + 0xAD, 0xC5, 0x18, 0x79, 0x05, 0xB1, 0x66, 0x9C, + 0xD8, 0xEC, 0x9C, 0x72, 0x1E, 0x19, 0x53, 0x78, + 0x6B, 0x9D, 0x89, 0xA9, 0xBA, 0xE3, 0x07, 0x80, + 0xF1, 0xE1, 0xEA, 0xB2, 0x4A, 0x00, 0x52, 0x3C + }, + { + 0xE9, 0x07, 0x56, 0xFF, 0x7F, 0x9A, 0xD8, 0x10, + 0xB2, 0x39, 0xA1, 0x0C, 0xED, 0x2C, 0xF9, 0xB2, + 0x28, 0x43, 0x54, 0xC1, 0xF8, 0xC7, 0xE0, 0xAC, + 0xCC, 0x24, 0x61, 0xDC, 0x79, 0x6D, 0x6E, 0x89 + }, + { + 0x12, 0x51, 0xF7, 0x6E, 0x56, 0x97, 0x84, 0x81, + 0x87, 0x53, 0x59, 0x80, 0x1D, 0xB5, 0x89, 0xA0, + 0xB2, 0x2F, 0x86, 0xD8, 0xD6, 0x34, 0xDC, 0x04, + 0x50, 0x6F, 0x32, 0x2E, 0xD7, 0x8F, 0x17, 0xE8 + }, + { + 0x3A, 0xFA, 0x89, 0x9F, 0xD9, 0x80, 0xE7, 0x3E, + 0xCB, 0x7F, 0x4D, 0x8B, 0x8F, 0x29, 0x1D, 0xC9, + 0xAF, 0x79, 0x6B, 0xC6, 0x5D, 0x27, 0xF9, 0x74, + 0xC6, 0xF1, 0x93, 0xC9, 0x19, 0x1A, 0x09, 0xFD + }, + { + 0xAA, 0x30, 0x5B, 0xE2, 0x6E, 0x5D, 0xED, 0xDC, + 0x3C, 0x10, 0x10, 0xCB, 0xC2, 0x13, 0xF9, 0x5F, + 0x05, 0x1C, 0x78, 0x5C, 0x5B, 0x43, 0x1E, 0x6A, + 0x7C, 0xD0, 0x48, 0xF1, 0x61, 0x78, 0x75, 0x28 + }, + { + 0x8E, 0xA1, 0x88, 0x4F, 0xF3, 0x2E, 0x9D, 0x10, + 0xF0, 0x39, 0xB4, 0x07, 0xD0, 0xD4, 0x4E, 0x7E, + 0x67, 0x0A, 0xBD, 0x88, 0x4A, 0xEE, 0xE0, 0xFB, + 0x75, 0x7A, 0xE9, 0x4E, 0xAA, 0x97, 0x37, 0x3D + }, + { + 0xD4, 0x82, 0xB2, 0x15, 0x5D, 0x4D, 0xEC, 0x6B, + 0x47, 0x36, 0xA1, 0xF1, 0x61, 0x7B, 0x53, 0xAA, + 0xA3, 0x73, 0x10, 0x27, 0x7D, 0x3F, 0xEF, 0x0C, + 0x37, 0xAD, 0x41, 0x76, 0x8F, 0xC2, 0x35, 0xB4 + }, + { + 0x4D, 0x41, 0x39, 0x71, 0x38, 0x7E, 0x7A, 0x88, + 0x98, 0xA8, 0xDC, 0x2A, 0x27, 0x50, 0x07, 0x78, + 0x53, 0x9E, 0xA2, 0x14, 0xA2, 0xDF, 0xE9, 0xB3, + 0xD7, 0xE8, 0xEB, 0xDC, 0xE5, 0xCF, 0x3D, 0xB3 + }, + { + 0x69, 0x6E, 0x5D, 0x46, 0xE6, 0xC5, 0x7E, 0x87, + 0x96, 0xE4, 0x73, 0x5D, 0x08, 0x91, 0x6E, 0x0B, + 0x79, 0x29, 0xB3, 0xCF, 0x29, 0x8C, 0x29, 0x6D, + 0x22, 0xE9, 0xD3, 0x01, 0x96, 0x53, 0x37, 0x1C + }, + { + 0x1F, 0x56, 0x47, 0xC1, 0xD3, 0xB0, 0x88, 0x22, + 0x88, 0x85, 0x86, 0x5C, 0x89, 0x40, 0x90, 0x8B, + 0xF4, 0x0D, 0x1A, 0x82, 0x72, 0x82, 0x19, 0x73, + 0xB1, 0x60, 0x00, 0x8E, 0x7A, 0x3C, 0xE2, 0xEB + }, + { + 0xB6, 0xE7, 0x6C, 0x33, 0x0F, 0x02, 0x1A, 0x5B, + 0xDA, 0x65, 0x87, 0x50, 0x10, 0xB0, 0xED, 0xF0, + 0x91, 0x26, 0xC0, 0xF5, 0x10, 0xEA, 0x84, 0x90, + 0x48, 0x19, 0x20, 0x03, 0xAE, 0xF4, 0xC6, 0x1C + }, + { + 0x3C, 0xD9, 0x52, 0xA0, 0xBE, 0xAD, 0xA4, 0x1A, + 0xBB, 0x42, 0x4C, 0xE4, 0x7F, 0x94, 0xB4, 0x2B, + 0xE6, 0x4E, 0x1F, 0xFB, 0x0F, 0xD0, 0x78, 0x22, + 0x76, 0x80, 0x79, 0x46, 0xD0, 0xD0, 0xBC, 0x55 + }, + { + 0x98, 0xD9, 0x26, 0x77, 0x43, 0x9B, 0x41, 0xB7, + 0xBB, 0x51, 0x33, 0x12, 0xAF, 0xB9, 0x2B, 0xCC, + 0x8E, 0xE9, 0x68, 0xB2, 0xE3, 0xB2, 0x38, 0xCE, + 0xCB, 0x9B, 0x0F, 0x34, 0xC9, 0xBB, 0x63, 0xD0 + }, + { + 0xEC, 0xBC, 0xA2, 0xCF, 0x08, 0xAE, 0x57, 0xD5, + 0x17, 0xAD, 0x16, 0x15, 0x8A, 0x32, 0xBF, 0xA7, + 0xDC, 0x03, 0x82, 0xEA, 0xED, 0xA1, 0x28, 0xE9, + 0x18, 0x86, 0x73, 0x4C, 0x24, 0xA0, 0xB2, 0x9D + }, + { + 0x94, 0x2C, 0xC7, 0xC0, 0xB5, 0x2E, 0x2B, 0x16, + 0xA4, 0xB8, 0x9F, 0xA4, 0xFC, 0x7E, 0x0B, 0xF6, + 0x09, 0xE2, 0x9A, 0x08, 0xC1, 0xA8, 0x54, 0x34, + 0x52, 0xB7, 0x7C, 0x7B, 0xFD, 0x11, 0xBB, 0x28 + }, + { + 0x8A, 0x06, 0x5D, 0x8B, 0x61, 0xA0, 0xDF, 0xFB, + 0x17, 0x0D, 0x56, 0x27, 0x73, 0x5A, 0x76, 0xB0, + 0xE9, 0x50, 0x60, 0x37, 0x80, 0x8C, 0xBA, 0x16, + 0xC3, 0x45, 0x00, 0x7C, 0x9F, 0x79, 0xCF, 0x8F + }, + { + 0x1B, 0x9F, 0xA1, 0x97, 0x14, 0x65, 0x9C, 0x78, + 0xFF, 0x41, 0x38, 0x71, 0x84, 0x92, 0x15, 0x36, + 0x10, 0x29, 0xAC, 0x80, 0x2B, 0x1C, 0xBC, 0xD5, + 0x4E, 0x40, 0x8B, 0xD8, 0x72, 0x87, 0xF8, 0x1F + }, + { + 0x8D, 0xAB, 0x07, 0x1B, 0xCD, 0x6C, 0x72, 0x92, + 0xA9, 0xEF, 0x72, 0x7B, 0x4A, 0xE0, 0xD8, 0x67, + 0x13, 0x30, 0x1D, 0xA8, 0x61, 0x8D, 0x9A, 0x48, + 0xAD, 0xCE, 0x55, 0xF3, 0x03, 0xA8, 0x69, 0xA1 + }, + { + 0x82, 0x53, 0xE3, 0xE7, 0xC7, 0xB6, 0x84, 0xB9, + 0xCB, 0x2B, 0xEB, 0x01, 0x4C, 0xE3, 0x30, 0xFF, + 0x3D, 0x99, 0xD1, 0x7A, 0xBB, 0xDB, 0xAB, 0xE4, + 0xF4, 0xD6, 0x74, 0xDE, 0xD5, 0x3F, 0xFC, 0x6B + }, + { + 0xF1, 0x95, 0xF3, 0x21, 0xE9, 0xE3, 0xD6, 0xBD, + 0x7D, 0x07, 0x45, 0x04, 0xDD, 0x2A, 0xB0, 0xE6, + 0x24, 0x1F, 0x92, 0xE7, 0x84, 0xB1, 0xAA, 0x27, + 0x1F, 0xF6, 0x48, 0xB1, 0xCA, 0xB6, 0xD7, 0xF6 + }, + { + 0x27, 0xE4, 0xCC, 0x72, 0x09, 0x0F, 0x24, 0x12, + 0x66, 0x47, 0x6A, 0x7C, 0x09, 0x49, 0x5F, 0x2D, + 0xB1, 0x53, 0xD5, 0xBC, 0xBD, 0x76, 0x19, 0x03, + 0xEF, 0x79, 0x27, 0x5E, 0xC5, 0x6B, 0x2E, 0xD8 + }, + { + 0x89, 0x9C, 0x24, 0x05, 0x78, 0x8E, 0x25, 0xB9, + 0x9A, 0x18, 0x46, 0x35, 0x5E, 0x64, 0x6D, 0x77, + 0xCF, 0x40, 0x00, 0x83, 0x41, 0x5F, 0x7D, 0xC5, + 0xAF, 0xE6, 0x9D, 0x6E, 0x17, 0xC0, 0x00, 0x23 + }, + { + 0xA5, 0x9B, 0x78, 0xC4, 0x90, 0x57, 0x44, 0x07, + 0x6B, 0xFE, 0xE8, 0x94, 0xDE, 0x70, 0x7D, 0x4F, + 0x12, 0x0B, 0x5C, 0x68, 0x93, 0xEA, 0x04, 0x00, + 0x29, 0x7D, 0x0B, 0xB8, 0x34, 0x72, 0x76, 0x32 + }, + { + 0x59, 0xDC, 0x78, 0xB1, 0x05, 0x64, 0x97, 0x07, + 0xA2, 0xBB, 0x44, 0x19, 0xC4, 0x8F, 0x00, 0x54, + 0x00, 0xD3, 0x97, 0x3D, 0xE3, 0x73, 0x66, 0x10, + 0x23, 0x04, 0x35, 0xB1, 0x04, 0x24, 0xB2, 0x4F + }, + { + 0xC0, 0x14, 0x9D, 0x1D, 0x7E, 0x7A, 0x63, 0x53, + 0xA6, 0xD9, 0x06, 0xEF, 0xE7, 0x28, 0xF2, 0xF3, + 0x29, 0xFE, 0x14, 0xA4, 0x14, 0x9A, 0x3E, 0xA7, + 0x76, 0x09, 0xBC, 0x42, 0xB9, 0x75, 0xDD, 0xFA + }, + { + 0xA3, 0x2F, 0x24, 0x14, 0x74, 0xA6, 0xC1, 0x69, + 0x32, 0xE9, 0x24, 0x3B, 0xE0, 0xCF, 0x09, 0xBC, + 0xDC, 0x7E, 0x0C, 0xA0, 0xE7, 0xA6, 0xA1, 0xB9, + 0xB1, 0xA0, 0xF0, 0x1E, 0x41, 0x50, 0x23, 0x77 + }, + { + 0xB2, 0x39, 0xB2, 0xE4, 0xF8, 0x18, 0x41, 0x36, + 0x1C, 0x13, 0x39, 0xF6, 0x8E, 0x2C, 0x35, 0x9F, + 0x92, 0x9A, 0xF9, 0xAD, 0x9F, 0x34, 0xE0, 0x1A, + 0xAB, 0x46, 0x31, 0xAD, 0x6D, 0x55, 0x00, 0xB0 + }, + { + 0x85, 0xFB, 0x41, 0x9C, 0x70, 0x02, 0xA3, 0xE0, + 0xB4, 0xB6, 0xEA, 0x09, 0x3B, 0x4C, 0x1A, 0xC6, + 0x93, 0x66, 0x45, 0xB6, 0x5D, 0xAC, 0x5A, 0xC1, + 0x5A, 0x85, 0x28, 0xB7, 0xB9, 0x4C, 0x17, 0x54 + }, + { + 0x96, 0x19, 0x72, 0x06, 0x25, 0xF1, 0x90, 0xB9, + 0x3A, 0x3F, 0xAD, 0x18, 0x6A, 0xB3, 0x14, 0x18, + 0x96, 0x33, 0xC0, 0xD3, 0xA0, 0x1E, 0x6F, 0x9B, + 0xC8, 0xC4, 0xA8, 0xF8, 0x2F, 0x38, 0x3D, 0xBF + }, + { + 0x7D, 0x62, 0x0D, 0x90, 0xFE, 0x69, 0xFA, 0x46, + 0x9A, 0x65, 0x38, 0x38, 0x89, 0x70, 0xA1, 0xAA, + 0x09, 0xBB, 0x48, 0xA2, 0xD5, 0x9B, 0x34, 0x7B, + 0x97, 0xE8, 0xCE, 0x71, 0xF4, 0x8C, 0x7F, 0x46 + }, + { + 0x29, 0x43, 0x83, 0x56, 0x85, 0x96, 0xFB, 0x37, + 0xC7, 0x5B, 0xBA, 0xCD, 0x97, 0x9C, 0x5F, 0xF6, + 0xF2, 0x0A, 0x55, 0x6B, 0xF8, 0x87, 0x9C, 0xC7, + 0x29, 0x24, 0x85, 0x5D, 0xF9, 0xB8, 0x24, 0x0E + }, + { + 0x16, 0xB1, 0x8A, 0xB3, 0x14, 0x35, 0x9C, 0x2B, + 0x83, 0x3C, 0x1C, 0x69, 0x86, 0xD4, 0x8C, 0x55, + 0xA9, 0xFC, 0x97, 0xCD, 0xE9, 0xA3, 0xC1, 0xF1, + 0x0A, 0x31, 0x77, 0x14, 0x0F, 0x73, 0xF7, 0x38 + }, + { + 0x8C, 0xBB, 0xDD, 0x14, 0xBC, 0x33, 0xF0, 0x4C, + 0xF4, 0x58, 0x13, 0xE4, 0xA1, 0x53, 0xA2, 0x73, + 0xD3, 0x6A, 0xDA, 0xD5, 0xCE, 0x71, 0xF4, 0x99, + 0xEE, 0xB8, 0x7F, 0xB8, 0xAC, 0x63, 0xB7, 0x29 + }, + { + 0x69, 0xC9, 0xA4, 0x98, 0xDB, 0x17, 0x4E, 0xCA, + 0xEF, 0xCC, 0x5A, 0x3A, 0xC9, 0xFD, 0xED, 0xF0, + 0xF8, 0x13, 0xA5, 0xBE, 0xC7, 0x27, 0xF1, 0xE7, + 0x75, 0xBA, 0xBD, 0xEC, 0x77, 0x18, 0x81, 0x6E + }, + { + 0xB4, 0x62, 0xC3, 0xBE, 0x40, 0x44, 0x8F, 0x1D, + 0x4F, 0x80, 0x62, 0x62, 0x54, 0xE5, 0x35, 0xB0, + 0x8B, 0xC9, 0xCD, 0xCF, 0xF5, 0x99, 0xA7, 0x68, + 0x57, 0x8D, 0x4B, 0x28, 0x81, 0xA8, 0xE3, 0xF0 + }, + { + 0x55, 0x3E, 0x9D, 0x9C, 0x5F, 0x36, 0x0A, 0xC0, + 0xB7, 0x4A, 0x7D, 0x44, 0xE5, 0xA3, 0x91, 0xDA, + 0xD4, 0xCE, 0xD0, 0x3E, 0x0C, 0x24, 0x18, 0x3B, + 0x7E, 0x8E, 0xCA, 0xBD, 0xF1, 0x71, 0x5A, 0x64 + }, + { + 0x7A, 0x7C, 0x55, 0xA5, 0x6F, 0xA9, 0xAE, 0x51, + 0xE6, 0x55, 0xE0, 0x19, 0x75, 0xD8, 0xA6, 0xFF, + 0x4A, 0xE9, 0xE4, 0xB4, 0x86, 0xFC, 0xBE, 0x4E, + 0xAC, 0x04, 0x45, 0x88, 0xF2, 0x45, 0xEB, 0xEA + }, + { + 0x2A, 0xFD, 0xF3, 0xC8, 0x2A, 0xBC, 0x48, 0x67, + 0xF5, 0xDE, 0x11, 0x12, 0x86, 0xC2, 0xB3, 0xBE, + 0x7D, 0x6E, 0x48, 0x65, 0x7B, 0xA9, 0x23, 0xCF, + 0xBF, 0x10, 0x1A, 0x6D, 0xFC, 0xF9, 0xDB, 0x9A + }, + { + 0x41, 0x03, 0x7D, 0x2E, 0xDC, 0xDC, 0xE0, 0xC4, + 0x9B, 0x7F, 0xB4, 0xA6, 0xAA, 0x09, 0x99, 0xCA, + 0x66, 0x97, 0x6C, 0x74, 0x83, 0xAF, 0xE6, 0x31, + 0xD4, 0xED, 0xA2, 0x83, 0x14, 0x4F, 0x6D, 0xFC + }, + { + 0xC4, 0x46, 0x6F, 0x84, 0x97, 0xCA, 0x2E, 0xEB, + 0x45, 0x83, 0xA0, 0xB0, 0x8E, 0x9D, 0x9A, 0xC7, + 0x43, 0x95, 0x70, 0x9F, 0xDA, 0x10, 0x9D, 0x24, + 0xF2, 0xE4, 0x46, 0x21, 0x96, 0x77, 0x9C, 0x5D + }, + { + 0x75, 0xF6, 0x09, 0x33, 0x8A, 0xA6, 0x7D, 0x96, + 0x9A, 0x2A, 0xE2, 0xA2, 0x36, 0x2B, 0x2D, 0xA9, + 0xD7, 0x7C, 0x69, 0x5D, 0xFD, 0x1D, 0xF7, 0x22, + 0x4A, 0x69, 0x01, 0xDB, 0x93, 0x2C, 0x33, 0x64 + }, + { + 0x68, 0x60, 0x6C, 0xEB, 0x98, 0x9D, 0x54, 0x88, + 0xFC, 0x7C, 0xF6, 0x49, 0xF3, 0xD7, 0xC2, 0x72, + 0xEF, 0x05, 0x5D, 0xA1, 0xA9, 0x3F, 0xAE, 0xCD, + 0x55, 0xFE, 0x06, 0xF6, 0x96, 0x70, 0x98, 0xCA + }, + { + 0x44, 0x34, 0x6B, 0xDE, 0xB7, 0xE0, 0x52, 0xF6, + 0x25, 0x50, 0x48, 0xF0, 0xD9, 0xB4, 0x2C, 0x42, + 0x5B, 0xAB, 0x9C, 0x3D, 0xD2, 0x41, 0x68, 0x21, + 0x2C, 0x3E, 0xCF, 0x1E, 0xBF, 0x34, 0xE6, 0xAE + }, + { + 0x8E, 0x9C, 0xF6, 0xE1, 0xF3, 0x66, 0x47, 0x1F, + 0x2A, 0xC7, 0xD2, 0xEE, 0x9B, 0x5E, 0x62, 0x66, + 0xFD, 0xA7, 0x1F, 0x8F, 0x2E, 0x41, 0x09, 0xF2, + 0x23, 0x7E, 0xD5, 0xF8, 0x81, 0x3F, 0xC7, 0x18 + }, + { + 0x84, 0xBB, 0xEB, 0x84, 0x06, 0xD2, 0x50, 0x95, + 0x1F, 0x8C, 0x1B, 0x3E, 0x86, 0xA7, 0xC0, 0x10, + 0x08, 0x29, 0x21, 0x83, 0x3D, 0xFD, 0x95, 0x55, + 0xA2, 0xF9, 0x09, 0xB1, 0x08, 0x6E, 0xB4, 0xB8 + }, + { + 0xEE, 0x66, 0x6F, 0x3E, 0xEF, 0x0F, 0x7E, 0x2A, + 0x9C, 0x22, 0x29, 0x58, 0xC9, 0x7E, 0xAF, 0x35, + 0xF5, 0x1C, 0xED, 0x39, 0x3D, 0x71, 0x44, 0x85, + 0xAB, 0x09, 0xA0, 0x69, 0x34, 0x0F, 0xDF, 0x88 + }, + { + 0xC1, 0x53, 0xD3, 0x4A, 0x65, 0xC4, 0x7B, 0x4A, + 0x62, 0xC5, 0xCA, 0xCF, 0x24, 0x01, 0x09, 0x75, + 0xD0, 0x35, 0x6B, 0x2F, 0x32, 0xC8, 0xF5, 0xDA, + 0x53, 0x0D, 0x33, 0x88, 0x16, 0xAD, 0x5D, 0xE6 + }, + { + 0x9F, 0xC5, 0x45, 0x01, 0x09, 0xE1, 0xB7, 0x79, + 0xF6, 0xC7, 0xAE, 0x79, 0xD5, 0x6C, 0x27, 0x63, + 0x5C, 0x8D, 0xD4, 0x26, 0xC5, 0xA9, 0xD5, 0x4E, + 0x25, 0x78, 0xDB, 0x98, 0x9B, 0x8C, 0x3B, 0x4E + }, + { + 0xD1, 0x2B, 0xF3, 0x73, 0x2E, 0xF4, 0xAF, 0x5C, + 0x22, 0xFA, 0x90, 0x35, 0x6A, 0xF8, 0xFC, 0x50, + 0xFC, 0xB4, 0x0F, 0x8F, 0x2E, 0xA5, 0xC8, 0x59, + 0x47, 0x37, 0xA3, 0xB3, 0xD5, 0xAB, 0xDB, 0xD7 + }, + { + 0x11, 0x03, 0x0B, 0x92, 0x89, 0xBB, 0xA5, 0xAF, + 0x65, 0x26, 0x06, 0x72, 0xAB, 0x6F, 0xEE, 0x88, + 0xB8, 0x74, 0x20, 0xAC, 0xEF, 0x4A, 0x17, 0x89, + 0xA2, 0x07, 0x3B, 0x7E, 0xC2, 0xF2, 0xA0, 0x9E + }, + { + 0x69, 0xCB, 0x19, 0x2B, 0x84, 0x44, 0x00, 0x5C, + 0x8C, 0x0C, 0xEB, 0x12, 0xC8, 0x46, 0x86, 0x07, + 0x68, 0x18, 0x8C, 0xDA, 0x0A, 0xEC, 0x27, 0xA9, + 0xC8, 0xA5, 0x5C, 0xDE, 0xE2, 0x12, 0x36, 0x32 + }, + { + 0xDB, 0x44, 0x4C, 0x15, 0x59, 0x7B, 0x5F, 0x1A, + 0x03, 0xD1, 0xF9, 0xED, 0xD1, 0x6E, 0x4A, 0x9F, + 0x43, 0xA6, 0x67, 0xCC, 0x27, 0x51, 0x75, 0xDF, + 0xA2, 0xB7, 0x04, 0xE3, 0xBB, 0x1A, 0x9B, 0x83 + }, + { + 0x3F, 0xB7, 0x35, 0x06, 0x1A, 0xBC, 0x51, 0x9D, + 0xFE, 0x97, 0x9E, 0x54, 0xC1, 0xEE, 0x5B, 0xFA, + 0xD0, 0xA9, 0xD8, 0x58, 0xB3, 0x31, 0x5B, 0xAD, + 0x34, 0xBD, 0xE9, 0x99, 0xEF, 0xD7, 0x24, 0xDD + }, +}; + + + + +static const uint8_t blake2b_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03, + 0xC6, 0xC6, 0xFD, 0x85, 0x25, 0x52, 0xD2, 0x72, + 0x91, 0x2F, 0x47, 0x40, 0xE1, 0x58, 0x47, 0x61, + 0x8A, 0x86, 0xE2, 0x17, 0xF7, 0x1F, 0x54, 0x19, + 0xD2, 0x5E, 0x10, 0x31, 0xAF, 0xEE, 0x58, 0x53, + 0x13, 0x89, 0x64, 0x44, 0x93, 0x4E, 0xB0, 0x4B, + 0x90, 0x3A, 0x68, 0x5B, 0x14, 0x48, 0xB7, 0x55, + 0xD5, 0x6F, 0x70, 0x1A, 0xFE, 0x9B, 0xE2, 0xCE + }, + { + 0x2F, 0xA3, 0xF6, 0x86, 0xDF, 0x87, 0x69, 0x95, + 0x16, 0x7E, 0x7C, 0x2E, 0x5D, 0x74, 0xC4, 0xC7, + 0xB6, 0xE4, 0x8F, 0x80, 0x68, 0xFE, 0x0E, 0x44, + 0x20, 0x83, 0x44, 0xD4, 0x80, 0xF7, 0x90, 0x4C, + 0x36, 0x96, 0x3E, 0x44, 0x11, 0x5F, 0xE3, 0xEB, + 0x2A, 0x3A, 0xC8, 0x69, 0x4C, 0x28, 0xBC, 0xB4, + 0xF5, 0xA0, 0xF3, 0x27, 0x6F, 0x2E, 0x79, 0x48, + 0x7D, 0x82, 0x19, 0x05, 0x7A, 0x50, 0x6E, 0x4B + }, + { + 0x1C, 0x08, 0x79, 0x8D, 0xC6, 0x41, 0xAB, 0xA9, + 0xDE, 0xE4, 0x35, 0xE2, 0x25, 0x19, 0xA4, 0x72, + 0x9A, 0x09, 0xB2, 0xBF, 0xE0, 0xFF, 0x00, 0xEF, + 0x2D, 0xCD, 0x8E, 0xD6, 0xF8, 0xA0, 0x7D, 0x15, + 0xEA, 0xF4, 0xAE, 0xE5, 0x2B, 0xBF, 0x18, 0xAB, + 0x56, 0x08, 0xA6, 0x19, 0x0F, 0x70, 0xB9, 0x04, + 0x86, 0xC8, 0xA7, 0xD4, 0x87, 0x37, 0x10, 0xB1, + 0x11, 0x5D, 0x3D, 0xEB, 0xBB, 0x43, 0x27, 0xB5 + }, + { + 0x40, 0xA3, 0x74, 0x72, 0x73, 0x02, 0xD9, 0xA4, + 0x76, 0x9C, 0x17, 0xB5, 0xF4, 0x09, 0xFF, 0x32, + 0xF5, 0x8A, 0xA2, 0x4F, 0xF1, 0x22, 0xD7, 0x60, + 0x3E, 0x4F, 0xDA, 0x15, 0x09, 0xE9, 0x19, 0xD4, + 0x10, 0x7A, 0x52, 0xC5, 0x75, 0x70, 0xA6, 0xD9, + 0x4E, 0x50, 0x96, 0x7A, 0xEA, 0x57, 0x3B, 0x11, + 0xF8, 0x6F, 0x47, 0x3F, 0x53, 0x75, 0x65, 0xC6, + 0x6F, 0x70, 0x39, 0x83, 0x0A, 0x85, 0xD1, 0x86 + }, + { + 0x77, 0xDD, 0xF4, 0xB1, 0x44, 0x25, 0xEB, 0x3D, + 0x05, 0x3C, 0x1E, 0x84, 0xE3, 0x46, 0x9D, 0x92, + 0xC4, 0xCD, 0x91, 0x0E, 0xD2, 0x0F, 0x92, 0x03, + 0x5E, 0x0C, 0x99, 0xD8, 0xA7, 0xA8, 0x6C, 0xEC, + 0xAF, 0x69, 0xF9, 0x66, 0x3C, 0x20, 0xA7, 0xAA, + 0x23, 0x0B, 0xC8, 0x2F, 0x60, 0xD2, 0x2F, 0xB4, + 0xA0, 0x0B, 0x09, 0xD3, 0xEB, 0x8F, 0xC6, 0x5E, + 0xF5, 0x47, 0xFE, 0x63, 0xC8, 0xD3, 0xDD, 0xCE + }, + { + 0xCB, 0xAA, 0x0B, 0xA7, 0xD4, 0x82, 0xB1, 0xF3, + 0x01, 0x10, 0x9A, 0xE4, 0x10, 0x51, 0x99, 0x1A, + 0x32, 0x89, 0xBC, 0x11, 0x98, 0x00, 0x5A, 0xF2, + 0x26, 0xC5, 0xE4, 0xF1, 0x03, 0xB6, 0x65, 0x79, + 0xF4, 0x61, 0x36, 0x10, 0x44, 0xC8, 0xBA, 0x34, + 0x39, 0xFF, 0x12, 0xC5, 0x15, 0xFB, 0x29, 0xC5, + 0x21, 0x61, 0xB7, 0xEB, 0x9C, 0x28, 0x37, 0xB7, + 0x6A, 0x5D, 0xC3, 0x3F, 0x7C, 0xB2, 0xE2, 0xE8 + }, + { + 0xF9, 0x5D, 0x45, 0xCF, 0x69, 0xAF, 0x5C, 0x20, + 0x23, 0xBD, 0xB5, 0x05, 0x82, 0x1E, 0x62, 0xE8, + 0x5D, 0x7C, 0xAE, 0xDF, 0x7B, 0xED, 0xA1, 0x2C, + 0x02, 0x48, 0x77, 0x5B, 0x0C, 0x88, 0x20, 0x5E, + 0xEB, 0x35, 0xAF, 0x3A, 0x90, 0x81, 0x6F, 0x66, + 0x08, 0xCE, 0x7D, 0xD4, 0x4E, 0xC2, 0x8D, 0xB1, + 0x14, 0x06, 0x14, 0xE1, 0xDD, 0xEB, 0xF3, 0xAA, + 0x9C, 0xD1, 0x84, 0x3E, 0x0F, 0xAD, 0x2C, 0x36 + }, + { + 0x8F, 0x94, 0x5B, 0xA7, 0x00, 0xF2, 0x53, 0x0E, + 0x5C, 0x2A, 0x7D, 0xF7, 0xD5, 0xDC, 0xE0, 0xF8, + 0x3F, 0x9E, 0xFC, 0x78, 0xC0, 0x73, 0xFE, 0x71, + 0xAE, 0x1F, 0x88, 0x20, 0x4A, 0x4F, 0xD1, 0xCF, + 0x70, 0xA0, 0x73, 0xF5, 0xD1, 0xF9, 0x42, 0xED, + 0x62, 0x3A, 0xA1, 0x6E, 0x90, 0xA8, 0x71, 0x24, + 0x6C, 0x90, 0xC4, 0x5B, 0x62, 0x1B, 0x34, 0x01, + 0xA5, 0xDD, 0xBD, 0x9D, 0xF6, 0x26, 0x41, 0x65 + }, + { + 0xE9, 0x98, 0xE0, 0xDC, 0x03, 0xEC, 0x30, 0xEB, + 0x99, 0xBB, 0x6B, 0xFA, 0xAF, 0x66, 0x18, 0xAC, + 0xC6, 0x20, 0x32, 0x0D, 0x72, 0x20, 0xB3, 0xAF, + 0x2B, 0x23, 0xD1, 0x12, 0xD8, 0xE9, 0xCB, 0x12, + 0x62, 0xF3, 0xC0, 0xD6, 0x0D, 0x18, 0x3B, 0x1E, + 0xE7, 0xF0, 0x96, 0xD1, 0x2D, 0xAE, 0x42, 0xC9, + 0x58, 0x41, 0x86, 0x00, 0x21, 0x4D, 0x04, 0xF5, + 0xED, 0x6F, 0x5E, 0x71, 0x8B, 0xE3, 0x55, 0x66 + }, + { + 0x6A, 0x9A, 0x09, 0x0C, 0x61, 0xB3, 0x41, 0x0A, + 0xED, 0xE7, 0xEC, 0x91, 0x38, 0x14, 0x6C, 0xEB, + 0x2C, 0x69, 0x66, 0x2F, 0x46, 0x0C, 0x3D, 0xA5, + 0x3C, 0x65, 0x15, 0xC1, 0xEB, 0x31, 0xF4, 0x1C, + 0xA3, 0xD2, 0x80, 0xE5, 0x67, 0x88, 0x2F, 0x95, + 0xCF, 0x66, 0x4A, 0x94, 0x14, 0x7D, 0x78, 0xF4, + 0x2C, 0xFC, 0x71, 0x4A, 0x40, 0xD2, 0x2E, 0xF1, + 0x94, 0x70, 0xE0, 0x53, 0x49, 0x35, 0x08, 0xA2 + }, + { + 0x29, 0x10, 0x25, 0x11, 0xD7, 0x49, 0xDB, 0x3C, + 0xC9, 0xB4, 0xE3, 0x35, 0xFA, 0x1F, 0x5E, 0x8F, + 0xAC, 0xA8, 0x42, 0x1D, 0x55, 0x8F, 0x6A, 0x3F, + 0x33, 0x21, 0xD5, 0x0D, 0x04, 0x4A, 0x24, 0x8B, + 0xA5, 0x95, 0xCF, 0xC3, 0xEF, 0xD3, 0xD2, 0xAD, + 0xC9, 0x73, 0x34, 0xDA, 0x73, 0x24, 0x13, 0xF5, + 0xCB, 0xF4, 0x75, 0x1C, 0x36, 0x2B, 0xA1, 0xD5, + 0x38, 0x62, 0xAC, 0x1E, 0x8D, 0xAB, 0xEE, 0xE8 + }, + { + 0xC9, 0x7A, 0x47, 0x79, 0xD4, 0x7E, 0x6F, 0x77, + 0x72, 0x9B, 0x59, 0x17, 0xD0, 0x13, 0x8A, 0xBB, + 0x35, 0x98, 0x0A, 0xB6, 0x41, 0xBD, 0x73, 0xA8, + 0x85, 0x9E, 0xB1, 0xAC, 0x98, 0xC0, 0x53, 0x62, + 0xED, 0x7D, 0x60, 0x8F, 0x2E, 0x95, 0x87, 0xD6, + 0xBA, 0x9E, 0x27, 0x1D, 0x34, 0x31, 0x25, 0xD4, + 0x0D, 0x93, 0x3A, 0x8E, 0xD0, 0x4E, 0xC1, 0xFE, + 0x75, 0xEC, 0x40, 0x7C, 0x7A, 0x53, 0xC3, 0x4E + }, + { + 0x10, 0xF0, 0xDC, 0x91, 0xB9, 0xF8, 0x45, 0xFB, + 0x95, 0xFA, 0xD6, 0x86, 0x0E, 0x6C, 0xE1, 0xAD, + 0xFA, 0x00, 0x2C, 0x7F, 0xC3, 0x27, 0x11, 0x6D, + 0x44, 0xD0, 0x47, 0xCD, 0x7D, 0x58, 0x70, 0xD7, + 0x72, 0xBB, 0x12, 0xB5, 0xFA, 0xC0, 0x0E, 0x02, + 0xB0, 0x8A, 0xC2, 0xA0, 0x17, 0x4D, 0x04, 0x46, + 0xC3, 0x6A, 0xB3, 0x5F, 0x14, 0xCA, 0x31, 0x89, + 0x4C, 0xD6, 0x1C, 0x78, 0xC8, 0x49, 0xB4, 0x8A + }, + { + 0xDE, 0xA9, 0x10, 0x1C, 0xAC, 0x62, 0xB8, 0xF6, + 0xA3, 0xC6, 0x50, 0xF9, 0x0E, 0xEA, 0x5B, 0xFA, + 0xE2, 0x65, 0x3A, 0x4E, 0xAF, 0xD6, 0x3A, 0x6D, + 0x1F, 0x0F, 0x13, 0x2D, 0xB9, 0xE4, 0xF2, 0xB1, + 0xB6, 0x62, 0x43, 0x2E, 0xC8, 0x5B, 0x17, 0xBC, + 0xAC, 0x41, 0xE7, 0x75, 0x63, 0x78, 0x81, 0xF6, + 0xAA, 0xB3, 0x8D, 0xD6, 0x6D, 0xCB, 0xD0, 0x80, + 0xF0, 0x99, 0x0A, 0x7A, 0x6E, 0x98, 0x54, 0xFE + }, + { + 0x44, 0x1F, 0xFA, 0xA0, 0x8C, 0xD7, 0x9D, 0xFF, + 0x4A, 0xFC, 0x9B, 0x9E, 0x5B, 0x56, 0x20, 0xEE, + 0xC0, 0x86, 0x73, 0x0C, 0x25, 0xF6, 0x61, 0xB1, + 0xD6, 0xFB, 0xFB, 0xD1, 0xCE, 0xC3, 0x14, 0x8D, + 0xD7, 0x22, 0x58, 0xC6, 0x56, 0x41, 0xF2, 0xFC, + 0xA5, 0xEB, 0x15, 0x5F, 0xAD, 0xBC, 0xAB, 0xB1, + 0x3C, 0x6E, 0x21, 0xDC, 0x11, 0xFA, 0xF7, 0x2C, + 0x2A, 0x28, 0x1B, 0x7D, 0x56, 0x14, 0x5F, 0x19 + }, + { + 0x44, 0x4B, 0x24, 0x0F, 0xE3, 0xED, 0x86, 0xD0, + 0xE2, 0xEF, 0x4C, 0xE7, 0xD8, 0x51, 0xED, 0xDE, + 0x22, 0x15, 0x55, 0x82, 0xAA, 0x09, 0x14, 0x79, + 0x7B, 0x72, 0x6C, 0xD0, 0x58, 0xB6, 0xF4, 0x59, + 0x32, 0xE0, 0xE1, 0x29, 0x51, 0x68, 0x76, 0x52, + 0x7B, 0x1D, 0xD8, 0x8F, 0xC6, 0x6D, 0x71, 0x19, + 0xF4, 0xAB, 0x3B, 0xED, 0x93, 0xA6, 0x1A, 0x0E, + 0x2D, 0x2D, 0x2A, 0xEA, 0xC3, 0x36, 0xD9, 0x58 + }, + { + 0xBF, 0xBA, 0xBB, 0xEF, 0x45, 0x55, 0x4C, 0xCF, + 0xA0, 0xDC, 0x83, 0x75, 0x2A, 0x19, 0xCC, 0x35, + 0xD5, 0x92, 0x09, 0x56, 0xB3, 0x01, 0xD5, 0x58, + 0xD7, 0x72, 0x28, 0x2B, 0xC8, 0x67, 0x00, 0x91, + 0x68, 0xE9, 0xE9, 0x86, 0x06, 0xBB, 0x5B, 0xA7, + 0x3A, 0x38, 0x5D, 0xE5, 0x74, 0x92, 0x28, 0xC9, + 0x25, 0xA8, 0x50, 0x19, 0xB7, 0x1F, 0x72, 0xFE, + 0x29, 0xB3, 0xCD, 0x37, 0xCA, 0x52, 0xEF, 0xE6 + }, + { + 0x9C, 0x4D, 0x0C, 0x3E, 0x1C, 0xDB, 0xBF, 0x48, + 0x5B, 0xEC, 0x86, 0xF4, 0x1C, 0xEC, 0x7C, 0x98, + 0x37, 0x3F, 0x0E, 0x09, 0xF3, 0x92, 0x84, 0x9A, + 0xAA, 0x22, 0x9E, 0xBF, 0xBF, 0x39, 0x7B, 0x22, + 0x08, 0x55, 0x29, 0xCB, 0x7E, 0xF3, 0x9F, 0x9C, + 0x7C, 0x22, 0x22, 0xA5, 0x14, 0x18, 0x2B, 0x1E, + 0xFF, 0xAA, 0x17, 0x8C, 0xC3, 0x68, 0x7B, 0x1B, + 0x2B, 0x6C, 0xBC, 0xB6, 0xFD, 0xEB, 0x96, 0xF8 + }, + { + 0x47, 0x71, 0x76, 0xB3, 0xBF, 0xCB, 0xAD, 0xD7, + 0x65, 0x7C, 0x23, 0xC2, 0x46, 0x25, 0xE4, 0xD0, + 0xD6, 0x74, 0xD1, 0x86, 0x8F, 0x00, 0x60, 0x06, + 0x39, 0x8A, 0xF9, 0x7A, 0xA4, 0x18, 0x77, 0xC8, + 0xE7, 0x0D, 0x3D, 0x14, 0xC3, 0xBB, 0xC9, 0xBB, + 0xCD, 0xCE, 0xA8, 0x01, 0xBD, 0x0E, 0x15, 0x99, + 0xAF, 0x1F, 0x3E, 0xEC, 0x67, 0x40, 0x51, 0x70, + 0xF4, 0xE2, 0x6C, 0x96, 0x4A, 0x57, 0xA8, 0xB7 + }, + { + 0xA7, 0x8C, 0x49, 0x0E, 0xDA, 0x31, 0x73, 0xBB, + 0x3F, 0x10, 0xDE, 0xE5, 0x2F, 0x11, 0x0F, 0xB1, + 0xC0, 0x8E, 0x03, 0x02, 0x23, 0x0B, 0x85, 0xDD, + 0xD7, 0xC1, 0x12, 0x57, 0xD9, 0x2D, 0xE1, 0x48, + 0x78, 0x5E, 0xF0, 0x0C, 0x03, 0x9C, 0x0B, 0xB8, + 0xEB, 0x98, 0x08, 0xA3, 0x5B, 0x2D, 0x8C, 0x08, + 0x0F, 0x57, 0x28, 0x59, 0x71, 0x4C, 0x9D, 0x40, + 0x69, 0xC5, 0xBC, 0xAF, 0x09, 0x0E, 0x89, 0x8E + }, + { + 0x58, 0xD0, 0x23, 0x39, 0x7B, 0xEB, 0x5B, 0x41, + 0x45, 0xCB, 0x22, 0x55, 0xB0, 0x7D, 0x74, 0x29, + 0x0B, 0x36, 0xD9, 0xFD, 0x1E, 0x59, 0x4A, 0xFB, + 0xD8, 0xEE, 0xA4, 0x7C, 0x20, 0x5B, 0x2E, 0xFB, + 0xFE, 0x6F, 0x46, 0x19, 0x0F, 0xAF, 0x95, 0xAF, + 0x50, 0x4A, 0xB0, 0x72, 0xE3, 0x6F, 0x6C, 0x85, + 0xD7, 0x67, 0xA3, 0x21, 0xBF, 0xD7, 0xF2, 0x26, + 0x87, 0xA4, 0xAB, 0xBF, 0x49, 0x4A, 0x68, 0x9C + }, + { + 0x40, 0x01, 0xEC, 0x74, 0xD5, 0xA4, 0x6F, 0xD2, + 0x9C, 0x2C, 0x3C, 0xDB, 0xE5, 0xD1, 0xB9, 0xF2, + 0x0E, 0x51, 0xA9, 0x41, 0xBE, 0x98, 0xD2, 0xA4, + 0xE1, 0xE2, 0xFB, 0xF8, 0x66, 0xA6, 0x72, 0x12, + 0x1D, 0xB6, 0xF8, 0x1A, 0x51, 0x4C, 0xFD, 0x10, + 0xE7, 0x35, 0x8D, 0x57, 0x1B, 0xDB, 0xA4, 0x8E, + 0x4C, 0xE7, 0x08, 0xB9, 0xD1, 0x24, 0x89, 0x4B, + 0xC0, 0xB5, 0xED, 0x55, 0x49, 0x35, 0xF7, 0x3A + }, + { + 0xCC, 0xD1, 0xB2, 0x2D, 0xAB, 0x65, 0x11, 0x22, + 0x5D, 0x24, 0x01, 0xEA, 0x2D, 0x86, 0x25, 0xD2, + 0x06, 0xA1, 0x24, 0x73, 0xCC, 0x73, 0x2B, 0x61, + 0x5E, 0x56, 0x40, 0xCE, 0xFF, 0xF0, 0xA4, 0xAD, + 0xF9, 0x71, 0xB0, 0xE8, 0x27, 0xA6, 0x19, 0xE0, + 0xA8, 0x0F, 0x5D, 0xB9, 0xCC, 0xD0, 0x96, 0x23, + 0x29, 0x01, 0x0D, 0x07, 0xE3, 0x4A, 0x20, 0x64, + 0xE7, 0x31, 0xC5, 0x20, 0x81, 0x7B, 0x21, 0x83 + }, + { + 0xB4, 0xA0, 0xA9, 0xE3, 0x57, 0x4E, 0xDB, 0x9E, + 0x1E, 0x72, 0xAA, 0x31, 0xE3, 0x9C, 0xC5, 0xF3, + 0x0D, 0xBF, 0x94, 0x3F, 0x8C, 0xAB, 0xC4, 0x08, + 0x44, 0x96, 0x54, 0xA3, 0x91, 0x31, 0xE6, 0x6D, + 0x71, 0x8A, 0x18, 0x81, 0x91, 0x43, 0xE3, 0xEA, + 0x96, 0xB4, 0xA1, 0x89, 0x59, 0x88, 0xA1, 0xC0, + 0x05, 0x6C, 0xF2, 0xB6, 0xE0, 0x4F, 0x9A, 0xC1, + 0x9D, 0x65, 0x73, 0x83, 0xC2, 0x91, 0x0C, 0x44 + }, + { + 0x44, 0x7B, 0xEC, 0xAB, 0x16, 0x63, 0x06, 0x08, + 0xD3, 0x9F, 0x4F, 0x05, 0x8B, 0x16, 0xF7, 0xAF, + 0x95, 0xB8, 0x5A, 0x76, 0xAA, 0x0F, 0xA7, 0xCE, + 0xA2, 0xB8, 0x07, 0x55, 0xFB, 0x76, 0xE9, 0xC8, + 0x04, 0xF2, 0xCA, 0x78, 0xF0, 0x26, 0x43, 0xC9, + 0x15, 0xFB, 0xF2, 0xFC, 0xE5, 0xE1, 0x9D, 0xE8, + 0x60, 0x00, 0xDE, 0x03, 0xB1, 0x88, 0x61, 0x81, + 0x5A, 0x83, 0x12, 0x60, 0x71, 0xF8, 0xA3, 0x7B + }, + { + 0x54, 0xE6, 0xDA, 0xB9, 0x97, 0x73, 0x80, 0xA5, + 0x66, 0x58, 0x22, 0xDB, 0x93, 0x37, 0x4E, 0xDA, + 0x52, 0x8D, 0x9B, 0xEB, 0x62, 0x6F, 0x9B, 0x94, + 0x02, 0x70, 0x71, 0xCB, 0x26, 0x67, 0x5E, 0x11, + 0x2B, 0x4A, 0x7F, 0xEC, 0x94, 0x1E, 0xE6, 0x0A, + 0x81, 0xE4, 0xD2, 0xEA, 0x3F, 0xF7, 0xBC, 0x52, + 0xCF, 0xC4, 0x5D, 0xFB, 0xFE, 0x73, 0x5A, 0x1C, + 0x64, 0x6B, 0x2C, 0xF6, 0xD6, 0xA4, 0x9B, 0x62 + }, + { + 0x3E, 0xA6, 0x26, 0x25, 0x94, 0x9E, 0x36, 0x46, + 0x70, 0x4D, 0x7E, 0x3C, 0x90, 0x6F, 0x82, 0xF6, + 0xC0, 0x28, 0xF5, 0x40, 0xF5, 0xF7, 0x2A, 0x79, + 0x4B, 0x0C, 0x57, 0xBF, 0x97, 0xB7, 0x64, 0x9B, + 0xFE, 0xB9, 0x0B, 0x01, 0xD3, 0xCA, 0x3E, 0x82, + 0x9D, 0xE2, 0x1B, 0x38, 0x26, 0xE6, 0xF8, 0x70, + 0x14, 0xD3, 0xC7, 0x73, 0x50, 0xCB, 0x5A, 0x15, + 0xFF, 0x5D, 0x46, 0x8A, 0x81, 0xBE, 0xC1, 0x60 + }, + { + 0x21, 0x3C, 0xFE, 0x14, 0x5C, 0x54, 0xA3, 0x36, + 0x91, 0x56, 0x99, 0x80, 0xE5, 0x93, 0x8C, 0x88, + 0x83, 0xA4, 0x6D, 0x84, 0xD1, 0x49, 0xC8, 0xFF, + 0x1A, 0x67, 0xCD, 0x28, 0x7B, 0x4D, 0x49, 0xC6, + 0xDA, 0x69, 0xD3, 0xA0, 0x35, 0x44, 0x3D, 0xB0, + 0x85, 0x98, 0x3D, 0x0E, 0xFE, 0x63, 0x70, 0x6B, + 0xD5, 0xB6, 0xF1, 0x5A, 0x7D, 0xA4, 0x59, 0xE8, + 0xD5, 0x0A, 0x19, 0x09, 0x3D, 0xB5, 0x5E, 0x80 + }, + { + 0x57, 0x16, 0xC4, 0xA3, 0x8F, 0x38, 0xDB, 0x10, + 0x4E, 0x49, 0x4A, 0x0A, 0x27, 0xCB, 0xE8, 0x9A, + 0x26, 0xA6, 0xBB, 0x6F, 0x49, 0x9E, 0xC0, 0x1C, + 0x8C, 0x01, 0xAA, 0x7C, 0xB8, 0x84, 0x97, 0xE7, + 0x51, 0x48, 0xCD, 0x6E, 0xEE, 0x12, 0xA7, 0x16, + 0x8B, 0x6F, 0x78, 0xAB, 0x74, 0xE4, 0xBE, 0x74, + 0x92, 0x51, 0xA1, 0xA7, 0x4C, 0x38, 0xC8, 0x6D, + 0x61, 0x29, 0x17, 0x7E, 0x28, 0x89, 0xE0, 0xB6 + }, + { + 0x03, 0x04, 0x60, 0xA9, 0x8B, 0xDF, 0x9F, 0xF1, + 0x7C, 0xD9, 0x64, 0x04, 0xF2, 0x8F, 0xC3, 0x04, + 0xF2, 0xB7, 0xC0, 0x4E, 0xAA, 0xDE, 0x53, 0x67, + 0x7F, 0xD2, 0x8F, 0x78, 0x8C, 0xA2, 0x21, 0x86, + 0xB8, 0xBC, 0x80, 0xDD, 0x21, 0xD1, 0x7F, 0x85, + 0x49, 0xC7, 0x11, 0xAF, 0xF0, 0xE5, 0x14, 0xE1, + 0x9D, 0x4E, 0x15, 0xF5, 0x99, 0x02, 0x52, 0xA0, + 0x3E, 0x08, 0x2F, 0x28, 0xDC, 0x20, 0x52, 0xF6 + }, + { + 0x19, 0xE7, 0xF1, 0xCC, 0xEE, 0x88, 0xA1, 0x06, + 0x72, 0x33, 0x3E, 0x39, 0x0C, 0xF2, 0x20, 0x13, + 0xA8, 0xC7, 0x34, 0xC6, 0xCB, 0x9E, 0xAB, 0x41, + 0xF1, 0x7C, 0x3C, 0x80, 0x32, 0xA2, 0xE4, 0xAC, + 0xA0, 0x56, 0x9E, 0xA3, 0x6F, 0x08, 0x60, 0xC7, + 0xA1, 0xAF, 0x28, 0xFA, 0x47, 0x68, 0x40, 0xD6, + 0x60, 0x11, 0x16, 0x88, 0x59, 0x33, 0x4A, 0x9E, + 0x4E, 0xF9, 0xCC, 0x2E, 0x61, 0xA0, 0xE2, 0x9E + }, + { + 0x29, 0xF8, 0xB8, 0xC7, 0x8C, 0x80, 0xF2, 0xFC, + 0xB4, 0xBD, 0xF7, 0x82, 0x5E, 0xD9, 0x0A, 0x70, + 0xD6, 0x25, 0xFF, 0x78, 0x5D, 0x26, 0x26, 0x77, + 0xE2, 0x50, 0xC0, 0x4F, 0x37, 0x20, 0xC8, 0x88, + 0xD0, 0x3F, 0x80, 0x45, 0xE4, 0xED, 0xF3, 0xF5, + 0x28, 0x5B, 0xD3, 0x9D, 0x92, 0x8A, 0x10, 0xA7, + 0xD0, 0xA5, 0xDF, 0x00, 0xB8, 0x48, 0x4A, 0xC2, + 0x86, 0x81, 0x42, 0xA1, 0xE8, 0xBE, 0xA3, 0x51 + }, + { + 0x5C, 0x52, 0x92, 0x0A, 0x72, 0x63, 0xE3, 0x9D, + 0x57, 0x92, 0x0C, 0xA0, 0xCB, 0x75, 0x2A, 0xC6, + 0xD7, 0x9A, 0x04, 0xFE, 0xF8, 0xA7, 0xA2, 0x16, + 0xA1, 0xEC, 0xB7, 0x11, 0x5C, 0xE0, 0x6D, 0x89, + 0xFD, 0x7D, 0x73, 0x5B, 0xD6, 0xF4, 0x27, 0x25, + 0x55, 0xDB, 0xA2, 0x2C, 0x2D, 0x1C, 0x96, 0xE6, + 0x35, 0x23, 0x22, 0xC6, 0x2C, 0x56, 0x30, 0xFD, + 0xE0, 0xF4, 0x77, 0x7A, 0x76, 0xC3, 0xDE, 0x2C + }, + { + 0x83, 0xB0, 0x98, 0xF2, 0x62, 0x25, 0x1B, 0xF6, + 0x60, 0x06, 0x4A, 0x9D, 0x35, 0x11, 0xCE, 0x76, + 0x87, 0xA0, 0x9E, 0x6D, 0xFB, 0xB8, 0x78, 0x29, + 0x9C, 0x30, 0xE9, 0x3D, 0xFB, 0x43, 0xA9, 0x31, + 0x4D, 0xB9, 0xA6, 0x00, 0x33, 0x7D, 0xB2, 0x6E, + 0xBE, 0xED, 0xAF, 0x22, 0x56, 0xA9, 0x6D, 0xAB, + 0xE9, 0xB2, 0x9E, 0x75, 0x73, 0xAD, 0x11, 0xC3, + 0x52, 0x3D, 0x87, 0x4D, 0xDE, 0x5B, 0xE7, 0xED + }, + { + 0x94, 0x47, 0xD9, 0x8A, 0xA5, 0xC9, 0x33, 0x13, + 0x52, 0xF4, 0x3D, 0x3E, 0x56, 0xD0, 0xA9, 0xA9, + 0xF9, 0x58, 0x18, 0x65, 0x99, 0x8E, 0x28, 0x85, + 0xCC, 0x56, 0xDD, 0x0A, 0x0B, 0xD5, 0xA7, 0xB5, + 0x05, 0x95, 0xBD, 0x10, 0xF7, 0x52, 0x9B, 0xCD, + 0x31, 0xF3, 0x7D, 0xC1, 0x6A, 0x14, 0x65, 0xD5, + 0x94, 0x07, 0x96, 0x67, 0xDA, 0x2A, 0x3F, 0xCB, + 0x70, 0x40, 0x14, 0x98, 0x83, 0x7C, 0xED, 0xEB + }, + { + 0x86, 0x77, 0x32, 0xF2, 0xFE, 0xEB, 0x23, 0x89, + 0x30, 0x97, 0x56, 0x1A, 0xC7, 0x10, 0xA4, 0xBF, + 0xF4, 0x53, 0xBE, 0x9C, 0xFB, 0xED, 0xBA, 0x8B, + 0xA3, 0x24, 0xF9, 0xD3, 0x12, 0xA8, 0x2D, 0x73, + 0x2E, 0x1B, 0x83, 0xB8, 0x29, 0xFD, 0xCD, 0x17, + 0x7B, 0x88, 0x2C, 0xA0, 0xC1, 0xBF, 0x54, 0x4B, + 0x22, 0x3B, 0xE5, 0x29, 0x92, 0x4A, 0x24, 0x6A, + 0x63, 0xCF, 0x05, 0x9B, 0xFD, 0xC5, 0x0A, 0x1B + }, + { + 0xF1, 0x5A, 0xB2, 0x6D, 0x4C, 0xDF, 0xCF, 0x56, + 0xE1, 0x96, 0xBB, 0x6B, 0xA1, 0x70, 0xA8, 0xFC, + 0xCC, 0x41, 0x4D, 0xE9, 0x28, 0x5A, 0xFD, 0x98, + 0xA3, 0xD3, 0xCF, 0x2F, 0xB8, 0x8F, 0xCB, 0xC0, + 0xF1, 0x98, 0x32, 0xAC, 0x43, 0x3A, 0x5B, 0x2C, + 0xC2, 0x39, 0x2A, 0x4C, 0xE3, 0x43, 0x32, 0x98, + 0x7D, 0x8D, 0x2C, 0x2B, 0xEF, 0x6C, 0x34, 0x66, + 0x13, 0x8D, 0xB0, 0xC6, 0xE4, 0x2F, 0xA4, 0x7B + }, + { + 0x28, 0x13, 0x51, 0x6D, 0x68, 0xED, 0x4A, 0x08, + 0xB3, 0x9D, 0x64, 0x8A, 0xA6, 0xAA, 0xCD, 0x81, + 0xE9, 0xD6, 0x55, 0xEC, 0xD5, 0xF0, 0xC1, 0x35, + 0x56, 0xC6, 0x0F, 0xDF, 0x0D, 0x33, 0x3E, 0xA3, + 0x84, 0x64, 0xB3, 0x6C, 0x02, 0xBA, 0xCC, 0xD7, + 0x46, 0xE9, 0x57, 0x5E, 0x96, 0xC6, 0x30, 0x14, + 0xF0, 0x74, 0xAE, 0x34, 0xA0, 0xA2, 0x5B, 0x32, + 0x0F, 0x0F, 0xBE, 0xDD, 0x6A, 0xCF, 0x76, 0x65 + }, + { + 0xD3, 0x25, 0x9A, 0xFC, 0xA8, 0xA4, 0x89, 0x62, + 0xFA, 0x89, 0x2E, 0x14, 0x5A, 0xCF, 0x54, 0x7F, + 0x26, 0x92, 0x3A, 0xE8, 0xD4, 0x92, 0x4C, 0x8A, + 0x53, 0x15, 0x81, 0x52, 0x6B, 0x04, 0xB4, 0x4C, + 0x7A, 0xF8, 0x3C, 0x64, 0x3E, 0xF5, 0xA0, 0xBC, + 0x28, 0x2D, 0x36, 0xF3, 0xFB, 0x04, 0xC8, 0x4E, + 0x28, 0xB3, 0x51, 0xF4, 0x0C, 0x74, 0xB6, 0x9D, + 0xC7, 0x84, 0x0B, 0xC7, 0x17, 0xB6, 0xF1, 0x5F + }, + { + 0xF1, 0x4B, 0x06, 0x1A, 0xE3, 0x59, 0xFA, 0x31, + 0xB9, 0x89, 0xE3, 0x03, 0x32, 0xBF, 0xE8, 0xDE, + 0x8C, 0xC8, 0xCD, 0xB5, 0x68, 0xE1, 0x4B, 0xE2, + 0x14, 0xA2, 0x22, 0x3B, 0x84, 0xCA, 0xAB, 0x74, + 0x19, 0x54, 0x9E, 0xCF, 0xCC, 0x96, 0xCE, 0x2A, + 0xCE, 0xC1, 0x19, 0x48, 0x5D, 0x87, 0xD1, 0x57, + 0xD3, 0xA8, 0x73, 0x4F, 0xC4, 0x26, 0x59, 0x7D, + 0x64, 0xF3, 0x65, 0x70, 0xCE, 0xAF, 0x22, 0x4D + }, + { + 0x55, 0xE7, 0x0B, 0x01, 0xD1, 0xFB, 0xF8, 0xB2, + 0x3B, 0x57, 0xFB, 0x62, 0xE2, 0x6C, 0x2C, 0xE5, + 0x4F, 0x13, 0xF8, 0xFA, 0x24, 0x64, 0xE6, 0xEB, + 0x98, 0xD1, 0x6A, 0x61, 0x17, 0x02, 0x6D, 0x8B, + 0x90, 0x81, 0x90, 0x12, 0x49, 0x6D, 0x40, 0x71, + 0xEB, 0xE2, 0xE5, 0x95, 0x57, 0xEC, 0xE3, 0x51, + 0x9A, 0x7A, 0xA4, 0x58, 0x02, 0xF9, 0x61, 0x53, + 0x74, 0x87, 0x73, 0x32, 0xB7, 0x34, 0x90, 0xB3 + }, + { + 0x25, 0x26, 0x1E, 0xB2, 0x96, 0x97, 0x1D, 0x6E, + 0x4A, 0x71, 0xB2, 0x92, 0x8E, 0x64, 0x83, 0x9C, + 0x67, 0xD4, 0x22, 0x87, 0x2B, 0xF9, 0xF3, 0xC3, + 0x19, 0x93, 0x61, 0x52, 0x22, 0xDE, 0x9F, 0x8F, + 0x0B, 0x2C, 0x4B, 0xE8, 0x54, 0x85, 0x59, 0xB4, + 0xB3, 0x54, 0xE7, 0x36, 0x41, 0x6E, 0x32, 0x18, + 0xD4, 0xE8, 0xA1, 0xE2, 0x19, 0xA4, 0xA6, 0xD4, + 0x3E, 0x1A, 0x9A, 0x52, 0x1D, 0x0E, 0x75, 0xFC + }, + { + 0x08, 0x30, 0x7F, 0x34, 0x7C, 0x41, 0x29, 0x4E, + 0x34, 0xBB, 0x54, 0xCB, 0x42, 0xB1, 0x52, 0x2D, + 0x22, 0xF8, 0x24, 0xF7, 0xB6, 0xE5, 0xDB, 0x50, + 0xFD, 0xA0, 0x96, 0x79, 0x8E, 0x18, 0x1A, 0x8F, + 0x02, 0x6F, 0xA2, 0x7B, 0x4A, 0xE4, 0x5D, 0x52, + 0xA6, 0x2C, 0xAF, 0x9D, 0x51, 0x98, 0xE2, 0x4A, + 0x49, 0x13, 0xC6, 0x67, 0x17, 0x75, 0xB2, 0xD7, + 0x23, 0xC1, 0x23, 0x9B, 0xFB, 0xF0, 0x16, 0xD7 + }, + { + 0x1E, 0x5C, 0x62, 0xE7, 0xE9, 0xBF, 0xA1, 0xB1, + 0x18, 0x74, 0x7A, 0x2D, 0xE0, 0x8B, 0x3C, 0xA1, + 0x01, 0x12, 0xAF, 0x96, 0xA4, 0x6E, 0x4B, 0x22, + 0xC3, 0xFC, 0x06, 0xF9, 0xBF, 0xEE, 0x4E, 0xB5, + 0xC4, 0x9E, 0x05, 0x7A, 0x4A, 0x48, 0x86, 0x23, + 0x43, 0x24, 0x57, 0x25, 0x76, 0xBB, 0x9B, 0x5E, + 0xCF, 0xDE, 0x0D, 0x99, 0xB0, 0xDE, 0x4F, 0x98, + 0xEC, 0x16, 0xE4, 0xD1, 0xB8, 0x5F, 0xA9, 0x47 + }, + { + 0xC7, 0x4A, 0x77, 0x39, 0x5F, 0xB8, 0xBC, 0x12, + 0x64, 0x47, 0x45, 0x48, 0x38, 0xE5, 0x61, 0xE9, + 0x62, 0x85, 0x3D, 0xC7, 0xEB, 0x49, 0xA1, 0xE3, + 0xCB, 0x67, 0xC3, 0xD0, 0x85, 0x1F, 0x3E, 0x39, + 0x51, 0x7B, 0xE8, 0xC3, 0x50, 0xAC, 0x91, 0x09, + 0x03, 0xD4, 0x9C, 0xD2, 0xBF, 0xDF, 0x54, 0x5C, + 0x99, 0x31, 0x6D, 0x03, 0x46, 0x17, 0x0B, 0x73, + 0x9F, 0x0A, 0xDD, 0x5D, 0x53, 0x3C, 0x2C, 0xFC + }, + { + 0x0D, 0xD5, 0x7B, 0x42, 0x3C, 0xC0, 0x1E, 0xB2, + 0x86, 0x13, 0x91, 0xEB, 0x88, 0x6A, 0x0D, 0x17, + 0x07, 0x9B, 0x93, 0x3F, 0xC7, 0x6E, 0xB3, 0xFC, + 0x08, 0xA1, 0x9F, 0x8A, 0x74, 0x95, 0x2C, 0xB6, + 0x8F, 0x6B, 0xCD, 0xC6, 0x44, 0xF7, 0x73, 0x70, + 0x96, 0x6E, 0x4D, 0x13, 0xE8, 0x05, 0x60, 0xBC, + 0xF0, 0x82, 0xEF, 0x04, 0x79, 0xD4, 0x8F, 0xBB, + 0xAB, 0x4D, 0xF0, 0x3B, 0x53, 0xA4, 0xE1, 0x78 + }, + { + 0x4D, 0x8D, 0xC3, 0x92, 0x3E, 0xDC, 0xCD, 0xFC, + 0xE7, 0x00, 0x72, 0x39, 0x8B, 0x8A, 0x3D, 0xA5, + 0xC3, 0x1F, 0xCB, 0x3E, 0xE3, 0xB6, 0x45, 0xC8, + 0x5F, 0x71, 0x7C, 0xBA, 0xEB, 0x4B, 0x67, 0x3A, + 0x19, 0x39, 0x44, 0x25, 0xA5, 0x85, 0xBF, 0xB4, + 0x64, 0xD9, 0x2F, 0x15, 0x97, 0xD0, 0xB7, 0x54, + 0xD1, 0x63, 0xF9, 0x7C, 0xED, 0x34, 0x3B, 0x25, + 0xDB, 0x5A, 0x70, 0xEF, 0x48, 0xEB, 0xB3, 0x4F + }, + { + 0xF0, 0xA5, 0x05, 0x53, 0xE4, 0xDF, 0xB0, 0xC4, + 0xE3, 0xE3, 0xD3, 0xBA, 0x82, 0x03, 0x48, 0x57, + 0xE3, 0xB1, 0xE5, 0x09, 0x18, 0xF5, 0xB8, 0xA7, + 0xD6, 0x98, 0xE1, 0x0D, 0x24, 0x2B, 0x0F, 0xB5, + 0x44, 0xAF, 0x6C, 0x92, 0xD0, 0xC3, 0xAA, 0xF9, + 0x93, 0x22, 0x20, 0x41, 0x61, 0x17, 0xB4, 0xE7, + 0x8E, 0xCB, 0x8A, 0x8F, 0x43, 0x0E, 0x13, 0xB8, + 0x2A, 0x59, 0x15, 0x29, 0x0A, 0x58, 0x19, 0xC5 + }, + { + 0xB1, 0x55, 0x43, 0xF3, 0xF7, 0x36, 0x08, 0x66, + 0x27, 0xCC, 0x53, 0x65, 0xE7, 0xE8, 0x98, 0x8C, + 0x2E, 0xF1, 0x55, 0xC0, 0xFD, 0x4F, 0x42, 0x89, + 0x61, 0xB0, 0x0D, 0x15, 0x26, 0xF0, 0x4D, 0x6D, + 0x6A, 0x65, 0x8B, 0x4B, 0x8E, 0xD3, 0x2C, 0x5D, + 0x86, 0x21, 0xE7, 0xF4, 0xF8, 0xE8, 0xA9, 0x33, + 0xD9, 0xEC, 0xC9, 0xDD, 0x1B, 0x83, 0x33, 0xCB, + 0xE2, 0x8C, 0xFC, 0x37, 0xD9, 0x71, 0x9E, 0x1C + }, + { + 0x7B, 0x4F, 0xA1, 0x58, 0xE4, 0x15, 0xFE, 0xF0, + 0x23, 0x24, 0x72, 0x64, 0xCB, 0xBE, 0x15, 0xD1, + 0x6D, 0x91, 0xA4, 0x44, 0x24, 0xA8, 0xDB, 0x70, + 0x7E, 0xB1, 0xE2, 0x03, 0x3C, 0x30, 0xE9, 0xE1, + 0xE7, 0xC8, 0xC0, 0x86, 0x45, 0x95, 0xD2, 0xCB, + 0x8C, 0x58, 0x0E, 0xB4, 0x7E, 0x9D, 0x16, 0xAB, + 0xBD, 0x7E, 0x44, 0xE8, 0x24, 0xF7, 0xCE, 0xDB, + 0x7D, 0xEF, 0x57, 0x13, 0x0E, 0x52, 0xCF, 0xE9 + }, + { + 0x60, 0x42, 0x4F, 0xF2, 0x32, 0x34, 0xC3, 0x4D, + 0xC9, 0x68, 0x7A, 0xD5, 0x02, 0x86, 0x93, 0x72, + 0xCC, 0x31, 0xA5, 0x93, 0x80, 0x18, 0x6B, 0xC2, + 0x36, 0x1C, 0x83, 0x5D, 0x97, 0x2F, 0x49, 0x66, + 0x6E, 0xB1, 0xAC, 0x69, 0x62, 0x9D, 0xE6, 0x46, + 0xF0, 0x3F, 0x9B, 0x4D, 0xB9, 0xE2, 0xAC, 0xE0, + 0x93, 0xFB, 0xFD, 0xF8, 0xF2, 0x0A, 0xB5, 0xF9, + 0x85, 0x41, 0x97, 0x8B, 0xE8, 0xEF, 0x54, 0x9F + }, + { + 0x74, 0x06, 0x01, 0x8C, 0xE7, 0x04, 0xD8, 0x4F, + 0x5E, 0xB9, 0xC7, 0x9F, 0xEA, 0x97, 0xDA, 0x34, + 0x56, 0x99, 0x46, 0x8A, 0x35, 0x0E, 0xE0, 0xB2, + 0xD0, 0xF3, 0xA4, 0xBF, 0x20, 0x70, 0x30, 0x4E, + 0xA8, 0x62, 0xD7, 0x2A, 0x51, 0xC5, 0x7D, 0x30, + 0x64, 0x94, 0x72, 0x86, 0xF5, 0x31, 0xE0, 0xEA, + 0xF7, 0x56, 0x37, 0x02, 0x26, 0x2E, 0x6C, 0x72, + 0x4A, 0xBF, 0x5E, 0xD8, 0xC8, 0x39, 0x8D, 0x17 + }, + { + 0x14, 0xEF, 0x5C, 0x6D, 0x64, 0x7B, 0x3B, 0xD1, + 0xE6, 0xE3, 0x20, 0x06, 0xC2, 0x31, 0x19, 0x98, + 0x10, 0xDE, 0x5C, 0x4D, 0xC8, 0x8E, 0x70, 0x24, + 0x02, 0x73, 0xB0, 0xEA, 0x18, 0xE6, 0x51, 0xA3, + 0xEB, 0x4F, 0x5C, 0xA3, 0x11, 0x4B, 0x8A, 0x56, + 0x71, 0x69, 0x69, 0xC7, 0xCD, 0xA2, 0x7E, 0x0C, + 0x8D, 0xB8, 0x32, 0xAD, 0x5E, 0x89, 0xA2, 0xDC, + 0x6C, 0xB0, 0xAD, 0xBE, 0x7D, 0x93, 0xAB, 0xD1 + }, + { + 0x38, 0xCF, 0x6C, 0x24, 0xE3, 0xE0, 0x8B, 0xCF, + 0x1F, 0x6C, 0xF3, 0xD1, 0xB1, 0xF6, 0x5B, 0x90, + 0x52, 0x39, 0xA3, 0x11, 0x80, 0x33, 0x24, 0x9E, + 0x44, 0x81, 0x13, 0xEC, 0x63, 0x2E, 0xA6, 0xDC, + 0x34, 0x6F, 0xEE, 0xB2, 0x57, 0x1C, 0x38, 0xBD, + 0x9A, 0x73, 0x98, 0xB2, 0x22, 0x12, 0x80, 0x32, + 0x80, 0x02, 0xB2, 0x3E, 0x1A, 0x45, 0xAD, 0xAF, + 0xFE, 0x66, 0xD9, 0x3F, 0x65, 0x64, 0xEA, 0xA2 + }, + { + 0x6C, 0xD7, 0x20, 0x8A, 0x4B, 0xC7, 0xE7, 0xE5, + 0x62, 0x01, 0xBB, 0xBA, 0x02, 0xA0, 0xF4, 0x89, + 0xCD, 0x38, 0x4A, 0xBE, 0x40, 0xAF, 0xD4, 0x22, + 0x2F, 0x15, 0x8B, 0x3D, 0x98, 0x6E, 0xE7, 0x2A, + 0x54, 0xC5, 0x0F, 0xB6, 0x4F, 0xD4, 0xED, 0x25, + 0x30, 0xED, 0xA2, 0xC8, 0xAF, 0x29, 0x28, 0xA0, + 0xDA, 0x6D, 0x4F, 0x83, 0x0A, 0xE1, 0xC9, 0xDB, + 0x46, 0x9D, 0xFD, 0x97, 0x0F, 0x12, 0xA5, 0x6F + }, + { + 0x65, 0x98, 0x58, 0xF0, 0xB5, 0xC9, 0xED, 0xAB, + 0x5B, 0x94, 0xFD, 0x73, 0x2F, 0x6E, 0x6B, 0x17, + 0xC5, 0x1C, 0xC0, 0x96, 0x10, 0x4F, 0x09, 0xBE, + 0xB3, 0xAF, 0xC3, 0xAA, 0x46, 0x7C, 0x2E, 0xCF, + 0x88, 0x5C, 0x4C, 0x65, 0x41, 0xEF, 0xFA, 0x90, + 0x23, 0xD3, 0xB5, 0x73, 0x8A, 0xE5, 0xA1, 0x4D, + 0x86, 0x7E, 0x15, 0xDB, 0x06, 0xFE, 0x1F, 0x9D, + 0x11, 0x27, 0xB7, 0x7E, 0x1A, 0xAB, 0xB5, 0x16 + }, + { + 0x26, 0xCC, 0xA0, 0x12, 0x6F, 0x5D, 0x1A, 0x81, + 0x3C, 0x62, 0xE5, 0xC7, 0x10, 0x01, 0xC0, 0x46, + 0xF9, 0xC9, 0x20, 0x95, 0x70, 0x45, 0x50, 0xBE, + 0x58, 0x73, 0xA4, 0x95, 0xA9, 0x99, 0xAD, 0x01, + 0x0A, 0x4F, 0x79, 0x49, 0x1F, 0x24, 0xF2, 0x86, + 0x50, 0x0A, 0xDC, 0xE1, 0xA1, 0x37, 0xBC, 0x20, + 0x84, 0xE4, 0x94, 0x9F, 0x5B, 0x72, 0x94, 0xCE, + 0xFE, 0x51, 0xEC, 0xAF, 0xF8, 0xE9, 0x5C, 0xBA + }, + { + 0x41, 0x47, 0xC1, 0xF5, 0x51, 0x72, 0x78, 0x8C, + 0x55, 0x67, 0xC5, 0x61, 0xFE, 0xEF, 0x87, 0x6F, + 0x62, 0x1F, 0xFF, 0x1C, 0xE8, 0x77, 0x86, 0xB8, + 0x46, 0x76, 0x37, 0xE7, 0x0D, 0xFB, 0xCD, 0x0D, + 0xBD, 0xB6, 0x41, 0x5C, 0xB6, 0x00, 0x95, 0x4A, + 0xB9, 0xC0, 0x4C, 0x0E, 0x45, 0x7E, 0x62, 0x5B, + 0x40, 0x72, 0x22, 0xC0, 0xFE, 0x1A, 0xE2, 0x1B, + 0x21, 0x43, 0x68, 0x8A, 0xDA, 0x94, 0xDC, 0x58 + }, + { + 0x5B, 0x1B, 0xF1, 0x54, 0xC6, 0x2A, 0x8A, 0xF6, + 0xE9, 0x3D, 0x35, 0xF1, 0x8F, 0x7F, 0x90, 0xAB, + 0xB1, 0x6A, 0x6E, 0xF0, 0xE8, 0xD1, 0xAE, 0xCD, + 0x11, 0x8B, 0xF7, 0x01, 0x67, 0xBA, 0xB2, 0xAF, + 0x08, 0x93, 0x5C, 0x6F, 0xDC, 0x06, 0x63, 0xCE, + 0x74, 0x48, 0x2D, 0x17, 0xA8, 0xE5, 0x4B, 0x54, + 0x6D, 0x1C, 0x29, 0x66, 0x31, 0xC6, 0x5F, 0x3B, + 0x52, 0x2A, 0x51, 0x58, 0x39, 0xD4, 0x3D, 0x71 + }, + { + 0x9F, 0x60, 0x04, 0x19, 0xA4, 0xE8, 0xF4, 0xFB, + 0x83, 0x4C, 0x24, 0xB0, 0xF7, 0xFC, 0x13, 0xBF, + 0x4E, 0x27, 0x9D, 0x98, 0xE8, 0xA3, 0xC7, 0x65, + 0xEE, 0x93, 0x49, 0x17, 0x40, 0x3E, 0x3A, 0x66, + 0x09, 0x71, 0x82, 0xEA, 0x21, 0x45, 0x3C, 0xB6, + 0x3E, 0xBB, 0xE8, 0xB7, 0x3A, 0x9C, 0x21, 0x67, + 0x59, 0x64, 0x46, 0x43, 0x8C, 0x57, 0x62, 0x7F, + 0x33, 0x0B, 0xAD, 0xD4, 0xF5, 0x69, 0xF7, 0xD6 + }, + { + 0x45, 0x7E, 0xF6, 0x46, 0x6A, 0x89, 0x24, 0xFD, + 0x80, 0x11, 0xA3, 0x44, 0x71, 0xA5, 0xA1, 0xAC, + 0x8C, 0xCD, 0x9B, 0xD0, 0xD0, 0x7A, 0x97, 0x41, + 0x4A, 0xC9, 0x43, 0x02, 0x1C, 0xE4, 0xB9, 0xE4, + 0xB9, 0xC8, 0xDB, 0x0A, 0x28, 0xF0, 0x16, 0xED, + 0x43, 0xB1, 0x54, 0x24, 0x81, 0x99, 0x00, 0x22, + 0x14, 0x7B, 0x31, 0x3E, 0x19, 0x46, 0x71, 0x13, + 0x1E, 0x70, 0x8D, 0xD4, 0x3A, 0x3E, 0xD7, 0xDC + }, + { + 0x99, 0x97, 0xB2, 0x19, 0x4D, 0x9A, 0xF6, 0xDF, + 0xCB, 0x91, 0x43, 0xF4, 0x1C, 0x0E, 0xD8, 0x3D, + 0x3A, 0x3F, 0x43, 0x88, 0x36, 0x11, 0x03, 0xD3, + 0x8C, 0x2A, 0x49, 0xB2, 0x80, 0xA5, 0x81, 0x21, + 0x27, 0x15, 0xFD, 0x90, 0x8D, 0x41, 0xC6, 0x51, + 0xF5, 0xC7, 0x15, 0xCA, 0x38, 0xC0, 0xCE, 0x28, + 0x30, 0xA3, 0x7E, 0x00, 0xE5, 0x08, 0xCE, 0xD1, + 0xBC, 0xDC, 0x32, 0x0E, 0x5E, 0x4D, 0x1E, 0x2E + }, + { + 0x5C, 0x6B, 0xBF, 0x16, 0xBA, 0xA1, 0x80, 0xF9, + 0x86, 0xBD, 0x40, 0xA1, 0x28, 0x7E, 0xD4, 0xC5, + 0x49, 0x77, 0x0E, 0x72, 0x84, 0x85, 0x8F, 0xC4, + 0x7B, 0xC2, 0x1A, 0xB9, 0x5E, 0xBB, 0xF3, 0x37, + 0x4B, 0x4E, 0xE3, 0xFD, 0x9F, 0x2A, 0xF6, 0x0F, + 0x33, 0x95, 0x22, 0x1B, 0x2A, 0xCC, 0x76, 0xF2, + 0xD3, 0x4C, 0x13, 0x29, 0x54, 0x04, 0x9F, 0x8A, + 0x3A, 0x99, 0x6F, 0x1E, 0x32, 0xEC, 0x84, 0xE5 + }, + { + 0xD1, 0x0B, 0xF9, 0xA1, 0x5B, 0x1C, 0x9F, 0xC8, + 0xD4, 0x1F, 0x89, 0xBB, 0x14, 0x0B, 0xF0, 0xBE, + 0x08, 0xD2, 0xF3, 0x66, 0x61, 0x76, 0xD1, 0x3B, + 0xAA, 0xC4, 0xD3, 0x81, 0x35, 0x8A, 0xD0, 0x74, + 0xC9, 0xD4, 0x74, 0x8C, 0x30, 0x05, 0x20, 0xEB, + 0x02, 0x6D, 0xAE, 0xAE, 0xA7, 0xC5, 0xB1, 0x58, + 0x89, 0x2F, 0xDE, 0x4E, 0x8E, 0xC1, 0x7D, 0xC9, + 0x98, 0xDC, 0xD5, 0x07, 0xDF, 0x26, 0xEB, 0x63 + }, + { + 0x2F, 0xC6, 0xE6, 0x9F, 0xA2, 0x6A, 0x89, 0xA5, + 0xED, 0x26, 0x90, 0x92, 0xCB, 0x9B, 0x2A, 0x44, + 0x9A, 0x44, 0x09, 0xA7, 0xA4, 0x40, 0x11, 0xEE, + 0xCA, 0xD1, 0x3D, 0x7C, 0x4B, 0x04, 0x56, 0x60, + 0x2D, 0x40, 0x2F, 0xA5, 0x84, 0x4F, 0x1A, 0x7A, + 0x75, 0x81, 0x36, 0xCE, 0x3D, 0x5D, 0x8D, 0x0E, + 0x8B, 0x86, 0x92, 0x1F, 0xFF, 0xF4, 0xF6, 0x92, + 0xDD, 0x95, 0xBD, 0xC8, 0xE5, 0xFF, 0x00, 0x52 + }, + { + 0xFC, 0xBE, 0x8B, 0xE7, 0xDC, 0xB4, 0x9A, 0x32, + 0xDB, 0xDF, 0x23, 0x94, 0x59, 0xE2, 0x63, 0x08, + 0xB8, 0x4D, 0xFF, 0x1E, 0xA4, 0x80, 0xDF, 0x8D, + 0x10, 0x4E, 0xEF, 0xF3, 0x4B, 0x46, 0xFA, 0xE9, + 0x86, 0x27, 0xB4, 0x50, 0xC2, 0x26, 0x7D, 0x48, + 0xC0, 0x94, 0x6A, 0x69, 0x7C, 0x5B, 0x59, 0x53, + 0x14, 0x52, 0xAC, 0x04, 0x84, 0xF1, 0xC8, 0x4E, + 0x3A, 0x33, 0xD0, 0xC3, 0x39, 0xBB, 0x2E, 0x28 + }, + { + 0xA1, 0x90, 0x93, 0xA6, 0xE3, 0xBC, 0xF5, 0x95, + 0x2F, 0x85, 0x0F, 0x20, 0x30, 0xF6, 0x9B, 0x96, + 0x06, 0xF1, 0x47, 0xF9, 0x0B, 0x8B, 0xAE, 0xE3, + 0x36, 0x2D, 0xA7, 0x1D, 0x9F, 0x35, 0xB4, 0x4E, + 0xF9, 0xD8, 0xF0, 0xA7, 0x71, 0x2B, 0xA1, 0x87, + 0x7F, 0xDD, 0xCD, 0x2D, 0x8E, 0xA8, 0xF1, 0xE5, + 0xA7, 0x73, 0xD0, 0xB7, 0x45, 0xD4, 0x72, 0x56, + 0x05, 0x98, 0x3A, 0x2D, 0xE9, 0x01, 0xF8, 0x03 + }, + { + 0x3C, 0x20, 0x06, 0x42, 0x3F, 0x73, 0xE2, 0x68, + 0xFA, 0x59, 0xD2, 0x92, 0x03, 0x77, 0xEB, 0x29, + 0xA4, 0xF9, 0xA8, 0xB4, 0x62, 0xBE, 0x15, 0x98, + 0x3E, 0xE3, 0xB8, 0x5A, 0xE8, 0xA7, 0x8E, 0x99, + 0x26, 0x33, 0x58, 0x1A, 0x90, 0x99, 0x89, 0x3B, + 0x63, 0xDB, 0x30, 0x24, 0x1C, 0x34, 0xF6, 0x43, + 0x02, 0x7D, 0xC8, 0x78, 0x27, 0x9A, 0xF5, 0x85, + 0x0D, 0x7E, 0x2D, 0x4A, 0x26, 0x53, 0x07, 0x3A + }, + { + 0xD0, 0xF2, 0xF2, 0xE3, 0x78, 0x76, 0x53, 0xF7, + 0x7C, 0xCE, 0x2F, 0xA2, 0x48, 0x35, 0x78, 0x5B, + 0xBD, 0x0C, 0x43, 0x3F, 0xC7, 0x79, 0x46, 0x5A, + 0x11, 0x51, 0x49, 0x90, 0x5A, 0x9D, 0xD1, 0xCB, + 0x82, 0x7A, 0x62, 0x85, 0x06, 0xD4, 0x57, 0xFC, + 0xF1, 0x24, 0xA0, 0xC2, 0xAE, 0xF9, 0xCE, 0x2D, + 0x2A, 0x0A, 0x0F, 0x63, 0x54, 0x55, 0x70, 0xD8, + 0x66, 0x7F, 0xF9, 0xE2, 0xEB, 0xA0, 0x73, 0x34 + }, + { + 0x78, 0xA9, 0xFC, 0x04, 0x8E, 0x25, 0xC6, 0xDC, + 0xB5, 0xDE, 0x45, 0x66, 0x7D, 0xE8, 0xFF, 0xDD, + 0x3A, 0x93, 0x71, 0x11, 0x41, 0xD5, 0x94, 0xE9, + 0xFA, 0x62, 0xA9, 0x59, 0x47, 0x5D, 0xA6, 0x07, + 0x5E, 0xA8, 0xF0, 0x91, 0x6E, 0x84, 0xE4, 0x5A, + 0xD9, 0x11, 0xB7, 0x54, 0x67, 0x07, 0x7E, 0xE5, + 0x2D, 0x2C, 0x9A, 0xEB, 0xF4, 0xD5, 0x8F, 0x20, + 0xCE, 0x4A, 0x3A, 0x00, 0x45, 0x8B, 0x05, 0xD4 + }, + { + 0x45, 0x81, 0x3F, 0x44, 0x17, 0x69, 0xAB, 0x6E, + 0xD3, 0x7D, 0x34, 0x9F, 0xF6, 0xE7, 0x22, 0x67, + 0xD7, 0x6A, 0xE6, 0xBB, 0x3E, 0x3C, 0x61, 0x2E, + 0xC0, 0x5C, 0x6E, 0x02, 0xA1, 0x2A, 0xF5, 0xA3, + 0x7C, 0x91, 0x8B, 0x52, 0xBF, 0x74, 0x26, 0x7C, + 0x3F, 0x6A, 0x3F, 0x18, 0x3A, 0x80, 0x64, 0xFF, + 0x84, 0xC0, 0x7B, 0x19, 0x3D, 0x08, 0x06, 0x67, + 0x89, 0xA0, 0x1A, 0xCC, 0xDB, 0x6F, 0x93, 0x40 + }, + { + 0x95, 0x6D, 0xA1, 0xC6, 0x8D, 0x83, 0xA7, 0xB8, + 0x81, 0xE0, 0x1B, 0x9A, 0x96, 0x6C, 0x3C, 0x0B, + 0xF2, 0x7F, 0x68, 0x60, 0x6A, 0x8B, 0x71, 0xD4, + 0x57, 0xBD, 0x01, 0x6D, 0x4C, 0x41, 0xDD, 0x8A, + 0x38, 0x0C, 0x70, 0x9A, 0x29, 0x6C, 0xB4, 0xC6, + 0x54, 0x47, 0x92, 0x92, 0x0F, 0xD7, 0x88, 0x83, + 0x57, 0x71, 0xA0, 0x7D, 0x4A, 0x16, 0xFB, 0x52, + 0xED, 0x48, 0x05, 0x03, 0x31, 0xDC, 0x4C, 0x8B + }, + { + 0xDF, 0x18, 0x6C, 0x2D, 0xC0, 0x9C, 0xAA, 0x48, + 0xE1, 0x4E, 0x94, 0x2F, 0x75, 0xDE, 0x5A, 0xC1, + 0xB7, 0xA2, 0x1E, 0x4F, 0x9F, 0x07, 0x2A, 0x5B, + 0x37, 0x1E, 0x09, 0xE0, 0x73, 0x45, 0xB0, 0x74, + 0x0C, 0x76, 0x17, 0x7B, 0x01, 0x27, 0x88, 0x08, + 0xFE, 0xC0, 0x25, 0xED, 0xED, 0x98, 0x22, 0xC1, + 0x22, 0xAF, 0xD1, 0xC6, 0x3E, 0x6F, 0x0C, 0xE2, + 0xE3, 0x26, 0x31, 0x04, 0x10, 0x63, 0x14, 0x5C + }, + { + 0x87, 0x47, 0x56, 0x40, 0x96, 0x6A, 0x9F, 0xDC, + 0xD6, 0xD3, 0xA3, 0xB5, 0xA2, 0xCC, 0xA5, 0xC0, + 0x8F, 0x0D, 0x88, 0x2B, 0x10, 0x24, 0x3C, 0x0E, + 0xC1, 0xBF, 0x3C, 0x6B, 0x1C, 0x37, 0xF2, 0xCD, + 0x32, 0x12, 0xF1, 0x9A, 0x05, 0x78, 0x64, 0x47, + 0x7D, 0x5E, 0xAF, 0x8F, 0xAE, 0xD7, 0x3F, 0x29, + 0x37, 0xC7, 0x68, 0xA0, 0xAF, 0x41, 0x5E, 0x84, + 0xBB, 0xCE, 0x6B, 0xD7, 0xDE, 0x23, 0xB6, 0x60 + }, + { + 0xC3, 0xB5, 0x73, 0xBB, 0xE1, 0x09, 0x49, 0xA0, + 0xFB, 0xD4, 0xFF, 0x88, 0x4C, 0x44, 0x6F, 0x22, + 0x29, 0xB7, 0x69, 0x02, 0xF9, 0xDF, 0xDB, 0xB8, + 0xA0, 0x35, 0x3D, 0xA5, 0xC8, 0x3C, 0xA1, 0x4E, + 0x81, 0x51, 0xBB, 0xAA, 0xC8, 0x2F, 0xD1, 0x57, + 0x6A, 0x00, 0x9A, 0xDC, 0x6F, 0x19, 0x35, 0xCF, + 0x26, 0xED, 0xD4, 0xF1, 0xFB, 0x8D, 0xA4, 0x83, + 0xE6, 0xC5, 0xCD, 0x9D, 0x89, 0x23, 0xAD, 0xC3 + }, + { + 0xB0, 0x9D, 0x8D, 0x0B, 0xBA, 0x8A, 0x72, 0x86, + 0xE4, 0x35, 0x68, 0xF7, 0x90, 0x75, 0x50, 0xE4, + 0x20, 0x36, 0xD6, 0x74, 0xE3, 0xC8, 0xFC, 0x34, + 0xD8, 0xCA, 0x46, 0xF7, 0x71, 0xD6, 0x46, 0x6B, + 0x70, 0xFB, 0x60, 0x58, 0x75, 0xF6, 0xA8, 0x63, + 0xC8, 0x77, 0xD1, 0x2F, 0x07, 0x06, 0x3F, 0xDC, + 0x2E, 0x90, 0xCC, 0xD4, 0x59, 0xB1, 0x91, 0x0D, + 0xCD, 0x52, 0xD8, 0xF1, 0x0B, 0x2B, 0x0A, 0x15 + }, + { + 0xAF, 0x3A, 0x22, 0xBF, 0x75, 0xB2, 0x1A, 0xBF, + 0xB0, 0xAC, 0xD5, 0x44, 0x22, 0xBA, 0x1B, 0x73, + 0x00, 0xA9, 0x52, 0xEF, 0xF0, 0x2E, 0xBE, 0xB6, + 0x5B, 0x5C, 0x23, 0x44, 0x71, 0xA9, 0x8D, 0xF3, + 0x2F, 0x4F, 0x96, 0x43, 0xCE, 0x19, 0x04, 0x10, + 0x8A, 0x16, 0x87, 0x67, 0x92, 0x42, 0x80, 0xBD, + 0x76, 0xC8, 0x3F, 0x8C, 0x82, 0xD9, 0xA7, 0x9D, + 0x92, 0x59, 0xB1, 0x95, 0x36, 0x2A, 0x2A, 0x04 + }, + { + 0xBF, 0x4F, 0xF2, 0x22, 0x1B, 0x7E, 0x69, 0x57, + 0xA7, 0x24, 0xCD, 0x96, 0x4A, 0xA3, 0xD5, 0xD0, + 0xD9, 0x94, 0x1F, 0x54, 0x04, 0x13, 0x75, 0x2F, + 0x46, 0x99, 0xD8, 0x10, 0x1B, 0x3E, 0x53, 0x75, + 0x08, 0xBF, 0x09, 0xF8, 0x50, 0x8B, 0x31, 0x77, + 0x36, 0xFF, 0xD2, 0x65, 0xF2, 0x84, 0x7A, 0xA7, + 0xD8, 0x4B, 0xD2, 0xD9, 0x75, 0x69, 0xC4, 0x9D, + 0x63, 0x2A, 0xED, 0x99, 0x45, 0xE5, 0xFA, 0x5E + }, + { + 0x9C, 0x6B, 0x6B, 0x78, 0x19, 0x9B, 0x1B, 0xDA, + 0xCB, 0x43, 0x00, 0xE3, 0x14, 0x79, 0xFA, 0x62, + 0x2A, 0x6B, 0x5B, 0xC8, 0x0D, 0x46, 0x78, 0xA6, + 0x07, 0x8F, 0x88, 0xA8, 0x26, 0x8C, 0xD7, 0x20, + 0x6A, 0x27, 0x99, 0xE8, 0xD4, 0x62, 0x1A, 0x46, + 0x4E, 0xF6, 0xB4, 0x3D, 0xD8, 0xAD, 0xFF, 0xE9, + 0x7C, 0xAF, 0x22, 0x1B, 0x22, 0xB6, 0xB8, 0x77, + 0x8B, 0x14, 0x9A, 0x82, 0x2A, 0xEF, 0xBB, 0x09 + }, + { + 0x89, 0x06, 0x56, 0xF0, 0x9C, 0x99, 0xD2, 0x80, + 0xB5, 0xEC, 0xB3, 0x81, 0xF5, 0x64, 0x27, 0xB8, + 0x13, 0x75, 0x1B, 0xC6, 0x52, 0xC7, 0x82, 0x80, + 0x78, 0xB2, 0x3A, 0x4A, 0xF8, 0x3B, 0x4E, 0x3A, + 0x61, 0xFD, 0xBA, 0xC6, 0x1F, 0x89, 0xBE, 0xE8, + 0x4E, 0xA6, 0xBE, 0xE7, 0x60, 0xC0, 0x47, 0xF2, + 0x5C, 0x6B, 0x0A, 0x20, 0x1C, 0x69, 0xA3, 0x8F, + 0xD6, 0xFD, 0x97, 0x1A, 0xF1, 0x85, 0x88, 0xBB + }, + { + 0x31, 0xA0, 0x46, 0xF7, 0x88, 0x2F, 0xFE, 0x6F, + 0x83, 0xCE, 0x47, 0x2E, 0x9A, 0x07, 0x01, 0x83, + 0x2E, 0xC7, 0xB3, 0xF7, 0x6F, 0xBC, 0xFD, 0x1D, + 0xF6, 0x0F, 0xE3, 0xEA, 0x48, 0xFD, 0xE1, 0x65, + 0x12, 0x54, 0x24, 0x7C, 0x3F, 0xD9, 0x5E, 0x10, + 0x0F, 0x91, 0x72, 0x73, 0x1E, 0x17, 0xFD, 0x52, + 0x97, 0xC1, 0x1F, 0x4B, 0xB3, 0x28, 0x36, 0x3C, + 0xA3, 0x61, 0x62, 0x4A, 0x81, 0xAF, 0x79, 0x7C + }, + { + 0x27, 0xA6, 0x0B, 0x2D, 0x00, 0xE7, 0xA6, 0x71, + 0xD4, 0x7D, 0x0A, 0xEC, 0x2A, 0x68, 0x6A, 0x0A, + 0xC0, 0x4B, 0x52, 0xF4, 0x0A, 0xB6, 0x62, 0x90, + 0x28, 0xEB, 0x7D, 0x13, 0xF4, 0xBA, 0xA9, 0x9A, + 0xC0, 0xFE, 0x46, 0xEE, 0x6C, 0x81, 0x49, 0x44, + 0xF2, 0xF4, 0xB4, 0xD2, 0x0E, 0x93, 0x78, 0xE4, + 0x84, 0x7E, 0xA4, 0x4C, 0x13, 0x17, 0x80, 0x91, + 0xE2, 0x77, 0xB8, 0x7E, 0xA7, 0xA5, 0x57, 0x11 + }, + { + 0x8B, 0x5C, 0xCE, 0xF1, 0x94, 0x16, 0x2C, 0x1F, + 0x19, 0xD6, 0x8F, 0x91, 0xE0, 0xB0, 0x92, 0x8F, + 0x28, 0x9E, 0xC5, 0x28, 0x37, 0x20, 0x84, 0x0C, + 0x2F, 0x73, 0xD2, 0x53, 0x11, 0x12, 0x38, 0xDC, + 0xFE, 0x94, 0xAF, 0x2B, 0x59, 0xC2, 0xC1, 0xCA, + 0x25, 0x91, 0x90, 0x1A, 0x7B, 0xC0, 0x60, 0xE7, + 0x45, 0x9B, 0x6C, 0x47, 0xDF, 0x0F, 0x71, 0x70, + 0x1A, 0x35, 0xCC, 0x0A, 0xA8, 0x31, 0xB5, 0xB6 + }, + { + 0x57, 0xAB, 0x6C, 0x4B, 0x22, 0x29, 0xAE, 0xB3, + 0xB7, 0x04, 0x76, 0xD8, 0x03, 0xCD, 0x63, 0x81, + 0x2F, 0x10, 0x7C, 0xE6, 0xDA, 0x17, 0xFE, 0xD9, + 0xB1, 0x78, 0x75, 0xE8, 0xF8, 0x6C, 0x72, 0x4F, + 0x49, 0xE0, 0x24, 0xCB, 0xF3, 0xA1, 0xB8, 0xB1, + 0x19, 0xC5, 0x03, 0x57, 0x65, 0x2B, 0x81, 0x87, + 0x9D, 0x2A, 0xDE, 0x2D, 0x58, 0x8B, 0x9E, 0x4F, + 0x7C, 0xED, 0xBA, 0x0E, 0x46, 0x44, 0xC9, 0xEE + }, + { + 0x01, 0x90, 0xA8, 0xDA, 0xC3, 0x20, 0xA7, 0x39, + 0xF3, 0x22, 0xE1, 0x57, 0x31, 0xAA, 0x14, 0x0D, + 0xDA, 0xF5, 0xBE, 0xD2, 0x94, 0xD5, 0xC8, 0x2E, + 0x54, 0xFE, 0xF2, 0x9F, 0x21, 0x4E, 0x18, 0xAA, + 0xFA, 0xA8, 0x4F, 0x8B, 0xE9, 0x9A, 0xF6, 0x29, + 0x50, 0x26, 0x6B, 0x8F, 0x90, 0x1F, 0x15, 0xDD, + 0x4C, 0x5D, 0x35, 0x51, 0x6F, 0xC3, 0x5B, 0x4C, + 0xAB, 0x2E, 0x96, 0xE4, 0x69, 0x5B, 0xBE, 0x1C + }, + { + 0xD1, 0x4D, 0x7C, 0x4C, 0x41, 0x5E, 0xEB, 0x0E, + 0x10, 0xB1, 0x59, 0x22, 0x4B, 0xEA, 0x12, 0x7E, + 0xBD, 0x84, 0xF9, 0x59, 0x1C, 0x70, 0x2A, 0x33, + 0x0F, 0x5B, 0xB7, 0xBB, 0x7A, 0xA4, 0x4E, 0xA3, + 0x9D, 0xE6, 0xED, 0x01, 0xF1, 0x8D, 0xA7, 0xAD, + 0xF4, 0x0C, 0xFB, 0x97, 0xC5, 0xD1, 0x52, 0xC2, + 0x75, 0x28, 0x82, 0x4B, 0x21, 0xE2, 0x39, 0x52, + 0x6A, 0xF8, 0xF3, 0x6B, 0x21, 0x4E, 0x0C, 0xFB + }, + { + 0xBE, 0x28, 0xC4, 0xBE, 0x70, 0x69, 0x70, 0x48, + 0x8F, 0xAC, 0x7D, 0x29, 0xC3, 0xBD, 0x5C, 0x4E, + 0x98, 0x60, 0x85, 0xC4, 0xC3, 0x33, 0x2F, 0x1F, + 0x3F, 0xD3, 0x09, 0x73, 0xDB, 0x61, 0x41, 0x64, + 0xBA, 0x2F, 0x31, 0xA7, 0x88, 0x75, 0xFF, 0xDC, + 0x15, 0x03, 0x25, 0xC8, 0x83, 0x27, 0xA9, 0x44, + 0x3E, 0xD0, 0x4F, 0xDF, 0xE5, 0xBE, 0x93, 0x87, + 0x6D, 0x16, 0x28, 0x56, 0x0C, 0x76, 0x4A, 0x80 + }, + { + 0x03, 0x1D, 0xA1, 0x06, 0x9E, 0x3A, 0x2E, 0x9C, + 0x33, 0x82, 0xE4, 0x36, 0xFF, 0xD7, 0x9D, 0xF7, + 0x4B, 0x1C, 0xA6, 0xA8, 0xAD, 0xB2, 0xDE, 0xAB, + 0xE6, 0x76, 0xAB, 0x45, 0x99, 0x4C, 0xBC, 0x05, + 0x4F, 0x03, 0x7D, 0x2F, 0x0E, 0xAC, 0xE8, 0x58, + 0xD3, 0x2C, 0x14, 0xE2, 0xD1, 0xC8, 0xB4, 0x60, + 0x77, 0x30, 0x8E, 0x3B, 0xDC, 0x2C, 0x1B, 0x53, + 0x17, 0x2E, 0xCF, 0x7A, 0x8C, 0x14, 0xE3, 0x49 + }, + { + 0x46, 0x65, 0xCE, 0xF8, 0xBA, 0x4D, 0xB4, 0xD0, + 0xAC, 0xB1, 0x18, 0xF2, 0x98, 0x7F, 0x0B, 0xB0, + 0x9F, 0x8F, 0x86, 0xAA, 0x44, 0x5A, 0xA3, 0xD5, + 0xFC, 0x9A, 0x8B, 0x34, 0x68, 0x64, 0x78, 0x74, + 0x89, 0xE8, 0xFC, 0xEC, 0xC1, 0x25, 0xD1, 0x7E, + 0x9B, 0x56, 0xE1, 0x29, 0x88, 0xEA, 0xC5, 0xEC, + 0xC7, 0x28, 0x68, 0x83, 0xDB, 0x06, 0x61, 0xB8, + 0xFF, 0x05, 0xDA, 0x2A, 0xFF, 0xF3, 0x0F, 0xE4 + }, + { + 0x63, 0xB7, 0x03, 0x2E, 0x5F, 0x93, 0x0C, 0xC9, + 0x93, 0x95, 0x17, 0xF9, 0xE9, 0x86, 0x81, 0x6C, + 0xFB, 0xEC, 0x2B, 0xE5, 0x9B, 0x95, 0x68, 0xB1, + 0x3F, 0x2E, 0xAD, 0x05, 0xBA, 0xE7, 0x77, 0x7C, + 0xAB, 0x62, 0x0C, 0x66, 0x59, 0x40, 0x4F, 0x74, + 0x09, 0xE4, 0x19, 0x9A, 0x3B, 0xE5, 0xF7, 0x86, + 0x5A, 0xA7, 0xCB, 0xDF, 0x8C, 0x42, 0x53, 0xF7, + 0xE8, 0x21, 0x9B, 0x1B, 0xD5, 0xF4, 0x6F, 0xEA + }, + { + 0x9F, 0x09, 0xBF, 0x09, 0x3A, 0x2B, 0x0F, 0xF8, + 0xC2, 0x63, 0x4B, 0x49, 0xE3, 0x7F, 0x1B, 0x21, + 0x35, 0xB4, 0x47, 0xAA, 0x91, 0x44, 0xC9, 0x78, + 0x7D, 0xBF, 0xD9, 0x21, 0x29, 0x31, 0x6C, 0x99, + 0xE8, 0x8A, 0xAB, 0x8A, 0x21, 0xFD, 0xEF, 0x23, + 0x72, 0xD1, 0x18, 0x9A, 0xEC, 0x50, 0x0F, 0x95, + 0x77, 0x5F, 0x1F, 0x92, 0xBF, 0xB4, 0x55, 0x45, + 0xE4, 0x25, 0x9F, 0xB9, 0xB7, 0xB0, 0x2D, 0x14 + }, + { + 0xF9, 0xF8, 0x49, 0x3C, 0x68, 0x08, 0x88, 0x07, + 0xDF, 0x7F, 0x6A, 0x26, 0x93, 0xD6, 0x4E, 0xA5, + 0x9F, 0x03, 0xE9, 0xE0, 0x5A, 0x22, 0x3E, 0x68, + 0x52, 0x4C, 0xA3, 0x21, 0x95, 0xA4, 0x73, 0x4B, + 0x65, 0x4F, 0xCE, 0xA4, 0xD2, 0x73, 0x4C, 0x86, + 0x6C, 0xF9, 0x5C, 0x88, 0x9F, 0xB1, 0x0C, 0x49, + 0x15, 0x9B, 0xE2, 0xF5, 0x04, 0x3D, 0xC9, 0x8B, + 0xB5, 0x5E, 0x02, 0xEF, 0x7B, 0xDC, 0xB0, 0x82 + }, + { + 0x3C, 0x9A, 0x73, 0x59, 0xAB, 0x4F, 0xEB, 0xCE, + 0x07, 0xB2, 0x0A, 0xC4, 0x47, 0xB0, 0x6A, 0x24, + 0x0B, 0x7F, 0xE1, 0xDA, 0xE5, 0x43, 0x9C, 0x49, + 0xB6, 0x0B, 0x58, 0x19, 0xF7, 0x81, 0x2E, 0x4C, + 0x17, 0x24, 0x06, 0xC1, 0xAA, 0xC3, 0x16, 0x71, + 0x3C, 0xF0, 0xDD, 0xED, 0x10, 0x38, 0x07, 0x72, + 0x58, 0xE2, 0xEF, 0xF5, 0xB3, 0x39, 0x13, 0xD9, + 0xD9, 0x5C, 0xAE, 0xB4, 0xE6, 0xC6, 0xB9, 0x70 + }, + { + 0xAD, 0x6A, 0xAB, 0x80, 0x84, 0x51, 0x0E, 0x82, + 0x2C, 0xFC, 0xE8, 0x62, 0x5D, 0x62, 0xCF, 0x4D, + 0xE6, 0x55, 0xF4, 0x76, 0x38, 0x84, 0xC7, 0x1E, + 0x80, 0xBA, 0xB9, 0xAC, 0x9D, 0x53, 0x18, 0xDB, + 0xA4, 0xA6, 0x03, 0x3E, 0xD2, 0x90, 0x84, 0xE6, + 0x52, 0x16, 0xC0, 0x31, 0x60, 0x6C, 0xA1, 0x76, + 0x15, 0xDC, 0xFE, 0x3B, 0xA1, 0x1D, 0x26, 0x85, + 0x1A, 0xE0, 0x99, 0x9C, 0xA6, 0xE2, 0x32, 0xCF + }, + { + 0x15, 0x6E, 0x9E, 0x62, 0x61, 0x37, 0x4C, 0x9D, + 0xC8, 0x84, 0xF3, 0x6E, 0x70, 0xF0, 0xFE, 0x1A, + 0xB9, 0x29, 0x79, 0x97, 0xB8, 0x36, 0xFA, 0x7D, + 0x17, 0x0A, 0x9C, 0x9E, 0xBF, 0x57, 0x5B, 0x88, + 0x1E, 0x7B, 0xCE, 0xA4, 0x4D, 0x6C, 0x02, 0x48, + 0xD3, 0x55, 0x97, 0x90, 0x71, 0x54, 0x82, 0x89, + 0x55, 0xBE, 0x19, 0x13, 0x58, 0x52, 0xF9, 0x22, + 0x88, 0x15, 0xEC, 0xA0, 0x24, 0xA8, 0xAD, 0xFB + }, + { + 0x42, 0x15, 0x40, 0x76, 0x33, 0xF4, 0xCC, 0xA9, + 0xB6, 0x78, 0x8B, 0xE9, 0x3E, 0x6A, 0xA3, 0xD9, + 0x63, 0xC7, 0xD6, 0xCE, 0x4B, 0x14, 0x72, 0x47, + 0x09, 0x9F, 0x46, 0xA3, 0xAC, 0xB5, 0x00, 0xA3, + 0x00, 0x38, 0xCB, 0x3E, 0x78, 0x8C, 0x3D, 0x29, + 0xF1, 0x32, 0xAD, 0x84, 0x4E, 0x80, 0xE9, 0xE9, + 0x92, 0x51, 0xF6, 0xDB, 0x96, 0xAC, 0xD8, 0xA0, + 0x91, 0xCF, 0xC7, 0x70, 0xAF, 0x53, 0x84, 0x7B + }, + { + 0x1C, 0x07, 0x7E, 0x27, 0x9D, 0xE6, 0x54, 0x85, + 0x23, 0x50, 0x2B, 0x6D, 0xF8, 0x00, 0xFF, 0xDA, + 0xB5, 0xE2, 0xC3, 0xE9, 0x44, 0x2E, 0xB8, 0x38, + 0xF5, 0x8C, 0x29, 0x5F, 0x3B, 0x14, 0x7C, 0xEF, + 0x9D, 0x70, 0x1C, 0x41, 0xC3, 0x21, 0x28, 0x3F, + 0x00, 0xC7, 0x1A, 0xFF, 0xA0, 0x61, 0x93, 0x10, + 0x39, 0x91, 0x26, 0x29, 0x5B, 0x78, 0xDD, 0x4D, + 0x1A, 0x74, 0x57, 0x2E, 0xF9, 0xED, 0x51, 0x35 + }, + { + 0xF0, 0x7A, 0x55, 0x5F, 0x49, 0xFE, 0x48, 0x1C, + 0xF4, 0xCD, 0x0A, 0x87, 0xB7, 0x1B, 0x82, 0xE4, + 0xA9, 0x50, 0x64, 0xD0, 0x66, 0x77, 0xFD, 0xD9, + 0x0A, 0x0E, 0xB5, 0x98, 0x87, 0x7B, 0xA1, 0xC8, + 0x3D, 0x46, 0x77, 0xB3, 0x93, 0xC3, 0xA3, 0xB6, + 0x66, 0x1C, 0x42, 0x1F, 0x5B, 0x12, 0xCB, 0x99, + 0xD2, 0x03, 0x76, 0xBA, 0x72, 0x75, 0xC2, 0xF3, + 0xA8, 0xF5, 0xA9, 0xB7, 0x82, 0x17, 0x20, 0xDA + }, + { + 0xB5, 0x91, 0x1B, 0x38, 0x0D, 0x20, 0xC7, 0xB0, + 0x43, 0x23, 0xE4, 0x02, 0x6B, 0x38, 0xE2, 0x00, + 0xF5, 0x34, 0x25, 0x92, 0x33, 0xB5, 0x81, 0xE0, + 0x2C, 0x1E, 0x3E, 0x2D, 0x84, 0x38, 0xD6, 0xC6, + 0x6D, 0x5A, 0x4E, 0xB2, 0x01, 0xD5, 0xA8, 0xB7, + 0x50, 0x72, 0xC4, 0xEC, 0x29, 0x10, 0x63, 0x34, + 0xDA, 0x70, 0xBC, 0x79, 0x52, 0x1B, 0x0C, 0xED, + 0x2C, 0xFD, 0x53, 0x3F, 0x5F, 0xF8, 0x4F, 0x95 + }, + { + 0x01, 0xF0, 0x70, 0xA0, 0x9B, 0xAE, 0x91, 0x12, + 0x96, 0x36, 0x1F, 0x91, 0xAA, 0x0E, 0x8E, 0x0D, + 0x09, 0xA7, 0x72, 0x54, 0x78, 0x53, 0x6D, 0x9D, + 0x48, 0xC5, 0xFE, 0x1E, 0x5E, 0x7C, 0x3C, 0x5B, + 0x9B, 0x9D, 0x6E, 0xB0, 0x77, 0x96, 0xF6, 0xDA, + 0x57, 0xAE, 0x56, 0x2A, 0x7D, 0x70, 0xE8, 0x82, + 0xE3, 0x7A, 0xDF, 0xDE, 0x83, 0xF0, 0xC4, 0x33, + 0xC2, 0xCD, 0x36, 0x35, 0x36, 0xBB, 0x22, 0xC8 + }, + { + 0x6F, 0x79, 0x3E, 0xB4, 0x37, 0x4A, 0x48, 0xB0, + 0x77, 0x5A, 0xCA, 0xF9, 0xAD, 0xCF, 0x8E, 0x45, + 0xE5, 0x42, 0x70, 0xC9, 0x47, 0x5F, 0x00, 0x4A, + 0xD8, 0xD5, 0x97, 0x3E, 0x2A, 0xCA, 0x52, 0x74, + 0x7F, 0xF4, 0xED, 0x04, 0xAE, 0x96, 0x72, 0x75, + 0xB9, 0xF9, 0xEB, 0x0E, 0x1F, 0xF7, 0x5F, 0xB4, + 0xF7, 0x94, 0xFA, 0x8B, 0xE9, 0xAD, 0xD7, 0xA4, + 0x13, 0x04, 0x86, 0x8D, 0x10, 0x3F, 0xAB, 0x10 + }, + { + 0x96, 0x5F, 0x20, 0xF1, 0x39, 0x76, 0x5F, 0xCC, + 0x4C, 0xE4, 0xBA, 0x37, 0x94, 0x67, 0x58, 0x63, + 0xCA, 0xC2, 0x4D, 0xB4, 0x72, 0xCD, 0x2B, 0x79, + 0x9D, 0x03, 0x5B, 0xCE, 0x3D, 0xBE, 0xA5, 0x02, + 0xDA, 0x7B, 0x52, 0x48, 0x65, 0xF6, 0xB8, 0x11, + 0xD8, 0xC5, 0x82, 0x8D, 0x3A, 0x88, 0x96, 0x46, + 0xFE, 0x64, 0xA3, 0x80, 0xDA, 0x1A, 0xA7, 0xC7, + 0x04, 0x4E, 0x9F, 0x24, 0x5D, 0xCE, 0xD1, 0x28 + }, + { + 0xEC, 0x29, 0x5B, 0x57, 0x83, 0x60, 0x12, 0x44, + 0xC3, 0x0E, 0x46, 0x41, 0xE3, 0xB4, 0x5B, 0xE2, + 0x22, 0xC4, 0xDC, 0xE7, 0x7A, 0x58, 0x70, 0x0F, + 0x53, 0xBC, 0x8E, 0xC5, 0x2A, 0x94, 0x16, 0x90, + 0xB4, 0xD0, 0xB0, 0x87, 0xFB, 0x6F, 0xCB, 0x3F, + 0x39, 0x83, 0x2B, 0x9D, 0xE8, 0xF7, 0x5E, 0xC2, + 0x0B, 0xD4, 0x30, 0x79, 0x81, 0x17, 0x49, 0xCD, + 0xC9, 0x07, 0xED, 0xB9, 0x41, 0x57, 0xD1, 0x80 + }, + { + 0x61, 0xC7, 0x2F, 0x8C, 0xCC, 0x91, 0xDB, 0xB5, + 0x4C, 0xA6, 0x75, 0x0B, 0xC4, 0x89, 0x67, 0x2D, + 0xE0, 0x9F, 0xAE, 0xDB, 0x8F, 0xDD, 0x4F, 0x94, + 0xFF, 0x23, 0x20, 0x90, 0x9A, 0x30, 0x3F, 0x5D, + 0x5A, 0x98, 0x48, 0x1C, 0x0B, 0xC1, 0xA6, 0x25, + 0x41, 0x9F, 0xB4, 0xDE, 0xBF, 0xBF, 0x7F, 0x8A, + 0x53, 0xBB, 0x07, 0xEC, 0x3D, 0x98, 0x5E, 0x8E, + 0xA1, 0x1E, 0x72, 0xD5, 0x59, 0x94, 0x07, 0x80 + }, + { + 0xAF, 0xD8, 0x14, 0x5B, 0x25, 0x9E, 0xEF, 0xC8, + 0xD1, 0x26, 0x20, 0xC3, 0xC5, 0xB0, 0x3E, 0x1E, + 0xD8, 0xFD, 0x2C, 0xCE, 0xFE, 0x03, 0x65, 0x07, + 0x8C, 0x80, 0xFD, 0x42, 0xC1, 0x77, 0x0E, 0x28, + 0xB4, 0x49, 0x48, 0xF2, 0x7E, 0x65, 0xA1, 0x88, + 0x66, 0x90, 0x11, 0x0D, 0xB8, 0x14, 0x39, 0x7B, + 0x68, 0xE4, 0x3D, 0x80, 0xD1, 0xBA, 0x16, 0xDF, + 0xA3, 0x58, 0xE7, 0x39, 0xC8, 0x98, 0xCF, 0xA3 + }, + { + 0x55, 0x2F, 0xC7, 0x89, 0x3C, 0xF1, 0xCE, 0x93, + 0x3A, 0xDA, 0x35, 0xC0, 0xDA, 0x98, 0x84, 0x4E, + 0x41, 0x54, 0x5E, 0x24, 0x4C, 0x31, 0x57, 0xA1, + 0x42, 0x8D, 0x7B, 0x4C, 0x21, 0xF9, 0xCD, 0x7E, + 0x40, 0x71, 0xAE, 0xD7, 0x7B, 0x7C, 0xA9, 0xF1, + 0xC3, 0x8F, 0xBA, 0x32, 0x23, 0x74, 0x12, 0xEF, + 0x21, 0xA3, 0x42, 0x74, 0x2E, 0xC8, 0x32, 0x43, + 0x78, 0xF2, 0x1E, 0x50, 0x7F, 0xAF, 0xDD, 0x88 + }, + { + 0x46, 0x7A, 0x33, 0xFB, 0xAD, 0xF5, 0xEB, 0xC5, + 0x25, 0x96, 0xEF, 0x86, 0xAA, 0xAE, 0xFC, 0x6F, + 0xAB, 0xA8, 0xEE, 0x65, 0x1B, 0x1C, 0xE0, 0x4D, + 0xE3, 0x68, 0xA0, 0x3A, 0x5A, 0x90, 0x40, 0xEF, + 0x28, 0x35, 0xE0, 0x0A, 0xDB, 0x09, 0xAB, 0xB3, + 0xFB, 0xD2, 0xBC, 0xE8, 0x18, 0xA2, 0x41, 0x3D, + 0x0B, 0x02, 0x53, 0xB5, 0xBD, 0xA4, 0xFC, 0x5B, + 0x2F, 0x6F, 0x85, 0xF3, 0xFD, 0x5B, 0x55, 0xF2 + }, + { + 0x22, 0xEF, 0xF8, 0xE6, 0xDD, 0x52, 0x36, 0xF5, + 0xF5, 0x7D, 0x94, 0xED, 0xE8, 0x74, 0xD6, 0xC9, + 0x42, 0x8E, 0x8F, 0x5D, 0x56, 0x6F, 0x17, 0xCD, + 0x6D, 0x18, 0x48, 0xCD, 0x75, 0x2F, 0xE1, 0x3C, + 0x65, 0x5C, 0xB1, 0x0F, 0xBA, 0xAF, 0xF7, 0x68, + 0x72, 0xF2, 0xBF, 0x2D, 0xA9, 0x9E, 0x15, 0xDC, + 0x62, 0x40, 0x75, 0xE1, 0xEC, 0x2F, 0x58, 0xA3, + 0xF6, 0x40, 0x72, 0x12, 0x18, 0x38, 0x56, 0x9E + }, + { + 0x9C, 0xEC, 0x6B, 0xBF, 0x62, 0xC4, 0xBC, 0xE4, + 0x13, 0x8A, 0xBA, 0xE1, 0xCB, 0xEC, 0x8D, 0xAD, + 0x31, 0x95, 0x04, 0x44, 0xE9, 0x03, 0x21, 0xB1, + 0x34, 0x71, 0x96, 0x83, 0x4C, 0x11, 0x4B, 0x86, + 0x4A, 0xF3, 0xF3, 0xCC, 0x35, 0x08, 0xF8, 0x37, + 0x51, 0xFF, 0xB4, 0xED, 0xA7, 0xC8, 0x4D, 0x14, + 0x07, 0x34, 0xBB, 0x42, 0x63, 0xC3, 0x62, 0x5C, + 0x00, 0xF0, 0x4F, 0x4C, 0x80, 0x68, 0x98, 0x1B + }, + { + 0xA8, 0xB6, 0x0F, 0xA4, 0xFC, 0x24, 0x42, 0xF6, + 0xF1, 0x51, 0x4A, 0xD7, 0x40, 0x26, 0x26, 0x92, + 0x0C, 0xC7, 0xC2, 0xC9, 0xF7, 0x21, 0x24, 0xB8, + 0xCB, 0xA8, 0xEE, 0x2C, 0xB7, 0xC4, 0x58, 0x6F, + 0x65, 0x8A, 0x44, 0x10, 0xCF, 0xFC, 0xC0, 0xAB, + 0x88, 0x34, 0x39, 0x55, 0xE0, 0x94, 0xC6, 0xAF, + 0x0D, 0x20, 0xD0, 0xC7, 0x14, 0xFB, 0x0A, 0x98, + 0x8F, 0x54, 0x3F, 0x30, 0x0F, 0x58, 0xD3, 0x89 + }, + { + 0x82, 0x71, 0xCC, 0x45, 0xDF, 0xA5, 0xE4, 0x17, + 0x0E, 0x84, 0x7E, 0x86, 0x30, 0xB9, 0x52, 0xCF, + 0x9C, 0x2A, 0xA7, 0x77, 0xD0, 0x6F, 0x26, 0xA7, + 0x58, 0x5B, 0x83, 0x81, 0xF1, 0x88, 0xDA, 0xCC, + 0x73, 0x37, 0x39, 0x1C, 0xFC, 0xC9, 0x4B, 0x05, + 0x3D, 0xC4, 0xEC, 0x29, 0xCC, 0x17, 0xF0, 0x77, + 0x87, 0x04, 0x28, 0xF1, 0xAC, 0x23, 0xFD, 0xDD, + 0xA1, 0x65, 0xEF, 0x5A, 0x3F, 0x15, 0x5F, 0x39 + }, + { + 0xBF, 0x23, 0xC0, 0xC2, 0x5C, 0x80, 0x60, 0xE4, + 0xF6, 0x99, 0x5F, 0x16, 0x23, 0xA3, 0xBE, 0xBE, + 0xCA, 0xA9, 0x6E, 0x30, 0x86, 0x80, 0x00, 0x0A, + 0x8A, 0xA3, 0xCD, 0x56, 0xBB, 0x1A, 0x6D, 0xA0, + 0x99, 0xE1, 0x0D, 0x92, 0x31, 0xB3, 0x7F, 0x45, + 0x19, 0xB2, 0xEF, 0xD2, 0xC2, 0x4D, 0xE7, 0x2F, + 0x31, 0xA5, 0xF1, 0x95, 0x35, 0x24, 0x1B, 0x4A, + 0x59, 0xFA, 0x3C, 0x03, 0xCE, 0xB7, 0x90, 0xE7 + }, + { + 0x87, 0x7F, 0xD6, 0x52, 0xC0, 0x52, 0x81, 0x00, + 0x9C, 0x0A, 0x52, 0x50, 0xE7, 0xA3, 0xA6, 0x71, + 0xF8, 0xB1, 0x8C, 0x10, 0x88, 0x17, 0xFE, 0x4A, + 0x87, 0x4D, 0xE2, 0x2D, 0xA8, 0xE4, 0x5D, 0xB1, + 0x19, 0x58, 0xA6, 0x00, 0xC5, 0xF6, 0x2E, 0x67, + 0xD3, 0x6C, 0xBF, 0x84, 0x47, 0x4C, 0xF2, 0x44, + 0xA9, 0xC2, 0xB0, 0x3A, 0x9F, 0xB9, 0xDC, 0x71, + 0x1C, 0xD1, 0xA2, 0xCA, 0xB6, 0xF3, 0xFA, 0xE0 + }, + { + 0x29, 0xDF, 0x4D, 0x87, 0xEA, 0x44, 0x4B, 0xAF, + 0x5B, 0xCD, 0xF5, 0xF4, 0xE4, 0x15, 0x79, 0xE2, + 0x8A, 0x67, 0xDE, 0x84, 0x14, 0x9F, 0x06, 0xC0, + 0x3F, 0x11, 0x0E, 0xA8, 0x4F, 0x57, 0x2A, 0x9F, + 0x67, 0x6A, 0xDD, 0xD0, 0x4C, 0x48, 0x78, 0xF4, + 0x9C, 0x5C, 0x00, 0xAC, 0xCD, 0xA4, 0x41, 0xB1, + 0xA3, 0x87, 0xCA, 0xCE, 0xB2, 0xE9, 0x93, 0xBB, + 0x7A, 0x10, 0xCD, 0x8C, 0x2D, 0x67, 0x17, 0xE1 + }, + { + 0x71, 0x0D, 0xAC, 0xB1, 0x66, 0x84, 0x46, 0x39, + 0xCD, 0x7B, 0x63, 0x7C, 0x27, 0x42, 0x09, 0x42, + 0x4E, 0x24, 0x49, 0xDC, 0x35, 0xD7, 0x90, 0xBB, + 0xFA, 0x4F, 0x76, 0x17, 0x70, 0x54, 0xA3, 0x6B, + 0x3B, 0x76, 0xFA, 0xC0, 0xCA, 0x6E, 0x61, 0xDF, + 0x1E, 0x68, 0x70, 0x00, 0x67, 0x8A, 0xC0, 0x74, + 0x6D, 0xF7, 0x5D, 0x0A, 0x39, 0x54, 0x89, 0x76, + 0x81, 0xFD, 0x39, 0x3A, 0x15, 0x5A, 0x1B, 0xB4 + }, + { + 0xC1, 0xD5, 0xF9, 0x3B, 0x8D, 0xEA, 0x1F, 0x25, + 0x71, 0xBA, 0xBC, 0xCB, 0xC0, 0x17, 0x64, 0x54, + 0x1A, 0x0C, 0xDA, 0x87, 0xE4, 0x44, 0xD6, 0x73, + 0xC5, 0x09, 0x66, 0xCA, 0x55, 0x9C, 0x33, 0x35, + 0x4B, 0x3A, 0xCB, 0x26, 0xE5, 0xD5, 0x78, 0x1F, + 0xFB, 0x28, 0x84, 0x7A, 0x4B, 0x47, 0x54, 0xD7, + 0x70, 0x08, 0xC6, 0x2A, 0x83, 0x58, 0x35, 0xF5, + 0x00, 0xDE, 0xA7, 0xC3, 0xB5, 0x8B, 0xDA, 0xE2 + }, + { + 0xA4, 0x1E, 0x41, 0x27, 0x1C, 0xDA, 0xB8, 0xAF, + 0x4D, 0x72, 0xB1, 0x04, 0xBF, 0xB2, 0xAD, 0x04, + 0x1A, 0xC4, 0xDF, 0x14, 0x67, 0x7D, 0xA6, 0x71, + 0xD8, 0x56, 0x40, 0xC4, 0xB1, 0x87, 0xF5, 0x0C, + 0x2B, 0x66, 0x51, 0x3C, 0x46, 0x19, 0xFB, 0xD5, + 0xD5, 0xDC, 0x4F, 0xE6, 0x5D, 0xD3, 0x7B, 0x90, + 0x42, 0xE9, 0x84, 0x8D, 0xDA, 0x55, 0x6A, 0x50, + 0x4C, 0xAA, 0x2B, 0x1C, 0x6A, 0xFE, 0x47, 0x30 + }, + { + 0xE7, 0xBC, 0xBA, 0xCD, 0xC3, 0x79, 0xC4, 0x3D, + 0x81, 0xEB, 0xAD, 0xCB, 0x37, 0x78, 0x15, 0x52, + 0xFC, 0x1D, 0x75, 0x3E, 0x8C, 0xF3, 0x10, 0xD9, + 0x68, 0x39, 0x2D, 0x06, 0xC9, 0x1F, 0x1D, 0x64, + 0xCC, 0x9E, 0x90, 0xCE, 0x1D, 0x22, 0xC3, 0x2D, + 0x27, 0x7F, 0xC6, 0xCD, 0xA4, 0x33, 0xA4, 0xD4, + 0x42, 0xC7, 0x62, 0xE9, 0xEA, 0xCF, 0x2C, 0x25, + 0x9F, 0x32, 0xD6, 0x4C, 0xF9, 0xDA, 0x3A, 0x22 + }, + { + 0x51, 0x75, 0x5B, 0x4A, 0xC5, 0x45, 0x6B, 0x13, + 0x21, 0x8A, 0x19, 0xC5, 0xB9, 0x24, 0x2F, 0x57, + 0xC4, 0xA9, 0x81, 0xE4, 0xD4, 0xEC, 0xDC, 0xE0, + 0x9A, 0x31, 0x93, 0x36, 0x2B, 0x80, 0x8A, 0x57, + 0x93, 0x45, 0xD4, 0x88, 0x1C, 0x26, 0x07, 0xA5, + 0x65, 0x34, 0xDD, 0x7F, 0x21, 0x95, 0x6A, 0xFF, + 0x72, 0xC2, 0xF4, 0x17, 0x3A, 0x6E, 0x7B, 0x6C, + 0xC2, 0x21, 0x2B, 0xA0, 0xE3, 0xDA, 0xEE, 0x1F + }, + { + 0xDC, 0xC2, 0xC4, 0xBE, 0xB9, 0xC1, 0xF2, 0x60, + 0x7B, 0x78, 0x6C, 0x20, 0xC6, 0x31, 0x97, 0x23, + 0x47, 0x03, 0x4C, 0x1C, 0xC0, 0x2F, 0xCC, 0x7D, + 0x02, 0xFF, 0x01, 0x09, 0x9C, 0xFE, 0x1C, 0x69, + 0x89, 0x84, 0x0A, 0xC2, 0x13, 0x92, 0x36, 0x29, + 0x11, 0x3A, 0xA8, 0xBA, 0xD7, 0x13, 0xCC, 0xF0, + 0xFE, 0x4C, 0xE1, 0x32, 0x64, 0xFB, 0x32, 0xB8, + 0xB0, 0xFE, 0x37, 0x2D, 0xA3, 0x82, 0x54, 0x4A + }, + { + 0x3D, 0x55, 0x17, 0x6A, 0xCE, 0xA4, 0xA7, 0xE3, + 0xA6, 0x5F, 0xFA, 0x9F, 0xB1, 0x0A, 0x7A, 0x17, + 0x67, 0x19, 0x9C, 0xF0, 0x77, 0xCE, 0xE9, 0xF7, + 0x15, 0x32, 0xD6, 0x7C, 0xD7, 0xC7, 0x3C, 0x9F, + 0x93, 0xCF, 0xC3, 0x7C, 0xCD, 0xCC, 0x1F, 0xDE, + 0xF5, 0x0A, 0xAD, 0x46, 0xA5, 0x04, 0xA6, 0x50, + 0xD2, 0x98, 0xD5, 0x97, 0xA3, 0xA9, 0xFA, 0x95, + 0xC6, 0xC4, 0x0C, 0xB7, 0x1F, 0xA5, 0xE7, 0x25 + }, + { + 0xD0, 0x77, 0x13, 0xC0, 0x05, 0xDE, 0x96, 0xDD, + 0x21, 0xD2, 0xEB, 0x8B, 0xBE, 0xCA, 0x66, 0x74, + 0x6E, 0xA5, 0x1A, 0x31, 0xAE, 0x92, 0x2A, 0x3E, + 0x74, 0x86, 0x48, 0x89, 0x54, 0x0A, 0x48, 0xDB, + 0x27, 0xD7, 0xE4, 0xC9, 0x03, 0x11, 0x63, 0x8B, + 0x22, 0x4B, 0xF0, 0x20, 0x1B, 0x50, 0x18, 0x91, + 0x75, 0x48, 0x48, 0x11, 0x3C, 0x26, 0x61, 0x08, + 0xD0, 0xAD, 0xB1, 0x3D, 0xB7, 0x19, 0x09, 0xC7 + }, + { + 0x58, 0x98, 0x3C, 0x21, 0x43, 0x3D, 0x95, 0x0C, + 0xAA, 0x23, 0xE4, 0xBC, 0x18, 0x54, 0x3B, 0x8E, + 0x60, 0x1C, 0x20, 0x43, 0x18, 0x53, 0x21, 0x52, + 0xDA, 0xF5, 0xE1, 0x59, 0xA0, 0xCD, 0x14, 0x80, + 0x18, 0x3D, 0x29, 0x28, 0x5C, 0x05, 0xF1, 0x29, + 0xCB, 0x0C, 0xC3, 0x16, 0x46, 0x87, 0x92, 0x80, + 0x86, 0xFF, 0xE3, 0x80, 0x15, 0x8D, 0xF1, 0xD3, + 0x94, 0xC6, 0xAC, 0x0D, 0x42, 0x88, 0xBC, 0xA8 + }, + { + 0x81, 0x00, 0xA8, 0xDC, 0x52, 0x8D, 0x2B, 0x68, + 0x2A, 0xB4, 0x25, 0x08, 0x01, 0xBA, 0x33, 0xF0, + 0x2A, 0x3E, 0x94, 0xC5, 0x4D, 0xAC, 0x0A, 0xE1, + 0x48, 0x2A, 0xA2, 0x1F, 0x51, 0xEF, 0x3A, 0x82, + 0xF3, 0x80, 0x7E, 0x6F, 0xAC, 0xB0, 0xAE, 0xB0, + 0x59, 0x47, 0xBF, 0x7A, 0xA2, 0xAD, 0xCB, 0x03, + 0x43, 0x56, 0xF9, 0x0F, 0xA4, 0x56, 0x0E, 0xDE, + 0x02, 0x20, 0x1A, 0x37, 0xE4, 0x11, 0xEC, 0x1A + }, + { + 0x07, 0x02, 0x5F, 0x1B, 0xB6, 0xC7, 0x84, 0xF3, + 0xFE, 0x49, 0xDE, 0x5C, 0x14, 0xB9, 0x36, 0xA5, + 0xAC, 0xAC, 0xAC, 0xAA, 0xB3, 0x3F, 0x6A, 0xC4, + 0xD0, 0xE0, 0x0A, 0xB6, 0xA1, 0x24, 0x83, 0xD6, + 0xBE, 0xC0, 0x0B, 0x4F, 0xE6, 0x7C, 0x7C, 0xA5, + 0xCC, 0x50, 0x8C, 0x2A, 0x53, 0xEF, 0xB5, 0xBF, + 0xA5, 0x39, 0x87, 0x69, 0xD8, 0x43, 0xFF, 0x0D, + 0x9E, 0x8B, 0x14, 0xD3, 0x6A, 0x01, 0xA7, 0x7F + }, + { + 0xBA, 0x6A, 0xEF, 0xD9, 0x72, 0xB6, 0x18, 0x6E, + 0x02, 0x7A, 0x76, 0x27, 0x3A, 0x4A, 0x72, 0x33, + 0x21, 0xA3, 0xF5, 0x80, 0xCF, 0xA8, 0x94, 0xDA, + 0x5A, 0x9C, 0xE8, 0xE7, 0x21, 0xC8, 0x28, 0x55, + 0x2C, 0x64, 0xDA, 0xCE, 0xE3, 0xA7, 0xFD, 0x2D, + 0x74, 0x3B, 0x5C, 0x35, 0xAD, 0x0C, 0x8E, 0xFA, + 0x71, 0xF8, 0xCE, 0x99, 0xBF, 0x96, 0x33, 0x47, + 0x10, 0xE2, 0xC2, 0x34, 0x6E, 0x8F, 0x3C, 0x52 + }, + { + 0xE0, 0x72, 0x1E, 0x02, 0x51, 0x7A, 0xED, 0xFA, + 0x4E, 0x7E, 0x9B, 0xA5, 0x03, 0xE0, 0x25, 0xFD, + 0x46, 0xE7, 0x14, 0x56, 0x6D, 0xC8, 0x89, 0xA8, + 0x4C, 0xBF, 0xE5, 0x6A, 0x55, 0xDF, 0xBE, 0x2F, + 0xC4, 0x93, 0x8A, 0xC4, 0x12, 0x05, 0x88, 0x33, + 0x5D, 0xEA, 0xC8, 0xEF, 0x3F, 0xA2, 0x29, 0xAD, + 0xC9, 0x64, 0x7F, 0x54, 0xAD, 0x2E, 0x34, 0x72, + 0x23, 0x4F, 0x9B, 0x34, 0xEF, 0xC4, 0x65, 0x43 + }, + { + 0xB6, 0x29, 0x26, 0x69, 0xCC, 0xD3, 0x8D, 0x5F, + 0x01, 0xCA, 0xAE, 0x96, 0xBA, 0x27, 0x2C, 0x76, + 0xA8, 0x79, 0xA4, 0x57, 0x43, 0xAF, 0xA0, 0x72, + 0x5D, 0x83, 0xB9, 0xEB, 0xB2, 0x66, 0x65, 0xB7, + 0x31, 0xF1, 0x84, 0x8C, 0x52, 0xF1, 0x19, 0x72, + 0xB6, 0x64, 0x4F, 0x55, 0x4C, 0x06, 0x4F, 0xA9, + 0x07, 0x80, 0xDB, 0xBB, 0xF3, 0xA8, 0x9D, 0x4F, + 0xC3, 0x1F, 0x67, 0xDF, 0x3E, 0x58, 0x57, 0xEF + }, + { + 0x23, 0x19, 0xE3, 0x78, 0x9C, 0x47, 0xE2, 0xDA, + 0xA5, 0xFE, 0x80, 0x7F, 0x61, 0xBE, 0xC2, 0xA1, + 0xA6, 0x53, 0x7F, 0xA0, 0x3F, 0x19, 0xFF, 0x32, + 0xE8, 0x7E, 0xEC, 0xBF, 0xD6, 0x4B, 0x7E, 0x0E, + 0x8C, 0xCF, 0xF4, 0x39, 0xAC, 0x33, 0x3B, 0x04, + 0x0F, 0x19, 0xB0, 0xC4, 0xDD, 0xD1, 0x1A, 0x61, + 0xE2, 0x4A, 0xC1, 0xFE, 0x0F, 0x10, 0xA0, 0x39, + 0x80, 0x6C, 0x5D, 0xCC, 0x0D, 0xA3, 0xD1, 0x15 + }, + { + 0xF5, 0x97, 0x11, 0xD4, 0x4A, 0x03, 0x1D, 0x5F, + 0x97, 0xA9, 0x41, 0x3C, 0x06, 0x5D, 0x1E, 0x61, + 0x4C, 0x41, 0x7E, 0xDE, 0x99, 0x85, 0x90, 0x32, + 0x5F, 0x49, 0xBA, 0xD2, 0xFD, 0x44, 0x4D, 0x3E, + 0x44, 0x18, 0xBE, 0x19, 0xAE, 0xC4, 0xE1, 0x14, + 0x49, 0xAC, 0x1A, 0x57, 0x20, 0x78, 0x98, 0xBC, + 0x57, 0xD7, 0x6A, 0x1B, 0xCF, 0x35, 0x66, 0x29, + 0x2C, 0x20, 0xC6, 0x83, 0xA5, 0xC4, 0x64, 0x8F + }, + { + 0xDF, 0x0A, 0x9D, 0x0C, 0x21, 0x28, 0x43, 0xA6, + 0xA9, 0x34, 0xE3, 0x90, 0x2B, 0x2D, 0xD3, 0x0D, + 0x17, 0xFB, 0xA5, 0xF9, 0x69, 0xD2, 0x03, 0x0B, + 0x12, 0xA5, 0x46, 0xD8, 0xA6, 0xA4, 0x5E, 0x80, + 0xCF, 0x56, 0x35, 0xF0, 0x71, 0xF0, 0x45, 0x2E, + 0x9C, 0x91, 0x92, 0x75, 0xDA, 0x99, 0xBE, 0xD5, + 0x1E, 0xB1, 0x17, 0x3C, 0x1A, 0xF0, 0x51, 0x87, + 0x26, 0xB7, 0x5B, 0x0E, 0xC3, 0xBA, 0xE2, 0xB5 + }, + { + 0xA3, 0xEB, 0x6E, 0x6C, 0x7B, 0xF2, 0xFB, 0x8B, + 0x28, 0xBF, 0xE8, 0xB1, 0x5E, 0x15, 0xBB, 0x50, + 0x0F, 0x78, 0x1E, 0xCC, 0x86, 0xF7, 0x78, 0xC3, + 0xA4, 0xE6, 0x55, 0xFC, 0x58, 0x69, 0xBF, 0x28, + 0x46, 0xA2, 0x45, 0xD4, 0xE3, 0x3B, 0x7B, 0x14, + 0x43, 0x6A, 0x17, 0xE6, 0x3B, 0xE7, 0x9B, 0x36, + 0x65, 0x5C, 0x22, 0x6A, 0x50, 0xFF, 0xBC, 0x71, + 0x24, 0x20, 0x7B, 0x02, 0x02, 0x34, 0x2D, 0xB5 + }, + { + 0x56, 0xD4, 0xCB, 0xCD, 0x07, 0x05, 0x63, 0x42, + 0x6A, 0x01, 0x70, 0x69, 0x42, 0x5C, 0x2C, 0xD2, + 0xAE, 0x54, 0x06, 0x68, 0x28, 0x7A, 0x5F, 0xB9, + 0xDA, 0xC4, 0x32, 0xEB, 0x8A, 0xB1, 0xA3, 0x53, + 0xA3, 0x0F, 0x2F, 0xE1, 0xF4, 0x0D, 0x83, 0x33, + 0x3A, 0xFE, 0x69, 0x6A, 0x26, 0x77, 0x95, 0x40, + 0x8A, 0x92, 0xFE, 0x7D, 0xA0, 0x7A, 0x0C, 0x18, + 0x14, 0xCF, 0x77, 0xF3, 0x6E, 0x10, 0x5E, 0xE8 + }, + { + 0xE5, 0x9B, 0x99, 0x87, 0xD4, 0x28, 0xB3, 0xED, + 0xA3, 0x7D, 0x80, 0xAB, 0xDB, 0x16, 0xCD, 0x2B, + 0x0A, 0xEF, 0x67, 0x4C, 0x2B, 0x1D, 0xDA, 0x44, + 0x32, 0xEA, 0x91, 0xEE, 0x6C, 0x93, 0x5C, 0x68, + 0x4B, 0x48, 0xB4, 0x42, 0x8A, 0x8C, 0xC7, 0x40, + 0xE5, 0x79, 0xA3, 0x0D, 0xEF, 0xF3, 0x5A, 0x80, + 0x30, 0x13, 0x82, 0x0D, 0xD2, 0x3F, 0x14, 0xAE, + 0x1D, 0x84, 0x13, 0xB5, 0xC8, 0x67, 0x2A, 0xEC + }, + { + 0xCD, 0x9F, 0xCC, 0x99, 0xF9, 0x9D, 0x4C, 0xC1, + 0x6D, 0x03, 0x19, 0x00, 0xB2, 0xA7, 0x36, 0xE1, + 0x50, 0x8D, 0xB4, 0xB5, 0x86, 0x81, 0x4E, 0x63, + 0x45, 0x85, 0x7F, 0x35, 0x4A, 0x70, 0xCC, 0xEC, + 0xB1, 0xDF, 0x3B, 0x50, 0xA1, 0x9A, 0xDA, 0xF4, + 0x3C, 0x27, 0x8E, 0xFA, 0x42, 0x3F, 0xF4, 0xBB, + 0x6C, 0x52, 0x3E, 0xC7, 0xFD, 0x78, 0x59, 0xB9, + 0x7B, 0x16, 0x8A, 0x7E, 0xBF, 0xF8, 0x46, 0x7C + }, + { + 0x06, 0x02, 0x18, 0x5D, 0x8C, 0x3A, 0x78, 0x73, + 0x8B, 0x99, 0x16, 0x4B, 0x8B, 0xC6, 0xFF, 0xB2, + 0x1C, 0x7D, 0xEB, 0xEB, 0xBF, 0x80, 0x63, 0x72, + 0xE0, 0xDA, 0x44, 0xD1, 0x21, 0x54, 0x55, 0x97, + 0xB9, 0xC6, 0x62, 0xA2, 0x55, 0xDC, 0x31, 0x54, + 0x2C, 0xF9, 0x95, 0xEC, 0xBE, 0x6A, 0x50, 0xFB, + 0x5E, 0x6E, 0x0E, 0xE4, 0xEF, 0x24, 0x0F, 0xE5, + 0x57, 0xED, 0xED, 0x11, 0x88, 0x08, 0x7E, 0x86 + }, + { + 0xC0, 0x8A, 0xFA, 0x5B, 0x92, 0x7B, 0xF0, 0x80, + 0x97, 0xAF, 0xC5, 0xFF, 0xF9, 0xCA, 0x4E, 0x78, + 0x00, 0x12, 0x5C, 0x1F, 0x52, 0xF2, 0xAF, 0x35, + 0x53, 0xFA, 0x2B, 0x89, 0xE1, 0xE3, 0x01, 0x5C, + 0x4F, 0x87, 0xD5, 0xE0, 0xA4, 0x89, 0x56, 0xAD, + 0x31, 0x45, 0x0B, 0x08, 0x3D, 0xAD, 0x14, 0x7F, + 0xFB, 0x5E, 0xC0, 0x34, 0x34, 0xA2, 0x68, 0x30, + 0xCF, 0x37, 0xD1, 0x03, 0xAB, 0x50, 0xC5, 0xDA + }, + { + 0x36, 0xF1, 0xE1, 0xC1, 0x1D, 0x6E, 0xF6, 0xBC, + 0x3B, 0x53, 0x6D, 0x50, 0x5D, 0x54, 0x4A, 0x87, + 0x15, 0x22, 0xC5, 0xC2, 0xA2, 0x53, 0x06, 0x7E, + 0xC9, 0x93, 0x3B, 0x6E, 0xC2, 0x54, 0x64, 0xDA, + 0xF9, 0x85, 0x52, 0x5F, 0x5B, 0x95, 0x60, 0xA1, + 0x6D, 0x89, 0x02, 0x59, 0xAC, 0x1B, 0xB5, 0xCC, + 0x67, 0xC0, 0xC4, 0x69, 0xCD, 0xE1, 0x33, 0xDE, + 0xF0, 0x00, 0xEA, 0x1D, 0x68, 0x6F, 0x4F, 0x5D + }, + { + 0xBF, 0x2A, 0xB2, 0xE2, 0x47, 0x0F, 0x54, 0x38, + 0xC3, 0xB6, 0x89, 0xE6, 0x6E, 0x76, 0x86, 0xFF, + 0xFA, 0x0C, 0xB1, 0xE1, 0x79, 0x8A, 0xD3, 0xA8, + 0x6F, 0xF9, 0x90, 0x75, 0xBF, 0x61, 0x38, 0xE3, + 0x3D, 0x9C, 0x0C, 0xE5, 0x9A, 0xFB, 0x24, 0xAC, + 0x67, 0xA0, 0x2A, 0xF3, 0x44, 0x28, 0x19, 0x1A, + 0x9A, 0x0A, 0x60, 0x41, 0xC0, 0x74, 0x71, 0xB7, + 0xC3, 0xB1, 0xA7, 0x52, 0xD6, 0xFC, 0x0B, 0x8B + }, + { + 0xD4, 0x00, 0x60, 0x1F, 0x97, 0x28, 0xCC, 0xC4, + 0xC9, 0x23, 0x42, 0xD9, 0x78, 0x7D, 0x8D, 0x28, + 0xAB, 0x32, 0x3A, 0xF3, 0x75, 0xCA, 0x56, 0x24, + 0xB4, 0xBB, 0x91, 0xD1, 0x72, 0x71, 0xFB, 0xAE, + 0x86, 0x2E, 0x41, 0x3B, 0xE7, 0x3F, 0x1F, 0x68, + 0xE6, 0x15, 0xB8, 0xC5, 0xC3, 0x91, 0xBE, 0x0D, + 0xBD, 0x91, 0x44, 0x74, 0x6E, 0xB3, 0x39, 0xAD, + 0x54, 0x15, 0x47, 0xBA, 0x9C, 0x46, 0x8A, 0x17 + }, + { + 0x79, 0xFE, 0x2F, 0xE1, 0x57, 0xEB, 0x85, 0xA0, + 0x38, 0xAB, 0xB8, 0xEB, 0xBC, 0x64, 0x77, 0x31, + 0xD2, 0xC8, 0x3F, 0x51, 0xB0, 0xAC, 0x6E, 0xE1, + 0x4A, 0xA2, 0x84, 0xCB, 0x6A, 0x35, 0x49, 0xA4, + 0xDC, 0xCE, 0xB3, 0x00, 0x74, 0x0A, 0x82, 0x5F, + 0x52, 0xF5, 0xFB, 0x30, 0xB0, 0x3B, 0x8C, 0x4D, + 0x8B, 0x0F, 0x4A, 0xA6, 0x7A, 0x63, 0xF4, 0xA9, + 0x4E, 0x33, 0x03, 0xC4, 0xED, 0xA4, 0xC0, 0x2B + }, + { + 0x75, 0x35, 0x13, 0x13, 0xB5, 0x2A, 0x85, 0x29, + 0x29, 0x8D, 0x8C, 0x18, 0x6B, 0x17, 0x68, 0x66, + 0x6D, 0xCC, 0xA8, 0x59, 0x53, 0x17, 0xD7, 0xA4, + 0x81, 0x6E, 0xB8, 0x8C, 0x06, 0x20, 0x20, 0xC0, + 0xC8, 0xEF, 0xC5, 0x54, 0xBB, 0x34, 0x1B, 0x64, + 0x68, 0x8D, 0xB5, 0xCC, 0xAF, 0xC3, 0x5F, 0x3C, + 0x3C, 0xD0, 0x9D, 0x65, 0x64, 0xB3, 0x6D, 0x7B, + 0x04, 0xA2, 0x48, 0xE1, 0x46, 0x98, 0x0D, 0x4B + }, + { + 0xE3, 0x12, 0x8B, 0x1D, 0x31, 0x1D, 0x02, 0x17, + 0x9D, 0x7F, 0x25, 0xF9, 0x7A, 0x5A, 0x8B, 0xEE, + 0x2C, 0xC8, 0xC8, 0x63, 0x03, 0x64, 0x4F, 0xCD, + 0x66, 0x4E, 0x15, 0x7D, 0x1F, 0xEF, 0x00, 0xF2, + 0x3E, 0x46, 0xF9, 0xA5, 0xE8, 0xE5, 0xC8, 0x90, + 0xCE, 0x56, 0x5B, 0xB6, 0xAB, 0xD4, 0x30, 0x2C, + 0xE0, 0x64, 0x69, 0xD5, 0x2A, 0x5B, 0xD5, 0x3E, + 0x1C, 0x5A, 0x54, 0xD0, 0x46, 0x49, 0xDC, 0x03 + }, + { + 0xC2, 0x38, 0x2A, 0x72, 0xD2, 0xD3, 0xAC, 0xE9, + 0xD5, 0x93, 0x3D, 0x00, 0xB6, 0x08, 0x27, 0xED, + 0x38, 0x0C, 0xDA, 0x08, 0xD0, 0xBA, 0x5F, 0x6D, + 0xD4, 0x1E, 0x29, 0xEE, 0x6D, 0xBE, 0x8E, 0xCB, + 0x92, 0x35, 0xF0, 0x6B, 0xE9, 0x5D, 0x83, 0xB6, + 0x81, 0x6A, 0x2F, 0xB7, 0xA5, 0xAD, 0x47, 0x03, + 0x5E, 0x8A, 0x4B, 0x69, 0xA4, 0x88, 0x4B, 0x99, + 0xE4, 0xBE, 0xCE, 0x58, 0xCA, 0xB2, 0x5D, 0x44 + }, + { + 0x6B, 0x1C, 0x69, 0x46, 0x0B, 0xBD, 0x50, 0xAC, + 0x2E, 0xD6, 0xF3, 0x2E, 0x6E, 0x88, 0x7C, 0xFE, + 0xD4, 0x07, 0xD4, 0x7D, 0xCF, 0x0A, 0xAA, 0x60, + 0x38, 0x7F, 0xE3, 0x20, 0xD7, 0x80, 0xBD, 0x03, + 0xEA, 0xB6, 0xD7, 0xBA, 0xEB, 0x2A, 0x07, 0xD1, + 0x0C, 0xD5, 0x52, 0xA3, 0x00, 0x34, 0x13, 0x54, + 0xEA, 0x9A, 0x5F, 0x03, 0x18, 0x3A, 0x62, 0x3F, + 0x92, 0xA2, 0xD4, 0xD9, 0xF0, 0x09, 0x26, 0xAF + }, + { + 0x6C, 0xDA, 0x20, 0x6C, 0x80, 0xCD, 0xC9, 0xC4, + 0x4B, 0xA9, 0x90, 0xE0, 0x32, 0x8C, 0x31, 0x4F, + 0x81, 0x9B, 0x14, 0x2D, 0x00, 0x63, 0x04, 0x04, + 0xC4, 0x8C, 0x05, 0xDC, 0x76, 0xD1, 0xB0, 0x0C, + 0xE4, 0xD7, 0x2F, 0xC6, 0xA4, 0x8E, 0x14, 0x69, + 0xDD, 0xEF, 0x60, 0x94, 0x12, 0xC3, 0x64, 0x82, + 0x08, 0x54, 0x21, 0x4B, 0x48, 0x69, 0xAF, 0x09, + 0x0F, 0x00, 0xD3, 0xC1, 0xBA, 0x44, 0x3E, 0x1B + }, + { + 0x7F, 0xFC, 0x8C, 0x26, 0xFB, 0xD6, 0xA0, 0xF7, + 0xA6, 0x09, 0xE6, 0xE1, 0x93, 0x9F, 0x6A, 0x9E, + 0xDF, 0x1B, 0x0B, 0x06, 0x66, 0x41, 0xFB, 0x76, + 0xC4, 0xF9, 0x60, 0x2E, 0xD7, 0x48, 0xD1, 0x16, + 0x02, 0x49, 0x6B, 0x35, 0x35, 0x5B, 0x1A, 0xA2, + 0x55, 0x85, 0x0A, 0x50, 0x9D, 0x2F, 0x8E, 0xE1, + 0x8C, 0x8F, 0x3E, 0x1D, 0x7D, 0xCB, 0xC3, 0x7A, + 0x13, 0x65, 0x98, 0xF5, 0x6A, 0x59, 0xED, 0x17 + }, + { + 0x70, 0xDE, 0x1F, 0x08, 0xDD, 0x4E, 0x09, 0xD5, + 0xFC, 0x15, 0x1F, 0x17, 0xFC, 0x99, 0x1A, 0x23, + 0xAB, 0xFC, 0x05, 0x10, 0x42, 0x90, 0xD5, 0x04, + 0x68, 0x88, 0x2E, 0xFA, 0xF5, 0x82, 0xB6, 0xEC, + 0x2F, 0x14, 0xF5, 0x77, 0xC0, 0xD6, 0x8C, 0x3A, + 0xD0, 0x66, 0x26, 0x91, 0x6E, 0x3C, 0x86, 0xE6, + 0xDA, 0xAB, 0x6C, 0x53, 0xE5, 0x16, 0x3E, 0x82, + 0xB6, 0xBD, 0x0C, 0xE4, 0x9F, 0xC0, 0xD8, 0xDF + }, + { + 0x4F, 0x81, 0x93, 0x57, 0x56, 0xED, 0x35, 0xEE, + 0x20, 0x58, 0xEE, 0x0C, 0x6A, 0x61, 0x10, 0xD6, + 0xFA, 0xC5, 0xCB, 0x6A, 0x4F, 0x46, 0xAA, 0x94, + 0x11, 0x60, 0x3F, 0x99, 0x96, 0x58, 0x23, 0xB6, + 0xDA, 0x48, 0x38, 0x27, 0x6C, 0x5C, 0x06, 0xBC, + 0x78, 0x80, 0xE3, 0x76, 0xD9, 0x27, 0x58, 0x36, + 0x9E, 0xE7, 0x30, 0x5B, 0xCE, 0xC8, 0xD3, 0xCF, + 0xD2, 0x8C, 0xCA, 0xBB, 0x7B, 0x4F, 0x05, 0x79 + }, + { + 0xAB, 0xCB, 0x61, 0xCB, 0x36, 0x83, 0xD1, 0x8F, + 0x27, 0xAD, 0x52, 0x79, 0x08, 0xED, 0x2D, 0x32, + 0xA0, 0x42, 0x6C, 0xB7, 0xBB, 0x4B, 0xF1, 0x80, + 0x61, 0x90, 0x3A, 0x7D, 0xC4, 0x2E, 0x7E, 0x76, + 0xF9, 0x82, 0x38, 0x23, 0x04, 0xD1, 0x8A, 0xF8, + 0xC8, 0x0D, 0x91, 0xDD, 0x58, 0xDD, 0x47, 0xAF, + 0x76, 0xF8, 0xE2, 0xC3, 0x6E, 0x28, 0xAF, 0x24, + 0x76, 0xB4, 0xBC, 0xCF, 0x82, 0xE8, 0x9F, 0xDF + }, + { + 0x02, 0xD2, 0x61, 0xAD, 0x56, 0xA5, 0x26, 0x33, + 0x1B, 0x64, 0x3D, 0xD2, 0x18, 0x6D, 0xE9, 0xA8, + 0x2E, 0x72, 0xA5, 0x82, 0x23, 0xCD, 0x1E, 0x72, + 0x36, 0x86, 0xC5, 0x3D, 0x86, 0x9B, 0x83, 0xB9, + 0x46, 0x32, 0xB7, 0xB6, 0x47, 0xAB, 0x2A, 0xFC, + 0x0D, 0x52, 0x2E, 0x29, 0xDA, 0x3A, 0x56, 0x15, + 0xB7, 0x41, 0xD8, 0x28, 0x52, 0xE0, 0xDF, 0x41, + 0xB6, 0x60, 0x07, 0xDB, 0xCB, 0xA9, 0x05, 0x43 + }, + { + 0xC5, 0x83, 0x27, 0x41, 0xFA, 0x30, 0xC5, 0x43, + 0x68, 0x23, 0x01, 0x53, 0x83, 0xD2, 0x97, 0xFF, + 0x4C, 0x4A, 0x5D, 0x72, 0x76, 0xC3, 0xF9, 0x02, + 0x12, 0x20, 0x66, 0xE0, 0x4B, 0xE5, 0x43, 0x1B, + 0x1A, 0x85, 0xFA, 0xF7, 0x3B, 0x91, 0x84, 0x34, + 0xF9, 0x30, 0x09, 0x63, 0xD1, 0xDE, 0xA9, 0xE8, + 0xAC, 0x39, 0x24, 0xEF, 0x49, 0x02, 0x26, 0xED, + 0xEE, 0xA5, 0xF7, 0x43, 0xE4, 0x10, 0x66, 0x9F + }, + { + 0xCF, 0xAE, 0xAB, 0x26, 0x8C, 0xD0, 0x75, 0xA5, + 0xA6, 0xAE, 0xD5, 0x15, 0x02, 0x3A, 0x03, 0x2D, + 0x54, 0xF2, 0xF2, 0xFF, 0x73, 0x3C, 0xE0, 0xCB, + 0xC7, 0x8D, 0xB5, 0x1D, 0xB4, 0x50, 0x4D, 0x67, + 0x59, 0x23, 0xF8, 0x27, 0x46, 0xD6, 0x59, 0x46, + 0x06, 0xAD, 0x5D, 0x67, 0x73, 0x4B, 0x11, 0xA6, + 0x7C, 0xC6, 0xA4, 0x68, 0xC2, 0x03, 0x2E, 0x43, + 0xCA, 0x1A, 0x94, 0xC6, 0x27, 0x3A, 0x98, 0x5E + }, + { + 0x86, 0x08, 0x50, 0xF9, 0x2E, 0xB2, 0x68, 0x27, + 0x2B, 0x67, 0xD1, 0x33, 0x60, 0x9B, 0xD6, 0x4E, + 0x34, 0xF6, 0x1B, 0xF0, 0x3F, 0x4C, 0x17, 0x38, + 0x64, 0x5C, 0x17, 0xFE, 0xC8, 0x18, 0x46, 0x5D, + 0x7E, 0xCD, 0x2B, 0xE2, 0x90, 0x76, 0x41, 0x13, + 0x00, 0x25, 0xFD, 0xA7, 0x94, 0x70, 0xAB, 0x73, + 0x16, 0x46, 0xE7, 0xF6, 0x94, 0x40, 0xE8, 0x36, + 0x7E, 0xA7, 0x6A, 0xC4, 0xCE, 0xE8, 0xA1, 0xDF + }, + { + 0x84, 0xB1, 0x54, 0xED, 0x29, 0xBB, 0xED, 0xEF, + 0xA6, 0x48, 0x28, 0x68, 0x39, 0x04, 0x6F, 0x4B, + 0x5A, 0xA3, 0x44, 0x30, 0xE2, 0xD6, 0x7F, 0x74, + 0x96, 0xE4, 0xC3, 0x9F, 0x2C, 0x7E, 0xA7, 0x89, + 0x95, 0xF6, 0x9E, 0x12, 0x92, 0x20, 0x00, 0x16, + 0xF1, 0x6A, 0xC3, 0xB3, 0x77, 0x00, 0xE6, 0xC7, + 0xE7, 0x86, 0x1A, 0xFC, 0x39, 0x6B, 0x64, 0xA5, + 0x9A, 0x1D, 0xBF, 0x47, 0xA5, 0x5C, 0x4B, 0xBC + }, + { + 0xAE, 0xEE, 0xC2, 0x60, 0xA5, 0xD8, 0xEF, 0xF5, + 0xCC, 0xAB, 0x8B, 0x95, 0xDA, 0x43, 0x5A, 0x63, + 0xED, 0x7A, 0x21, 0xEA, 0x7F, 0xC7, 0x55, 0x94, + 0x13, 0xFD, 0x61, 0x7E, 0x33, 0x60, 0x9F, 0x8C, + 0x29, 0x0E, 0x64, 0xBB, 0xAC, 0xC5, 0x28, 0xF6, + 0xC0, 0x80, 0x26, 0x22, 0x88, 0xB0, 0xF0, 0xA3, + 0x21, 0x9B, 0xE2, 0x23, 0xC9, 0x91, 0xBE, 0xE9, + 0x2E, 0x72, 0x34, 0x95, 0x93, 0xE6, 0x76, 0x38 + }, + { + 0x8A, 0xD7, 0x8A, 0x9F, 0x26, 0x60, 0x1D, 0x12, + 0x7E, 0x8D, 0x2F, 0x2F, 0x97, 0x6E, 0x63, 0xD1, + 0x9A, 0x05, 0x4A, 0x17, 0xDC, 0xF5, 0x9E, 0x0F, + 0x01, 0x3A, 0xB5, 0x4A, 0x68, 0x87, 0xBB, 0xDF, + 0xFD, 0xE7, 0xAA, 0xAE, 0x11, 0x7E, 0x0F, 0xBF, + 0x32, 0x71, 0x01, 0x65, 0x95, 0xB9, 0xD9, 0xC7, + 0x12, 0xC0, 0x1B, 0x2C, 0x53, 0xE9, 0x65, 0x5A, + 0x38, 0x2B, 0xC4, 0x52, 0x2E, 0x61, 0x66, 0x45 + }, + { + 0x89, 0x34, 0x15, 0x9D, 0xAD, 0xE1, 0xAC, 0x74, + 0x14, 0x7D, 0xFA, 0x28, 0x2C, 0x75, 0x95, 0x4F, + 0xCE, 0xF4, 0x43, 0xEF, 0x25, 0xF8, 0x0D, 0xFE, + 0x9F, 0xB6, 0xEA, 0x63, 0x3B, 0x85, 0x45, 0x11, + 0x1D, 0x08, 0xB3, 0x4E, 0xF4, 0x3F, 0xFF, 0x17, + 0x02, 0x6C, 0x79, 0x64, 0xF5, 0xDE, 0xAC, 0x6D, + 0x2B, 0x3C, 0x29, 0xDA, 0xCF, 0x27, 0x47, 0xF0, + 0x22, 0xDF, 0x59, 0x67, 0xDF, 0xDC, 0x1A, 0x0A + }, + { + 0xCD, 0x36, 0xDD, 0x0B, 0x24, 0x06, 0x14, 0xCF, + 0x2F, 0xA2, 0xB9, 0xE9, 0x59, 0x67, 0x9D, 0xCD, + 0xD7, 0x2E, 0xC0, 0xCD, 0x58, 0xA4, 0x3D, 0xA3, + 0x79, 0x0A, 0x92, 0xF6, 0xCD, 0xEB, 0x9E, 0x1E, + 0x79, 0x5E, 0x47, 0x8A, 0x0A, 0x47, 0xD3, 0x71, + 0x10, 0x0D, 0x34, 0x0C, 0x5C, 0xED, 0xCD, 0xBB, + 0xC9, 0xE6, 0x8B, 0x3F, 0x46, 0x08, 0x18, 0xE5, + 0xBD, 0xFF, 0x7B, 0x4C, 0xDA, 0x4C, 0x27, 0x44 + }, + { + 0x00, 0xDF, 0x4E, 0x09, 0x9B, 0x80, 0x71, 0x37, + 0xA8, 0x59, 0x90, 0xF4, 0x9D, 0x3A, 0x94, 0x31, + 0x5E, 0x5A, 0x5F, 0x7F, 0x7A, 0x60, 0x76, 0xB3, + 0x03, 0xE9, 0x6B, 0x05, 0x6F, 0xB9, 0x38, 0x00, + 0x11, 0x1F, 0x47, 0x96, 0x28, 0xE2, 0xF8, 0xDB, + 0x59, 0xAE, 0xB6, 0xAC, 0x70, 0xC3, 0xB6, 0x1F, + 0x51, 0xF9, 0xB4, 0x6E, 0x80, 0xFF, 0xDE, 0xAE, + 0x25, 0xEB, 0xDD, 0xB4, 0xAF, 0x6C, 0xB4, 0xEE + }, + { + 0x2B, 0x9C, 0x95, 0x5E, 0x6C, 0xAE, 0xD4, 0xB7, + 0xC9, 0xE2, 0x46, 0xB8, 0x6F, 0x9A, 0x17, 0x26, + 0xE8, 0x10, 0xC5, 0x9D, 0x12, 0x6C, 0xEE, 0x66, + 0xED, 0x71, 0xBF, 0x01, 0x5B, 0x83, 0x55, 0x8A, + 0x4B, 0x6D, 0x84, 0xD1, 0x8D, 0xC3, 0xFF, 0x46, + 0x20, 0xC2, 0xFF, 0xB7, 0x22, 0x35, 0x9F, 0xDE, + 0xF8, 0x5B, 0xA0, 0xD4, 0xE2, 0xD2, 0x2E, 0xCB, + 0xE0, 0xED, 0x78, 0x4F, 0x99, 0xAF, 0xE5, 0x87 + }, + { + 0x18, 0x1D, 0xF0, 0xA2, 0x61, 0xA2, 0xF7, 0xD2, + 0x9E, 0xA5, 0xA1, 0x57, 0x72, 0x71, 0x51, 0x05, + 0xD4, 0x50, 0xA4, 0xB6, 0xC2, 0x36, 0xF6, 0x99, + 0xF4, 0x62, 0xD6, 0x0C, 0xA7, 0x64, 0x87, 0xFE, + 0xED, 0xFC, 0x9F, 0x5E, 0xB9, 0x2D, 0xF8, 0x38, + 0xE8, 0xFB, 0x5D, 0xC3, 0x69, 0x4E, 0x84, 0xC5, + 0xE0, 0xF4, 0xA1, 0x0B, 0x76, 0x1F, 0x50, 0x67, + 0x62, 0xBE, 0x05, 0x2C, 0x74, 0x5A, 0x6E, 0xE8 + }, + { + 0x21, 0xFB, 0x20, 0x34, 0x58, 0xBF, 0x3A, 0x7E, + 0x9A, 0x80, 0x43, 0x9F, 0x9A, 0x90, 0x28, 0x99, + 0xCD, 0x5D, 0xE0, 0x13, 0x9D, 0xFD, 0x56, 0xF7, + 0x11, 0x0C, 0x9D, 0xEC, 0x84, 0x37, 0xB2, 0x6B, + 0xDA, 0x63, 0xDE, 0x2F, 0x56, 0x59, 0x26, 0xD8, + 0x5E, 0xDB, 0x1D, 0x6C, 0x68, 0x25, 0x66, 0x97, + 0x43, 0xDD, 0x99, 0x92, 0x65, 0x3D, 0x13, 0x97, + 0x95, 0x44, 0xD5, 0xDC, 0x82, 0x28, 0xBF, 0xAA + }, + { + 0xEF, 0x02, 0x1F, 0x29, 0xC5, 0xFF, 0xB8, 0x30, + 0xE6, 0x4B, 0x9A, 0xA9, 0x05, 0x8D, 0xD6, 0x60, + 0xFD, 0x2F, 0xCB, 0x81, 0xC4, 0x97, 0xA7, 0xE6, + 0x98, 0xBC, 0xFB, 0xF5, 0x9D, 0xE5, 0xAD, 0x4A, + 0x86, 0xFF, 0x93, 0xC1, 0x0A, 0x4B, 0x9D, 0x1A, + 0xE5, 0x77, 0x47, 0x25, 0xF9, 0x07, 0x2D, 0xCD, + 0xE9, 0xE1, 0xF1, 0x99, 0xBA, 0xB9, 0x1F, 0x8B, + 0xFF, 0x92, 0x18, 0x64, 0xAA, 0x50, 0x2E, 0xEE + }, + { + 0xB3, 0xCF, 0xDA, 0x40, 0x52, 0x6B, 0x7F, 0x1D, + 0x37, 0x56, 0x9B, 0xDF, 0xCD, 0xF9, 0x11, 0xE5, + 0xA6, 0xEF, 0xE6, 0xB2, 0xEC, 0x90, 0xA0, 0x45, + 0x4C, 0x47, 0xB2, 0xC0, 0x46, 0xBF, 0x13, 0x0F, + 0xC3, 0xB3, 0x52, 0xB3, 0x4D, 0xF4, 0x81, 0x3D, + 0x48, 0xD3, 0x3A, 0xB8, 0xE2, 0x69, 0xB6, 0x9B, + 0x07, 0x56, 0x76, 0xCB, 0x6D, 0x00, 0xA8, 0xDC, + 0xF9, 0xE1, 0xF9, 0x67, 0xEC, 0x19, 0x1B, 0x2C + }, + { + 0xB4, 0xC6, 0xC3, 0xB2, 0x67, 0x07, 0x1E, 0xEF, + 0xB9, 0xC8, 0xC7, 0x2E, 0x0E, 0x2B, 0x94, 0x12, + 0x93, 0x64, 0x1F, 0x86, 0x73, 0xCB, 0x70, 0xC1, + 0xCC, 0x26, 0xAD, 0x1E, 0x73, 0xCF, 0x14, 0x17, + 0x55, 0x86, 0x0A, 0xD1, 0x9B, 0x34, 0xC2, 0xF3, + 0x4E, 0xD3, 0x5B, 0xB5, 0x2E, 0xC4, 0x50, 0x7C, + 0xC1, 0xFE, 0x59, 0x04, 0x77, 0x43, 0xA5, 0xF0, + 0xC6, 0xFE, 0xBD, 0xE6, 0x25, 0xE2, 0x60, 0x91 + }, + { + 0x57, 0xA3, 0x4F, 0x2B, 0xCC, 0xA6, 0x0D, 0x4B, + 0x85, 0x10, 0x3B, 0x83, 0x0C, 0x9D, 0x79, 0x52, + 0xA4, 0x16, 0xBE, 0x52, 0x63, 0xAE, 0x42, 0x9C, + 0x9E, 0x5E, 0x53, 0xFE, 0x85, 0x90, 0xA8, 0xF7, + 0x8E, 0xC6, 0x5A, 0x51, 0x10, 0x9E, 0xA8, 0x5D, + 0xCD, 0xF7, 0xB6, 0x22, 0x3F, 0x9F, 0x2B, 0x34, + 0x05, 0x39, 0xFA, 0xD8, 0x19, 0x23, 0xDB, 0xF8, + 0xED, 0xAB, 0xF9, 0x51, 0x29, 0xE4, 0xDF, 0xF6 + }, + { + 0x9C, 0xF4, 0x66, 0x62, 0xFC, 0xD6, 0x1A, 0x23, + 0x22, 0x77, 0xB6, 0x85, 0x66, 0x3B, 0x8B, 0x5D, + 0xA8, 0x32, 0xDF, 0xD9, 0xA3, 0xB8, 0xCC, 0xFE, + 0xEC, 0x99, 0x3E, 0xC6, 0xAC, 0x41, 0x5A, 0xD0, + 0x7E, 0x04, 0x8A, 0xDF, 0xE4, 0x14, 0xDF, 0x27, + 0x27, 0x70, 0xDB, 0xA8, 0x67, 0xDA, 0x5C, 0x12, + 0x24, 0xC6, 0xFD, 0x0A, 0xA0, 0xC2, 0x18, 0x7D, + 0x42, 0x6A, 0xC6, 0x47, 0xE9, 0x88, 0x73, 0x61 + }, + { + 0x5C, 0xE1, 0x04, 0x2A, 0xB4, 0xD5, 0x42, 0xC2, + 0xF9, 0xEE, 0x9D, 0x17, 0x26, 0x2A, 0xF8, 0x16, + 0x40, 0x98, 0x93, 0x5B, 0xEF, 0x17, 0x3D, 0x0E, + 0x18, 0x48, 0x9B, 0x04, 0x84, 0x17, 0x46, 0xCD, + 0x2F, 0x2D, 0xF8, 0x66, 0xBD, 0x7D, 0xA6, 0xE5, + 0xEF, 0x90, 0x24, 0xC6, 0x48, 0x02, 0x3E, 0xC7, + 0x23, 0xAB, 0x9C, 0x62, 0xFD, 0x80, 0x28, 0x57, + 0x39, 0xD8, 0x4F, 0x15, 0xD2, 0xAB, 0x51, 0x5A + }, + { + 0x84, 0x88, 0x39, 0x6B, 0xD4, 0xA8, 0x72, 0x9B, + 0x7A, 0x47, 0x31, 0x78, 0xF2, 0x32, 0xDA, 0xDF, + 0x3F, 0x0F, 0x8E, 0x22, 0x67, 0x8B, 0xA5, 0xA4, + 0x3E, 0x04, 0x1E, 0x72, 0xDA, 0x1E, 0x2C, 0xF8, + 0x21, 0x94, 0xC3, 0x07, 0x20, 0x7A, 0x54, 0xCB, + 0x81, 0x56, 0x29, 0x33, 0x39, 0xEA, 0xEC, 0x69, + 0x3F, 0xF6, 0x6B, 0xFC, 0xD5, 0xEF, 0xC6, 0x5E, + 0x95, 0xE4, 0xEC, 0xAF, 0x54, 0x53, 0x0A, 0xBD + }, + { + 0xF5, 0x98, 0xDA, 0x90, 0x1C, 0x38, 0x35, 0xBC, + 0xA5, 0x60, 0x77, 0x90, 0x37, 0xDF, 0xDE, 0x9F, + 0x0C, 0x51, 0xDC, 0x61, 0xC0, 0xB7, 0x60, 0xFC, + 0x15, 0x22, 0xD7, 0xB4, 0x70, 0xEE, 0x63, 0xF5, + 0xBD, 0xC6, 0x49, 0x84, 0x76, 0xE8, 0x60, 0x49, + 0xAD, 0x86, 0xE4, 0xE2, 0x1A, 0xF2, 0x85, 0x4A, + 0x98, 0x4C, 0xC9, 0x05, 0x42, 0x7D, 0x2F, 0x17, + 0xF6, 0x6B, 0x1F, 0x41, 0xC3, 0xDA, 0x6F, 0x61 + }, + { + 0x5F, 0x93, 0x26, 0x97, 0x98, 0xCF, 0x02, 0x13, + 0x21, 0x07, 0x33, 0x76, 0x60, 0xA8, 0xD7, 0xA1, + 0x77, 0x35, 0x4C, 0x02, 0x12, 0xEB, 0x93, 0xE5, + 0x55, 0xE7, 0xC3, 0x7A, 0x08, 0xAE, 0xF3, 0xD8, + 0xDC, 0xE0, 0x12, 0x17, 0x01, 0x1C, 0xD9, 0x65, + 0xC0, 0x4D, 0xD2, 0xC1, 0x05, 0xF2, 0xE2, 0xB6, + 0xCA, 0xE5, 0xE4, 0xE6, 0xBC, 0xAF, 0x09, 0xDF, + 0xBE, 0xE3, 0xE0, 0xA6, 0xA6, 0x35, 0x7C, 0x37 + }, + { + 0x0E, 0xCF, 0x58, 0x1D, 0x47, 0xBA, 0xC9, 0x23, + 0x09, 0x86, 0xFA, 0xAB, 0xD7, 0x0C, 0x2F, 0x5B, + 0x80, 0xE9, 0x10, 0x66, 0xF0, 0xEC, 0x55, 0xA8, + 0x42, 0x93, 0x78, 0x82, 0x28, 0x6D, 0x2C, 0xA0, + 0x07, 0xBB, 0x4E, 0x97, 0x3B, 0x0B, 0x09, 0x1D, + 0x52, 0x16, 0x7F, 0xF7, 0xC4, 0x00, 0x9C, 0x7A, + 0xB4, 0xAD, 0x38, 0xFF, 0xF1, 0xDC, 0xEA, 0xCD, + 0xB7, 0xBE, 0x81, 0xEF, 0x4A, 0x45, 0x29, 0x52 + }, + { + 0x5A, 0xEC, 0xA8, 0xAB, 0xE1, 0x52, 0x85, 0x82, + 0xB2, 0xA3, 0x07, 0xB4, 0x00, 0x95, 0x85, 0x49, + 0x8A, 0x3D, 0x46, 0x7C, 0xA6, 0x10, 0x1C, 0xB0, + 0xC5, 0x12, 0x6F, 0x99, 0x76, 0x05, 0x6E, 0x9F, + 0xFC, 0x12, 0x3C, 0xC2, 0x0C, 0x30, 0x2B, 0x2A, + 0x73, 0x7F, 0x49, 0x2C, 0x75, 0xD2, 0x1F, 0x01, + 0x51, 0x2C, 0x90, 0xCA, 0x05, 0x41, 0xDF, 0xA5, + 0x6E, 0x95, 0x0A, 0x32, 0x1D, 0xCB, 0x28, 0xD8 + }, + { + 0x73, 0x2F, 0xBF, 0x8F, 0x1C, 0xB2, 0xB8, 0x32, + 0x92, 0x63, 0xED, 0xE2, 0x78, 0x58, 0xFE, 0x46, + 0xF8, 0xD3, 0x35, 0x4D, 0x37, 0x6B, 0xCD, 0xA0, + 0x54, 0x8E, 0x7C, 0xE1, 0xFA, 0x9D, 0xD1, 0x1F, + 0x85, 0xEB, 0x66, 0x1F, 0xE9, 0x50, 0xB5, 0x43, + 0xAA, 0x63, 0x5C, 0xA4, 0xD3, 0xF0, 0x4E, 0xDE, + 0x5B, 0x32, 0xD6, 0xB6, 0x56, 0xE5, 0xCE, 0x1C, + 0x44, 0xD3, 0x5C, 0x4A, 0x6C, 0x56, 0xCF, 0xF8 + }, + { + 0xD5, 0xE9, 0x38, 0x73, 0x5D, 0x63, 0x78, 0x8C, + 0x80, 0x10, 0x0A, 0xEF, 0xD1, 0x86, 0x48, 0xD1, + 0x8C, 0xF2, 0x72, 0xF6, 0x9F, 0x20, 0xFF, 0x24, + 0xCF, 0xE2, 0x89, 0x5C, 0x08, 0x8A, 0xD0, 0x8B, + 0x01, 0x04, 0xDA, 0x16, 0x72, 0xA4, 0xEB, 0x26, + 0xFC, 0x52, 0x54, 0x5C, 0xC7, 0xD7, 0xA0, 0x1B, + 0x26, 0x6C, 0xF5, 0x46, 0xC4, 0x03, 0xC4, 0x5B, + 0xD1, 0x29, 0xEB, 0x41, 0xBD, 0xD9, 0x20, 0x0B + }, + { + 0x65, 0xA2, 0x45, 0xB4, 0x93, 0x52, 0xEE, 0x29, + 0x7D, 0x91, 0xAF, 0x8C, 0x8B, 0xE0, 0x05, 0x28, + 0xAC, 0x6E, 0x04, 0x6D, 0xD8, 0x3A, 0xC7, 0xBD, + 0x46, 0x5A, 0x98, 0x81, 0x6D, 0xD6, 0x8F, 0x3E, + 0x00, 0xE1, 0xAE, 0x8F, 0x89, 0x53, 0x27, 0xA7, + 0xE9, 0xA8, 0xC9, 0x32, 0x65, 0x98, 0x37, 0x9A, + 0x29, 0xC9, 0xFC, 0x91, 0xEC, 0x0C, 0x6E, 0xEF, + 0x08, 0xF3, 0xE2, 0xB2, 0x16, 0xC1, 0x10, 0x08 + }, + { + 0xC9, 0x56, 0x54, 0xB6, 0x30, 0x19, 0x13, 0x0A, + 0xB4, 0x5D, 0xD0, 0xFB, 0x49, 0x41, 0xB9, 0x8A, + 0xEB, 0x3A, 0xF2, 0xA1, 0x23, 0x91, 0x3E, 0xCA, + 0x2C, 0xE9, 0x9B, 0x3E, 0x97, 0x41, 0x0A, 0x7B, + 0xF8, 0x66, 0x1C, 0xC7, 0xFB, 0xAA, 0x2B, 0xC1, + 0xCF, 0x2B, 0x13, 0x11, 0x3B, 0x1E, 0xD4, 0x0A, + 0x01, 0x18, 0xB8, 0x8E, 0x5F, 0xFF, 0xC3, 0x54, + 0x27, 0x59, 0xEA, 0x00, 0x7E, 0xD4, 0xC5, 0x8D + }, + { + 0x1E, 0xB2, 0x62, 0xF3, 0x8F, 0xA4, 0x94, 0x43, + 0x1F, 0x01, 0x7D, 0xAD, 0x44, 0xC0, 0xDF, 0xB6, + 0x93, 0x24, 0xAC, 0x03, 0x2F, 0x04, 0xB6, 0x57, + 0xFC, 0x91, 0xA8, 0x86, 0x47, 0xBB, 0x74, 0x76, + 0x0F, 0x24, 0xE7, 0xC9, 0x56, 0x51, 0x4F, 0x0C, + 0xF0, 0x02, 0x99, 0x0B, 0x18, 0x2C, 0x16, 0x42, + 0xB9, 0xB2, 0x42, 0x6E, 0x96, 0xA6, 0x11, 0x87, + 0xE4, 0xE0, 0x12, 0xF0, 0x0E, 0x21, 0x7D, 0x84 + }, + { + 0x3B, 0x95, 0x5A, 0xEE, 0xBF, 0xA5, 0x15, 0x1A, + 0xC1, 0xAB, 0x8E, 0x3F, 0x5C, 0xC1, 0xE3, 0x76, + 0x70, 0x84, 0xC8, 0x42, 0xA5, 0x75, 0xD3, 0x62, + 0x69, 0x83, 0x6E, 0x97, 0x35, 0x3D, 0x41, 0x62, + 0x2B, 0x73, 0x1D, 0xDD, 0xCD, 0x5F, 0x26, 0x95, + 0x50, 0xA3, 0xA5, 0xB8, 0x7B, 0xE1, 0xE9, 0x03, + 0x26, 0x34, 0x0B, 0x6E, 0x0E, 0x62, 0x55, 0x58, + 0x15, 0xD9, 0x60, 0x05, 0x97, 0xAC, 0x6E, 0xF9 + }, + { + 0x68, 0x28, 0x9F, 0x66, 0x05, 0x47, 0x3B, 0xA0, + 0xE4, 0xF2, 0x41, 0xBA, 0xF7, 0x47, 0x7A, 0x98, + 0x85, 0x42, 0x6A, 0x85, 0x8F, 0x19, 0xEF, 0x2A, + 0x18, 0xB0, 0xD4, 0x0E, 0xF8, 0xE4, 0x12, 0x82, + 0xED, 0x55, 0x26, 0xB5, 0x19, 0x79, 0x9E, 0x27, + 0x0F, 0x13, 0x88, 0x13, 0x27, 0x91, 0x82, 0x78, + 0x75, 0x57, 0x11, 0x07, 0x1D, 0x85, 0x11, 0xFE, + 0x96, 0x3E, 0x3B, 0x56, 0x06, 0xAA, 0x37, 0x16 + }, + { + 0x80, 0xA3, 0x37, 0x87, 0x54, 0x26, 0x12, 0xC3, + 0x8F, 0x6B, 0xCD, 0x7C, 0xD8, 0x6C, 0xAB, 0x46, + 0x02, 0x27, 0x50, 0x9B, 0x1C, 0xBA, 0xD5, 0xEC, + 0x40, 0x8A, 0x91, 0x41, 0x3D, 0x51, 0x15, 0x5A, + 0x04, 0x76, 0xDA, 0xDB, 0xF3, 0xA2, 0x51, 0x8E, + 0x4A, 0x6E, 0x77, 0xCC, 0x34, 0x66, 0x22, 0xE3, + 0x47, 0xA4, 0x69, 0xBF, 0x8B, 0xAA, 0x5F, 0x04, + 0xEB, 0x2D, 0x98, 0x70, 0x53, 0x55, 0xD0, 0x63 + }, + { + 0x34, 0x62, 0x9B, 0xC6, 0xD8, 0x31, 0x39, 0x1C, + 0x4C, 0xDF, 0x8A, 0xF1, 0xB4, 0xB7, 0xB6, 0xB8, + 0xE8, 0xEE, 0x17, 0xCF, 0x98, 0xC7, 0x0E, 0x5D, + 0xD5, 0x86, 0xCD, 0x99, 0xF1, 0x4B, 0x11, 0xDF, + 0x94, 0x51, 0x66, 0x23, 0x6A, 0x95, 0x71, 0xE6, + 0xD5, 0x91, 0xBB, 0x83, 0xEE, 0x4D, 0x16, 0x4D, + 0x46, 0xF6, 0xB9, 0xD8, 0xEF, 0x86, 0xFF, 0x86, + 0x5A, 0x81, 0xBF, 0xB9, 0x1B, 0x00, 0x42, 0x4B + }, + { + 0x8B, 0x7C, 0xC3, 0x39, 0x16, 0x38, 0x63, 0xBB, + 0x43, 0x83, 0xE5, 0x42, 0xB0, 0xEF, 0x0E, 0x7C, + 0xF3, 0x6B, 0x84, 0xAD, 0x93, 0x2C, 0xDF, 0x5A, + 0x80, 0x41, 0x9E, 0xC9, 0xAD, 0x69, 0x2E, 0x7A, + 0x7E, 0x78, 0x4D, 0x2C, 0x7C, 0xB3, 0x79, 0x6A, + 0x18, 0xB8, 0xF8, 0x00, 0x03, 0x5F, 0x3A, 0xA0, + 0x6C, 0x82, 0x41, 0x00, 0x61, 0x11, 0x20, 0xA7, + 0xBD, 0xEB, 0x35, 0x61, 0x8C, 0xCB, 0x81, 0xB7 + }, + { + 0x4F, 0x08, 0x4E, 0x49, 0x39, 0xDD, 0x5A, 0x7F, + 0x5A, 0x65, 0x8F, 0xAD, 0x58, 0xA1, 0x8A, 0x15, + 0xC2, 0x5C, 0x32, 0xEC, 0x1C, 0x7F, 0xD5, 0xC5, + 0xC6, 0xC3, 0xE8, 0x92, 0xB3, 0x97, 0x1A, 0xEA, + 0xAC, 0x30, 0x83, 0x04, 0xEF, 0x17, 0xB1, 0xC4, + 0x72, 0x39, 0xEA, 0x4B, 0xB3, 0x98, 0xB3, 0xFD, + 0x6D, 0x45, 0x28, 0xD8, 0xDE, 0x8E, 0x76, 0x8A, + 0xE0, 0xF1, 0xA5, 0xA5, 0xC6, 0xB5, 0xC2, 0x97 + }, + { + 0x48, 0xF4, 0x07, 0xA1, 0xAF, 0x5B, 0x80, 0x09, + 0xB2, 0x05, 0x17, 0x42, 0xE8, 0xCF, 0x5C, 0xD5, + 0x65, 0x66, 0x69, 0xE7, 0xD7, 0x22, 0xEE, 0x8E, + 0x7B, 0xD2, 0x02, 0x06, 0x08, 0x49, 0x44, 0x21, + 0x68, 0xD8, 0xFA, 0xCC, 0x11, 0x7C, 0x01, 0x2B, + 0xFB, 0x7B, 0xF4, 0x49, 0xD9, 0x9B, 0xEF, 0xFF, + 0x6A, 0x34, 0xAE, 0xA2, 0x03, 0xF1, 0xD8, 0xD3, + 0x52, 0x72, 0x2B, 0xE5, 0x01, 0x4E, 0xC8, 0x18 + }, + { + 0xA6, 0xAA, 0x82, 0xCD, 0x1E, 0x42, 0x6F, 0x9A, + 0x73, 0xBF, 0xA3, 0x9A, 0x29, 0x03, 0x78, 0x76, + 0x11, 0x46, 0x55, 0xB8, 0xC2, 0x2D, 0x6D, 0x3F, + 0xF8, 0xB6, 0x38, 0xAE, 0x7D, 0xEA, 0x6B, 0x17, + 0x84, 0x3E, 0x09, 0xE5, 0x2E, 0xB6, 0x6F, 0xA1, + 0xE4, 0x75, 0xE4, 0xA8, 0xA3, 0xDE, 0x42, 0x9B, + 0x7D, 0x0F, 0x4A, 0x77, 0x6F, 0xCB, 0x8B, 0xDC, + 0x9B, 0x9F, 0xED, 0xE7, 0xD5, 0x2E, 0x81, 0x5F + }, + { + 0x58, 0x17, 0x02, 0x7D, 0x6B, 0xDD, 0x00, 0xC5, + 0xDD, 0x10, 0xAC, 0x59, 0x3C, 0xD5, 0x60, 0x37, + 0x22, 0x70, 0x77, 0x5A, 0x18, 0x52, 0x6D, 0x7E, + 0x6F, 0x13, 0x87, 0x2A, 0x2E, 0x20, 0xEA, 0xB6, + 0x64, 0x62, 0x5B, 0xE7, 0x16, 0x8A, 0xC4, 0xBD, + 0x7C, 0x9E, 0x0C, 0xE7, 0xFC, 0x40, 0x99, 0xE0, + 0xF4, 0x84, 0x42, 0xE2, 0xC7, 0x67, 0x19, 0x1C, + 0x6E, 0x12, 0x84, 0xE9, 0xB2, 0xCC, 0xEA, 0x8C + }, + { + 0x08, 0xE4, 0x10, 0x28, 0x34, 0x0A, 0x45, 0xC7, + 0x4E, 0x40, 0x52, 0xB3, 0xA8, 0xD6, 0x38, 0x9E, + 0x22, 0xE0, 0x43, 0xA1, 0xAD, 0xAB, 0x5E, 0x28, + 0xD9, 0x76, 0x19, 0x45, 0x0D, 0x72, 0x34, 0x69, + 0xB6, 0x20, 0xCA, 0xA5, 0x19, 0xB8, 0x1C, 0x14, + 0x52, 0x38, 0x54, 0xF6, 0x19, 0xFD, 0x30, 0x27, + 0xE3, 0x84, 0x7B, 0xD0, 0x32, 0x76, 0xE6, 0x06, + 0x04, 0xA8, 0x0D, 0xDB, 0x4D, 0xE8, 0x76, 0xD6 + }, + { + 0x13, 0x0B, 0x84, 0x20, 0x53, 0x7E, 0xB0, 0x7D, + 0x72, 0xAB, 0xDA, 0x07, 0xC8, 0x5A, 0xCB, 0xD8, + 0xB9, 0xA4, 0x4F, 0x16, 0x32, 0x1D, 0xD0, 0x42, + 0x21, 0x45, 0xF8, 0x09, 0x67, 0x3D, 0x30, 0xF2, + 0xB5, 0x32, 0x13, 0x26, 0xE2, 0xBF, 0xF3, 0x17, + 0xEF, 0x3F, 0xEF, 0x98, 0x3C, 0x51, 0xC4, 0xF8, + 0xAB, 0x24, 0xA3, 0x25, 0xD2, 0x98, 0xE3, 0x4A, + 0xFC, 0xE5, 0x69, 0xA8, 0x25, 0x55, 0x77, 0x4C + }, + { + 0xAC, 0x49, 0xB8, 0x44, 0xAF, 0xAA, 0x01, 0x2E, + 0x31, 0xC4, 0x74, 0xCA, 0x26, 0x36, 0x48, 0x84, + 0x4F, 0xD2, 0xF6, 0x30, 0x79, 0x92, 0xC2, 0xF7, + 0x52, 0xAC, 0xA0, 0x2C, 0x38, 0x28, 0x96, 0x51, + 0x75, 0x79, 0x4D, 0xEE, 0xE2, 0xD2, 0xEE, 0x95, + 0xC6, 0x1C, 0xD2, 0x84, 0xF6, 0xB5, 0xA2, 0xD7, + 0x5E, 0x2E, 0xF2, 0xB2, 0x9E, 0xE8, 0x14, 0x9E, + 0x77, 0xFB, 0x81, 0x44, 0x7B, 0x2F, 0xD0, 0x4B + }, + { + 0xB9, 0xD7, 0xCA, 0x81, 0xCC, 0x60, 0xBB, 0x95, + 0x78, 0xE4, 0x40, 0x24, 0xE5, 0xA0, 0xA0, 0xBE, + 0x80, 0xF2, 0x73, 0x36, 0xA6, 0xA9, 0xF4, 0xE5, + 0x3D, 0xF3, 0x99, 0x9C, 0xB1, 0x91, 0x28, 0x0B, + 0x09, 0x0E, 0x2A, 0xC2, 0xD2, 0x9C, 0x5B, 0xAA, + 0xD9, 0xD7, 0x14, 0x15, 0xBD, 0xC1, 0x29, 0xE6, + 0x9A, 0xA2, 0x66, 0x7A, 0xF6, 0xA7, 0xFD, 0x5E, + 0x18, 0x9F, 0xCC, 0xDC, 0xEE, 0x81, 0x73, 0x40 + }, + { + 0xA7, 0x55, 0xE1, 0x13, 0x38, 0x65, 0x72, 0xC7, + 0x5C, 0xED, 0x61, 0xD7, 0x19, 0x70, 0x60, 0x70, + 0xB9, 0x14, 0x60, 0x48, 0xE4, 0x2A, 0x9F, 0x8C, + 0xD3, 0x56, 0x67, 0xA0, 0x88, 0xB4, 0x2F, 0x08, + 0x80, 0x8A, 0xBD, 0xF7, 0x7E, 0x61, 0x8A, 0xBD, + 0x95, 0x9A, 0xFC, 0x75, 0x73, 0x79, 0xCA, 0x2C, + 0x00, 0xBC, 0xC1, 0xA4, 0x83, 0x90, 0xFA, 0x2B, + 0xFF, 0x61, 0x8B, 0x1E, 0x00, 0x78, 0xA6, 0x13 + }, + { + 0xA7, 0x3C, 0x7D, 0xEB, 0xED, 0x32, 0x6F, 0x1C, + 0x0D, 0xB0, 0x79, 0x5E, 0xE7, 0xD6, 0xE3, 0x94, + 0x68, 0x94, 0xB8, 0x26, 0xB1, 0xF8, 0x10, 0x1C, + 0x56, 0xC8, 0x23, 0xBA, 0x17, 0x16, 0x83, 0x12, + 0xE7, 0xF5, 0x3F, 0xC7, 0xDB, 0xE5, 0x2C, 0x3E, + 0x11, 0xE6, 0x98, 0x52, 0xC4, 0x04, 0x85, 0xE2, + 0xEF, 0x18, 0x24, 0x77, 0x86, 0x2E, 0xA6, 0xA3, + 0x4E, 0xC1, 0x36, 0xE2, 0xDF, 0xEE, 0xA6, 0xF4 + }, + { + 0x6C, 0xB8, 0xF9, 0xD5, 0x2C, 0x56, 0xD8, 0x2C, + 0xAC, 0x28, 0xF3, 0x9E, 0xA1, 0x59, 0x3E, 0x8B, + 0xB2, 0x50, 0x62, 0x93, 0xAC, 0x0D, 0x68, 0x37, + 0x6A, 0x17, 0x09, 0xB6, 0x2A, 0x46, 0xDF, 0x14, + 0xA4, 0xAE, 0x64, 0xB2, 0xD8, 0xFA, 0xB7, 0x67, + 0x33, 0xA1, 0xCE, 0xD2, 0xD5, 0x48, 0xE3, 0xF3, + 0xC6, 0xFC, 0xB4, 0x9D, 0x40, 0xC3, 0xD5, 0x80, + 0x8E, 0x44, 0x9C, 0xD8, 0x3D, 0x1C, 0x2A, 0xA2 + }, + { + 0x68, 0x3F, 0xA2, 0xB2, 0x36, 0x9A, 0x10, 0x16, + 0x2C, 0x1C, 0x1C, 0x7B, 0x24, 0xBC, 0x97, 0x0E, + 0xE6, 0x7D, 0xA2, 0x20, 0x56, 0x4F, 0x32, 0x20, + 0x3F, 0x62, 0x56, 0x96, 0xC0, 0x35, 0x2A, 0x0B, + 0x9A, 0xD9, 0x66, 0x24, 0x36, 0x2D, 0x95, 0x2D, + 0x84, 0x46, 0x3C, 0x11, 0x06, 0xA2, 0xDB, 0xA7, + 0xA0, 0x92, 0x59, 0x98, 0x84, 0xB3, 0x5A, 0x0B, + 0x89, 0xC8, 0xF1, 0xB6, 0xA9, 0xB5, 0xA6, 0x1E + }, + { + 0xAA, 0xD9, 0xAD, 0x44, 0x61, 0x01, 0x18, 0xB7, + 0x7D, 0x50, 0x8A, 0xEB, 0x1B, 0xBC, 0xD1, 0xC1, + 0xB7, 0xD0, 0x17, 0x13, 0x97, 0xFB, 0x51, 0x0A, + 0x40, 0x1B, 0xBC, 0x0E, 0xC3, 0x46, 0x23, 0x67, + 0x0D, 0x86, 0xA2, 0xDC, 0x3C, 0x8F, 0x3A, 0xB5, + 0xA2, 0x04, 0x4D, 0xF7, 0x30, 0x25, 0x67, 0x27, + 0x54, 0x5F, 0x08, 0x60, 0xCE, 0x21, 0xA1, 0xEA, + 0xC7, 0x17, 0xDF, 0xC4, 0x8F, 0x5D, 0x22, 0x8E + }, + { + 0xC4, 0x25, 0x78, 0xDE, 0x23, 0xB4, 0xC9, 0x87, + 0xD5, 0xE1, 0xAC, 0x4D, 0x68, 0x9E, 0xD5, 0xDE, + 0x4B, 0x04, 0x17, 0xF9, 0x70, 0x4B, 0xC6, 0xBC, + 0xE9, 0x69, 0xFA, 0x13, 0x47, 0x15, 0x85, 0xD6, + 0x2C, 0x2C, 0xB1, 0x21, 0x2A, 0x94, 0x4F, 0x39, + 0x7F, 0xC9, 0xCA, 0x2C, 0x37, 0x47, 0xC3, 0xBE, + 0xB6, 0x94, 0xEC, 0x4C, 0x5B, 0xE6, 0x88, 0x28, + 0xDD, 0xA5, 0x3E, 0xF4, 0x3F, 0xAE, 0xC6, 0xC0 + }, + { + 0x47, 0x0F, 0x00, 0x84, 0x1E, 0xE8, 0x24, 0x4E, + 0x63, 0xED, 0x2C, 0x7E, 0xA3, 0x0E, 0x2E, 0x41, + 0x98, 0x97, 0xC1, 0x97, 0x46, 0x2E, 0xCC, 0xCE, + 0xCF, 0x71, 0x3B, 0x42, 0xA5, 0x06, 0x5F, 0xFF, + 0x59, 0x14, 0xBC, 0x9B, 0x79, 0xAF, 0xFE, 0x8F, + 0x6B, 0x65, 0x78, 0x75, 0xE7, 0x89, 0xAE, 0x21, + 0x3B, 0xD9, 0x14, 0xCD, 0x35, 0xBD, 0x17, 0x4D, + 0x46, 0xE9, 0xD1, 0x8B, 0xD8, 0x43, 0x77, 0x3D + }, + { + 0x34, 0xFC, 0x42, 0x13, 0x73, 0x0F, 0x47, 0xA5, + 0xE9, 0xA3, 0x58, 0x0F, 0x64, 0x3E, 0x12, 0x94, + 0x5C, 0xFC, 0xB3, 0x1B, 0xF2, 0x06, 0xF6, 0xAD, + 0x45, 0x0C, 0xE5, 0x28, 0xDA, 0x3F, 0xA4, 0x32, + 0xE0, 0x05, 0xD6, 0xB0, 0xEC, 0xCE, 0x10, 0xDC, + 0xA7, 0xC5, 0x99, 0x5F, 0x6A, 0xAC, 0xC5, 0x15, + 0x0E, 0x1B, 0x00, 0x9E, 0x19, 0x75, 0x1E, 0x83, + 0x09, 0xF8, 0x85, 0x95, 0x31, 0x84, 0x43, 0x74 + }, + { + 0xFB, 0x3C, 0x1F, 0x0F, 0x56, 0xA5, 0x6F, 0x8E, + 0x31, 0x6F, 0xDF, 0x5D, 0x85, 0x3C, 0x8C, 0x87, + 0x2C, 0x39, 0x63, 0x5D, 0x08, 0x36, 0x34, 0xC3, + 0x90, 0x4F, 0xC3, 0xAC, 0x07, 0xD1, 0xB5, 0x78, + 0xE8, 0x5F, 0xF0, 0xE4, 0x80, 0xE9, 0x2D, 0x44, + 0xAD, 0xE3, 0x3B, 0x62, 0xE8, 0x93, 0xEE, 0x32, + 0x34, 0x3E, 0x79, 0xDD, 0xF6, 0xEF, 0x29, 0x2E, + 0x89, 0xB5, 0x82, 0xD3, 0x12, 0x50, 0x23, 0x14 + }, + { + 0xC7, 0xC9, 0x7F, 0xC6, 0x5D, 0xD2, 0xB9, 0xE3, + 0xD3, 0xD6, 0x07, 0xD3, 0x15, 0x98, 0xD3, 0xF8, + 0x42, 0x61, 0xE9, 0x91, 0x92, 0x51, 0xE9, 0xC8, + 0xE5, 0x7B, 0xB5, 0xF8, 0x29, 0x37, 0x7D, 0x5F, + 0x73, 0xEA, 0xBB, 0xED, 0x55, 0xC6, 0xC3, 0x81, + 0x18, 0x0F, 0x29, 0xAD, 0x02, 0xE5, 0xBE, 0x79, + 0x7F, 0xFE, 0xC7, 0xE5, 0x7B, 0xDE, 0xCB, 0xC5, + 0x0A, 0xD3, 0xD0, 0x62, 0xF0, 0x99, 0x3A, 0xB0 + }, + { + 0xA5, 0x7A, 0x49, 0xCD, 0xBE, 0x67, 0xAE, 0x7D, + 0x9F, 0x79, 0x7B, 0xB5, 0xCC, 0x7E, 0xFC, 0x2D, + 0xF0, 0x7F, 0x4E, 0x1B, 0x15, 0x95, 0x5F, 0x85, + 0xDA, 0xE7, 0x4B, 0x76, 0xE2, 0xEC, 0xB8, 0x5A, + 0xFB, 0x6C, 0xD9, 0xEE, 0xED, 0x88, 0x88, 0xD5, + 0xCA, 0x3E, 0xC5, 0xAB, 0x65, 0xD2, 0x7A, 0x7B, + 0x19, 0xE5, 0x78, 0x47, 0x57, 0x60, 0xA0, 0x45, + 0xAC, 0x3C, 0x92, 0xE1, 0x3A, 0x93, 0x8E, 0x77 + }, + { + 0xC7, 0x14, 0x3F, 0xCE, 0x96, 0x14, 0xA1, 0x7F, + 0xD6, 0x53, 0xAE, 0xB1, 0x40, 0x72, 0x6D, 0xC9, + 0xC3, 0xDB, 0xB1, 0xDE, 0x6C, 0xC5, 0x81, 0xB2, + 0x72, 0x68, 0x97, 0xEC, 0x24, 0xB7, 0xA5, 0x03, + 0x59, 0xAD, 0x49, 0x22, 0x43, 0xBE, 0x66, 0xD9, + 0xED, 0xD8, 0xC9, 0x33, 0xB5, 0xB8, 0x0E, 0x0B, + 0x91, 0xBB, 0x61, 0xEA, 0x98, 0x05, 0x60, 0x06, + 0x51, 0x69, 0x76, 0xFA, 0xE8, 0xD9, 0x9A, 0x35 + }, + { + 0x65, 0xBB, 0x58, 0xD0, 0x7F, 0x93, 0x7E, 0x2D, + 0x3C, 0x7E, 0x65, 0x38, 0x5F, 0x9C, 0x54, 0x73, + 0x0B, 0x70, 0x41, 0x05, 0xCC, 0xDB, 0x69, 0x1F, + 0x6E, 0x14, 0x6D, 0x4E, 0xE8, 0xF6, 0xC0, 0x86, + 0xF4, 0x95, 0x11, 0x03, 0x51, 0x10, 0xA9, 0xAD, + 0x60, 0x31, 0xFD, 0xCE, 0xB9, 0x43, 0xE0, 0xF9, + 0x61, 0x3B, 0xCB, 0x27, 0x6D, 0xD4, 0x0F, 0x06, + 0x24, 0xEF, 0x0F, 0x92, 0x4F, 0x80, 0x97, 0x83 + }, + { + 0xE5, 0x40, 0x27, 0x7F, 0x68, 0x3B, 0x11, 0x86, + 0xDD, 0x3B, 0x5B, 0x3F, 0x61, 0x43, 0x33, 0x96, + 0x58, 0x1A, 0x35, 0xFE, 0xB1, 0x20, 0x02, 0xBE, + 0x8C, 0x6A, 0x62, 0x31, 0xFC, 0x40, 0xFF, 0xA7, + 0x0F, 0x08, 0x08, 0x1B, 0xC5, 0x8B, 0x2D, 0x94, + 0xF7, 0x64, 0x95, 0x43, 0x61, 0x4A, 0x43, 0x5F, + 0xAA, 0x2D, 0x62, 0x11, 0x0E, 0x13, 0xDA, 0xBC, + 0x7B, 0x86, 0x62, 0x9B, 0x63, 0xAF, 0x9C, 0x24 + }, + { + 0x41, 0x85, 0x00, 0x87, 0x8C, 0x5F, 0xBC, 0xB5, + 0x84, 0xC4, 0x32, 0xF4, 0x28, 0x5E, 0x05, 0xE4, + 0x9F, 0x2E, 0x3E, 0x07, 0x53, 0x99, 0xA0, 0xDB, + 0xFC, 0xF8, 0x74, 0xEB, 0xF8, 0xC0, 0x3D, 0x02, + 0xBF, 0x16, 0xBC, 0x69, 0x89, 0xD1, 0x61, 0xC7, + 0x7C, 0xA0, 0x78, 0x6B, 0x05, 0x05, 0x3C, 0x6C, + 0x70, 0x94, 0x33, 0x71, 0x23, 0x19, 0x19, 0x21, + 0x28, 0x83, 0x5C, 0xF0, 0xB6, 0x60, 0x59, 0x5B + }, + { + 0x88, 0x90, 0x90, 0xDB, 0xB1, 0x94, 0x4B, 0xDC, + 0x94, 0x33, 0xEE, 0x5E, 0xF1, 0x01, 0x0C, 0x7A, + 0x4A, 0x24, 0xA8, 0xE7, 0x1E, 0xCE, 0xA8, 0xE1, + 0x2A, 0x31, 0x31, 0x8C, 0xE4, 0x9D, 0xCA, 0xB0, + 0xAC, 0xA5, 0xC3, 0x80, 0x23, 0x34, 0xAA, 0xB2, + 0xCC, 0x84, 0xB1, 0x4C, 0x6B, 0x93, 0x21, 0xFE, + 0x58, 0x6B, 0xF3, 0xF8, 0x76, 0xF1, 0x9C, 0xD4, + 0x06, 0xEB, 0x11, 0x27, 0xFB, 0x94, 0x48, 0x01 + }, + { + 0x53, 0xB6, 0xA2, 0x89, 0x10, 0xAA, 0x92, 0xE2, + 0x7E, 0x53, 0x6F, 0xB5, 0x49, 0xCF, 0x9B, 0x99, + 0x18, 0x79, 0x10, 0x60, 0x89, 0x8E, 0x0B, 0x9F, + 0xE1, 0x83, 0x57, 0x7F, 0xF4, 0x3B, 0x5E, 0x9C, + 0x76, 0x89, 0xC7, 0x45, 0xB3, 0x2E, 0x41, 0x22, + 0x69, 0x83, 0x7C, 0x31, 0xB8, 0x9E, 0x6C, 0xC1, + 0x2B, 0xF7, 0x6E, 0x13, 0xCA, 0xD3, 0x66, 0xB7, + 0x4E, 0xCE, 0x48, 0xBB, 0x85, 0xFD, 0x09, 0xE9 + }, + { + 0x7C, 0x09, 0x20, 0x80, 0xC6, 0xA8, 0x0D, 0x67, + 0x24, 0x09, 0xD0, 0x81, 0xD3, 0xD1, 0x77, 0x10, + 0x6B, 0xCD, 0x63, 0x56, 0x77, 0x85, 0x14, 0x07, + 0x19, 0x49, 0x09, 0x50, 0xAE, 0x07, 0xAE, 0x8F, + 0xCA, 0xAB, 0xBA, 0xAA, 0xB3, 0x30, 0xCF, 0xBC, + 0xF7, 0x37, 0x44, 0x82, 0xC2, 0x20, 0xAF, 0x2E, + 0xAD, 0xEE, 0xB7, 0x3D, 0xCB, 0xB3, 0x5E, 0xD8, + 0x23, 0x34, 0x4E, 0x14, 0x4E, 0x7D, 0x48, 0x99 + }, + { + 0x9C, 0xCD, 0xE5, 0x66, 0xD2, 0x40, 0x05, 0x09, + 0x18, 0x11, 0x11, 0xF3, 0x2D, 0xDE, 0x4C, 0xD6, + 0x32, 0x09, 0xFE, 0x59, 0xA3, 0x0C, 0x11, 0x45, + 0x46, 0xAD, 0x27, 0x76, 0xD8, 0x89, 0xA4, 0x1B, + 0xAD, 0x8F, 0xA1, 0xBB, 0x46, 0x8C, 0xB2, 0xF9, + 0xD4, 0x2C, 0xA9, 0x92, 0x8A, 0x77, 0x70, 0xFE, + 0xF8, 0xE8, 0xBA, 0x4D, 0x0C, 0x81, 0x2D, 0x9A, + 0x1E, 0x75, 0xC3, 0xD8, 0xD2, 0xCC, 0xD7, 0x5A + }, + { + 0x6E, 0x29, 0x3B, 0xF5, 0xD0, 0x3F, 0xE4, 0x39, + 0x77, 0xCF, 0xE3, 0xF5, 0x7C, 0xCD, 0xB3, 0xAE, + 0x28, 0x2A, 0x85, 0x45, 0x5D, 0xCA, 0x33, 0xF3, + 0x7F, 0x4B, 0x74, 0xF8, 0x39, 0x8C, 0xC6, 0x12, + 0x43, 0x3D, 0x75, 0x5C, 0xBE, 0xC4, 0x12, 0xF8, + 0xF8, 0x2A, 0x3B, 0xD3, 0xBC, 0x4A, 0x27, 0x8F, + 0x7E, 0xCD, 0x0D, 0xFA, 0x9B, 0xBD, 0xC4, 0x0B, + 0xE7, 0xA7, 0x87, 0xC8, 0xF1, 0x59, 0xB2, 0xDF + }, + { + 0xC5, 0x65, 0x46, 0xFB, 0x21, 0x78, 0x45, 0x6F, + 0x33, 0x61, 0x64, 0xC1, 0x8B, 0x90, 0xDE, 0xFF, + 0xC8, 0x3A, 0xE2, 0xB5, 0xA3, 0xAC, 0xA7, 0x7B, + 0x68, 0x84, 0xD3, 0x6D, 0x2C, 0x1D, 0xB3, 0x95, + 0x01, 0xB3, 0xE6, 0x5E, 0x36, 0xC7, 0x58, 0xC6, + 0x6E, 0x31, 0x88, 0x45, 0x1F, 0xDB, 0x35, 0x15, + 0xEE, 0x16, 0x2C, 0x00, 0x1F, 0x06, 0xC3, 0xE8, + 0xCB, 0x57, 0x3A, 0xDF, 0x30, 0xF7, 0xA1, 0x01 + }, + { + 0x6F, 0x82, 0xF8, 0x9F, 0x29, 0x9E, 0xBC, 0xA2, + 0xFE, 0x01, 0x4B, 0x59, 0xBF, 0xFE, 0x1A, 0xA8, + 0x4E, 0x88, 0xB1, 0x91, 0x5F, 0xE2, 0x56, 0xAF, + 0xB6, 0x46, 0xFD, 0x84, 0x48, 0xAF, 0x2B, 0x88, + 0x91, 0xA7, 0xFA, 0xB3, 0x7A, 0x4E, 0xA6, 0xF9, + 0xA5, 0x0E, 0x6C, 0x31, 0x70, 0x39, 0xD8, 0xCF, + 0x87, 0x8F, 0x4C, 0x8E, 0x1A, 0x0D, 0xD4, 0x64, + 0xF0, 0xB4, 0xD6, 0xFF, 0x1C, 0x7E, 0xA8, 0x53 + }, + { + 0x2B, 0x85, 0x99, 0xFF, 0x9C, 0x3D, 0x61, 0x98, + 0x63, 0x7A, 0xD5, 0x1E, 0x57, 0xD1, 0x99, 0x8B, + 0x0D, 0x75, 0x31, 0x3F, 0xE2, 0xDD, 0x61, 0xA5, + 0x33, 0xC9, 0x64, 0xA6, 0xDD, 0x96, 0x07, 0xC6, + 0xF7, 0x23, 0xE9, 0x45, 0x2C, 0xE4, 0x6E, 0x01, + 0x4B, 0x1C, 0x1D, 0x6D, 0xE7, 0x7B, 0xA5, 0xB8, + 0x8C, 0x91, 0x4D, 0x1C, 0x59, 0x7B, 0xF1, 0xEA, + 0xE1, 0x34, 0x74, 0xB4, 0x29, 0x0E, 0x89, 0xB2 + }, + { + 0x08, 0xBF, 0x34, 0x6D, 0x38, 0xE1, 0xDF, 0x06, + 0xC8, 0x26, 0x0E, 0xDB, 0x1D, 0xA7, 0x55, 0x79, + 0x27, 0x59, 0x48, 0xD5, 0xC0, 0xA0, 0xAA, 0x9E, + 0xD2, 0x88, 0x6F, 0x88, 0x56, 0xDE, 0x54, 0x17, + 0xA1, 0x56, 0x99, 0x87, 0x58, 0xF5, 0xB1, 0x7E, + 0x52, 0xF1, 0x01, 0xCA, 0x95, 0x7A, 0x71, 0x13, + 0x74, 0x73, 0xDF, 0xD1, 0x8D, 0x7D, 0x20, 0x9C, + 0x4C, 0x10, 0xD9, 0x23, 0x3C, 0x93, 0x69, 0x1D + }, + { + 0x6D, 0xF2, 0x15, 0x6D, 0x77, 0x31, 0x14, 0xD3, + 0x10, 0xB6, 0x3D, 0xB9, 0xEE, 0x53, 0x50, 0xD7, + 0x7E, 0x6B, 0xCF, 0x25, 0xB0, 0x5F, 0xCD, 0x91, + 0x0F, 0x9B, 0x31, 0xBC, 0x42, 0xBB, 0x13, 0xFE, + 0x82, 0x25, 0xEB, 0xCB, 0x2A, 0x23, 0xA6, 0x22, + 0x80, 0x77, 0x7B, 0x6B, 0xF7, 0x4E, 0x2C, 0xD0, + 0x91, 0x7C, 0x76, 0x40, 0xB4, 0x3D, 0xEF, 0xE4, + 0x68, 0xCD, 0x1E, 0x18, 0xC9, 0x43, 0xC6, 0x6A + }, + { + 0x7C, 0x70, 0x38, 0xBC, 0x13, 0xA9, 0x11, 0x51, + 0x82, 0x8A, 0x5B, 0xA8, 0x2B, 0x4A, 0x96, 0x04, + 0x0F, 0x25, 0x8A, 0x4D, 0xFB, 0x1B, 0x13, 0x73, + 0xF0, 0xD3, 0x59, 0x16, 0x8A, 0xFB, 0x05, 0x17, + 0xA2, 0x0B, 0x28, 0xA1, 0x2D, 0x36, 0x44, 0x04, + 0x6B, 0xE6, 0x6B, 0x8D, 0x08, 0xD8, 0xAE, 0x7F, + 0x6A, 0x92, 0x3E, 0xA1, 0xC0, 0x01, 0x87, 0xC6, + 0xD1, 0x1D, 0xC5, 0x02, 0xBA, 0xC7, 0x13, 0x05 + }, + { + 0xBC, 0xD1, 0xB3, 0x0D, 0x80, 0x8F, 0xB7, 0x39, + 0xB9, 0x87, 0xCB, 0xF1, 0x54, 0xBE, 0xA0, 0x0D, + 0xA9, 0xD4, 0x03, 0x80, 0xB8, 0x61, 0xD4, 0xC1, + 0xD6, 0x37, 0x71, 0x22, 0xDA, 0xDD, 0x61, 0xC0, + 0xE5, 0x90, 0x18, 0xB7, 0x19, 0x41, 0xCF, 0xB6, + 0x2E, 0x00, 0xDC, 0xD7, 0x0A, 0xEB, 0x9A, 0xBF, + 0x04, 0x73, 0xE8, 0x0F, 0x0A, 0x7E, 0xCA, 0x6B, + 0x6D, 0xEA, 0x24, 0x6A, 0xB2, 0x29, 0xDD, 0x2B + }, + { + 0x7E, 0xD4, 0x46, 0x8D, 0x96, 0x85, 0x30, 0xFE, + 0x7A, 0xB2, 0xC3, 0x35, 0x40, 0xB2, 0x6D, 0x8C, + 0x3B, 0xD3, 0xED, 0x44, 0xB3, 0x4F, 0xBE, 0x8C, + 0x2A, 0x9D, 0x7F, 0x80, 0x5B, 0x5A, 0xDA, 0x0E, + 0xA2, 0x52, 0xEE, 0xAD, 0xE4, 0xFC, 0xE9, 0x7F, + 0x89, 0x72, 0x8A, 0xD8, 0x5B, 0xC8, 0xBB, 0x24, + 0x30, 0xB1, 0xBE, 0xF2, 0xCD, 0xDD, 0x32, 0xC8, + 0x44, 0x6E, 0x59, 0xB8, 0xE8, 0xBA, 0x3C, 0x67 + }, + { + 0x6D, 0x30, 0xB7, 0xC6, 0xCE, 0x8A, 0x32, 0x36, + 0xC0, 0xCA, 0x2F, 0x8D, 0x72, 0x8B, 0x10, 0x88, + 0xCA, 0x06, 0x98, 0x3A, 0x80, 0x43, 0xE6, 0x21, + 0xD5, 0xDC, 0xF0, 0xC5, 0x37, 0xD1, 0x3B, 0x08, + 0x79, 0x1E, 0xDE, 0xB0, 0x1A, 0x3C, 0xF0, 0x94, + 0x3E, 0xC1, 0xC8, 0x90, 0xAB, 0x6E, 0x29, 0xB1, + 0x46, 0xA2, 0x36, 0xCD, 0x46, 0xBC, 0xB9, 0xD9, + 0x3B, 0xF5, 0x16, 0xFB, 0x67, 0xC6, 0x3F, 0xE5 + }, + { + 0x97, 0xFE, 0x03, 0xCE, 0xF3, 0x14, 0x38, 0x50, + 0x89, 0x11, 0xBD, 0xED, 0x97, 0x59, 0x80, 0xA6, + 0x60, 0x29, 0x30, 0x5D, 0xC5, 0xE3, 0xFA, 0x8A, + 0xD1, 0xB4, 0xFB, 0x22, 0xFC, 0xDF, 0x5A, 0x19, + 0xA7, 0x33, 0x32, 0x03, 0x27, 0xD8, 0xF7, 0x1C, + 0xCF, 0x49, 0x6C, 0xB3, 0xA4, 0x4A, 0x77, 0xAF, + 0x56, 0xE3, 0xDD, 0xE7, 0x3D, 0x3A, 0x5F, 0x17, + 0x68, 0x96, 0xCC, 0x57, 0xC9, 0xA5, 0xAD, 0x99 + }, + { + 0x78, 0x5A, 0x9D, 0x0F, 0xBD, 0x21, 0x13, 0x6D, + 0xBC, 0xE8, 0xFA, 0x7E, 0xAF, 0xD6, 0x3C, 0x9D, + 0xAD, 0x22, 0x00, 0x52, 0x97, 0x84, 0x16, 0xB3, + 0x1D, 0x97, 0x53, 0xEA, 0xA1, 0x49, 0x09, 0x78, + 0x47, 0xED, 0x9B, 0x30, 0xA6, 0x5C, 0x70, 0x50, + 0x7E, 0xFF, 0x01, 0x87, 0x91, 0x49, 0xED, 0x5C, + 0xF0, 0x47, 0x1D, 0x37, 0x79, 0x8E, 0xDC, 0x05, + 0xAB, 0xD5, 0x6A, 0xD4, 0xA2, 0xCC, 0xCB, 0x1D + }, + { + 0xAD, 0x40, 0x8D, 0x2A, 0xBD, 0xDF, 0xD3, 0x7B, + 0x3B, 0xF3, 0x47, 0x94, 0xC1, 0xA3, 0x37, 0x1D, + 0x92, 0x8E, 0xD7, 0xFC, 0x8D, 0x96, 0x62, 0x25, + 0x33, 0x35, 0x84, 0xC5, 0x66, 0x58, 0x17, 0x83, + 0x2A, 0x37, 0xC0, 0x7F, 0x0D, 0xC7, 0xCB, 0x5A, + 0xA8, 0x74, 0xCD, 0x7D, 0x20, 0xFE, 0x8F, 0xAB, + 0x8E, 0xAB, 0xCB, 0x9B, 0x33, 0xD2, 0xE0, 0x84, + 0x1F, 0x6E, 0x20, 0x09, 0x60, 0x89, 0x9D, 0x95 + }, + { + 0x97, 0x66, 0x8F, 0x74, 0x5B, 0x60, 0x32, 0xFC, + 0x81, 0x5D, 0x95, 0x79, 0x32, 0x27, 0x69, 0xDC, + 0xCD, 0x95, 0x01, 0xA5, 0x08, 0x00, 0x29, 0xB8, + 0xAE, 0x82, 0x6B, 0xEF, 0xB6, 0x74, 0x23, 0x31, + 0xBD, 0x9F, 0x76, 0xEF, 0xEB, 0x3E, 0x2B, 0x8E, + 0x81, 0xA9, 0x78, 0x6B, 0x28, 0x2F, 0x50, 0x68, + 0xA3, 0xA2, 0x42, 0x46, 0x97, 0xA7, 0x7C, 0x41, + 0x87, 0x6B, 0x7E, 0x75, 0x3F, 0x4C, 0x77, 0x67 + }, + { + 0x26, 0xBB, 0x98, 0x5F, 0x47, 0xE7, 0xFE, 0xE0, + 0xCF, 0xD2, 0x52, 0xD4, 0xEF, 0x96, 0xBE, 0xD4, + 0x2B, 0x9C, 0x37, 0x0C, 0x1C, 0x6A, 0x3E, 0x8C, + 0x9E, 0xB0, 0x4E, 0xF7, 0xF7, 0x81, 0x8B, 0x83, + 0x3A, 0x0D, 0x1F, 0x04, 0x3E, 0xBA, 0xFB, 0x91, + 0x1D, 0xC7, 0x79, 0xE0, 0x27, 0x40, 0xA0, 0x2A, + 0x44, 0xD3, 0xA1, 0xEA, 0x45, 0xED, 0x4A, 0xD5, + 0x5E, 0x68, 0x6C, 0x92, 0x7C, 0xAF, 0xE9, 0x7E + }, + { + 0x5B, 0xFE, 0x2B, 0x1D, 0xCF, 0x7F, 0xE9, 0xB9, + 0x50, 0x88, 0xAC, 0xED, 0xB5, 0x75, 0xC1, 0x90, + 0x16, 0xC7, 0x43, 0xB2, 0xE7, 0x63, 0xBF, 0x58, + 0x51, 0xAC, 0x40, 0x7C, 0x9E, 0xDA, 0x43, 0x71, + 0x5E, 0xDF, 0xA4, 0x8B, 0x48, 0x25, 0x49, 0x2C, + 0x51, 0x79, 0x59, 0x3F, 0xFF, 0x21, 0x35, 0x1B, + 0x76, 0xE8, 0xB7, 0xE0, 0x34, 0xE4, 0xC5, 0x3C, + 0x79, 0xF6, 0x1F, 0x29, 0xC4, 0x79, 0xBD, 0x08 + }, + { + 0xC7, 0x65, 0x09, 0xEF, 0x72, 0xF4, 0xA6, 0xF9, + 0xC9, 0xC4, 0x06, 0x18, 0xED, 0x52, 0xB2, 0x08, + 0x4F, 0x83, 0x50, 0x22, 0x32, 0xE0, 0xAC, 0x8B, + 0xDA, 0xF3, 0x26, 0x43, 0x68, 0xE4, 0xD0, 0x18, + 0x0F, 0x68, 0x54, 0xC4, 0xAB, 0xF4, 0xF6, 0x50, + 0x9C, 0x79, 0xCA, 0xAF, 0xC4, 0x4C, 0xF3, 0x19, + 0x4A, 0xFC, 0x57, 0xBD, 0x07, 0x7B, 0xD7, 0xB3, + 0xC9, 0xBD, 0xA3, 0xD4, 0xB8, 0x77, 0x58, 0x16 + }, + { + 0xD6, 0x6F, 0x2B, 0xEA, 0xB9, 0x90, 0xE3, 0x54, + 0xCC, 0xB9, 0x10, 0xE4, 0xE9, 0xC7, 0xAC, 0x61, + 0x8C, 0x7B, 0x63, 0xEF, 0x29, 0x2A, 0x96, 0xB5, + 0x52, 0x34, 0x1D, 0xE7, 0x8D, 0xC4, 0x6D, 0x3E, + 0xC8, 0xCF, 0xAB, 0xC6, 0x99, 0xB5, 0x0A, 0xF4, + 0x1F, 0xDA, 0x39, 0xCF, 0x1B, 0x01, 0x73, 0x66, + 0x09, 0x23, 0x51, 0x0A, 0xD6, 0x7F, 0xAE, 0xDE, + 0xF5, 0x20, 0x7C, 0xFF, 0xE8, 0x64, 0x1D, 0x20 + }, + { + 0x7D, 0x8F, 0x06, 0x72, 0x99, 0x2B, 0x79, 0xBE, + 0x3A, 0x36, 0x4D, 0x8E, 0x59, 0x04, 0xF4, 0xAB, + 0x71, 0x3B, 0xBC, 0x8A, 0xB0, 0x1B, 0x4F, 0x30, + 0x9A, 0xD8, 0xCC, 0xF2, 0x23, 0xCE, 0x10, 0x34, + 0xA8, 0x60, 0xDC, 0xB0, 0xB0, 0x05, 0x50, 0x61, + 0x2C, 0xC2, 0xFA, 0x17, 0xF2, 0x96, 0x9E, 0x18, + 0xF2, 0x2E, 0x14, 0x27, 0xD2, 0x54, 0xB4, 0xA8, + 0x2B, 0x3A, 0x03, 0xA3, 0xEB, 0x39, 0x4A, 0xDF + }, + { + 0xA5, 0x6D, 0x67, 0x25, 0xBF, 0xB3, 0xDE, 0x47, + 0xC1, 0x41, 0x4A, 0xDF, 0x25, 0xFC, 0x8F, 0x0F, + 0xC9, 0x84, 0x6F, 0x69, 0x87, 0x72, 0x2B, 0xC0, + 0x63, 0x66, 0xD5, 0xCA, 0x4E, 0x89, 0x72, 0x29, + 0x25, 0xEB, 0xBC, 0x88, 0x14, 0x18, 0x84, 0x40, + 0x75, 0x39, 0x7A, 0x0C, 0xA8, 0x98, 0x42, 0xC7, + 0xB9, 0xE9, 0xE0, 0x7E, 0x1D, 0x9D, 0x18, 0x3E, + 0xBE, 0xB3, 0x9E, 0x12, 0x0B, 0x48, 0x3B, 0xF7 + }, + { + 0xAF, 0x5E, 0x03, 0xD7, 0xFE, 0x60, 0xC6, 0x7E, + 0x10, 0x31, 0x33, 0x44, 0x43, 0x4E, 0x79, 0x48, + 0x5A, 0x03, 0xA7, 0x58, 0xD6, 0xDC, 0xE9, 0x85, + 0x57, 0x47, 0x45, 0x76, 0x3C, 0x1C, 0x5C, 0x77, + 0xD4, 0xFB, 0x3E, 0x6F, 0xB1, 0x22, 0x30, 0x36, + 0x83, 0x70, 0x99, 0x3B, 0xF9, 0x0F, 0xEE, 0xD0, + 0xC5, 0xD1, 0x60, 0x75, 0x24, 0x56, 0x2D, 0x7C, + 0x09, 0xC0, 0xC2, 0x10, 0xED, 0x39, 0x3D, 0x7C + }, + { + 0x7A, 0x20, 0x54, 0x0C, 0xC0, 0x7B, 0xF7, 0x2B, + 0x58, 0x24, 0x21, 0xFC, 0x34, 0x2E, 0x82, 0xF5, + 0x21, 0x34, 0xB6, 0x98, 0x41, 0xEC, 0x28, 0xED, + 0x18, 0x9E, 0x2E, 0xA6, 0xA2, 0x9D, 0xD2, 0xF8, + 0x2A, 0x64, 0x03, 0x52, 0xD2, 0x22, 0xB5, 0x2F, + 0x29, 0x11, 0xDC, 0x72, 0xA7, 0xDA, 0xB3, 0x1C, + 0xAA, 0xDD, 0x80, 0xC6, 0x11, 0x8F, 0x13, 0xC5, + 0x6B, 0x2A, 0x1E, 0x43, 0x73, 0xBE, 0x0E, 0xA3 + }, + { + 0x48, 0x6F, 0x02, 0xC6, 0x3E, 0x54, 0x67, 0xEA, + 0x1F, 0xDD, 0xE7, 0xE8, 0x2B, 0xFA, 0xCC, 0x2C, + 0x1B, 0xA5, 0xD6, 0x36, 0xD9, 0xF3, 0xD0, 0x8B, + 0x21, 0x0D, 0xA3, 0xF3, 0x72, 0xF7, 0x06, 0xEC, + 0x21, 0x8C, 0xC1, 0x7F, 0xF6, 0x0A, 0xEF, 0x70, + 0x3B, 0xBE, 0x0C, 0x15, 0xC3, 0x8A, 0xE5, 0x5D, + 0x28, 0x6A, 0x68, 0x4F, 0x86, 0x4C, 0x78, 0x21, + 0x1C, 0xCA, 0xB4, 0x17, 0x8C, 0x92, 0xAD, 0xBA + }, + { + 0x1C, 0x7A, 0x5C, 0x1D, 0xED, 0xCD, 0x04, 0xA9, + 0x21, 0x78, 0x8F, 0x7E, 0xB2, 0x33, 0x61, 0xCA, + 0x19, 0x53, 0xB0, 0x4B, 0x9C, 0x7A, 0xEC, 0x35, + 0xD6, 0x5E, 0xA3, 0xE4, 0x99, 0x6D, 0xB2, 0x6F, + 0x28, 0x12, 0x78, 0xEA, 0x4A, 0xE6, 0x66, 0xAD, + 0x81, 0x02, 0x7D, 0x98, 0xAF, 0x57, 0x26, 0x2C, + 0xDB, 0xFA, 0x4C, 0x08, 0x5F, 0x42, 0x10, 0x56, + 0x8C, 0x7E, 0x15, 0xEE, 0xC7, 0x80, 0x51, 0x14 + }, + { + 0x9C, 0xE3, 0xFA, 0x9A, 0x86, 0x0B, 0xDB, 0xD5, + 0x37, 0x8F, 0xD6, 0xD7, 0xB8, 0xB6, 0x71, 0xC6, + 0xCB, 0x76, 0x92, 0x91, 0x0C, 0xE8, 0xF9, 0xB6, + 0xCB, 0x41, 0x22, 0xCB, 0xCB, 0xE6, 0xAC, 0x06, + 0xCA, 0x04, 0x22, 0xCE, 0xF1, 0x22, 0x59, 0x35, + 0x05, 0x3B, 0x7D, 0x19, 0x3A, 0x81, 0xB9, 0xE9, + 0x72, 0xEB, 0x85, 0xA1, 0xD3, 0x07, 0x4F, 0x14, + 0xCB, 0xB5, 0xEC, 0x9F, 0x05, 0x73, 0x89, 0x2D + }, + { + 0xA9, 0x11, 0x87, 0xBE, 0x5C, 0x37, 0x1C, 0x42, + 0x65, 0xC1, 0x74, 0xFD, 0x46, 0x53, 0xB8, 0xAB, + 0x70, 0x85, 0x51, 0xF8, 0x3D, 0x1F, 0xEE, 0x1C, + 0xC1, 0x47, 0x95, 0x81, 0xBC, 0x00, 0x6D, 0x6F, + 0xB7, 0x8F, 0xCC, 0x9A, 0x5D, 0xEE, 0x1D, 0xB3, + 0x66, 0x6F, 0x50, 0x8F, 0x97, 0x80, 0xA3, 0x75, + 0x93, 0xEB, 0xCC, 0xCF, 0x5F, 0xBE, 0xD3, 0x96, + 0x67, 0xDC, 0x63, 0x61, 0xE9, 0x21, 0xF7, 0x79 + }, + { + 0x46, 0x25, 0x76, 0x7D, 0x7B, 0x1D, 0x3D, 0x3E, + 0xD2, 0xFB, 0xC6, 0x74, 0xAF, 0x14, 0xE0, 0x24, + 0x41, 0x52, 0xF2, 0xA4, 0x02, 0x1F, 0xCF, 0x33, + 0x11, 0x50, 0x5D, 0x89, 0xBD, 0x81, 0xE2, 0xF9, + 0xF9, 0xA5, 0x00, 0xC3, 0xB1, 0x99, 0x91, 0x4D, + 0xB4, 0x95, 0x00, 0xB3, 0xC9, 0x8D, 0x03, 0xEA, + 0x93, 0x28, 0x67, 0x51, 0xA6, 0x86, 0xA3, 0xB8, + 0x75, 0xDA, 0xAB, 0x0C, 0xCD, 0x63, 0xB4, 0x4F + }, + { + 0x43, 0xDF, 0xDF, 0xE1, 0xB0, 0x14, 0xFE, 0xD3, + 0xA2, 0xAC, 0xAB, 0xB7, 0xF3, 0xE9, 0xA1, 0x82, + 0xF2, 0xAA, 0x18, 0x01, 0x9D, 0x27, 0xE3, 0xE6, + 0xCD, 0xCF, 0x31, 0xA1, 0x5B, 0x42, 0x8E, 0x91, + 0xE7, 0xB0, 0x8C, 0xF5, 0xE5, 0xC3, 0x76, 0xFC, + 0xE2, 0xD8, 0xA2, 0x8F, 0xF8, 0x5A, 0xB0, 0xA0, + 0xA1, 0x65, 0x6E, 0xDB, 0x4A, 0x0A, 0x91, 0x53, + 0x26, 0x20, 0x09, 0x6D, 0x9A, 0x5A, 0x65, 0x2D + }, + { + 0x27, 0x9E, 0x32, 0x02, 0xBE, 0x39, 0x89, 0xBA, + 0x31, 0x12, 0x77, 0x25, 0x85, 0x17, 0x74, 0x87, + 0xE4, 0xFE, 0x3E, 0xE3, 0xEA, 0xB4, 0x9C, 0x2F, + 0x7F, 0xA7, 0xFE, 0x87, 0xCF, 0xE7, 0xB8, 0x0D, + 0x3E, 0x03, 0x55, 0xED, 0xFF, 0x6D, 0x03, 0x1E, + 0x6C, 0x96, 0xC7, 0x95, 0xDB, 0x1C, 0x6F, 0x04, + 0x18, 0x80, 0xEC, 0x38, 0x24, 0xDE, 0xFA, 0xCF, + 0x92, 0x63, 0x82, 0x0A, 0x8E, 0x73, 0x27, 0xDE + }, + { + 0xEA, 0x2D, 0x06, 0x6A, 0xC2, 0x29, 0xD4, 0xD4, + 0xB6, 0x16, 0xA8, 0xBE, 0xDE, 0xC7, 0x34, 0x32, + 0x52, 0x24, 0xE4, 0xB4, 0xE5, 0x8F, 0x1A, 0xE6, + 0xDA, 0xD7, 0xE4, 0x0C, 0x2D, 0xA2, 0x91, 0x96, + 0xC3, 0xB1, 0xEA, 0x95, 0x71, 0xDA, 0xCC, 0x81, + 0xE8, 0x73, 0x28, 0xCA, 0xA0, 0x21, 0x1E, 0x09, + 0x02, 0x7B, 0x05, 0x24, 0xAA, 0x3F, 0x4A, 0x84, + 0x99, 0x17, 0xB3, 0x58, 0x67, 0x47, 0xEB, 0xBB + }, + { + 0x49, 0xF0, 0x14, 0xF5, 0xC6, 0x18, 0x22, 0xC8, + 0x99, 0xAB, 0x5C, 0xAE, 0x51, 0xBE, 0x40, 0x44, + 0xA4, 0x49, 0x5E, 0x77, 0x7D, 0xEB, 0x7D, 0xA9, + 0xB6, 0xD8, 0x49, 0x0E, 0xFB, 0xB8, 0x75, 0x30, + 0xAD, 0xF2, 0x93, 0xDA, 0xF0, 0x79, 0xF9, 0x4C, + 0x33, 0xB7, 0x04, 0x4E, 0xF6, 0x2E, 0x2E, 0x5B, + 0xB3, 0xEB, 0x11, 0xE1, 0x73, 0x04, 0xF8, 0x45, + 0x3E, 0xE6, 0xCE, 0x24, 0xF0, 0x33, 0xDD, 0xB0 + }, + { + 0x92, 0x33, 0x49, 0x03, 0x44, 0xE5, 0xB0, 0xDC, + 0x59, 0x12, 0x67, 0x1B, 0x7A, 0xE5, 0x4C, 0xEE, + 0x77, 0x30, 0xDB, 0xE1, 0xF4, 0xC7, 0xD9, 0x2A, + 0x4D, 0x3E, 0x3A, 0xAB, 0x50, 0x57, 0x17, 0x08, + 0xDB, 0x51, 0xDC, 0xF9, 0xC2, 0x94, 0x45, 0x91, + 0xDB, 0x65, 0x1D, 0xB3, 0x2D, 0x22, 0x93, 0x5B, + 0x86, 0x94, 0x49, 0x69, 0xBE, 0x77, 0xD5, 0xB5, + 0xFE, 0xAE, 0x6C, 0x38, 0x40, 0xA8, 0xDB, 0x26 + }, + { + 0xB6, 0xE7, 0x5E, 0x6F, 0x4C, 0x7F, 0x45, 0x3B, + 0x74, 0x65, 0xD2, 0x5B, 0x5A, 0xC8, 0xC7, 0x19, + 0x69, 0x02, 0xEA, 0xA9, 0x53, 0x87, 0x52, 0x28, + 0xC8, 0x63, 0x4E, 0x16, 0xE2, 0xAE, 0x1F, 0x38, + 0xBC, 0x32, 0x75, 0x30, 0x43, 0x35, 0xF5, 0x98, + 0x9E, 0xCC, 0xC1, 0xE3, 0x41, 0x67, 0xD4, 0xE6, + 0x8D, 0x77, 0x19, 0x96, 0x8F, 0xBA, 0x8E, 0x2F, + 0xE6, 0x79, 0x47, 0xC3, 0x5C, 0x48, 0xE8, 0x06 + }, + { + 0xCC, 0x14, 0xCA, 0x66, 0x5A, 0xF1, 0x48, 0x3E, + 0xFB, 0xC3, 0xAF, 0x80, 0x08, 0x0E, 0x65, 0x0D, + 0x50, 0x46, 0xA3, 0x93, 0x2F, 0x4F, 0x51, 0xF3, + 0xFE, 0x90, 0xA0, 0x70, 0x5E, 0xC2, 0x51, 0x04, + 0xAD, 0xF0, 0x78, 0x39, 0x26, 0x5D, 0xC5, 0x1D, + 0x43, 0x40, 0x14, 0x11, 0x24, 0x6E, 0x47, 0x4F, + 0x0D, 0x5E, 0x56, 0x37, 0xAF, 0x94, 0x76, 0x72, + 0x83, 0xD5, 0x3E, 0x06, 0x17, 0xE9, 0x81, 0xF4 + }, + { + 0x23, 0x0A, 0x1C, 0x85, 0x7C, 0xB2, 0xE7, 0x85, + 0x2E, 0x41, 0xB6, 0x47, 0xE9, 0x0E, 0x45, 0x85, + 0xD2, 0xD8, 0x81, 0xE1, 0x73, 0x4D, 0xC3, 0x89, + 0x55, 0x35, 0x6E, 0x8D, 0xD7, 0xBF, 0xF3, 0x90, + 0x53, 0x09, 0x2C, 0x6B, 0x38, 0xE2, 0x36, 0xE1, + 0x89, 0x95, 0x25, 0x64, 0x70, 0x73, 0xDD, 0xDF, + 0x68, 0x95, 0xD6, 0x42, 0x06, 0x32, 0x5E, 0x76, + 0x47, 0xF2, 0x75, 0x56, 0x7B, 0x25, 0x59, 0x09 + }, + { + 0xCB, 0xB6, 0x53, 0x21, 0xAC, 0x43, 0x6E, 0x2F, + 0xFD, 0xAB, 0x29, 0x36, 0x35, 0x9C, 0xE4, 0x90, + 0x23, 0xF7, 0xDE, 0xE7, 0x61, 0x4E, 0xF2, 0x8D, + 0x17, 0x3C, 0x3D, 0x27, 0xC5, 0xD1, 0xBF, 0xFA, + 0x51, 0x55, 0x3D, 0x43, 0x3F, 0x8E, 0xE3, 0xC9, + 0xE4, 0x9C, 0x05, 0xA2, 0xB8, 0x83, 0xCC, 0xE9, + 0x54, 0xC9, 0xA8, 0x09, 0x3B, 0x80, 0x61, 0x2A, + 0x0C, 0xDD, 0x47, 0x32, 0xE0, 0x41, 0xF9, 0x95 + }, + { + 0x3E, 0x7E, 0x57, 0x00, 0x74, 0x33, 0x72, 0x75, + 0xEF, 0xB5, 0x13, 0x15, 0x58, 0x80, 0x34, 0xC3, + 0xCF, 0x0D, 0xDD, 0xCA, 0x20, 0xB4, 0x61, 0x2E, + 0x0B, 0xD5, 0xB8, 0x81, 0xE7, 0xE5, 0x47, 0x6D, + 0x31, 0x9C, 0xE4, 0xFE, 0x9F, 0x19, 0x18, 0x6E, + 0x4C, 0x08, 0x26, 0xF4, 0x4F, 0x13, 0x1E, 0xB0, + 0x48, 0xE6, 0x5B, 0xE2, 0x42, 0xB1, 0x17, 0x2C, + 0x63, 0xBA, 0xDB, 0x12, 0x3A, 0xB0, 0xCB, 0xE8 + }, + { + 0xD3, 0x2E, 0x9E, 0xC0, 0x2D, 0x38, 0xD4, 0xE1, + 0xB8, 0x24, 0x9D, 0xF8, 0xDC, 0xB0, 0x0C, 0x5B, + 0x9C, 0x68, 0xEB, 0x89, 0x22, 0x67, 0x2E, 0x35, + 0x05, 0x39, 0x3B, 0x6A, 0x21, 0x0B, 0xA5, 0x6F, + 0x94, 0x96, 0xE5, 0xEE, 0x04, 0x90, 0xEF, 0x38, + 0x7C, 0x3C, 0xDE, 0xC0, 0x61, 0xF0, 0x6B, 0xC0, + 0x38, 0x2D, 0x93, 0x04, 0xCA, 0xFB, 0xB8, 0xE0, + 0xCD, 0x33, 0xD5, 0x70, 0x29, 0xE6, 0x2D, 0xF2 + }, + { + 0x8C, 0x15, 0x12, 0x46, 0x60, 0x89, 0xF0, 0x5B, + 0x37, 0x75, 0xC2, 0x62, 0xB6, 0x2D, 0x22, 0xB8, + 0x38, 0x54, 0xA8, 0x32, 0x18, 0x13, 0x0B, 0x4E, + 0xC9, 0x1B, 0x3C, 0xCB, 0xD2, 0x93, 0xD2, 0xA5, + 0x43, 0x02, 0xCE, 0xCA, 0xAB, 0x9B, 0x10, 0x0C, + 0x68, 0xD1, 0xE6, 0xDD, 0xC8, 0xF0, 0x7C, 0xDD, + 0xBD, 0xFE, 0x6F, 0xDA, 0xAA, 0xF0, 0x99, 0xCC, + 0x09, 0xD6, 0xB7, 0x25, 0x87, 0x9C, 0x63, 0x69 + }, + { + 0x91, 0xA7, 0xF6, 0x1C, 0x97, 0xC2, 0x91, 0x1E, + 0x4C, 0x81, 0x2E, 0xF7, 0x1D, 0x78, 0x0A, 0xD8, + 0xFA, 0x78, 0x87, 0x94, 0x56, 0x1D, 0x08, 0x30, + 0x3F, 0xD1, 0xC1, 0xCB, 0x60, 0x8A, 0x46, 0xA1, + 0x25, 0x63, 0x08, 0x6E, 0xC5, 0xB3, 0x9D, 0x47, + 0x1A, 0xED, 0x94, 0xFB, 0x0F, 0x6C, 0x67, 0x8A, + 0x43, 0xB8, 0x79, 0x29, 0x32, 0xF9, 0x02, 0x8D, + 0x77, 0x2A, 0x22, 0x76, 0x8E, 0xA2, 0x3A, 0x9B + }, + { + 0x4F, 0x6B, 0xB2, 0x22, 0xA3, 0x95, 0xE8, 0xB1, + 0x8F, 0x6B, 0xA1, 0x55, 0x47, 0x7A, 0xED, 0x3F, + 0x07, 0x29, 0xAC, 0x9E, 0x83, 0xE1, 0x6D, 0x31, + 0xA2, 0xA8, 0xBC, 0x65, 0x54, 0x22, 0xB8, 0x37, + 0xC8, 0x91, 0xC6, 0x19, 0x9E, 0x6F, 0x0D, 0x75, + 0x79, 0x9E, 0x3B, 0x69, 0x15, 0x25, 0xC5, 0x81, + 0x95, 0x35, 0x17, 0xF2, 0x52, 0xC4, 0xB9, 0xE3, + 0xA2, 0x7A, 0x28, 0xFB, 0xAF, 0x49, 0x64, 0x4C + }, + { + 0x5D, 0x06, 0xC0, 0x7E, 0x7A, 0x64, 0x6C, 0x41, + 0x3A, 0x50, 0x1C, 0x3F, 0x4B, 0xB2, 0xFC, 0x38, + 0x12, 0x7D, 0xE7, 0x50, 0x9B, 0x70, 0x77, 0xC4, + 0xD9, 0xB5, 0x61, 0x32, 0x01, 0xC1, 0xAA, 0x02, + 0xFD, 0x5F, 0x79, 0xD2, 0x74, 0x59, 0x15, 0xDD, + 0x57, 0xFB, 0xCB, 0x4C, 0xE0, 0x86, 0x95, 0xF6, + 0xEF, 0xC0, 0xCB, 0x3D, 0x2D, 0x33, 0x0E, 0x19, + 0xB4, 0xB0, 0xE6, 0x00, 0x4E, 0xA6, 0x47, 0x1E + }, + { + 0xB9, 0x67, 0x56, 0xE5, 0x79, 0x09, 0x96, 0x8F, + 0x14, 0xB7, 0x96, 0xA5, 0xD3, 0x0F, 0x4C, 0x9D, + 0x67, 0x14, 0x72, 0xCF, 0x82, 0xC8, 0xCF, 0xB2, + 0xCA, 0xCA, 0x7A, 0xC7, 0xA4, 0x4C, 0xA0, 0xA1, + 0x4C, 0x98, 0x42, 0xD0, 0x0C, 0x82, 0xE3, 0x37, + 0x50, 0x2C, 0x94, 0xD5, 0x96, 0x0A, 0xCA, 0x4C, + 0x49, 0x2E, 0xA7, 0xB0, 0xDF, 0x91, 0x9D, 0xDF, + 0x1A, 0xAD, 0xA2, 0xA2, 0x75, 0xBB, 0x10, 0xD4 + }, + { + 0xFF, 0x0A, 0x01, 0x5E, 0x98, 0xDB, 0x9C, 0x99, + 0xF0, 0x39, 0x77, 0x71, 0x0A, 0xAC, 0x3E, 0x65, + 0x8C, 0x0D, 0x89, 0x6F, 0x6D, 0x71, 0xD6, 0x18, + 0xBA, 0x79, 0xDC, 0x6C, 0xF7, 0x2A, 0xC7, 0x5B, + 0x7C, 0x03, 0x8E, 0xB6, 0x86, 0x2D, 0xED, 0xE4, + 0x54, 0x3E, 0x14, 0x54, 0x13, 0xA6, 0x36, 0x8D, + 0x69, 0xF5, 0x72, 0x2C, 0x82, 0x7B, 0xA3, 0xEF, + 0x25, 0xB6, 0xAE, 0x64, 0x40, 0xD3, 0x92, 0x76 + }, + { + 0x5B, 0x21, 0xC5, 0xFD, 0x88, 0x68, 0x36, 0x76, + 0x12, 0x47, 0x4F, 0xA2, 0xE7, 0x0E, 0x9C, 0xFA, + 0x22, 0x01, 0xFF, 0xEE, 0xE8, 0xFA, 0xFA, 0xB5, + 0x79, 0x7A, 0xD5, 0x8F, 0xEF, 0xA1, 0x7C, 0x9B, + 0x5B, 0x10, 0x7D, 0xA4, 0xA3, 0xDB, 0x63, 0x20, + 0xBA, 0xAF, 0x2C, 0x86, 0x17, 0xD5, 0xA5, 0x1D, + 0xF9, 0x14, 0xAE, 0x88, 0xDA, 0x38, 0x67, 0xC2, + 0xD4, 0x1F, 0x0C, 0xC1, 0x4F, 0xA6, 0x79, 0x28 + }, +}; + + + + +static const uint8_t blake2b_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0x10, 0xEB, 0xB6, 0x77, 0x00, 0xB1, 0x86, 0x8E, + 0xFB, 0x44, 0x17, 0x98, 0x7A, 0xCF, 0x46, 0x90, + 0xAE, 0x9D, 0x97, 0x2F, 0xB7, 0xA5, 0x90, 0xC2, + 0xF0, 0x28, 0x71, 0x79, 0x9A, 0xAA, 0x47, 0x86, + 0xB5, 0xE9, 0x96, 0xE8, 0xF0, 0xF4, 0xEB, 0x98, + 0x1F, 0xC2, 0x14, 0xB0, 0x05, 0xF4, 0x2D, 0x2F, + 0xF4, 0x23, 0x34, 0x99, 0x39, 0x16, 0x53, 0xDF, + 0x7A, 0xEF, 0xCB, 0xC1, 0x3F, 0xC5, 0x15, 0x68 + }, + { + 0x96, 0x1F, 0x6D, 0xD1, 0xE4, 0xDD, 0x30, 0xF6, + 0x39, 0x01, 0x69, 0x0C, 0x51, 0x2E, 0x78, 0xE4, + 0xB4, 0x5E, 0x47, 0x42, 0xED, 0x19, 0x7C, 0x3C, + 0x5E, 0x45, 0xC5, 0x49, 0xFD, 0x25, 0xF2, 0xE4, + 0x18, 0x7B, 0x0B, 0xC9, 0xFE, 0x30, 0x49, 0x2B, + 0x16, 0xB0, 0xD0, 0xBC, 0x4E, 0xF9, 0xB0, 0xF3, + 0x4C, 0x70, 0x03, 0xFA, 0xC0, 0x9A, 0x5E, 0xF1, + 0x53, 0x2E, 0x69, 0x43, 0x02, 0x34, 0xCE, 0xBD + }, + { + 0xDA, 0x2C, 0xFB, 0xE2, 0xD8, 0x40, 0x9A, 0x0F, + 0x38, 0x02, 0x61, 0x13, 0x88, 0x4F, 0x84, 0xB5, + 0x01, 0x56, 0x37, 0x1A, 0xE3, 0x04, 0xC4, 0x43, + 0x01, 0x73, 0xD0, 0x8A, 0x99, 0xD9, 0xFB, 0x1B, + 0x98, 0x31, 0x64, 0xA3, 0x77, 0x07, 0x06, 0xD5, + 0x37, 0xF4, 0x9E, 0x0C, 0x91, 0x6D, 0x9F, 0x32, + 0xB9, 0x5C, 0xC3, 0x7A, 0x95, 0xB9, 0x9D, 0x85, + 0x74, 0x36, 0xF0, 0x23, 0x2C, 0x88, 0xA9, 0x65 + }, + { + 0x33, 0xD0, 0x82, 0x5D, 0xDD, 0xF7, 0xAD, 0xA9, + 0x9B, 0x0E, 0x7E, 0x30, 0x71, 0x04, 0xAD, 0x07, + 0xCA, 0x9C, 0xFD, 0x96, 0x92, 0x21, 0x4F, 0x15, + 0x61, 0x35, 0x63, 0x15, 0xE7, 0x84, 0xF3, 0xE5, + 0xA1, 0x7E, 0x36, 0x4A, 0xE9, 0xDB, 0xB1, 0x4C, + 0xB2, 0x03, 0x6D, 0xF9, 0x32, 0xB7, 0x7F, 0x4B, + 0x29, 0x27, 0x61, 0x36, 0x5F, 0xB3, 0x28, 0xDE, + 0x7A, 0xFD, 0xC6, 0xD8, 0x99, 0x8F, 0x5F, 0xC1 + }, + { + 0xBE, 0xAA, 0x5A, 0x3D, 0x08, 0xF3, 0x80, 0x71, + 0x43, 0xCF, 0x62, 0x1D, 0x95, 0xCD, 0x69, 0x05, + 0x14, 0xD0, 0xB4, 0x9E, 0xFF, 0xF9, 0xC9, 0x1D, + 0x24, 0xB5, 0x92, 0x41, 0xEC, 0x0E, 0xEF, 0xA5, + 0xF6, 0x01, 0x96, 0xD4, 0x07, 0x04, 0x8B, 0xBA, + 0x8D, 0x21, 0x46, 0x82, 0x8E, 0xBC, 0xB0, 0x48, + 0x8D, 0x88, 0x42, 0xFD, 0x56, 0xBB, 0x4F, 0x6D, + 0xF8, 0xE1, 0x9C, 0x4B, 0x4D, 0xAA, 0xB8, 0xAC + }, + { + 0x09, 0x80, 0x84, 0xB5, 0x1F, 0xD1, 0x3D, 0xEA, + 0xE5, 0xF4, 0x32, 0x0D, 0xE9, 0x4A, 0x68, 0x8E, + 0xE0, 0x7B, 0xAE, 0xA2, 0x80, 0x04, 0x86, 0x68, + 0x9A, 0x86, 0x36, 0x11, 0x7B, 0x46, 0xC1, 0xF4, + 0xC1, 0xF6, 0xAF, 0x7F, 0x74, 0xAE, 0x7C, 0x85, + 0x76, 0x00, 0x45, 0x6A, 0x58, 0xA3, 0xAF, 0x25, + 0x1D, 0xC4, 0x72, 0x3A, 0x64, 0xCC, 0x7C, 0x0A, + 0x5A, 0xB6, 0xD9, 0xCA, 0xC9, 0x1C, 0x20, 0xBB + }, + { + 0x60, 0x44, 0x54, 0x0D, 0x56, 0x08, 0x53, 0xEB, + 0x1C, 0x57, 0xDF, 0x00, 0x77, 0xDD, 0x38, 0x10, + 0x94, 0x78, 0x1C, 0xDB, 0x90, 0x73, 0xE5, 0xB1, + 0xB3, 0xD3, 0xF6, 0xC7, 0x82, 0x9E, 0x12, 0x06, + 0x6B, 0xBA, 0xCA, 0x96, 0xD9, 0x89, 0xA6, 0x90, + 0xDE, 0x72, 0xCA, 0x31, 0x33, 0xA8, 0x36, 0x52, + 0xBA, 0x28, 0x4A, 0x6D, 0x62, 0x94, 0x2B, 0x27, + 0x1F, 0xFA, 0x26, 0x20, 0xC9, 0xE7, 0x5B, 0x1F + }, + { + 0x7A, 0x8C, 0xFE, 0x9B, 0x90, 0xF7, 0x5F, 0x7E, + 0xCB, 0x3A, 0xCC, 0x05, 0x3A, 0xAE, 0xD6, 0x19, + 0x31, 0x12, 0xB6, 0xF6, 0xA4, 0xAE, 0xEB, 0x3F, + 0x65, 0xD3, 0xDE, 0x54, 0x19, 0x42, 0xDE, 0xB9, + 0xE2, 0x22, 0x81, 0x52, 0xA3, 0xC4, 0xBB, 0xBE, + 0x72, 0xFC, 0x3B, 0x12, 0x62, 0x95, 0x28, 0xCF, + 0xBB, 0x09, 0xFE, 0x63, 0x0F, 0x04, 0x74, 0x33, + 0x9F, 0x54, 0xAB, 0xF4, 0x53, 0xE2, 0xED, 0x52 + }, + { + 0x38, 0x0B, 0xEA, 0xF6, 0xEA, 0x7C, 0xC9, 0x36, + 0x5E, 0x27, 0x0E, 0xF0, 0xE6, 0xF3, 0xA6, 0x4F, + 0xB9, 0x02, 0xAC, 0xAE, 0x51, 0xDD, 0x55, 0x12, + 0xF8, 0x42, 0x59, 0xAD, 0x2C, 0x91, 0xF4, 0xBC, + 0x41, 0x08, 0xDB, 0x73, 0x19, 0x2A, 0x5B, 0xBF, + 0xB0, 0xCB, 0xCF, 0x71, 0xE4, 0x6C, 0x3E, 0x21, + 0xAE, 0xE1, 0xC5, 0xE8, 0x60, 0xDC, 0x96, 0xE8, + 0xEB, 0x0B, 0x7B, 0x84, 0x26, 0xE6, 0xAB, 0xE9 + }, + { + 0x60, 0xFE, 0x3C, 0x45, 0x35, 0xE1, 0xB5, 0x9D, + 0x9A, 0x61, 0xEA, 0x85, 0x00, 0xBF, 0xAC, 0x41, + 0xA6, 0x9D, 0xFF, 0xB1, 0xCE, 0xAD, 0xD9, 0xAC, + 0xA3, 0x23, 0xE9, 0xA6, 0x25, 0xB6, 0x4D, 0xA5, + 0x76, 0x3B, 0xAD, 0x72, 0x26, 0xDA, 0x02, 0xB9, + 0xC8, 0xC4, 0xF1, 0xA5, 0xDE, 0x14, 0x0A, 0xC5, + 0xA6, 0xC1, 0x12, 0x4E, 0x4F, 0x71, 0x8C, 0xE0, + 0xB2, 0x8E, 0xA4, 0x73, 0x93, 0xAA, 0x66, 0x37 + }, + { + 0x4F, 0xE1, 0x81, 0xF5, 0x4A, 0xD6, 0x3A, 0x29, + 0x83, 0xFE, 0xAA, 0xF7, 0x7D, 0x1E, 0x72, 0x35, + 0xC2, 0xBE, 0xB1, 0x7F, 0xA3, 0x28, 0xB6, 0xD9, + 0x50, 0x5B, 0xDA, 0x32, 0x7D, 0xF1, 0x9F, 0xC3, + 0x7F, 0x02, 0xC4, 0xB6, 0xF0, 0x36, 0x8C, 0xE2, + 0x31, 0x47, 0x31, 0x3A, 0x8E, 0x57, 0x38, 0xB5, + 0xFA, 0x2A, 0x95, 0xB2, 0x9D, 0xE1, 0xC7, 0xF8, + 0x26, 0x4E, 0xB7, 0x7B, 0x69, 0xF5, 0x85, 0xCD + }, + { + 0xF2, 0x28, 0x77, 0x3C, 0xE3, 0xF3, 0xA4, 0x2B, + 0x5F, 0x14, 0x4D, 0x63, 0x23, 0x7A, 0x72, 0xD9, + 0x96, 0x93, 0xAD, 0xB8, 0x83, 0x7D, 0x0E, 0x11, + 0x2A, 0x8A, 0x0F, 0x8F, 0xFF, 0xF2, 0xC3, 0x62, + 0x85, 0x7A, 0xC4, 0x9C, 0x11, 0xEC, 0x74, 0x0D, + 0x15, 0x00, 0x74, 0x9D, 0xAC, 0x9B, 0x1F, 0x45, + 0x48, 0x10, 0x8B, 0xF3, 0x15, 0x57, 0x94, 0xDC, + 0xC9, 0xE4, 0x08, 0x28, 0x49, 0xE2, 0xB8, 0x5B + }, + { + 0x96, 0x24, 0x52, 0xA8, 0x45, 0x5C, 0xC5, 0x6C, + 0x85, 0x11, 0x31, 0x7E, 0x3B, 0x1F, 0x3B, 0x2C, + 0x37, 0xDF, 0x75, 0xF5, 0x88, 0xE9, 0x43, 0x25, + 0xFD, 0xD7, 0x70, 0x70, 0x35, 0x9C, 0xF6, 0x3A, + 0x9A, 0xE6, 0xE9, 0x30, 0x93, 0x6F, 0xDF, 0x8E, + 0x1E, 0x08, 0xFF, 0xCA, 0x44, 0x0C, 0xFB, 0x72, + 0xC2, 0x8F, 0x06, 0xD8, 0x9A, 0x21, 0x51, 0xD1, + 0xC4, 0x6C, 0xD5, 0xB2, 0x68, 0xEF, 0x85, 0x63 + }, + { + 0x43, 0xD4, 0x4B, 0xFA, 0x18, 0x76, 0x8C, 0x59, + 0x89, 0x6B, 0xF7, 0xED, 0x17, 0x65, 0xCB, 0x2D, + 0x14, 0xAF, 0x8C, 0x26, 0x02, 0x66, 0x03, 0x90, + 0x99, 0xB2, 0x5A, 0x60, 0x3E, 0x4D, 0xDC, 0x50, + 0x39, 0xD6, 0xEF, 0x3A, 0x91, 0x84, 0x7D, 0x10, + 0x88, 0xD4, 0x01, 0xC0, 0xC7, 0xE8, 0x47, 0x78, + 0x1A, 0x8A, 0x59, 0x0D, 0x33, 0xA3, 0xC6, 0xCB, + 0x4D, 0xF0, 0xFA, 0xB1, 0xC2, 0xF2, 0x23, 0x55 + }, + { + 0xDC, 0xFF, 0xA9, 0xD5, 0x8C, 0x2A, 0x4C, 0xA2, + 0xCD, 0xBB, 0x0C, 0x7A, 0xA4, 0xC4, 0xC1, 0xD4, + 0x51, 0x65, 0x19, 0x00, 0x89, 0xF4, 0xE9, 0x83, + 0xBB, 0x1C, 0x2C, 0xAB, 0x4A, 0xAE, 0xFF, 0x1F, + 0xA2, 0xB5, 0xEE, 0x51, 0x6F, 0xEC, 0xD7, 0x80, + 0x54, 0x02, 0x40, 0xBF, 0x37, 0xE5, 0x6C, 0x8B, + 0xCC, 0xA7, 0xFA, 0xB9, 0x80, 0xE1, 0xE6, 0x1C, + 0x94, 0x00, 0xD8, 0xA9, 0xA5, 0xB1, 0x4A, 0xC6 + }, + { + 0x6F, 0xBF, 0x31, 0xB4, 0x5A, 0xB0, 0xC0, 0xB8, + 0xDA, 0xD1, 0xC0, 0xF5, 0xF4, 0x06, 0x13, 0x79, + 0x91, 0x2D, 0xDE, 0x5A, 0xA9, 0x22, 0x09, 0x9A, + 0x03, 0x0B, 0x72, 0x5C, 0x73, 0x34, 0x6C, 0x52, + 0x42, 0x91, 0xAD, 0xEF, 0x89, 0xD2, 0xF6, 0xFD, + 0x8D, 0xFC, 0xDA, 0x6D, 0x07, 0xDA, 0xD8, 0x11, + 0xA9, 0x31, 0x45, 0x36, 0xC2, 0x91, 0x5E, 0xD4, + 0x5D, 0xA3, 0x49, 0x47, 0xE8, 0x3D, 0xE3, 0x4E + }, + { + 0xA0, 0xC6, 0x5B, 0xDD, 0xDE, 0x8A, 0xDE, 0xF5, + 0x72, 0x82, 0xB0, 0x4B, 0x11, 0xE7, 0xBC, 0x8A, + 0xAB, 0x10, 0x5B, 0x99, 0x23, 0x1B, 0x75, 0x0C, + 0x02, 0x1F, 0x4A, 0x73, 0x5C, 0xB1, 0xBC, 0xFA, + 0xB8, 0x75, 0x53, 0xBB, 0xA3, 0xAB, 0xB0, 0xC3, + 0xE6, 0x4A, 0x0B, 0x69, 0x55, 0x28, 0x51, 0x85, + 0xA0, 0xBD, 0x35, 0xFB, 0x8C, 0xFD, 0xE5, 0x57, + 0x32, 0x9B, 0xEB, 0xB1, 0xF6, 0x29, 0xEE, 0x93 + }, + { + 0xF9, 0x9D, 0x81, 0x55, 0x50, 0x55, 0x8E, 0x81, + 0xEC, 0xA2, 0xF9, 0x67, 0x18, 0xAE, 0xD1, 0x0D, + 0x86, 0xF3, 0xF1, 0xCF, 0xB6, 0x75, 0xCC, 0xE0, + 0x6B, 0x0E, 0xFF, 0x02, 0xF6, 0x17, 0xC5, 0xA4, + 0x2C, 0x5A, 0xA7, 0x60, 0x27, 0x0F, 0x26, 0x79, + 0xDA, 0x26, 0x77, 0xC5, 0xAE, 0xB9, 0x4F, 0x11, + 0x42, 0x27, 0x7F, 0x21, 0xC7, 0xF7, 0x9F, 0x3C, + 0x4F, 0x0C, 0xCE, 0x4E, 0xD8, 0xEE, 0x62, 0xB1 + }, + { + 0x95, 0x39, 0x1D, 0xA8, 0xFC, 0x7B, 0x91, 0x7A, + 0x20, 0x44, 0xB3, 0xD6, 0xF5, 0x37, 0x4E, 0x1C, + 0xA0, 0x72, 0xB4, 0x14, 0x54, 0xD5, 0x72, 0xC7, + 0x35, 0x6C, 0x05, 0xFD, 0x4B, 0xC1, 0xE0, 0xF4, + 0x0B, 0x8B, 0xB8, 0xB4, 0xA9, 0xF6, 0xBC, 0xE9, + 0xBE, 0x2C, 0x46, 0x23, 0xC3, 0x99, 0xB0, 0xDC, + 0xA0, 0xDA, 0xB0, 0x5C, 0xB7, 0x28, 0x1B, 0x71, + 0xA2, 0x1B, 0x0E, 0xBC, 0xD9, 0xE5, 0x56, 0x70 + }, + { + 0x04, 0xB9, 0xCD, 0x3D, 0x20, 0xD2, 0x21, 0xC0, + 0x9A, 0xC8, 0x69, 0x13, 0xD3, 0xDC, 0x63, 0x04, + 0x19, 0x89, 0xA9, 0xA1, 0xE6, 0x94, 0xF1, 0xE6, + 0x39, 0xA3, 0xBA, 0x7E, 0x45, 0x18, 0x40, 0xF7, + 0x50, 0xC2, 0xFC, 0x19, 0x1D, 0x56, 0xAD, 0x61, + 0xF2, 0xE7, 0x93, 0x6B, 0xC0, 0xAC, 0x8E, 0x09, + 0x4B, 0x60, 0xCA, 0xEE, 0xD8, 0x78, 0xC1, 0x87, + 0x99, 0x04, 0x54, 0x02, 0xD6, 0x1C, 0xEA, 0xF9 + }, + { + 0xEC, 0x0E, 0x0E, 0xF7, 0x07, 0xE4, 0xED, 0x6C, + 0x0C, 0x66, 0xF9, 0xE0, 0x89, 0xE4, 0x95, 0x4B, + 0x05, 0x80, 0x30, 0xD2, 0xDD, 0x86, 0x39, 0x8F, + 0xE8, 0x40, 0x59, 0x63, 0x1F, 0x9E, 0xE5, 0x91, + 0xD9, 0xD7, 0x73, 0x75, 0x35, 0x51, 0x49, 0x17, + 0x8C, 0x0C, 0xF8, 0xF8, 0xE7, 0xC4, 0x9E, 0xD2, + 0xA5, 0xE4, 0xF9, 0x54, 0x88, 0xA2, 0x24, 0x70, + 0x67, 0xC2, 0x08, 0x51, 0x0F, 0xAD, 0xC4, 0x4C + }, + { + 0x9A, 0x37, 0xCC, 0xE2, 0x73, 0xB7, 0x9C, 0x09, + 0x91, 0x36, 0x77, 0x51, 0x0E, 0xAF, 0x76, 0x88, + 0xE8, 0x9B, 0x33, 0x14, 0xD3, 0x53, 0x2F, 0xD2, + 0x76, 0x4C, 0x39, 0xDE, 0x02, 0x2A, 0x29, 0x45, + 0xB5, 0x71, 0x0D, 0x13, 0x51, 0x7A, 0xF8, 0xDD, + 0xC0, 0x31, 0x66, 0x24, 0xE7, 0x3B, 0xEC, 0x1C, + 0xE6, 0x7D, 0xF1, 0x52, 0x28, 0x30, 0x20, 0x36, + 0xF3, 0x30, 0xAB, 0x0C, 0xB4, 0xD2, 0x18, 0xDD + }, + { + 0x4C, 0xF9, 0xBB, 0x8F, 0xB3, 0xD4, 0xDE, 0x8B, + 0x38, 0xB2, 0xF2, 0x62, 0xD3, 0xC4, 0x0F, 0x46, + 0xDF, 0xE7, 0x47, 0xE8, 0xFC, 0x0A, 0x41, 0x4C, + 0x19, 0x3D, 0x9F, 0xCF, 0x75, 0x31, 0x06, 0xCE, + 0x47, 0xA1, 0x8F, 0x17, 0x2F, 0x12, 0xE8, 0xA2, + 0xF1, 0xC2, 0x67, 0x26, 0x54, 0x53, 0x58, 0xE5, + 0xEE, 0x28, 0xC9, 0xE2, 0x21, 0x3A, 0x87, 0x87, + 0xAA, 0xFB, 0xC5, 0x16, 0xD2, 0x34, 0x31, 0x52 + }, + { + 0x64, 0xE0, 0xC6, 0x3A, 0xF9, 0xC8, 0x08, 0xFD, + 0x89, 0x31, 0x37, 0x12, 0x98, 0x67, 0xFD, 0x91, + 0x93, 0x9D, 0x53, 0xF2, 0xAF, 0x04, 0xBE, 0x4F, + 0xA2, 0x68, 0x00, 0x61, 0x00, 0x06, 0x9B, 0x2D, + 0x69, 0xDA, 0xA5, 0xC5, 0xD8, 0xED, 0x7F, 0xDD, + 0xCB, 0x2A, 0x70, 0xEE, 0xEC, 0xDF, 0x2B, 0x10, + 0x5D, 0xD4, 0x6A, 0x1E, 0x3B, 0x73, 0x11, 0x72, + 0x8F, 0x63, 0x9A, 0xB4, 0x89, 0x32, 0x6B, 0xC9 + }, + { + 0x5E, 0x9C, 0x93, 0x15, 0x8D, 0x65, 0x9B, 0x2D, + 0xEF, 0x06, 0xB0, 0xC3, 0xC7, 0x56, 0x50, 0x45, + 0x54, 0x26, 0x62, 0xD6, 0xEE, 0xE8, 0xA9, 0x6A, + 0x89, 0xB7, 0x8A, 0xDE, 0x09, 0xFE, 0x8B, 0x3D, + 0xCC, 0x09, 0x6D, 0x4F, 0xE4, 0x88, 0x15, 0xD8, + 0x8D, 0x8F, 0x82, 0x62, 0x01, 0x56, 0x60, 0x2A, + 0xF5, 0x41, 0x95, 0x5E, 0x1F, 0x6C, 0xA3, 0x0D, + 0xCE, 0x14, 0xE2, 0x54, 0xC3, 0x26, 0xB8, 0x8F + }, + { + 0x77, 0x75, 0xDF, 0xF8, 0x89, 0x45, 0x8D, 0xD1, + 0x1A, 0xEF, 0x41, 0x72, 0x76, 0x85, 0x3E, 0x21, + 0x33, 0x5E, 0xB8, 0x8E, 0x4D, 0xEC, 0x9C, 0xFB, + 0x4E, 0x9E, 0xDB, 0x49, 0x82, 0x00, 0x88, 0x55, + 0x1A, 0x2C, 0xA6, 0x03, 0x39, 0xF1, 0x20, 0x66, + 0x10, 0x11, 0x69, 0xF0, 0xDF, 0xE8, 0x4B, 0x09, + 0x8F, 0xDD, 0xB1, 0x48, 0xD9, 0xDA, 0x6B, 0x3D, + 0x61, 0x3D, 0xF2, 0x63, 0x88, 0x9A, 0xD6, 0x4B + }, + { + 0xF0, 0xD2, 0x80, 0x5A, 0xFB, 0xB9, 0x1F, 0x74, + 0x39, 0x51, 0x35, 0x1A, 0x6D, 0x02, 0x4F, 0x93, + 0x53, 0xA2, 0x3C, 0x7C, 0xE1, 0xFC, 0x2B, 0x05, + 0x1B, 0x3A, 0x8B, 0x96, 0x8C, 0x23, 0x3F, 0x46, + 0xF5, 0x0F, 0x80, 0x6E, 0xCB, 0x15, 0x68, 0xFF, + 0xAA, 0x0B, 0x60, 0x66, 0x1E, 0x33, 0x4B, 0x21, + 0xDD, 0xE0, 0x4F, 0x8F, 0xA1, 0x55, 0xAC, 0x74, + 0x0E, 0xEB, 0x42, 0xE2, 0x0B, 0x60, 0xD7, 0x64 + }, + { + 0x86, 0xA2, 0xAF, 0x31, 0x6E, 0x7D, 0x77, 0x54, + 0x20, 0x1B, 0x94, 0x2E, 0x27, 0x53, 0x64, 0xAC, + 0x12, 0xEA, 0x89, 0x62, 0xAB, 0x5B, 0xD8, 0xD7, + 0xFB, 0x27, 0x6D, 0xC5, 0xFB, 0xFF, 0xC8, 0xF9, + 0xA2, 0x8C, 0xAE, 0x4E, 0x48, 0x67, 0xDF, 0x67, + 0x80, 0xD9, 0xB7, 0x25, 0x24, 0x16, 0x09, 0x27, + 0xC8, 0x55, 0xDA, 0x5B, 0x60, 0x78, 0xE0, 0xB5, + 0x54, 0xAA, 0x91, 0xE3, 0x1C, 0xB9, 0xCA, 0x1D + }, + { + 0x10, 0xBD, 0xF0, 0xCA, 0xA0, 0x80, 0x27, 0x05, + 0xE7, 0x06, 0x36, 0x9B, 0xAF, 0x8A, 0x3F, 0x79, + 0xD7, 0x2C, 0x0A, 0x03, 0xA8, 0x06, 0x75, 0xA7, + 0xBB, 0xB0, 0x0B, 0xE3, 0xA4, 0x5E, 0x51, 0x64, + 0x24, 0xD1, 0xEE, 0x88, 0xEF, 0xB5, 0x6F, 0x6D, + 0x57, 0x77, 0x54, 0x5A, 0xE6, 0xE2, 0x77, 0x65, + 0xC3, 0xA8, 0xF5, 0xE4, 0x93, 0xFC, 0x30, 0x89, + 0x15, 0x63, 0x89, 0x33, 0xA1, 0xDF, 0xEE, 0x55 + }, + { + 0xB0, 0x17, 0x81, 0x09, 0x2B, 0x17, 0x48, 0x45, + 0x9E, 0x2E, 0x4E, 0xC1, 0x78, 0x69, 0x66, 0x27, + 0xBF, 0x4E, 0xBA, 0xFE, 0xBB, 0xA7, 0x74, 0xEC, + 0xF0, 0x18, 0xB7, 0x9A, 0x68, 0xAE, 0xB8, 0x49, + 0x17, 0xBF, 0x0B, 0x84, 0xBB, 0x79, 0xD1, 0x7B, + 0x74, 0x31, 0x51, 0x14, 0x4C, 0xD6, 0x6B, 0x7B, + 0x33, 0xA4, 0xB9, 0xE5, 0x2C, 0x76, 0xC4, 0xE1, + 0x12, 0x05, 0x0F, 0xF5, 0x38, 0x5B, 0x7F, 0x0B + }, + { + 0xC6, 0xDB, 0xC6, 0x1D, 0xEC, 0x6E, 0xAE, 0xAC, + 0x81, 0xE3, 0xD5, 0xF7, 0x55, 0x20, 0x3C, 0x8E, + 0x22, 0x05, 0x51, 0x53, 0x4A, 0x0B, 0x2F, 0xD1, + 0x05, 0xA9, 0x18, 0x89, 0x94, 0x5A, 0x63, 0x85, + 0x50, 0x20, 0x4F, 0x44, 0x09, 0x3D, 0xD9, 0x98, + 0xC0, 0x76, 0x20, 0x5D, 0xFF, 0xAD, 0x70, 0x3A, + 0x0E, 0x5C, 0xD3, 0xC7, 0xF4, 0x38, 0xA7, 0xE6, + 0x34, 0xCD, 0x59, 0xFE, 0xDE, 0xDB, 0x53, 0x9E + }, + { + 0xEB, 0xA5, 0x1A, 0xCF, 0xFB, 0x4C, 0xEA, 0x31, + 0xDB, 0x4B, 0x8D, 0x87, 0xE9, 0xBF, 0x7D, 0xD4, + 0x8F, 0xE9, 0x7B, 0x02, 0x53, 0xAE, 0x67, 0xAA, + 0x58, 0x0F, 0x9A, 0xC4, 0xA9, 0xD9, 0x41, 0xF2, + 0xBE, 0xA5, 0x18, 0xEE, 0x28, 0x68, 0x18, 0xCC, + 0x9F, 0x63, 0x3F, 0x2A, 0x3B, 0x9F, 0xB6, 0x8E, + 0x59, 0x4B, 0x48, 0xCD, 0xD6, 0xD5, 0x15, 0xBF, + 0x1D, 0x52, 0xBA, 0x6C, 0x85, 0xA2, 0x03, 0xA7 + }, + { + 0x86, 0x22, 0x1F, 0x3A, 0xDA, 0x52, 0x03, 0x7B, + 0x72, 0x22, 0x4F, 0x10, 0x5D, 0x79, 0x99, 0x23, + 0x1C, 0x5E, 0x55, 0x34, 0xD0, 0x3D, 0xA9, 0xD9, + 0xC0, 0xA1, 0x2A, 0xCB, 0x68, 0x46, 0x0C, 0xD3, + 0x75, 0xDA, 0xF8, 0xE2, 0x43, 0x86, 0x28, 0x6F, + 0x96, 0x68, 0xF7, 0x23, 0x26, 0xDB, 0xF9, 0x9B, + 0xA0, 0x94, 0x39, 0x24, 0x37, 0xD3, 0x98, 0xE9, + 0x5B, 0xB8, 0x16, 0x1D, 0x71, 0x7F, 0x89, 0x91 + }, + { + 0x55, 0x95, 0xE0, 0x5C, 0x13, 0xA7, 0xEC, 0x4D, + 0xC8, 0xF4, 0x1F, 0xB7, 0x0C, 0xB5, 0x0A, 0x71, + 0xBC, 0xE1, 0x7C, 0x02, 0x4F, 0xF6, 0xDE, 0x7A, + 0xF6, 0x18, 0xD0, 0xCC, 0x4E, 0x9C, 0x32, 0xD9, + 0x57, 0x0D, 0x6D, 0x3E, 0xA4, 0x5B, 0x86, 0x52, + 0x54, 0x91, 0x03, 0x0C, 0x0D, 0x8F, 0x2B, 0x18, + 0x36, 0xD5, 0x77, 0x8C, 0x1C, 0xE7, 0x35, 0xC1, + 0x77, 0x07, 0xDF, 0x36, 0x4D, 0x05, 0x43, 0x47 + }, + { + 0xCE, 0x0F, 0x4F, 0x6A, 0xCA, 0x89, 0x59, 0x0A, + 0x37, 0xFE, 0x03, 0x4D, 0xD7, 0x4D, 0xD5, 0xFA, + 0x65, 0xEB, 0x1C, 0xBD, 0x0A, 0x41, 0x50, 0x8A, + 0xAD, 0xDC, 0x09, 0x35, 0x1A, 0x3C, 0xEA, 0x6D, + 0x18, 0xCB, 0x21, 0x89, 0xC5, 0x4B, 0x70, 0x0C, + 0x00, 0x9F, 0x4C, 0xBF, 0x05, 0x21, 0xC7, 0xEA, + 0x01, 0xBE, 0x61, 0xC5, 0xAE, 0x09, 0xCB, 0x54, + 0xF2, 0x7B, 0xC1, 0xB4, 0x4D, 0x65, 0x8C, 0x82 + }, + { + 0x7E, 0xE8, 0x0B, 0x06, 0xA2, 0x15, 0xA3, 0xBC, + 0xA9, 0x70, 0xC7, 0x7C, 0xDA, 0x87, 0x61, 0x82, + 0x2B, 0xC1, 0x03, 0xD4, 0x4F, 0xA4, 0xB3, 0x3F, + 0x4D, 0x07, 0xDC, 0xB9, 0x97, 0xE3, 0x6D, 0x55, + 0x29, 0x8B, 0xCE, 0xAE, 0x12, 0x24, 0x1B, 0x3F, + 0xA0, 0x7F, 0xA6, 0x3B, 0xE5, 0x57, 0x60, 0x68, + 0xDA, 0x38, 0x7B, 0x8D, 0x58, 0x59, 0xAE, 0xAB, + 0x70, 0x13, 0x69, 0x84, 0x8B, 0x17, 0x6D, 0x42 + }, + { + 0x94, 0x0A, 0x84, 0xB6, 0xA8, 0x4D, 0x10, 0x9A, + 0xAB, 0x20, 0x8C, 0x02, 0x4C, 0x6C, 0xE9, 0x64, + 0x76, 0x76, 0xBA, 0x0A, 0xAA, 0x11, 0xF8, 0x6D, + 0xBB, 0x70, 0x18, 0xF9, 0xFD, 0x22, 0x20, 0xA6, + 0xD9, 0x01, 0xA9, 0x02, 0x7F, 0x9A, 0xBC, 0xF9, + 0x35, 0x37, 0x27, 0x27, 0xCB, 0xF0, 0x9E, 0xBD, + 0x61, 0xA2, 0xA2, 0xEE, 0xB8, 0x76, 0x53, 0xE8, + 0xEC, 0xAD, 0x1B, 0xAB, 0x85, 0xDC, 0x83, 0x27 + }, + { + 0x20, 0x20, 0xB7, 0x82, 0x64, 0xA8, 0x2D, 0x9F, + 0x41, 0x51, 0x14, 0x1A, 0xDB, 0xA8, 0xD4, 0x4B, + 0xF2, 0x0C, 0x5E, 0xC0, 0x62, 0xEE, 0xE9, 0xB5, + 0x95, 0xA1, 0x1F, 0x9E, 0x84, 0x90, 0x1B, 0xF1, + 0x48, 0xF2, 0x98, 0xE0, 0xC9, 0xF8, 0x77, 0x7D, + 0xCD, 0xBC, 0x7C, 0xC4, 0x67, 0x0A, 0xAC, 0x35, + 0x6C, 0xC2, 0xAD, 0x8C, 0xCB, 0x16, 0x29, 0xF1, + 0x6F, 0x6A, 0x76, 0xBC, 0xEF, 0xBE, 0xE7, 0x60 + }, + { + 0xD1, 0xB8, 0x97, 0xB0, 0xE0, 0x75, 0xBA, 0x68, + 0xAB, 0x57, 0x2A, 0xDF, 0x9D, 0x9C, 0x43, 0x66, + 0x63, 0xE4, 0x3E, 0xB3, 0xD8, 0xE6, 0x2D, 0x92, + 0xFC, 0x49, 0xC9, 0xBE, 0x21, 0x4E, 0x6F, 0x27, + 0x87, 0x3F, 0xE2, 0x15, 0xA6, 0x51, 0x70, 0xE6, + 0xBE, 0xA9, 0x02, 0x40, 0x8A, 0x25, 0xB4, 0x95, + 0x06, 0xF4, 0x7B, 0xAB, 0xD0, 0x7C, 0xEC, 0xF7, + 0x11, 0x3E, 0xC1, 0x0C, 0x5D, 0xD3, 0x12, 0x52 + }, + { + 0xB1, 0x4D, 0x0C, 0x62, 0xAB, 0xFA, 0x46, 0x9A, + 0x35, 0x71, 0x77, 0xE5, 0x94, 0xC1, 0x0C, 0x19, + 0x42, 0x43, 0xED, 0x20, 0x25, 0xAB, 0x8A, 0xA5, + 0xAD, 0x2F, 0xA4, 0x1A, 0xD3, 0x18, 0xE0, 0xFF, + 0x48, 0xCD, 0x5E, 0x60, 0xBE, 0xC0, 0x7B, 0x13, + 0x63, 0x4A, 0x71, 0x1D, 0x23, 0x26, 0xE4, 0x88, + 0xA9, 0x85, 0xF3, 0x1E, 0x31, 0x15, 0x33, 0x99, + 0xE7, 0x30, 0x88, 0xEF, 0xC8, 0x6A, 0x5C, 0x55 + }, + { + 0x41, 0x69, 0xC5, 0xCC, 0x80, 0x8D, 0x26, 0x97, + 0xDC, 0x2A, 0x82, 0x43, 0x0D, 0xC2, 0x3E, 0x3C, + 0xD3, 0x56, 0xDC, 0x70, 0xA9, 0x45, 0x66, 0x81, + 0x05, 0x02, 0xB8, 0xD6, 0x55, 0xB3, 0x9A, 0xBF, + 0x9E, 0x7F, 0x90, 0x2F, 0xE7, 0x17, 0xE0, 0x38, + 0x92, 0x19, 0x85, 0x9E, 0x19, 0x45, 0xDF, 0x1A, + 0xF6, 0xAD, 0xA4, 0x2E, 0x4C, 0xCD, 0xA5, 0x5A, + 0x19, 0x7B, 0x71, 0x00, 0xA3, 0x0C, 0x30, 0xA1 + }, + { + 0x25, 0x8A, 0x4E, 0xDB, 0x11, 0x3D, 0x66, 0xC8, + 0x39, 0xC8, 0xB1, 0xC9, 0x1F, 0x15, 0xF3, 0x5A, + 0xDE, 0x60, 0x9F, 0x11, 0xCD, 0x7F, 0x86, 0x81, + 0xA4, 0x04, 0x5B, 0x9F, 0xEF, 0x7B, 0x0B, 0x24, + 0xC8, 0x2C, 0xDA, 0x06, 0xA5, 0xF2, 0x06, 0x7B, + 0x36, 0x88, 0x25, 0xE3, 0x91, 0x4E, 0x53, 0xD6, + 0x94, 0x8E, 0xDE, 0x92, 0xEF, 0xD6, 0xE8, 0x38, + 0x7F, 0xA2, 0xE5, 0x37, 0x23, 0x9B, 0x5B, 0xEE + }, + { + 0x79, 0xD2, 0xD8, 0x69, 0x6D, 0x30, 0xF3, 0x0F, + 0xB3, 0x46, 0x57, 0x76, 0x11, 0x71, 0xA1, 0x1E, + 0x6C, 0x3F, 0x1E, 0x64, 0xCB, 0xE7, 0xBE, 0xBE, + 0xE1, 0x59, 0xCB, 0x95, 0xBF, 0xAF, 0x81, 0x2B, + 0x4F, 0x41, 0x1E, 0x2F, 0x26, 0xD9, 0xC4, 0x21, + 0xDC, 0x2C, 0x28, 0x4A, 0x33, 0x42, 0xD8, 0x23, + 0xEC, 0x29, 0x38, 0x49, 0xE4, 0x2D, 0x1E, 0x46, + 0xB0, 0xA4, 0xAC, 0x1E, 0x3C, 0x86, 0xAB, 0xAA + }, + { + 0x8B, 0x94, 0x36, 0x01, 0x0D, 0xC5, 0xDE, 0xE9, + 0x92, 0xAE, 0x38, 0xAE, 0xA9, 0x7F, 0x2C, 0xD6, + 0x3B, 0x94, 0x6D, 0x94, 0xFE, 0xDD, 0x2E, 0xC9, + 0x67, 0x1D, 0xCD, 0xE3, 0xBD, 0x4C, 0xE9, 0x56, + 0x4D, 0x55, 0x5C, 0x66, 0xC1, 0x5B, 0xB2, 0xB9, + 0x00, 0xDF, 0x72, 0xED, 0xB6, 0xB8, 0x91, 0xEB, + 0xCA, 0xDF, 0xEF, 0xF6, 0x3C, 0x9E, 0xA4, 0x03, + 0x6A, 0x99, 0x8B, 0xE7, 0x97, 0x39, 0x81, 0xE7 + }, + { + 0xC8, 0xF6, 0x8E, 0x69, 0x6E, 0xD2, 0x82, 0x42, + 0xBF, 0x99, 0x7F, 0x5B, 0x3B, 0x34, 0x95, 0x95, + 0x08, 0xE4, 0x2D, 0x61, 0x38, 0x10, 0xF1, 0xE2, + 0xA4, 0x35, 0xC9, 0x6E, 0xD2, 0xFF, 0x56, 0x0C, + 0x70, 0x22, 0xF3, 0x61, 0xA9, 0x23, 0x4B, 0x98, + 0x37, 0xFE, 0xEE, 0x90, 0xBF, 0x47, 0x92, 0x2E, + 0xE0, 0xFD, 0x5F, 0x8D, 0xDF, 0x82, 0x37, 0x18, + 0xD8, 0x6D, 0x1E, 0x16, 0xC6, 0x09, 0x00, 0x71 + }, + { + 0xB0, 0x2D, 0x3E, 0xEE, 0x48, 0x60, 0xD5, 0x86, + 0x8B, 0x2C, 0x39, 0xCE, 0x39, 0xBF, 0xE8, 0x10, + 0x11, 0x29, 0x05, 0x64, 0xDD, 0x67, 0x8C, 0x85, + 0xE8, 0x78, 0x3F, 0x29, 0x30, 0x2D, 0xFC, 0x13, + 0x99, 0xBA, 0x95, 0xB6, 0xB5, 0x3C, 0xD9, 0xEB, + 0xBF, 0x40, 0x0C, 0xCA, 0x1D, 0xB0, 0xAB, 0x67, + 0xE1, 0x9A, 0x32, 0x5F, 0x2D, 0x11, 0x58, 0x12, + 0xD2, 0x5D, 0x00, 0x97, 0x8A, 0xD1, 0xBC, 0xA4 + }, + { + 0x76, 0x93, 0xEA, 0x73, 0xAF, 0x3A, 0xC4, 0xDA, + 0xD2, 0x1C, 0xA0, 0xD8, 0xDA, 0x85, 0xB3, 0x11, + 0x8A, 0x7D, 0x1C, 0x60, 0x24, 0xCF, 0xAF, 0x55, + 0x76, 0x99, 0x86, 0x82, 0x17, 0xBC, 0x0C, 0x2F, + 0x44, 0xA1, 0x99, 0xBC, 0x6C, 0x0E, 0xDD, 0x51, + 0x97, 0x98, 0xBA, 0x05, 0xBD, 0x5B, 0x1B, 0x44, + 0x84, 0x34, 0x6A, 0x47, 0xC2, 0xCA, 0xDF, 0x6B, + 0xF3, 0x0B, 0x78, 0x5C, 0xC8, 0x8B, 0x2B, 0xAF + }, + { + 0xA0, 0xE5, 0xC1, 0xC0, 0x03, 0x1C, 0x02, 0xE4, + 0x8B, 0x7F, 0x09, 0xA5, 0xE8, 0x96, 0xEE, 0x9A, + 0xEF, 0x2F, 0x17, 0xFC, 0x9E, 0x18, 0xE9, 0x97, + 0xD7, 0xF6, 0xCA, 0xC7, 0xAE, 0x31, 0x64, 0x22, + 0xC2, 0xB1, 0xE7, 0x79, 0x84, 0xE5, 0xF3, 0xA7, + 0x3C, 0xB4, 0x5D, 0xEE, 0xD5, 0xD3, 0xF8, 0x46, + 0x00, 0x10, 0x5E, 0x6E, 0xE3, 0x8F, 0x2D, 0x09, + 0x0C, 0x7D, 0x04, 0x42, 0xEA, 0x34, 0xC4, 0x6D + }, + { + 0x41, 0xDA, 0xA6, 0xAD, 0xCF, 0xDB, 0x69, 0xF1, + 0x44, 0x0C, 0x37, 0xB5, 0x96, 0x44, 0x01, 0x65, + 0xC1, 0x5A, 0xDA, 0x59, 0x68, 0x13, 0xE2, 0xE2, + 0x2F, 0x06, 0x0F, 0xCD, 0x55, 0x1F, 0x24, 0xDE, + 0xE8, 0xE0, 0x4B, 0xA6, 0x89, 0x03, 0x87, 0x88, + 0x6C, 0xEE, 0xC4, 0xA7, 0xA0, 0xD7, 0xFC, 0x6B, + 0x44, 0x50, 0x63, 0x92, 0xEC, 0x38, 0x22, 0xC0, + 0xD8, 0xC1, 0xAC, 0xFC, 0x7D, 0x5A, 0xEB, 0xE8 + }, + { + 0x14, 0xD4, 0xD4, 0x0D, 0x59, 0x84, 0xD8, 0x4C, + 0x5C, 0xF7, 0x52, 0x3B, 0x77, 0x98, 0xB2, 0x54, + 0xE2, 0x75, 0xA3, 0xA8, 0xCC, 0x0A, 0x1B, 0xD0, + 0x6E, 0xBC, 0x0B, 0xEE, 0x72, 0x68, 0x56, 0xAC, + 0xC3, 0xCB, 0xF5, 0x16, 0xFF, 0x66, 0x7C, 0xDA, + 0x20, 0x58, 0xAD, 0x5C, 0x34, 0x12, 0x25, 0x44, + 0x60, 0xA8, 0x2C, 0x92, 0x18, 0x70, 0x41, 0x36, + 0x3C, 0xC7, 0x7A, 0x4D, 0xC2, 0x15, 0xE4, 0x87 + }, + { + 0xD0, 0xE7, 0xA1, 0xE2, 0xB9, 0xA4, 0x47, 0xFE, + 0xE8, 0x3E, 0x22, 0x77, 0xE9, 0xFF, 0x80, 0x10, + 0xC2, 0xF3, 0x75, 0xAE, 0x12, 0xFA, 0x7A, 0xAA, + 0x8C, 0xA5, 0xA6, 0x31, 0x78, 0x68, 0xA2, 0x6A, + 0x36, 0x7A, 0x0B, 0x69, 0xFB, 0xC1, 0xCF, 0x32, + 0xA5, 0x5D, 0x34, 0xEB, 0x37, 0x06, 0x63, 0x01, + 0x6F, 0x3D, 0x21, 0x10, 0x23, 0x0E, 0xBA, 0x75, + 0x40, 0x28, 0xA5, 0x6F, 0x54, 0xAC, 0xF5, 0x7C + }, + { + 0xE7, 0x71, 0xAA, 0x8D, 0xB5, 0xA3, 0xE0, 0x43, + 0xE8, 0x17, 0x8F, 0x39, 0xA0, 0x85, 0x7B, 0xA0, + 0x4A, 0x3F, 0x18, 0xE4, 0xAA, 0x05, 0x74, 0x3C, + 0xF8, 0xD2, 0x22, 0xB0, 0xB0, 0x95, 0x82, 0x53, + 0x50, 0xBA, 0x42, 0x2F, 0x63, 0x38, 0x2A, 0x23, + 0xD9, 0x2E, 0x41, 0x49, 0x07, 0x4E, 0x81, 0x6A, + 0x36, 0xC1, 0xCD, 0x28, 0x28, 0x4D, 0x14, 0x62, + 0x67, 0x94, 0x0B, 0x31, 0xF8, 0x81, 0x8E, 0xA2 + }, + { + 0xFE, 0xB4, 0xFD, 0x6F, 0x9E, 0x87, 0xA5, 0x6B, + 0xEF, 0x39, 0x8B, 0x32, 0x84, 0xD2, 0xBD, 0xA5, + 0xB5, 0xB0, 0xE1, 0x66, 0x58, 0x3A, 0x66, 0xB6, + 0x1E, 0x53, 0x84, 0x57, 0xFF, 0x05, 0x84, 0x87, + 0x2C, 0x21, 0xA3, 0x29, 0x62, 0xB9, 0x92, 0x8F, + 0xFA, 0xB5, 0x8D, 0xE4, 0xAF, 0x2E, 0xDD, 0x4E, + 0x15, 0xD8, 0xB3, 0x55, 0x70, 0x52, 0x32, 0x07, + 0xFF, 0x4E, 0x2A, 0x5A, 0xA7, 0x75, 0x4C, 0xAA + }, + { + 0x46, 0x2F, 0x17, 0xBF, 0x00, 0x5F, 0xB1, 0xC1, + 0xB9, 0xE6, 0x71, 0x77, 0x9F, 0x66, 0x52, 0x09, + 0xEC, 0x28, 0x73, 0xE3, 0xE4, 0x11, 0xF9, 0x8D, + 0xAB, 0xF2, 0x40, 0xA1, 0xD5, 0xEC, 0x3F, 0x95, + 0xCE, 0x67, 0x96, 0xB6, 0xFC, 0x23, 0xFE, 0x17, + 0x19, 0x03, 0xB5, 0x02, 0x02, 0x34, 0x67, 0xDE, + 0xC7, 0x27, 0x3F, 0xF7, 0x48, 0x79, 0xB9, 0x29, + 0x67, 0xA2, 0xA4, 0x3A, 0x5A, 0x18, 0x3D, 0x33 + }, + { + 0xD3, 0x33, 0x81, 0x93, 0xB6, 0x45, 0x53, 0xDB, + 0xD3, 0x8D, 0x14, 0x4B, 0xEA, 0x71, 0xC5, 0x91, + 0x5B, 0xB1, 0x10, 0xE2, 0xD8, 0x81, 0x80, 0xDB, + 0xC5, 0xDB, 0x36, 0x4F, 0xD6, 0x17, 0x1D, 0xF3, + 0x17, 0xFC, 0x72, 0x68, 0x83, 0x1B, 0x5A, 0xEF, + 0x75, 0xE4, 0x34, 0x2B, 0x2F, 0xAD, 0x87, 0x97, + 0xBA, 0x39, 0xED, 0xDC, 0xEF, 0x80, 0xE6, 0xEC, + 0x08, 0x15, 0x93, 0x50, 0xB1, 0xAD, 0x69, 0x6D + }, + { + 0xE1, 0x59, 0x0D, 0x58, 0x5A, 0x3D, 0x39, 0xF7, + 0xCB, 0x59, 0x9A, 0xBD, 0x47, 0x90, 0x70, 0x96, + 0x64, 0x09, 0xA6, 0x84, 0x6D, 0x43, 0x77, 0xAC, + 0xF4, 0x47, 0x1D, 0x06, 0x5D, 0x5D, 0xB9, 0x41, + 0x29, 0xCC, 0x9B, 0xE9, 0x25, 0x73, 0xB0, 0x5E, + 0xD2, 0x26, 0xBE, 0x1E, 0x9B, 0x7C, 0xB0, 0xCA, + 0xBE, 0x87, 0x91, 0x85, 0x89, 0xF8, 0x0D, 0xAD, + 0xD4, 0xEF, 0x5E, 0xF2, 0x5A, 0x93, 0xD2, 0x8E + }, + { + 0xF8, 0xF3, 0x72, 0x6A, 0xC5, 0xA2, 0x6C, 0xC8, + 0x01, 0x32, 0x49, 0x3A, 0x6F, 0xED, 0xCB, 0x0E, + 0x60, 0x76, 0x0C, 0x09, 0xCF, 0xC8, 0x4C, 0xAD, + 0x17, 0x81, 0x75, 0x98, 0x68, 0x19, 0x66, 0x5E, + 0x76, 0x84, 0x2D, 0x7B, 0x9F, 0xED, 0xF7, 0x6D, + 0xDD, 0xEB, 0xF5, 0xD3, 0xF5, 0x6F, 0xAA, 0xAD, + 0x44, 0x77, 0x58, 0x7A, 0xF2, 0x16, 0x06, 0xD3, + 0x96, 0xAE, 0x57, 0x0D, 0x8E, 0x71, 0x9A, 0xF2 + }, + { + 0x30, 0x18, 0x60, 0x55, 0xC0, 0x79, 0x49, 0x94, + 0x81, 0x83, 0xC8, 0x50, 0xE9, 0xA7, 0x56, 0xCC, + 0x09, 0x93, 0x7E, 0x24, 0x7D, 0x9D, 0x92, 0x8E, + 0x86, 0x9E, 0x20, 0xBA, 0xFC, 0x3C, 0xD9, 0x72, + 0x17, 0x19, 0xD3, 0x4E, 0x04, 0xA0, 0x89, 0x9B, + 0x92, 0xC7, 0x36, 0x08, 0x45, 0x50, 0x18, 0x68, + 0x86, 0xEF, 0xBA, 0x2E, 0x79, 0x0D, 0x8B, 0xE6, + 0xEB, 0xF0, 0x40, 0xB2, 0x09, 0xC4, 0x39, 0xA4 + }, + { + 0xF3, 0xC4, 0x27, 0x6C, 0xB8, 0x63, 0x63, 0x77, + 0x12, 0xC2, 0x41, 0xC4, 0x44, 0xC5, 0xCC, 0x1E, + 0x35, 0x54, 0xE0, 0xFD, 0xDB, 0x17, 0x4D, 0x03, + 0x58, 0x19, 0xDD, 0x83, 0xEB, 0x70, 0x0B, 0x4C, + 0xE8, 0x8D, 0xF3, 0xAB, 0x38, 0x41, 0xBA, 0x02, + 0x08, 0x5E, 0x1A, 0x99, 0xB4, 0xE1, 0x73, 0x10, + 0xC5, 0x34, 0x10, 0x75, 0xC0, 0x45, 0x8B, 0xA3, + 0x76, 0xC9, 0x5A, 0x68, 0x18, 0xFB, 0xB3, 0xE2 + }, + { + 0x0A, 0xA0, 0x07, 0xC4, 0xDD, 0x9D, 0x58, 0x32, + 0x39, 0x30, 0x40, 0xA1, 0x58, 0x3C, 0x93, 0x0B, + 0xCA, 0x7D, 0xC5, 0xE7, 0x7E, 0xA5, 0x3A, 0xDD, + 0x7E, 0x2B, 0x3F, 0x7C, 0x8E, 0x23, 0x13, 0x68, + 0x04, 0x35, 0x20, 0xD4, 0xA3, 0xEF, 0x53, 0xC9, + 0x69, 0xB6, 0xBB, 0xFD, 0x02, 0x59, 0x46, 0xF6, + 0x32, 0xBD, 0x7F, 0x76, 0x5D, 0x53, 0xC2, 0x10, + 0x03, 0xB8, 0xF9, 0x83, 0xF7, 0x5E, 0x2A, 0x6A + }, + { + 0x08, 0xE9, 0x46, 0x47, 0x20, 0x53, 0x3B, 0x23, + 0xA0, 0x4E, 0xC2, 0x4F, 0x7A, 0xE8, 0xC1, 0x03, + 0x14, 0x5F, 0x76, 0x53, 0x87, 0xD7, 0x38, 0x77, + 0x7D, 0x3D, 0x34, 0x34, 0x77, 0xFD, 0x1C, 0x58, + 0xDB, 0x05, 0x21, 0x42, 0xCA, 0xB7, 0x54, 0xEA, + 0x67, 0x43, 0x78, 0xE1, 0x87, 0x66, 0xC5, 0x35, + 0x42, 0xF7, 0x19, 0x70, 0x17, 0x1C, 0xC4, 0xF8, + 0x16, 0x94, 0x24, 0x6B, 0x71, 0x7D, 0x75, 0x64 + }, + { + 0xD3, 0x7F, 0xF7, 0xAD, 0x29, 0x79, 0x93, 0xE7, + 0xEC, 0x21, 0xE0, 0xF1, 0xB4, 0xB5, 0xAE, 0x71, + 0x9C, 0xDC, 0x83, 0xC5, 0xDB, 0x68, 0x75, 0x27, + 0xF2, 0x75, 0x16, 0xCB, 0xFF, 0xA8, 0x22, 0x88, + 0x8A, 0x68, 0x10, 0xEE, 0x5C, 0x1C, 0xA7, 0xBF, + 0xE3, 0x32, 0x11, 0x19, 0xBE, 0x1A, 0xB7, 0xBF, + 0xA0, 0xA5, 0x02, 0x67, 0x1C, 0x83, 0x29, 0x49, + 0x4D, 0xF7, 0xAD, 0x6F, 0x52, 0x2D, 0x44, 0x0F + }, + { + 0xDD, 0x90, 0x42, 0xF6, 0xE4, 0x64, 0xDC, 0xF8, + 0x6B, 0x12, 0x62, 0xF6, 0xAC, 0xCF, 0xAF, 0xBD, + 0x8C, 0xFD, 0x90, 0x2E, 0xD3, 0xED, 0x89, 0xAB, + 0xF7, 0x8F, 0xFA, 0x48, 0x2D, 0xBD, 0xEE, 0xB6, + 0x96, 0x98, 0x42, 0x39, 0x4C, 0x9A, 0x11, 0x68, + 0xAE, 0x3D, 0x48, 0x1A, 0x01, 0x78, 0x42, 0xF6, + 0x60, 0x00, 0x2D, 0x42, 0x44, 0x7C, 0x6B, 0x22, + 0xF7, 0xB7, 0x2F, 0x21, 0xAA, 0xE0, 0x21, 0xC9 + }, + { + 0xBD, 0x96, 0x5B, 0xF3, 0x1E, 0x87, 0xD7, 0x03, + 0x27, 0x53, 0x6F, 0x2A, 0x34, 0x1C, 0xEB, 0xC4, + 0x76, 0x8E, 0xCA, 0x27, 0x5F, 0xA0, 0x5E, 0xF9, + 0x8F, 0x7F, 0x1B, 0x71, 0xA0, 0x35, 0x12, 0x98, + 0xDE, 0x00, 0x6F, 0xBA, 0x73, 0xFE, 0x67, 0x33, + 0xED, 0x01, 0xD7, 0x58, 0x01, 0xB4, 0xA9, 0x28, + 0xE5, 0x42, 0x31, 0xB3, 0x8E, 0x38, 0xC5, 0x62, + 0xB2, 0xE3, 0x3E, 0xA1, 0x28, 0x49, 0x92, 0xFA + }, + { + 0x65, 0x67, 0x6D, 0x80, 0x06, 0x17, 0x97, 0x2F, + 0xBD, 0x87, 0xE4, 0xB9, 0x51, 0x4E, 0x1C, 0x67, + 0x40, 0x2B, 0x7A, 0x33, 0x10, 0x96, 0xD3, 0xBF, + 0xAC, 0x22, 0xF1, 0xAB, 0xB9, 0x53, 0x74, 0xAB, + 0xC9, 0x42, 0xF1, 0x6E, 0x9A, 0xB0, 0xEA, 0xD3, + 0x3B, 0x87, 0xC9, 0x19, 0x68, 0xA6, 0xE5, 0x09, + 0xE1, 0x19, 0xFF, 0x07, 0x78, 0x7B, 0x3E, 0xF4, + 0x83, 0xE1, 0xDC, 0xDC, 0xCF, 0x6E, 0x30, 0x22 + }, + { + 0x93, 0x9F, 0xA1, 0x89, 0x69, 0x9C, 0x5D, 0x2C, + 0x81, 0xDD, 0xD1, 0xFF, 0xC1, 0xFA, 0x20, 0x7C, + 0x97, 0x0B, 0x6A, 0x36, 0x85, 0xBB, 0x29, 0xCE, + 0x1D, 0x3E, 0x99, 0xD4, 0x2F, 0x2F, 0x74, 0x42, + 0xDA, 0x53, 0xE9, 0x5A, 0x72, 0x90, 0x73, 0x14, + 0xF4, 0x58, 0x83, 0x99, 0xA3, 0xFF, 0x5B, 0x0A, + 0x92, 0xBE, 0xB3, 0xF6, 0xBE, 0x26, 0x94, 0xF9, + 0xF8, 0x6E, 0xCF, 0x29, 0x52, 0xD5, 0xB4, 0x1C + }, + { + 0xC5, 0x16, 0x54, 0x17, 0x01, 0x86, 0x3F, 0x91, + 0x00, 0x5F, 0x31, 0x41, 0x08, 0xCE, 0xEC, 0xE3, + 0xC6, 0x43, 0xE0, 0x4F, 0xC8, 0xC4, 0x2F, 0xD2, + 0xFF, 0x55, 0x62, 0x20, 0xE6, 0x16, 0xAA, 0xA6, + 0xA4, 0x8A, 0xEB, 0x97, 0xA8, 0x4B, 0xAD, 0x74, + 0x78, 0x2E, 0x8D, 0xFF, 0x96, 0xA1, 0xA2, 0xFA, + 0x94, 0x93, 0x39, 0xD7, 0x22, 0xED, 0xCA, 0xA3, + 0x2B, 0x57, 0x06, 0x70, 0x41, 0xDF, 0x88, 0xCC + }, + { + 0x98, 0x7F, 0xD6, 0xE0, 0xD6, 0x85, 0x7C, 0x55, + 0x3E, 0xAE, 0xBB, 0x3D, 0x34, 0x97, 0x0A, 0x2C, + 0x2F, 0x6E, 0x89, 0xA3, 0x54, 0x8F, 0x49, 0x25, + 0x21, 0x72, 0x2B, 0x80, 0xA1, 0xC2, 0x1A, 0x15, + 0x38, 0x92, 0x34, 0x6D, 0x2C, 0xBA, 0x64, 0x44, + 0x21, 0x2D, 0x56, 0xDA, 0x9A, 0x26, 0xE3, 0x24, + 0xDC, 0xCB, 0xC0, 0xDC, 0xDE, 0x85, 0xD4, 0xD2, + 0xEE, 0x43, 0x99, 0xEE, 0xC5, 0xA6, 0x4E, 0x8F + }, + { + 0xAE, 0x56, 0xDE, 0xB1, 0xC2, 0x32, 0x8D, 0x9C, + 0x40, 0x17, 0x70, 0x6B, 0xCE, 0x6E, 0x99, 0xD4, + 0x13, 0x49, 0x05, 0x3B, 0xA9, 0xD3, 0x36, 0xD6, + 0x77, 0xC4, 0xC2, 0x7D, 0x9F, 0xD5, 0x0A, 0xE6, + 0xAE, 0xE1, 0x7E, 0x85, 0x31, 0x54, 0xE1, 0xF4, + 0xFE, 0x76, 0x72, 0x34, 0x6D, 0xA2, 0xEA, 0xA3, + 0x1E, 0xEA, 0x53, 0xFC, 0xF2, 0x4A, 0x22, 0x80, + 0x4F, 0x11, 0xD0, 0x3D, 0xA6, 0xAB, 0xFC, 0x2B + }, + { + 0x49, 0xD6, 0xA6, 0x08, 0xC9, 0xBD, 0xE4, 0x49, + 0x18, 0x70, 0x49, 0x85, 0x72, 0xAC, 0x31, 0xAA, + 0xC3, 0xFA, 0x40, 0x93, 0x8B, 0x38, 0xA7, 0x81, + 0x8F, 0x72, 0x38, 0x3E, 0xB0, 0x40, 0xAD, 0x39, + 0x53, 0x2B, 0xC0, 0x65, 0x71, 0xE1, 0x3D, 0x76, + 0x7E, 0x69, 0x45, 0xAB, 0x77, 0xC0, 0xBD, 0xC3, + 0xB0, 0x28, 0x42, 0x53, 0x34, 0x3F, 0x9F, 0x6C, + 0x12, 0x44, 0xEB, 0xF2, 0xFF, 0x0D, 0xF8, 0x66 + }, + { + 0xDA, 0x58, 0x2A, 0xD8, 0xC5, 0x37, 0x0B, 0x44, + 0x69, 0xAF, 0x86, 0x2A, 0xA6, 0x46, 0x7A, 0x22, + 0x93, 0xB2, 0xB2, 0x8B, 0xD8, 0x0A, 0xE0, 0xE9, + 0x1F, 0x42, 0x5A, 0xD3, 0xD4, 0x72, 0x49, 0xFD, + 0xF9, 0x88, 0x25, 0xCC, 0x86, 0xF1, 0x40, 0x28, + 0xC3, 0x30, 0x8C, 0x98, 0x04, 0xC7, 0x8B, 0xFE, + 0xEE, 0xEE, 0x46, 0x14, 0x44, 0xCE, 0x24, 0x36, + 0x87, 0xE1, 0xA5, 0x05, 0x22, 0x45, 0x6A, 0x1D + }, + { + 0xD5, 0x26, 0x6A, 0xA3, 0x33, 0x11, 0x94, 0xAE, + 0xF8, 0x52, 0xEE, 0xD8, 0x6D, 0x7B, 0x5B, 0x26, + 0x33, 0xA0, 0xAF, 0x1C, 0x73, 0x59, 0x06, 0xF2, + 0xE1, 0x32, 0x79, 0xF1, 0x49, 0x31, 0xA9, 0xFC, + 0x3B, 0x0E, 0xAC, 0x5C, 0xE9, 0x24, 0x52, 0x73, + 0xBD, 0x1A, 0xA9, 0x29, 0x05, 0xAB, 0xE1, 0x62, + 0x78, 0xEF, 0x7E, 0xFD, 0x47, 0x69, 0x47, 0x89, + 0xA7, 0x28, 0x3B, 0x77, 0xDA, 0x3C, 0x70, 0xF8 + }, + { + 0x29, 0x62, 0x73, 0x4C, 0x28, 0x25, 0x21, 0x86, + 0xA9, 0xA1, 0x11, 0x1C, 0x73, 0x2A, 0xD4, 0xDE, + 0x45, 0x06, 0xD4, 0xB4, 0x48, 0x09, 0x16, 0x30, + 0x3E, 0xB7, 0x99, 0x1D, 0x65, 0x9C, 0xCD, 0xA0, + 0x7A, 0x99, 0x11, 0x91, 0x4B, 0xC7, 0x5C, 0x41, + 0x8A, 0xB7, 0xA4, 0x54, 0x17, 0x57, 0xAD, 0x05, + 0x47, 0x96, 0xE2, 0x67, 0x97, 0xFE, 0xAF, 0x36, + 0xE9, 0xF6, 0xAD, 0x43, 0xF1, 0x4B, 0x35, 0xA4 + }, + { + 0xE8, 0xB7, 0x9E, 0xC5, 0xD0, 0x6E, 0x11, 0x1B, + 0xDF, 0xAF, 0xD7, 0x1E, 0x9F, 0x57, 0x60, 0xF0, + 0x0A, 0xC8, 0xAC, 0x5D, 0x8B, 0xF7, 0x68, 0xF9, + 0xFF, 0x6F, 0x08, 0xB8, 0xF0, 0x26, 0x09, 0x6B, + 0x1C, 0xC3, 0xA4, 0xC9, 0x73, 0x33, 0x30, 0x19, + 0xF1, 0xE3, 0x55, 0x3E, 0x77, 0xDA, 0x3F, 0x98, + 0xCB, 0x9F, 0x54, 0x2E, 0x0A, 0x90, 0xE5, 0xF8, + 0xA9, 0x40, 0xCC, 0x58, 0xE5, 0x98, 0x44, 0xB3 + }, + { + 0xDF, 0xB3, 0x20, 0xC4, 0x4F, 0x9D, 0x41, 0xD1, + 0xEF, 0xDC, 0xC0, 0x15, 0xF0, 0x8D, 0xD5, 0x53, + 0x9E, 0x52, 0x6E, 0x39, 0xC8, 0x7D, 0x50, 0x9A, + 0xE6, 0x81, 0x2A, 0x96, 0x9E, 0x54, 0x31, 0xBF, + 0x4F, 0xA7, 0xD9, 0x1F, 0xFD, 0x03, 0xB9, 0x81, + 0xE0, 0xD5, 0x44, 0xCF, 0x72, 0xD7, 0xB1, 0xC0, + 0x37, 0x4F, 0x88, 0x01, 0x48, 0x2E, 0x6D, 0xEA, + 0x2E, 0xF9, 0x03, 0x87, 0x7E, 0xBA, 0x67, 0x5E + }, + { + 0xD8, 0x86, 0x75, 0x11, 0x8F, 0xDB, 0x55, 0xA5, + 0xFB, 0x36, 0x5A, 0xC2, 0xAF, 0x1D, 0x21, 0x7B, + 0xF5, 0x26, 0xCE, 0x1E, 0xE9, 0xC9, 0x4B, 0x2F, + 0x00, 0x90, 0xB2, 0xC5, 0x8A, 0x06, 0xCA, 0x58, + 0x18, 0x7D, 0x7F, 0xE5, 0x7C, 0x7B, 0xED, 0x9D, + 0x26, 0xFC, 0xA0, 0x67, 0xB4, 0x11, 0x0E, 0xEF, + 0xCD, 0x9A, 0x0A, 0x34, 0x5D, 0xE8, 0x72, 0xAB, + 0xE2, 0x0D, 0xE3, 0x68, 0x00, 0x1B, 0x07, 0x45 + }, + { + 0xB8, 0x93, 0xF2, 0xFC, 0x41, 0xF7, 0xB0, 0xDD, + 0x6E, 0x2F, 0x6A, 0xA2, 0xE0, 0x37, 0x0C, 0x0C, + 0xFF, 0x7D, 0xF0, 0x9E, 0x3A, 0xCF, 0xCC, 0x0E, + 0x92, 0x0B, 0x6E, 0x6F, 0xAD, 0x0E, 0xF7, 0x47, + 0xC4, 0x06, 0x68, 0x41, 0x7D, 0x34, 0x2B, 0x80, + 0xD2, 0x35, 0x1E, 0x8C, 0x17, 0x5F, 0x20, 0x89, + 0x7A, 0x06, 0x2E, 0x97, 0x65, 0xE6, 0xC6, 0x7B, + 0x53, 0x9B, 0x6B, 0xA8, 0xB9, 0x17, 0x05, 0x45 + }, + { + 0x6C, 0x67, 0xEC, 0x56, 0x97, 0xAC, 0xCD, 0x23, + 0x5C, 0x59, 0xB4, 0x86, 0xD7, 0xB7, 0x0B, 0xAE, + 0xED, 0xCB, 0xD4, 0xAA, 0x64, 0xEB, 0xD4, 0xEE, + 0xF3, 0xC7, 0xEA, 0xC1, 0x89, 0x56, 0x1A, 0x72, + 0x62, 0x50, 0xAE, 0xC4, 0xD4, 0x8C, 0xAD, 0xCA, + 0xFB, 0xBE, 0x2C, 0xE3, 0xC1, 0x6C, 0xE2, 0xD6, + 0x91, 0xA8, 0xCC, 0xE0, 0x6E, 0x88, 0x79, 0x55, + 0x6D, 0x44, 0x83, 0xED, 0x71, 0x65, 0xC0, 0x63 + }, + { + 0xF1, 0xAA, 0x2B, 0x04, 0x4F, 0x8F, 0x0C, 0x63, + 0x8A, 0x3F, 0x36, 0x2E, 0x67, 0x7B, 0x5D, 0x89, + 0x1D, 0x6F, 0xD2, 0xAB, 0x07, 0x65, 0xF6, 0xEE, + 0x1E, 0x49, 0x87, 0xDE, 0x05, 0x7E, 0xAD, 0x35, + 0x78, 0x83, 0xD9, 0xB4, 0x05, 0xB9, 0xD6, 0x09, + 0xEE, 0xA1, 0xB8, 0x69, 0xD9, 0x7F, 0xB1, 0x6D, + 0x9B, 0x51, 0x01, 0x7C, 0x55, 0x3F, 0x3B, 0x93, + 0xC0, 0xA1, 0xE0, 0xF1, 0x29, 0x6F, 0xED, 0xCD + }, + { + 0xCB, 0xAA, 0x25, 0x95, 0x72, 0xD4, 0xAE, 0xBF, + 0xC1, 0x91, 0x7A, 0xCD, 0xDC, 0x58, 0x2B, 0x9F, + 0x8D, 0xFA, 0xA9, 0x28, 0xA1, 0x98, 0xCA, 0x7A, + 0xCD, 0x0F, 0x2A, 0xA7, 0x6A, 0x13, 0x4A, 0x90, + 0x25, 0x2E, 0x62, 0x98, 0xA6, 0x5B, 0x08, 0x18, + 0x6A, 0x35, 0x0D, 0x5B, 0x76, 0x26, 0x69, 0x9F, + 0x8C, 0xB7, 0x21, 0xA3, 0xEA, 0x59, 0x21, 0xB7, + 0x53, 0xAE, 0x3A, 0x2D, 0xCE, 0x24, 0xBA, 0x3A + }, + { + 0xFA, 0x15, 0x49, 0xC9, 0x79, 0x6C, 0xD4, 0xD3, + 0x03, 0xDC, 0xF4, 0x52, 0xC1, 0xFB, 0xD5, 0x74, + 0x4F, 0xD9, 0xB9, 0xB4, 0x70, 0x03, 0xD9, 0x20, + 0xB9, 0x2D, 0xE3, 0x48, 0x39, 0xD0, 0x7E, 0xF2, + 0xA2, 0x9D, 0xED, 0x68, 0xF6, 0xFC, 0x9E, 0x6C, + 0x45, 0xE0, 0x71, 0xA2, 0xE4, 0x8B, 0xD5, 0x0C, + 0x50, 0x84, 0xE9, 0x6B, 0x65, 0x7D, 0xD0, 0x40, + 0x40, 0x45, 0xA1, 0xDD, 0xEF, 0xE2, 0x82, 0xED + }, + { + 0x5C, 0xF2, 0xAC, 0x89, 0x7A, 0xB4, 0x44, 0xDC, + 0xB5, 0xC8, 0xD8, 0x7C, 0x49, 0x5D, 0xBD, 0xB3, + 0x4E, 0x18, 0x38, 0xB6, 0xB6, 0x29, 0x42, 0x7C, + 0xAA, 0x51, 0x70, 0x2A, 0xD0, 0xF9, 0x68, 0x85, + 0x25, 0xF1, 0x3B, 0xEC, 0x50, 0x3A, 0x3C, 0x3A, + 0x2C, 0x80, 0xA6, 0x5E, 0x0B, 0x57, 0x15, 0xE8, + 0xAF, 0xAB, 0x00, 0xFF, 0xA5, 0x6E, 0xC4, 0x55, + 0xA4, 0x9A, 0x1A, 0xD3, 0x0A, 0xA2, 0x4F, 0xCD + }, + { + 0x9A, 0xAF, 0x80, 0x20, 0x7B, 0xAC, 0xE1, 0x7B, + 0xB7, 0xAB, 0x14, 0x57, 0x57, 0xD5, 0x69, 0x6B, + 0xDE, 0x32, 0x40, 0x6E, 0xF2, 0x2B, 0x44, 0x29, + 0x2E, 0xF6, 0x5D, 0x45, 0x19, 0xC3, 0xBB, 0x2A, + 0xD4, 0x1A, 0x59, 0xB6, 0x2C, 0xC3, 0xE9, 0x4B, + 0x6F, 0xA9, 0x6D, 0x32, 0xA7, 0xFA, 0xAD, 0xAE, + 0x28, 0xAF, 0x7D, 0x35, 0x09, 0x72, 0x19, 0xAA, + 0x3F, 0xD8, 0xCD, 0xA3, 0x1E, 0x40, 0xC2, 0x75 + }, + { + 0xAF, 0x88, 0xB1, 0x63, 0x40, 0x2C, 0x86, 0x74, + 0x5C, 0xB6, 0x50, 0xC2, 0x98, 0x8F, 0xB9, 0x52, + 0x11, 0xB9, 0x4B, 0x03, 0xEF, 0x29, 0x0E, 0xED, + 0x96, 0x62, 0x03, 0x42, 0x41, 0xFD, 0x51, 0xCF, + 0x39, 0x8F, 0x80, 0x73, 0xE3, 0x69, 0x35, 0x4C, + 0x43, 0xEA, 0xE1, 0x05, 0x2F, 0x9B, 0x63, 0xB0, + 0x81, 0x91, 0xCA, 0xA1, 0x38, 0xAA, 0x54, 0xFE, + 0xA8, 0x89, 0xCC, 0x70, 0x24, 0x23, 0x68, 0x97 + }, + { + 0x48, 0xFA, 0x7D, 0x64, 0xE1, 0xCE, 0xEE, 0x27, + 0xB9, 0x86, 0x4D, 0xB5, 0xAD, 0xA4, 0xB5, 0x3D, + 0x00, 0xC9, 0xBC, 0x76, 0x26, 0x55, 0x58, 0x13, + 0xD3, 0xCD, 0x67, 0x30, 0xAB, 0x3C, 0xC0, 0x6F, + 0xF3, 0x42, 0xD7, 0x27, 0x90, 0x5E, 0x33, 0x17, + 0x1B, 0xDE, 0x6E, 0x84, 0x76, 0xE7, 0x7F, 0xB1, + 0x72, 0x08, 0x61, 0xE9, 0x4B, 0x73, 0xA2, 0xC5, + 0x38, 0xD2, 0x54, 0x74, 0x62, 0x85, 0xF4, 0x30 + }, + { + 0x0E, 0x6F, 0xD9, 0x7A, 0x85, 0xE9, 0x04, 0xF8, + 0x7B, 0xFE, 0x85, 0xBB, 0xEB, 0x34, 0xF6, 0x9E, + 0x1F, 0x18, 0x10, 0x5C, 0xF4, 0xED, 0x4F, 0x87, + 0xAE, 0xC3, 0x6C, 0x6E, 0x8B, 0x5F, 0x68, 0xBD, + 0x2A, 0x6F, 0x3D, 0xC8, 0xA9, 0xEC, 0xB2, 0xB6, + 0x1D, 0xB4, 0xEE, 0xDB, 0x6B, 0x2E, 0xA1, 0x0B, + 0xF9, 0xCB, 0x02, 0x51, 0xFB, 0x0F, 0x8B, 0x34, + 0x4A, 0xBF, 0x7F, 0x36, 0x6B, 0x6D, 0xE5, 0xAB + }, + { + 0x06, 0x62, 0x2D, 0xA5, 0x78, 0x71, 0x76, 0x28, + 0x7F, 0xDC, 0x8F, 0xED, 0x44, 0x0B, 0xAD, 0x18, + 0x7D, 0x83, 0x00, 0x99, 0xC9, 0x4E, 0x6D, 0x04, + 0xC8, 0xE9, 0xC9, 0x54, 0xCD, 0xA7, 0x0C, 0x8B, + 0xB9, 0xE1, 0xFC, 0x4A, 0x6D, 0x0B, 0xAA, 0x83, + 0x1B, 0x9B, 0x78, 0xEF, 0x66, 0x48, 0x68, 0x1A, + 0x48, 0x67, 0xA1, 0x1D, 0xA9, 0x3E, 0xE3, 0x6E, + 0x5E, 0x6A, 0x37, 0xD8, 0x7F, 0xC6, 0x3F, 0x6F + }, + { + 0x1D, 0xA6, 0x77, 0x2B, 0x58, 0xFA, 0xBF, 0x9C, + 0x61, 0xF6, 0x8D, 0x41, 0x2C, 0x82, 0xF1, 0x82, + 0xC0, 0x23, 0x6D, 0x7D, 0x57, 0x5E, 0xF0, 0xB5, + 0x8D, 0xD2, 0x24, 0x58, 0xD6, 0x43, 0xCD, 0x1D, + 0xFC, 0x93, 0xB0, 0x38, 0x71, 0xC3, 0x16, 0xD8, + 0x43, 0x0D, 0x31, 0x29, 0x95, 0xD4, 0x19, 0x7F, + 0x08, 0x74, 0xC9, 0x91, 0x72, 0xBA, 0x00, 0x4A, + 0x01, 0xEE, 0x29, 0x5A, 0xBA, 0xC2, 0x4E, 0x46 + }, + { + 0x3C, 0xD2, 0xD9, 0x32, 0x0B, 0x7B, 0x1D, 0x5F, + 0xB9, 0xAA, 0xB9, 0x51, 0xA7, 0x60, 0x23, 0xFA, + 0x66, 0x7B, 0xE1, 0x4A, 0x91, 0x24, 0xE3, 0x94, + 0x51, 0x39, 0x18, 0xA3, 0xF4, 0x40, 0x96, 0xAE, + 0x49, 0x04, 0xBA, 0x0F, 0xFC, 0x15, 0x0B, 0x63, + 0xBC, 0x7A, 0xB1, 0xEE, 0xB9, 0xA6, 0xE2, 0x57, + 0xE5, 0xC8, 0xF0, 0x00, 0xA7, 0x03, 0x94, 0xA5, + 0xAF, 0xD8, 0x42, 0x71, 0x5D, 0xE1, 0x5F, 0x29 + }, + { + 0x04, 0xCD, 0xC1, 0x4F, 0x74, 0x34, 0xE0, 0xB4, + 0xBE, 0x70, 0xCB, 0x41, 0xDB, 0x4C, 0x77, 0x9A, + 0x88, 0xEA, 0xEF, 0x6A, 0xCC, 0xEB, 0xCB, 0x41, + 0xF2, 0xD4, 0x2F, 0xFF, 0xE7, 0xF3, 0x2A, 0x8E, + 0x28, 0x1B, 0x5C, 0x10, 0x3A, 0x27, 0x02, 0x1D, + 0x0D, 0x08, 0x36, 0x22, 0x50, 0x75, 0x3C, 0xDF, + 0x70, 0x29, 0x21, 0x95, 0xA5, 0x3A, 0x48, 0x72, + 0x8C, 0xEB, 0x58, 0x44, 0xC2, 0xD9, 0x8B, 0xAB + }, + { + 0x90, 0x71, 0xB7, 0xA8, 0xA0, 0x75, 0xD0, 0x09, + 0x5B, 0x8F, 0xB3, 0xAE, 0x51, 0x13, 0x78, 0x57, + 0x35, 0xAB, 0x98, 0xE2, 0xB5, 0x2F, 0xAF, 0x91, + 0xD5, 0xB8, 0x9E, 0x44, 0xAA, 0xC5, 0xB5, 0xD4, + 0xEB, 0xBF, 0x91, 0x22, 0x3B, 0x0F, 0xF4, 0xC7, + 0x19, 0x05, 0xDA, 0x55, 0x34, 0x2E, 0x64, 0x65, + 0x5D, 0x6E, 0xF8, 0xC8, 0x9A, 0x47, 0x68, 0xC3, + 0xF9, 0x3A, 0x6D, 0xC0, 0x36, 0x6B, 0x5B, 0xC8 + }, + { + 0xEB, 0xB3, 0x02, 0x40, 0xDD, 0x96, 0xC7, 0xBC, + 0x8D, 0x0A, 0xBE, 0x49, 0xAA, 0x4E, 0xDC, 0xBB, + 0x4A, 0xFD, 0xC5, 0x1F, 0xF9, 0xAA, 0xF7, 0x20, + 0xD3, 0xF9, 0xE7, 0xFB, 0xB0, 0xF9, 0xC6, 0xD6, + 0x57, 0x13, 0x50, 0x50, 0x17, 0x69, 0xFC, 0x4E, + 0xBD, 0x0B, 0x21, 0x41, 0x24, 0x7F, 0xF4, 0x00, + 0xD4, 0xFD, 0x4B, 0xE4, 0x14, 0xED, 0xF3, 0x77, + 0x57, 0xBB, 0x90, 0xA3, 0x2A, 0xC5, 0xC6, 0x5A + }, + { + 0x85, 0x32, 0xC5, 0x8B, 0xF3, 0xC8, 0x01, 0x5D, + 0x9D, 0x1C, 0xBE, 0x00, 0xEE, 0xF1, 0xF5, 0x08, + 0x2F, 0x8F, 0x36, 0x32, 0xFB, 0xE9, 0xF1, 0xED, + 0x4F, 0x9D, 0xFB, 0x1F, 0xA7, 0x9E, 0x82, 0x83, + 0x06, 0x6D, 0x77, 0xC4, 0x4C, 0x4A, 0xF9, 0x43, + 0xD7, 0x6B, 0x30, 0x03, 0x64, 0xAE, 0xCB, 0xD0, + 0x64, 0x8C, 0x8A, 0x89, 0x39, 0xBD, 0x20, 0x41, + 0x23, 0xF4, 0xB5, 0x62, 0x60, 0x42, 0x2D, 0xEC + }, + { + 0xFE, 0x98, 0x46, 0xD6, 0x4F, 0x7C, 0x77, 0x08, + 0x69, 0x6F, 0x84, 0x0E, 0x2D, 0x76, 0xCB, 0x44, + 0x08, 0xB6, 0x59, 0x5C, 0x2F, 0x81, 0xEC, 0x6A, + 0x28, 0xA7, 0xF2, 0xF2, 0x0C, 0xB8, 0x8C, 0xFE, + 0x6A, 0xC0, 0xB9, 0xE9, 0xB8, 0x24, 0x4F, 0x08, + 0xBD, 0x70, 0x95, 0xC3, 0x50, 0xC1, 0xD0, 0x84, + 0x2F, 0x64, 0xFB, 0x01, 0xBB, 0x7F, 0x53, 0x2D, + 0xFC, 0xD4, 0x73, 0x71, 0xB0, 0xAE, 0xEB, 0x79 + }, + { + 0x28, 0xF1, 0x7E, 0xA6, 0xFB, 0x6C, 0x42, 0x09, + 0x2D, 0xC2, 0x64, 0x25, 0x7E, 0x29, 0x74, 0x63, + 0x21, 0xFB, 0x5B, 0xDA, 0xEA, 0x98, 0x73, 0xC2, + 0xA7, 0xFA, 0x9D, 0x8F, 0x53, 0x81, 0x8E, 0x89, + 0x9E, 0x16, 0x1B, 0xC7, 0x7D, 0xFE, 0x80, 0x90, + 0xAF, 0xD8, 0x2B, 0xF2, 0x26, 0x6C, 0x5C, 0x1B, + 0xC9, 0x30, 0xA8, 0xD1, 0x54, 0x76, 0x24, 0x43, + 0x9E, 0x66, 0x2E, 0xF6, 0x95, 0xF2, 0x6F, 0x24 + }, + { + 0xEC, 0x6B, 0x7D, 0x7F, 0x03, 0x0D, 0x48, 0x50, + 0xAC, 0xAE, 0x3C, 0xB6, 0x15, 0xC2, 0x1D, 0xD2, + 0x52, 0x06, 0xD6, 0x3E, 0x84, 0xD1, 0xDB, 0x8D, + 0x95, 0x73, 0x70, 0x73, 0x7B, 0xA0, 0xE9, 0x84, + 0x67, 0xEA, 0x0C, 0xE2, 0x74, 0xC6, 0x61, 0x99, + 0x90, 0x1E, 0xAE, 0xC1, 0x8A, 0x08, 0x52, 0x57, + 0x15, 0xF5, 0x3B, 0xFD, 0xB0, 0xAA, 0xCB, 0x61, + 0x3D, 0x34, 0x2E, 0xBD, 0xCE, 0xED, 0xDC, 0x3B + }, + { + 0xB4, 0x03, 0xD3, 0x69, 0x1C, 0x03, 0xB0, 0xD3, + 0x41, 0x8D, 0xF3, 0x27, 0xD5, 0x86, 0x0D, 0x34, + 0xBB, 0xFC, 0xC4, 0x51, 0x9B, 0xFB, 0xCE, 0x36, + 0xBF, 0x33, 0xB2, 0x08, 0x38, 0x5F, 0xAD, 0xB9, + 0x18, 0x6B, 0xC7, 0x8A, 0x76, 0xC4, 0x89, 0xD8, + 0x9F, 0xD5, 0x7E, 0x7D, 0xC7, 0x54, 0x12, 0xD2, + 0x3B, 0xCD, 0x1D, 0xAE, 0x84, 0x70, 0xCE, 0x92, + 0x74, 0x75, 0x4B, 0xB8, 0x58, 0x5B, 0x13, 0xC5 + }, + { + 0x31, 0xFC, 0x79, 0x73, 0x8B, 0x87, 0x72, 0xB3, + 0xF5, 0x5C, 0xD8, 0x17, 0x88, 0x13, 0xB3, 0xB5, + 0x2D, 0x0D, 0xB5, 0xA4, 0x19, 0xD3, 0x0B, 0xA9, + 0x49, 0x5C, 0x4B, 0x9D, 0xA0, 0x21, 0x9F, 0xAC, + 0x6D, 0xF8, 0xE7, 0xC2, 0x3A, 0x81, 0x15, 0x51, + 0xA6, 0x2B, 0x82, 0x7F, 0x25, 0x6E, 0xCD, 0xB8, + 0x12, 0x4A, 0xC8, 0xA6, 0x79, 0x2C, 0xCF, 0xEC, + 0xC3, 0xB3, 0x01, 0x27, 0x22, 0xE9, 0x44, 0x63 + }, + { + 0xBB, 0x20, 0x39, 0xEC, 0x28, 0x70, 0x91, 0xBC, + 0xC9, 0x64, 0x2F, 0xC9, 0x00, 0x49, 0xE7, 0x37, + 0x32, 0xE0, 0x2E, 0x57, 0x7E, 0x28, 0x62, 0xB3, + 0x22, 0x16, 0xAE, 0x9B, 0xED, 0xCD, 0x73, 0x0C, + 0x4C, 0x28, 0x4E, 0xF3, 0x96, 0x8C, 0x36, 0x8B, + 0x7D, 0x37, 0x58, 0x4F, 0x97, 0xBD, 0x4B, 0x4D, + 0xC6, 0xEF, 0x61, 0x27, 0xAC, 0xFE, 0x2E, 0x6A, + 0xE2, 0x50, 0x91, 0x24, 0xE6, 0x6C, 0x8A, 0xF4 + }, + { + 0xF5, 0x3D, 0x68, 0xD1, 0x3F, 0x45, 0xED, 0xFC, + 0xB9, 0xBD, 0x41, 0x5E, 0x28, 0x31, 0xE9, 0x38, + 0x35, 0x0D, 0x53, 0x80, 0xD3, 0x43, 0x22, 0x78, + 0xFC, 0x1C, 0x0C, 0x38, 0x1F, 0xCB, 0x7C, 0x65, + 0xC8, 0x2D, 0xAF, 0xE0, 0x51, 0xD8, 0xC8, 0xB0, + 0xD4, 0x4E, 0x09, 0x74, 0xA0, 0xE5, 0x9E, 0xC7, + 0xBF, 0x7E, 0xD0, 0x45, 0x9F, 0x86, 0xE9, 0x6F, + 0x32, 0x9F, 0xC7, 0x97, 0x52, 0x51, 0x0F, 0xD3 + }, + { + 0x8D, 0x56, 0x8C, 0x79, 0x84, 0xF0, 0xEC, 0xDF, + 0x76, 0x40, 0xFB, 0xC4, 0x83, 0xB5, 0xD8, 0xC9, + 0xF8, 0x66, 0x34, 0xF6, 0xF4, 0x32, 0x91, 0x84, + 0x1B, 0x30, 0x9A, 0x35, 0x0A, 0xB9, 0xC1, 0x13, + 0x7D, 0x24, 0x06, 0x6B, 0x09, 0xDA, 0x99, 0x44, + 0xBA, 0xC5, 0x4D, 0x5B, 0xB6, 0x58, 0x0D, 0x83, + 0x60, 0x47, 0xAA, 0xC7, 0x4A, 0xB7, 0x24, 0xB8, + 0x87, 0xEB, 0xF9, 0x3D, 0x4B, 0x32, 0xEC, 0xA9 + }, + { + 0xC0, 0xB6, 0x5C, 0xE5, 0xA9, 0x6F, 0xF7, 0x74, + 0xC4, 0x56, 0xCA, 0xC3, 0xB5, 0xF2, 0xC4, 0xCD, + 0x35, 0x9B, 0x4F, 0xF5, 0x3E, 0xF9, 0x3A, 0x3D, + 0xA0, 0x77, 0x8B, 0xE4, 0x90, 0x0D, 0x1E, 0x8D, + 0xA1, 0x60, 0x1E, 0x76, 0x9E, 0x8F, 0x1B, 0x02, + 0xD2, 0xA2, 0xF8, 0xC5, 0xB9, 0xFA, 0x10, 0xB4, + 0x4F, 0x1C, 0x18, 0x69, 0x85, 0x46, 0x8F, 0xEE, + 0xB0, 0x08, 0x73, 0x02, 0x83, 0xA6, 0x65, 0x7D + }, + { + 0x49, 0x00, 0xBB, 0xA6, 0xF5, 0xFB, 0x10, 0x3E, + 0xCE, 0x8E, 0xC9, 0x6A, 0xDA, 0x13, 0xA5, 0xC3, + 0xC8, 0x54, 0x88, 0xE0, 0x55, 0x51, 0xDA, 0x6B, + 0x6B, 0x33, 0xD9, 0x88, 0xE6, 0x11, 0xEC, 0x0F, + 0xE2, 0xE3, 0xC2, 0xAA, 0x48, 0xEA, 0x6A, 0xE8, + 0x98, 0x6A, 0x3A, 0x23, 0x1B, 0x22, 0x3C, 0x5D, + 0x27, 0xCE, 0xC2, 0xEA, 0xDD, 0xE9, 0x1C, 0xE0, + 0x79, 0x81, 0xEE, 0x65, 0x28, 0x62, 0xD1, 0xE4 + }, + { + 0xC7, 0xF5, 0xC3, 0x7C, 0x72, 0x85, 0xF9, 0x27, + 0xF7, 0x64, 0x43, 0x41, 0x4D, 0x43, 0x57, 0xFF, + 0x78, 0x96, 0x47, 0xD7, 0xA0, 0x05, 0xA5, 0xA7, + 0x87, 0xE0, 0x3C, 0x34, 0x6B, 0x57, 0xF4, 0x9F, + 0x21, 0xB6, 0x4F, 0xA9, 0xCF, 0x4B, 0x7E, 0x45, + 0x57, 0x3E, 0x23, 0x04, 0x90, 0x17, 0x56, 0x71, + 0x21, 0xA9, 0xC3, 0xD4, 0xB2, 0xB7, 0x3E, 0xC5, + 0xE9, 0x41, 0x35, 0x77, 0x52, 0x5D, 0xB4, 0x5A + }, + { + 0xEC, 0x70, 0x96, 0x33, 0x07, 0x36, 0xFD, 0xB2, + 0xD6, 0x4B, 0x56, 0x53, 0xE7, 0x47, 0x5D, 0xA7, + 0x46, 0xC2, 0x3A, 0x46, 0x13, 0xA8, 0x26, 0x87, + 0xA2, 0x80, 0x62, 0xD3, 0x23, 0x63, 0x64, 0x28, + 0x4A, 0xC0, 0x17, 0x20, 0xFF, 0xB4, 0x06, 0xCF, + 0xE2, 0x65, 0xC0, 0xDF, 0x62, 0x6A, 0x18, 0x8C, + 0x9E, 0x59, 0x63, 0xAC, 0xE5, 0xD3, 0xD5, 0xBB, + 0x36, 0x3E, 0x32, 0xC3, 0x8C, 0x21, 0x90, 0xA6 + }, + { + 0x82, 0xE7, 0x44, 0xC7, 0x5F, 0x46, 0x49, 0xEC, + 0x52, 0xB8, 0x07, 0x71, 0xA7, 0x7D, 0x47, 0x5A, + 0x3B, 0xC0, 0x91, 0x98, 0x95, 0x56, 0x96, 0x0E, + 0x27, 0x6A, 0x5F, 0x9E, 0xAD, 0x92, 0xA0, 0x3F, + 0x71, 0x87, 0x42, 0xCD, 0xCF, 0xEA, 0xEE, 0x5C, + 0xB8, 0x5C, 0x44, 0xAF, 0x19, 0x8A, 0xDC, 0x43, + 0xA4, 0xA4, 0x28, 0xF5, 0xF0, 0xC2, 0xDD, 0xB0, + 0xBE, 0x36, 0x05, 0x9F, 0x06, 0xD7, 0xDF, 0x73 + }, + { + 0x28, 0x34, 0xB7, 0xA7, 0x17, 0x0F, 0x1F, 0x5B, + 0x68, 0x55, 0x9A, 0xB7, 0x8C, 0x10, 0x50, 0xEC, + 0x21, 0xC9, 0x19, 0x74, 0x0B, 0x78, 0x4A, 0x90, + 0x72, 0xF6, 0xE5, 0xD6, 0x9F, 0x82, 0x8D, 0x70, + 0xC9, 0x19, 0xC5, 0x03, 0x9F, 0xB1, 0x48, 0xE3, + 0x9E, 0x2C, 0x8A, 0x52, 0x11, 0x83, 0x78, 0xB0, + 0x64, 0xCA, 0x8D, 0x50, 0x01, 0xCD, 0x10, 0xA5, + 0x47, 0x83, 0x87, 0xB9, 0x66, 0x71, 0x5E, 0xD6 + }, + { + 0x16, 0xB4, 0xAD, 0xA8, 0x83, 0xF7, 0x2F, 0x85, + 0x3B, 0xB7, 0xEF, 0x25, 0x3E, 0xFC, 0xAB, 0x0C, + 0x3E, 0x21, 0x61, 0x68, 0x7A, 0xD6, 0x15, 0x43, + 0xA0, 0xD2, 0x82, 0x4F, 0x91, 0xC1, 0xF8, 0x13, + 0x47, 0xD8, 0x6B, 0xE7, 0x09, 0xB1, 0x69, 0x96, + 0xE1, 0x7F, 0x2D, 0xD4, 0x86, 0x92, 0x7B, 0x02, + 0x88, 0xAD, 0x38, 0xD1, 0x30, 0x63, 0xC4, 0xA9, + 0x67, 0x2C, 0x39, 0x39, 0x7D, 0x37, 0x89, 0xB6 + }, + { + 0x78, 0xD0, 0x48, 0xF3, 0xA6, 0x9D, 0x8B, 0x54, + 0xAE, 0x0E, 0xD6, 0x3A, 0x57, 0x3A, 0xE3, 0x50, + 0xD8, 0x9F, 0x7C, 0x6C, 0xF1, 0xF3, 0x68, 0x89, + 0x30, 0xDE, 0x89, 0x9A, 0xFA, 0x03, 0x76, 0x97, + 0x62, 0x9B, 0x31, 0x4E, 0x5C, 0xD3, 0x03, 0xAA, + 0x62, 0xFE, 0xEA, 0x72, 0xA2, 0x5B, 0xF4, 0x2B, + 0x30, 0x4B, 0x6C, 0x6B, 0xCB, 0x27, 0xFA, 0xE2, + 0x1C, 0x16, 0xD9, 0x25, 0xE1, 0xFB, 0xDA, 0xC3 + }, + { + 0x0F, 0x74, 0x6A, 0x48, 0x74, 0x92, 0x87, 0xAD, + 0xA7, 0x7A, 0x82, 0x96, 0x1F, 0x05, 0xA4, 0xDA, + 0x4A, 0xBD, 0xB7, 0xD7, 0x7B, 0x12, 0x20, 0xF8, + 0x36, 0xD0, 0x9E, 0xC8, 0x14, 0x35, 0x9C, 0x0E, + 0xC0, 0x23, 0x9B, 0x8C, 0x7B, 0x9F, 0xF9, 0xE0, + 0x2F, 0x56, 0x9D, 0x1B, 0x30, 0x1E, 0xF6, 0x7C, + 0x46, 0x12, 0xD1, 0xDE, 0x4F, 0x73, 0x0F, 0x81, + 0xC1, 0x2C, 0x40, 0xCC, 0x06, 0x3C, 0x5C, 0xAA + }, + { + 0xF0, 0xFC, 0x85, 0x9D, 0x3B, 0xD1, 0x95, 0xFB, + 0xDC, 0x2D, 0x59, 0x1E, 0x4C, 0xDA, 0xC1, 0x51, + 0x79, 0xEC, 0x0F, 0x1D, 0xC8, 0x21, 0xC1, 0x1D, + 0xF1, 0xF0, 0xC1, 0xD2, 0x6E, 0x62, 0x60, 0xAA, + 0xA6, 0x5B, 0x79, 0xFA, 0xFA, 0xCA, 0xFD, 0x7D, + 0x3A, 0xD6, 0x1E, 0x60, 0x0F, 0x25, 0x09, 0x05, + 0xF5, 0x87, 0x8C, 0x87, 0x45, 0x28, 0x97, 0x64, + 0x7A, 0x35, 0xB9, 0x95, 0xBC, 0xAD, 0xC3, 0xA3 + }, + { + 0x26, 0x20, 0xF6, 0x87, 0xE8, 0x62, 0x5F, 0x6A, + 0x41, 0x24, 0x60, 0xB4, 0x2E, 0x2C, 0xEF, 0x67, + 0x63, 0x42, 0x08, 0xCE, 0x10, 0xA0, 0xCB, 0xD4, + 0xDF, 0xF7, 0x04, 0x4A, 0x41, 0xB7, 0x88, 0x00, + 0x77, 0xE9, 0xF8, 0xDC, 0x3B, 0x8D, 0x12, 0x16, + 0xD3, 0x37, 0x6A, 0x21, 0xE0, 0x15, 0xB5, 0x8F, + 0xB2, 0x79, 0xB5, 0x21, 0xD8, 0x3F, 0x93, 0x88, + 0xC7, 0x38, 0x2C, 0x85, 0x05, 0x59, 0x0B, 0x9B + }, + { + 0x22, 0x7E, 0x3A, 0xED, 0x8D, 0x2C, 0xB1, 0x0B, + 0x91, 0x8F, 0xCB, 0x04, 0xF9, 0xDE, 0x3E, 0x6D, + 0x0A, 0x57, 0xE0, 0x84, 0x76, 0xD9, 0x37, 0x59, + 0xCD, 0x7B, 0x2E, 0xD5, 0x4A, 0x1C, 0xBF, 0x02, + 0x39, 0xC5, 0x28, 0xFB, 0x04, 0xBB, 0xF2, 0x88, + 0x25, 0x3E, 0x60, 0x1D, 0x3B, 0xC3, 0x8B, 0x21, + 0x79, 0x4A, 0xFE, 0xF9, 0x0B, 0x17, 0x09, 0x4A, + 0x18, 0x2C, 0xAC, 0x55, 0x77, 0x45, 0xE7, 0x5F + }, + { + 0x1A, 0x92, 0x99, 0x01, 0xB0, 0x9C, 0x25, 0xF2, + 0x7D, 0x6B, 0x35, 0xBE, 0x7B, 0x2F, 0x1C, 0x47, + 0x45, 0x13, 0x1F, 0xDE, 0xBC, 0xA7, 0xF3, 0xE2, + 0x45, 0x19, 0x26, 0x72, 0x04, 0x34, 0xE0, 0xDB, + 0x6E, 0x74, 0xFD, 0x69, 0x3A, 0xD2, 0x9B, 0x77, + 0x7D, 0xC3, 0x35, 0x5C, 0x59, 0x2A, 0x36, 0x1C, + 0x48, 0x73, 0xB0, 0x11, 0x33, 0xA5, 0x7C, 0x2E, + 0x3B, 0x70, 0x75, 0xCB, 0xDB, 0x86, 0xF4, 0xFC + }, + { + 0x5F, 0xD7, 0x96, 0x8B, 0xC2, 0xFE, 0x34, 0xF2, + 0x20, 0xB5, 0xE3, 0xDC, 0x5A, 0xF9, 0x57, 0x17, + 0x42, 0xD7, 0x3B, 0x7D, 0x60, 0x81, 0x9F, 0x28, + 0x88, 0xB6, 0x29, 0x07, 0x2B, 0x96, 0xA9, 0xD8, + 0xAB, 0x2D, 0x91, 0xB8, 0x2D, 0x0A, 0x9A, 0xAB, + 0xA6, 0x1B, 0xBD, 0x39, 0x95, 0x81, 0x32, 0xFC, + 0xC4, 0x25, 0x70, 0x23, 0xD1, 0xEC, 0xA5, 0x91, + 0xB3, 0x05, 0x4E, 0x2D, 0xC8, 0x1C, 0x82, 0x00 + }, + { + 0xDF, 0xCC, 0xE8, 0xCF, 0x32, 0x87, 0x0C, 0xC6, + 0xA5, 0x03, 0xEA, 0xDA, 0xFC, 0x87, 0xFD, 0x6F, + 0x78, 0x91, 0x8B, 0x9B, 0x4D, 0x07, 0x37, 0xDB, + 0x68, 0x10, 0xBE, 0x99, 0x6B, 0x54, 0x97, 0xE7, + 0xE5, 0xCC, 0x80, 0xE3, 0x12, 0xF6, 0x1E, 0x71, + 0xFF, 0x3E, 0x96, 0x24, 0x43, 0x60, 0x73, 0x15, + 0x64, 0x03, 0xF7, 0x35, 0xF5, 0x6B, 0x0B, 0x01, + 0x84, 0x5C, 0x18, 0xF6, 0xCA, 0xF7, 0x72, 0xE6 + }, + { + 0x02, 0xF7, 0xEF, 0x3A, 0x9C, 0xE0, 0xFF, 0xF9, + 0x60, 0xF6, 0x70, 0x32, 0xB2, 0x96, 0xEF, 0xCA, + 0x30, 0x61, 0xF4, 0x93, 0x4D, 0x69, 0x07, 0x49, + 0xF2, 0xD0, 0x1C, 0x35, 0xC8, 0x1C, 0x14, 0xF3, + 0x9A, 0x67, 0xFA, 0x35, 0x0B, 0xC8, 0xA0, 0x35, + 0x9B, 0xF1, 0x72, 0x4B, 0xFF, 0xC3, 0xBC, 0xA6, + 0xD7, 0xC7, 0xBB, 0xA4, 0x79, 0x1F, 0xD5, 0x22, + 0xA3, 0xAD, 0x35, 0x3C, 0x02, 0xEC, 0x5A, 0xA8 + }, + { + 0x64, 0xBE, 0x5C, 0x6A, 0xBA, 0x65, 0xD5, 0x94, + 0x84, 0x4A, 0xE7, 0x8B, 0xB0, 0x22, 0xE5, 0xBE, + 0xBE, 0x12, 0x7F, 0xD6, 0xB6, 0xFF, 0xA5, 0xA1, + 0x37, 0x03, 0x85, 0x5A, 0xB6, 0x3B, 0x62, 0x4D, + 0xCD, 0x1A, 0x36, 0x3F, 0x99, 0x20, 0x3F, 0x63, + 0x2E, 0xC3, 0x86, 0xF3, 0xEA, 0x76, 0x7F, 0xC9, + 0x92, 0xE8, 0xED, 0x96, 0x86, 0x58, 0x6A, 0xA2, + 0x75, 0x55, 0xA8, 0x59, 0x9D, 0x5B, 0x80, 0x8F + }, + { + 0xF7, 0x85, 0x85, 0x50, 0x5C, 0x4E, 0xAA, 0x54, + 0xA8, 0xB5, 0xBE, 0x70, 0xA6, 0x1E, 0x73, 0x5E, + 0x0F, 0xF9, 0x7A, 0xF9, 0x44, 0xDD, 0xB3, 0x00, + 0x1E, 0x35, 0xD8, 0x6C, 0x4E, 0x21, 0x99, 0xD9, + 0x76, 0x10, 0x4B, 0x6A, 0xE3, 0x17, 0x50, 0xA3, + 0x6A, 0x72, 0x6E, 0xD2, 0x85, 0x06, 0x4F, 0x59, + 0x81, 0xB5, 0x03, 0x88, 0x9F, 0xEF, 0x82, 0x2F, + 0xCD, 0xC2, 0x89, 0x8D, 0xDD, 0xB7, 0x88, 0x9A + }, + { + 0xE4, 0xB5, 0x56, 0x60, 0x33, 0x86, 0x95, 0x72, + 0xED, 0xFD, 0x87, 0x47, 0x9A, 0x5B, 0xB7, 0x3C, + 0x80, 0xE8, 0x75, 0x9B, 0x91, 0x23, 0x28, 0x79, + 0xD9, 0x6B, 0x1D, 0xDA, 0x36, 0xC0, 0x12, 0x07, + 0x6E, 0xE5, 0xA2, 0xED, 0x7A, 0xE2, 0xDE, 0x63, + 0xEF, 0x84, 0x06, 0xA0, 0x6A, 0xEA, 0x82, 0xC1, + 0x88, 0x03, 0x1B, 0x56, 0x0B, 0xEA, 0xFB, 0x58, + 0x3F, 0xB3, 0xDE, 0x9E, 0x57, 0x95, 0x2A, 0x7E + }, + { + 0xE1, 0xB3, 0xE7, 0xED, 0x86, 0x7F, 0x6C, 0x94, + 0x84, 0xA2, 0xA9, 0x7F, 0x77, 0x15, 0xF2, 0x5E, + 0x25, 0x29, 0x4E, 0x99, 0x2E, 0x41, 0xF6, 0xA7, + 0xC1, 0x61, 0xFF, 0xC2, 0xAD, 0xC6, 0xDA, 0xAE, + 0xB7, 0x11, 0x31, 0x02, 0xD5, 0xE6, 0x09, 0x02, + 0x87, 0xFE, 0x6A, 0xD9, 0x4C, 0xE5, 0xD6, 0xB7, + 0x39, 0xC6, 0xCA, 0x24, 0x0B, 0x05, 0xC7, 0x6F, + 0xB7, 0x3F, 0x25, 0xDD, 0x02, 0x4B, 0xF9, 0x35 + }, + { + 0x85, 0xFD, 0x08, 0x5F, 0xDC, 0x12, 0xA0, 0x80, + 0x98, 0x3D, 0xF0, 0x7B, 0xD7, 0x01, 0x2B, 0x0D, + 0x40, 0x2A, 0x0F, 0x40, 0x43, 0xFC, 0xB2, 0x77, + 0x5A, 0xDF, 0x0B, 0xAD, 0x17, 0x4F, 0x9B, 0x08, + 0xD1, 0x67, 0x6E, 0x47, 0x69, 0x85, 0x78, 0x5C, + 0x0A, 0x5D, 0xCC, 0x41, 0xDB, 0xFF, 0x6D, 0x95, + 0xEF, 0x4D, 0x66, 0xA3, 0xFB, 0xDC, 0x4A, 0x74, + 0xB8, 0x2B, 0xA5, 0x2D, 0xA0, 0x51, 0x2B, 0x74 + }, + { + 0xAE, 0xD8, 0xFA, 0x76, 0x4B, 0x0F, 0xBF, 0xF8, + 0x21, 0xE0, 0x52, 0x33, 0xD2, 0xF7, 0xB0, 0x90, + 0x0E, 0xC4, 0x4D, 0x82, 0x6F, 0x95, 0xE9, 0x3C, + 0x34, 0x3C, 0x1B, 0xC3, 0xBA, 0x5A, 0x24, 0x37, + 0x4B, 0x1D, 0x61, 0x6E, 0x7E, 0x7A, 0xBA, 0x45, + 0x3A, 0x0A, 0xDA, 0x5E, 0x4F, 0xAB, 0x53, 0x82, + 0x40, 0x9E, 0x0D, 0x42, 0xCE, 0x9C, 0x2B, 0xC7, + 0xFB, 0x39, 0xA9, 0x9C, 0x34, 0x0C, 0x20, 0xF0 + }, + { + 0x7B, 0xA3, 0xB2, 0xE2, 0x97, 0x23, 0x35, 0x22, + 0xEE, 0xB3, 0x43, 0xBD, 0x3E, 0xBC, 0xFD, 0x83, + 0x5A, 0x04, 0x00, 0x77, 0x35, 0xE8, 0x7F, 0x0C, + 0xA3, 0x00, 0xCB, 0xEE, 0x6D, 0x41, 0x65, 0x65, + 0x16, 0x21, 0x71, 0x58, 0x1E, 0x40, 0x20, 0xFF, + 0x4C, 0xF1, 0x76, 0x45, 0x0F, 0x12, 0x91, 0xEA, + 0x22, 0x85, 0xCB, 0x9E, 0xBF, 0xFE, 0x4C, 0x56, + 0x66, 0x06, 0x27, 0x68, 0x51, 0x45, 0x05, 0x1C + }, + { + 0xDE, 0x74, 0x8B, 0xCF, 0x89, 0xEC, 0x88, 0x08, + 0x47, 0x21, 0xE1, 0x6B, 0x85, 0xF3, 0x0A, 0xDB, + 0x1A, 0x61, 0x34, 0xD6, 0x64, 0xB5, 0x84, 0x35, + 0x69, 0xBA, 0xBC, 0x5B, 0xBD, 0x1A, 0x15, 0xCA, + 0x9B, 0x61, 0x80, 0x3C, 0x90, 0x1A, 0x4F, 0xEF, + 0x32, 0x96, 0x5A, 0x17, 0x49, 0xC9, 0xF3, 0xA4, + 0xE2, 0x43, 0xE1, 0x73, 0x93, 0x9D, 0xC5, 0xA8, + 0xDC, 0x49, 0x5C, 0x67, 0x1A, 0xB5, 0x21, 0x45 + }, + { + 0xAA, 0xF4, 0xD2, 0xBD, 0xF2, 0x00, 0xA9, 0x19, + 0x70, 0x6D, 0x98, 0x42, 0xDC, 0xE1, 0x6C, 0x98, + 0x14, 0x0D, 0x34, 0xBC, 0x43, 0x3D, 0xF3, 0x20, + 0xAB, 0xA9, 0xBD, 0x42, 0x9E, 0x54, 0x9A, 0xA7, + 0xA3, 0x39, 0x76, 0x52, 0xA4, 0xD7, 0x68, 0x27, + 0x77, 0x86, 0xCF, 0x99, 0x3C, 0xDE, 0x23, 0x38, + 0x67, 0x3E, 0xD2, 0xE6, 0xB6, 0x6C, 0x96, 0x1F, + 0xEF, 0xB8, 0x2C, 0xD2, 0x0C, 0x93, 0x33, 0x8F + }, + { + 0xC4, 0x08, 0x21, 0x89, 0x68, 0xB7, 0x88, 0xBF, + 0x86, 0x4F, 0x09, 0x97, 0xE6, 0xBC, 0x4C, 0x3D, + 0xBA, 0x68, 0xB2, 0x76, 0xE2, 0x12, 0x5A, 0x48, + 0x43, 0x29, 0x60, 0x52, 0xFF, 0x93, 0xBF, 0x57, + 0x67, 0xB8, 0xCD, 0xCE, 0x71, 0x31, 0xF0, 0x87, + 0x64, 0x30, 0xC1, 0x16, 0x5F, 0xEC, 0x6C, 0x4F, + 0x47, 0xAD, 0xAA, 0x4F, 0xD8, 0xBC, 0xFA, 0xCE, + 0xF4, 0x63, 0xB5, 0xD3, 0xD0, 0xFA, 0x61, 0xA0 + }, + { + 0x76, 0xD2, 0xD8, 0x19, 0xC9, 0x2B, 0xCE, 0x55, + 0xFA, 0x8E, 0x09, 0x2A, 0xB1, 0xBF, 0x9B, 0x9E, + 0xAB, 0x23, 0x7A, 0x25, 0x26, 0x79, 0x86, 0xCA, + 0xCF, 0x2B, 0x8E, 0xE1, 0x4D, 0x21, 0x4D, 0x73, + 0x0D, 0xC9, 0xA5, 0xAA, 0x2D, 0x7B, 0x59, 0x6E, + 0x86, 0xA1, 0xFD, 0x8F, 0xA0, 0x80, 0x4C, 0x77, + 0x40, 0x2D, 0x2F, 0xCD, 0x45, 0x08, 0x36, 0x88, + 0xB2, 0x18, 0xB1, 0xCD, 0xFA, 0x0D, 0xCB, 0xCB + }, + { + 0x72, 0x06, 0x5E, 0xE4, 0xDD, 0x91, 0xC2, 0xD8, + 0x50, 0x9F, 0xA1, 0xFC, 0x28, 0xA3, 0x7C, 0x7F, + 0xC9, 0xFA, 0x7D, 0x5B, 0x3F, 0x8A, 0xD3, 0xD0, + 0xD7, 0xA2, 0x56, 0x26, 0xB5, 0x7B, 0x1B, 0x44, + 0x78, 0x8D, 0x4C, 0xAF, 0x80, 0x62, 0x90, 0x42, + 0x5F, 0x98, 0x90, 0xA3, 0xA2, 0xA3, 0x5A, 0x90, + 0x5A, 0xB4, 0xB3, 0x7A, 0xCF, 0xD0, 0xDA, 0x6E, + 0x45, 0x17, 0xB2, 0x52, 0x5C, 0x96, 0x51, 0xE4 + }, + { + 0x64, 0x47, 0x5D, 0xFE, 0x76, 0x00, 0xD7, 0x17, + 0x1B, 0xEA, 0x0B, 0x39, 0x4E, 0x27, 0xC9, 0xB0, + 0x0D, 0x8E, 0x74, 0xDD, 0x1E, 0x41, 0x6A, 0x79, + 0x47, 0x36, 0x82, 0xAD, 0x3D, 0xFD, 0xBB, 0x70, + 0x66, 0x31, 0x55, 0x80, 0x55, 0xCF, 0xC8, 0xA4, + 0x0E, 0x07, 0xBD, 0x01, 0x5A, 0x45, 0x40, 0xDC, + 0xDE, 0xA1, 0x58, 0x83, 0xCB, 0xBF, 0x31, 0x41, + 0x2D, 0xF1, 0xDE, 0x1C, 0xD4, 0x15, 0x2B, 0x91 + }, + { + 0x12, 0xCD, 0x16, 0x74, 0xA4, 0x48, 0x8A, 0x5D, + 0x7C, 0x2B, 0x31, 0x60, 0xD2, 0xE2, 0xC4, 0xB5, + 0x83, 0x71, 0xBE, 0xDA, 0xD7, 0x93, 0x41, 0x8D, + 0x6F, 0x19, 0xC6, 0xEE, 0x38, 0x5D, 0x70, 0xB3, + 0xE0, 0x67, 0x39, 0x36, 0x9D, 0x4D, 0xF9, 0x10, + 0xED, 0xB0, 0xB0, 0xA5, 0x4C, 0xBF, 0xF4, 0x3D, + 0x54, 0x54, 0x4C, 0xD3, 0x7A, 0xB3, 0xA0, 0x6C, + 0xFA, 0x0A, 0x3D, 0xDA, 0xC8, 0xB6, 0x6C, 0x89 + }, + { + 0x60, 0x75, 0x69, 0x66, 0x47, 0x9D, 0xED, 0xC6, + 0xDD, 0x4B, 0xCF, 0xF8, 0xEA, 0x7D, 0x1D, 0x4C, + 0xE4, 0xD4, 0xAF, 0x2E, 0x7B, 0x09, 0x7E, 0x32, + 0xE3, 0x76, 0x35, 0x18, 0x44, 0x11, 0x47, 0xCC, + 0x12, 0xB3, 0xC0, 0xEE, 0x6D, 0x2E, 0xCA, 0xBF, + 0x11, 0x98, 0xCE, 0xC9, 0x2E, 0x86, 0xA3, 0x61, + 0x6F, 0xBA, 0x4F, 0x4E, 0x87, 0x2F, 0x58, 0x25, + 0x33, 0x0A, 0xDB, 0xB4, 0xC1, 0xDE, 0xE4, 0x44 + }, + { + 0xA7, 0x80, 0x3B, 0xCB, 0x71, 0xBC, 0x1D, 0x0F, + 0x43, 0x83, 0xDD, 0xE1, 0xE0, 0x61, 0x2E, 0x04, + 0xF8, 0x72, 0xB7, 0x15, 0xAD, 0x30, 0x81, 0x5C, + 0x22, 0x49, 0xCF, 0x34, 0xAB, 0xB8, 0xB0, 0x24, + 0x91, 0x5C, 0xB2, 0xFC, 0x9F, 0x4E, 0x7C, 0xC4, + 0xC8, 0xCF, 0xD4, 0x5B, 0xE2, 0xD5, 0xA9, 0x1E, + 0xAB, 0x09, 0x41, 0xC7, 0xD2, 0x70, 0xE2, 0xDA, + 0x4C, 0xA4, 0xA9, 0xF7, 0xAC, 0x68, 0x66, 0x3A + }, + { + 0xB8, 0x4E, 0xF6, 0xA7, 0x22, 0x9A, 0x34, 0xA7, + 0x50, 0xD9, 0xA9, 0x8E, 0xE2, 0x52, 0x98, 0x71, + 0x81, 0x6B, 0x87, 0xFB, 0xE3, 0xBC, 0x45, 0xB4, + 0x5F, 0xA5, 0xAE, 0x82, 0xD5, 0x14, 0x15, 0x40, + 0x21, 0x11, 0x65, 0xC3, 0xC5, 0xD7, 0xA7, 0x47, + 0x6B, 0xA5, 0xA4, 0xAA, 0x06, 0xD6, 0x64, 0x76, + 0xF0, 0xD9, 0xDC, 0x49, 0xA3, 0xF1, 0xEE, 0x72, + 0xC3, 0xAC, 0xAB, 0xD4, 0x98, 0x96, 0x74, 0x14 + }, + { + 0xFA, 0xE4, 0xB6, 0xD8, 0xEF, 0xC3, 0xF8, 0xC8, + 0xE6, 0x4D, 0x00, 0x1D, 0xAB, 0xEC, 0x3A, 0x21, + 0xF5, 0x44, 0xE8, 0x27, 0x14, 0x74, 0x52, 0x51, + 0xB2, 0xB4, 0xB3, 0x93, 0xF2, 0xF4, 0x3E, 0x0D, + 0xA3, 0xD4, 0x03, 0xC6, 0x4D, 0xB9, 0x5A, 0x2C, + 0xB6, 0xE2, 0x3E, 0xBB, 0x7B, 0x9E, 0x94, 0xCD, + 0xD5, 0xDD, 0xAC, 0x54, 0xF0, 0x7C, 0x4A, 0x61, + 0xBD, 0x3C, 0xB1, 0x0A, 0xA6, 0xF9, 0x3B, 0x49 + }, + { + 0x34, 0xF7, 0x28, 0x66, 0x05, 0xA1, 0x22, 0x36, + 0x95, 0x40, 0x14, 0x1D, 0xED, 0x79, 0xB8, 0x95, + 0x72, 0x55, 0xDA, 0x2D, 0x41, 0x55, 0xAB, 0xBF, + 0x5A, 0x8D, 0xBB, 0x89, 0xC8, 0xEB, 0x7E, 0xDE, + 0x8E, 0xEE, 0xF1, 0xDA, 0xA4, 0x6D, 0xC2, 0x9D, + 0x75, 0x1D, 0x04, 0x5D, 0xC3, 0xB1, 0xD6, 0x58, + 0xBB, 0x64, 0xB8, 0x0F, 0xF8, 0x58, 0x9E, 0xDD, + 0xB3, 0x82, 0x4B, 0x13, 0xDA, 0x23, 0x5A, 0x6B + }, + { + 0x3B, 0x3B, 0x48, 0x43, 0x4B, 0xE2, 0x7B, 0x9E, + 0xAB, 0xAB, 0xBA, 0x43, 0xBF, 0x6B, 0x35, 0xF1, + 0x4B, 0x30, 0xF6, 0xA8, 0x8D, 0xC2, 0xE7, 0x50, + 0xC3, 0x58, 0x47, 0x0D, 0x6B, 0x3A, 0xA3, 0xC1, + 0x8E, 0x47, 0xDB, 0x40, 0x17, 0xFA, 0x55, 0x10, + 0x6D, 0x82, 0x52, 0xF0, 0x16, 0x37, 0x1A, 0x00, + 0xF5, 0xF8, 0xB0, 0x70, 0xB7, 0x4B, 0xA5, 0xF2, + 0x3C, 0xFF, 0xC5, 0x51, 0x1C, 0x9F, 0x09, 0xF0 + }, + { + 0xBA, 0x28, 0x9E, 0xBD, 0x65, 0x62, 0xC4, 0x8C, + 0x3E, 0x10, 0xA8, 0xAD, 0x6C, 0xE0, 0x2E, 0x73, + 0x43, 0x3D, 0x1E, 0x93, 0xD7, 0xC9, 0x27, 0x9D, + 0x4D, 0x60, 0xA7, 0xE8, 0x79, 0xEE, 0x11, 0xF4, + 0x41, 0xA0, 0x00, 0xF4, 0x8E, 0xD9, 0xF7, 0xC4, + 0xED, 0x87, 0xA4, 0x51, 0x36, 0xD7, 0xDC, 0xCD, + 0xCA, 0x48, 0x21, 0x09, 0xC7, 0x8A, 0x51, 0x06, + 0x2B, 0x3B, 0xA4, 0x04, 0x4A, 0xDA, 0x24, 0x69 + }, + { + 0x02, 0x29, 0x39, 0xE2, 0x38, 0x6C, 0x5A, 0x37, + 0x04, 0x98, 0x56, 0xC8, 0x50, 0xA2, 0xBB, 0x10, + 0xA1, 0x3D, 0xFE, 0xA4, 0x21, 0x2B, 0x4C, 0x73, + 0x2A, 0x88, 0x40, 0xA9, 0xFF, 0xA5, 0xFA, 0xF5, + 0x48, 0x75, 0xC5, 0x44, 0x88, 0x16, 0xB2, 0x78, + 0x5A, 0x00, 0x7D, 0xA8, 0xA8, 0xD2, 0xBC, 0x7D, + 0x71, 0xA5, 0x4E, 0x4E, 0x65, 0x71, 0xF1, 0x0B, + 0x60, 0x0C, 0xBD, 0xB2, 0x5D, 0x13, 0xED, 0xE3 + }, + { + 0xE6, 0xFE, 0xC1, 0x9D, 0x89, 0xCE, 0x87, 0x17, + 0xB1, 0xA0, 0x87, 0x02, 0x46, 0x70, 0xFE, 0x02, + 0x6F, 0x6C, 0x7C, 0xBD, 0xA1, 0x1C, 0xAE, 0xF9, + 0x59, 0xBB, 0x2D, 0x35, 0x1B, 0xF8, 0x56, 0xF8, + 0x05, 0x5D, 0x1C, 0x0E, 0xBD, 0xAA, 0xA9, 0xD1, + 0xB1, 0x78, 0x86, 0xFC, 0x2C, 0x56, 0x2B, 0x5E, + 0x99, 0x64, 0x2F, 0xC0, 0x64, 0x71, 0x0C, 0x0D, + 0x34, 0x88, 0xA0, 0x2B, 0x5E, 0xD7, 0xF6, 0xFD + }, + { + 0x94, 0xC9, 0x6F, 0x02, 0xA8, 0xF5, 0x76, 0xAC, + 0xA3, 0x2B, 0xA6, 0x1C, 0x2B, 0x20, 0x6F, 0x90, + 0x72, 0x85, 0xD9, 0x29, 0x9B, 0x83, 0xAC, 0x17, + 0x5C, 0x20, 0x9A, 0x8D, 0x43, 0xD5, 0x3B, 0xFE, + 0x68, 0x3D, 0xD1, 0xD8, 0x3E, 0x75, 0x49, 0xCB, + 0x90, 0x6C, 0x28, 0xF5, 0x9A, 0xB7, 0xC4, 0x6F, + 0x87, 0x51, 0x36, 0x6A, 0x28, 0xC3, 0x9D, 0xD5, + 0xFE, 0x26, 0x93, 0xC9, 0x01, 0x96, 0x66, 0xC8 + }, + { + 0x31, 0xA0, 0xCD, 0x21, 0x5E, 0xBD, 0x2C, 0xB6, + 0x1D, 0xE5, 0xB9, 0xED, 0xC9, 0x1E, 0x61, 0x95, + 0xE3, 0x1C, 0x59, 0xA5, 0x64, 0x8D, 0x5C, 0x9F, + 0x73, 0x7E, 0x12, 0x5B, 0x26, 0x05, 0x70, 0x8F, + 0x2E, 0x32, 0x5A, 0xB3, 0x38, 0x1C, 0x8D, 0xCE, + 0x1A, 0x3E, 0x95, 0x88, 0x86, 0xF1, 0xEC, 0xDC, + 0x60, 0x31, 0x8F, 0x88, 0x2C, 0xFE, 0x20, 0xA2, + 0x41, 0x91, 0x35, 0x2E, 0x61, 0x7B, 0x0F, 0x21 + }, + { + 0x91, 0xAB, 0x50, 0x4A, 0x52, 0x2D, 0xCE, 0x78, + 0x77, 0x9F, 0x4C, 0x6C, 0x6B, 0xA2, 0xE6, 0xB6, + 0xDB, 0x55, 0x65, 0xC7, 0x6D, 0x3E, 0x7E, 0x7C, + 0x92, 0x0C, 0xAF, 0x7F, 0x75, 0x7E, 0xF9, 0xDB, + 0x7C, 0x8F, 0xCF, 0x10, 0xE5, 0x7F, 0x03, 0x37, + 0x9E, 0xA9, 0xBF, 0x75, 0xEB, 0x59, 0x89, 0x5D, + 0x96, 0xE1, 0x49, 0x80, 0x0B, 0x6A, 0xAE, 0x01, + 0xDB, 0x77, 0x8B, 0xB9, 0x0A, 0xFB, 0xC9, 0x89 + }, + { + 0xD8, 0x5C, 0xAB, 0xC6, 0xBD, 0x5B, 0x1A, 0x01, + 0xA5, 0xAF, 0xD8, 0xC6, 0x73, 0x47, 0x40, 0xDA, + 0x9F, 0xD1, 0xC1, 0xAC, 0xC6, 0xDB, 0x29, 0xBF, + 0xC8, 0xA2, 0xE5, 0xB6, 0x68, 0xB0, 0x28, 0xB6, + 0xB3, 0x15, 0x4B, 0xFB, 0x87, 0x03, 0xFA, 0x31, + 0x80, 0x25, 0x1D, 0x58, 0x9A, 0xD3, 0x80, 0x40, + 0xCE, 0xB7, 0x07, 0xC4, 0xBA, 0xD1, 0xB5, 0x34, + 0x3C, 0xB4, 0x26, 0xB6, 0x1E, 0xAA, 0x49, 0xC1 + }, + { + 0xD6, 0x2E, 0xFB, 0xEC, 0x2C, 0xA9, 0xC1, 0xF8, + 0xBD, 0x66, 0xCE, 0x8B, 0x3F, 0x6A, 0x89, 0x8C, + 0xB3, 0xF7, 0x56, 0x6B, 0xA6, 0x56, 0x8C, 0x61, + 0x8A, 0xD1, 0xFE, 0xB2, 0xB6, 0x5B, 0x76, 0xC3, + 0xCE, 0x1D, 0xD2, 0x0F, 0x73, 0x95, 0x37, 0x2F, + 0xAF, 0x28, 0x42, 0x7F, 0x61, 0xC9, 0x27, 0x80, + 0x49, 0xCF, 0x01, 0x40, 0xDF, 0x43, 0x4F, 0x56, + 0x33, 0x04, 0x8C, 0x86, 0xB8, 0x1E, 0x03, 0x99 + }, + { + 0x7C, 0x8F, 0xDC, 0x61, 0x75, 0x43, 0x9E, 0x2C, + 0x3D, 0xB1, 0x5B, 0xAF, 0xA7, 0xFB, 0x06, 0x14, + 0x3A, 0x6A, 0x23, 0xBC, 0x90, 0xF4, 0x49, 0xE7, + 0x9D, 0xEE, 0xF7, 0x3C, 0x3D, 0x49, 0x2A, 0x67, + 0x17, 0x15, 0xC1, 0x93, 0xB6, 0xFE, 0xA9, 0xF0, + 0x36, 0x05, 0x0B, 0x94, 0x60, 0x69, 0x85, 0x6B, + 0x89, 0x7E, 0x08, 0xC0, 0x07, 0x68, 0xF5, 0xEE, + 0x5D, 0xDC, 0xF7, 0x0B, 0x7C, 0xD6, 0xD0, 0xE0 + }, + { + 0x58, 0x60, 0x2E, 0xE7, 0x46, 0x8E, 0x6B, 0xC9, + 0xDF, 0x21, 0xBD, 0x51, 0xB2, 0x3C, 0x00, 0x5F, + 0x72, 0xD6, 0xCB, 0x01, 0x3F, 0x0A, 0x1B, 0x48, + 0xCB, 0xEC, 0x5E, 0xCA, 0x29, 0x92, 0x99, 0xF9, + 0x7F, 0x09, 0xF5, 0x4A, 0x9A, 0x01, 0x48, 0x3E, + 0xAE, 0xB3, 0x15, 0xA6, 0x47, 0x8B, 0xAD, 0x37, + 0xBA, 0x47, 0xCA, 0x13, 0x47, 0xC7, 0xC8, 0xFC, + 0x9E, 0x66, 0x95, 0x59, 0x2C, 0x91, 0xD7, 0x23 + }, + { + 0x27, 0xF5, 0xB7, 0x9E, 0xD2, 0x56, 0xB0, 0x50, + 0x99, 0x3D, 0x79, 0x34, 0x96, 0xED, 0xF4, 0x80, + 0x7C, 0x1D, 0x85, 0xA7, 0xB0, 0xA6, 0x7C, 0x9C, + 0x4F, 0xA9, 0x98, 0x60, 0x75, 0x0B, 0x0A, 0xE6, + 0x69, 0x89, 0x67, 0x0A, 0x8F, 0xFD, 0x78, 0x56, + 0xD7, 0xCE, 0x41, 0x15, 0x99, 0xE5, 0x8C, 0x4D, + 0x77, 0xB2, 0x32, 0xA6, 0x2B, 0xEF, 0x64, 0xD1, + 0x52, 0x75, 0xBE, 0x46, 0xA6, 0x82, 0x35, 0xFF + }, + { + 0x39, 0x57, 0xA9, 0x76, 0xB9, 0xF1, 0x88, 0x7B, + 0xF0, 0x04, 0xA8, 0xDC, 0xA9, 0x42, 0xC9, 0x2D, + 0x2B, 0x37, 0xEA, 0x52, 0x60, 0x0F, 0x25, 0xE0, + 0xC9, 0xBC, 0x57, 0x07, 0xD0, 0x27, 0x9C, 0x00, + 0xC6, 0xE8, 0x5A, 0x83, 0x9B, 0x0D, 0x2D, 0x8E, + 0xB5, 0x9C, 0x51, 0xD9, 0x47, 0x88, 0xEB, 0xE6, + 0x24, 0x74, 0xA7, 0x91, 0xCA, 0xDF, 0x52, 0xCC, + 0xCF, 0x20, 0xF5, 0x07, 0x0B, 0x65, 0x73, 0xFC + }, + { + 0xEA, 0xA2, 0x37, 0x6D, 0x55, 0x38, 0x0B, 0xF7, + 0x72, 0xEC, 0xCA, 0x9C, 0xB0, 0xAA, 0x46, 0x68, + 0xC9, 0x5C, 0x70, 0x71, 0x62, 0xFA, 0x86, 0xD5, + 0x18, 0xC8, 0xCE, 0x0C, 0xA9, 0xBF, 0x73, 0x62, + 0xB9, 0xF2, 0xA0, 0xAD, 0xC3, 0xFF, 0x59, 0x92, + 0x2D, 0xF9, 0x21, 0xB9, 0x45, 0x67, 0xE8, 0x1E, + 0x45, 0x2F, 0x6C, 0x1A, 0x07, 0xFC, 0x81, 0x7C, + 0xEB, 0xE9, 0x96, 0x04, 0xB3, 0x50, 0x5D, 0x38 + }, + { + 0xC1, 0xE2, 0xC7, 0x8B, 0x6B, 0x27, 0x34, 0xE2, + 0x48, 0x0E, 0xC5, 0x50, 0x43, 0x4C, 0xB5, 0xD6, + 0x13, 0x11, 0x1A, 0xDC, 0xC2, 0x1D, 0x47, 0x55, + 0x45, 0xC3, 0xB1, 0xB7, 0xE6, 0xFF, 0x12, 0x44, + 0x44, 0x76, 0xE5, 0xC0, 0x55, 0x13, 0x2E, 0x22, + 0x29, 0xDC, 0x0F, 0x80, 0x70, 0x44, 0xBB, 0x91, + 0x9B, 0x1A, 0x56, 0x62, 0xDD, 0x38, 0xA9, 0xEE, + 0x65, 0xE2, 0x43, 0xA3, 0x91, 0x1A, 0xED, 0x1A + }, + { + 0x8A, 0xB4, 0x87, 0x13, 0x38, 0x9D, 0xD0, 0xFC, + 0xF9, 0xF9, 0x65, 0xD3, 0xCE, 0x66, 0xB1, 0xE5, + 0x59, 0xA1, 0xF8, 0xC5, 0x87, 0x41, 0xD6, 0x76, + 0x83, 0xCD, 0x97, 0x13, 0x54, 0xF4, 0x52, 0xE6, + 0x2D, 0x02, 0x07, 0xA6, 0x5E, 0x43, 0x6C, 0x5D, + 0x5D, 0x8F, 0x8E, 0xE7, 0x1C, 0x6A, 0xBF, 0xE5, + 0x0E, 0x66, 0x90, 0x04, 0xC3, 0x02, 0xB3, 0x1A, + 0x7E, 0xA8, 0x31, 0x1D, 0x4A, 0x91, 0x60, 0x51 + }, + { + 0x24, 0xCE, 0x0A, 0xDD, 0xAA, 0x4C, 0x65, 0x03, + 0x8B, 0xD1, 0xB1, 0xC0, 0xF1, 0x45, 0x2A, 0x0B, + 0x12, 0x87, 0x77, 0xAA, 0xBC, 0x94, 0xA2, 0x9D, + 0xF2, 0xFD, 0x6C, 0x7E, 0x2F, 0x85, 0xF8, 0xAB, + 0x9A, 0xC7, 0xEF, 0xF5, 0x16, 0xB0, 0xE0, 0xA8, + 0x25, 0xC8, 0x4A, 0x24, 0xCF, 0xE4, 0x92, 0xEA, + 0xAD, 0x0A, 0x63, 0x08, 0xE4, 0x6D, 0xD4, 0x2F, + 0xE8, 0x33, 0x3A, 0xB9, 0x71, 0xBB, 0x30, 0xCA + }, + { + 0x51, 0x54, 0xF9, 0x29, 0xEE, 0x03, 0x04, 0x5B, + 0x6B, 0x0C, 0x00, 0x04, 0xFA, 0x77, 0x8E, 0xDE, + 0xE1, 0xD1, 0x39, 0x89, 0x32, 0x67, 0xCC, 0x84, + 0x82, 0x5A, 0xD7, 0xB3, 0x6C, 0x63, 0xDE, 0x32, + 0x79, 0x8E, 0x4A, 0x16, 0x6D, 0x24, 0x68, 0x65, + 0x61, 0x35, 0x4F, 0x63, 0xB0, 0x07, 0x09, 0xA1, + 0x36, 0x4B, 0x3C, 0x24, 0x1D, 0xE3, 0xFE, 0xBF, + 0x07, 0x54, 0x04, 0x58, 0x97, 0x46, 0x7C, 0xD4 + }, + { + 0xE7, 0x4E, 0x90, 0x79, 0x20, 0xFD, 0x87, 0xBD, + 0x5A, 0xD6, 0x36, 0xDD, 0x11, 0x08, 0x5E, 0x50, + 0xEE, 0x70, 0x45, 0x9C, 0x44, 0x3E, 0x1C, 0xE5, + 0x80, 0x9A, 0xF2, 0xBC, 0x2E, 0xBA, 0x39, 0xF9, + 0xE6, 0xD7, 0x12, 0x8E, 0x0E, 0x37, 0x12, 0xC3, + 0x16, 0xDA, 0x06, 0xF4, 0x70, 0x5D, 0x78, 0xA4, + 0x83, 0x8E, 0x28, 0x12, 0x1D, 0x43, 0x44, 0xA2, + 0xC7, 0x9C, 0x5E, 0x0D, 0xB3, 0x07, 0xA6, 0x77 + }, + { + 0xBF, 0x91, 0xA2, 0x23, 0x34, 0xBA, 0xC2, 0x0F, + 0x3F, 0xD8, 0x06, 0x63, 0xB3, 0xCD, 0x06, 0xC4, + 0xE8, 0x80, 0x2F, 0x30, 0xE6, 0xB5, 0x9F, 0x90, + 0xD3, 0x03, 0x5C, 0xC9, 0x79, 0x8A, 0x21, 0x7E, + 0xD5, 0xA3, 0x1A, 0xBB, 0xDA, 0x7F, 0xA6, 0x84, + 0x28, 0x27, 0xBD, 0xF2, 0xA7, 0xA1, 0xC2, 0x1F, + 0x6F, 0xCF, 0xCC, 0xBB, 0x54, 0xC6, 0xC5, 0x29, + 0x26, 0xF3, 0x2D, 0xA8, 0x16, 0x26, 0x9B, 0xE1 + }, + { + 0xD9, 0xD5, 0xC7, 0x4B, 0xE5, 0x12, 0x1B, 0x0B, + 0xD7, 0x42, 0xF2, 0x6B, 0xFF, 0xB8, 0xC8, 0x9F, + 0x89, 0x17, 0x1F, 0x3F, 0x93, 0x49, 0x13, 0x49, + 0x2B, 0x09, 0x03, 0xC2, 0x71, 0xBB, 0xE2, 0xB3, + 0x39, 0x5E, 0xF2, 0x59, 0x66, 0x9B, 0xEF, 0x43, + 0xB5, 0x7F, 0x7F, 0xCC, 0x30, 0x27, 0xDB, 0x01, + 0x82, 0x3F, 0x6B, 0xAE, 0xE6, 0x6E, 0x4F, 0x9F, + 0xEA, 0xD4, 0xD6, 0x72, 0x6C, 0x74, 0x1F, 0xCE + }, + { + 0x50, 0xC8, 0xB8, 0xCF, 0x34, 0xCD, 0x87, 0x9F, + 0x80, 0xE2, 0xFA, 0xAB, 0x32, 0x30, 0xB0, 0xC0, + 0xE1, 0xCC, 0x3E, 0x9D, 0xCA, 0xDE, 0xB1, 0xB9, + 0xD9, 0x7A, 0xB9, 0x23, 0x41, 0x5D, 0xD9, 0xA1, + 0xFE, 0x38, 0xAD, 0xDD, 0x5C, 0x11, 0x75, 0x6C, + 0x67, 0x99, 0x0B, 0x25, 0x6E, 0x95, 0xAD, 0x6D, + 0x8F, 0x9F, 0xED, 0xCE, 0x10, 0xBF, 0x1C, 0x90, + 0x67, 0x9C, 0xDE, 0x0E, 0xCF, 0x1B, 0xE3, 0x47 + }, + { + 0x0A, 0x38, 0x6E, 0x7C, 0xD5, 0xDD, 0x9B, 0x77, + 0xA0, 0x35, 0xE0, 0x9F, 0xE6, 0xFE, 0xE2, 0xC8, + 0xCE, 0x61, 0xB5, 0x38, 0x3C, 0x87, 0xEA, 0x43, + 0x20, 0x50, 0x59, 0xC5, 0xE4, 0xCD, 0x4F, 0x44, + 0x08, 0x31, 0x9B, 0xB0, 0xA8, 0x23, 0x60, 0xF6, + 0xA5, 0x8E, 0x6C, 0x9C, 0xE3, 0xF4, 0x87, 0xC4, + 0x46, 0x06, 0x3B, 0xF8, 0x13, 0xBC, 0x6B, 0xA5, + 0x35, 0xE1, 0x7F, 0xC1, 0x82, 0x6C, 0xFC, 0x91 + }, + { + 0x1F, 0x14, 0x59, 0xCB, 0x6B, 0x61, 0xCB, 0xAC, + 0x5F, 0x0E, 0xFE, 0x8F, 0xC4, 0x87, 0x53, 0x8F, + 0x42, 0x54, 0x89, 0x87, 0xFC, 0xD5, 0x62, 0x21, + 0xCF, 0xA7, 0xBE, 0xB2, 0x25, 0x04, 0x76, 0x9E, + 0x79, 0x2C, 0x45, 0xAD, 0xFB, 0x1D, 0x6B, 0x3D, + 0x60, 0xD7, 0xB7, 0x49, 0xC8, 0xA7, 0x5B, 0x0B, + 0xDF, 0x14, 0xE8, 0xEA, 0x72, 0x1B, 0x95, 0xDC, + 0xA5, 0x38, 0xCA, 0x6E, 0x25, 0x71, 0x12, 0x09 + }, + { + 0xE5, 0x8B, 0x38, 0x36, 0xB7, 0xD8, 0xFE, 0xDB, + 0xB5, 0x0C, 0xA5, 0x72, 0x5C, 0x65, 0x71, 0xE7, + 0x4C, 0x07, 0x85, 0xE9, 0x78, 0x21, 0xDA, 0xB8, + 0xB6, 0x29, 0x8C, 0x10, 0xE4, 0xC0, 0x79, 0xD4, + 0xA6, 0xCD, 0xF2, 0x2F, 0x0F, 0xED, 0xB5, 0x50, + 0x32, 0x92, 0x5C, 0x16, 0x74, 0x81, 0x15, 0xF0, + 0x1A, 0x10, 0x5E, 0x77, 0xE0, 0x0C, 0xEE, 0x3D, + 0x07, 0x92, 0x4D, 0xC0, 0xD8, 0xF9, 0x06, 0x59 + }, + { + 0xB9, 0x29, 0xCC, 0x65, 0x05, 0xF0, 0x20, 0x15, + 0x86, 0x72, 0xDE, 0xDA, 0x56, 0xD0, 0xDB, 0x08, + 0x1A, 0x2E, 0xE3, 0x4C, 0x00, 0xC1, 0x10, 0x00, + 0x29, 0xBD, 0xF8, 0xEA, 0x98, 0x03, 0x4F, 0xA4, + 0xBF, 0x3E, 0x86, 0x55, 0xEC, 0x69, 0x7F, 0xE3, + 0x6F, 0x40, 0x55, 0x3C, 0x5B, 0xB4, 0x68, 0x01, + 0x64, 0x4A, 0x62, 0x7D, 0x33, 0x42, 0xF4, 0xFC, + 0x92, 0xB6, 0x1F, 0x03, 0x29, 0x0F, 0xB3, 0x81 + }, + { + 0x72, 0xD3, 0x53, 0x99, 0x4B, 0x49, 0xD3, 0xE0, + 0x31, 0x53, 0x92, 0x9A, 0x1E, 0x4D, 0x4F, 0x18, + 0x8E, 0xE5, 0x8A, 0xB9, 0xE7, 0x2E, 0xE8, 0xE5, + 0x12, 0xF2, 0x9B, 0xC7, 0x73, 0x91, 0x38, 0x19, + 0xCE, 0x05, 0x7D, 0xDD, 0x70, 0x02, 0xC0, 0x43, + 0x3E, 0xE0, 0xA1, 0x61, 0x14, 0xE3, 0xD1, 0x56, + 0xDD, 0x2C, 0x4A, 0x7E, 0x80, 0xEE, 0x53, 0x37, + 0x8B, 0x86, 0x70, 0xF2, 0x3E, 0x33, 0xEF, 0x56 + }, + { + 0xC7, 0x0E, 0xF9, 0xBF, 0xD7, 0x75, 0xD4, 0x08, + 0x17, 0x67, 0x37, 0xA0, 0x73, 0x6D, 0x68, 0x51, + 0x7C, 0xE1, 0xAA, 0xAD, 0x7E, 0x81, 0xA9, 0x3C, + 0x8C, 0x1E, 0xD9, 0x67, 0xEA, 0x21, 0x4F, 0x56, + 0xC8, 0xA3, 0x77, 0xB1, 0x76, 0x3E, 0x67, 0x66, + 0x15, 0xB6, 0x0F, 0x39, 0x88, 0x24, 0x1E, 0xAE, + 0x6E, 0xAB, 0x96, 0x85, 0xA5, 0x12, 0x49, 0x29, + 0xD2, 0x81, 0x88, 0xF2, 0x9E, 0xAB, 0x06, 0xF7 + }, + { + 0xC2, 0x30, 0xF0, 0x80, 0x26, 0x79, 0xCB, 0x33, + 0x82, 0x2E, 0xF8, 0xB3, 0xB2, 0x1B, 0xF7, 0xA9, + 0xA2, 0x89, 0x42, 0x09, 0x29, 0x01, 0xD7, 0xDA, + 0xC3, 0x76, 0x03, 0x00, 0x83, 0x10, 0x26, 0xCF, + 0x35, 0x4C, 0x92, 0x32, 0xDF, 0x3E, 0x08, 0x4D, + 0x99, 0x03, 0x13, 0x0C, 0x60, 0x1F, 0x63, 0xC1, + 0xF4, 0xA4, 0xA4, 0xB8, 0x10, 0x6E, 0x46, 0x8C, + 0xD4, 0x43, 0xBB, 0xE5, 0xA7, 0x34, 0xF4, 0x5F + }, + { + 0x6F, 0x43, 0x09, 0x4C, 0xAF, 0xB5, 0xEB, 0xF1, + 0xF7, 0xA4, 0x93, 0x7E, 0xC5, 0x0F, 0x56, 0xA4, + 0xC9, 0xDA, 0x30, 0x3C, 0xBB, 0x55, 0xAC, 0x1F, + 0x27, 0xF1, 0xF1, 0x97, 0x6C, 0xD9, 0x6B, 0xED, + 0xA9, 0x46, 0x4F, 0x0E, 0x7B, 0x9C, 0x54, 0x62, + 0x0B, 0x8A, 0x9F, 0xBA, 0x98, 0x31, 0x64, 0xB8, + 0xBE, 0x35, 0x78, 0x42, 0x5A, 0x02, 0x4F, 0x5F, + 0xE1, 0x99, 0xC3, 0x63, 0x56, 0xB8, 0x89, 0x72 + }, + { + 0x37, 0x45, 0x27, 0x3F, 0x4C, 0x38, 0x22, 0x5D, + 0xB2, 0x33, 0x73, 0x81, 0x87, 0x1A, 0x0C, 0x6A, + 0xAF, 0xD3, 0xAF, 0x9B, 0x01, 0x8C, 0x88, 0xAA, + 0x02, 0x02, 0x58, 0x50, 0xA5, 0xDC, 0x3A, 0x42, + 0xA1, 0xA3, 0xE0, 0x3E, 0x56, 0xCB, 0xF1, 0xB0, + 0x87, 0x6D, 0x63, 0xA4, 0x41, 0xF1, 0xD2, 0x85, + 0x6A, 0x39, 0xB8, 0x80, 0x1E, 0xB5, 0xAF, 0x32, + 0x52, 0x01, 0xC4, 0x15, 0xD6, 0x5E, 0x97, 0xFE + }, + { + 0xC5, 0x0C, 0x44, 0xCC, 0xA3, 0xEC, 0x3E, 0xDA, + 0xAE, 0x77, 0x9A, 0x7E, 0x17, 0x94, 0x50, 0xEB, + 0xDD, 0xA2, 0xF9, 0x70, 0x67, 0xC6, 0x90, 0xAA, + 0x6C, 0x5A, 0x4A, 0xC7, 0xC3, 0x01, 0x39, 0xBB, + 0x27, 0xC0, 0xDF, 0x4D, 0xB3, 0x22, 0x0E, 0x63, + 0xCB, 0x11, 0x0D, 0x64, 0xF3, 0x7F, 0xFE, 0x07, + 0x8D, 0xB7, 0x26, 0x53, 0xE2, 0xDA, 0xAC, 0xF9, + 0x3A, 0xE3, 0xF0, 0xA2, 0xD1, 0xA7, 0xEB, 0x2E + }, + { + 0x8A, 0xEF, 0x26, 0x3E, 0x38, 0x5C, 0xBC, 0x61, + 0xE1, 0x9B, 0x28, 0x91, 0x42, 0x43, 0x26, 0x2A, + 0xF5, 0xAF, 0xE8, 0x72, 0x6A, 0xF3, 0xCE, 0x39, + 0xA7, 0x9C, 0x27, 0x02, 0x8C, 0xF3, 0xEC, 0xD3, + 0xF8, 0xD2, 0xDF, 0xD9, 0xCF, 0xC9, 0xAD, 0x91, + 0xB5, 0x8F, 0x6F, 0x20, 0x77, 0x8F, 0xD5, 0xF0, + 0x28, 0x94, 0xA3, 0xD9, 0x1C, 0x7D, 0x57, 0xD1, + 0xE4, 0xB8, 0x66, 0xA7, 0xF3, 0x64, 0xB6, 0xBE + }, + { + 0x28, 0x69, 0x61, 0x41, 0xDE, 0x6E, 0x2D, 0x9B, + 0xCB, 0x32, 0x35, 0x57, 0x8A, 0x66, 0x16, 0x6C, + 0x14, 0x48, 0xD3, 0xE9, 0x05, 0xA1, 0xB4, 0x82, + 0xD4, 0x23, 0xBE, 0x4B, 0xC5, 0x36, 0x9B, 0xC8, + 0xC7, 0x4D, 0xAE, 0x0A, 0xCC, 0x9C, 0xC1, 0x23, + 0xE1, 0xD8, 0xDD, 0xCE, 0x9F, 0x97, 0x91, 0x7E, + 0x8C, 0x01, 0x9C, 0x55, 0x2D, 0xA3, 0x2D, 0x39, + 0xD2, 0x21, 0x9B, 0x9A, 0xBF, 0x0F, 0xA8, 0xC8 + }, + { + 0x2F, 0xB9, 0xEB, 0x20, 0x85, 0x83, 0x01, 0x81, + 0x90, 0x3A, 0x9D, 0xAF, 0xE3, 0xDB, 0x42, 0x8E, + 0xE1, 0x5B, 0xE7, 0x66, 0x22, 0x24, 0xEF, 0xD6, + 0x43, 0x37, 0x1F, 0xB2, 0x56, 0x46, 0xAE, 0xE7, + 0x16, 0xE5, 0x31, 0xEC, 0xA6, 0x9B, 0x2B, 0xDC, + 0x82, 0x33, 0xF1, 0xA8, 0x08, 0x1F, 0xA4, 0x3D, + 0xA1, 0x50, 0x03, 0x02, 0x97, 0x5A, 0x77, 0xF4, + 0x2F, 0xA5, 0x92, 0x13, 0x67, 0x10, 0xE9, 0xDC + }, + { + 0x66, 0xF9, 0xA7, 0x14, 0x3F, 0x7A, 0x33, 0x14, + 0xA6, 0x69, 0xBF, 0x2E, 0x24, 0xBB, 0xB3, 0x50, + 0x14, 0x26, 0x1D, 0x63, 0x9F, 0x49, 0x5B, 0x6C, + 0x9C, 0x1F, 0x10, 0x4F, 0xE8, 0xE3, 0x20, 0xAC, + 0xA6, 0x0D, 0x45, 0x50, 0xD6, 0x9D, 0x52, 0xED, + 0xBD, 0x5A, 0x3C, 0xDE, 0xB4, 0x01, 0x4A, 0xE6, + 0x5B, 0x1D, 0x87, 0xAA, 0x77, 0x0B, 0x69, 0xAE, + 0x5C, 0x15, 0xF4, 0x33, 0x0B, 0x0B, 0x0A, 0xD8 + }, + { + 0xF4, 0xC4, 0xDD, 0x1D, 0x59, 0x4C, 0x35, 0x65, + 0xE3, 0xE2, 0x5C, 0xA4, 0x3D, 0xAD, 0x82, 0xF6, + 0x2A, 0xBE, 0xA4, 0x83, 0x5E, 0xD4, 0xCD, 0x81, + 0x1B, 0xCD, 0x97, 0x5E, 0x46, 0x27, 0x98, 0x28, + 0xD4, 0x4D, 0x4C, 0x62, 0xC3, 0x67, 0x9F, 0x1B, + 0x7F, 0x7B, 0x9D, 0xD4, 0x57, 0x1D, 0x7B, 0x49, + 0x55, 0x73, 0x47, 0xB8, 0xC5, 0x46, 0x0C, 0xBD, + 0xC1, 0xBE, 0xF6, 0x90, 0xFB, 0x2A, 0x08, 0xC0 + }, + { + 0x8F, 0x1D, 0xC9, 0x64, 0x9C, 0x3A, 0x84, 0x55, + 0x1F, 0x8F, 0x6E, 0x91, 0xCA, 0xC6, 0x82, 0x42, + 0xA4, 0x3B, 0x1F, 0x8F, 0x32, 0x8E, 0xE9, 0x22, + 0x80, 0x25, 0x73, 0x87, 0xFA, 0x75, 0x59, 0xAA, + 0x6D, 0xB1, 0x2E, 0x4A, 0xEA, 0xDC, 0x2D, 0x26, + 0x09, 0x91, 0x78, 0x74, 0x9C, 0x68, 0x64, 0xB3, + 0x57, 0xF3, 0xF8, 0x3B, 0x2F, 0xB3, 0xEF, 0xA8, + 0xD2, 0xA8, 0xDB, 0x05, 0x6B, 0xED, 0x6B, 0xCC + }, + { + 0x31, 0x39, 0xC1, 0xA7, 0xF9, 0x7A, 0xFD, 0x16, + 0x75, 0xD4, 0x60, 0xEB, 0xBC, 0x07, 0xF2, 0x72, + 0x8A, 0xA1, 0x50, 0xDF, 0x84, 0x96, 0x24, 0x51, + 0x1E, 0xE0, 0x4B, 0x74, 0x3B, 0xA0, 0xA8, 0x33, + 0x09, 0x2F, 0x18, 0xC1, 0x2D, 0xC9, 0x1B, 0x4D, + 0xD2, 0x43, 0xF3, 0x33, 0x40, 0x2F, 0x59, 0xFE, + 0x28, 0xAB, 0xDB, 0xBB, 0xAE, 0x30, 0x1E, 0x7B, + 0x65, 0x9C, 0x7A, 0x26, 0xD5, 0xC0, 0xF9, 0x79 + }, + { + 0x06, 0xF9, 0x4A, 0x29, 0x96, 0x15, 0x8A, 0x81, + 0x9F, 0xE3, 0x4C, 0x40, 0xDE, 0x3C, 0xF0, 0x37, + 0x9F, 0xD9, 0xFB, 0x85, 0xB3, 0xE3, 0x63, 0xBA, + 0x39, 0x26, 0xA0, 0xE7, 0xD9, 0x60, 0xE3, 0xF4, + 0xC2, 0xE0, 0xC7, 0x0C, 0x7C, 0xE0, 0xCC, 0xB2, + 0xA6, 0x4F, 0xC2, 0x98, 0x69, 0xF6, 0xE7, 0xAB, + 0x12, 0xBD, 0x4D, 0x3F, 0x14, 0xFC, 0xE9, 0x43, + 0x27, 0x90, 0x27, 0xE7, 0x85, 0xFB, 0x5C, 0x29 + }, + { + 0xC2, 0x9C, 0x39, 0x9E, 0xF3, 0xEE, 0xE8, 0x96, + 0x1E, 0x87, 0x56, 0x5C, 0x1C, 0xE2, 0x63, 0x92, + 0x5F, 0xC3, 0xD0, 0xCE, 0x26, 0x7D, 0x13, 0xE4, + 0x8D, 0xD9, 0xE7, 0x32, 0xEE, 0x67, 0xB0, 0xF6, + 0x9F, 0xAD, 0x56, 0x40, 0x1B, 0x0F, 0x10, 0xFC, + 0xAA, 0xC1, 0x19, 0x20, 0x10, 0x46, 0xCC, 0xA2, + 0x8C, 0x5B, 0x14, 0xAB, 0xDE, 0xA3, 0x21, 0x2A, + 0xE6, 0x55, 0x62, 0xF7, 0xF1, 0x38, 0xDB, 0x3D + }, + { + 0x4C, 0xEC, 0x4C, 0x9D, 0xF5, 0x2E, 0xEF, 0x05, + 0xC3, 0xF6, 0xFA, 0xAA, 0x97, 0x91, 0xBC, 0x74, + 0x45, 0x93, 0x71, 0x83, 0x22, 0x4E, 0xCC, 0x37, + 0xA1, 0xE5, 0x8D, 0x01, 0x32, 0xD3, 0x56, 0x17, + 0x53, 0x1D, 0x7E, 0x79, 0x5F, 0x52, 0xAF, 0x7B, + 0x1E, 0xB9, 0xD1, 0x47, 0xDE, 0x12, 0x92, 0xD3, + 0x45, 0xFE, 0x34, 0x18, 0x23, 0xF8, 0xE6, 0xBC, + 0x1E, 0x5B, 0xAD, 0xCA, 0x5C, 0x65, 0x61, 0x08 + }, + { + 0x89, 0x8B, 0xFB, 0xAE, 0x93, 0xB3, 0xE1, 0x8D, + 0x00, 0x69, 0x7E, 0xAB, 0x7D, 0x97, 0x04, 0xFA, + 0x36, 0xEC, 0x33, 0x9D, 0x07, 0x61, 0x31, 0xCE, + 0xFD, 0xF3, 0x0E, 0xDB, 0xE8, 0xD9, 0xCC, 0x81, + 0xC3, 0xA8, 0x0B, 0x12, 0x96, 0x59, 0xB1, 0x63, + 0xA3, 0x23, 0xBA, 0xB9, 0x79, 0x3D, 0x4F, 0xEE, + 0xD9, 0x2D, 0x54, 0xDA, 0xE9, 0x66, 0xC7, 0x75, + 0x29, 0x76, 0x4A, 0x09, 0xBE, 0x88, 0xDB, 0x45 + }, + { + 0xEE, 0x9B, 0xD0, 0x46, 0x9D, 0x3A, 0xAF, 0x4F, + 0x14, 0x03, 0x5B, 0xE4, 0x8A, 0x2C, 0x3B, 0x84, + 0xD9, 0xB4, 0xB1, 0xFF, 0xF1, 0xD9, 0x45, 0xE1, + 0xF1, 0xC1, 0xD3, 0x89, 0x80, 0xA9, 0x51, 0xBE, + 0x19, 0x7B, 0x25, 0xFE, 0x22, 0xC7, 0x31, 0xF2, + 0x0A, 0xEA, 0xCC, 0x93, 0x0B, 0xA9, 0xC4, 0xA1, + 0xF4, 0x76, 0x22, 0x27, 0x61, 0x7A, 0xD3, 0x50, + 0xFD, 0xAB, 0xB4, 0xE8, 0x02, 0x73, 0xA0, 0xF4 + }, + { + 0x3D, 0x4D, 0x31, 0x13, 0x30, 0x05, 0x81, 0xCD, + 0x96, 0xAC, 0xBF, 0x09, 0x1C, 0x3D, 0x0F, 0x3C, + 0x31, 0x01, 0x38, 0xCD, 0x69, 0x79, 0xE6, 0x02, + 0x6C, 0xDE, 0x62, 0x3E, 0x2D, 0xD1, 0xB2, 0x4D, + 0x4A, 0x86, 0x38, 0xBE, 0xD1, 0x07, 0x33, 0x44, + 0x78, 0x3A, 0xD0, 0x64, 0x9C, 0xC6, 0x30, 0x5C, + 0xCE, 0xC0, 0x4B, 0xEB, 0x49, 0xF3, 0x1C, 0x63, + 0x30, 0x88, 0xA9, 0x9B, 0x65, 0x13, 0x02, 0x67 + }, + { + 0x95, 0xC0, 0x59, 0x1A, 0xD9, 0x1F, 0x92, 0x1A, + 0xC7, 0xBE, 0x6D, 0x9C, 0xE3, 0x7E, 0x06, 0x63, + 0xED, 0x80, 0x11, 0xC1, 0xCF, 0xD6, 0xD0, 0x16, + 0x2A, 0x55, 0x72, 0xE9, 0x43, 0x68, 0xBA, 0xC0, + 0x20, 0x24, 0x48, 0x5E, 0x6A, 0x39, 0x85, 0x4A, + 0xA4, 0x6F, 0xE3, 0x8E, 0x97, 0xD6, 0xC6, 0xB1, + 0x94, 0x7C, 0xD2, 0x72, 0xD8, 0x6B, 0x06, 0xBB, + 0x5B, 0x2F, 0x78, 0xB9, 0xB6, 0x8D, 0x55, 0x9D + }, + { + 0x22, 0x7B, 0x79, 0xDE, 0xD3, 0x68, 0x15, 0x3B, + 0xF4, 0x6C, 0x0A, 0x3C, 0xA9, 0x78, 0xBF, 0xDB, + 0xEF, 0x31, 0xF3, 0x02, 0x4A, 0x56, 0x65, 0x84, + 0x24, 0x68, 0x49, 0x0B, 0x0F, 0xF7, 0x48, 0xAE, + 0x04, 0xE7, 0x83, 0x2E, 0xD4, 0xC9, 0xF4, 0x9D, + 0xE9, 0xB1, 0x70, 0x67, 0x09, 0xD6, 0x23, 0xE5, + 0xC8, 0xC1, 0x5E, 0x3C, 0xAE, 0xCA, 0xE8, 0xD5, + 0xE4, 0x33, 0x43, 0x0F, 0xF7, 0x2F, 0x20, 0xEB + }, + { + 0x5D, 0x34, 0xF3, 0x95, 0x2F, 0x01, 0x05, 0xEE, + 0xF8, 0x8A, 0xE8, 0xB6, 0x4C, 0x6C, 0xE9, 0x5E, + 0xBF, 0xAD, 0xE0, 0xE0, 0x2C, 0x69, 0xB0, 0x87, + 0x62, 0xA8, 0x71, 0x2D, 0x2E, 0x49, 0x11, 0xAD, + 0x3F, 0x94, 0x1F, 0xC4, 0x03, 0x4D, 0xC9, 0xB2, + 0xE4, 0x79, 0xFD, 0xBC, 0xD2, 0x79, 0xB9, 0x02, + 0xFA, 0xF5, 0xD8, 0x38, 0xBB, 0x2E, 0x0C, 0x64, + 0x95, 0xD3, 0x72, 0xB5, 0xB7, 0x02, 0x98, 0x13 + }, + { + 0x7F, 0x93, 0x9B, 0xF8, 0x35, 0x3A, 0xBC, 0xE4, + 0x9E, 0x77, 0xF1, 0x4F, 0x37, 0x50, 0xAF, 0x20, + 0xB7, 0xB0, 0x39, 0x02, 0xE1, 0xA1, 0xE7, 0xFB, + 0x6A, 0xAF, 0x76, 0xD0, 0x25, 0x9C, 0xD4, 0x01, + 0xA8, 0x31, 0x90, 0xF1, 0x56, 0x40, 0xE7, 0x4F, + 0x3E, 0x6C, 0x5A, 0x90, 0xE8, 0x39, 0xC7, 0x82, + 0x1F, 0x64, 0x74, 0x75, 0x7F, 0x75, 0xC7, 0xBF, + 0x90, 0x02, 0x08, 0x4D, 0xDC, 0x7A, 0x62, 0xDC + }, + { + 0x06, 0x2B, 0x61, 0xA2, 0xF9, 0xA3, 0x3A, 0x71, + 0xD7, 0xD0, 0xA0, 0x61, 0x19, 0x64, 0x4C, 0x70, + 0xB0, 0x71, 0x6A, 0x50, 0x4D, 0xE7, 0xE5, 0xE1, + 0xBE, 0x49, 0xBD, 0x7B, 0x86, 0xE7, 0xED, 0x68, + 0x17, 0x71, 0x4F, 0x9F, 0x0F, 0xC3, 0x13, 0xD0, + 0x61, 0x29, 0x59, 0x7E, 0x9A, 0x22, 0x35, 0xEC, + 0x85, 0x21, 0xDE, 0x36, 0xF7, 0x29, 0x0A, 0x90, + 0xCC, 0xFC, 0x1F, 0xFA, 0x6D, 0x0A, 0xEE, 0x29 + }, + { + 0xF2, 0x9E, 0x01, 0xEE, 0xAE, 0x64, 0x31, 0x1E, + 0xB7, 0xF1, 0xC6, 0x42, 0x2F, 0x94, 0x6B, 0xF7, + 0xBE, 0xA3, 0x63, 0x79, 0x52, 0x3E, 0x7B, 0x2B, + 0xBA, 0xBA, 0x7D, 0x1D, 0x34, 0xA2, 0x2D, 0x5E, + 0xA5, 0xF1, 0xC5, 0xA0, 0x9D, 0x5C, 0xE1, 0xFE, + 0x68, 0x2C, 0xCE, 0xD9, 0xA4, 0x79, 0x8D, 0x1A, + 0x05, 0xB4, 0x6C, 0xD7, 0x2D, 0xFF, 0x5C, 0x1B, + 0x35, 0x54, 0x40, 0xB2, 0xA2, 0xD4, 0x76, 0xBC + }, + { + 0xEC, 0x38, 0xCD, 0x3B, 0xBA, 0xB3, 0xEF, 0x35, + 0xD7, 0xCB, 0x6D, 0x5C, 0x91, 0x42, 0x98, 0x35, + 0x1D, 0x8A, 0x9D, 0xC9, 0x7F, 0xCE, 0xE0, 0x51, + 0xA8, 0xA0, 0x2F, 0x58, 0xE3, 0xED, 0x61, 0x84, + 0xD0, 0xB7, 0x81, 0x0A, 0x56, 0x15, 0x41, 0x1A, + 0xB1, 0xB9, 0x52, 0x09, 0xC3, 0xC8, 0x10, 0x11, + 0x4F, 0xDE, 0xB2, 0x24, 0x52, 0x08, 0x4E, 0x77, + 0xF3, 0xF8, 0x47, 0xC6, 0xDB, 0xAA, 0xFE, 0x16 + }, + { + 0xC2, 0xAE, 0xF5, 0xE0, 0xCA, 0x43, 0xE8, 0x26, + 0x41, 0x56, 0x5B, 0x8C, 0xB9, 0x43, 0xAA, 0x8B, + 0xA5, 0x35, 0x50, 0xCA, 0xEF, 0x79, 0x3B, 0x65, + 0x32, 0xFA, 0xFA, 0xD9, 0x4B, 0x81, 0x60, 0x82, + 0xF0, 0x11, 0x3A, 0x3E, 0xA2, 0xF6, 0x36, 0x08, + 0xAB, 0x40, 0x43, 0x7E, 0xCC, 0x0F, 0x02, 0x29, + 0xCB, 0x8F, 0xA2, 0x24, 0xDC, 0xF1, 0xC4, 0x78, + 0xA6, 0x7D, 0x9B, 0x64, 0x16, 0x2B, 0x92, 0xD1 + }, + { + 0x15, 0xF5, 0x34, 0xEF, 0xFF, 0x71, 0x05, 0xCD, + 0x1C, 0x25, 0x4D, 0x07, 0x4E, 0x27, 0xD5, 0x89, + 0x8B, 0x89, 0x31, 0x3B, 0x7D, 0x36, 0x6D, 0xC2, + 0xD7, 0xD8, 0x71, 0x13, 0xFA, 0x7D, 0x53, 0xAA, + 0xE1, 0x3F, 0x6D, 0xBA, 0x48, 0x7A, 0xD8, 0x10, + 0x3D, 0x5E, 0x85, 0x4C, 0x91, 0xFD, 0xB6, 0xE1, + 0xE7, 0x4B, 0x2E, 0xF6, 0xD1, 0x43, 0x17, 0x69, + 0xC3, 0x07, 0x67, 0xDD, 0xE0, 0x67, 0xA3, 0x5C + }, + { + 0x89, 0xAC, 0xBC, 0xA0, 0xB1, 0x69, 0x89, 0x7A, + 0x0A, 0x27, 0x14, 0xC2, 0xDF, 0x8C, 0x95, 0xB5, + 0xB7, 0x9C, 0xB6, 0x93, 0x90, 0x14, 0x2B, 0x7D, + 0x60, 0x18, 0xBB, 0x3E, 0x30, 0x76, 0xB0, 0x99, + 0xB7, 0x9A, 0x96, 0x41, 0x52, 0xA9, 0xD9, 0x12, + 0xB1, 0xB8, 0x64, 0x12, 0xB7, 0xE3, 0x72, 0xE9, + 0xCE, 0xCA, 0xD7, 0xF2, 0x5D, 0x4C, 0xBA, 0xB8, + 0xA3, 0x17, 0xBE, 0x36, 0x49, 0x2A, 0x67, 0xD7 + }, + { + 0xE3, 0xC0, 0x73, 0x91, 0x90, 0xED, 0x84, 0x9C, + 0x9C, 0x96, 0x2F, 0xD9, 0xDB, 0xB5, 0x5E, 0x20, + 0x7E, 0x62, 0x4F, 0xCA, 0xC1, 0xEB, 0x41, 0x76, + 0x91, 0x51, 0x54, 0x99, 0xEE, 0xA8, 0xD8, 0x26, + 0x7B, 0x7E, 0x8F, 0x12, 0x87, 0xA6, 0x36, 0x33, + 0xAF, 0x50, 0x11, 0xFD, 0xE8, 0xC4, 0xDD, 0xF5, + 0x5B, 0xFD, 0xF7, 0x22, 0xED, 0xF8, 0x88, 0x31, + 0x41, 0x4F, 0x2C, 0xFA, 0xED, 0x59, 0xCB, 0x9A + }, + { + 0x8D, 0x6C, 0xF8, 0x7C, 0x08, 0x38, 0x0D, 0x2D, + 0x15, 0x06, 0xEE, 0xE4, 0x6F, 0xD4, 0x22, 0x2D, + 0x21, 0xD8, 0xC0, 0x4E, 0x58, 0x5F, 0xBF, 0xD0, + 0x82, 0x69, 0xC9, 0x8F, 0x70, 0x28, 0x33, 0xA1, + 0x56, 0x32, 0x6A, 0x07, 0x24, 0x65, 0x64, 0x00, + 0xEE, 0x09, 0x35, 0x1D, 0x57, 0xB4, 0x40, 0x17, + 0x5E, 0x2A, 0x5D, 0xE9, 0x3C, 0xC5, 0xF8, 0x0D, + 0xB6, 0xDA, 0xF8, 0x35, 0x76, 0xCF, 0x75, 0xFA + }, + { + 0xDA, 0x24, 0xBE, 0xDE, 0x38, 0x36, 0x66, 0xD5, + 0x63, 0xEE, 0xED, 0x37, 0xF6, 0x31, 0x9B, 0xAF, + 0x20, 0xD5, 0xC7, 0x5D, 0x16, 0x35, 0xA6, 0xBA, + 0x5E, 0xF4, 0xCF, 0xA1, 0xAC, 0x95, 0x48, 0x7E, + 0x96, 0xF8, 0xC0, 0x8A, 0xF6, 0x00, 0xAA, 0xB8, + 0x7C, 0x98, 0x6E, 0xBA, 0xD4, 0x9F, 0xC7, 0x0A, + 0x58, 0xB4, 0x89, 0x0B, 0x9C, 0x87, 0x6E, 0x09, + 0x10, 0x16, 0xDA, 0xF4, 0x9E, 0x1D, 0x32, 0x2E + }, + { + 0xF9, 0xD1, 0xD1, 0xB1, 0xE8, 0x7E, 0xA7, 0xAE, + 0x75, 0x3A, 0x02, 0x97, 0x50, 0xCC, 0x1C, 0xF3, + 0xD0, 0x15, 0x7D, 0x41, 0x80, 0x5E, 0x24, 0x5C, + 0x56, 0x17, 0xBB, 0x93, 0x4E, 0x73, 0x2F, 0x0A, + 0xE3, 0x18, 0x0B, 0x78, 0xE0, 0x5B, 0xFE, 0x76, + 0xC7, 0xC3, 0x05, 0x1E, 0x3E, 0x3A, 0xC7, 0x8B, + 0x9B, 0x50, 0xC0, 0x51, 0x42, 0x65, 0x7E, 0x1E, + 0x03, 0x21, 0x5D, 0x6E, 0xC7, 0xBF, 0xD0, 0xFC + }, + { + 0x11, 0xB7, 0xBC, 0x16, 0x68, 0x03, 0x20, 0x48, + 0xAA, 0x43, 0x34, 0x3D, 0xE4, 0x76, 0x39, 0x5E, + 0x81, 0x4B, 0xBB, 0xC2, 0x23, 0x67, 0x8D, 0xB9, + 0x51, 0xA1, 0xB0, 0x3A, 0x02, 0x1E, 0xFA, 0xC9, + 0x48, 0xCF, 0xBE, 0x21, 0x5F, 0x97, 0xFE, 0x9A, + 0x72, 0xA2, 0xF6, 0xBC, 0x03, 0x9E, 0x39, 0x56, + 0xBF, 0xA4, 0x17, 0xC1, 0xA9, 0xF1, 0x0D, 0x6D, + 0x7B, 0xA5, 0xD3, 0xD3, 0x2F, 0xF3, 0x23, 0xE5 + }, + { + 0xB8, 0xD9, 0x00, 0x0E, 0x4F, 0xC2, 0xB0, 0x66, + 0xED, 0xB9, 0x1A, 0xFE, 0xE8, 0xE7, 0xEB, 0x0F, + 0x24, 0xE3, 0xA2, 0x01, 0xDB, 0x8B, 0x67, 0x93, + 0xC0, 0x60, 0x85, 0x81, 0xE6, 0x28, 0xED, 0x0B, + 0xCC, 0x4E, 0x5A, 0xA6, 0x78, 0x79, 0x92, 0xA4, + 0xBC, 0xC4, 0x4E, 0x28, 0x80, 0x93, 0xE6, 0x3E, + 0xE8, 0x3A, 0xBD, 0x0B, 0xC3, 0xEC, 0x6D, 0x09, + 0x34, 0xA6, 0x74, 0xA4, 0xDA, 0x13, 0x83, 0x8A + }, + { + 0xCE, 0x32, 0x5E, 0x29, 0x4F, 0x9B, 0x67, 0x19, + 0xD6, 0xB6, 0x12, 0x78, 0x27, 0x6A, 0xE0, 0x6A, + 0x25, 0x64, 0xC0, 0x3B, 0xB0, 0xB7, 0x83, 0xFA, + 0xFE, 0x78, 0x5B, 0xDF, 0x89, 0xC7, 0xD5, 0xAC, + 0xD8, 0x3E, 0x78, 0x75, 0x6D, 0x30, 0x1B, 0x44, + 0x56, 0x99, 0x02, 0x4E, 0xAE, 0xB7, 0x7B, 0x54, + 0xD4, 0x77, 0x33, 0x6E, 0xC2, 0xA4, 0xF3, 0x32, + 0xF2, 0xB3, 0xF8, 0x87, 0x65, 0xDD, 0xB0, 0xC3 + }, + { + 0x29, 0xAC, 0xC3, 0x0E, 0x96, 0x03, 0xAE, 0x2F, + 0xCC, 0xF9, 0x0B, 0xF9, 0x7E, 0x6C, 0xC4, 0x63, + 0xEB, 0xE2, 0x8C, 0x1B, 0x2F, 0x9B, 0x4B, 0x76, + 0x5E, 0x70, 0x53, 0x7C, 0x25, 0xC7, 0x02, 0xA2, + 0x9D, 0xCB, 0xFB, 0xF1, 0x4C, 0x99, 0xC5, 0x43, + 0x45, 0xBA, 0x2B, 0x51, 0xF1, 0x7B, 0x77, 0xB5, + 0xF1, 0x5D, 0xB9, 0x2B, 0xBA, 0xD8, 0xFA, 0x95, + 0xC4, 0x71, 0xF5, 0xD0, 0x70, 0xA1, 0x37, 0xCC + }, + { + 0x33, 0x79, 0xCB, 0xAA, 0xE5, 0x62, 0xA8, 0x7B, + 0x4C, 0x04, 0x25, 0x55, 0x0F, 0xFD, 0xD6, 0xBF, + 0xE1, 0x20, 0x3F, 0x0D, 0x66, 0x6C, 0xC7, 0xEA, + 0x09, 0x5B, 0xE4, 0x07, 0xA5, 0xDF, 0xE6, 0x1E, + 0xE9, 0x14, 0x41, 0xCD, 0x51, 0x54, 0xB3, 0xE5, + 0x3B, 0x4F, 0x5F, 0xB3, 0x1A, 0xD4, 0xC7, 0xA9, + 0xAD, 0x5C, 0x7A, 0xF4, 0xAE, 0x67, 0x9A, 0xA5, + 0x1A, 0x54, 0x00, 0x3A, 0x54, 0xCA, 0x6B, 0x2D + }, + { + 0x30, 0x95, 0xA3, 0x49, 0xD2, 0x45, 0x70, 0x8C, + 0x7C, 0xF5, 0x50, 0x11, 0x87, 0x03, 0xD7, 0x30, + 0x2C, 0x27, 0xB6, 0x0A, 0xF5, 0xD4, 0xE6, 0x7F, + 0xC9, 0x78, 0xF8, 0xA4, 0xE6, 0x09, 0x53, 0xC7, + 0xA0, 0x4F, 0x92, 0xFC, 0xF4, 0x1A, 0xEE, 0x64, + 0x32, 0x1C, 0xCB, 0x70, 0x7A, 0x89, 0x58, 0x51, + 0x55, 0x2B, 0x1E, 0x37, 0xB0, 0x0B, 0xC5, 0xE6, + 0xB7, 0x2F, 0xA5, 0xBC, 0xEF, 0x9E, 0x3F, 0xFF + }, + { + 0x07, 0x26, 0x2D, 0x73, 0x8B, 0x09, 0x32, 0x1F, + 0x4D, 0xBC, 0xCE, 0xC4, 0xBB, 0x26, 0xF4, 0x8C, + 0xB0, 0xF0, 0xED, 0x24, 0x6C, 0xE0, 0xB3, 0x1B, + 0x9A, 0x6E, 0x7B, 0xC6, 0x83, 0x04, 0x9F, 0x1F, + 0x3E, 0x55, 0x45, 0xF2, 0x8C, 0xE9, 0x32, 0xDD, + 0x98, 0x5C, 0x5A, 0xB0, 0xF4, 0x3B, 0xD6, 0xDE, + 0x07, 0x70, 0x56, 0x0A, 0xF3, 0x29, 0x06, 0x5E, + 0xD2, 0xE4, 0x9D, 0x34, 0x62, 0x4C, 0x2C, 0xBB + }, + { + 0xB6, 0x40, 0x5E, 0xCA, 0x8E, 0xE3, 0x31, 0x6C, + 0x87, 0x06, 0x1C, 0xC6, 0xEC, 0x18, 0xDB, 0xA5, + 0x3E, 0x6C, 0x25, 0x0C, 0x63, 0xBA, 0x1F, 0x3B, + 0xAE, 0x9E, 0x55, 0xDD, 0x34, 0x98, 0x03, 0x6A, + 0xF0, 0x8C, 0xD2, 0x72, 0xAA, 0x24, 0xD7, 0x13, + 0xC6, 0x02, 0x0D, 0x77, 0xAB, 0x2F, 0x39, 0x19, + 0xAF, 0x1A, 0x32, 0xF3, 0x07, 0x42, 0x06, 0x18, + 0xAB, 0x97, 0xE7, 0x39, 0x53, 0x99, 0x4F, 0xB4 + }, + { + 0x7E, 0xE6, 0x82, 0xF6, 0x31, 0x48, 0xEE, 0x45, + 0xF6, 0xE5, 0x31, 0x5D, 0xA8, 0x1E, 0x5C, 0x6E, + 0x55, 0x7C, 0x2C, 0x34, 0x64, 0x1F, 0xC5, 0x09, + 0xC7, 0xA5, 0x70, 0x10, 0x88, 0xC3, 0x8A, 0x74, + 0x75, 0x61, 0x68, 0xE2, 0xCD, 0x8D, 0x35, 0x1E, + 0x88, 0xFD, 0x1A, 0x45, 0x1F, 0x36, 0x0A, 0x01, + 0xF5, 0xB2, 0x58, 0x0F, 0x9B, 0x5A, 0x2E, 0x8C, + 0xFC, 0x13, 0x8F, 0x3D, 0xD5, 0x9A, 0x3F, 0xFC + }, + { + 0x1D, 0x26, 0x3C, 0x17, 0x9D, 0x6B, 0x26, 0x8F, + 0x6F, 0xA0, 0x16, 0xF3, 0xA4, 0xF2, 0x9E, 0x94, + 0x38, 0x91, 0x12, 0x5E, 0xD8, 0x59, 0x3C, 0x81, + 0x25, 0x60, 0x59, 0xF5, 0xA7, 0xB4, 0x4A, 0xF2, + 0xDC, 0xB2, 0x03, 0x0D, 0x17, 0x5C, 0x00, 0xE6, + 0x2E, 0xCA, 0xF7, 0xEE, 0x96, 0x68, 0x2A, 0xA0, + 0x7A, 0xB2, 0x0A, 0x61, 0x10, 0x24, 0xA2, 0x85, + 0x32, 0xB1, 0xC2, 0x5B, 0x86, 0x65, 0x79, 0x02 + }, + { + 0x10, 0x6D, 0x13, 0x2C, 0xBD, 0xB4, 0xCD, 0x25, + 0x97, 0x81, 0x28, 0x46, 0xE2, 0xBC, 0x1B, 0xF7, + 0x32, 0xFE, 0xC5, 0xF0, 0xA5, 0xF6, 0x5D, 0xBB, + 0x39, 0xEC, 0x4E, 0x6D, 0xC6, 0x4A, 0xB2, 0xCE, + 0x6D, 0x24, 0x63, 0x0D, 0x0F, 0x15, 0xA8, 0x05, + 0xC3, 0x54, 0x00, 0x25, 0xD8, 0x4A, 0xFA, 0x98, + 0xE3, 0x67, 0x03, 0xC3, 0xDB, 0xEE, 0x71, 0x3E, + 0x72, 0xDD, 0xE8, 0x46, 0x5B, 0xC1, 0xBE, 0x7E + }, + { + 0x0E, 0x79, 0x96, 0x82, 0x26, 0x65, 0x06, 0x67, + 0xA8, 0xD8, 0x62, 0xEA, 0x8D, 0xA4, 0x89, 0x1A, + 0xF5, 0x6A, 0x4E, 0x3A, 0x8B, 0x6D, 0x17, 0x50, + 0xE3, 0x94, 0xF0, 0xDE, 0xA7, 0x6D, 0x64, 0x0D, + 0x85, 0x07, 0x7B, 0xCE, 0xC2, 0xCC, 0x86, 0x88, + 0x6E, 0x50, 0x67, 0x51, 0xB4, 0xF6, 0xA5, 0x83, + 0x8F, 0x7F, 0x0B, 0x5F, 0xEF, 0x76, 0x5D, 0x9D, + 0xC9, 0x0D, 0xCD, 0xCB, 0xAF, 0x07, 0x9F, 0x08 + }, + { + 0x52, 0x11, 0x56, 0xA8, 0x2A, 0xB0, 0xC4, 0xE5, + 0x66, 0xE5, 0x84, 0x4D, 0x5E, 0x31, 0xAD, 0x9A, + 0xAF, 0x14, 0x4B, 0xBD, 0x5A, 0x46, 0x4F, 0xDC, + 0xA3, 0x4D, 0xBD, 0x57, 0x17, 0xE8, 0xFF, 0x71, + 0x1D, 0x3F, 0xFE, 0xBB, 0xFA, 0x08, 0x5D, 0x67, + 0xFE, 0x99, 0x6A, 0x34, 0xF6, 0xD3, 0xE4, 0xE6, + 0x0B, 0x13, 0x96, 0xBF, 0x4B, 0x16, 0x10, 0xC2, + 0x63, 0xBD, 0xBB, 0x83, 0x4D, 0x56, 0x08, 0x16 + }, + { + 0x1A, 0xBA, 0x88, 0xBE, 0xFC, 0x55, 0xBC, 0x25, + 0xEF, 0xBC, 0xE0, 0x2D, 0xB8, 0xB9, 0x93, 0x3E, + 0x46, 0xF5, 0x76, 0x61, 0xBA, 0xEA, 0xBE, 0xB2, + 0x1C, 0xC2, 0x57, 0x4D, 0x2A, 0x51, 0x8A, 0x3C, + 0xBA, 0x5D, 0xC5, 0xA3, 0x8E, 0x49, 0x71, 0x34, + 0x40, 0xB2, 0x5F, 0x9C, 0x74, 0x4E, 0x75, 0xF6, + 0xB8, 0x5C, 0x9D, 0x8F, 0x46, 0x81, 0xF6, 0x76, + 0x16, 0x0F, 0x61, 0x05, 0x35, 0x7B, 0x84, 0x06 + }, + { + 0x5A, 0x99, 0x49, 0xFC, 0xB2, 0xC4, 0x73, 0xCD, + 0xA9, 0x68, 0xAC, 0x1B, 0x5D, 0x08, 0x56, 0x6D, + 0xC2, 0xD8, 0x16, 0xD9, 0x60, 0xF5, 0x7E, 0x63, + 0xB8, 0x98, 0xFA, 0x70, 0x1C, 0xF8, 0xEB, 0xD3, + 0xF5, 0x9B, 0x12, 0x4D, 0x95, 0xBF, 0xBB, 0xED, + 0xC5, 0xF1, 0xCF, 0x0E, 0x17, 0xD5, 0xEA, 0xED, + 0x0C, 0x02, 0xC5, 0x0B, 0x69, 0xD8, 0xA4, 0x02, + 0xCA, 0xBC, 0xCA, 0x44, 0x33, 0xB5, 0x1F, 0xD4 + }, + { + 0xB0, 0xCE, 0xAD, 0x09, 0x80, 0x7C, 0x67, 0x2A, + 0xF2, 0xEB, 0x2B, 0x0F, 0x06, 0xDD, 0xE4, 0x6C, + 0xF5, 0x37, 0x0E, 0x15, 0xA4, 0x09, 0x6B, 0x1A, + 0x7D, 0x7C, 0xBB, 0x36, 0xEC, 0x31, 0xC2, 0x05, + 0xFB, 0xEF, 0xCA, 0x00, 0xB7, 0xA4, 0x16, 0x2F, + 0xA8, 0x9F, 0xB4, 0xFB, 0x3E, 0xB7, 0x8D, 0x79, + 0x77, 0x0C, 0x23, 0xF4, 0x4E, 0x72, 0x06, 0x66, + 0x4C, 0xE3, 0xCD, 0x93, 0x1C, 0x29, 0x1E, 0x5D + }, + { + 0xBB, 0x66, 0x64, 0x93, 0x1E, 0xC9, 0x70, 0x44, + 0xE4, 0x5B, 0x2A, 0xE4, 0x20, 0xAE, 0x1C, 0x55, + 0x1A, 0x88, 0x74, 0xBC, 0x93, 0x7D, 0x08, 0xE9, + 0x69, 0x39, 0x9C, 0x39, 0x64, 0xEB, 0xDB, 0xA8, + 0x34, 0x6C, 0xDD, 0x5D, 0x09, 0xCA, 0xAF, 0xE4, + 0xC2, 0x8B, 0xA7, 0xEC, 0x78, 0x81, 0x91, 0xCE, + 0xCA, 0x65, 0xDD, 0xD6, 0xF9, 0x5F, 0x18, 0x58, + 0x3E, 0x04, 0x0D, 0x0F, 0x30, 0xD0, 0x36, 0x4D + }, + { + 0x65, 0xBC, 0x77, 0x0A, 0x5F, 0xAA, 0x37, 0x92, + 0x36, 0x98, 0x03, 0x68, 0x3E, 0x84, 0x4B, 0x0B, + 0xE7, 0xEE, 0x96, 0xF2, 0x9F, 0x6D, 0x6A, 0x35, + 0x56, 0x80, 0x06, 0xBD, 0x55, 0x90, 0xF9, 0xA4, + 0xEF, 0x63, 0x9B, 0x7A, 0x80, 0x61, 0xC7, 0xB0, + 0x42, 0x4B, 0x66, 0xB6, 0x0A, 0xC3, 0x4A, 0xF3, + 0x11, 0x99, 0x05, 0xF3, 0x3A, 0x9D, 0x8C, 0x3A, + 0xE1, 0x83, 0x82, 0xCA, 0x9B, 0x68, 0x99, 0x00 + }, + { + 0xEA, 0x9B, 0x4D, 0xCA, 0x33, 0x33, 0x36, 0xAA, + 0xF8, 0x39, 0xA4, 0x5C, 0x6E, 0xAA, 0x48, 0xB8, + 0xCB, 0x4C, 0x7D, 0xDA, 0xBF, 0xFE, 0xA4, 0xF6, + 0x43, 0xD6, 0x35, 0x7E, 0xA6, 0x62, 0x8A, 0x48, + 0x0A, 0x5B, 0x45, 0xF2, 0xB0, 0x52, 0xC1, 0xB0, + 0x7D, 0x1F, 0xED, 0xCA, 0x91, 0x8B, 0x6F, 0x11, + 0x39, 0xD8, 0x0F, 0x74, 0xC2, 0x45, 0x10, 0xDC, + 0xBA, 0xA4, 0xBE, 0x70, 0xEA, 0xCC, 0x1B, 0x06 + }, + { + 0xE6, 0x34, 0x2F, 0xB4, 0xA7, 0x80, 0xAD, 0x97, + 0x5D, 0x0E, 0x24, 0xBC, 0xE1, 0x49, 0x98, 0x9B, + 0x91, 0xD3, 0x60, 0x55, 0x7E, 0x87, 0x99, 0x4F, + 0x6B, 0x45, 0x7B, 0x89, 0x55, 0x75, 0xCC, 0x02, + 0xD0, 0xC1, 0x5B, 0xAD, 0x3C, 0xE7, 0x57, 0x7F, + 0x4C, 0x63, 0x92, 0x7F, 0xF1, 0x3F, 0x3E, 0x38, + 0x1F, 0xF7, 0xE7, 0x2B, 0xDB, 0xE7, 0x45, 0x32, + 0x48, 0x44, 0xA9, 0xD2, 0x7E, 0x3F, 0x1C, 0x01 + }, + { + 0x3E, 0x20, 0x9C, 0x9B, 0x33, 0xE8, 0xE4, 0x61, + 0x17, 0x8A, 0xB4, 0x6B, 0x1C, 0x64, 0xB4, 0x9A, + 0x07, 0xFB, 0x74, 0x5F, 0x1C, 0x8B, 0xC9, 0x5F, + 0xBF, 0xB9, 0x4C, 0x6B, 0x87, 0xC6, 0x95, 0x16, + 0x65, 0x1B, 0x26, 0x4E, 0xF9, 0x80, 0x93, 0x7F, + 0xAD, 0x41, 0x23, 0x8B, 0x91, 0xDD, 0xC0, 0x11, + 0xA5, 0xDD, 0x77, 0x7C, 0x7E, 0xFD, 0x44, 0x94, + 0xB4, 0xB6, 0xEC, 0xD3, 0xA9, 0xC2, 0x2A, 0xC0 + }, + { + 0xFD, 0x6A, 0x3D, 0x5B, 0x18, 0x75, 0xD8, 0x04, + 0x86, 0xD6, 0xE6, 0x96, 0x94, 0xA5, 0x6D, 0xBB, + 0x04, 0xA9, 0x9A, 0x4D, 0x05, 0x1F, 0x15, 0xDB, + 0x26, 0x89, 0x77, 0x6B, 0xA1, 0xC4, 0x88, 0x2E, + 0x6D, 0x46, 0x2A, 0x60, 0x3B, 0x70, 0x15, 0xDC, + 0x9F, 0x4B, 0x74, 0x50, 0xF0, 0x53, 0x94, 0x30, + 0x3B, 0x86, 0x52, 0xCF, 0xB4, 0x04, 0xA2, 0x66, + 0x96, 0x2C, 0x41, 0xBA, 0xE6, 0xE1, 0x8A, 0x94 + }, + { + 0x95, 0x1E, 0x27, 0x51, 0x7E, 0x6B, 0xAD, 0x9E, + 0x41, 0x95, 0xFC, 0x86, 0x71, 0xDE, 0xE3, 0xE7, + 0xE9, 0xBE, 0x69, 0xCE, 0xE1, 0x42, 0x2C, 0xB9, + 0xFE, 0xCF, 0xCE, 0x0D, 0xBA, 0x87, 0x5F, 0x7B, + 0x31, 0x0B, 0x93, 0xEE, 0x3A, 0x3D, 0x55, 0x8F, + 0x94, 0x1F, 0x63, 0x5F, 0x66, 0x8F, 0xF8, 0x32, + 0xD2, 0xC1, 0xD0, 0x33, 0xC5, 0xE2, 0xF0, 0x99, + 0x7E, 0x4C, 0x66, 0xF1, 0x47, 0x34, 0x4E, 0x02 + }, + { + 0x8E, 0xBA, 0x2F, 0x87, 0x4F, 0x1A, 0xE8, 0x40, + 0x41, 0x90, 0x3C, 0x7C, 0x42, 0x53, 0xC8, 0x22, + 0x92, 0x53, 0x0F, 0xC8, 0x50, 0x95, 0x50, 0xBF, + 0xDC, 0x34, 0xC9, 0x5C, 0x7E, 0x28, 0x89, 0xD5, + 0x65, 0x0B, 0x0A, 0xD8, 0xCB, 0x98, 0x8E, 0x5C, + 0x48, 0x94, 0xCB, 0x87, 0xFB, 0xFB, 0xB1, 0x96, + 0x12, 0xEA, 0x93, 0xCC, 0xC4, 0xC5, 0xCA, 0xD1, + 0x71, 0x58, 0xB9, 0x76, 0x34, 0x64, 0xB4, 0x92 + }, + { + 0x16, 0xF7, 0x12, 0xEA, 0xA1, 0xB7, 0xC6, 0x35, + 0x47, 0x19, 0xA8, 0xE7, 0xDB, 0xDF, 0xAF, 0x55, + 0xE4, 0x06, 0x3A, 0x4D, 0x27, 0x7D, 0x94, 0x75, + 0x50, 0x01, 0x9B, 0x38, 0xDF, 0xB5, 0x64, 0x83, + 0x09, 0x11, 0x05, 0x7D, 0x50, 0x50, 0x61, 0x36, + 0xE2, 0x39, 0x4C, 0x3B, 0x28, 0x94, 0x5C, 0xC9, + 0x64, 0x96, 0x7D, 0x54, 0xE3, 0x00, 0x0C, 0x21, + 0x81, 0x62, 0x6C, 0xFB, 0x9B, 0x73, 0xEF, 0xD2 + }, + { + 0xC3, 0x96, 0x39, 0xE7, 0xD5, 0xC7, 0xFB, 0x8C, + 0xDD, 0x0F, 0xD3, 0xE6, 0xA5, 0x20, 0x96, 0x03, + 0x94, 0x37, 0x12, 0x2F, 0x21, 0xC7, 0x8F, 0x16, + 0x79, 0xCE, 0xA9, 0xD7, 0x8A, 0x73, 0x4C, 0x56, + 0xEC, 0xBE, 0xB2, 0x86, 0x54, 0xB4, 0xF1, 0x8E, + 0x34, 0x2C, 0x33, 0x1F, 0x6F, 0x72, 0x29, 0xEC, + 0x4B, 0x4B, 0xC2, 0x81, 0xB2, 0xD8, 0x0A, 0x6E, + 0xB5, 0x00, 0x43, 0xF3, 0x17, 0x96, 0xC8, 0x8C + }, + { + 0x72, 0xD0, 0x81, 0xAF, 0x99, 0xF8, 0xA1, 0x73, + 0xDC, 0xC9, 0xA0, 0xAC, 0x4E, 0xB3, 0x55, 0x74, + 0x05, 0x63, 0x9A, 0x29, 0x08, 0x4B, 0x54, 0xA4, + 0x01, 0x72, 0x91, 0x2A, 0x2F, 0x8A, 0x39, 0x51, + 0x29, 0xD5, 0x53, 0x6F, 0x09, 0x18, 0xE9, 0x02, + 0xF9, 0xE8, 0xFA, 0x60, 0x00, 0x99, 0x5F, 0x41, + 0x68, 0xDD, 0xC5, 0xF8, 0x93, 0x01, 0x1B, 0xE6, + 0xA0, 0xDB, 0xC9, 0xB8, 0xA1, 0xA3, 0xF5, 0xBB + }, + { + 0xC1, 0x1A, 0xA8, 0x1E, 0x5E, 0xFD, 0x24, 0xD5, + 0xFC, 0x27, 0xEE, 0x58, 0x6C, 0xFD, 0x88, 0x47, + 0xFB, 0xB0, 0xE2, 0x76, 0x01, 0xCC, 0xEC, 0xE5, + 0xEC, 0xCA, 0x01, 0x98, 0xE3, 0xC7, 0x76, 0x53, + 0x93, 0xBB, 0x74, 0x45, 0x7C, 0x7E, 0x7A, 0x27, + 0xEB, 0x91, 0x70, 0x35, 0x0E, 0x1F, 0xB5, 0x38, + 0x57, 0x17, 0x75, 0x06, 0xBE, 0x3E, 0x76, 0x2C, + 0xC0, 0xF1, 0x4D, 0x8C, 0x3A, 0xFE, 0x90, 0x77 + }, + { + 0xC2, 0x8F, 0x21, 0x50, 0xB4, 0x52, 0xE6, 0xC0, + 0xC4, 0x24, 0xBC, 0xDE, 0x6F, 0x8D, 0x72, 0x00, + 0x7F, 0x93, 0x10, 0xFE, 0xD7, 0xF2, 0xF8, 0x7D, + 0xE0, 0xDB, 0xB6, 0x4F, 0x44, 0x79, 0xD6, 0xC1, + 0x44, 0x1B, 0xA6, 0x6F, 0x44, 0xB2, 0xAC, 0xCE, + 0xE6, 0x16, 0x09, 0x17, 0x7E, 0xD3, 0x40, 0x12, + 0x8B, 0x40, 0x7E, 0xCE, 0xC7, 0xC6, 0x4B, 0xBE, + 0x50, 0xD6, 0x3D, 0x22, 0xD8, 0x62, 0x77, 0x27 + }, + { + 0xF6, 0x3D, 0x88, 0x12, 0x28, 0x77, 0xEC, 0x30, + 0xB8, 0xC8, 0xB0, 0x0D, 0x22, 0xE8, 0x90, 0x00, + 0xA9, 0x66, 0x42, 0x61, 0x12, 0xBD, 0x44, 0x16, + 0x6E, 0x2F, 0x52, 0x5B, 0x76, 0x9C, 0xCB, 0xE9, + 0xB2, 0x86, 0xD4, 0x37, 0xA0, 0x12, 0x91, 0x30, + 0xDD, 0xE1, 0xA8, 0x6C, 0x43, 0xE0, 0x4B, 0xED, + 0xB5, 0x94, 0xE6, 0x71, 0xD9, 0x82, 0x83, 0xAF, + 0xE6, 0x4C, 0xE3, 0x31, 0xDE, 0x98, 0x28, 0xFD + }, + { + 0x34, 0x8B, 0x05, 0x32, 0x88, 0x0B, 0x88, 0xA6, + 0x61, 0x4A, 0x8D, 0x74, 0x08, 0xC3, 0xF9, 0x13, + 0x35, 0x7F, 0xBB, 0x60, 0xE9, 0x95, 0xC6, 0x02, + 0x05, 0xBE, 0x91, 0x39, 0xE7, 0x49, 0x98, 0xAE, + 0xDE, 0x7F, 0x45, 0x81, 0xE4, 0x2F, 0x6B, 0x52, + 0x69, 0x8F, 0x7F, 0xA1, 0x21, 0x97, 0x08, 0xC1, + 0x44, 0x98, 0x06, 0x7F, 0xD1, 0xE0, 0x95, 0x02, + 0xDE, 0x83, 0xA7, 0x7D, 0xD2, 0x81, 0x15, 0x0C + }, + { + 0x51, 0x33, 0xDC, 0x8B, 0xEF, 0x72, 0x53, 0x59, + 0xDF, 0xF5, 0x97, 0x92, 0xD8, 0x5E, 0xAF, 0x75, + 0xB7, 0xE1, 0xDC, 0xD1, 0x97, 0x8B, 0x01, 0xC3, + 0x5B, 0x1B, 0x85, 0xFC, 0xEB, 0xC6, 0x33, 0x88, + 0xAD, 0x99, 0xA1, 0x7B, 0x63, 0x46, 0xA2, 0x17, + 0xDC, 0x1A, 0x96, 0x22, 0xEB, 0xD1, 0x22, 0xEC, + 0xF6, 0x91, 0x3C, 0x4D, 0x31, 0xA6, 0xB5, 0x2A, + 0x69, 0x5B, 0x86, 0xAF, 0x00, 0xD7, 0x41, 0xA0 + }, + { + 0x27, 0x53, 0xC4, 0xC0, 0xE9, 0x8E, 0xCA, 0xD8, + 0x06, 0xE8, 0x87, 0x80, 0xEC, 0x27, 0xFC, 0xCD, + 0x0F, 0x5C, 0x1A, 0xB5, 0x47, 0xF9, 0xE4, 0xBF, + 0x16, 0x59, 0xD1, 0x92, 0xC2, 0x3A, 0xA2, 0xCC, + 0x97, 0x1B, 0x58, 0xB6, 0x80, 0x25, 0x80, 0xBA, + 0xEF, 0x8A, 0xDC, 0x3B, 0x77, 0x6E, 0xF7, 0x08, + 0x6B, 0x25, 0x45, 0xC2, 0x98, 0x7F, 0x34, 0x8E, + 0xE3, 0x71, 0x9C, 0xDE, 0xF2, 0x58, 0xC4, 0x03 + }, + { + 0xB1, 0x66, 0x35, 0x73, 0xCE, 0x4B, 0x9D, 0x8C, + 0xAE, 0xFC, 0x86, 0x50, 0x12, 0xF3, 0xE3, 0x97, + 0x14, 0xB9, 0x89, 0x8A, 0x5D, 0xA6, 0xCE, 0x17, + 0xC2, 0x5A, 0x6A, 0x47, 0x93, 0x1A, 0x9D, 0xDB, + 0x9B, 0xBE, 0x98, 0xAD, 0xAA, 0x55, 0x3B, 0xEE, + 0xD4, 0x36, 0xE8, 0x95, 0x78, 0x45, 0x54, 0x16, + 0xC2, 0xA5, 0x2A, 0x52, 0x5C, 0xF2, 0x86, 0x2B, + 0x8D, 0x1D, 0x49, 0xA2, 0x53, 0x1B, 0x73, 0x91 + }, + { + 0x64, 0xF5, 0x8B, 0xD6, 0xBF, 0xC8, 0x56, 0xF5, + 0xE8, 0x73, 0xB2, 0xA2, 0x95, 0x6E, 0xA0, 0xED, + 0xA0, 0xD6, 0xDB, 0x0D, 0xA3, 0x9C, 0x8C, 0x7F, + 0xC6, 0x7C, 0x9F, 0x9F, 0xEE, 0xFC, 0xFF, 0x30, + 0x72, 0xCD, 0xF9, 0xE6, 0xEA, 0x37, 0xF6, 0x9A, + 0x44, 0xF0, 0xC6, 0x1A, 0xA0, 0xDA, 0x36, 0x93, + 0xC2, 0xDB, 0x5B, 0x54, 0x96, 0x0C, 0x02, 0x81, + 0xA0, 0x88, 0x15, 0x1D, 0xB4, 0x2B, 0x11, 0xE8 + }, + { + 0x07, 0x64, 0xC7, 0xBE, 0x28, 0x12, 0x5D, 0x90, + 0x65, 0xC4, 0xB9, 0x8A, 0x69, 0xD6, 0x0A, 0xED, + 0xE7, 0x03, 0x54, 0x7C, 0x66, 0xA1, 0x2E, 0x17, + 0xE1, 0xC6, 0x18, 0x99, 0x41, 0x32, 0xF5, 0xEF, + 0x82, 0x48, 0x2C, 0x1E, 0x3F, 0xE3, 0x14, 0x6C, + 0xC6, 0x53, 0x76, 0xCC, 0x10, 0x9F, 0x01, 0x38, + 0xED, 0x9A, 0x80, 0xE4, 0x9F, 0x1F, 0x3C, 0x7D, + 0x61, 0x0D, 0x2F, 0x24, 0x32, 0xF2, 0x06, 0x05 + }, + { + 0xF7, 0x48, 0x78, 0x43, 0x98, 0xA2, 0xFF, 0x03, + 0xEB, 0xEB, 0x07, 0xE1, 0x55, 0xE6, 0x61, 0x16, + 0xA8, 0x39, 0x74, 0x1A, 0x33, 0x6E, 0x32, 0xDA, + 0x71, 0xEC, 0x69, 0x60, 0x01, 0xF0, 0xAD, 0x1B, + 0x25, 0xCD, 0x48, 0xC6, 0x9C, 0xFC, 0xA7, 0x26, + 0x5E, 0xCA, 0x1D, 0xD7, 0x19, 0x04, 0xA0, 0xCE, + 0x74, 0x8A, 0xC4, 0x12, 0x4F, 0x35, 0x71, 0x07, + 0x6D, 0xFA, 0x71, 0x16, 0xA9, 0xCF, 0x00, 0xE9 + }, + { + 0x3F, 0x0D, 0xBC, 0x01, 0x86, 0xBC, 0xEB, 0x6B, + 0x78, 0x5B, 0xA7, 0x8D, 0x2A, 0x2A, 0x01, 0x3C, + 0x91, 0x0B, 0xE1, 0x57, 0xBD, 0xAF, 0xFA, 0xE8, + 0x1B, 0xB6, 0x66, 0x3B, 0x1A, 0x73, 0x72, 0x2F, + 0x7F, 0x12, 0x28, 0x79, 0x5F, 0x3E, 0xCA, 0xDA, + 0x87, 0xCF, 0x6E, 0xF0, 0x07, 0x84, 0x74, 0xAF, + 0x73, 0xF3, 0x1E, 0xCA, 0x0C, 0xC2, 0x00, 0xED, + 0x97, 0x5B, 0x68, 0x93, 0xF7, 0x61, 0xCB, 0x6D + }, + { + 0xD4, 0x76, 0x2C, 0xD4, 0x59, 0x98, 0x76, 0xCA, + 0x75, 0xB2, 0xB8, 0xFE, 0x24, 0x99, 0x44, 0xDB, + 0xD2, 0x7A, 0xCE, 0x74, 0x1F, 0xDA, 0xB9, 0x36, + 0x16, 0xCB, 0xC6, 0xE4, 0x25, 0x46, 0x0F, 0xEB, + 0x51, 0xD4, 0xE7, 0xAD, 0xCC, 0x38, 0x18, 0x0E, + 0x7F, 0xC4, 0x7C, 0x89, 0x02, 0x4A, 0x7F, 0x56, + 0x19, 0x1A, 0xDB, 0x87, 0x8D, 0xFD, 0xE4, 0xEA, + 0xD6, 0x22, 0x23, 0xF5, 0xA2, 0x61, 0x0E, 0xFE + }, + { + 0xCD, 0x36, 0xB3, 0xD5, 0xB4, 0xC9, 0x1B, 0x90, + 0xFC, 0xBB, 0xA7, 0x95, 0x13, 0xCF, 0xEE, 0x19, + 0x07, 0xD8, 0x64, 0x5A, 0x16, 0x2A, 0xFD, 0x0C, + 0xD4, 0xCF, 0x41, 0x92, 0xD4, 0xA5, 0xF4, 0xC8, + 0x92, 0x18, 0x3A, 0x8E, 0xAC, 0xDB, 0x2B, 0x6B, + 0x6A, 0x9D, 0x9A, 0xA8, 0xC1, 0x1A, 0xC1, 0xB2, + 0x61, 0xB3, 0x80, 0xDB, 0xEE, 0x24, 0xCA, 0x46, + 0x8F, 0x1B, 0xFD, 0x04, 0x3C, 0x58, 0xEE, 0xFE + }, + { + 0x98, 0x59, 0x34, 0x52, 0x28, 0x16, 0x61, 0xA5, + 0x3C, 0x48, 0xA9, 0xD8, 0xCD, 0x79, 0x08, 0x26, + 0xC1, 0xA1, 0xCE, 0x56, 0x77, 0x38, 0x05, 0x3D, + 0x0B, 0xEE, 0x4A, 0x91, 0xA3, 0xD5, 0xBD, 0x92, + 0xEE, 0xFD, 0xBA, 0xBE, 0xBE, 0x32, 0x04, 0xF2, + 0x03, 0x1C, 0xA5, 0xF7, 0x81, 0xBD, 0xA9, 0x9E, + 0xF5, 0xD8, 0xAE, 0x56, 0xE5, 0xB0, 0x4A, 0x9E, + 0x1E, 0xCD, 0x21, 0xB0, 0xEB, 0x05, 0xD3, 0xE1 + }, + { + 0x77, 0x1F, 0x57, 0xDD, 0x27, 0x75, 0xCC, 0xDA, + 0xB5, 0x59, 0x21, 0xD3, 0xE8, 0xE3, 0x0C, 0xCF, + 0x48, 0x4D, 0x61, 0xFE, 0x1C, 0x1B, 0x9C, 0x2A, + 0xE8, 0x19, 0xD0, 0xFB, 0x2A, 0x12, 0xFA, 0xB9, + 0xBE, 0x70, 0xC4, 0xA7, 0xA1, 0x38, 0xDA, 0x84, + 0xE8, 0x28, 0x04, 0x35, 0xDA, 0xAD, 0xE5, 0xBB, + 0xE6, 0x6A, 0xF0, 0x83, 0x6A, 0x15, 0x4F, 0x81, + 0x7F, 0xB1, 0x7F, 0x33, 0x97, 0xE7, 0x25, 0xA3 + }, + { + 0xC6, 0x08, 0x97, 0xC6, 0xF8, 0x28, 0xE2, 0x1F, + 0x16, 0xFB, 0xB5, 0xF1, 0x5B, 0x32, 0x3F, 0x87, + 0xB6, 0xC8, 0x95, 0x5E, 0xAB, 0xF1, 0xD3, 0x80, + 0x61, 0xF7, 0x07, 0xF6, 0x08, 0xAB, 0xDD, 0x99, + 0x3F, 0xAC, 0x30, 0x70, 0x63, 0x3E, 0x28, 0x6C, + 0xF8, 0x33, 0x9C, 0xE2, 0x95, 0xDD, 0x35, 0x2D, + 0xF4, 0xB4, 0xB4, 0x0B, 0x2F, 0x29, 0xDA, 0x1D, + 0xD5, 0x0B, 0x3A, 0x05, 0xD0, 0x79, 0xE6, 0xBB + }, + { + 0x82, 0x10, 0xCD, 0x2C, 0x2D, 0x3B, 0x13, 0x5C, + 0x2C, 0xF0, 0x7F, 0xA0, 0xD1, 0x43, 0x3C, 0xD7, + 0x71, 0xF3, 0x25, 0xD0, 0x75, 0xC6, 0x46, 0x9D, + 0x9C, 0x7F, 0x1B, 0xA0, 0x94, 0x3C, 0xD4, 0xAB, + 0x09, 0x80, 0x8C, 0xAB, 0xF4, 0xAC, 0xB9, 0xCE, + 0x5B, 0xB8, 0x8B, 0x49, 0x89, 0x29, 0xB4, 0xB8, + 0x47, 0xF6, 0x81, 0xAD, 0x2C, 0x49, 0x0D, 0x04, + 0x2D, 0xB2, 0xAE, 0xC9, 0x42, 0x14, 0xB0, 0x6B + }, + { + 0x1D, 0x4E, 0xDF, 0xFF, 0xD8, 0xFD, 0x80, 0xF7, + 0xE4, 0x10, 0x78, 0x40, 0xFA, 0x3A, 0xA3, 0x1E, + 0x32, 0x59, 0x84, 0x91, 0xE4, 0xAF, 0x70, 0x13, + 0xC1, 0x97, 0xA6, 0x5B, 0x7F, 0x36, 0xDD, 0x3A, + 0xC4, 0xB4, 0x78, 0x45, 0x61, 0x11, 0xCD, 0x43, + 0x09, 0xD9, 0x24, 0x35, 0x10, 0x78, 0x2F, 0xA3, + 0x1B, 0x7C, 0x4C, 0x95, 0xFA, 0x95, 0x15, 0x20, + 0xD0, 0x20, 0xEB, 0x7E, 0x5C, 0x36, 0xE4, 0xEF + }, + { + 0xAF, 0x8E, 0x6E, 0x91, 0xFA, 0xB4, 0x6C, 0xE4, + 0x87, 0x3E, 0x1A, 0x50, 0xA8, 0xEF, 0x44, 0x8C, + 0xC2, 0x91, 0x21, 0xF7, 0xF7, 0x4D, 0xEE, 0xF3, + 0x4A, 0x71, 0xEF, 0x89, 0xCC, 0x00, 0xD9, 0x27, + 0x4B, 0xC6, 0xC2, 0x45, 0x4B, 0xBB, 0x32, 0x30, + 0xD8, 0xB2, 0xEC, 0x94, 0xC6, 0x2B, 0x1D, 0xEC, + 0x85, 0xF3, 0x59, 0x3B, 0xFA, 0x30, 0xEA, 0x6F, + 0x7A, 0x44, 0xD7, 0xC0, 0x94, 0x65, 0xA2, 0x53 + }, + { + 0x29, 0xFD, 0x38, 0x4E, 0xD4, 0x90, 0x6F, 0x2D, + 0x13, 0xAA, 0x9F, 0xE7, 0xAF, 0x90, 0x59, 0x90, + 0x93, 0x8B, 0xED, 0x80, 0x7F, 0x18, 0x32, 0x45, + 0x4A, 0x37, 0x2A, 0xB4, 0x12, 0xEE, 0xA1, 0xF5, + 0x62, 0x5A, 0x1F, 0xCC, 0x9A, 0xC8, 0x34, 0x3B, + 0x7C, 0x67, 0xC5, 0xAB, 0xA6, 0xE0, 0xB1, 0xCC, + 0x46, 0x44, 0x65, 0x49, 0x13, 0x69, 0x2C, 0x6B, + 0x39, 0xEB, 0x91, 0x87, 0xCE, 0xAC, 0xD3, 0xEC + }, + { + 0xA2, 0x68, 0xC7, 0x88, 0x5D, 0x98, 0x74, 0xA5, + 0x1C, 0x44, 0xDF, 0xFE, 0xD8, 0xEA, 0x53, 0xE9, + 0x4F, 0x78, 0x45, 0x6E, 0x0B, 0x2E, 0xD9, 0x9F, + 0xF5, 0xA3, 0x92, 0x47, 0x60, 0x81, 0x38, 0x26, + 0xD9, 0x60, 0xA1, 0x5E, 0xDB, 0xED, 0xBB, 0x5D, + 0xE5, 0x22, 0x6B, 0xA4, 0xB0, 0x74, 0xE7, 0x1B, + 0x05, 0xC5, 0x5B, 0x97, 0x56, 0xBB, 0x79, 0xE5, + 0x5C, 0x02, 0x75, 0x4C, 0x2C, 0x7B, 0x6C, 0x8A + }, + { + 0x0C, 0xF8, 0x54, 0x54, 0x88, 0xD5, 0x6A, 0x86, + 0x81, 0x7C, 0xD7, 0xEC, 0xB1, 0x0F, 0x71, 0x16, + 0xB7, 0xEA, 0x53, 0x0A, 0x45, 0xB6, 0xEA, 0x49, + 0x7B, 0x6C, 0x72, 0xC9, 0x97, 0xE0, 0x9E, 0x3D, + 0x0D, 0xA8, 0x69, 0x8F, 0x46, 0xBB, 0x00, 0x6F, + 0xC9, 0x77, 0xC2, 0xCD, 0x3D, 0x11, 0x77, 0x46, + 0x3A, 0xC9, 0x05, 0x7F, 0xDD, 0x16, 0x62, 0xC8, + 0x5D, 0x0C, 0x12, 0x64, 0x43, 0xC1, 0x04, 0x73 + }, + { + 0xB3, 0x96, 0x14, 0x26, 0x8F, 0xDD, 0x87, 0x81, + 0x51, 0x5E, 0x2C, 0xFE, 0xBF, 0x89, 0xB4, 0xD5, + 0x40, 0x2B, 0xAB, 0x10, 0xC2, 0x26, 0xE6, 0x34, + 0x4E, 0x6B, 0x9A, 0xE0, 0x00, 0xFB, 0x0D, 0x6C, + 0x79, 0xCB, 0x2F, 0x3E, 0xC8, 0x0E, 0x80, 0xEA, + 0xEB, 0x19, 0x80, 0xD2, 0xF8, 0x69, 0x89, 0x16, + 0xBD, 0x2E, 0x9F, 0x74, 0x72, 0x36, 0x65, 0x51, + 0x16, 0x64, 0x9C, 0xD3, 0xCA, 0x23, 0xA8, 0x37 + }, + { + 0x74, 0xBE, 0xF0, 0x92, 0xFC, 0x6F, 0x1E, 0x5D, + 0xBA, 0x36, 0x63, 0xA3, 0xFB, 0x00, 0x3B, 0x2A, + 0x5B, 0xA2, 0x57, 0x49, 0x65, 0x36, 0xD9, 0x9F, + 0x62, 0xB9, 0xD7, 0x3F, 0x8F, 0x9E, 0xB3, 0xCE, + 0x9F, 0xF3, 0xEE, 0xC7, 0x09, 0xEB, 0x88, 0x36, + 0x55, 0xEC, 0x9E, 0xB8, 0x96, 0xB9, 0x12, 0x8F, + 0x2A, 0xFC, 0x89, 0xCF, 0x7D, 0x1A, 0xB5, 0x8A, + 0x72, 0xF4, 0xA3, 0xBF, 0x03, 0x4D, 0x2B, 0x4A + }, + { + 0x3A, 0x98, 0x8D, 0x38, 0xD7, 0x56, 0x11, 0xF3, + 0xEF, 0x38, 0xB8, 0x77, 0x49, 0x80, 0xB3, 0x3E, + 0x57, 0x3B, 0x6C, 0x57, 0xBE, 0xE0, 0x46, 0x9B, + 0xA5, 0xEE, 0xD9, 0xB4, 0x4F, 0x29, 0x94, 0x5E, + 0x73, 0x47, 0x96, 0x7F, 0xBA, 0x2C, 0x16, 0x2E, + 0x1C, 0x3B, 0xE7, 0xF3, 0x10, 0xF2, 0xF7, 0x5E, + 0xE2, 0x38, 0x1E, 0x7B, 0xFD, 0x6B, 0x3F, 0x0B, + 0xAE, 0xA8, 0xD9, 0x5D, 0xFB, 0x1D, 0xAF, 0xB1 + }, + { + 0x58, 0xAE, 0xDF, 0xCE, 0x6F, 0x67, 0xDD, 0xC8, + 0x5A, 0x28, 0xC9, 0x92, 0xF1, 0xC0, 0xBD, 0x09, + 0x69, 0xF0, 0x41, 0xE6, 0x6F, 0x1E, 0xE8, 0x80, + 0x20, 0xA1, 0x25, 0xCB, 0xFC, 0xFE, 0xBC, 0xD6, + 0x17, 0x09, 0xC9, 0xC4, 0xEB, 0xA1, 0x92, 0xC1, + 0x5E, 0x69, 0xF0, 0x20, 0xD4, 0x62, 0x48, 0x60, + 0x19, 0xFA, 0x8D, 0xEA, 0x0C, 0xD7, 0xA4, 0x29, + 0x21, 0xA1, 0x9D, 0x2F, 0xE5, 0x46, 0xD4, 0x3D + }, + { + 0x93, 0x47, 0xBD, 0x29, 0x14, 0x73, 0xE6, 0xB4, + 0xE3, 0x68, 0x43, 0x7B, 0x8E, 0x56, 0x1E, 0x06, + 0x5F, 0x64, 0x9A, 0x6D, 0x8A, 0xDA, 0x47, 0x9A, + 0xD0, 0x9B, 0x19, 0x99, 0xA8, 0xF2, 0x6B, 0x91, + 0xCF, 0x61, 0x20, 0xFD, 0x3B, 0xFE, 0x01, 0x4E, + 0x83, 0xF2, 0x3A, 0xCF, 0xA4, 0xC0, 0xAD, 0x7B, + 0x37, 0x12, 0xB2, 0xC3, 0xC0, 0x73, 0x32, 0x70, + 0x66, 0x31, 0x12, 0xCC, 0xD9, 0x28, 0x5C, 0xD9 + }, + { + 0xB3, 0x21, 0x63, 0xE7, 0xC5, 0xDB, 0xB5, 0xF5, + 0x1F, 0xDC, 0x11, 0xD2, 0xEA, 0xC8, 0x75, 0xEF, + 0xBB, 0xCB, 0x7E, 0x76, 0x99, 0x09, 0x0A, 0x7E, + 0x7F, 0xF8, 0xA8, 0xD5, 0x07, 0x95, 0xAF, 0x5D, + 0x74, 0xD9, 0xFF, 0x98, 0x54, 0x3E, 0xF8, 0xCD, + 0xF8, 0x9A, 0xC1, 0x3D, 0x04, 0x85, 0x27, 0x87, + 0x56, 0xE0, 0xEF, 0x00, 0xC8, 0x17, 0x74, 0x56, + 0x61, 0xE1, 0xD5, 0x9F, 0xE3, 0x8E, 0x75, 0x37 + }, + { + 0x10, 0x85, 0xD7, 0x83, 0x07, 0xB1, 0xC4, 0xB0, + 0x08, 0xC5, 0x7A, 0x2E, 0x7E, 0x5B, 0x23, 0x46, + 0x58, 0xA0, 0xA8, 0x2E, 0x4F, 0xF1, 0xE4, 0xAA, + 0xAC, 0x72, 0xB3, 0x12, 0xFD, 0xA0, 0xFE, 0x27, + 0xD2, 0x33, 0xBC, 0x5B, 0x10, 0xE9, 0xCC, 0x17, + 0xFD, 0xC7, 0x69, 0x7B, 0x54, 0x0C, 0x7D, 0x95, + 0xEB, 0x21, 0x5A, 0x19, 0xA1, 0xA0, 0xE2, 0x0E, + 0x1A, 0xBF, 0xA1, 0x26, 0xEF, 0xD5, 0x68, 0xC7 + }, + { + 0x4E, 0x5C, 0x73, 0x4C, 0x7D, 0xDE, 0x01, 0x1D, + 0x83, 0xEA, 0xC2, 0xB7, 0x34, 0x7B, 0x37, 0x35, + 0x94, 0xF9, 0x2D, 0x70, 0x91, 0xB9, 0xCA, 0x34, + 0xCB, 0x9C, 0x6F, 0x39, 0xBD, 0xF5, 0xA8, 0xD2, + 0xF1, 0x34, 0x37, 0x9E, 0x16, 0xD8, 0x22, 0xF6, + 0x52, 0x21, 0x70, 0xCC, 0xF2, 0xDD, 0xD5, 0x5C, + 0x84, 0xB9, 0xE6, 0xC6, 0x4F, 0xC9, 0x27, 0xAC, + 0x4C, 0xF8, 0xDF, 0xB2, 0xA1, 0x77, 0x01, 0xF2 + }, + { + 0x69, 0x5D, 0x83, 0xBD, 0x99, 0x0A, 0x11, 0x17, + 0xB3, 0xD0, 0xCE, 0x06, 0xCC, 0x88, 0x80, 0x27, + 0xD1, 0x2A, 0x05, 0x4C, 0x26, 0x77, 0xFD, 0x82, + 0xF0, 0xD4, 0xFB, 0xFC, 0x93, 0x57, 0x55, 0x23, + 0xE7, 0x99, 0x1A, 0x5E, 0x35, 0xA3, 0x75, 0x2E, + 0x9B, 0x70, 0xCE, 0x62, 0x99, 0x2E, 0x26, 0x8A, + 0x87, 0x77, 0x44, 0xCD, 0xD4, 0x35, 0xF5, 0xF1, + 0x30, 0x86, 0x9C, 0x9A, 0x20, 0x74, 0xB3, 0x38 + }, + { + 0xA6, 0x21, 0x37, 0x43, 0x56, 0x8E, 0x3B, 0x31, + 0x58, 0xB9, 0x18, 0x43, 0x01, 0xF3, 0x69, 0x08, + 0x47, 0x55, 0x4C, 0x68, 0x45, 0x7C, 0xB4, 0x0F, + 0xC9, 0xA4, 0xB8, 0xCF, 0xD8, 0xD4, 0xA1, 0x18, + 0xC3, 0x01, 0xA0, 0x77, 0x37, 0xAE, 0xDA, 0x0F, + 0x92, 0x9C, 0x68, 0x91, 0x3C, 0x5F, 0x51, 0xC8, + 0x03, 0x94, 0xF5, 0x3B, 0xFF, 0x1C, 0x3E, 0x83, + 0xB2, 0xE4, 0x0C, 0xA9, 0x7E, 0xBA, 0x9E, 0x15 + }, + { + 0xD4, 0x44, 0xBF, 0xA2, 0x36, 0x2A, 0x96, 0xDF, + 0x21, 0x3D, 0x07, 0x0E, 0x33, 0xFA, 0x84, 0x1F, + 0x51, 0x33, 0x4E, 0x4E, 0x76, 0x86, 0x6B, 0x81, + 0x39, 0xE8, 0xAF, 0x3B, 0xB3, 0x39, 0x8B, 0xE2, + 0xDF, 0xAD, 0xDC, 0xBC, 0x56, 0xB9, 0x14, 0x6D, + 0xE9, 0xF6, 0x81, 0x18, 0xDC, 0x58, 0x29, 0xE7, + 0x4B, 0x0C, 0x28, 0xD7, 0x71, 0x19, 0x07, 0xB1, + 0x21, 0xF9, 0x16, 0x1C, 0xB9, 0x2B, 0x69, 0xA9 + }, + { + 0x14, 0x27, 0x09, 0xD6, 0x2E, 0x28, 0xFC, 0xCC, + 0xD0, 0xAF, 0x97, 0xFA, 0xD0, 0xF8, 0x46, 0x5B, + 0x97, 0x1E, 0x82, 0x20, 0x1D, 0xC5, 0x10, 0x70, + 0xFA, 0xA0, 0x37, 0x2A, 0xA4, 0x3E, 0x92, 0x48, + 0x4B, 0xE1, 0xC1, 0xE7, 0x3B, 0xA1, 0x09, 0x06, + 0xD5, 0xD1, 0x85, 0x3D, 0xB6, 0xA4, 0x10, 0x6E, + 0x0A, 0x7B, 0xF9, 0x80, 0x0D, 0x37, 0x3D, 0x6D, + 0xEE, 0x2D, 0x46, 0xD6, 0x2E, 0xF2, 0xA4, 0x61 + }, +}; + + + + +static const uint8_t blake2sp_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0xDD, 0x0E, 0x89, 0x17, 0x76, 0x93, 0x3F, 0x43, + 0xC7, 0xD0, 0x32, 0xB0, 0x8A, 0x91, 0x7E, 0x25, + 0x74, 0x1F, 0x8A, 0xA9, 0xA1, 0x2C, 0x12, 0xE1, + 0xCA, 0xC8, 0x80, 0x15, 0x00, 0xF2, 0xCA, 0x4F + }, + { + 0xA6, 0xB9, 0xEE, 0xCC, 0x25, 0x22, 0x7A, 0xD7, + 0x88, 0xC9, 0x9D, 0x3F, 0x23, 0x6D, 0xEB, 0xC8, + 0xDA, 0x40, 0x88, 0x49, 0xE9, 0xA5, 0x17, 0x89, + 0x78, 0x72, 0x7A, 0x81, 0x45, 0x7F, 0x72, 0x39 + }, + { + 0xDA, 0xCA, 0xDE, 0xCE, 0x7A, 0x8E, 0x6B, 0xF3, + 0xAB, 0xFE, 0x32, 0x4C, 0xA6, 0x95, 0x43, 0x69, + 0x84, 0xB8, 0x19, 0x5D, 0x29, 0xF6, 0xBB, 0xD8, + 0x96, 0xE4, 0x1E, 0x18, 0xE2, 0x1C, 0x91, 0x45 + }, + { + 0xED, 0x14, 0x41, 0x3B, 0x40, 0xDA, 0x68, 0x9F, + 0x1F, 0x7F, 0xED, 0x2B, 0x08, 0xDF, 0xF4, 0x5B, + 0x80, 0x92, 0xDB, 0x5E, 0xC2, 0xC3, 0x61, 0x0E, + 0x02, 0x72, 0x4D, 0x20, 0x2F, 0x42, 0x3C, 0x46 + }, + { + 0x9B, 0x8A, 0x52, 0x7B, 0x52, 0x72, 0x25, 0x0A, + 0x1E, 0xC3, 0x97, 0x38, 0x8F, 0x04, 0x09, 0x14, + 0x95, 0x48, 0x06, 0xE7, 0x94, 0xDB, 0x04, 0xB7, + 0x0A, 0x46, 0x11, 0xBC, 0x59, 0x58, 0x6A, 0x83 + }, + { + 0x2B, 0xB6, 0x33, 0x37, 0x29, 0x00, 0x0B, 0xE3, + 0xD5, 0xA2, 0x1B, 0x98, 0xF8, 0xE7, 0xEA, 0xD0, + 0x77, 0xF1, 0x51, 0xA5, 0x39, 0x39, 0x19, 0xEB, + 0x67, 0xC8, 0x76, 0xEE, 0x00, 0xBB, 0xBB, 0x04 + }, + { + 0x63, 0xC0, 0x14, 0x08, 0x15, 0x4A, 0xD1, 0x9D, + 0x7F, 0xB7, 0x39, 0xF3, 0x11, 0x78, 0x17, 0x80, + 0x46, 0x2C, 0xF2, 0xEE, 0xCC, 0xE6, 0x0F, 0x06, + 0x4E, 0x85, 0x34, 0x87, 0xC2, 0x72, 0xE3, 0xEB + }, + { + 0x3D, 0x05, 0x1A, 0x11, 0x76, 0x01, 0x9C, 0xA3, + 0x7B, 0xF3, 0x3D, 0x60, 0x42, 0x7F, 0x8D, 0x9D, + 0x1C, 0x3A, 0xBD, 0x59, 0x82, 0x97, 0xCF, 0xB4, + 0x23, 0x5F, 0x74, 0x7D, 0x7C, 0x7C, 0x7F, 0xEC + }, + { + 0x39, 0x1E, 0xA9, 0x12, 0xDF, 0x4D, 0x4D, 0x79, + 0xA4, 0x64, 0x6D, 0x9D, 0xA2, 0x54, 0x9A, 0x44, + 0x6D, 0x22, 0x40, 0xF6, 0x24, 0x15, 0xD0, 0x70, + 0xA2, 0xE0, 0x93, 0x99, 0x2B, 0x47, 0x1F, 0xBA + }, + { + 0x32, 0x46, 0x40, 0x44, 0x0E, 0xA5, 0xC3, 0x08, + 0x2D, 0xDC, 0x30, 0x9E, 0x78, 0x09, 0xD7, 0x41, + 0xD6, 0xCC, 0x1B, 0x2D, 0x49, 0x0F, 0xF8, 0xC0, + 0x52, 0x12, 0x8A, 0x6E, 0xEB, 0x40, 0x9D, 0x62 + }, + { + 0xAB, 0x85, 0x5E, 0x6F, 0xA3, 0x9A, 0x5E, 0x8F, + 0xC9, 0x0E, 0xAC, 0xB9, 0x99, 0xC7, 0xF7, 0x8A, + 0xE7, 0x1E, 0x59, 0xC3, 0xD9, 0x7D, 0x60, 0xAF, + 0xE5, 0x17, 0xD5, 0x87, 0x92, 0x3B, 0x77, 0x11 + }, + { + 0x2A, 0x39, 0xDA, 0x45, 0x86, 0xEF, 0xC4, 0x77, + 0x85, 0xA7, 0xA8, 0xDA, 0x85, 0x68, 0x3A, 0x51, + 0x72, 0x4C, 0xDE, 0xF5, 0x41, 0x3B, 0x35, 0x6D, + 0xC4, 0xFB, 0x50, 0x05, 0x13, 0xF8, 0xFA, 0x2E + }, + { + 0x8A, 0x00, 0x57, 0xC1, 0xF7, 0x8A, 0xD6, 0x21, + 0x45, 0x55, 0xC0, 0x67, 0x07, 0x33, 0xE2, 0x9A, + 0x4C, 0x7E, 0x95, 0x62, 0x27, 0x66, 0x0E, 0xFE, + 0xB1, 0xD7, 0xFC, 0x79, 0xF5, 0x8E, 0xC6, 0xF2 + }, + { + 0x07, 0x64, 0xB0, 0x01, 0x7F, 0x5B, 0xD9, 0x51, + 0xF0, 0x1D, 0x9F, 0xDF, 0x95, 0xC0, 0xCB, 0x41, + 0x38, 0x98, 0x5D, 0x84, 0x79, 0x9C, 0xD4, 0x29, + 0x84, 0xE2, 0x5B, 0x51, 0x28, 0x00, 0xE7, 0x3C + }, + { + 0xCC, 0x02, 0x49, 0x56, 0x93, 0xC8, 0xE1, 0x84, + 0xAD, 0x2E, 0xD0, 0x9D, 0x53, 0x3D, 0xC3, 0x3B, + 0x76, 0xA7, 0x78, 0x3D, 0x62, 0x07, 0xFC, 0xAC, + 0xCB, 0x64, 0xF3, 0xED, 0x2C, 0x6D, 0x66, 0xE0 + }, + { + 0xC0, 0xDF, 0x49, 0xC2, 0x06, 0xA3, 0x42, 0x88, + 0x14, 0x32, 0x16, 0x84, 0x7D, 0xF3, 0x34, 0xD4, + 0x56, 0x9D, 0xAD, 0x73, 0xC2, 0xB1, 0xFF, 0x62, + 0x84, 0x88, 0x4F, 0xD3, 0x89, 0x41, 0xFB, 0x95 + }, + { + 0xB9, 0x19, 0x45, 0x19, 0xE4, 0x97, 0x8A, 0x9D, + 0xC8, 0x93, 0xB2, 0x8B, 0xD8, 0x08, 0xCD, 0xFA, + 0xBB, 0x1B, 0xD5, 0x10, 0xD8, 0x62, 0xB3, 0x17, + 0x1F, 0xF6, 0xE0, 0x17, 0xA4, 0x1B, 0x80, 0x4C + }, + { + 0xBB, 0xA9, 0x27, 0xAC, 0xF1, 0x1B, 0xEB, 0xD3, + 0x62, 0xA3, 0xA3, 0xEB, 0x78, 0xC4, 0xBB, 0x65, + 0xE6, 0x02, 0xA8, 0x70, 0x9F, 0xCE, 0xF3, 0x8D, + 0xC6, 0xC8, 0xB7, 0xBD, 0xA6, 0x64, 0xC3, 0x2C + }, + { + 0xEC, 0xB4, 0x90, 0x0A, 0x63, 0x92, 0x4E, 0x72, + 0x0D, 0x40, 0xF2, 0xD2, 0xB1, 0x4D, 0x1B, 0xB3, + 0x9C, 0x37, 0x01, 0xAD, 0x73, 0x46, 0xBD, 0x0B, + 0x67, 0x23, 0x42, 0x70, 0xBF, 0xBE, 0x7E, 0x70 + }, + { + 0xF8, 0x31, 0x5A, 0x21, 0xB2, 0x5E, 0x6B, 0xA8, + 0xBF, 0x59, 0xB1, 0x7B, 0x05, 0x91, 0x3B, 0x8C, + 0xA4, 0x65, 0x9F, 0x1C, 0xD8, 0x38, 0xFC, 0xC7, + 0x73, 0xC9, 0xEB, 0x12, 0xE7, 0x00, 0x4E, 0x09 + }, + { + 0x4B, 0x77, 0xAF, 0x67, 0xA9, 0x23, 0x2B, 0xF1, + 0x18, 0x4E, 0x57, 0x81, 0x82, 0x94, 0x03, 0x1E, + 0x55, 0xF1, 0xF8, 0x53, 0xC9, 0x4D, 0xBA, 0xB5, + 0x57, 0x75, 0x47, 0x33, 0x0D, 0x65, 0xAA, 0x61 + }, + { + 0x76, 0x85, 0x68, 0x39, 0x0F, 0xD2, 0xB8, 0x70, + 0x94, 0x11, 0x4E, 0xD4, 0xCF, 0x72, 0x3E, 0xA3, + 0x20, 0xFE, 0x97, 0x7B, 0x53, 0x18, 0x03, 0x05, + 0xC3, 0x84, 0x33, 0x54, 0x79, 0xF0, 0xB5, 0x9B + }, + { + 0xA4, 0x31, 0xCB, 0x27, 0x0F, 0x3E, 0x2C, 0x9B, + 0x7A, 0x95, 0x93, 0xB1, 0x55, 0xCC, 0xEC, 0xFF, + 0x5B, 0x5C, 0x4A, 0x2D, 0xCD, 0x5D, 0x6B, 0xB1, + 0xC4, 0x85, 0xAA, 0x28, 0x69, 0x97, 0xF9, 0x15 + }, + { + 0xD6, 0x91, 0xFA, 0x6A, 0x79, 0x0B, 0x1A, 0x51, + 0x79, 0x80, 0x08, 0x7F, 0x50, 0xB0, 0x3D, 0xED, + 0x8C, 0x6E, 0xD4, 0x86, 0xD0, 0x84, 0x22, 0x1C, + 0x82, 0x7D, 0x9B, 0xD9, 0x22, 0xBE, 0xB8, 0xC0 + }, + { + 0x8F, 0x97, 0x8A, 0x49, 0x32, 0xF4, 0x45, 0x98, + 0x13, 0xE8, 0xFE, 0x15, 0x68, 0x6E, 0x4E, 0xFA, + 0x25, 0xC2, 0xC5, 0xFF, 0x5A, 0x3A, 0x4F, 0x8C, + 0x9B, 0x14, 0x96, 0x5D, 0x2F, 0x0B, 0xE4, 0x61 + }, + { + 0x1E, 0xFB, 0xD0, 0xC1, 0x31, 0x44, 0x91, 0x42, + 0xF2, 0x29, 0x5F, 0x2D, 0x42, 0x41, 0x1D, 0xFE, + 0x0F, 0x48, 0xD4, 0xAC, 0xAE, 0x76, 0x2D, 0x8D, + 0xF6, 0x7A, 0x57, 0x0B, 0xF7, 0xB1, 0xDC, 0xD5 + }, + { + 0xD5, 0x3B, 0xA9, 0x33, 0x46, 0x14, 0x3A, 0xB8, + 0xE0, 0xD3, 0xD1, 0xBF, 0x27, 0x27, 0x06, 0xD1, + 0x69, 0xE6, 0x6C, 0x69, 0xC7, 0xB8, 0xF4, 0xA5, + 0xE8, 0x2F, 0xEF, 0x44, 0x07, 0x02, 0xBC, 0xF2 + }, + { + 0xF7, 0x1A, 0x3E, 0xC0, 0x1A, 0xA3, 0x82, 0xEA, + 0x76, 0x99, 0x2B, 0x43, 0x0A, 0x7F, 0x42, 0xC7, + 0xAD, 0x2A, 0x86, 0xAE, 0xA9, 0xC1, 0x9E, 0x76, + 0xCD, 0x17, 0x32, 0xEC, 0x68, 0x30, 0xDE, 0x6F + }, + { + 0x80, 0xA6, 0xAB, 0x7B, 0x71, 0x04, 0x64, 0xF9, + 0x3E, 0x6C, 0xBA, 0x96, 0x86, 0x4A, 0xA6, 0x40, + 0x9B, 0xCA, 0xFC, 0x1B, 0xF4, 0xB3, 0x2A, 0x30, + 0x93, 0x72, 0xE8, 0x57, 0xE8, 0x04, 0x06, 0x8C + }, + { + 0xDB, 0xDE, 0x81, 0xE5, 0x1A, 0x52, 0x17, 0x4B, + 0x10, 0x14, 0x90, 0x1B, 0x53, 0xBE, 0xF8, 0x8D, + 0xE9, 0x3B, 0x29, 0xE2, 0x74, 0x34, 0x7E, 0x8E, + 0x9A, 0x7B, 0x03, 0x74, 0x56, 0x62, 0x9F, 0x35 + }, + { + 0x75, 0xF2, 0x74, 0x46, 0x6B, 0x1A, 0x2D, 0x0F, + 0xD8, 0x45, 0xBB, 0xB5, 0x7C, 0x38, 0xC9, 0x89, + 0x51, 0x6E, 0x15, 0x68, 0x32, 0x0A, 0xB5, 0x17, + 0xB1, 0x63, 0xEA, 0xF7, 0x09, 0x23, 0x4C, 0xC7 + }, + { + 0xAF, 0xE1, 0xA0, 0x59, 0x1C, 0x49, 0x1D, 0x41, + 0x6E, 0xB6, 0x4F, 0x62, 0x86, 0xF3, 0xBA, 0x29, + 0xD4, 0xC9, 0x99, 0x82, 0x14, 0xA3, 0x83, 0x1C, + 0x39, 0x01, 0x4A, 0xC0, 0x30, 0x55, 0x79, 0x45 + }, + { + 0x67, 0xFF, 0x6A, 0xCD, 0xBE, 0x8A, 0x99, 0xA1, + 0x66, 0xA5, 0xD9, 0xCF, 0x32, 0x13, 0x65, 0x06, + 0xB5, 0x48, 0xD6, 0xC9, 0x47, 0xC2, 0x4C, 0x69, + 0x9C, 0xEA, 0x3A, 0xFD, 0x92, 0xAD, 0xFA, 0xCA + }, + { + 0xBF, 0xB4, 0xD0, 0xC7, 0x11, 0x20, 0x75, 0x26, + 0x2C, 0x2D, 0xD2, 0x48, 0xF3, 0x34, 0xB2, 0xEF, + 0x15, 0x40, 0x08, 0x7E, 0xCC, 0x73, 0x82, 0xBC, + 0x2A, 0x27, 0x25, 0x75, 0xC5, 0x00, 0x9F, 0x70 + }, + { + 0x17, 0xC9, 0x4B, 0x9C, 0x53, 0x72, 0x43, 0xF2, + 0x33, 0x5B, 0x86, 0x39, 0x49, 0xB2, 0xB9, 0x1C, + 0x98, 0xA6, 0x95, 0x6D, 0x7C, 0x10, 0xAA, 0x98, + 0x99, 0x59, 0xA8, 0x0F, 0x91, 0x0C, 0x25, 0x22 + }, + { + 0xF6, 0x33, 0x8F, 0x43, 0x4D, 0x31, 0x94, 0x10, + 0x19, 0x6D, 0x95, 0x19, 0xAB, 0xCA, 0xEF, 0xF7, + 0xD5, 0x54, 0x39, 0xFD, 0x2A, 0xA5, 0xBA, 0xBF, + 0x7A, 0x7E, 0x79, 0x13, 0xB2, 0x94, 0xED, 0x4D + }, + { + 0x08, 0xEF, 0x7D, 0x65, 0xF9, 0xBB, 0xF3, 0xDA, + 0x1F, 0x78, 0x84, 0xAE, 0x9B, 0x75, 0x90, 0x1F, + 0xD8, 0x52, 0x95, 0x66, 0x2A, 0x6E, 0xA7, 0x1D, + 0xE0, 0x8B, 0xEE, 0x38, 0x34, 0x57, 0x62, 0x78 + }, + { + 0x16, 0x47, 0xEC, 0xC2, 0xBA, 0x13, 0xF8, 0xB9, + 0x3B, 0x2F, 0xBC, 0xDC, 0x4E, 0x8F, 0x1D, 0xFA, + 0x47, 0xFE, 0x3B, 0xE1, 0x2A, 0xAA, 0x0E, 0x45, + 0x9B, 0x0E, 0x5A, 0x87, 0xF3, 0xA6, 0x9B, 0xB0 + }, + { + 0xFF, 0x92, 0x7A, 0x71, 0x78, 0x81, 0xF6, 0xFD, + 0x8E, 0xD8, 0xBF, 0x5D, 0x5E, 0x35, 0xBD, 0x80, + 0x16, 0x15, 0x73, 0xE5, 0x82, 0x94, 0x04, 0xC3, + 0x2D, 0x2A, 0x27, 0x6A, 0x01, 0xF4, 0xB9, 0x06 + }, + { + 0xC8, 0xCA, 0xF1, 0x36, 0xFF, 0x20, 0x9C, 0x82, + 0xE0, 0x24, 0x0C, 0x1E, 0x62, 0xA3, 0xBC, 0x7E, + 0x9C, 0xAC, 0x87, 0x3B, 0x01, 0x1C, 0xF7, 0xC5, + 0xE6, 0x7E, 0xC1, 0x87, 0xA5, 0xFB, 0xCD, 0x96 + }, + { + 0xD9, 0xAC, 0xC7, 0x3E, 0x3F, 0x42, 0x1E, 0x18, + 0x83, 0xB5, 0xED, 0x53, 0xD8, 0x2A, 0x9A, 0xEC, + 0x8F, 0x5D, 0xC9, 0x80, 0xC4, 0x2B, 0xCA, 0xEB, + 0x0E, 0x7D, 0x89, 0x76, 0xA3, 0x38, 0xEF, 0x51 + }, + { + 0x9F, 0x17, 0x3F, 0xCF, 0x08, 0xA5, 0x36, 0x21, + 0x93, 0xF3, 0x52, 0xC8, 0x25, 0x6A, 0xE5, 0x34, + 0xAE, 0x9C, 0xE7, 0xBF, 0xA4, 0xBC, 0x09, 0xFA, + 0xC9, 0x00, 0x98, 0xF9, 0x8A, 0x71, 0x62, 0x94 + }, + { + 0x0A, 0x72, 0x45, 0x79, 0xDC, 0x80, 0xBC, 0x0C, + 0x90, 0x04, 0xE5, 0x1B, 0xE7, 0xEF, 0xF3, 0xAF, + 0xA5, 0x30, 0x75, 0xAB, 0x4A, 0x32, 0x55, 0x77, + 0x33, 0x58, 0x6E, 0x82, 0x0F, 0xD3, 0x64, 0x23 + }, + { + 0x38, 0xF7, 0xC3, 0x40, 0xF4, 0xB1, 0x59, 0xB1, + 0xE5, 0x94, 0xF6, 0xEB, 0x83, 0x28, 0x49, 0x17, + 0xB7, 0xAA, 0x19, 0xC7, 0x4F, 0x57, 0x11, 0x7A, + 0x4E, 0x08, 0xCF, 0x7C, 0x4E, 0x32, 0xA2, 0x3C + }, + { + 0x1C, 0x67, 0x4B, 0xE2, 0x57, 0xE9, 0xB3, 0x31, + 0x34, 0xD4, 0x16, 0x8F, 0x15, 0x2F, 0x8B, 0x63, + 0xDF, 0xD7, 0x80, 0xC9, 0x7D, 0xC4, 0xDC, 0x37, + 0xAC, 0x26, 0xCC, 0x0A, 0xEF, 0xB7, 0x9C, 0x1A + }, + { + 0x2F, 0x0C, 0x59, 0x76, 0x16, 0xD5, 0x75, 0x17, + 0x14, 0xA5, 0xFB, 0x4E, 0xBF, 0x3C, 0x48, 0x1A, + 0x96, 0xC3, 0xAD, 0x14, 0x5E, 0xBD, 0xE0, 0x65, + 0x09, 0xF3, 0xA2, 0xE5, 0xF2, 0xC1, 0x3F, 0xC8 + }, + { + 0xFD, 0xDC, 0x69, 0xE0, 0xC9, 0x83, 0xCD, 0x82, + 0x83, 0xED, 0x81, 0x88, 0xBE, 0xC4, 0xE5, 0xF4, + 0x1D, 0xEA, 0x3D, 0x01, 0xB9, 0xE7, 0x4C, 0x4B, + 0xAF, 0x73, 0x41, 0xD8, 0xB4, 0xBF, 0x55, 0x3D + }, + { + 0x24, 0xD0, 0x83, 0xCB, 0xA0, 0x38, 0xC8, 0x7E, + 0x9A, 0xCB, 0x86, 0x81, 0x82, 0x02, 0x08, 0xB7, + 0x5C, 0xB3, 0x29, 0x3A, 0x96, 0xC9, 0xEF, 0xA7, + 0x5D, 0x2C, 0x63, 0xF1, 0x6B, 0x85, 0xFE, 0x1E + }, + { + 0x7F, 0x6A, 0x64, 0x9C, 0xCA, 0x89, 0xB2, 0x53, + 0xFF, 0xBD, 0x20, 0xC0, 0x16, 0x98, 0x01, 0x00, + 0xA8, 0x7C, 0x16, 0x81, 0x09, 0x62, 0x8F, 0xCC, + 0x66, 0x52, 0x5D, 0x8B, 0xAA, 0xFE, 0x50, 0x5F + }, + { + 0x6D, 0xA3, 0x73, 0xB4, 0xC1, 0x87, 0x92, 0xB3, + 0x20, 0x9A, 0xDD, 0x15, 0xA5, 0x07, 0x4A, 0x1D, + 0x70, 0xC1, 0x0B, 0xB3, 0x94, 0x80, 0xCA, 0x3F, + 0xE5, 0xC4, 0x39, 0xD9, 0x5F, 0xC2, 0x86, 0xCA + }, + { + 0x27, 0x0A, 0xFF, 0xA6, 0x42, 0x6F, 0x1A, 0x51, + 0x5C, 0x9B, 0x76, 0xDF, 0xC2, 0x7D, 0x18, 0x1F, + 0xC2, 0xFD, 0x57, 0xD0, 0x82, 0xA3, 0xBA, 0x2C, + 0x1E, 0xEF, 0x07, 0x15, 0x33, 0xA6, 0xDF, 0xB7 + }, + { + 0xC2, 0x2E, 0x15, 0xCF, 0xC5, 0xA3, 0xD1, 0x4B, + 0x64, 0xD1, 0x31, 0xF3, 0x5F, 0xB3, 0x5D, 0xD5, + 0xE6, 0xC5, 0x7D, 0xC4, 0xAF, 0xC5, 0x52, 0x27, + 0x75, 0x01, 0xEC, 0xA7, 0x64, 0xDA, 0x74, 0xBF + }, + { + 0xAD, 0x68, 0x3E, 0x96, 0xB8, 0xAC, 0x65, 0x8C, + 0x4F, 0x3F, 0x10, 0xAD, 0x22, 0xD9, 0x9B, 0x07, + 0xCB, 0x5E, 0xF9, 0xE3, 0x1C, 0xBE, 0x11, 0xE7, + 0xF7, 0xDC, 0x29, 0xF2, 0xAE, 0xE5, 0x02, 0x4C + }, + { + 0x78, 0xD3, 0xCE, 0xDA, 0x1C, 0xE0, 0x52, 0x93, + 0xF4, 0x30, 0xF6, 0x16, 0x7B, 0x33, 0xC9, 0x9F, + 0x0B, 0x1D, 0x6D, 0xAD, 0xE5, 0x21, 0x43, 0xC2, + 0x92, 0x55, 0x77, 0xC0, 0xBA, 0x82, 0x53, 0xEB + }, + { + 0xE0, 0x06, 0x45, 0x63, 0x44, 0xF9, 0x0F, 0x50, + 0x1C, 0x25, 0x81, 0x3F, 0x9B, 0xE2, 0xA3, 0xF4, + 0x0B, 0x98, 0x74, 0xFA, 0x05, 0x63, 0x98, 0x1C, + 0xD4, 0x56, 0xEE, 0x8D, 0x44, 0x80, 0x7C, 0x93 + }, + { + 0x39, 0x08, 0xE8, 0xD5, 0x47, 0xC0, 0xAF, 0xB1, + 0x13, 0x49, 0x49, 0x46, 0x63, 0x04, 0xA1, 0x45, + 0x02, 0x7E, 0x6B, 0xB7, 0xA7, 0x4D, 0xD1, 0xC1, + 0x62, 0xCD, 0xF0, 0xBC, 0xF7, 0x72, 0x37, 0xE8 + }, + { + 0x1B, 0x6C, 0x87, 0xA3, 0x48, 0x38, 0xC7, 0xCD, + 0x5F, 0xD0, 0x89, 0x14, 0x22, 0x4E, 0x90, 0xC2, + 0x2A, 0xBF, 0x5A, 0x97, 0xB1, 0x06, 0x46, 0xD9, + 0x8C, 0x49, 0x16, 0xD3, 0xA8, 0x93, 0x9E, 0x62 + }, + { + 0xB0, 0xD3, 0x8F, 0x82, 0xF2, 0x48, 0x91, 0x69, + 0x52, 0xB3, 0x16, 0xB6, 0xD3, 0x6D, 0x9E, 0x02, + 0x2D, 0xF6, 0xEE, 0xCC, 0x26, 0xC7, 0x62, 0xA6, + 0x55, 0xCF, 0x5F, 0x0A, 0xE6, 0x49, 0xE2, 0xBD + }, + { + 0x8D, 0x66, 0xFC, 0x9C, 0xED, 0xA5, 0xED, 0xDF, + 0xB1, 0xE0, 0x4D, 0x09, 0x6C, 0xA7, 0x0E, 0xF5, + 0x06, 0x50, 0xFB, 0x87, 0xCC, 0x6A, 0x9F, 0xFB, + 0xB3, 0xD2, 0x0B, 0xCE, 0x7B, 0x5A, 0x60, 0x74 + }, + { + 0x06, 0x43, 0x54, 0xE8, 0xE1, 0x1C, 0xF7, 0x13, + 0xB2, 0xC7, 0x2B, 0xA6, 0x7A, 0xC7, 0xD7, 0x6E, + 0x41, 0xBA, 0x61, 0xDB, 0x9C, 0x2D, 0xEA, 0x52, + 0x2E, 0x0B, 0xDA, 0x17, 0xCB, 0xA5, 0xE3, 0x92 + }, + { + 0xC8, 0xEF, 0x5F, 0x49, 0x8B, 0xD1, 0xBC, 0x70, + 0x7F, 0xBC, 0x7B, 0x5C, 0xBC, 0x2D, 0xFF, 0x04, + 0x93, 0x14, 0x4A, 0xC5, 0x27, 0x86, 0xDB, 0x3C, + 0x79, 0x3E, 0xF4, 0xAE, 0x8A, 0x83, 0x88, 0x47 + }, + { + 0x8A, 0x23, 0x97, 0xDF, 0x31, 0xE7, 0xF0, 0xCC, + 0x29, 0x0D, 0xA9, 0xA8, 0xBB, 0xE4, 0xF5, 0xF7, + 0xA3, 0xA1, 0x37, 0x50, 0x73, 0x0D, 0xB6, 0x2D, + 0xC2, 0x54, 0x0F, 0xDB, 0xD6, 0x18, 0x85, 0x89 + }, + { + 0xF1, 0x2D, 0x0B, 0x13, 0xC6, 0xAD, 0xFB, 0x3B, + 0xE5, 0x0A, 0x51, 0xEB, 0x6B, 0xAF, 0x65, 0xAB, + 0xFB, 0x17, 0x00, 0xBA, 0xA8, 0x7E, 0x52, 0x7D, + 0xBE, 0x3E, 0x67, 0x5A, 0x7A, 0x99, 0x46, 0x61 + }, + { + 0x10, 0x24, 0xC9, 0x40, 0xBE, 0x73, 0x41, 0x44, + 0x9B, 0x50, 0x10, 0x52, 0x2B, 0x50, 0x9F, 0x65, + 0xBB, 0xDC, 0x12, 0x87, 0xB4, 0x55, 0xC2, 0xBB, + 0x7F, 0x72, 0xB2, 0xC9, 0x2F, 0xD0, 0xD1, 0x89 + }, + { + 0x52, 0x60, 0x3B, 0x6C, 0xBF, 0xAD, 0x49, 0x66, + 0xCB, 0x04, 0x4C, 0xB2, 0x67, 0x56, 0x83, 0x85, + 0xCF, 0x35, 0xF2, 0x1E, 0x6C, 0x45, 0xCF, 0x30, + 0xAE, 0xD1, 0x98, 0x32, 0xCB, 0x51, 0xE9, 0xF5 + }, + { + 0xFF, 0xF2, 0x4D, 0x3C, 0xC7, 0x29, 0xD3, 0x95, + 0xDA, 0xF9, 0x78, 0xB0, 0x15, 0x73, 0x06, 0xCB, + 0x49, 0x57, 0x97, 0xE6, 0xC8, 0xDC, 0xA1, 0x73, + 0x1D, 0x2F, 0x6F, 0x81, 0xB8, 0x49, 0xBA, 0xAE + }, + { + 0x41, 0xEE, 0xE9, 0x0D, 0x47, 0xEC, 0x27, 0x72, + 0xCD, 0x35, 0x2D, 0xFD, 0x67, 0xE0, 0x60, 0x5F, + 0xBD, 0xFC, 0x5F, 0xD6, 0xD8, 0x26, 0x45, 0x1E, + 0x3D, 0x06, 0x4D, 0x38, 0x28, 0xBD, 0x3B, 0xAE + }, + { + 0x30, 0x0B, 0x6B, 0x36, 0xE5, 0x9F, 0x85, 0x1D, + 0xDD, 0xC2, 0x9B, 0xFA, 0x93, 0x08, 0x25, 0x20, + 0xCD, 0x77, 0xC5, 0x1E, 0x00, 0x7E, 0x00, 0xD2, + 0xD7, 0x8B, 0x26, 0xF4, 0xAF, 0x96, 0x15, 0x32 + }, + { + 0x9E, 0xF3, 0x03, 0x14, 0x83, 0x4E, 0x40, 0x1C, + 0x87, 0x1A, 0x20, 0x04, 0xE3, 0x8D, 0x5C, 0xE3, + 0x2E, 0xD2, 0x8E, 0x11, 0x37, 0xF1, 0x97, 0x0F, + 0x4F, 0x43, 0x78, 0xC7, 0x37, 0x06, 0x76, 0x3D + }, + { + 0x3F, 0xBD, 0xCD, 0xE7, 0xB6, 0x43, 0x04, 0x02, + 0x5E, 0xC0, 0x58, 0x26, 0x09, 0x03, 0x1E, 0xC2, + 0x66, 0xD5, 0x0F, 0x56, 0x83, 0x5A, 0xE0, 0xCB, + 0x72, 0xD8, 0xCD, 0xB4, 0xCF, 0xAF, 0x44, 0x19 + }, + { + 0xE9, 0x0E, 0xAD, 0x3B, 0x98, 0x2B, 0x43, 0x5B, + 0x66, 0x36, 0x6A, 0x49, 0x6C, 0x3F, 0x8A, 0xE6, + 0x5B, 0x17, 0x61, 0x37, 0x00, 0xF5, 0x47, 0x67, + 0x3F, 0x62, 0x15, 0x35, 0x41, 0x91, 0x28, 0x64 + }, + { + 0xAB, 0xE3, 0x54, 0x7B, 0x33, 0x6D, 0x6E, 0x24, + 0x0D, 0x7F, 0xE6, 0x82, 0xD7, 0x4B, 0x9C, 0xC7, + 0xE8, 0xD7, 0xF9, 0xB5, 0x66, 0x48, 0x58, 0xB9, + 0x4D, 0xF5, 0x9E, 0x9F, 0xC3, 0x30, 0xD9, 0xE5 + }, + { + 0xB2, 0x99, 0x64, 0x20, 0x95, 0xB8, 0x28, 0x6C, + 0x52, 0x1C, 0xDB, 0x21, 0xED, 0x0F, 0xE0, 0x57, + 0x27, 0x80, 0x21, 0xBB, 0x40, 0x38, 0xEB, 0x5A, + 0x3D, 0x79, 0x54, 0x2F, 0x5D, 0x75, 0x1F, 0x54 + }, + { + 0xE4, 0xD7, 0x58, 0x35, 0x9F, 0x08, 0x67, 0x93, + 0xA8, 0x37, 0x54, 0xAC, 0xA6, 0x96, 0x8C, 0x3E, + 0x9F, 0xD9, 0x4B, 0x40, 0x49, 0x7F, 0x2E, 0xC2, + 0x24, 0xA2, 0x91, 0x60, 0x63, 0xA2, 0x14, 0xA3 + }, + { + 0x59, 0xA3, 0x04, 0xFC, 0x03, 0xAB, 0x75, 0xD5, + 0x57, 0xDB, 0x04, 0xEB, 0xD0, 0x2D, 0xD4, 0xC6, + 0xB8, 0x10, 0xA1, 0x38, 0xBB, 0xFE, 0xEA, 0x5D, + 0xFC, 0xEE, 0xAA, 0x2B, 0x75, 0xB0, 0x64, 0x91 + }, + { + 0x39, 0x95, 0x10, 0x22, 0x15, 0xF5, 0xFE, 0x92, + 0x10, 0xEB, 0x30, 0xD9, 0x52, 0xD8, 0xC9, 0x19, + 0x58, 0x9E, 0x71, 0x45, 0xFC, 0xD4, 0x95, 0xEA, + 0x78, 0xD0, 0x2B, 0x9C, 0x14, 0x8F, 0xAF, 0x09 + }, + { + 0x47, 0x2E, 0xE7, 0x11, 0x56, 0x35, 0x06, 0xA5, + 0xF0, 0x08, 0x3F, 0xE8, 0x2B, 0x08, 0xB9, 0x92, + 0x3C, 0xF6, 0xC8, 0x40, 0x4D, 0x0C, 0xBA, 0xCB, + 0xF8, 0x48, 0x64, 0xF6, 0x48, 0x54, 0x2A, 0xC0 + }, + { + 0x68, 0xFD, 0xB8, 0x2A, 0xDA, 0xE7, 0x9B, 0xEF, + 0x59, 0x0A, 0xBA, 0x62, 0xD7, 0xAC, 0x55, 0x32, + 0x12, 0x06, 0x1C, 0x36, 0xE3, 0x6F, 0x12, 0xC0, + 0xEF, 0xA2, 0x9A, 0x17, 0x62, 0xDE, 0x3B, 0x6A + }, + { + 0x75, 0x85, 0xC0, 0x77, 0x33, 0x83, 0xF1, 0x74, + 0xFD, 0x66, 0x65, 0x49, 0xA8, 0x35, 0x2B, 0x30, + 0x5B, 0xF6, 0x85, 0x5B, 0xC9, 0x8B, 0xEA, 0x28, + 0xC3, 0x91, 0xB3, 0xC0, 0x34, 0xDA, 0x5A, 0x5A + }, + { + 0xAC, 0xC5, 0x75, 0xFE, 0x2C, 0xD7, 0xBA, 0x2A, + 0x31, 0xFC, 0x7D, 0x67, 0x0A, 0x92, 0x34, 0xAF, + 0x68, 0x50, 0x33, 0x86, 0xE9, 0x59, 0x07, 0x3D, + 0x16, 0xA8, 0x1B, 0x33, 0xB9, 0x22, 0xB5, 0x0E + }, + { + 0x9E, 0xC7, 0xD2, 0x99, 0x59, 0x43, 0xD3, 0x9D, + 0x6B, 0x97, 0x14, 0x93, 0xB8, 0x97, 0xA0, 0xEE, + 0x2D, 0x33, 0x92, 0xA7, 0x2D, 0xB8, 0x75, 0xC2, + 0x40, 0x5D, 0x35, 0x71, 0x78, 0xFB, 0x69, 0x11 + }, + { + 0x2D, 0x7E, 0xF1, 0x94, 0x01, 0x42, 0x5A, 0xBA, + 0x45, 0x0E, 0x82, 0xD3, 0x6D, 0x0F, 0xE7, 0xB2, + 0x08, 0x5E, 0xA0, 0xAF, 0x60, 0x45, 0xA5, 0x99, + 0x4C, 0xF4, 0x31, 0xEA, 0x59, 0x93, 0x9C, 0xC9 + }, + { + 0xF3, 0x2F, 0xD8, 0x55, 0xF0, 0x11, 0xC7, 0x18, + 0x02, 0x7F, 0x2E, 0xBE, 0x37, 0x7D, 0x69, 0x39, + 0xF1, 0x23, 0x70, 0xCA, 0xFF, 0x15, 0x1C, 0x1E, + 0x5A, 0xCE, 0x43, 0x8D, 0x70, 0x3C, 0x6D, 0x9F + }, + { + 0xB2, 0xBD, 0x83, 0xD2, 0x31, 0x0D, 0x3D, 0x7B, + 0x1D, 0x2D, 0x5A, 0xAF, 0x43, 0x59, 0xFA, 0xE2, + 0x86, 0x12, 0x96, 0x27, 0x19, 0xFD, 0xDE, 0x4D, + 0xDA, 0xF6, 0x9E, 0x78, 0x20, 0xF3, 0x3F, 0x61 + }, + { + 0x1A, 0x7A, 0x9D, 0x0F, 0x44, 0xDD, 0xFA, 0x7F, + 0xC2, 0xF4, 0x77, 0x0C, 0xAD, 0x74, 0x22, 0xFA, + 0x6C, 0x4E, 0x37, 0xE6, 0xCB, 0x03, 0x6D, 0x89, + 0x9E, 0x10, 0x27, 0x50, 0xE5, 0x94, 0xFF, 0xCD + }, + { + 0xDC, 0x69, 0xF6, 0x14, 0x1C, 0x8E, 0x10, 0x3F, + 0xF6, 0x1F, 0x62, 0x98, 0xA2, 0xC4, 0x4F, 0x52, + 0xD1, 0x47, 0x36, 0x6D, 0xDB, 0xD9, 0xC7, 0x9C, + 0xC3, 0x08, 0xFE, 0x84, 0x33, 0x6A, 0x95, 0x64 + }, + { + 0xE3, 0x4E, 0xD4, 0x17, 0xB0, 0x79, 0x1D, 0x9A, + 0x77, 0xEE, 0x1E, 0x50, 0xCC, 0x2C, 0x20, 0x7E, + 0x54, 0x0C, 0x77, 0x14, 0x04, 0x21, 0xC4, 0x6C, + 0xE0, 0x86, 0x28, 0x78, 0xAA, 0xEB, 0x27, 0x09 + }, + { + 0x21, 0x74, 0x42, 0x5C, 0x8C, 0xCA, 0xE3, 0x98, + 0xC4, 0xFF, 0x06, 0xF8, 0x48, 0x99, 0x1C, 0x5E, + 0x9B, 0xC0, 0xF3, 0x46, 0x11, 0x11, 0x70, 0x6F, + 0xB9, 0x5D, 0x0B, 0xE1, 0xC6, 0x8E, 0x47, 0x60 + }, + { + 0x18, 0x94, 0x58, 0x2A, 0x8A, 0x25, 0xFE, 0x8F, + 0x84, 0x7A, 0x4A, 0x03, 0x25, 0x74, 0xB7, 0x7B, + 0x8B, 0x36, 0xBF, 0x19, 0x99, 0x75, 0x26, 0xBB, + 0x4B, 0xC8, 0x5F, 0x38, 0x24, 0x53, 0x7F, 0xEB + }, + { + 0x17, 0xED, 0x18, 0x8A, 0xE3, 0xC9, 0x53, 0xD6, + 0x55, 0x44, 0x59, 0x83, 0xB8, 0x32, 0x5B, 0xAF, + 0xFF, 0x32, 0xE2, 0x22, 0xB2, 0xDF, 0xEB, 0x16, + 0xE8, 0x61, 0x7A, 0xBF, 0x86, 0xEE, 0x7C, 0xC5 + }, + { + 0xF1, 0x48, 0x9A, 0xD1, 0xC3, 0x54, 0xCD, 0xE9, + 0x78, 0x92, 0x37, 0xEA, 0x6D, 0xBF, 0x67, 0xFC, + 0x1E, 0x44, 0xD1, 0xAC, 0xC8, 0xDC, 0x66, 0xAD, + 0x83, 0x87, 0x27, 0xF4, 0x7D, 0x9A, 0x91, 0xFE + }, + { + 0x36, 0x7F, 0x22, 0x16, 0x5B, 0x8B, 0x66, 0xE9, + 0x7F, 0x66, 0x70, 0xF3, 0x4E, 0xBA, 0x27, 0x49, + 0xD2, 0x64, 0x3B, 0x21, 0xBE, 0xAD, 0xAD, 0xFE, + 0xFE, 0xA2, 0x57, 0x4B, 0x7C, 0x9B, 0x21, 0x96 + }, + { + 0x3D, 0x8D, 0xFE, 0xA1, 0x7E, 0xEA, 0x5D, 0x64, + 0x5A, 0xC1, 0xD4, 0x1A, 0x5B, 0x59, 0x22, 0x6C, + 0x48, 0x6C, 0x36, 0xBD, 0x77, 0xED, 0x44, 0xBB, + 0x34, 0x91, 0x70, 0xD0, 0x80, 0xE3, 0x0E, 0x68 + }, + { + 0x41, 0x15, 0xF8, 0x9E, 0x0B, 0x3B, 0x5C, 0x8F, + 0x61, 0x22, 0xC0, 0x25, 0x00, 0x17, 0x1D, 0xCF, + 0xFB, 0xCE, 0xA4, 0x66, 0x2A, 0x8C, 0x5F, 0x8C, + 0x1C, 0x01, 0xA9, 0xCA, 0x7B, 0x10, 0x27, 0xBB + }, + { + 0xED, 0x6E, 0x91, 0x0B, 0x96, 0x02, 0x55, 0xD7, + 0xD7, 0x92, 0xEB, 0xE6, 0x7F, 0x26, 0x0A, 0x14, + 0x3C, 0xFA, 0xC1, 0x05, 0x1D, 0xFC, 0x05, 0x90, + 0x25, 0xEE, 0x0C, 0x1B, 0xFC, 0xBC, 0x56, 0x81 + }, + { + 0x55, 0x8F, 0xA8, 0xAF, 0xA1, 0x2B, 0xBE, 0xE5, + 0x4A, 0xF7, 0x8F, 0x6B, 0x74, 0x45, 0xF9, 0x96, + 0x65, 0xD4, 0xE3, 0x56, 0xBC, 0x07, 0xD3, 0xEF, + 0xFD, 0x8F, 0xD6, 0x5A, 0xB9, 0xC7, 0x47, 0x16 + }, + { + 0x5B, 0x60, 0x12, 0x76, 0x20, 0x53, 0xB8, 0x73, + 0x4A, 0xF0, 0xE5, 0x55, 0xE6, 0xA2, 0xBB, 0x4F, + 0xD4, 0x84, 0x0A, 0xF3, 0xB0, 0x4F, 0xCF, 0x63, + 0x50, 0xA2, 0xB8, 0xA5, 0x1B, 0x67, 0x96, 0xAD + }, + { + 0xAB, 0x7A, 0xCC, 0xA5, 0xD7, 0x77, 0x10, 0xBA, + 0xD3, 0x7B, 0xA0, 0xFF, 0x4C, 0xEA, 0xE2, 0x7E, + 0x84, 0x71, 0x79, 0xF7, 0xFD, 0x7A, 0xEC, 0x88, + 0x69, 0xC6, 0x49, 0xB3, 0x3F, 0x8D, 0x25, 0x77 + }, + { + 0xFF, 0x77, 0x30, 0xB4, 0x74, 0xEC, 0x21, 0x45, + 0xA9, 0x2D, 0xD1, 0xCF, 0xFE, 0x45, 0xC3, 0x42, + 0xC6, 0xFD, 0x6B, 0xAC, 0x58, 0x0F, 0xF9, 0x5A, + 0x75, 0xED, 0xA3, 0xBF, 0x90, 0xEB, 0x4F, 0x01 + }, + { + 0xD1, 0x0F, 0x06, 0x1D, 0x5B, 0x9C, 0xB4, 0x4E, + 0xE0, 0x78, 0xA9, 0x6B, 0x33, 0x18, 0x57, 0x9E, + 0x5E, 0xF5, 0x0A, 0xEF, 0x3E, 0xD9, 0x6E, 0x4F, + 0x62, 0x14, 0x9B, 0x2E, 0x9F, 0x7C, 0x66, 0x0C + }, + { + 0x67, 0xD2, 0x2B, 0x8E, 0xDF, 0x20, 0x01, 0xD8, + 0x64, 0x22, 0x13, 0x6A, 0xC6, 0x51, 0x6C, 0xF3, + 0x9F, 0x7F, 0xC6, 0xA7, 0x02, 0x98, 0x92, 0xFD, + 0x75, 0xC9, 0x87, 0x90, 0x96, 0x4A, 0x72, 0x0B + }, + { + 0x7A, 0x5E, 0xC5, 0xBA, 0x76, 0x25, 0x9B, 0x07, + 0xB4, 0xDA, 0x03, 0xF3, 0x81, 0xFE, 0x7B, 0xEA, + 0x48, 0x65, 0xC8, 0x6C, 0x42, 0x4A, 0xBA, 0xA0, + 0xDD, 0x1E, 0xCF, 0x74, 0xF8, 0x7D, 0x2A, 0xC0 + }, + { + 0xE0, 0xFF, 0x60, 0xD6, 0x90, 0x29, 0xE6, 0xBD, + 0x1C, 0x15, 0x95, 0x3E, 0x91, 0x50, 0x9C, 0x0C, + 0x59, 0xED, 0x5D, 0xA5, 0x00, 0x01, 0x99, 0xF2, + 0x16, 0xD2, 0x9F, 0x96, 0x07, 0x9C, 0x2F, 0xEF + }, + { + 0xFC, 0x13, 0xEA, 0xD8, 0x41, 0x01, 0x8F, 0x59, + 0x90, 0x3B, 0x40, 0xF2, 0x02, 0x0C, 0x66, 0x38, + 0xA6, 0x6A, 0x54, 0xC3, 0xA3, 0x38, 0x41, 0x4D, + 0x97, 0xA5, 0xC3, 0x94, 0xF3, 0x26, 0x6F, 0x33 + }, + { + 0x0C, 0x2F, 0x62, 0xB8, 0x98, 0xFB, 0x2F, 0x63, + 0x61, 0x7E, 0x78, 0x73, 0x45, 0x26, 0x3C, 0xB9, + 0xCF, 0x60, 0x65, 0x4B, 0x55, 0x3B, 0x20, 0x3E, + 0xE4, 0x9D, 0xCB, 0xB8, 0xF2, 0xA6, 0xAF, 0xAC + }, + { + 0xD7, 0xD6, 0xCB, 0x55, 0x2A, 0xEB, 0x36, 0xEB, + 0x96, 0xB1, 0xD5, 0xE0, 0x52, 0xF8, 0xD9, 0x21, + 0xC3, 0x24, 0x5A, 0x97, 0x0D, 0x0B, 0xC8, 0x41, + 0x0C, 0xD6, 0x5E, 0xA1, 0x04, 0xC8, 0xE7, 0x79 + }, + { + 0xB7, 0x14, 0x1F, 0x30, 0x5E, 0xFD, 0xFE, 0xE5, + 0x56, 0xBD, 0x13, 0xE0, 0x40, 0x0D, 0x1E, 0x8C, + 0xFD, 0x65, 0x48, 0xBF, 0x81, 0xEE, 0x5D, 0x15, + 0x32, 0x7E, 0x49, 0x95, 0xCA, 0x8A, 0xD6, 0xFD + }, + { + 0xB6, 0xB6, 0x38, 0xD2, 0x2B, 0x7A, 0x12, 0x82, + 0x53, 0x74, 0xF7, 0x03, 0x48, 0xD7, 0x44, 0x8D, + 0x4E, 0x7D, 0x90, 0x8C, 0xF6, 0xE7, 0xBB, 0xEF, + 0x8C, 0x93, 0xEF, 0x67, 0x9B, 0x2A, 0x54, 0x78 + }, + { + 0x0D, 0xF4, 0x58, 0x56, 0x41, 0xFA, 0x09, 0xF6, + 0xCB, 0xA4, 0xCC, 0x16, 0x5A, 0x10, 0xAD, 0xDE, + 0x34, 0xF8, 0x0D, 0x42, 0x5A, 0x70, 0xDB, 0x67, + 0xE2, 0xFD, 0x23, 0x7B, 0x62, 0x7F, 0x43, 0x8A + }, + { + 0x10, 0x6B, 0x2B, 0x35, 0x4D, 0x95, 0xAC, 0xEC, + 0xD0, 0xD9, 0x58, 0x8F, 0xBC, 0x23, 0x1F, 0x8B, + 0xEA, 0x2E, 0x94, 0xEA, 0x66, 0x2D, 0xDD, 0x3F, + 0x13, 0x9E, 0x1B, 0x67, 0x87, 0x46, 0x1E, 0xED + }, + { + 0xAE, 0x5C, 0x69, 0xEE, 0xFE, 0x90, 0x89, 0xB2, + 0x9C, 0x6C, 0x1A, 0x23, 0x70, 0xD2, 0x05, 0x52, + 0xBA, 0x40, 0xC3, 0xD5, 0xE3, 0x71, 0x3C, 0x12, + 0xDE, 0xFC, 0xAE, 0x99, 0x7F, 0x43, 0x3E, 0xCD + }, + { + 0x1A, 0xAE, 0xF5, 0x5D, 0x4F, 0xA8, 0x92, 0xB6, + 0x35, 0xFB, 0x2A, 0x7A, 0x25, 0xF9, 0xA8, 0xE0, + 0x3B, 0x9F, 0xFB, 0x08, 0x2A, 0xE9, 0xC0, 0x7C, + 0x20, 0x42, 0xA0, 0x49, 0xC6, 0x51, 0x5E, 0x45 + }, + { + 0x29, 0x7D, 0xAA, 0xC4, 0xD5, 0x4D, 0xC4, 0x1C, + 0x83, 0xE3, 0x23, 0x94, 0x59, 0x9F, 0x17, 0x1C, + 0xDA, 0xA9, 0xDD, 0xB7, 0x17, 0x26, 0xDA, 0x4E, + 0xCE, 0x3C, 0xCF, 0x95, 0xC1, 0x1F, 0x56, 0xDF + }, + { + 0x2C, 0x45, 0xAC, 0xF4, 0x91, 0xEC, 0x2F, 0x4B, + 0x7E, 0x30, 0x9E, 0x7E, 0xDD, 0x81, 0x5B, 0xE5, + 0xA5, 0x4C, 0x44, 0x58, 0xD1, 0xA5, 0x7C, 0x4F, + 0x9B, 0x76, 0x3B, 0x0C, 0x67, 0x18, 0xD4, 0x3E + }, + { + 0x2F, 0x92, 0xF9, 0x01, 0x70, 0xD3, 0xAE, 0x95, + 0xAB, 0xFA, 0xC3, 0xA6, 0x98, 0x9A, 0x2A, 0x60, + 0xCB, 0x28, 0xB8, 0x58, 0x78, 0x2B, 0xE7, 0xEA, + 0x17, 0x9B, 0x48, 0xA7, 0x27, 0x6D, 0xD8, 0x60 + }, + { + 0xB4, 0x01, 0xE8, 0x4B, 0x15, 0xAC, 0xC4, 0x70, + 0x93, 0x6D, 0x6E, 0x37, 0xF7, 0x88, 0x83, 0x33, + 0x09, 0x27, 0x31, 0x13, 0x3B, 0x25, 0x1B, 0xEA, + 0x22, 0x16, 0x58, 0xCA, 0x19, 0xA7, 0x56, 0x69 + }, + { + 0xF8, 0xB3, 0x40, 0xD2, 0xB9, 0xB3, 0x3D, 0x43, + 0xA0, 0xA6, 0x6F, 0x34, 0x97, 0x82, 0x0A, 0xFA, + 0xAE, 0xE4, 0x34, 0xC4, 0xE3, 0xC0, 0xC1, 0x7E, + 0x89, 0x8B, 0x83, 0x01, 0xC5, 0x7A, 0x26, 0xBD + }, + { + 0x56, 0x6D, 0xA2, 0x83, 0x99, 0x03, 0x89, 0x13, + 0x8A, 0xA6, 0xF2, 0xAA, 0xA3, 0xB9, 0xE4, 0x0C, + 0xBF, 0x90, 0x84, 0x0E, 0xC7, 0x62, 0xBD, 0x96, + 0xB7, 0xE3, 0x3A, 0x31, 0x13, 0xB1, 0x01, 0x08 + }, + { + 0x34, 0x06, 0x72, 0xB7, 0x04, 0x67, 0x60, 0x42, + 0xC9, 0xBF, 0x3F, 0x33, 0x7B, 0xA7, 0x9F, 0x11, + 0x33, 0x6A, 0xEB, 0xB5, 0xEC, 0x5D, 0x31, 0xDF, + 0x54, 0xEB, 0x6A, 0xD3, 0xB0, 0x43, 0x04, 0x42 + }, + { + 0x50, 0x50, 0xB7, 0x3B, 0x93, 0x16, 0xEE, 0xA2, + 0xF1, 0x49, 0xBF, 0xFD, 0x22, 0xAE, 0xE3, 0x84, + 0xDC, 0x54, 0x03, 0xB1, 0x8E, 0x16, 0xFA, 0x88, + 0x82, 0x5E, 0x18, 0x16, 0x09, 0x49, 0x6F, 0xD2 + }, + { + 0x13, 0x65, 0xCC, 0x6F, 0xB9, 0x26, 0x0E, 0x86, + 0x88, 0x9B, 0x3A, 0xFB, 0xD1, 0xC8, 0xBC, 0x12, + 0x92, 0x31, 0x97, 0x71, 0x5D, 0xB2, 0x66, 0xCC, + 0x7A, 0x01, 0xCA, 0x57, 0x15, 0x9F, 0x75, 0x96 + }, + { + 0x29, 0x46, 0x6F, 0x51, 0xC0, 0x11, 0xFD, 0x10, + 0x18, 0x14, 0x94, 0xA9, 0x37, 0x9B, 0x61, 0x59, + 0xB8, 0x08, 0xAE, 0x0F, 0xCB, 0x01, 0x61, 0xF8, + 0xF0, 0x79, 0x09, 0xFF, 0x04, 0x1B, 0x19, 0x65 + }, + { + 0x65, 0x91, 0xA3, 0xC3, 0xC7, 0x67, 0xB3, 0x8D, + 0x80, 0x5E, 0xD3, 0xF7, 0xEB, 0x67, 0x63, 0xE8, + 0xB3, 0xD2, 0xD6, 0x42, 0xE7, 0x30, 0x77, 0x45, + 0xCD, 0x34, 0x18, 0xEF, 0xF6, 0x9A, 0x19, 0xED + }, + { + 0x1D, 0x84, 0xB0, 0x4B, 0x13, 0x38, 0xB0, 0xD2, + 0xE3, 0xC9, 0x8F, 0x7A, 0xEA, 0x3E, 0x98, 0xEF, + 0xFC, 0x53, 0x0A, 0x50, 0x44, 0xB9, 0x3B, 0x96, + 0xC6, 0x7E, 0xE3, 0x79, 0xD6, 0x2E, 0x81, 0x5F + }, + { + 0x6F, 0xA2, 0x95, 0x27, 0x25, 0x32, 0xE9, 0x83, + 0xE1, 0x66, 0xB1, 0x2E, 0x49, 0x99, 0xC0, 0x52, + 0xF8, 0x9D, 0x9F, 0x30, 0xAE, 0x14, 0x81, 0xF3, + 0xD6, 0x0E, 0xAE, 0x85, 0xF8, 0xEE, 0x17, 0x8A + }, + { + 0x4E, 0xD8, 0xCA, 0xA9, 0x8E, 0xC3, 0x9F, 0x6A, + 0x62, 0x9F, 0x9A, 0x65, 0x4A, 0x44, 0x7E, 0x7E, + 0x3E, 0x4F, 0xAE, 0xEC, 0xF3, 0x4D, 0xCF, 0x65, + 0x8D, 0x2D, 0x4B, 0x98, 0xB7, 0xA2, 0xEC, 0x1A + }, + { + 0xCF, 0xAB, 0x82, 0x99, 0xA0, 0xDA, 0x0C, 0x2A, + 0x7E, 0x8F, 0xF5, 0x4D, 0x0A, 0x67, 0x6D, 0x14, + 0x1A, 0xB2, 0x6B, 0xC0, 0x01, 0x2E, 0x5F, 0x66, + 0x8E, 0x85, 0xD8, 0x14, 0xBC, 0x98, 0x88, 0xB0 + }, + { + 0xA6, 0x26, 0x54, 0x3C, 0x27, 0x1F, 0xCC, 0xC3, + 0xE4, 0x45, 0x0B, 0x48, 0xD6, 0x6B, 0xC9, 0xCB, + 0xDE, 0xB2, 0x5E, 0x5D, 0x07, 0x7A, 0x62, 0x13, + 0xCD, 0x90, 0xCB, 0xBD, 0x0F, 0xD2, 0x20, 0x76 + }, + { + 0x05, 0xCF, 0x3A, 0x90, 0x04, 0x91, 0x16, 0xDC, + 0x60, 0xEF, 0xC3, 0x15, 0x36, 0xAA, 0xA3, 0xD1, + 0x67, 0x76, 0x29, 0x94, 0x89, 0x28, 0x76, 0xDC, + 0xB7, 0xEF, 0x3F, 0xBE, 0xCD, 0x74, 0x49, 0xC0 + }, + { + 0xCC, 0xD6, 0x1C, 0x92, 0x6C, 0xC1, 0xE5, 0xE9, + 0x12, 0x8C, 0x02, 0x1C, 0x0C, 0x6E, 0x92, 0xAE, + 0xFC, 0x4F, 0xFB, 0xDE, 0x39, 0x4D, 0xD6, 0xF3, + 0xB7, 0xD8, 0x7A, 0x8C, 0xED, 0x89, 0x60, 0x14 + }, + { + 0x3F, 0xFA, 0x4F, 0x6D, 0xAF, 0xA5, 0x7F, 0x1C, + 0x50, 0xF1, 0xAF, 0xA4, 0xF8, 0x12, 0x92, 0xAE, + 0x71, 0xA0, 0x6F, 0xE4, 0xF8, 0xFF, 0x46, 0xC5, + 0x1D, 0x32, 0xFF, 0x26, 0x13, 0x48, 0x9F, 0x2B + }, + { + 0x19, 0xD3, 0x92, 0x1C, 0xFC, 0x0F, 0x1A, 0x2B, + 0xB8, 0x13, 0xB3, 0xDF, 0xA9, 0x6D, 0xF9, 0x0E, + 0x2C, 0x6B, 0x87, 0xD7, 0x8E, 0x92, 0x38, 0xF8, + 0x5B, 0xBC, 0x77, 0xAE, 0x9A, 0x73, 0xF9, 0x8F + }, + { + 0xF5, 0xC9, 0x16, 0xFF, 0x2B, 0xAD, 0xDE, 0x3E, + 0x29, 0xA5, 0xF9, 0x40, 0x23, 0x3E, 0xA3, 0x40, + 0x07, 0xD8, 0xF1, 0x82, 0xA4, 0x8A, 0x80, 0x8B, + 0x46, 0xBB, 0x80, 0x58, 0x00, 0x3F, 0x19, 0x03 + }, + { + 0x6B, 0xA0, 0x7A, 0x1A, 0xF7, 0x58, 0xE6, 0x82, + 0xD3, 0xE0, 0x9A, 0xDD, 0x2D, 0x3D, 0xCD, 0xF3, + 0x5D, 0x95, 0x53, 0xF6, 0x79, 0x98, 0x54, 0xA2, + 0x7E, 0x53, 0x60, 0x63, 0xC5, 0x7F, 0x81, 0xA5 + }, + { + 0xB7, 0x83, 0x78, 0xFB, 0x44, 0x6C, 0x54, 0x4B, + 0x04, 0xD4, 0xA1, 0x52, 0xAC, 0x49, 0x57, 0x31, + 0x61, 0xB3, 0xDD, 0xEB, 0xF6, 0x93, 0x86, 0x77, + 0x0A, 0x55, 0xA7, 0xD4, 0x7B, 0x88, 0x0E, 0x5D + }, + { + 0xB5, 0x19, 0x53, 0x8F, 0xE1, 0x62, 0x6F, 0x0C, + 0x59, 0x59, 0x45, 0xAD, 0xA5, 0x8A, 0x34, 0x4F, + 0xAA, 0xC0, 0x06, 0x17, 0x61, 0xCC, 0x9D, 0x4A, + 0x84, 0x14, 0x19, 0xBD, 0x32, 0xEE, 0xC0, 0xD9 + }, + { + 0x96, 0xE4, 0x88, 0xB0, 0x27, 0x89, 0x64, 0x13, + 0xF4, 0x03, 0x4B, 0x03, 0x54, 0xF4, 0x84, 0x84, + 0xF6, 0xCF, 0xC1, 0x0F, 0x8E, 0xC5, 0x7B, 0x02, + 0x6F, 0xD2, 0x1A, 0x3B, 0x88, 0x36, 0x1A, 0x74 + }, + { + 0x77, 0x0C, 0x8A, 0x5F, 0x47, 0xBF, 0xD7, 0x69, + 0xCE, 0xD3, 0x5A, 0x71, 0xAF, 0xC3, 0xCA, 0x1F, + 0xF4, 0xC1, 0xF1, 0xE7, 0xCC, 0x3D, 0x23, 0x56, + 0xDE, 0x94, 0x50, 0x04, 0x36, 0x8D, 0x81, 0x45 + }, + { + 0x6D, 0xF9, 0xD8, 0xD0, 0xD3, 0xA8, 0xD9, 0x8C, + 0x83, 0x50, 0xD7, 0x16, 0x2B, 0xD1, 0x55, 0x79, + 0xD5, 0x70, 0x7A, 0xDD, 0x76, 0x11, 0xA0, 0x0E, + 0xEB, 0x6C, 0xA5, 0x74, 0x3E, 0xD7, 0x8C, 0xB7 + }, + { + 0x4F, 0x0F, 0xE8, 0xFC, 0x17, 0x90, 0x15, 0x91, + 0xCF, 0x34, 0x87, 0x30, 0xE1, 0x87, 0xDE, 0x52, + 0x3D, 0x6D, 0x75, 0x68, 0xC1, 0xFB, 0xD8, 0x24, + 0x85, 0x91, 0x39, 0x85, 0xEB, 0x67, 0x97, 0x1C + }, + { + 0x0E, 0xF3, 0xBB, 0x35, 0xCF, 0x37, 0x2B, 0xD9, + 0x4E, 0x3F, 0x80, 0xEE, 0xCE, 0xBD, 0x50, 0xEF, + 0x0D, 0x03, 0x08, 0xE0, 0x1E, 0x0E, 0xD6, 0xDE, + 0x0F, 0x5A, 0x8A, 0x8C, 0x81, 0x8A, 0x00, 0x74 + }, + { + 0xC0, 0x38, 0xD3, 0xE8, 0x09, 0xA5, 0xE3, 0xA5, + 0x8D, 0xB2, 0xF9, 0x1C, 0x15, 0xAE, 0x12, 0x43, + 0x95, 0x78, 0xF7, 0x54, 0x85, 0xCD, 0x84, 0xF5, + 0x56, 0xC6, 0x97, 0x1E, 0x8E, 0x25, 0x06, 0x20 + }, + { + 0xCE, 0x39, 0x9A, 0x0F, 0x08, 0x27, 0x7D, 0x8D, + 0x48, 0x16, 0x09, 0x50, 0x60, 0xEB, 0xBF, 0x33, + 0xDA, 0x01, 0x6F, 0xB4, 0x3A, 0x6C, 0x35, 0x6D, + 0x5A, 0x3F, 0xE4, 0xBB, 0x57, 0x4C, 0x5E, 0x7B + }, + { + 0x86, 0x9F, 0x7E, 0x31, 0x6B, 0x19, 0x4F, 0x95, + 0x31, 0xBC, 0xAF, 0x33, 0xF7, 0x91, 0x3F, 0x1B, + 0x9C, 0xFC, 0x6B, 0xB5, 0xDC, 0xF8, 0x6B, 0x69, + 0x2B, 0xF8, 0xCA, 0xB2, 0x9B, 0x8A, 0xA9, 0x6F + }, + { + 0x32, 0x7D, 0xFA, 0x46, 0x44, 0x59, 0xD9, 0xE4, + 0x8F, 0x5E, 0x55, 0xC7, 0xF5, 0xBA, 0xA6, 0x8F, + 0xC4, 0xA2, 0x5A, 0xD6, 0x22, 0xBC, 0x7B, 0xF0, + 0x1A, 0xCA, 0x82, 0xFD, 0x5E, 0x72, 0x31, 0x4C + }, + { + 0xE0, 0x0D, 0xAD, 0x31, 0x51, 0xB9, 0x08, 0x5E, + 0xAE, 0x78, 0x69, 0x84, 0xFE, 0x20, 0x73, 0x52, + 0x32, 0xB7, 0xFF, 0x7F, 0x1B, 0x1D, 0xB7, 0x96, + 0x1F, 0xD0, 0xD0, 0xE0, 0xF6, 0x05, 0xDB, 0x9A + }, + { + 0x07, 0x6F, 0x64, 0x45, 0x20, 0xD0, 0xB4, 0x73, + 0x2D, 0x6C, 0x53, 0x1C, 0x93, 0x49, 0x08, 0x90, + 0x26, 0x93, 0x6D, 0x99, 0x82, 0x04, 0x61, 0xDA, + 0x87, 0x74, 0x9A, 0x52, 0x0F, 0xBE, 0x90, 0xCE + }, + { + 0xB4, 0x41, 0x4C, 0xA1, 0x37, 0x3B, 0xE4, 0x6F, + 0x15, 0xCE, 0xA6, 0xB1, 0x25, 0x5A, 0x7D, 0x18, + 0x86, 0xC6, 0xFD, 0xB0, 0x8E, 0xD5, 0xAF, 0x96, + 0x57, 0xD5, 0xAA, 0xC3, 0x17, 0xDE, 0x3A, 0x29 + }, + { + 0x8D, 0x1A, 0xB0, 0x26, 0x3D, 0xAB, 0x7B, 0x86, + 0xEC, 0xEE, 0x21, 0x91, 0x62, 0xD9, 0x99, 0xA0, + 0x12, 0x45, 0x57, 0x22, 0x69, 0xDE, 0x31, 0x10, + 0x0E, 0x5D, 0x88, 0xFC, 0x1B, 0x1E, 0xAA, 0x69 + }, + { + 0xB4, 0x8D, 0x1C, 0x1F, 0x83, 0x92, 0x4A, 0x02, + 0xA2, 0x3E, 0x5E, 0x0F, 0x97, 0x1E, 0x16, 0xE8, + 0x7F, 0xC4, 0x88, 0x48, 0x53, 0x83, 0x34, 0x85, + 0x19, 0x1A, 0x2B, 0x60, 0x72, 0x2F, 0xE2, 0x69 + }, + { + 0xF2, 0xED, 0xD5, 0xF7, 0x50, 0xA2, 0x0A, 0x54, + 0x1D, 0x3F, 0x6B, 0xD5, 0xDF, 0x80, 0x83, 0x8F, + 0x11, 0x82, 0x5B, 0x25, 0xA9, 0x8F, 0x3D, 0xA5, + 0xE1, 0x52, 0x3B, 0xFF, 0x81, 0x3B, 0xB5, 0x60 + }, + { + 0x07, 0x16, 0x60, 0x04, 0xEF, 0x88, 0xE1, 0x61, + 0x4E, 0xBD, 0xC8, 0x87, 0xDF, 0xC7, 0xDA, 0x42, + 0xEB, 0xCD, 0xA0, 0x2D, 0x92, 0xC1, 0x2F, 0x18, + 0xD1, 0x18, 0x6C, 0xE3, 0xC9, 0x87, 0x10, 0xE4 + }, + { + 0x69, 0xF8, 0x3A, 0xA1, 0x01, 0xD6, 0x9B, 0x8F, + 0x12, 0x20, 0xDC, 0x1C, 0x53, 0x8D, 0x89, 0x34, + 0x45, 0x84, 0x20, 0xBE, 0x33, 0x5F, 0xEB, 0x46, + 0xFF, 0xC4, 0x7A, 0x2C, 0x8E, 0x2E, 0x6A, 0x8A + }, + { + 0xE1, 0x46, 0x9F, 0x16, 0xC6, 0xFC, 0xA1, 0x51, + 0x19, 0xA2, 0x72, 0xE5, 0x85, 0xC7, 0xF5, 0x04, + 0x21, 0xBC, 0x8A, 0x41, 0x4C, 0x86, 0x4F, 0xC7, + 0x6B, 0x01, 0x04, 0x8D, 0x4C, 0x6F, 0xC5, 0xD2 + }, + { + 0x67, 0x63, 0x34, 0x3A, 0x1C, 0x80, 0xF1, 0x92, + 0x83, 0xA8, 0x0A, 0xF8, 0x54, 0xE7, 0xE9, 0x06, + 0x5C, 0x2A, 0x83, 0x49, 0xEF, 0x11, 0xF1, 0x1B, + 0xFB, 0x76, 0xBA, 0x9F, 0x97, 0x04, 0x85, 0x39 + }, + { + 0x1A, 0xE3, 0xA0, 0xB8, 0xB2, 0xC7, 0x88, 0x5B, + 0xA3, 0x18, 0xAD, 0x6F, 0xD4, 0x49, 0xFC, 0x4D, + 0x7F, 0x84, 0x04, 0xB5, 0x9C, 0xF3, 0x27, 0x5F, + 0xCD, 0xEA, 0x13, 0x56, 0x34, 0x25, 0x77, 0x2D + }, + { + 0x3A, 0x71, 0x18, 0x4C, 0xBE, 0x8E, 0xB5, 0x8E, + 0x68, 0x12, 0xBA, 0x7A, 0x7A, 0x1D, 0xCA, 0x0C, + 0xA2, 0x8E, 0xEC, 0x63, 0x78, 0x2F, 0x2E, 0x6E, + 0x3C, 0x0B, 0x87, 0x07, 0x3F, 0x53, 0x3F, 0xFD + }, + { + 0x18, 0x4C, 0xCF, 0x2A, 0x52, 0xF3, 0x88, 0xC9, + 0xF8, 0x97, 0xA8, 0x57, 0xFE, 0x7C, 0xCE, 0xC2, + 0x95, 0x99, 0x11, 0xA8, 0xD1, 0xE0, 0x9E, 0xE8, + 0x80, 0x4D, 0x8D, 0x5D, 0x50, 0x8D, 0xD9, 0x18 + }, + { + 0xA6, 0x6D, 0x40, 0x9A, 0xF7, 0xAF, 0xD7, 0x5B, + 0xE8, 0x31, 0xDD, 0x49, 0x8C, 0x19, 0x6E, 0xF1, + 0x2C, 0x73, 0xC3, 0x11, 0x29, 0xEC, 0x02, 0xD5, + 0xF1, 0x2A, 0xB0, 0x2A, 0x2C, 0x63, 0xA2, 0x5E + }, + { + 0x58, 0xB3, 0x74, 0x97, 0xFC, 0xF0, 0xBE, 0x0E, + 0x0C, 0xF1, 0x73, 0x40, 0x45, 0xC2, 0x95, 0xB2, + 0x86, 0xC7, 0x6A, 0x7C, 0x04, 0x8E, 0x87, 0xC5, + 0x40, 0x28, 0xED, 0x36, 0x91, 0x5B, 0x5D, 0xF3 + }, + { + 0x2C, 0x73, 0x33, 0x54, 0x0A, 0x83, 0x2D, 0x64, + 0x45, 0x6E, 0x43, 0x05, 0x8C, 0x50, 0xD9, 0x3C, + 0x93, 0x2A, 0xD9, 0xB1, 0x8B, 0x3F, 0xC3, 0xA0, + 0x59, 0x92, 0x07, 0xCD, 0xA3, 0xB3, 0xC7, 0xA6 + }, + { + 0x3D, 0xC0, 0x62, 0xFF, 0xB5, 0x7D, 0x83, 0x5F, + 0xE3, 0xAA, 0x40, 0x94, 0x66, 0x82, 0x2F, 0x91, + 0x86, 0x91, 0x84, 0x23, 0x94, 0x75, 0x05, 0x16, + 0x5F, 0xDC, 0xDF, 0xB7, 0x30, 0x6F, 0x72, 0x59 + }, + { + 0x89, 0x20, 0x48, 0x44, 0xAC, 0xB9, 0x2F, 0x35, + 0x3B, 0xFC, 0x89, 0xA3, 0xCE, 0x8A, 0x98, 0x17, + 0x21, 0x9C, 0x10, 0x13, 0x85, 0xC5, 0x93, 0xCF, + 0x60, 0xE0, 0xBE, 0xFA, 0x96, 0x38, 0xE1, 0x4E + }, + { + 0x78, 0x2B, 0xA9, 0x02, 0xE9, 0x12, 0x32, 0x94, + 0x1C, 0x78, 0xC4, 0x9C, 0xD9, 0x77, 0x1A, 0x5D, + 0x99, 0x92, 0xF9, 0xB0, 0x7D, 0x9C, 0x0A, 0x2D, + 0xF8, 0x2D, 0x38, 0x5D, 0x15, 0xC4, 0x2B, 0xB3 + }, + { + 0x0D, 0xC3, 0xFF, 0x7D, 0xF0, 0xDF, 0xC0, 0x23, + 0x76, 0x3D, 0x76, 0x34, 0xE1, 0x8D, 0xA2, 0x73, + 0x93, 0xFC, 0x9F, 0xDB, 0x1C, 0x15, 0x46, 0x46, + 0x86, 0x10, 0x75, 0xF0, 0xA8, 0x7D, 0x0E, 0x90 + }, + { + 0xB9, 0x5C, 0x65, 0xFB, 0x6F, 0x25, 0x4E, 0xDB, + 0xDE, 0x8C, 0x03, 0x7D, 0x5C, 0x8B, 0x20, 0x39, + 0x34, 0x0F, 0x4A, 0xC2, 0xB0, 0x23, 0xA6, 0xAA, + 0x28, 0xA8, 0xFC, 0xD2, 0xD2, 0x68, 0x9C, 0xF4 + }, + { + 0x87, 0xE8, 0xF5, 0x15, 0x72, 0xA5, 0xD6, 0xA2, + 0x39, 0xF8, 0x5B, 0xC5, 0x3E, 0x11, 0x74, 0xE1, + 0x5B, 0xE1, 0x2F, 0xCD, 0xF1, 0x51, 0xA0, 0xB9, + 0xA2, 0xB4, 0x36, 0x40, 0xCA, 0xF7, 0x4C, 0x1D + }, + { + 0x2A, 0x6F, 0x3E, 0x46, 0x2C, 0x40, 0x5C, 0x35, + 0x4F, 0xE8, 0x0F, 0xCC, 0xCE, 0xD1, 0xC9, 0xBE, + 0x44, 0x32, 0x5D, 0x29, 0xE0, 0x7D, 0xA3, 0x09, + 0x60, 0xB6, 0x25, 0xA7, 0x6E, 0xA4, 0x2F, 0x83 + }, + { + 0x20, 0xB4, 0x6C, 0x8F, 0xBF, 0xCA, 0x97, 0x45, + 0x32, 0x62, 0x46, 0x0F, 0x84, 0x98, 0xA7, 0xE2, + 0xAF, 0x15, 0xAC, 0x79, 0xB5, 0x9D, 0xDF, 0xB0, + 0x27, 0xBB, 0x52, 0xF2, 0xD6, 0x8E, 0x8F, 0x51 + }, + { + 0x31, 0xB0, 0x76, 0x3C, 0xB9, 0xBA, 0x92, 0x40, + 0x3D, 0xCA, 0x1A, 0xBD, 0xD7, 0x34, 0x2D, 0x7D, + 0xE9, 0x4C, 0x58, 0x1E, 0x76, 0xF7, 0xC9, 0xA6, + 0x1E, 0x51, 0x59, 0x28, 0xE1, 0x0B, 0x4E, 0x77 + }, + { + 0xE1, 0x91, 0xE1, 0x17, 0x06, 0x3C, 0xFA, 0xC9, + 0x64, 0x2C, 0xD9, 0x3C, 0xB4, 0x2B, 0x39, 0xED, + 0xDD, 0x9E, 0x4A, 0xB6, 0x5F, 0x1D, 0x03, 0x97, + 0xE3, 0xE1, 0x7D, 0xD0, 0x4C, 0xAB, 0x11, 0x80 + }, + { + 0x22, 0x5A, 0x20, 0x21, 0x07, 0xA7, 0x47, 0x03, + 0xE0, 0x41, 0xC6, 0xCC, 0xA4, 0xEA, 0xCF, 0x4F, + 0x21, 0xEE, 0xA6, 0xF2, 0x2A, 0x14, 0x6D, 0x8D, + 0xA2, 0xAB, 0x8C, 0xF6, 0x19, 0x72, 0x29, 0xA5 + }, + { + 0xEF, 0xC4, 0x83, 0x6B, 0xE4, 0xAC, 0x3E, 0x97, + 0x91, 0xD2, 0xEC, 0x62, 0x22, 0x6E, 0x7D, 0xF6, + 0x41, 0x18, 0xF4, 0x56, 0x5C, 0x19, 0xE6, 0xC9, + 0xE8, 0x40, 0x63, 0xF5, 0x66, 0x1C, 0x7B, 0x2F + }, + { + 0x3A, 0x76, 0xB0, 0x15, 0x2C, 0x0E, 0x1D, 0x1F, + 0xD7, 0xAC, 0x9D, 0x91, 0xA2, 0x8A, 0x18, 0xE1, + 0xA4, 0xC0, 0x60, 0x80, 0xF2, 0xB7, 0xEC, 0xEF, + 0xB6, 0xEF, 0xFE, 0x28, 0xB8, 0xCF, 0xC7, 0x65 + }, + { + 0x0D, 0x46, 0xAD, 0x03, 0x90, 0x70, 0x11, 0x58, + 0x28, 0xF9, 0x4E, 0xB6, 0xB7, 0x29, 0x63, 0xE6, + 0x0A, 0x7D, 0x2D, 0xB7, 0xCA, 0x89, 0x91, 0xD2, + 0x25, 0xC3, 0x87, 0x7B, 0x14, 0x9B, 0x0A, 0x8A + }, + { + 0xE4, 0x4C, 0xFC, 0x42, 0x11, 0x8F, 0x09, 0x6B, + 0xFC, 0x51, 0x52, 0x1C, 0xB1, 0x8D, 0x5D, 0x65, + 0x25, 0x58, 0x6B, 0x98, 0x9F, 0x4E, 0xE2, 0xB8, + 0x28, 0xC5, 0x19, 0x9F, 0xEA, 0xB9, 0x4B, 0x82 + }, + { + 0x6D, 0x4B, 0xD2, 0xE0, 0x73, 0xEC, 0x49, 0x66, + 0x84, 0x7F, 0x5C, 0xBE, 0x88, 0xDD, 0xFA, 0xBA, + 0x2B, 0xE4, 0xCA, 0xF2, 0xF3, 0x33, 0x55, 0x2B, + 0x85, 0x53, 0xDA, 0x53, 0x34, 0x87, 0xC2, 0x5B + }, + { + 0xBB, 0xC4, 0x6D, 0xB4, 0x37, 0xD1, 0x07, 0xC9, + 0x67, 0xCA, 0x6D, 0x91, 0x45, 0x5B, 0xBD, 0xFE, + 0x05, 0x21, 0x18, 0xAB, 0xD1, 0xD0, 0x69, 0xF0, + 0x43, 0x59, 0x48, 0x7E, 0x13, 0xAE, 0xA0, 0xE1 + }, + { + 0xB9, 0x74, 0xC1, 0x4D, 0xB7, 0xD3, 0x17, 0x4D, + 0xD0, 0x60, 0x84, 0xBB, 0x30, 0x31, 0x08, 0xB2, + 0xF0, 0xDA, 0xF5, 0x0E, 0xCC, 0xC3, 0x29, 0x35, + 0x43, 0x79, 0x5C, 0x96, 0x36, 0xC6, 0x24, 0x82 + }, + { + 0x0E, 0xEE, 0x23, 0x5B, 0x06, 0x93, 0x6A, 0xED, + 0x71, 0x73, 0xC8, 0xC1, 0x9A, 0xA7, 0xC2, 0x17, + 0xB9, 0xEE, 0xDA, 0xEB, 0x1A, 0x88, 0xF3, 0x05, + 0x52, 0xE9, 0x22, 0x51, 0x45, 0x14, 0x9E, 0x82 + }, + { + 0x36, 0xD0, 0x89, 0xE0, 0x25, 0xB5, 0x68, 0x69, + 0x37, 0x74, 0x28, 0x25, 0xE6, 0xEE, 0x3D, 0x83, + 0xE7, 0xD7, 0xA5, 0x0C, 0x82, 0x3C, 0x82, 0x88, + 0x34, 0x60, 0xF3, 0x85, 0x14, 0x7D, 0xC1, 0x7B + }, + { + 0x77, 0xEE, 0x4F, 0xFC, 0x9F, 0x5D, 0xD6, 0x05, + 0x47, 0x0D, 0xC0, 0xE7, 0x4D, 0x6B, 0x17, 0xC5, + 0x13, 0x0D, 0x8B, 0x73, 0x91, 0x3F, 0x36, 0xD5, + 0xF8, 0x78, 0x7E, 0x61, 0x9A, 0x94, 0x7C, 0xA0 + }, + { + 0x0F, 0xE6, 0xC2, 0xAB, 0x75, 0x42, 0x33, 0x36, + 0x0D, 0x68, 0xB9, 0xAC, 0x80, 0xCD, 0x61, 0x18, + 0x4B, 0xFA, 0xA7, 0xD3, 0x56, 0x29, 0x41, 0x80, + 0x02, 0x5F, 0xE4, 0x06, 0x39, 0xC7, 0x6C, 0x36 + }, + { + 0x99, 0x60, 0x88, 0xC7, 0x94, 0x56, 0xEC, 0xDD, + 0xA1, 0xFB, 0xC0, 0x2E, 0xE1, 0xBA, 0x42, 0xD9, + 0x1D, 0x85, 0x8C, 0x31, 0x0A, 0x5A, 0x8B, 0x46, + 0x74, 0xFE, 0x6A, 0x7C, 0x14, 0x44, 0x14, 0xA1 + }, + { + 0x9E, 0x33, 0x8A, 0xED, 0x0B, 0xC7, 0x1C, 0x0C, + 0x97, 0xF1, 0x98, 0x55, 0xBF, 0x49, 0x17, 0x4F, + 0x70, 0xA9, 0xD7, 0x70, 0x14, 0x87, 0x36, 0x63, + 0x21, 0x34, 0x27, 0x50, 0x2B, 0xD8, 0x5D, 0x9F + }, + { + 0x4A, 0x84, 0x3D, 0x26, 0xAD, 0xEC, 0x52, 0x0E, + 0x4B, 0x5D, 0xBF, 0x01, 0x45, 0xCC, 0x4F, 0x50, + 0x24, 0xFA, 0xFC, 0xDC, 0x20, 0x25, 0x82, 0x4A, + 0x8C, 0x64, 0x65, 0x06, 0x17, 0x68, 0x7E, 0xE7 + }, + { + 0xC9, 0x16, 0x78, 0xC4, 0xA6, 0x4E, 0x2F, 0xA4, + 0xB7, 0x4D, 0xE6, 0x1A, 0xD0, 0xC0, 0x6F, 0xF0, + 0x6B, 0x5D, 0x67, 0x2F, 0xA7, 0xC6, 0x87, 0x7A, + 0x40, 0x14, 0xCE, 0x9E, 0x91, 0xBE, 0x38, 0xD7 + }, + { + 0xFF, 0x77, 0x77, 0x40, 0x5D, 0x32, 0x7A, 0xDB, + 0x58, 0x30, 0x1C, 0x71, 0x1E, 0xCD, 0xC2, 0xBC, + 0xE1, 0xBF, 0xA8, 0x29, 0xFF, 0xC9, 0xB1, 0x17, + 0xF2, 0x1A, 0x2B, 0x19, 0x8D, 0x0D, 0x68, 0x84 + }, + { + 0x0A, 0x8D, 0xDA, 0xF1, 0x72, 0x8C, 0x5C, 0xD9, + 0x3A, 0x25, 0x5D, 0x56, 0x23, 0xC3, 0xDA, 0xDA, + 0x2D, 0x3D, 0x05, 0x71, 0xBF, 0x14, 0x38, 0xAD, + 0xC8, 0xC9, 0x64, 0xA9, 0xAA, 0xD1, 0x18, 0xCB + }, + { + 0xC1, 0x33, 0xAB, 0xBD, 0x0D, 0x2D, 0x80, 0x8A, + 0x67, 0xB6, 0x74, 0x5B, 0x4B, 0x36, 0x50, 0xB4, + 0xA6, 0x4D, 0xC2, 0x76, 0xCF, 0x98, 0xE3, 0x03, + 0x57, 0xB6, 0xAB, 0xD5, 0xC1, 0xD2, 0x2A, 0x9B + }, + { + 0xC5, 0x9E, 0xE5, 0xC1, 0x96, 0xBA, 0x3C, 0xFE, + 0xF9, 0x40, 0x87, 0x79, 0x82, 0x07, 0xBD, 0xCE, + 0xF1, 0x39, 0xCE, 0x2C, 0xF7, 0x8D, 0xCE, 0xD6, + 0x19, 0x8F, 0x0F, 0xA3, 0xA4, 0x09, 0x13, 0x1C + }, + { + 0xC7, 0xFD, 0xAD, 0xE5, 0x9C, 0x46, 0x99, 0x38, + 0x5E, 0xBA, 0x59, 0xE7, 0x56, 0xC2, 0xB1, 0x71, + 0xB0, 0x23, 0xDE, 0xAE, 0x08, 0x2E, 0x5A, 0x6E, + 0x3B, 0xFB, 0xDC, 0x10, 0x73, 0xA3, 0x20, 0x03 + }, + { + 0x97, 0x53, 0x27, 0xC5, 0xF4, 0xDE, 0xC6, 0x41, + 0x4B, 0x6E, 0x00, 0xCB, 0x04, 0x23, 0x37, 0xB8, + 0xD2, 0xA6, 0x56, 0x46, 0x37, 0xA7, 0x44, 0x2A, + 0xEC, 0x7B, 0xE8, 0xF8, 0xC8, 0x9A, 0x2F, 0x1C + }, + { + 0xA2, 0xF7, 0x24, 0x6D, 0xF4, 0xA2, 0x4E, 0xFB, + 0xAC, 0xD3, 0xFD, 0x60, 0x68, 0x3A, 0xBC, 0x86, + 0x8B, 0xEF, 0x25, 0x32, 0x70, 0x52, 0xCF, 0x2F, + 0x1D, 0x93, 0xEC, 0xE4, 0xFF, 0xCD, 0x73, 0xC6 + }, + { + 0x49, 0x7F, 0xB2, 0xAC, 0xAC, 0xF1, 0x23, 0xF3, + 0x59, 0x5E, 0x40, 0xFC, 0x51, 0xA7, 0xBD, 0x24, + 0x45, 0x8B, 0xBC, 0xBA, 0x4A, 0x29, 0x40, 0xA5, + 0xCB, 0x03, 0xD6, 0x08, 0xFB, 0xDF, 0x28, 0x25 + }, + { + 0x0E, 0x97, 0xD2, 0x27, 0x93, 0xCE, 0x6F, 0x28, + 0x3D, 0x5C, 0x74, 0x0D, 0x30, 0x8A, 0x27, 0xAD, + 0x7C, 0x3B, 0x0D, 0x9A, 0xFC, 0xD3, 0xD9, 0xE9, + 0xB9, 0xCA, 0xC5, 0x6B, 0x10, 0x29, 0x0C, 0x8F + }, + { + 0x66, 0x30, 0xB3, 0x56, 0x18, 0xE7, 0x00, 0xD9, + 0x10, 0x68, 0x38, 0x93, 0x79, 0x5E, 0xF7, 0x0B, + 0xF0, 0x7E, 0xB1, 0x56, 0xF5, 0x5F, 0xFE, 0x3B, + 0x69, 0xAD, 0x88, 0xA4, 0xB8, 0xB0, 0xBF, 0xA1 + }, + { + 0x02, 0xF7, 0x42, 0xC6, 0xE9, 0x52, 0x78, 0x12, + 0x1A, 0x05, 0xE4, 0x42, 0x05, 0x44, 0x4F, 0xC5, + 0xEA, 0x6A, 0xF5, 0xE7, 0x41, 0xC5, 0x35, 0xBC, + 0x2C, 0xBC, 0x3B, 0x23, 0x5A, 0x2E, 0xA2, 0xB0 + }, + { + 0x46, 0x22, 0xF3, 0x6E, 0xB8, 0x98, 0x38, 0x3F, + 0x60, 0xD5, 0xBE, 0xD8, 0x09, 0xAC, 0x5C, 0x47, + 0x45, 0xC5, 0xD6, 0xAB, 0x84, 0xBC, 0xAD, 0xF7, + 0x9C, 0xF2, 0xA9, 0x6D, 0x4E, 0xC8, 0x88, 0x18 + }, + { + 0xCC, 0xD1, 0x1F, 0xAA, 0xA0, 0x58, 0x1E, 0xC3, + 0x2C, 0x3A, 0x40, 0x3F, 0x92, 0xEF, 0x43, 0xD5, + 0xDC, 0xF1, 0x95, 0xC1, 0xA1, 0x01, 0xDB, 0xFD, + 0x49, 0x5D, 0xBB, 0x4D, 0xCE, 0x80, 0x69, 0xE0 + }, + { + 0x06, 0x02, 0x4D, 0x6B, 0x07, 0xE0, 0x00, 0xBC, + 0xE6, 0x13, 0x47, 0x0A, 0x28, 0x80, 0x51, 0x9B, + 0x8B, 0xE4, 0xA3, 0x6B, 0xF3, 0x3C, 0x99, 0xC9, + 0x17, 0x89, 0x3E, 0xC7, 0x5D, 0xD9, 0x0F, 0xE3 + }, + { + 0xD9, 0x3A, 0xF9, 0x47, 0xB1, 0x46, 0x3A, 0x81, + 0x7D, 0xB4, 0x41, 0xA4, 0x74, 0x58, 0x8D, 0x6F, + 0x99, 0x6D, 0x24, 0x39, 0x83, 0xE8, 0x3C, 0x7E, + 0xEE, 0x90, 0xE1, 0xEF, 0xA4, 0x40, 0xD9, 0xBA + }, + { + 0x94, 0x89, 0x89, 0x45, 0xA7, 0xDB, 0x25, 0x9E, + 0x1B, 0x2E, 0x7C, 0xBE, 0xA4, 0x8A, 0xA0, 0xC6, + 0xD6, 0x57, 0x0D, 0x18, 0x17, 0x9F, 0x06, 0x18, + 0x47, 0x1C, 0x88, 0xF3, 0xEC, 0x3B, 0x0F, 0xC3 + }, + { + 0x4C, 0x2D, 0x93, 0x52, 0x56, 0x39, 0x2A, 0xA2, + 0xBE, 0x6E, 0x10, 0x78, 0xC0, 0x59, 0x38, 0x15, + 0xAB, 0xEF, 0x46, 0x9D, 0xE9, 0x69, 0xB5, 0x7B, + 0x88, 0x1B, 0x93, 0xAF, 0x55, 0x84, 0x65, 0xFA + }, + { + 0xAA, 0xC7, 0xBE, 0x16, 0xE5, 0x2F, 0x79, 0x0E, + 0x4F, 0xF7, 0x0B, 0x24, 0x01, 0x5C, 0xB1, 0x1B, + 0x40, 0x61, 0x6E, 0x94, 0xDB, 0x13, 0x88, 0x2B, + 0x41, 0xD3, 0xDD, 0x8C, 0x8C, 0x19, 0x52, 0xB7 + }, + { + 0x04, 0x34, 0xB4, 0x7C, 0x0E, 0xE7, 0xE6, 0xF5, + 0x39, 0x06, 0x79, 0x9A, 0x43, 0x20, 0x9D, 0x3F, + 0xC3, 0x7D, 0x3F, 0xD1, 0xF7, 0x45, 0x55, 0xDE, + 0x67, 0xAB, 0xAC, 0xB9, 0x51, 0xB0, 0x06, 0xF4 + }, + { + 0x04, 0x42, 0xFB, 0xDD, 0x5B, 0x58, 0x49, 0x6E, + 0xC7, 0x81, 0x59, 0xCC, 0xAA, 0x88, 0x7C, 0x88, + 0xA8, 0x61, 0xFC, 0xCA, 0x70, 0xE7, 0xAB, 0xC9, + 0x76, 0xF2, 0x4C, 0x11, 0x58, 0x8B, 0xE6, 0xEE + }, + { + 0xA7, 0x3E, 0x68, 0xBB, 0x18, 0xB0, 0x07, 0x64, + 0x8E, 0x76, 0xB5, 0x52, 0x8D, 0x1E, 0x50, 0xE7, + 0xFA, 0x65, 0x4D, 0xA3, 0x97, 0x0E, 0xC3, 0x49, + 0xBF, 0x59, 0x1A, 0x30, 0xD9, 0x32, 0xC8, 0xF6 + }, + { + 0x84, 0x9C, 0xF8, 0x73, 0x16, 0x2B, 0xA7, 0x2C, + 0x4B, 0x80, 0x08, 0xE6, 0x8F, 0x93, 0x2F, 0xB3, + 0xA0, 0x15, 0xA7, 0x4F, 0xCF, 0x95, 0x71, 0x98, + 0xD5, 0x6A, 0x0D, 0xC4, 0x62, 0x5A, 0x74, 0xF5 + }, + { + 0xA6, 0xDE, 0xC6, 0xFC, 0x89, 0x49, 0x34, 0x9C, + 0x4E, 0x9A, 0x9C, 0x62, 0x36, 0x87, 0xFB, 0xA4, + 0xC9, 0xB2, 0x75, 0xBD, 0xB2, 0x30, 0x50, 0x9B, + 0x72, 0xE3, 0xD6, 0x71, 0x19, 0x14, 0xE2, 0xD8 + }, + { + 0x58, 0xAF, 0xC2, 0xB2, 0x4A, 0x19, 0xFD, 0xBF, + 0x76, 0xA0, 0x9B, 0x70, 0xB1, 0xE3, 0xB7, 0x7F, + 0xCB, 0xD4, 0x06, 0x50, 0x01, 0xD9, 0x63, 0x66, + 0x40, 0xEB, 0x5A, 0x26, 0x28, 0xF4, 0x42, 0xCC + }, + { + 0x47, 0x3A, 0x43, 0xAA, 0x1D, 0x6A, 0x02, 0x87, + 0x67, 0x43, 0x2A, 0x83, 0x0A, 0xD1, 0x22, 0x1E, + 0x02, 0x9C, 0x58, 0x9A, 0xF9, 0xFD, 0x4D, 0x68, + 0xD5, 0x6C, 0x4F, 0xB8, 0x20, 0x25, 0x93, 0x52 + }, + { + 0xA0, 0xAE, 0xB4, 0xA5, 0xAD, 0x89, 0x9A, 0xF2, + 0xE2, 0x91, 0xB2, 0xE7, 0x9D, 0xBB, 0x6B, 0x0B, + 0xF5, 0x6B, 0x58, 0x44, 0x67, 0x6B, 0x95, 0x5D, + 0x94, 0x5B, 0x6C, 0x4A, 0xE1, 0xC0, 0x1E, 0xED + }, + { + 0xCF, 0xC3, 0x02, 0x9A, 0x9E, 0xEB, 0x15, 0x22, + 0x22, 0xD9, 0x66, 0x53, 0x49, 0x2E, 0x46, 0xCA, + 0x64, 0xCA, 0x4F, 0x0D, 0x64, 0x68, 0x30, 0x28, + 0xD3, 0xAE, 0xE5, 0xA4, 0x9C, 0xB4, 0x71, 0x63 + }, + { + 0x74, 0x67, 0xCF, 0x77, 0x61, 0xCD, 0x9F, 0x55, + 0x61, 0x8D, 0x30, 0xC9, 0xD8, 0xC5, 0xB4, 0x1E, + 0x47, 0x01, 0x51, 0x0C, 0x7D, 0x16, 0xAB, 0x4E, + 0x5D, 0x89, 0xA5, 0xD7, 0x71, 0x46, 0xB0, 0x92 + }, + { + 0xC0, 0x16, 0xD8, 0x42, 0x4E, 0x53, 0x1E, 0xFC, + 0x57, 0x37, 0xC0, 0x3F, 0xC9, 0x0A, 0x5E, 0xFC, + 0x9F, 0x90, 0x22, 0xE4, 0xD5, 0xBA, 0x3B, 0x06, + 0x95, 0xF7, 0xAE, 0x53, 0x82, 0x60, 0xC2, 0xEE + }, + { + 0x5D, 0x38, 0x11, 0x89, 0xE6, 0x00, 0x0F, 0xC1, + 0x17, 0xC7, 0x1F, 0x59, 0xF7, 0x86, 0xFB, 0x4B, + 0x79, 0xFD, 0xD4, 0xEC, 0x5D, 0x4C, 0xD3, 0x0A, + 0xAC, 0x21, 0x57, 0xF7, 0x5D, 0xEA, 0xD7, 0x78 + }, + { + 0x7C, 0x9C, 0xDD, 0x15, 0xC4, 0xC9, 0xAB, 0xCA, + 0xCB, 0xFE, 0x6F, 0x66, 0x4A, 0x7F, 0x5F, 0x8B, + 0x2E, 0x25, 0x91, 0x83, 0x29, 0x1A, 0xE5, 0xCC, + 0x91, 0x30, 0xA0, 0xB2, 0x41, 0xE5, 0x73, 0x7F + }, + { + 0xB8, 0x81, 0x31, 0x72, 0xF5, 0x21, 0x8A, 0xC3, + 0xEB, 0x68, 0x7B, 0xC4, 0xAF, 0xAF, 0xF8, 0x3F, + 0xBC, 0xA4, 0xE9, 0xC1, 0xA4, 0x62, 0x96, 0x33, + 0x01, 0xDD, 0x44, 0x59, 0x85, 0x01, 0x50, 0xA2 + }, + { + 0xE3, 0xD1, 0x30, 0xE3, 0x6A, 0x02, 0x8E, 0xA8, + 0x0C, 0x57, 0xA2, 0xAA, 0x48, 0x19, 0xFD, 0x34, + 0xE4, 0xDB, 0xBE, 0xB1, 0x4A, 0x49, 0x58, 0x94, + 0xB1, 0x5A, 0x87, 0x87, 0xDB, 0x1A, 0x9F, 0x9C + }, + { + 0xFF, 0xF1, 0xB4, 0x40, 0x0F, 0x48, 0x9E, 0x07, + 0xD2, 0x23, 0x51, 0xC1, 0xF0, 0x95, 0x65, 0xE2, + 0x65, 0xB6, 0x8A, 0xD2, 0x9F, 0x63, 0x29, 0x87, + 0x9E, 0x6B, 0x5F, 0x7F, 0x6B, 0x41, 0x93, 0x50 + }, + { + 0x55, 0x9E, 0xD5, 0xBB, 0x3E, 0x5F, 0x39, 0x85, + 0xFB, 0x57, 0x82, 0x28, 0xBF, 0x8C, 0x0F, 0x0B, + 0x17, 0x3F, 0x8D, 0x11, 0x53, 0xFA, 0xEB, 0x9F, + 0xEC, 0x75, 0x6F, 0xFD, 0x18, 0xA8, 0x72, 0x38 + }, + { + 0x88, 0x13, 0x12, 0x53, 0x01, 0x4D, 0x23, 0xC5, + 0xE3, 0x8E, 0x78, 0xBD, 0xA1, 0x94, 0x55, 0xD8, + 0xA0, 0x23, 0xBD, 0x7A, 0x7E, 0x72, 0x74, 0x57, + 0xA1, 0x52, 0xA8, 0x1D, 0x0B, 0x17, 0x18, 0xA7 + }, + { + 0xF4, 0xD3, 0xFA, 0xE7, 0xCD, 0xE6, 0xBB, 0x66, + 0x71, 0x5A, 0x19, 0x8F, 0xA4, 0x8D, 0x21, 0x0C, + 0x10, 0xF8, 0xDF, 0x32, 0x04, 0xAE, 0x5E, 0x33, + 0xA6, 0x02, 0x46, 0x7F, 0x1B, 0x62, 0x26, 0x85 + }, + { + 0xE6, 0x2B, 0x62, 0x2A, 0xC8, 0xA2, 0x13, 0x66, + 0xBF, 0x2D, 0xED, 0x30, 0xF4, 0x08, 0x2A, 0x53, + 0xE7, 0x7A, 0x9A, 0xA6, 0x96, 0xB1, 0xF3, 0xEE, + 0x8C, 0xFE, 0x99, 0xC5, 0x93, 0x12, 0xD9, 0xC7 + }, + { + 0x3D, 0x39, 0xFF, 0xA8, 0x55, 0x12, 0xC3, 0xC8, + 0x89, 0x0D, 0x4B, 0xDF, 0x31, 0x88, 0x9C, 0xA6, + 0x6E, 0x5C, 0xEC, 0xB6, 0x3C, 0xFE, 0xED, 0x57, + 0xB9, 0x26, 0x37, 0x08, 0xE7, 0x4C, 0x55, 0x0B + }, + { + 0xB1, 0x70, 0x3B, 0x8A, 0x00, 0xE2, 0x61, 0x24, + 0x97, 0xD1, 0x1C, 0x64, 0x9D, 0x15, 0x0A, 0x6C, + 0x96, 0x3B, 0xF4, 0xFD, 0x38, 0xFE, 0xB1, 0xC3, + 0x81, 0xFE, 0x0D, 0x9B, 0x04, 0xC0, 0x2B, 0x22 + }, + { + 0x12, 0xFB, 0xAD, 0x9D, 0x37, 0x82, 0x81, 0x2D, + 0x71, 0x17, 0x9A, 0x50, 0xFB, 0xD9, 0xB4, 0x56, + 0x6C, 0x7B, 0x06, 0xF5, 0xD7, 0x7C, 0x6F, 0x32, + 0x97, 0x17, 0xFB, 0x4A, 0xE2, 0xC5, 0xB4, 0xEC + }, + { + 0x76, 0x8B, 0x65, 0x9A, 0x82, 0x4B, 0x43, 0xF9, + 0xCA, 0x56, 0x60, 0xB9, 0xDD, 0xF0, 0x5F, 0x8B, + 0xA2, 0xBC, 0x49, 0x93, 0x86, 0x6B, 0x7C, 0x9B, + 0xE6, 0x87, 0x91, 0xF5, 0xB2, 0x46, 0x44, 0xB3 + }, + { + 0xC0, 0x20, 0x4E, 0x23, 0xCA, 0x86, 0xBE, 0x20, + 0x5E, 0xED, 0x0C, 0xC3, 0xDD, 0x72, 0x25, 0xCE, + 0x5F, 0xFE, 0x1E, 0xE1, 0x2D, 0xAC, 0xB9, 0x3C, + 0x5D, 0x06, 0x29, 0xB7, 0x69, 0x9C, 0xD7, 0x33 + }, + { + 0xF4, 0x32, 0x96, 0x96, 0x1F, 0x8E, 0xAE, 0xCC, + 0xD8, 0x54, 0x41, 0x3D, 0xC5, 0xAD, 0xDA, 0x62, + 0x39, 0x3A, 0x34, 0x46, 0x27, 0xE8, 0x6C, 0x06, + 0x6E, 0x79, 0x07, 0x55, 0x00, 0x40, 0x74, 0x4F + }, + { + 0x82, 0xF4, 0x46, 0x9E, 0x80, 0x78, 0x90, 0x21, + 0xC6, 0x1D, 0xB7, 0xE3, 0x2F, 0x36, 0xAC, 0xBE, + 0x59, 0x1A, 0x64, 0xF2, 0x60, 0x59, 0x26, 0x57, + 0x70, 0xAE, 0x65, 0x8D, 0x62, 0xBD, 0xE7, 0xEF + }, + { + 0x2A, 0x85, 0x67, 0x1A, 0x55, 0xC8, 0x9F, 0xA1, + 0x56, 0xE2, 0x96, 0xF7, 0x5D, 0xF1, 0xC7, 0xDB, + 0xAB, 0x17, 0x8E, 0xBB, 0xA6, 0x52, 0x04, 0xA7, + 0xE8, 0x17, 0x8C, 0x91, 0x6A, 0xD0, 0x87, 0xF8 + }, + { + 0x33, 0xE2, 0x45, 0x00, 0x28, 0x08, 0xF6, 0x93, + 0x4B, 0x9B, 0xE3, 0xA6, 0xFA, 0x8E, 0x86, 0x70, + 0xC9, 0x0B, 0xAA, 0x62, 0x57, 0x17, 0xB9, 0x20, + 0x1E, 0xB9, 0xB9, 0xDD, 0x91, 0x2F, 0x5C, 0xE2 + }, + { + 0x58, 0xEE, 0x5E, 0x79, 0x91, 0x84, 0xAD, 0x9D, + 0xA9, 0xA1, 0x7C, 0x5B, 0x46, 0xA4, 0x81, 0x0E, + 0x28, 0xBD, 0xD0, 0x8C, 0x35, 0x81, 0x63, 0x4C, + 0x83, 0x50, 0x30, 0x53, 0x9B, 0x79, 0x54, 0x4D + }, + { + 0x26, 0xD8, 0xFA, 0x08, 0xDB, 0x30, 0x8E, 0xDF, + 0x2F, 0x96, 0xF8, 0x2A, 0xF6, 0xB6, 0x0C, 0x17, + 0xD8, 0xF1, 0xFF, 0x85, 0x8C, 0x52, 0xF2, 0xD0, + 0xF3, 0x83, 0x10, 0x78, 0x12, 0x75, 0x26, 0xA3 + }, + { + 0x25, 0xA5, 0x8D, 0xF4, 0x03, 0x92, 0x47, 0xA2, + 0x2F, 0x68, 0xFF, 0x2B, 0x71, 0x76, 0x6B, 0x7B, + 0x56, 0x00, 0xDD, 0xF4, 0x01, 0xD9, 0x9F, 0xF2, + 0xC1, 0x95, 0x5A, 0xE7, 0xBB, 0x43, 0xE5, 0x6A + }, + { + 0xBE, 0x43, 0xE8, 0x68, 0x61, 0x60, 0xE9, 0x07, + 0xBA, 0x54, 0x7D, 0x5A, 0x87, 0x9D, 0x10, 0xF7, + 0x88, 0xAF, 0xC8, 0x42, 0xB8, 0xEB, 0xB9, 0xF3, + 0xF7, 0x88, 0x53, 0x25, 0x15, 0x91, 0x2A, 0xE4 + }, + { + 0xAA, 0x4A, 0xCB, 0x95, 0xD8, 0x79, 0x19, 0x2A, + 0x69, 0x08, 0xE8, 0x8A, 0xE3, 0xD6, 0x58, 0x9F, + 0x4E, 0x3E, 0xB3, 0xD4, 0xE0, 0x3A, 0x80, 0x6C, + 0xCD, 0xB9, 0xB5, 0xD6, 0xA9, 0x58, 0x6F, 0xDF + }, + { + 0x84, 0x66, 0xD5, 0xE4, 0x4C, 0xE9, 0x5B, 0x4F, + 0xA1, 0x79, 0x99, 0x24, 0x44, 0xB8, 0xC2, 0x48, + 0x5B, 0x88, 0x64, 0x48, 0xA6, 0xDC, 0xCF, 0xCF, + 0x0B, 0xC3, 0x0B, 0xC5, 0xF0, 0xF5, 0x6B, 0x01 + }, + { + 0x00, 0x56, 0xD7, 0xE0, 0xAC, 0x33, 0x35, 0x57, + 0x83, 0x65, 0x9B, 0x38, 0xEC, 0x8B, 0xEC, 0xCB, + 0xF7, 0x83, 0x93, 0x99, 0x67, 0xFE, 0x37, 0xAE, + 0xAC, 0xF3, 0x69, 0xDD, 0xB6, 0x70, 0xAD, 0xA0 + }, + { + 0x90, 0x4F, 0x42, 0xF3, 0x45, 0x53, 0x0A, 0xC8, + 0xA3, 0x52, 0xD0, 0x9B, 0x68, 0x72, 0xC5, 0xBC, + 0xA3, 0x66, 0x1A, 0xBC, 0xA6, 0xCA, 0x64, 0xC8, + 0x09, 0x9F, 0x2F, 0xB6, 0x86, 0x7C, 0x30, 0xFE + }, + { + 0xA8, 0xC3, 0xBF, 0x46, 0xF0, 0xB8, 0x8B, 0xBD, + 0x16, 0xFD, 0xA4, 0xA8, 0xB5, 0xCA, 0x81, 0xF5, + 0x24, 0x35, 0x20, 0xC3, 0x85, 0xD3, 0x8C, 0x0B, + 0x4D, 0x23, 0x52, 0xAB, 0x34, 0xEA, 0x35, 0xE6 + }, + { + 0x8D, 0x33, 0x17, 0xFC, 0x60, 0x6E, 0x56, 0x6D, + 0x30, 0x2E, 0xDA, 0xB5, 0x5E, 0x80, 0x16, 0x11, + 0xD8, 0xC1, 0x3F, 0x4A, 0x9A, 0x19, 0xD1, 0x85, + 0x97, 0x8D, 0xEF, 0x72, 0x83, 0x9C, 0xDA, 0xA3 + }, + { + 0x97, 0x38, 0x80, 0x11, 0xF5, 0x7A, 0x49, 0x86, + 0x90, 0xEC, 0x79, 0x88, 0xEF, 0xF9, 0x03, 0xFF, + 0x9B, 0x23, 0x58, 0xF5, 0xB6, 0x1B, 0xAA, 0x20, + 0xF7, 0x32, 0x90, 0xD6, 0x29, 0x6C, 0x1C, 0x0B + }, + { + 0xCF, 0xB8, 0x0C, 0xAB, 0x89, 0x90, 0x95, 0x08, + 0x09, 0x12, 0x3F, 0xBF, 0x85, 0xE9, 0x76, 0x45, + 0x47, 0x08, 0xE0, 0xAF, 0xED, 0x69, 0x8E, 0x33, + 0x52, 0xA3, 0x16, 0x35, 0x90, 0x9D, 0xB3, 0xE5 + }, + { + 0x0D, 0xAA, 0xCA, 0x55, 0x13, 0x2A, 0x23, 0x5B, + 0x83, 0x1A, 0x5E, 0xFF, 0x4E, 0xA4, 0x67, 0xCD, + 0x10, 0xAF, 0x44, 0x20, 0x08, 0x47, 0x73, 0x5A, + 0x1F, 0xFD, 0x51, 0xFA, 0x37, 0xEA, 0xA2, 0xA2 + }, + { + 0x69, 0xB2, 0x14, 0x97, 0xEB, 0xB8, 0x24, 0xBA, + 0x66, 0x53, 0x68, 0x18, 0x88, 0x25, 0xE6, 0xF6, + 0xF1, 0x4C, 0xF2, 0xC3, 0xF7, 0xB5, 0x53, 0x0B, + 0xB3, 0x4F, 0xA6, 0x58, 0xEE, 0xD9, 0xA7, 0x39 + }, + { + 0xB9, 0xA1, 0x9F, 0x50, 0x9B, 0xE0, 0x3F, 0xBC, + 0x40, 0xE2, 0x43, 0xA5, 0x8A, 0x3D, 0xED, 0x11, + 0xF0, 0xD5, 0x1F, 0x80, 0xE3, 0xE2, 0x9A, 0x50, + 0x56, 0x44, 0xCC, 0x05, 0x74, 0x38, 0x14, 0xEC + }, + { + 0xC4, 0xBC, 0xB2, 0x00, 0x25, 0x55, 0xD5, 0x44, + 0xFD, 0x0B, 0x02, 0x77, 0x06, 0x23, 0x89, 0x1E, + 0x70, 0xEE, 0xEC, 0x77, 0x44, 0x86, 0x5D, 0xD6, + 0x45, 0x5A, 0xD6, 0x65, 0xCC, 0x82, 0xE8, 0x61 + }, + { + 0x91, 0x2D, 0x24, 0xDC, 0x3D, 0x69, 0x23, 0xA4, + 0x83, 0xC2, 0x63, 0xEB, 0xA8, 0x1B, 0x7A, 0x87, + 0x97, 0xF2, 0x3C, 0xBF, 0x2F, 0x78, 0xB5, 0x1E, + 0x22, 0x26, 0x63, 0x9F, 0x84, 0xA5, 0x90, 0x47 + }, + { + 0x56, 0x82, 0x7A, 0x18, 0x88, 0x3A, 0xFD, 0xF9, + 0xCE, 0xEC, 0x56, 0x2B, 0x20, 0x66, 0xD8, 0xAC, + 0xB2, 0xC1, 0x95, 0x05, 0xEC, 0xE6, 0xF7, 0xA8, + 0x3E, 0x9F, 0x33, 0x46, 0xCB, 0xB8, 0x28, 0xC9 + }, + { + 0x25, 0x1D, 0x8D, 0x09, 0xFC, 0x48, 0xDD, 0x1D, + 0x6A, 0xF8, 0xFF, 0xDF, 0x39, 0x50, 0x91, 0xA4, + 0x6E, 0x05, 0xB8, 0xB7, 0xC5, 0xEC, 0x0C, 0x79, + 0xB6, 0x8A, 0x89, 0x04, 0xC8, 0x27, 0xBD, 0xEA + }, + { + 0xC2, 0xD1, 0x4D, 0x69, 0xFD, 0x0B, 0xBD, 0x1C, + 0x0F, 0xE8, 0xC8, 0x45, 0xD5, 0xFD, 0x6A, 0x8F, + 0x74, 0x01, 0x51, 0xB1, 0xD8, 0xEB, 0x4D, 0x26, + 0x36, 0x4B, 0xB0, 0x2D, 0xAE, 0x0C, 0x13, 0xBC + }, + { + 0x2E, 0x5F, 0xE2, 0x1F, 0x8F, 0x1B, 0x63, 0x97, + 0xA3, 0x8A, 0x60, 0x3D, 0x60, 0xB6, 0xF5, 0x3C, + 0x3B, 0x5D, 0xB2, 0x0A, 0xA5, 0x6C, 0x6D, 0x44, + 0xBE, 0xBD, 0x48, 0x28, 0xCE, 0x28, 0xF9, 0x0F + }, + { + 0x25, 0x05, 0x9F, 0x10, 0x60, 0x5E, 0x67, 0xAD, + 0xFE, 0x68, 0x13, 0x50, 0x66, 0x6E, 0x15, 0xAE, + 0x97, 0x6A, 0x5A, 0x57, 0x1C, 0x13, 0xCF, 0x5B, + 0xC8, 0x05, 0x3F, 0x43, 0x0E, 0x12, 0x0A, 0x52 + }, +}; + + + + +static const uint8_t blake2sp_keyed_kat[KAT_LENGTH][BLAKE2S_OUTBYTES] = +{ + { + 0x71, 0x5C, 0xB1, 0x38, 0x95, 0xAE, 0xB6, 0x78, + 0xF6, 0x12, 0x41, 0x60, 0xBF, 0xF2, 0x14, 0x65, + 0xB3, 0x0F, 0x4F, 0x68, 0x74, 0x19, 0x3F, 0xC8, + 0x51, 0xB4, 0x62, 0x10, 0x43, 0xF0, 0x9C, 0xC6 + }, + { + 0x40, 0x57, 0x8F, 0xFA, 0x52, 0xBF, 0x51, 0xAE, + 0x18, 0x66, 0xF4, 0x28, 0x4D, 0x3A, 0x15, 0x7F, + 0xC1, 0xBC, 0xD3, 0x6A, 0xC1, 0x3C, 0xBD, 0xCB, + 0x03, 0x77, 0xE4, 0xD0, 0xCD, 0x0B, 0x66, 0x03 + }, + { + 0x67, 0xE3, 0x09, 0x75, 0x45, 0xBA, 0xD7, 0xE8, + 0x52, 0xD7, 0x4D, 0x4E, 0xB5, 0x48, 0xEC, 0xA7, + 0xC2, 0x19, 0xC2, 0x02, 0xA7, 0xD0, 0x88, 0xDB, + 0x0E, 0xFE, 0xAC, 0x0E, 0xAC, 0x30, 0x42, 0x49 + }, + { + 0x8D, 0xBC, 0xC0, 0x58, 0x9A, 0x3D, 0x17, 0x29, + 0x6A, 0x7A, 0x58, 0xE2, 0xF1, 0xEF, 0xF0, 0xE2, + 0xAA, 0x42, 0x10, 0xB5, 0x8D, 0x1F, 0x88, 0xB8, + 0x6D, 0x7B, 0xA5, 0xF2, 0x9D, 0xD3, 0xB5, 0x83 + }, + { + 0xA9, 0xA9, 0x65, 0x2C, 0x8C, 0x67, 0x75, 0x94, + 0xC8, 0x72, 0x12, 0xD8, 0x9D, 0x5A, 0x75, 0xFB, + 0x31, 0xEF, 0x4F, 0x47, 0xC6, 0x58, 0x2C, 0xDE, + 0x5F, 0x1E, 0xF6, 0x6B, 0xD4, 0x94, 0x53, 0x3A + }, + { + 0x05, 0xA7, 0x18, 0x0E, 0x59, 0x50, 0x54, 0x73, + 0x99, 0x48, 0xC5, 0xE3, 0x38, 0xC9, 0x5F, 0xE0, + 0xB7, 0xFC, 0x61, 0xAC, 0x58, 0xA7, 0x35, 0x74, + 0x74, 0x56, 0x33, 0xBB, 0xC1, 0xF7, 0x70, 0x31 + }, + { + 0x81, 0x4D, 0xE8, 0x31, 0x53, 0xB8, 0xD7, 0x5D, + 0xFA, 0xDE, 0x29, 0xFD, 0x39, 0xAC, 0x72, 0xDD, + 0x09, 0xCA, 0x0F, 0x9B, 0xC8, 0xB7, 0xAB, 0x6A, + 0x06, 0xBA, 0xEE, 0x7D, 0xD0, 0xF9, 0xF0, 0x83 + }, + { + 0xDF, 0xD4, 0x19, 0x44, 0x91, 0x29, 0xFF, 0x60, + 0x4F, 0x0A, 0x14, 0x8B, 0x4C, 0x7D, 0x68, 0xF1, + 0x17, 0x4F, 0x7D, 0x0F, 0x8C, 0x8D, 0x2C, 0xE7, + 0x7F, 0x44, 0x8F, 0xD3, 0x41, 0x9C, 0x6F, 0xB0 + }, + { + 0xB9, 0xED, 0x22, 0xE7, 0xDD, 0x8D, 0xD1, 0x4E, + 0xE8, 0xC9, 0x5B, 0x20, 0xE7, 0x63, 0x2E, 0x85, + 0x53, 0xA2, 0x68, 0xD9, 0xFF, 0x86, 0x33, 0xED, + 0x3C, 0x21, 0xD1, 0xB8, 0xC9, 0xA7, 0x0B, 0xE1 + }, + { + 0x95, 0xF0, 0x31, 0x67, 0x1A, 0x4E, 0x3C, 0x54, + 0x44, 0x1C, 0xEE, 0x9D, 0xBE, 0xF4, 0xB7, 0xAC, + 0xA4, 0x46, 0x18, 0xA3, 0xA3, 0x33, 0xAD, 0x74, + 0x06, 0xD1, 0x97, 0xAC, 0x5B, 0xA0, 0x79, 0x1A + }, + { + 0xE2, 0x92, 0x5B, 0x9D, 0x5C, 0xA0, 0xFF, 0x62, + 0x88, 0xC5, 0xEA, 0x1A, 0xF2, 0xD2, 0x2B, 0x0A, + 0x6B, 0x79, 0xE2, 0xDA, 0xE0, 0x8B, 0xFD, 0x36, + 0xC3, 0xBE, 0x10, 0xBB, 0x8D, 0x71, 0xD8, 0x39 + }, + { + 0x16, 0x24, 0x9C, 0x74, 0x4E, 0x49, 0x51, 0x45, + 0x1D, 0x4C, 0x89, 0x4F, 0xB5, 0x9A, 0x3E, 0xCB, + 0x3F, 0xBF, 0xB7, 0xA4, 0x5F, 0x96, 0xF8, 0x5D, + 0x15, 0x80, 0xAC, 0x0B, 0x84, 0x2D, 0x96, 0xDA + }, + { + 0x43, 0x2B, 0xC9, 0x1C, 0x52, 0xAC, 0xEB, 0x9D, + 0xAE, 0xD8, 0x83, 0x28, 0x81, 0x64, 0x86, 0x50, + 0xC1, 0xB8, 0x1D, 0x11, 0x7A, 0xBD, 0x68, 0xE0, + 0x84, 0x51, 0x50, 0x8A, 0x63, 0xBE, 0x00, 0x81 + }, + { + 0xCD, 0xE8, 0x20, 0x2B, 0xCF, 0xA3, 0xF3, 0xE9, + 0x5D, 0x79, 0xBA, 0xCC, 0x16, 0x5D, 0x52, 0x70, + 0x0E, 0xF7, 0x1D, 0x87, 0x4A, 0x3C, 0x63, 0x7E, + 0x63, 0x4F, 0x64, 0x44, 0x73, 0x72, 0x0D, 0x6B + }, + { + 0x16, 0x21, 0x62, 0x1F, 0x5C, 0x3E, 0xE4, 0x46, + 0x89, 0x9D, 0x3C, 0x8A, 0xAE, 0x49, 0x17, 0xB1, + 0xE6, 0xDB, 0x4A, 0x0E, 0xD0, 0x42, 0x31, 0x5F, + 0xB2, 0xC1, 0x74, 0x82, 0x5E, 0x0A, 0x18, 0x19 + }, + { + 0x33, 0x6E, 0x8E, 0xBC, 0x71, 0xE2, 0x09, 0x5C, + 0x27, 0xF8, 0x64, 0xA3, 0x12, 0x1E, 0xFD, 0x0F, + 0xAA, 0x7A, 0x41, 0x28, 0x57, 0x25, 0xA5, 0x92, + 0xF6, 0x1B, 0xED, 0xED, 0x9D, 0xDE, 0x86, 0xED + }, + { + 0x07, 0x9B, 0xE0, 0x41, 0x0E, 0x78, 0x9B, 0x36, + 0xEE, 0x7F, 0x55, 0xC1, 0x9F, 0xAA, 0xC6, 0x91, + 0x65, 0x6E, 0xB0, 0x52, 0x1F, 0x42, 0x94, 0x9B, + 0x84, 0xEE, 0x29, 0xFE, 0x2A, 0x0E, 0x7F, 0x36 + }, + { + 0x17, 0x27, 0x0C, 0x4F, 0x34, 0x88, 0x08, 0x2D, + 0x9F, 0xF9, 0x93, 0x7E, 0xAB, 0x3C, 0xA9, 0x9C, + 0x97, 0xC5, 0xB4, 0x59, 0x61, 0x47, 0x37, 0x2D, + 0xD4, 0xE9, 0x8A, 0xCF, 0x13, 0xDB, 0x28, 0x10 + }, + { + 0x18, 0x3C, 0x38, 0x75, 0x4D, 0x03, 0x41, 0xCE, + 0x07, 0xC1, 0x7A, 0x6C, 0xB6, 0xC2, 0xFD, 0x8B, + 0xBC, 0xC1, 0x40, 0x4F, 0xDD, 0x01, 0x41, 0x99, + 0xC7, 0x8B, 0xE1, 0xA9, 0x75, 0x59, 0xA9, 0x28 + }, + { + 0x6E, 0x52, 0xD7, 0x28, 0xA4, 0x05, 0xA6, 0xE1, + 0xF8, 0x75, 0x87, 0xBB, 0xC2, 0xAC, 0x91, 0xC5, + 0xC0, 0x9B, 0x2D, 0x82, 0x8A, 0xC8, 0x1E, 0x5C, + 0x4A, 0x81, 0xD0, 0x3D, 0xD4, 0xAA, 0x8D, 0x5C + }, + { + 0xF4, 0xE0, 0x8E, 0x05, 0x9B, 0x74, 0x14, 0x4B, + 0xF9, 0x48, 0x14, 0x6D, 0x14, 0xA2, 0xC8, 0x1E, + 0x46, 0xDC, 0x15, 0xFF, 0x26, 0xEB, 0x52, 0x34, + 0x4C, 0xDD, 0x47, 0x4A, 0xBE, 0xA1, 0x4B, 0xC0 + }, + { + 0x0F, 0x2E, 0x0A, 0x10, 0x0E, 0xD8, 0xA1, 0x17, + 0x85, 0x96, 0x2A, 0xD4, 0x59, 0x6A, 0xF9, 0x55, + 0xE3, 0x0B, 0x9A, 0xEF, 0x93, 0x0A, 0x24, 0x8D, + 0xA9, 0x32, 0x2B, 0x70, 0x2D, 0x4B, 0x68, 0x72 + }, + { + 0x51, 0x90, 0xFC, 0xC7, 0x32, 0xF4, 0x04, 0xAA, + 0xD4, 0x36, 0x4A, 0xC7, 0x96, 0x0C, 0xFD, 0x5B, + 0x4E, 0x34, 0x86, 0x29, 0xC3, 0x72, 0xEE, 0xB3, + 0x25, 0xB5, 0xC6, 0xC7, 0xCB, 0xCE, 0x59, 0xAB + }, + { + 0xC0, 0xC4, 0xCB, 0x86, 0xEA, 0x25, 0xEA, 0x95, + 0x7E, 0xEC, 0x5B, 0x22, 0xD2, 0x55, 0x0A, 0x16, + 0x49, 0xE6, 0xDF, 0xFA, 0x31, 0x6B, 0xB8, 0xF4, + 0xC9, 0x1B, 0x8F, 0xF7, 0xA2, 0x4B, 0x25, 0x31 + }, + { + 0x2C, 0x9E, 0xDA, 0x13, 0x5A, 0x30, 0xAE, 0xCA, + 0xF3, 0xAC, 0xB3, 0xD2, 0x3A, 0x30, 0x35, 0xFB, + 0xAB, 0xBA, 0x98, 0x33, 0x31, 0x65, 0xD8, 0x7F, + 0xCB, 0xF8, 0xFE, 0x10, 0x33, 0x6E, 0xCF, 0x20 + }, + { + 0x3C, 0xD6, 0x69, 0xE8, 0xD5, 0x62, 0x62, 0xA2, + 0x37, 0x13, 0x67, 0x22, 0x4D, 0xAE, 0x6D, 0x75, + 0x9E, 0xE1, 0x52, 0xC3, 0x15, 0x33, 0xB2, 0x63, + 0xFA, 0x2E, 0x64, 0x92, 0x08, 0x77, 0xB2, 0xA7 + }, + { + 0x18, 0xA9, 0xA0, 0xC2, 0xD0, 0xEA, 0x6C, 0x3B, + 0xB3, 0x32, 0x83, 0x0F, 0x89, 0x18, 0xB0, 0x68, + 0x4F, 0x5D, 0x39, 0x94, 0xDF, 0x48, 0x67, 0x46, + 0x2D, 0xD0, 0x6E, 0xF0, 0x86, 0x24, 0x24, 0xCC + }, + { + 0x73, 0x90, 0xEA, 0x41, 0x04, 0xA9, 0xF4, 0xEE, + 0xA9, 0x0F, 0x81, 0xE2, 0x6A, 0x12, 0x9D, 0xCF, + 0x9F, 0x4A, 0xF3, 0x83, 0x52, 0xD9, 0xCB, 0x6A, + 0x81, 0x2C, 0xC8, 0x05, 0x69, 0x09, 0x05, 0x0E + }, + { + 0xE4, 0x9E, 0x01, 0x14, 0xC6, 0x29, 0xB4, 0x94, + 0xB1, 0x1E, 0xA9, 0x8E, 0xCD, 0x40, 0x32, 0x73, + 0x1F, 0x15, 0x3B, 0x46, 0x50, 0xAC, 0xAC, 0xD7, + 0xE0, 0xF6, 0xE7, 0xDE, 0x3D, 0xF0, 0x19, 0x77 + }, + { + 0x27, 0xC5, 0x70, 0x2B, 0xE1, 0x04, 0xB3, 0xA9, + 0x4F, 0xC4, 0x34, 0x23, 0xAE, 0xEE, 0x83, 0xAC, + 0x3C, 0xA7, 0x3B, 0x7F, 0x87, 0x83, 0x9A, 0x6B, + 0x2E, 0x29, 0x60, 0x79, 0x03, 0xB7, 0xF2, 0x87 + }, + { + 0x81, 0xD2, 0xE1, 0x2E, 0xB2, 0xF4, 0x27, 0x60, + 0xC6, 0xE3, 0xBA, 0xA7, 0x8F, 0x84, 0x07, 0x3A, + 0xE6, 0xF5, 0x61, 0x60, 0x70, 0xFE, 0x25, 0xBE, + 0xDE, 0x7C, 0x7C, 0x82, 0x48, 0xAB, 0x1F, 0xBA + }, + { + 0xFA, 0xB2, 0x35, 0xD5, 0x93, 0x48, 0xAB, 0x8C, + 0xE4, 0x9B, 0xEC, 0x77, 0xC0, 0xF1, 0x93, 0x28, + 0xFD, 0x04, 0x5D, 0xFD, 0x60, 0x8A, 0x53, 0x03, + 0x36, 0xDF, 0x4F, 0x94, 0xE1, 0x72, 0xA5, 0xC8 + }, + { + 0x8A, 0xAA, 0x8D, 0x80, 0x5C, 0x58, 0x88, 0x1F, + 0xF3, 0x79, 0xFB, 0xD4, 0x2C, 0x6B, 0xF6, 0xF1, + 0x4C, 0x6C, 0x73, 0xDF, 0x80, 0x71, 0xB3, 0xB2, + 0x28, 0x98, 0x11, 0x09, 0xCC, 0xC0, 0x15, 0xF9 + }, + { + 0x91, 0xFD, 0xD2, 0x62, 0x20, 0x39, 0x16, 0x39, + 0x47, 0x40, 0x95, 0x2B, 0xCE, 0x72, 0xB6, 0x4B, + 0xAB, 0xB6, 0xF7, 0x21, 0x34, 0x4D, 0xEE, 0x82, + 0x50, 0xBF, 0x0E, 0x46, 0xF1, 0xBA, 0x18, 0x8F + }, + { + 0xF7, 0xE5, 0x7B, 0x8F, 0x85, 0xF4, 0x7D, 0x59, + 0x03, 0xAD, 0x4C, 0xCB, 0x8A, 0xF6, 0x2A, 0x3E, + 0x85, 0x8A, 0xAB, 0x2B, 0x8C, 0xC2, 0x26, 0x49, + 0x4F, 0x7B, 0x00, 0xBE, 0xDB, 0xF5, 0xB0, 0xD0 + }, + { + 0xF7, 0x6F, 0x21, 0xAD, 0xDA, 0xE9, 0x6A, 0x96, + 0x46, 0xFC, 0x06, 0xF9, 0xBF, 0x52, 0xAE, 0x08, + 0x48, 0xF1, 0x8C, 0x35, 0x26, 0xB1, 0x29, 0xE1, + 0x5B, 0x2C, 0x35, 0x5E, 0x2E, 0x79, 0xE5, 0xDA + }, + { + 0x8A, 0xEB, 0x1C, 0x79, 0x5F, 0x34, 0x90, 0x01, + 0x5E, 0xF4, 0xCD, 0x61, 0xA2, 0x80, 0x7B, 0x23, + 0x0E, 0xFD, 0xC8, 0x46, 0x01, 0x73, 0xDA, 0xD0, + 0x26, 0xA4, 0xA0, 0xFC, 0xC2, 0xFB, 0xF2, 0x2A + }, + { + 0xC5, 0x64, 0xFF, 0xC6, 0x23, 0x07, 0x77, 0x65, + 0xBB, 0x97, 0x87, 0x58, 0x56, 0x54, 0xCE, 0x74, + 0x5D, 0xBD, 0x10, 0x8C, 0xEF, 0x24, 0x8A, 0xB0, + 0x0A, 0xD1, 0xA2, 0x64, 0x7D, 0x99, 0x03, 0x87 + }, + { + 0xFE, 0x89, 0x42, 0xA3, 0xE5, 0xF5, 0xE8, 0xCD, + 0x70, 0x51, 0x04, 0xF8, 0x82, 0x10, 0x72, 0x6E, + 0x53, 0xDD, 0x7E, 0xB3, 0xF9, 0xA2, 0x02, 0xBF, + 0x93, 0x14, 0xB3, 0xB9, 0x06, 0x5E, 0xB7, 0x12 + }, + { + 0xDC, 0x29, 0x53, 0x59, 0xD4, 0x36, 0xEE, 0xA7, + 0x80, 0x84, 0xE7, 0xB0, 0x77, 0xFE, 0x09, 0xB1, + 0x9C, 0x5B, 0xF3, 0xD2, 0xA7, 0x96, 0xDA, 0xB0, + 0x19, 0xE4, 0x20, 0x05, 0x99, 0xFD, 0x82, 0x02 + }, + { + 0x70, 0xB3, 0xF7, 0x2F, 0x74, 0x90, 0x32, 0xE2, + 0x5E, 0x38, 0x3B, 0x96, 0x43, 0x78, 0xEA, 0x1C, + 0x54, 0x3E, 0x9C, 0x15, 0xDE, 0x3A, 0x27, 0xD8, + 0x6D, 0x2A, 0x9D, 0x22, 0x31, 0xEF, 0xF4, 0x8A + }, + { + 0x79, 0x82, 0xB5, 0x4C, 0x08, 0xDB, 0x2B, 0xFB, + 0x6F, 0x45, 0xF3, 0x5B, 0xC3, 0x23, 0xBC, 0x09, + 0x37, 0x79, 0xB6, 0xBB, 0x0E, 0x3E, 0xEA, 0x3E, + 0x8C, 0x98, 0xB1, 0xDE, 0x99, 0xD3, 0xC5, 0x5E + }, + { + 0x75, 0xE4, 0x16, 0x22, 0x57, 0x01, 0x4B, 0xED, + 0xCC, 0x05, 0xC2, 0x94, 0x4D, 0xCE, 0x0D, 0xF0, + 0xC3, 0x5E, 0xBA, 0x13, 0x19, 0x54, 0x06, 0x4F, + 0x6E, 0x4E, 0x09, 0x5F, 0xD0, 0x84, 0x45, 0xEE + }, + { + 0x4A, 0x12, 0x9E, 0xA6, 0xCD, 0xBA, 0xBC, 0x2D, + 0x39, 0x24, 0x79, 0x37, 0x2F, 0x97, 0x5B, 0x9C, + 0xF5, 0xA1, 0xB7, 0xDE, 0xB6, 0x9A, 0x32, 0x66, + 0xF0, 0x3E, 0xBC, 0x6D, 0x11, 0x13, 0x93, 0xC4 + }, + { + 0x8F, 0xED, 0x70, 0xF2, 0x79, 0x55, 0xDC, 0x8A, + 0xD9, 0xF1, 0xB7, 0xB3, 0xF6, 0xF5, 0xDF, 0xBD, + 0x96, 0x2A, 0x33, 0x59, 0x2B, 0x42, 0xDE, 0x85, + 0x6D, 0x42, 0x1E, 0x29, 0x12, 0xBA, 0xB8, 0x6B + }, + { + 0xE2, 0xF2, 0x06, 0x60, 0x37, 0x6F, 0x2B, 0x18, + 0x39, 0x66, 0x7C, 0xBF, 0xE5, 0xE1, 0x6E, 0xF0, + 0x75, 0xAC, 0x39, 0x43, 0x64, 0x4F, 0x35, 0x32, + 0x28, 0x2F, 0x8B, 0xB0, 0x72, 0x3B, 0x99, 0x86 + }, + { + 0xAB, 0xF8, 0x4C, 0x91, 0x3A, 0x83, 0xDF, 0x98, + 0xC7, 0x00, 0x29, 0x81, 0x9C, 0x06, 0x5F, 0x6D, + 0x6D, 0xE4, 0xF6, 0xD4, 0x3A, 0xBF, 0x60, 0x0D, + 0xAD, 0xE0, 0x35, 0xB2, 0x3B, 0xED, 0x7B, 0xAA + }, + { + 0x45, 0x9C, 0x15, 0xD4, 0x85, 0x6C, 0x7E, 0xCF, + 0x82, 0x62, 0x03, 0x51, 0xC3, 0xC1, 0xC7, 0x6C, + 0x40, 0x3F, 0x3E, 0x97, 0x07, 0x74, 0x13, 0x87, + 0xE2, 0x99, 0x07, 0x3F, 0xB1, 0x70, 0x4B, 0x2B + }, + { + 0x9A, 0xB9, 0x12, 0xED, 0xA0, 0x76, 0x8A, 0xBD, + 0xF8, 0x26, 0xB6, 0xE0, 0x5D, 0x0D, 0x73, 0x58, + 0x39, 0xE6, 0xA5, 0xF0, 0x2E, 0x04, 0xC4, 0xCC, + 0x75, 0x65, 0x0B, 0x2C, 0x8C, 0xAB, 0x67, 0x49 + }, + { + 0x47, 0x40, 0xEB, 0xEC, 0xAC, 0x90, 0x03, 0x1B, + 0xB7, 0xE6, 0x8E, 0x51, 0xC5, 0x53, 0x91, 0xAF, + 0xB1, 0x89, 0xB3, 0x17, 0xF2, 0xDE, 0x55, 0x87, + 0x66, 0xF7, 0x8F, 0x5C, 0xB7, 0x1F, 0x81, 0xB6 + }, + { + 0x3C, 0xC4, 0x7F, 0x0E, 0xF6, 0x48, 0x21, 0x58, + 0x7C, 0x93, 0x7C, 0xDD, 0xBA, 0x85, 0xC9, 0x93, + 0xD3, 0xCE, 0x2D, 0xD0, 0xCE, 0xD4, 0x0D, 0x3B, + 0xE3, 0x3C, 0xB7, 0xDC, 0x7E, 0xDA, 0xBC, 0xF1 + }, + { + 0x9F, 0x47, 0x6A, 0x22, 0xDB, 0x54, 0xD6, 0xBB, + 0x9B, 0xEF, 0xDB, 0x26, 0x0C, 0x66, 0x57, 0x8A, + 0xE1, 0xD8, 0xA5, 0xF8, 0x7D, 0x3D, 0x8C, 0x01, + 0x7F, 0xDB, 0x74, 0x75, 0x08, 0x0F, 0xA8, 0xE1 + }, + { + 0x8B, 0x68, 0xC6, 0xFB, 0x07, 0x06, 0xA7, 0x95, + 0xF3, 0xA8, 0x39, 0xD6, 0xFE, 0x25, 0xFD, 0x4A, + 0xA7, 0xF9, 0x2E, 0x66, 0x4F, 0x76, 0x2D, 0x61, + 0x53, 0x81, 0xBC, 0x85, 0x9A, 0xFA, 0x29, 0x2C + }, + { + 0xF6, 0x40, 0xD2, 0x25, 0xA6, 0xBC, 0xD2, 0xFC, + 0x8A, 0xCC, 0xAF, 0xBE, 0xD5, 0xA8, 0x4B, 0x5B, + 0xBB, 0x5D, 0x8A, 0xE5, 0xDB, 0x06, 0xA1, 0x0B, + 0x6D, 0x9D, 0x93, 0x16, 0x0B, 0x39, 0x2E, 0xE0 + }, + { + 0x70, 0x48, 0x60, 0xA7, 0xF5, 0xBA, 0x68, 0xDB, + 0x27, 0x03, 0x1C, 0x15, 0xF2, 0x25, 0x50, 0x0D, + 0x69, 0x2A, 0xB2, 0x47, 0x53, 0x42, 0x81, 0xC4, + 0xF6, 0x84, 0xF6, 0xC6, 0xC8, 0xCD, 0x88, 0xC7 + }, + { + 0xC1, 0xA7, 0x5B, 0xDD, 0xA1, 0x2B, 0x8B, 0x2A, + 0xB1, 0xB9, 0x24, 0x84, 0x38, 0x58, 0x18, 0x3A, + 0x09, 0xD2, 0x02, 0x42, 0x1F, 0xDB, 0xCD, 0xF0, + 0xE6, 0x3E, 0xAE, 0x46, 0xF3, 0x7D, 0x91, 0xED + }, + { + 0x9A, 0x8C, 0xAB, 0x7A, 0x5F, 0x2E, 0x57, 0x62, + 0x21, 0xA6, 0xA8, 0x5E, 0x5F, 0xDD, 0xEE, 0x75, + 0x67, 0x8E, 0x06, 0x53, 0x24, 0xA6, 0x1D, 0xB0, + 0x3A, 0x39, 0x26, 0x1D, 0xDF, 0x75, 0xE3, 0xF4 + }, + { + 0x05, 0xC2, 0xB2, 0x6B, 0x03, 0xCE, 0x6C, 0xA5, + 0x87, 0x1B, 0xE0, 0xDE, 0x84, 0xEE, 0x27, 0x86, + 0xA7, 0x9B, 0xCD, 0x9F, 0x30, 0x03, 0x3E, 0x81, + 0x9B, 0x4A, 0x87, 0xCC, 0xA2, 0x7A, 0xFC, 0x6A + }, + { + 0xB0, 0xB0, 0x99, 0x3C, 0x6D, 0x0C, 0x6E, 0xD5, + 0xC3, 0x59, 0x04, 0x80, 0xF8, 0x65, 0xF4, 0x67, + 0xF4, 0x33, 0x1A, 0x58, 0xDD, 0x8E, 0x47, 0xBD, + 0x98, 0xEB, 0xBC, 0xDB, 0x8E, 0xB4, 0xF9, 0x4D + }, + { + 0xE5, 0x7C, 0x10, 0x3C, 0xF7, 0xB6, 0xBB, 0xEB, + 0x8A, 0x0D, 0xC8, 0xF0, 0x48, 0x62, 0x5C, 0x3F, + 0x4C, 0xE4, 0xF1, 0xA5, 0xAD, 0x4D, 0x07, 0x9C, + 0x11, 0x87, 0xBF, 0xE9, 0xEE, 0x3B, 0x8A, 0x5F + }, + { + 0xF1, 0x00, 0x23, 0xE1, 0x5F, 0x3B, 0x72, 0xB7, + 0x38, 0xAD, 0x61, 0xAE, 0x65, 0xAB, 0x9A, 0x07, + 0xE7, 0x77, 0x4E, 0x2D, 0x7A, 0xB0, 0x2D, 0xBA, + 0x4E, 0x0C, 0xAF, 0x56, 0x02, 0xC8, 0x01, 0x78 + }, + { + 0x9A, 0x8F, 0xB3, 0xB5, 0x38, 0xC1, 0xD6, 0xC4, + 0x50, 0x51, 0xFA, 0x9E, 0xD9, 0xB0, 0x7D, 0x3E, + 0x89, 0xB4, 0x43, 0x03, 0x30, 0x01, 0x4A, 0x1E, + 0xFA, 0x28, 0x23, 0xC0, 0x82, 0x3C, 0xF2, 0x37 + }, + { + 0x30, 0x75, 0xC5, 0xBC, 0x7C, 0x3A, 0xD7, 0xE3, + 0x92, 0x01, 0x01, 0xBC, 0x68, 0x99, 0xC5, 0x8E, + 0xA7, 0x01, 0x67, 0xA7, 0x77, 0x2C, 0xA2, 0x8E, + 0x38, 0xE2, 0xC1, 0xB0, 0xD3, 0x25, 0xE5, 0xA0 + }, + { + 0xE8, 0x55, 0x94, 0x70, 0x0E, 0x39, 0x22, 0xA1, + 0xE8, 0xE4, 0x1E, 0xB8, 0xB0, 0x64, 0xE7, 0xAC, + 0x6D, 0x94, 0x9D, 0x13, 0xB5, 0xA3, 0x45, 0x23, + 0xE5, 0xA6, 0xBE, 0xAC, 0x03, 0xC8, 0xAB, 0x29 + }, + { + 0x1D, 0x37, 0x01, 0xA5, 0x66, 0x1B, 0xD3, 0x1A, + 0xB2, 0x05, 0x62, 0xBD, 0x07, 0xB7, 0x4D, 0xD1, + 0x9A, 0xC8, 0xF3, 0x52, 0x4B, 0x73, 0xCE, 0x7B, + 0xC9, 0x96, 0xB7, 0x88, 0xAF, 0xD2, 0xF3, 0x17 + }, + { + 0x87, 0x4E, 0x19, 0x38, 0x03, 0x3D, 0x7D, 0x38, + 0x35, 0x97, 0xA2, 0xA6, 0x5F, 0x58, 0xB5, 0x54, + 0xE4, 0x11, 0x06, 0xF6, 0xD1, 0xD5, 0x0E, 0x9B, + 0xA0, 0xEB, 0x68, 0x5F, 0x6B, 0x6D, 0xA0, 0x71 + }, + { + 0x93, 0xF2, 0xF3, 0xD6, 0x9B, 0x2D, 0x36, 0x52, + 0x95, 0x56, 0xEC, 0xCA, 0xF9, 0xF9, 0x9A, 0xDB, + 0xE8, 0x95, 0xE1, 0x57, 0x22, 0x31, 0xE6, 0x49, + 0xB5, 0x05, 0x84, 0xB5, 0xD7, 0xD0, 0x8A, 0xF8 + }, + { + 0x06, 0xE0, 0x6D, 0x61, 0x0F, 0x2E, 0xEB, 0xBA, + 0x36, 0x76, 0x82, 0x3E, 0x77, 0x44, 0xD7, 0x51, + 0xAF, 0xF7, 0x30, 0x76, 0xED, 0x65, 0xF3, 0xCF, + 0xF5, 0xE7, 0x2F, 0xD2, 0x27, 0x99, 0x9C, 0x77 + }, + { + 0x8D, 0xF7, 0x57, 0xB3, 0xA1, 0xE0, 0xF4, 0x80, + 0xFA, 0x76, 0xC7, 0xF3, 0x58, 0xED, 0x03, 0x98, + 0xBE, 0x3F, 0x2A, 0x8F, 0x7B, 0x90, 0xEA, 0x8C, + 0x80, 0x75, 0x99, 0xDE, 0xDA, 0x1D, 0x05, 0x34 + }, + { + 0xEE, 0xC9, 0xC5, 0xC6, 0x3C, 0xC5, 0x16, 0x9D, + 0x96, 0x7B, 0xB1, 0x62, 0x4E, 0x9E, 0xE5, 0xCE, + 0xD9, 0x28, 0x97, 0x73, 0x6E, 0xFB, 0xD1, 0x57, + 0x54, 0x8D, 0x82, 0xE8, 0x7C, 0xC7, 0x2F, 0x25 + }, + { + 0xCC, 0x2B, 0x58, 0x32, 0xAD, 0x27, 0x2C, 0xC5, + 0x5C, 0x10, 0xD4, 0xF8, 0xC7, 0xF8, 0xBB, 0x38, + 0xE6, 0xE4, 0xEB, 0x92, 0x2F, 0x93, 0x86, 0x83, + 0x0F, 0x90, 0xB1, 0xE3, 0xDA, 0x39, 0x37, 0xD5 + }, + { + 0x36, 0x89, 0x85, 0xD5, 0x38, 0x7C, 0x0B, 0xFC, + 0x92, 0x8A, 0xC2, 0x54, 0xFA, 0x6D, 0x16, 0x67, + 0x3E, 0x70, 0x94, 0x75, 0x66, 0x96, 0x1B, 0x5F, + 0xB3, 0x32, 0x5A, 0x58, 0x8A, 0xB3, 0x17, 0x3A + }, + { + 0xF1, 0xE4, 0x42, 0xAF, 0xB8, 0x72, 0x15, 0x1F, + 0x81, 0x34, 0x95, 0x6C, 0x54, 0x8A, 0xE3, 0x24, + 0x0D, 0x07, 0xE6, 0xE3, 0x38, 0xD4, 0xA7, 0xA6, + 0xAF, 0x8D, 0xA4, 0x11, 0x9A, 0xB0, 0xE2, 0xB0 + }, + { + 0xB0, 0x12, 0xC7, 0x54, 0x6A, 0x39, 0xC4, 0x0C, + 0xAD, 0xEC, 0xE4, 0xE0, 0x4E, 0x7F, 0x33, 0xC5, + 0x93, 0xAD, 0x18, 0x2E, 0xBC, 0x5A, 0x46, 0xD2, + 0xDB, 0xF4, 0xAD, 0x1A, 0x92, 0xF5, 0x9E, 0x7B + }, + { + 0x6C, 0x60, 0x97, 0xCD, 0x20, 0x33, 0x09, 0x6B, + 0x4D, 0xF3, 0x17, 0xDE, 0x8A, 0x90, 0x8B, 0x7D, + 0x0C, 0x72, 0x94, 0x39, 0x0C, 0x5A, 0x39, 0x9C, + 0x30, 0x1B, 0xF2, 0xA2, 0x65, 0x2E, 0x82, 0x62 + }, + { + 0xBA, 0x83, 0xFE, 0xB5, 0x10, 0xB4, 0x9A, 0xDE, + 0x4F, 0xAE, 0xFB, 0xE9, 0x42, 0x78, 0x1E, 0xAF, + 0xD4, 0x1A, 0xD5, 0xD4, 0x36, 0x88, 0x85, 0x31, + 0xB6, 0x88, 0x59, 0xF2, 0x2C, 0x2D, 0x16, 0x4A + }, + { + 0x5A, 0x06, 0x9E, 0x43, 0x92, 0x19, 0x5A, 0xC9, + 0xD2, 0x84, 0xA4, 0x7F, 0x3B, 0xD8, 0x54, 0xAF, + 0x8F, 0xD0, 0xD7, 0xFD, 0xC3, 0x48, 0x3D, 0x2C, + 0x5F, 0x34, 0x24, 0xCC, 0xFD, 0xA1, 0x5C, 0x8E + }, + { + 0x7E, 0x88, 0xD6, 0x4B, 0xBB, 0xE2, 0x02, 0x4F, + 0x44, 0x54, 0xBA, 0x13, 0x98, 0xB3, 0xD8, 0x65, + 0x2D, 0xCE, 0xC8, 0x20, 0xB1, 0x4C, 0x3B, 0x0A, + 0xBF, 0xBF, 0x0F, 0x4F, 0x33, 0x06, 0xBB, 0x5E + }, + { + 0xF8, 0x74, 0x2F, 0xF4, 0x6D, 0xFD, 0xF3, 0xEC, + 0x82, 0x64, 0xF9, 0x94, 0x5B, 0x20, 0x41, 0x94, + 0x62, 0xF0, 0x69, 0xE8, 0x33, 0xC5, 0x94, 0xEC, + 0x80, 0xFF, 0xAC, 0x5E, 0x7E, 0x51, 0x34, 0xF9 + }, + { + 0xD3, 0xE0, 0xB7, 0x38, 0xD2, 0xE9, 0x2F, 0x3C, + 0x47, 0xC7, 0x94, 0x66, 0x66, 0x09, 0xC0, 0xF5, + 0x50, 0x4F, 0x67, 0xEC, 0x4E, 0x76, 0x0E, 0xEE, + 0xCC, 0xF8, 0x64, 0x4E, 0x68, 0x33, 0x34, 0x11 + }, + { + 0x0C, 0x90, 0xCE, 0x10, 0xED, 0xF0, 0xCE, 0x1D, + 0x47, 0xEE, 0xB5, 0x0B, 0x5B, 0x7A, 0xFF, 0x8E, + 0xE8, 0xA4, 0x3B, 0x64, 0xA8, 0x89, 0xC1, 0xC6, + 0xC6, 0xB8, 0xE3, 0x1A, 0x3C, 0xFC, 0x45, 0xEE + }, + { + 0x83, 0x91, 0x7A, 0xC1, 0xCD, 0xAD, 0xE8, 0xF0, + 0xE3, 0xBF, 0x42, 0x6F, 0xEA, 0xC1, 0x38, 0x8B, + 0x3F, 0xCB, 0xE3, 0xE1, 0xBF, 0x98, 0x79, 0x8C, + 0x81, 0x58, 0xBF, 0x75, 0x8E, 0x8D, 0x5D, 0x4E + }, + { + 0xDC, 0x8E, 0xB0, 0xC0, 0x13, 0xFA, 0x9D, 0x06, + 0x4E, 0xE3, 0x76, 0x23, 0x36, 0x9F, 0xB3, 0x94, + 0xAF, 0x97, 0x4B, 0x1A, 0xAC, 0x82, 0x40, 0x5B, + 0x88, 0x97, 0x6C, 0xD8, 0xFC, 0xA1, 0x25, 0x30 + }, + { + 0x9A, 0xF4, 0xFC, 0x92, 0xEA, 0x8D, 0x6B, 0x5F, + 0xE7, 0x99, 0x0E, 0x3A, 0x02, 0x70, 0x1E, 0xC2, + 0x2B, 0x2D, 0xFD, 0x71, 0x00, 0xB9, 0x0D, 0x05, + 0x51, 0x86, 0x94, 0x17, 0x95, 0x5E, 0x44, 0xC8 + }, + { + 0xC7, 0x22, 0xCE, 0xC1, 0x31, 0xBA, 0xA1, 0x63, + 0xF4, 0x7E, 0x4B, 0x33, 0x9E, 0x1F, 0xB9, 0xB4, + 0xAC, 0xA2, 0x48, 0xC4, 0x75, 0x93, 0x45, 0xEA, + 0xDB, 0xD6, 0xC6, 0xA7, 0xDD, 0xB5, 0x04, 0x77 + }, + { + 0x18, 0x37, 0xB1, 0x20, 0xD4, 0xE4, 0x04, 0x6C, + 0x6D, 0xE8, 0xCC, 0xAF, 0x09, 0xF1, 0xCA, 0xF3, + 0x02, 0xAD, 0x56, 0x23, 0x4E, 0x6B, 0x42, 0x2C, + 0xE9, 0x0A, 0x61, 0xBF, 0x06, 0xAE, 0xE4, 0x3D + }, + { + 0x87, 0xAC, 0x9D, 0x0F, 0x8A, 0x0B, 0x11, 0xBF, + 0xED, 0xD6, 0x99, 0x1A, 0x6D, 0xAF, 0x34, 0xC8, + 0xAA, 0x5D, 0x7E, 0x8A, 0xE1, 0xB9, 0xDF, 0x4A, + 0xF7, 0x38, 0x00, 0x5F, 0xE7, 0x8C, 0xE9, 0x3C + }, + { + 0xE2, 0x1F, 0xB6, 0x68, 0xEB, 0xB8, 0xBF, 0x2D, + 0x82, 0x08, 0x6D, 0xED, 0xCB, 0x3A, 0x53, 0x71, + 0xC2, 0xC4, 0x6F, 0xA1, 0xAC, 0x11, 0xD2, 0xE2, + 0xC5, 0x66, 0xD1, 0x4A, 0xD3, 0xC3, 0x65, 0x3F + }, + { + 0x5A, 0x9A, 0x69, 0x81, 0x5E, 0x4D, 0x3E, 0xB7, + 0x72, 0xED, 0x90, 0x8F, 0xE6, 0x58, 0xCE, 0x50, + 0x87, 0x31, 0x0E, 0xC1, 0xD5, 0x0C, 0xB9, 0x4F, + 0x56, 0x28, 0x33, 0x9A, 0x61, 0xDC, 0xD9, 0xEE + }, + { + 0xAA, 0xC2, 0x85, 0xF1, 0x20, 0x8F, 0x70, 0xA6, + 0x47, 0x97, 0xD0, 0xA9, 0x40, 0x0D, 0xA6, 0x46, + 0x53, 0x30, 0x18, 0x38, 0xFE, 0xF6, 0x69, 0x0B, + 0x87, 0xCD, 0xA9, 0x15, 0x9E, 0xE0, 0x7E, 0xF4 + }, + { + 0x05, 0x64, 0x3C, 0x1C, 0x6F, 0x26, 0x59, 0x25, + 0xA6, 0x50, 0x93, 0xF9, 0xDE, 0x8A, 0x19, 0x1C, + 0x4F, 0x6F, 0xD1, 0x41, 0x8F, 0xBF, 0x66, 0xBE, + 0x80, 0x59, 0xA9, 0x1B, 0xA8, 0xDC, 0xDA, 0x61 + }, + { + 0x1C, 0x6C, 0xDE, 0x5B, 0x78, 0x10, 0x3C, 0x9E, + 0x6F, 0x04, 0x6D, 0xFE, 0x30, 0xF5, 0x12, 0x1C, + 0xF9, 0xD4, 0x03, 0x9E, 0xFE, 0x22, 0x25, 0x40, + 0xA4, 0x1B, 0xBC, 0x06, 0xE4, 0x69, 0xFE, 0xB6 + }, + { + 0xB4, 0x9B, 0xB4, 0x6D, 0x1B, 0x19, 0x3B, 0x04, + 0x5E, 0x74, 0x12, 0x05, 0x9F, 0xE7, 0x2D, 0x55, + 0x25, 0x52, 0xA8, 0xFB, 0x6C, 0x36, 0x41, 0x07, + 0x23, 0xDC, 0x7D, 0x05, 0xFC, 0xCE, 0xDE, 0xD3 + }, + { + 0xB6, 0x12, 0xD3, 0xD2, 0x1F, 0xC4, 0xDE, 0x3C, + 0x79, 0x1A, 0xF7, 0x35, 0xE5, 0x9F, 0xB7, 0x17, + 0xD8, 0x39, 0x72, 0x3B, 0x42, 0x50, 0x8E, 0x9E, + 0xBF, 0x78, 0x06, 0xD9, 0x3E, 0x9C, 0x83, 0x7F + }, + { + 0x7C, 0x33, 0x90, 0xA3, 0xE5, 0xCB, 0x27, 0xD1, + 0x86, 0x8B, 0xA4, 0x55, 0xCF, 0xEB, 0x32, 0x22, + 0xFD, 0xE2, 0x7B, 0xCD, 0xA4, 0xBF, 0x24, 0x8E, + 0x3D, 0x29, 0xCF, 0x1F, 0x34, 0x32, 0x9F, 0x25 + }, + { + 0xBD, 0x42, 0xEE, 0xA7, 0xB3, 0x54, 0x86, 0xCD, + 0xD0, 0x90, 0x7C, 0xB4, 0x71, 0x2E, 0xDE, 0x2F, + 0x4D, 0xEE, 0xCC, 0xBC, 0xA1, 0x91, 0x60, 0x38, + 0x65, 0xA1, 0xCC, 0x80, 0x9F, 0x12, 0xB4, 0x46 + }, + { + 0xD1, 0xDD, 0x62, 0x01, 0x74, 0x0C, 0xFA, 0xAD, + 0x53, 0xCE, 0xCC, 0xB7, 0x56, 0xB1, 0x10, 0xF3, + 0xD5, 0x0F, 0x81, 0x7B, 0x43, 0xD7, 0x55, 0x95, + 0x57, 0xE5, 0x7A, 0xAD, 0x14, 0x3A, 0x85, 0xD9 + }, + { + 0x58, 0x29, 0x64, 0x3C, 0x1B, 0x10, 0xE1, 0xC8, + 0xCC, 0xF2, 0x0C, 0x9B, 0x4A, 0xF8, 0x21, 0xEA, + 0x05, 0x2D, 0x7F, 0x0F, 0x7C, 0x22, 0xF7, 0x38, + 0x0B, 0xBB, 0xCF, 0xAF, 0xB9, 0x77, 0xE2, 0x1F + }, + { + 0xFC, 0x4C, 0xF2, 0xA7, 0xFB, 0xE0, 0xB1, 0xE8, + 0xAE, 0xFB, 0xE4, 0xB4, 0xB7, 0x9E, 0xD8, 0x4E, + 0xC9, 0x7B, 0x03, 0x4F, 0x51, 0xB4, 0xE9, 0x7F, + 0x76, 0x0B, 0x20, 0x63, 0x97, 0x65, 0xB9, 0x33 + }, + { + 0x4D, 0x7C, 0x3B, 0x34, 0x38, 0xA0, 0xBD, 0xA2, + 0x8E, 0x7A, 0x96, 0xE4, 0x20, 0x27, 0xD8, 0x13, + 0xE8, 0x8A, 0xE6, 0x28, 0x85, 0x49, 0x98, 0x33, + 0xD3, 0xC5, 0xF6, 0x35, 0x9E, 0xF7, 0xED, 0xBC + }, + { + 0x34, 0xCB, 0xD3, 0x20, 0x68, 0xEF, 0x7E, 0x82, + 0x09, 0x9E, 0x58, 0x0B, 0xF9, 0xE2, 0x64, 0x23, + 0xE9, 0x81, 0xE3, 0x1B, 0x1B, 0xBC, 0xE6, 0x1A, + 0xEA, 0xB1, 0x4C, 0x32, 0xA2, 0x73, 0xE4, 0xCB + }, + { + 0xA0, 0x5D, 0xDA, 0x7D, 0x0D, 0xA9, 0xE0, 0x94, + 0xAE, 0x22, 0x53, 0x3F, 0x79, 0xE7, 0xDC, 0xCD, + 0x26, 0xB1, 0x75, 0x7C, 0xEF, 0xB9, 0x5B, 0xCF, + 0x62, 0xC4, 0xFF, 0x9C, 0x26, 0x92, 0xE1, 0xC0 + }, + { + 0x22, 0x4C, 0xCF, 0xFA, 0x7C, 0xCA, 0x4C, 0xE3, + 0x4A, 0xFD, 0x47, 0xF6, 0x2A, 0xDE, 0x53, 0xC5, + 0xE8, 0x48, 0x9B, 0x04, 0xAC, 0x9C, 0x41, 0xF7, + 0xFA, 0xD0, 0xC8, 0xED, 0xEB, 0x89, 0xE9, 0x41 + }, + { + 0x6B, 0xC6, 0x07, 0x64, 0x83, 0xAA, 0x11, 0xC0, + 0x7F, 0xBA, 0x55, 0xC0, 0xF9, 0xA1, 0xB5, 0xDA, + 0x87, 0xEC, 0xBF, 0xFE, 0xA7, 0x55, 0x98, 0xCC, + 0x31, 0x8A, 0x51, 0x4C, 0xEC, 0x7B, 0x3B, 0x6A + }, + { + 0x9A, 0x03, 0x60, 0xE2, 0x3A, 0x22, 0xF4, 0xF7, + 0x6C, 0x0E, 0x95, 0x28, 0xDA, 0xFD, 0x12, 0x9B, + 0xB4, 0x67, 0x5F, 0xB8, 0x8D, 0x44, 0xEA, 0xF8, + 0x57, 0x77, 0x30, 0x0C, 0xEC, 0x9B, 0xCC, 0x79 + }, + { + 0x79, 0x01, 0x99, 0xB4, 0xCA, 0x90, 0xDE, 0xDC, + 0xCF, 0xE3, 0x24, 0x74, 0xE8, 0x5B, 0x17, 0x4F, + 0x06, 0x9E, 0x35, 0x42, 0xBE, 0x31, 0x04, 0xC1, + 0x12, 0x5C, 0x2F, 0xDB, 0xD6, 0x9D, 0x32, 0xC7 + }, + { + 0x55, 0x83, 0x99, 0x25, 0x83, 0x4C, 0xA3, 0xE8, + 0x25, 0xE9, 0x92, 0x41, 0x87, 0x4D, 0x16, 0xD6, + 0xC2, 0x62, 0x36, 0x29, 0xC4, 0xC2, 0xAD, 0xDD, + 0xF0, 0xDB, 0xA0, 0x1E, 0x6C, 0xE8, 0xA0, 0xDC + }, + { + 0x61, 0x5F, 0xF8, 0x46, 0xD9, 0x93, 0x00, 0x7D, + 0x38, 0xDE, 0x1A, 0xEC, 0xB3, 0x17, 0x82, 0x89, + 0xDE, 0xD0, 0x9E, 0x6B, 0xB5, 0xCB, 0xD6, 0x0F, + 0x69, 0xC6, 0xAA, 0x36, 0x38, 0x30, 0x20, 0xF7 + }, + { + 0xF0, 0xE4, 0x0B, 0x4E, 0xD4, 0x0D, 0x34, 0x85, + 0x1E, 0x72, 0xB4, 0xEE, 0x4D, 0x00, 0xEA, 0x6A, + 0x40, 0xEA, 0x1C, 0x1B, 0xF9, 0xE5, 0xC2, 0x69, + 0x71, 0x0C, 0x9D, 0x51, 0xCB, 0xB8, 0xA3, 0xC9 + }, + { + 0x0B, 0x07, 0xB2, 0x33, 0x3B, 0x08, 0xD0, 0x8C, + 0x11, 0xCA, 0x34, 0xAB, 0x44, 0x9B, 0x71, 0xD2, + 0x9A, 0x0F, 0x43, 0xE1, 0xF7, 0x78, 0xE0, 0x73, + 0xE7, 0x90, 0x06, 0xCC, 0xB7, 0x30, 0xED, 0x62 + }, + { + 0xD1, 0xF4, 0xC2, 0x9D, 0x9F, 0x23, 0xEA, 0x35, + 0xEC, 0x40, 0x35, 0xB3, 0x77, 0xD5, 0x06, 0x53, + 0x8E, 0x72, 0x8B, 0xC7, 0x39, 0xC1, 0x45, 0x96, + 0x80, 0xCF, 0x1C, 0xC6, 0x94, 0x24, 0x92, 0x4D + }, + { + 0x12, 0x79, 0xCF, 0x6F, 0x66, 0x9F, 0x92, 0xF6, + 0xBF, 0xC2, 0x5D, 0x60, 0x5B, 0x94, 0x40, 0xC7, + 0xDC, 0xCB, 0xD2, 0x5D, 0xF2, 0x8D, 0xC7, 0x35, + 0x3A, 0xBC, 0x1C, 0x05, 0x30, 0x40, 0x5D, 0xC4 + }, + { + 0x1F, 0xA0, 0xAF, 0x00, 0x77, 0x5D, 0xC2, 0xCE, + 0x76, 0x50, 0x6D, 0x32, 0x80, 0xF4, 0x72, 0xD2, + 0xF6, 0xFF, 0x97, 0xA2, 0x15, 0x1F, 0xAA, 0x82, + 0x79, 0x42, 0xFE, 0xA4, 0x4A, 0xD0, 0xBA, 0x1F + }, + { + 0x3E, 0x1A, 0xD5, 0x4A, 0x5F, 0x83, 0x5B, 0x98, + 0x3B, 0xD2, 0xAA, 0xB0, 0xED, 0x2A, 0x4C, 0x0B, + 0xDD, 0x72, 0x16, 0x20, 0x9C, 0x36, 0xA7, 0x9E, + 0x9E, 0x2A, 0xAB, 0xB9, 0x9F, 0xAF, 0x35, 0x12 + }, + { + 0xC6, 0xED, 0x39, 0xE2, 0xD8, 0xB6, 0x36, 0xEC, + 0xCB, 0xA2, 0x45, 0xEF, 0x4E, 0x88, 0x64, 0xF4, + 0xCD, 0x94, 0x6B, 0xE2, 0x16, 0xB9, 0xBE, 0x48, + 0x30, 0x3E, 0x08, 0xB9, 0x2D, 0xD0, 0x94, 0x34 + }, + { + 0xE2, 0x47, 0x36, 0xC1, 0x3E, 0xCB, 0x9F, 0x36, + 0xA0, 0xD8, 0x29, 0xD4, 0x79, 0x8D, 0x76, 0x99, + 0xC1, 0x4C, 0xC6, 0x5B, 0x6D, 0xC4, 0x4E, 0xD6, + 0xF1, 0x0C, 0xD4, 0x85, 0x3D, 0x6E, 0x07, 0x57 + }, + { + 0x38, 0x9B, 0xE8, 0x80, 0x52, 0xA3, 0x81, 0x27, + 0x2C, 0x6D, 0xF7, 0x41, 0xA8, 0x8A, 0xD3, 0x49, + 0xB7, 0x12, 0x71, 0x84, 0x35, 0x48, 0x0A, 0x81, + 0x90, 0xB7, 0x04, 0x77, 0x1D, 0x2D, 0xE6, 0x37 + }, + { + 0x88, 0x9F, 0x2D, 0x57, 0x8A, 0x5D, 0xAE, 0xFD, + 0x34, 0x1C, 0x21, 0x09, 0x84, 0xE1, 0x26, 0xD1, + 0xD9, 0x6D, 0xA2, 0xDE, 0xE3, 0xC8, 0x1F, 0x7A, + 0x60, 0x80, 0xBF, 0x84, 0x56, 0x9B, 0x31, 0x14 + }, + { + 0xE9, 0x36, 0x09, 0x5B, 0x9B, 0x98, 0x2F, 0xFC, + 0x85, 0x6D, 0x2F, 0x52, 0x76, 0xA4, 0xE5, 0x29, + 0xEC, 0x73, 0x95, 0xDA, 0x31, 0x6D, 0x62, 0x87, + 0x02, 0xFB, 0x28, 0x1A, 0xDA, 0x6F, 0x38, 0x99 + }, + { + 0xEF, 0x89, 0xCE, 0x1D, 0x6F, 0x8B, 0x48, 0xEA, + 0x5C, 0xD6, 0xAE, 0xAB, 0x6A, 0x83, 0xD0, 0xCC, + 0x98, 0xC9, 0xA3, 0xA2, 0x07, 0xA1, 0x08, 0x57, + 0x32, 0xF0, 0x47, 0xD9, 0x40, 0x38, 0xC2, 0x88 + }, + { + 0xF9, 0x25, 0x01, 0x6D, 0x79, 0xF2, 0xAC, 0xA8, + 0xC4, 0x9E, 0xDF, 0xCD, 0x66, 0x21, 0xD5, 0xBE, + 0x3C, 0x8C, 0xEC, 0x61, 0xBD, 0x58, 0x71, 0xD8, + 0xC1, 0xD3, 0xA5, 0x65, 0xF3, 0x5E, 0x0C, 0x9F + }, + { + 0x63, 0xE8, 0x63, 0x4B, 0x75, 0x7A, 0x38, 0xF9, + 0x2B, 0x92, 0xFD, 0x23, 0x89, 0x3B, 0xA2, 0x99, + 0x85, 0x3A, 0x86, 0x13, 0x67, 0x9F, 0xDF, 0x7E, + 0x05, 0x11, 0x09, 0x5C, 0x0F, 0x04, 0x7B, 0xCA + }, + { + 0xCF, 0x2C, 0xCA, 0x07, 0x72, 0xB7, 0x05, 0xEB, + 0x57, 0xD2, 0x89, 0x43, 0xF8, 0x3D, 0x35, 0x3F, + 0xE2, 0x91, 0xE5, 0xB3, 0x77, 0x78, 0x0B, 0x37, + 0x4C, 0x8B, 0xA4, 0x66, 0x58, 0x30, 0xBE, 0x87 + }, + { + 0x46, 0xDF, 0x5B, 0x87, 0xC8, 0x0E, 0x7E, 0x40, + 0x74, 0xAE, 0xE6, 0x85, 0x59, 0x42, 0x47, 0x42, + 0x84, 0x5B, 0x9B, 0x35, 0x0F, 0x51, 0xBA, 0x55, + 0xB0, 0x74, 0xBB, 0xAE, 0x4C, 0x62, 0x6A, 0xAB + }, + { + 0x65, 0x8A, 0xA4, 0xF9, 0xD2, 0xBC, 0xBD, 0x4F, + 0x7F, 0x8E, 0xB6, 0x3E, 0x68, 0xF5, 0x36, 0x7E, + 0xDB, 0xC5, 0x00, 0xA0, 0xB1, 0xFB, 0xB4, 0x1E, + 0x9D, 0xF1, 0x41, 0xBC, 0xBA, 0x8F, 0xCD, 0x53 + }, + { + 0xEE, 0x80, 0x55, 0x50, 0x08, 0xA7, 0x16, 0x55, + 0xE0, 0x81, 0x09, 0x2B, 0xBA, 0x6F, 0x67, 0x0E, + 0xD9, 0x8A, 0xF9, 0xA0, 0x9F, 0xB5, 0xAF, 0xB9, + 0x4C, 0xBC, 0x5C, 0x75, 0x48, 0x14, 0xDB, 0x4F + }, + { + 0x2C, 0x5F, 0x9D, 0x04, 0x82, 0x20, 0xB0, 0x41, + 0xB6, 0xD4, 0x52, 0x4B, 0x44, 0x90, 0xCF, 0x8C, + 0x66, 0xFC, 0xB8, 0xE1, 0x4B, 0x0D, 0x64, 0x88, + 0x7A, 0xA1, 0xE4, 0x76, 0x1A, 0x60, 0x2B, 0x39 + }, + { + 0x44, 0xCB, 0x63, 0x11, 0xD0, 0x75, 0x0B, 0x7E, + 0x33, 0xF7, 0x33, 0x3A, 0xA7, 0x8A, 0xAC, 0xA9, + 0xC3, 0x4A, 0xD5, 0xF7, 0x9C, 0x1B, 0x15, 0x91, + 0xEC, 0x33, 0x95, 0x1E, 0x69, 0xC4, 0xC4, 0x61 + }, + { + 0x0C, 0x6C, 0xE3, 0x2A, 0x3E, 0xA0, 0x56, 0x12, + 0xC5, 0xF8, 0x09, 0x0F, 0x6A, 0x7E, 0x87, 0xF5, + 0xAB, 0x30, 0xE4, 0x1B, 0x70, 0x7D, 0xCB, 0xE5, + 0x41, 0x55, 0x62, 0x0A, 0xD7, 0x70, 0xA3, 0x40 + }, + { + 0xC6, 0x59, 0x38, 0xDD, 0x3A, 0x05, 0x3C, 0x72, + 0x9C, 0xF5, 0xB7, 0xC8, 0x9F, 0x39, 0x0B, 0xFE, + 0xBB, 0x51, 0x12, 0x76, 0x6B, 0xB0, 0x0A, 0xA5, + 0xFA, 0x31, 0x64, 0xDF, 0xDF, 0x3B, 0x56, 0x47 + }, + { + 0x7D, 0xE7, 0xF0, 0xD5, 0x9A, 0x90, 0x39, 0xAF, + 0xF3, 0xAA, 0xF3, 0x2C, 0x3E, 0xE5, 0x2E, 0x79, + 0x17, 0x53, 0x57, 0x29, 0x06, 0x21, 0x68, 0xD2, + 0x49, 0x0B, 0x6B, 0x6C, 0xE2, 0x44, 0xB3, 0x80 + }, + { + 0x89, 0x58, 0x98, 0xF5, 0x3A, 0x8F, 0x39, 0xE4, + 0x24, 0x10, 0xDA, 0x77, 0xB6, 0xC4, 0x81, 0x5B, + 0x0B, 0xB2, 0x39, 0x5E, 0x39, 0x22, 0xF5, 0xBE, + 0xD0, 0xE1, 0xFB, 0xF2, 0xA4, 0xC6, 0xDF, 0xEB + }, + { + 0xC9, 0x05, 0xA8, 0x49, 0x84, 0x34, 0x8A, 0x64, + 0xDB, 0x1F, 0x54, 0x20, 0x83, 0x74, 0x8A, 0xD9, + 0x0A, 0x4B, 0xAD, 0x98, 0x33, 0xCB, 0x6D, 0xA3, + 0x87, 0x29, 0x34, 0x31, 0xF1, 0x9E, 0x7C, 0x9C + }, + { + 0xED, 0x37, 0xD1, 0xA4, 0xD0, 0x6C, 0x90, 0xD1, + 0x95, 0x78, 0x48, 0x66, 0x7E, 0x95, 0x48, 0xFE, + 0xBB, 0x5D, 0x42, 0x3E, 0xAB, 0x4F, 0x56, 0x78, + 0x5C, 0xC4, 0xB5, 0x41, 0x6B, 0x78, 0x00, 0x08 + }, + { + 0x0B, 0xC6, 0x5D, 0x99, 0x97, 0xFB, 0x73, 0x4A, + 0x56, 0x1F, 0xB1, 0xE9, 0xF8, 0xC0, 0x95, 0x8A, + 0x02, 0xC7, 0xA4, 0xDB, 0xD0, 0x96, 0xEB, 0xEF, + 0x1A, 0x17, 0x51, 0xAE, 0xD9, 0x59, 0xEE, 0xD7 + }, + { + 0x7C, 0x5F, 0x43, 0x2E, 0xB8, 0xB7, 0x35, 0x2A, + 0x94, 0x94, 0xDE, 0xA4, 0xD5, 0x3C, 0x21, 0x38, + 0x70, 0x31, 0xCE, 0x70, 0xE8, 0x5D, 0x94, 0x08, + 0xFC, 0x6F, 0x8C, 0xD9, 0x8A, 0x6A, 0xAA, 0x1E + }, + { + 0xB8, 0xBF, 0x8E, 0x2C, 0x34, 0xE0, 0x33, 0x98, + 0x36, 0x39, 0x90, 0x9E, 0xAA, 0x37, 0x64, 0x0D, + 0x87, 0x7B, 0x04, 0x8F, 0xE2, 0x99, 0xB4, 0x70, + 0xAF, 0x2D, 0x0B, 0xA8, 0x2A, 0x5F, 0x14, 0xC0 + }, + { + 0x88, 0xA9, 0xDD, 0x13, 0xD5, 0xDA, 0xDB, 0xDE, + 0xE6, 0xBF, 0xF7, 0xEE, 0x1E, 0xF8, 0xC7, 0x1C, + 0xC1, 0x93, 0xAA, 0x4B, 0xF3, 0xE8, 0x4F, 0x8F, + 0xE8, 0x0C, 0xB0, 0x75, 0x68, 0x3C, 0x07, 0x79 + }, + { + 0x9A, 0xED, 0xB8, 0x87, 0x6D, 0xD2, 0x1C, 0x8C, + 0x84, 0xD2, 0xE7, 0x02, 0xA1, 0x36, 0x25, 0x98, + 0x04, 0x62, 0xF6, 0x8B, 0xF0, 0xA1, 0xB7, 0x25, + 0x4A, 0xD8, 0x06, 0xC3, 0x84, 0x03, 0xC9, 0xDE + }, + { + 0xD0, 0x97, 0x57, 0x3D, 0xF2, 0xD6, 0xB2, 0x48, + 0x9A, 0x47, 0x94, 0x84, 0x86, 0x98, 0x00, 0xA1, + 0xF8, 0x33, 0xEA, 0x16, 0x9E, 0xFF, 0x32, 0xAE, + 0x3C, 0xE6, 0x3A, 0x20, 0x79, 0x54, 0x8D, 0x78 + }, + { + 0xD1, 0x8F, 0x27, 0xA3, 0xE5, 0x55, 0xD7, 0xF9, + 0x1A, 0x00, 0x7C, 0x67, 0xAC, 0xEE, 0xDE, 0x39, + 0x1F, 0x75, 0xA6, 0x1F, 0xA4, 0x2A, 0x0B, 0x45, + 0x66, 0xEB, 0x58, 0x2C, 0xA0, 0x5E, 0xBC, 0xE7 + }, + { + 0xDF, 0x1D, 0xAA, 0x90, 0xB1, 0x70, 0x23, 0x13, + 0xE6, 0xA5, 0x90, 0x1C, 0x7A, 0xFC, 0x5E, 0xD9, + 0x65, 0x77, 0x17, 0xA7, 0x15, 0xFA, 0x53, 0xA4, + 0x18, 0x9E, 0xC1, 0xE5, 0xDF, 0x29, 0x3A, 0x68 + }, + { + 0x04, 0xE3, 0xA4, 0x96, 0xB6, 0x69, 0x96, 0xC6, + 0x6E, 0x32, 0x91, 0x9E, 0xD1, 0xF9, 0x4C, 0x36, + 0xEE, 0xBB, 0xF2, 0x40, 0x63, 0x3A, 0x2F, 0x73, + 0x98, 0x45, 0xF0, 0x29, 0x5D, 0x34, 0xAF, 0xBA + }, + { + 0x8C, 0x45, 0xD8, 0x8C, 0x4E, 0x9C, 0x9D, 0x0C, + 0x8C, 0x67, 0x7F, 0xE4, 0x8F, 0xA5, 0x44, 0x9B, + 0xA3, 0x01, 0x78, 0xD4, 0x0A, 0xF0, 0xF0, 0x21, + 0x79, 0x21, 0xC6, 0x2E, 0x4B, 0x60, 0xCD, 0xD3 + }, + { + 0xE1, 0x49, 0xA6, 0xB1, 0x3B, 0xDE, 0xDE, 0xA2, + 0xEE, 0xEE, 0x00, 0x9C, 0xE9, 0x44, 0x5E, 0x8D, + 0xCF, 0x76, 0xB7, 0x6E, 0x55, 0xA5, 0x01, 0xD8, + 0xF5, 0xB4, 0x3F, 0xF8, 0x96, 0x79, 0x6A, 0xD1 + }, + { + 0xA8, 0x37, 0xC4, 0xC7, 0xC6, 0xF5, 0xCF, 0xB9, + 0x9E, 0x10, 0x85, 0xFD, 0x43, 0x28, 0x7A, 0x41, + 0x05, 0xCB, 0x28, 0xB7, 0x6F, 0xC3, 0x8B, 0x60, + 0x55, 0xC5, 0xDC, 0xFF, 0x78, 0xB8, 0x25, 0x65 + }, + { + 0x42, 0x41, 0x1F, 0x28, 0x78, 0x0B, 0x4F, 0x16, + 0x38, 0x54, 0x0B, 0x87, 0x05, 0x21, 0xEC, 0x45, + 0xBC, 0xEB, 0x1E, 0x0C, 0x71, 0x31, 0xF7, 0xE1, + 0xC4, 0x67, 0x2E, 0x43, 0x6C, 0x88, 0xC8, 0xE9 + }, + { + 0x34, 0xB4, 0xE8, 0x76, 0x76, 0x94, 0x71, 0xDF, + 0x55, 0x2E, 0x55, 0x22, 0xCE, 0xA7, 0x84, 0xFA, + 0x53, 0xAC, 0x61, 0xBE, 0xDE, 0x8C, 0xFE, 0x29, + 0x14, 0x09, 0xE6, 0x8B, 0x69, 0xE8, 0x77, 0x6F + }, + { + 0x8F, 0x31, 0xD6, 0x37, 0xA9, 0x1D, 0xBD, 0x0E, + 0xCB, 0x0B, 0xA0, 0xE6, 0x94, 0xBE, 0xC1, 0x44, + 0x76, 0x58, 0xCE, 0x6C, 0x27, 0xEA, 0x9B, 0x95, + 0xFF, 0x36, 0x70, 0x1C, 0xAF, 0x36, 0xF0, 0x01 + }, + { + 0xB5, 0xC8, 0x95, 0xEB, 0x07, 0x1E, 0x3D, 0x38, + 0x52, 0x8D, 0x47, 0x5D, 0x3B, 0xB0, 0xBA, 0x88, + 0xB7, 0x17, 0x95, 0xE4, 0x0A, 0x98, 0x2E, 0x2A, + 0xC2, 0xD8, 0x44, 0x22, 0xA0, 0xF2, 0x68, 0x5D + }, + { + 0xE9, 0x06, 0x25, 0x7C, 0x41, 0x9D, 0x94, 0x1E, + 0xD2, 0xB8, 0xA9, 0xC1, 0x27, 0x81, 0xDB, 0x97, + 0x59, 0xA3, 0xFC, 0xF3, 0xDC, 0x7C, 0xDB, 0x03, + 0x15, 0x99, 0xE1, 0x08, 0x6B, 0x67, 0x2F, 0x10 + }, + { + 0x98, 0xAD, 0x24, 0x39, 0x7C, 0x6E, 0xAE, 0x4C, + 0xF7, 0x3E, 0xA8, 0xBB, 0xEF, 0x5A, 0x0B, 0x74, + 0xD2, 0x1A, 0xD1, 0x5F, 0x33, 0x92, 0x0F, 0x44, + 0x07, 0x0A, 0x98, 0xBD, 0xF5, 0x3D, 0x0B, 0x3A + }, + { + 0xDD, 0x51, 0x0C, 0xA5, 0x5B, 0x11, 0x70, 0xF9, + 0xCE, 0xFD, 0xBB, 0x16, 0xFC, 0x14, 0x52, 0x62, + 0xAA, 0x36, 0x3A, 0x87, 0x0A, 0x01, 0xE1, 0xBC, + 0x4F, 0xBE, 0x40, 0x23, 0x4B, 0x4B, 0x6F, 0x2F + }, + { + 0xF2, 0xD8, 0xD9, 0x31, 0xB9, 0x2E, 0x1C, 0xB6, + 0x98, 0xE5, 0x6E, 0xD0, 0x28, 0x19, 0xEA, 0x11, + 0xD2, 0x66, 0x19, 0xB8, 0x3A, 0x62, 0x09, 0xAD, + 0x67, 0x22, 0x53, 0x68, 0xFE, 0x11, 0x95, 0x71 + }, + { + 0xE4, 0x63, 0x70, 0x55, 0xDB, 0x91, 0xF9, 0x43, + 0x7C, 0xF4, 0x60, 0xEF, 0x40, 0xB5, 0x14, 0x5F, + 0x69, 0x98, 0x26, 0x6A, 0x5E, 0x74, 0xE9, 0x6A, + 0x00, 0x78, 0x2C, 0x62, 0xCF, 0x30, 0xCF, 0x1C + }, + { + 0x35, 0x63, 0x53, 0x0A, 0x89, 0xD3, 0x2B, 0x75, + 0xF7, 0x8D, 0x83, 0xE9, 0x87, 0x2A, 0xD4, 0xC5, + 0x75, 0xF5, 0x20, 0x39, 0x9D, 0x65, 0x03, 0x5D, + 0xED, 0x99, 0xE5, 0xEE, 0xC5, 0x80, 0x71, 0x50 + }, + { + 0x8E, 0x79, 0xF9, 0x2C, 0x86, 0x5B, 0xEB, 0x3E, + 0x1C, 0xDB, 0xF0, 0x8F, 0x75, 0x4A, 0x26, 0x06, + 0xE8, 0x53, 0x49, 0x05, 0x3D, 0x66, 0xD6, 0x16, + 0x02, 0x4A, 0x81, 0x3F, 0xCA, 0x54, 0x1A, 0x4D + }, + { + 0x86, 0x42, 0x26, 0xF2, 0x83, 0x9C, 0x76, 0xB1, + 0xD5, 0xF7, 0xC1, 0x3D, 0x98, 0xC2, 0xA5, 0x15, + 0x8C, 0x2A, 0xBB, 0x71, 0xD9, 0xD8, 0xF0, 0xFA, + 0x1F, 0x7C, 0x3F, 0x74, 0x68, 0x00, 0x16, 0x03 + }, + { + 0xD3, 0xE3, 0xF5, 0xB8, 0xCE, 0xEB, 0xB1, 0x11, + 0x84, 0x80, 0x35, 0x35, 0x90, 0x0B, 0x6E, 0xED, + 0xDA, 0x60, 0x6E, 0xEB, 0x36, 0x97, 0x51, 0xA7, + 0xCD, 0xA3, 0x6C, 0xA3, 0x02, 0x29, 0xFB, 0x02 + }, + { + 0x8C, 0x7D, 0x6B, 0x98, 0x72, 0x69, 0x16, 0x90, + 0x31, 0xF7, 0x1F, 0xD7, 0xE4, 0xC4, 0x45, 0x01, + 0x2D, 0x3E, 0x6A, 0x3C, 0x88, 0x09, 0xF6, 0x47, + 0x9B, 0xD6, 0x67, 0xCF, 0x31, 0x1E, 0x27, 0x6E + }, + { + 0xB9, 0x04, 0xB5, 0x71, 0x1B, 0xF1, 0x9E, 0x85, + 0x32, 0xF7, 0xAD, 0x64, 0x27, 0x41, 0x0A, 0x62, + 0xA1, 0xF7, 0x7F, 0x77, 0xB9, 0xB6, 0xD7, 0x1D, + 0x2F, 0xC4, 0x3B, 0xC9, 0x0F, 0x73, 0x23, 0x5A + }, + { + 0x45, 0x36, 0x63, 0x43, 0x15, 0xC8, 0x67, 0x28, + 0xF5, 0xAB, 0x74, 0x49, 0xEB, 0x2D, 0x04, 0x02, + 0x0E, 0x9E, 0xAE, 0x8D, 0xD6, 0x79, 0x55, 0x00, + 0xE9, 0xEC, 0x9A, 0x00, 0x66, 0x38, 0x6E, 0x69 + }, + { + 0xFD, 0x5E, 0x49, 0xFE, 0xD4, 0x9D, 0xC4, 0x4B, + 0xDE, 0x89, 0xF4, 0x60, 0xA9, 0x50, 0x19, 0x1E, + 0xBB, 0x06, 0x7C, 0x69, 0x8A, 0x3F, 0x21, 0xEA, + 0x14, 0x30, 0x8C, 0x74, 0x13, 0xB9, 0x16, 0x81 + }, + { + 0x31, 0xF0, 0x1D, 0x03, 0x0B, 0x9B, 0x22, 0xD0, + 0x0A, 0x0F, 0x71, 0xED, 0x2C, 0xEB, 0x5D, 0x2D, + 0xC8, 0x1A, 0xF2, 0xC2, 0x4B, 0xF5, 0x67, 0x0F, + 0xDE, 0x19, 0xA6, 0x85, 0xE8, 0xD1, 0x39, 0x2E + }, + { + 0x5F, 0x84, 0xD9, 0xDE, 0x28, 0x4B, 0x1E, 0x4F, + 0x67, 0x8E, 0x31, 0xAB, 0x6A, 0x76, 0xF5, 0x66, + 0x1B, 0x5A, 0xEA, 0xA7, 0x68, 0x53, 0x93, 0x84, + 0xAA, 0x38, 0xF9, 0xE4, 0x9C, 0xCE, 0x6E, 0x6E + }, + { + 0xB2, 0x07, 0x9E, 0x59, 0x97, 0xA4, 0xEA, 0xD3, + 0xA7, 0x1F, 0xEF, 0xC0, 0x2F, 0x90, 0xA7, 0x48, + 0x3A, 0x10, 0xFD, 0x2E, 0x6F, 0x31, 0xBD, 0xA9, + 0xD2, 0x08, 0x44, 0x85, 0xCC, 0x01, 0x6B, 0xBD + }, + { + 0xE0, 0xF8, 0x4D, 0x7F, 0x52, 0x5B, 0x6F, 0xED, + 0x79, 0x1F, 0x77, 0x28, 0x9A, 0xE5, 0x8F, 0x7D, + 0x50, 0xA2, 0x94, 0x32, 0xD4, 0x2C, 0x25, 0xC1, + 0xE8, 0x39, 0x29, 0xB8, 0x38, 0x89, 0x1D, 0x79 + }, + { + 0x70, 0x46, 0x96, 0x90, 0x95, 0x6D, 0x79, 0x18, + 0xAC, 0xE7, 0xBA, 0x5F, 0x41, 0x30, 0x2D, 0xA1, + 0x38, 0xC9, 0xB5, 0x6E, 0xCD, 0x41, 0x55, 0x44, + 0xFA, 0xCE, 0x8D, 0x99, 0x8C, 0x21, 0xAB, 0xEB + }, + { + 0x45, 0xC9, 0x1A, 0x62, 0x24, 0x9B, 0x39, 0xCD, + 0xA9, 0x4E, 0x50, 0x82, 0x95, 0xBE, 0xC7, 0x66, + 0x71, 0x19, 0x44, 0x77, 0x65, 0xEF, 0x80, 0xEF, + 0xA8, 0x2D, 0x1E, 0x92, 0xD5, 0x70, 0x67, 0xD8 + }, + { + 0x1D, 0x9E, 0x00, 0x73, 0xEE, 0xD0, 0x73, 0x15, + 0x54, 0xC3, 0xBE, 0xAA, 0x47, 0x46, 0x0D, 0x51, + 0x1A, 0xD2, 0x61, 0xDD, 0x4D, 0x4A, 0x3B, 0xED, + 0x9D, 0x8D, 0x20, 0x2F, 0x22, 0xF2, 0x15, 0x89 + }, + { + 0x40, 0x82, 0x62, 0x73, 0x6D, 0x8A, 0xEC, 0x0B, + 0x84, 0x7D, 0xBA, 0x25, 0x02, 0x58, 0x60, 0x8A, + 0x43, 0x45, 0xA6, 0x3A, 0x1E, 0xB1, 0x95, 0xE5, + 0xC7, 0xAE, 0x2E, 0xE8, 0x74, 0xC3, 0x4D, 0xA8 + }, + { + 0x23, 0xD2, 0xB7, 0x04, 0x39, 0x46, 0x99, 0x49, + 0x98, 0x23, 0x90, 0x53, 0x8D, 0x7E, 0x5A, 0xDE, + 0x9F, 0x18, 0xC8, 0xE3, 0xBB, 0xF6, 0x60, 0x5A, + 0xFC, 0xF4, 0x9B, 0x00, 0xC0, 0x61, 0xE8, 0x37 + }, + { + 0x23, 0x2F, 0xB1, 0x87, 0xD2, 0x71, 0xBE, 0xA9, + 0x12, 0xEF, 0xD4, 0x07, 0xFF, 0xE0, 0x80, 0x56, + 0xD6, 0xA4, 0x2E, 0x53, 0x21, 0xEC, 0x79, 0x2D, + 0xF3, 0xD5, 0x84, 0xA9, 0x4F, 0x63, 0x0A, 0xB2 + }, + { + 0x13, 0x8E, 0x19, 0x44, 0xE4, 0xB5, 0x4D, 0xE8, + 0x68, 0x1D, 0x7E, 0x48, 0xC4, 0xF0, 0x81, 0x48, + 0xE4, 0x0A, 0x56, 0x7E, 0x5C, 0xAD, 0x94, 0x6A, + 0x6A, 0xF4, 0xE8, 0xD5, 0xD2, 0x6F, 0x75, 0xC7 + }, + { + 0x80, 0xC1, 0x51, 0x32, 0x5F, 0xBF, 0xC6, 0x78, + 0xB7, 0xBE, 0x4E, 0x40, 0xB3, 0x0F, 0x29, 0xFE, + 0x31, 0xCD, 0xBE, 0x1C, 0x84, 0x12, 0x6E, 0x00, + 0x6D, 0xF3, 0xC1, 0x85, 0x24, 0xBD, 0x2D, 0x6C + }, + { + 0xA6, 0x42, 0x26, 0x73, 0x01, 0x66, 0x9D, 0xF2, + 0x61, 0xB8, 0x39, 0xF8, 0x73, 0x65, 0x76, 0x29, + 0x05, 0xFF, 0x32, 0x0A, 0x0A, 0x2F, 0xC4, 0xBD, + 0xC4, 0x8E, 0x5A, 0x8E, 0x15, 0xD1, 0x32, 0x33 + }, + { + 0x0F, 0x8B, 0x10, 0x99, 0x38, 0x60, 0x93, 0x7A, + 0x74, 0xCC, 0x2D, 0xE4, 0x0A, 0x27, 0x31, 0xDD, + 0x99, 0x54, 0xB6, 0x54, 0xBB, 0x94, 0xC3, 0x4E, + 0x87, 0x66, 0x52, 0xE9, 0x8D, 0x4B, 0xBD, 0x16 + }, + { + 0xE6, 0x34, 0xA5, 0x85, 0x12, 0x49, 0x32, 0x73, + 0x26, 0x0F, 0x10, 0xD4, 0x49, 0x53, 0xCD, 0x99, + 0x8E, 0x34, 0xCB, 0x82, 0x81, 0xC4, 0x1B, 0xF4, + 0x2E, 0x0A, 0xE2, 0xF2, 0x5C, 0xBD, 0x1F, 0x75 + }, + { + 0xBD, 0xE6, 0xAF, 0x9B, 0xAF, 0x3C, 0x07, 0xE9, + 0x54, 0x23, 0xCA, 0xB5, 0x04, 0xDE, 0xE7, 0x0E, + 0xDC, 0xC3, 0x31, 0x8B, 0x22, 0xDD, 0x1E, 0xB6, + 0xFD, 0x85, 0xBE, 0x44, 0x7A, 0xC9, 0xF2, 0x09 + }, + { + 0x91, 0x4B, 0x37, 0xAB, 0x5B, 0x8C, 0xFD, 0xE6, + 0xA4, 0x80, 0x46, 0x6A, 0x0D, 0x82, 0x43, 0x2C, + 0x7D, 0x76, 0x32, 0x8E, 0x9A, 0x88, 0xEF, 0x5B, + 0x4F, 0x52, 0x42, 0x9F, 0x7A, 0x3F, 0xFC, 0x7D + }, + { + 0x55, 0xBE, 0x66, 0xE9, 0xA5, 0xAA, 0x67, 0x1A, + 0x23, 0x88, 0x2E, 0xF3, 0xE7, 0xD9, 0xD3, 0x6E, + 0xA9, 0x54, 0x87, 0xDC, 0x71, 0xB7, 0x25, 0xA5, + 0xAD, 0x4B, 0x79, 0x8A, 0x87, 0x91, 0x43, 0xD0 + }, + { + 0x3F, 0xD0, 0x45, 0x89, 0x4B, 0x83, 0x6E, 0x44, + 0xE9, 0xCA, 0x75, 0xFB, 0xE3, 0xEA, 0xDC, 0x48, + 0x6C, 0xBB, 0xD0, 0xD8, 0xCE, 0xE1, 0xB3, 0xCF, + 0x14, 0xF7, 0x6E, 0x7F, 0x1E, 0x77, 0xAE, 0xF3 + }, + { + 0xCE, 0x60, 0x34, 0x3D, 0xC4, 0x87, 0x4B, 0x66, + 0x04, 0xE1, 0xFB, 0x23, 0x1E, 0x37, 0xEC, 0x1E, + 0xEC, 0x3F, 0x06, 0x56, 0x6E, 0x42, 0x8A, 0xE7, + 0x64, 0xEF, 0xFF, 0xA2, 0x30, 0xAD, 0xD4, 0x85 + }, + { + 0xE3, 0x8C, 0x9D, 0xF0, 0x24, 0xDE, 0x21, 0x53, + 0xD2, 0x26, 0x73, 0x8A, 0x0E, 0x5B, 0xA9, 0xB8, + 0xC6, 0x78, 0x4D, 0xAC, 0xA6, 0x5C, 0x22, 0xA7, + 0x62, 0x8E, 0xB5, 0x8E, 0xA0, 0xD4, 0x95, 0xA7 + }, + { + 0x8D, 0xFE, 0xC0, 0xD4, 0xF3, 0x65, 0x8A, 0x20, + 0xA0, 0xBA, 0xD6, 0x6F, 0x21, 0x60, 0x83, 0x2B, + 0x16, 0x4E, 0x70, 0x0A, 0x21, 0xEC, 0x5A, 0x01, + 0x65, 0xC3, 0x67, 0x72, 0xB2, 0x08, 0x61, 0x11 + }, + { + 0x44, 0x01, 0xB5, 0x0E, 0x09, 0x86, 0x5F, 0x42, + 0x38, 0x24, 0x3B, 0x82, 0x25, 0xCA, 0x40, 0xA0, + 0x8D, 0xBB, 0x46, 0x85, 0xF5, 0xF8, 0x62, 0xFB, + 0xDD, 0x72, 0x98, 0x04, 0x31, 0xA8, 0x5D, 0x3F + }, + { + 0x86, 0x68, 0x94, 0x27, 0x88, 0xC4, 0xCE, 0x8A, + 0x33, 0x19, 0x0F, 0xFC, 0xFA, 0xD1, 0xC6, 0x78, + 0xC4, 0xFA, 0x41, 0xE9, 0x94, 0x17, 0x09, 0x4E, + 0x24, 0x0F, 0x4A, 0x43, 0xF3, 0x87, 0xA3, 0xB6 + }, + { + 0xA7, 0x28, 0x8D, 0x5E, 0x09, 0x80, 0x9B, 0x69, + 0x69, 0x84, 0xEC, 0xD5, 0x32, 0x6C, 0xDD, 0x84, + 0xFB, 0xE3, 0x5F, 0xCF, 0x67, 0x23, 0x5D, 0x81, + 0x1C, 0x82, 0x00, 0x25, 0x36, 0xA3, 0xC5, 0xE1 + }, + { + 0x8E, 0x92, 0x5C, 0x3C, 0x14, 0x6B, 0xAC, 0xF3, + 0x35, 0x1E, 0xC5, 0x32, 0x41, 0xAC, 0xE5, 0xF7, + 0x3E, 0x8F, 0xC9, 0xBD, 0x8C, 0x61, 0xCA, 0xD9, + 0x7F, 0xD7, 0x72, 0xB0, 0x7E, 0x1B, 0x83, 0x73 + }, + { + 0xC7, 0xEB, 0x9E, 0x6D, 0xED, 0x2F, 0x99, 0x3D, + 0x48, 0xB0, 0x17, 0x0D, 0xA2, 0x7C, 0x5B, 0x75, + 0x3B, 0x12, 0x17, 0x6B, 0xE1, 0x26, 0xC7, 0xBA, + 0x2D, 0x6A, 0xF8, 0x5F, 0x85, 0x93, 0xB7, 0x52 + }, + { + 0xCA, 0x27, 0xF1, 0x6F, 0x94, 0xE4, 0xEC, 0x0E, + 0x62, 0x8E, 0x7F, 0x8A, 0xEF, 0xC6, 0x65, 0x7B, + 0xED, 0xC9, 0x37, 0x42, 0x96, 0x59, 0x40, 0xAE, + 0x78, 0x6A, 0x73, 0xB5, 0xFD, 0x59, 0x3B, 0x97 + }, + { + 0x8C, 0x21, 0xE6, 0x56, 0x8B, 0xC6, 0xDC, 0x00, + 0xE3, 0xD6, 0xEB, 0xC0, 0x9E, 0xA9, 0xC2, 0xCE, + 0x00, 0x6C, 0xD3, 0x11, 0xD3, 0xB3, 0xE9, 0xCC, + 0x9D, 0x8D, 0xDB, 0xFB, 0x3C, 0x5A, 0x77, 0x76 + }, + { + 0x52, 0x56, 0x66, 0x96, 0x8B, 0x3B, 0x7D, 0x00, + 0x7B, 0xB9, 0x26, 0xB6, 0xEF, 0xDC, 0x7E, 0x21, + 0x2A, 0x31, 0x15, 0x4C, 0x9A, 0xE1, 0x8D, 0x43, + 0xEE, 0x0E, 0xB7, 0xE6, 0xB1, 0xA9, 0x38, 0xD3 + }, + { + 0xE0, 0x9A, 0x4F, 0xA5, 0xC2, 0x8B, 0xDC, 0xD7, + 0xC8, 0x39, 0x84, 0x0E, 0x0A, 0x38, 0x3E, 0x4F, + 0x7A, 0x10, 0x2D, 0x0B, 0x1B, 0xC8, 0x49, 0xC9, + 0x49, 0x62, 0x7C, 0x41, 0x00, 0xC1, 0x7D, 0xD3 + }, + { + 0xC1, 0x9F, 0x3E, 0x29, 0x5D, 0xB2, 0xFC, 0x0E, + 0x74, 0x81, 0xC4, 0xF1, 0x6A, 0xF0, 0x11, 0x55, + 0xDD, 0xB0, 0xD7, 0xD1, 0x38, 0x3D, 0x4A, 0x1F, + 0xF1, 0x69, 0x9D, 0xB7, 0x11, 0x77, 0x34, 0x0C + }, + { + 0x76, 0x9E, 0x67, 0x8C, 0x0A, 0x09, 0x09, 0xA2, + 0x02, 0x1C, 0x4D, 0xC2, 0x6B, 0x1A, 0x3C, 0x9B, + 0xC5, 0x57, 0xAD, 0xB2, 0x1A, 0x50, 0x83, 0x4C, + 0xDC, 0x5C, 0x92, 0x93, 0xF7, 0x53, 0x65, 0xF8 + }, + { + 0xB6, 0x48, 0x74, 0xAD, 0xAB, 0x6B, 0xCB, 0x85, + 0xB9, 0x4B, 0xD9, 0xA6, 0xC5, 0x65, 0xD0, 0xD2, + 0xBC, 0x35, 0x44, 0x5D, 0x75, 0x28, 0xBC, 0x85, + 0xB4, 0x1F, 0xDC, 0x79, 0xDC, 0x76, 0xE3, 0x4F + }, + { + 0xFA, 0xF2, 0x50, 0xDE, 0x15, 0x82, 0x0F, 0x7F, + 0xC6, 0x10, 0xDD, 0x53, 0xEE, 0xAE, 0x44, 0x60, + 0x1C, 0x3E, 0xFF, 0xA3, 0xAC, 0xCD, 0x08, 0x8E, + 0xB6, 0x69, 0x05, 0xBB, 0x26, 0x53, 0xBE, 0x8C + }, + { + 0x1E, 0x20, 0x38, 0x73, 0x9B, 0x2C, 0x01, 0x8B, + 0x0E, 0x9E, 0x0E, 0x1E, 0x52, 0x2F, 0xD9, 0x65, + 0x12, 0x87, 0xEE, 0x6E, 0x36, 0x65, 0x91, 0x9B, + 0x24, 0xC2, 0x12, 0x4F, 0x0C, 0x1A, 0x3F, 0x3A + }, + { + 0x5F, 0xEC, 0x3A, 0xA0, 0x08, 0x61, 0xDE, 0x1A, + 0xC5, 0xDA, 0xB3, 0xC1, 0x37, 0x06, 0x5D, 0x1E, + 0x01, 0xBB, 0x03, 0xF6, 0x9D, 0xCC, 0x7D, 0x1C, + 0xF7, 0xCA, 0x4F, 0x43, 0x56, 0xAE, 0xC9, 0xA3 + }, + { + 0x44, 0x51, 0xFE, 0x6B, 0xBE, 0xF3, 0x93, 0x43, + 0x91, 0x92, 0x44, 0xC5, 0x1D, 0xAE, 0x1E, 0xA9, + 0xA9, 0x54, 0xCF, 0x2C, 0x09, 0x66, 0xAB, 0x04, + 0x5B, 0x15, 0x52, 0x1E, 0xCF, 0x35, 0x00, 0x81 + }, + { + 0x8C, 0x62, 0x2F, 0xA2, 0x16, 0x0E, 0x8E, 0x99, + 0x18, 0x13, 0xF1, 0x80, 0xBF, 0xEC, 0x0B, 0x43, + 0x1C, 0x6D, 0xBF, 0xA2, 0x95, 0x6D, 0x91, 0x75, + 0x81, 0x6A, 0x23, 0xC3, 0x82, 0xC4, 0xF2, 0x00 + }, + { + 0x81, 0x7D, 0x5C, 0x8F, 0x92, 0xE7, 0xB5, 0xCA, + 0x57, 0xF5, 0xE1, 0x63, 0x90, 0x16, 0xAD, 0x57, + 0x60, 0xE4, 0x46, 0xD6, 0xE9, 0xCA, 0xA7, 0x49, + 0x84, 0x14, 0xAC, 0xE8, 0x22, 0x80, 0xB5, 0xCD + }, + { + 0xA6, 0xA1, 0xAD, 0x58, 0xCE, 0xE5, 0x4E, 0x69, + 0xCB, 0xBC, 0xAA, 0x87, 0xDF, 0x07, 0xA6, 0x70, + 0x7E, 0xB2, 0x24, 0x73, 0x9C, 0x21, 0x76, 0x13, + 0x46, 0x0A, 0xB4, 0x54, 0xB4, 0x59, 0xCA, 0x9C + }, + { + 0x63, 0xB8, 0x47, 0x27, 0x52, 0x26, 0x60, 0x5B, + 0xE6, 0x76, 0x81, 0x25, 0x8F, 0x7D, 0x00, 0xBB, + 0xB3, 0x07, 0xC6, 0x6F, 0x19, 0x59, 0xBF, 0x2E, + 0x46, 0x7A, 0x41, 0xAE, 0xE7, 0x14, 0xE5, 0x5C + }, + { + 0xFE, 0x52, 0xEB, 0xE5, 0xCF, 0xCF, 0xE6, 0xA2, + 0x29, 0x7B, 0x53, 0x9F, 0xA3, 0xDA, 0xDB, 0xD6, + 0xEB, 0xD2, 0x01, 0xAA, 0x2C, 0xA1, 0x35, 0x63, + 0xE3, 0xD7, 0xF1, 0x4D, 0x15, 0xAB, 0xFF, 0x63 + }, + { + 0xB7, 0xBE, 0xF9, 0xFA, 0x5A, 0x3D, 0x10, 0x42, + 0x62, 0x46, 0xB5, 0xF6, 0x58, 0xC0, 0x8F, 0xDF, + 0x80, 0x66, 0xEA, 0xA3, 0xE5, 0x5A, 0x2F, 0x7D, + 0xA1, 0x59, 0x1E, 0x05, 0xC8, 0x7D, 0xF8, 0xC7 + }, + { + 0xDE, 0xD1, 0xD6, 0xCA, 0xA9, 0xF8, 0xF3, 0xBD, + 0xA9, 0x2C, 0xEA, 0x7F, 0x65, 0x49, 0xB1, 0xFB, + 0x86, 0xA2, 0x21, 0x14, 0x78, 0xC4, 0xEC, 0x28, + 0x9B, 0x83, 0x7E, 0xFC, 0x2B, 0x5C, 0x27, 0xD7 + }, + { + 0x9F, 0x30, 0x00, 0x8A, 0x2E, 0xB0, 0x50, 0xF1, + 0x8E, 0x56, 0xA7, 0x6B, 0xE9, 0x20, 0x91, 0xB2, + 0xFD, 0xC1, 0x64, 0xD5, 0x6E, 0x32, 0xC8, 0x7D, + 0xD6, 0x4C, 0x9E, 0x3A, 0x61, 0x10, 0x41, 0xB1 + }, + { + 0x01, 0x0B, 0x6A, 0x3B, 0x11, 0x86, 0x00, 0x88, + 0xF0, 0xAB, 0xC8, 0x0A, 0x89, 0x72, 0xCB, 0xBC, + 0x32, 0x9D, 0x52, 0x75, 0x34, 0x29, 0x50, 0xEB, + 0x9A, 0x04, 0x5A, 0xFD, 0xC8, 0xBB, 0xED, 0x24 + }, + { + 0x0C, 0xD2, 0x10, 0xAA, 0xC1, 0x1F, 0x1C, 0x1C, + 0xED, 0x49, 0x7F, 0x67, 0x3E, 0x53, 0xDB, 0x68, + 0xC3, 0xEC, 0x36, 0x07, 0xF0, 0xC5, 0x78, 0x7D, + 0xDC, 0x60, 0xA3, 0x55, 0xDF, 0xE5, 0x6C, 0x25 + }, + { + 0x0E, 0x56, 0xFD, 0x01, 0xDA, 0x3B, 0x4F, 0x8B, + 0xE2, 0xC9, 0x90, 0x55, 0x2A, 0xAC, 0x8D, 0x1E, + 0x8D, 0xA2, 0x09, 0xBC, 0xF4, 0xAA, 0xD4, 0xFF, + 0xB5, 0x42, 0x7F, 0xD6, 0x31, 0x72, 0x46, 0x3E + }, + { + 0xD6, 0xD5, 0xCD, 0xB1, 0x14, 0x40, 0xE3, 0x4A, + 0xCA, 0x3A, 0x2F, 0xCF, 0x30, 0xF5, 0x9E, 0x08, + 0xB1, 0x1A, 0x2A, 0x3D, 0xE5, 0x39, 0xE3, 0xE6, + 0x51, 0x3E, 0xD7, 0x8A, 0x4F, 0xEE, 0x51, 0x3B + }, + { + 0xAA, 0x35, 0xAC, 0x90, 0x68, 0x06, 0x70, 0xC7, + 0x32, 0xED, 0x1E, 0xF3, 0x7E, 0x8C, 0xBA, 0xAE, + 0x49, 0xA4, 0xD8, 0x8E, 0xCF, 0x4D, 0xF2, 0xB6, + 0x89, 0xA0, 0xF1, 0x01, 0xB7, 0x56, 0xAE, 0x47 + }, + { + 0x27, 0x8E, 0x56, 0x12, 0x88, 0x72, 0x26, 0x30, + 0xE2, 0x6A, 0x5F, 0xC9, 0x54, 0xBF, 0x2D, 0xCD, + 0x6A, 0x65, 0x81, 0x67, 0x39, 0xAB, 0xEE, 0x7B, + 0xE1, 0x43, 0x07, 0xA9, 0x61, 0x74, 0xE5, 0xB0 + }, + { + 0xAB, 0x4B, 0x2C, 0xA1, 0xA2, 0xB3, 0x49, 0x98, + 0x15, 0x24, 0xB6, 0x15, 0x54, 0x62, 0xF0, 0xFF, + 0x10, 0x60, 0xBF, 0x9B, 0xFA, 0x07, 0xFB, 0x9E, + 0xC6, 0x9C, 0xA4, 0x71, 0x64, 0x5B, 0x6A, 0x18 + }, + { + 0x18, 0xA9, 0xBB, 0xEC, 0x3C, 0x8E, 0x1F, 0x8E, + 0xE9, 0x57, 0x12, 0x97, 0xA9, 0x34, 0x36, 0xDE, + 0x42, 0x7C, 0xD2, 0x70, 0xEC, 0x69, 0xDF, 0xE8, + 0x88, 0xDB, 0x7D, 0xBF, 0x10, 0xB6, 0x49, 0x93 + }, + { + 0xBA, 0xFC, 0x7E, 0x43, 0xD2, 0x65, 0xA1, 0x73, + 0x02, 0x1A, 0x9D, 0x9E, 0x58, 0x3D, 0x60, 0xED, + 0x42, 0xA8, 0x03, 0xFA, 0xCD, 0x6B, 0x83, 0x60, + 0xDE, 0x1F, 0x91, 0x68, 0x35, 0x38, 0x9B, 0xF0 + }, + { + 0xA5, 0xB6, 0x7B, 0xE9, 0x50, 0xFB, 0xC2, 0xF0, + 0xDD, 0x32, 0x3A, 0x79, 0xA1, 0x9E, 0x3E, 0xD1, + 0xF4, 0xAE, 0x4B, 0xA7, 0x89, 0x4F, 0x93, 0x0E, + 0xA5, 0xEF, 0x73, 0x4D, 0xE7, 0xDB, 0x83, 0xAE + }, + { + 0xBF, 0x1E, 0x65, 0xF3, 0xCD, 0x84, 0x98, 0x88, + 0x4D, 0x9D, 0x5C, 0x19, 0xEB, 0xF7, 0xB9, 0x16, + 0x06, 0x76, 0x37, 0x60, 0x4E, 0x26, 0xDB, 0xE2, + 0xB7, 0x28, 0x8E, 0xCB, 0x11, 0x42, 0x60, 0x68 + }, + { + 0xC3, 0x34, 0x2C, 0xF9, 0xCB, 0xBF, 0x29, 0xD4, + 0x06, 0xD7, 0x89, 0x5D, 0xD4, 0xD9, 0x54, 0x8D, + 0x4A, 0xC7, 0x8B, 0x4D, 0x00, 0xE9, 0xB6, 0x3E, + 0x20, 0x3E, 0x5E, 0x19, 0xE9, 0x97, 0x46, 0x20 + }, + { + 0x1C, 0x0B, 0xE6, 0x02, 0x77, 0x43, 0x4B, 0x0E, + 0x00, 0x4B, 0x7B, 0x38, 0x8A, 0x37, 0x55, 0x9F, + 0x84, 0xB3, 0x0C, 0x6C, 0xF8, 0x60, 0x0F, 0x52, + 0x8B, 0xFC, 0xD3, 0x3C, 0xAF, 0x52, 0xCB, 0x1E + }, + { + 0x73, 0x95, 0x45, 0x30, 0xD0, 0x3F, 0x10, 0xBE, + 0xF5, 0x2A, 0xD5, 0xBC, 0x7F, 0xB4, 0xC0, 0x76, + 0xF8, 0x3F, 0x63, 0x31, 0xC8, 0xBD, 0x1E, 0xEE, + 0xC3, 0x88, 0x7F, 0x4A, 0xA2, 0x06, 0x92, 0x40 + }, + { + 0x69, 0xC1, 0x1E, 0xE0, 0x49, 0x44, 0xDE, 0xA9, + 0x85, 0xAC, 0x9F, 0x13, 0x96, 0x0E, 0x73, 0x98, + 0x0E, 0x1B, 0xB0, 0xE3, 0x09, 0xF4, 0x38, 0x4A, + 0x16, 0x76, 0xF8, 0xEF, 0xAB, 0x38, 0x42, 0x88 + }, + { + 0x36, 0xFB, 0x8F, 0xDE, 0x0E, 0xC2, 0x8C, 0xE8, + 0x53, 0xFB, 0x71, 0x75, 0xC1, 0xB7, 0x9D, 0xA3, + 0xB5, 0xE8, 0xC3, 0x91, 0x86, 0xE7, 0x8A, 0xAE, + 0xCE, 0x54, 0x64, 0xDB, 0xD9, 0xFE, 0x2A, 0xA2 + }, + { + 0x6B, 0xB2, 0xA0, 0x9D, 0xFC, 0xAF, 0x96, 0x96, + 0x2D, 0xE0, 0x0C, 0x8A, 0x08, 0x2D, 0x6D, 0xF9, + 0x32, 0x2B, 0x49, 0x66, 0xAE, 0x8D, 0x2E, 0xCF, + 0x73, 0x24, 0x11, 0xA7, 0x6A, 0x1A, 0x0E, 0xE6 + }, + { + 0x74, 0x12, 0xE7, 0xDD, 0x1B, 0xF1, 0xAA, 0x93, + 0x97, 0x41, 0x1B, 0xBA, 0x4D, 0x3E, 0x02, 0x76, + 0xD2, 0xE7, 0xA1, 0xA2, 0x9A, 0x24, 0x77, 0x15, + 0x7A, 0xD6, 0x03, 0x60, 0xD3, 0x3D, 0x4E, 0x76 + }, + { + 0xDD, 0xDE, 0xAF, 0xCF, 0xC7, 0x23, 0x21, 0xC8, + 0x49, 0xFB, 0x25, 0x94, 0x7A, 0xB4, 0x2C, 0x1A, + 0xF2, 0xA5, 0xE4, 0x3F, 0xEF, 0x68, 0x1B, 0xE4, + 0x2C, 0x7E, 0xAF, 0x36, 0x60, 0x08, 0x0A, 0xD3 + }, + { + 0x9D, 0xEF, 0xEB, 0xAD, 0xBD, 0xCB, 0x0A, 0x0E, + 0x7F, 0xF9, 0x92, 0xF9, 0x47, 0xCE, 0xD3, 0xD0, + 0xA4, 0xC8, 0x99, 0xE6, 0x4F, 0xE7, 0x73, 0x60, + 0xE8, 0x1E, 0x1F, 0x0E, 0x97, 0xF8, 0xC1, 0xA2 + }, + { + 0x84, 0x4C, 0x59, 0xFB, 0xE6, 0x47, 0x6F, 0xD1, + 0x89, 0x23, 0x99, 0x54, 0xF1, 0x7E, 0x36, 0xE1, + 0xF6, 0x9E, 0x24, 0xAA, 0xED, 0x5D, 0x5C, 0x8B, + 0x84, 0x05, 0xEF, 0x2A, 0x83, 0x0C, 0xC2, 0xA0 + }, + { + 0xFF, 0x3F, 0xAF, 0xB6, 0x77, 0x86, 0xE0, 0x1A, + 0x0C, 0x38, 0xEA, 0xDF, 0x99, 0xC4, 0xCA, 0xE8, + 0x02, 0x9D, 0xA8, 0xCF, 0x29, 0x87, 0x5F, 0xC4, + 0x19, 0xBF, 0x68, 0x00, 0x09, 0xB3, 0xBD, 0xB3 + }, + { + 0xCA, 0x67, 0x60, 0xF3, 0x45, 0x67, 0x8F, 0x30, + 0xA2, 0x8D, 0x62, 0x82, 0x94, 0x27, 0x2A, 0x19, + 0xE3, 0x07, 0x2E, 0xBC, 0x61, 0xB1, 0x9F, 0xF1, + 0x3B, 0x31, 0x89, 0x73, 0xE9, 0x7C, 0x27, 0x38 + }, + { + 0xC0, 0x8E, 0x1A, 0x90, 0x47, 0xC5, 0x05, 0x26, + 0x4A, 0x16, 0x44, 0x7C, 0x9E, 0xD9, 0x81, 0xA7, + 0x19, 0xD3, 0x81, 0xF2, 0x8E, 0x60, 0x5F, 0xD7, + 0xCA, 0xA9, 0xE8, 0xBD, 0xBB, 0x42, 0x99, 0x6A + }, + { + 0xF1, 0x73, 0xBA, 0x9D, 0x45, 0x84, 0xCD, 0x12, + 0x60, 0x50, 0xC6, 0x9F, 0xC2, 0x19, 0xA9, 0x19, + 0x0A, 0x0B, 0xF0, 0xAE, 0xCE, 0xCB, 0xE6, 0x11, + 0xBE, 0xED, 0x19, 0x3D, 0xA6, 0xCA, 0x4D, 0xE7 + }, + { + 0xB1, 0x84, 0x87, 0x65, 0x20, 0xDE, 0xD8, 0xBD, + 0x7D, 0xE2, 0x5E, 0xAE, 0xFB, 0xD3, 0xE0, 0x36, + 0x88, 0xC3, 0xBE, 0x39, 0xC1, 0x9F, 0xB7, 0x3E, + 0x1F, 0x0E, 0xCC, 0xAC, 0x7C, 0xC0, 0xF0, 0x14 + }, + { + 0x90, 0x25, 0xDB, 0x07, 0x58, 0xBD, 0xFB, 0x48, + 0xF0, 0x66, 0x7E, 0xBD, 0x7E, 0x12, 0x02, 0x46, + 0x59, 0x8F, 0xED, 0x01, 0xC2, 0x58, 0x76, 0x4F, + 0xA0, 0xFA, 0xE3, 0x34, 0xA2, 0xA0, 0x0A, 0x97 + }, + { + 0xE8, 0x3D, 0x80, 0x86, 0xFA, 0xBC, 0x46, 0x0D, + 0x5E, 0xFC, 0x45, 0x9F, 0x95, 0xA2, 0x68, 0xF5, + 0xDC, 0x4A, 0xC2, 0x84, 0x09, 0x3C, 0x24, 0x7C, + 0xA6, 0xEC, 0x84, 0x1A, 0xD6, 0x18, 0x3F, 0xE1 + }, + { + 0xCC, 0x9D, 0xF4, 0x1D, 0x35, 0xAA, 0x75, 0x92, + 0x8C, 0x18, 0x5F, 0x73, 0x93, 0x66, 0x61, 0x10, + 0xB8, 0x0F, 0x09, 0x86, 0xA2, 0x21, 0xC3, 0x70, + 0xF4, 0x5C, 0x2E, 0xB9, 0x01, 0x6C, 0x9A, 0x3B + }, + { + 0x92, 0xF9, 0xA5, 0x94, 0x95, 0x45, 0x90, 0xFA, + 0x81, 0x98, 0x17, 0xE5, 0xD1, 0xC2, 0x8A, 0xAB, + 0x2B, 0x1C, 0xC5, 0x04, 0xD8, 0x6D, 0xBA, 0x44, + 0x36, 0x76, 0xBD, 0xF8, 0x66, 0x79, 0x68, 0x11 + }, + { + 0x72, 0x95, 0x62, 0xA1, 0xE0, 0x7B, 0x0E, 0x26, + 0x05, 0x49, 0x48, 0x09, 0xBD, 0x48, 0x0F, 0x15, + 0x37, 0xCE, 0xA1, 0x0D, 0xCA, 0xD4, 0x3E, 0xF9, + 0xF6, 0x8C, 0x66, 0xE8, 0x25, 0xDC, 0x46, 0xB1 + }, + { + 0x26, 0xF1, 0x60, 0xAB, 0x96, 0xF5, 0x58, 0x20, + 0x45, 0x14, 0x6E, 0xAF, 0xF2, 0xE2, 0xA8, 0xD4, + 0xDA, 0xB2, 0x98, 0xB4, 0xC5, 0x7E, 0x11, 0x7C, + 0xDF, 0xC5, 0xD0, 0x25, 0xC9, 0x2A, 0x22, 0x68 + }, + { + 0x87, 0xEB, 0xE7, 0x21, 0x38, 0x38, 0x73, 0xD2, + 0x47, 0xF8, 0x61, 0x82, 0xE3, 0xF5, 0x99, 0xA7, + 0x63, 0x4F, 0xCA, 0xEC, 0x5E, 0x07, 0xB1, 0xE8, + 0x3E, 0xBB, 0x79, 0x62, 0x5B, 0xA3, 0x54, 0xE6 + }, + { + 0xE0, 0x8D, 0x38, 0x9F, 0x75, 0x69, 0x4A, 0xDC, + 0x99, 0x6C, 0x22, 0xF5, 0x5D, 0x4F, 0x85, 0x9F, + 0xFD, 0x0C, 0x13, 0x19, 0xFF, 0x9C, 0xED, 0xF7, + 0x8C, 0x31, 0xBE, 0x84, 0xB6, 0xF2, 0x1A, 0xBC + }, + { + 0x13, 0x63, 0xE2, 0x29, 0x13, 0xC6, 0xE1, 0x8E, + 0x7A, 0xA6, 0x5B, 0x83, 0xE7, 0x51, 0xC8, 0xA2, + 0xC6, 0x1B, 0x0F, 0x30, 0x71, 0x55, 0x86, 0x5A, + 0x57, 0xDB, 0xA5, 0x69, 0xA9, 0x9C, 0x7B, 0x0E + }, + { + 0x88, 0x78, 0x08, 0x8E, 0xB2, 0xD1, 0xF6, 0xD0, + 0xBB, 0x48, 0x1B, 0x4B, 0xB1, 0x87, 0xDA, 0x04, + 0xBC, 0xD8, 0xC2, 0xC6, 0x39, 0xF0, 0x05, 0xB0, + 0x80, 0x54, 0xCC, 0x41, 0x75, 0x39, 0x05, 0xFB + }, + { + 0x04, 0x18, 0xD6, 0x0D, 0x05, 0xB4, 0xE1, 0x24, + 0x64, 0x6E, 0xE5, 0x0E, 0x77, 0x49, 0xA1, 0xD2, + 0x09, 0x45, 0x7B, 0xC5, 0x43, 0xE3, 0xCC, 0x11, + 0x30, 0x27, 0x4A, 0xEA, 0x0F, 0x7B, 0xF3, 0xC1 + }, + { + 0x7A, 0x39, 0x7E, 0x50, 0x3F, 0x29, 0x3B, 0xC4, + 0x2D, 0x5F, 0x7E, 0xF5, 0xEC, 0x37, 0x87, 0x24, + 0x60, 0xA4, 0xF5, 0xB5, 0xCC, 0xDE, 0x77, 0xFB, + 0x4D, 0x47, 0xAC, 0x06, 0x81, 0xE5, 0xA0, 0x49 + }, + { + 0x5C, 0x0D, 0x29, 0x83, 0xE7, 0x2A, 0x6D, 0xD4, + 0xE6, 0x52, 0xD7, 0x23, 0xC1, 0xDF, 0xC1, 0x2B, + 0x41, 0x4C, 0x87, 0x3D, 0x4A, 0xB4, 0xA0, 0xA1, + 0x50, 0x40, 0x8E, 0xB3, 0x43, 0x47, 0xE9, 0x95 + }, + { + 0x56, 0x23, 0x36, 0x54, 0x53, 0xC0, 0x49, 0x89, + 0xC7, 0xCF, 0x33, 0x63, 0x5E, 0x0F, 0xC4, 0xCD, + 0xDD, 0x68, 0x6F, 0xC9, 0x5A, 0x33, 0xDF, 0xED, + 0xCF, 0x33, 0x35, 0x79, 0x4C, 0x7D, 0xC3, 0x44 + }, + { + 0x11, 0xF6, 0xDA, 0xD1, 0x88, 0x02, 0x8F, 0xDF, + 0x13, 0x78, 0xA2, 0x56, 0xE4, 0x57, 0x0E, 0x90, + 0x63, 0x10, 0x7B, 0x8F, 0x79, 0xDC, 0x66, 0x3F, + 0xA5, 0x55, 0x6F, 0x56, 0xFD, 0x44, 0xA0, 0xF0 + }, + { + 0x0E, 0xD8, 0x16, 0x17, 0x97, 0xEC, 0xEE, 0x88, + 0x1E, 0x7D, 0x0E, 0x3F, 0x4C, 0x5F, 0xB8, 0x39, + 0xC8, 0x4E, 0xB7, 0xA9, 0x24, 0x26, 0x57, 0xCC, + 0x48, 0x30, 0x68, 0x07, 0xB3, 0x2B, 0xEF, 0xDE + }, + { + 0x73, 0x66, 0x67, 0xC9, 0x36, 0x4C, 0xE1, 0x2D, + 0xB8, 0xF6, 0xB1, 0x43, 0xC6, 0xC1, 0x78, 0xCD, + 0xEF, 0x1E, 0x14, 0x45, 0xBC, 0x5A, 0x2F, 0x26, + 0x34, 0xF0, 0x8E, 0x99, 0x32, 0x27, 0x3C, 0xAA + }, + { + 0xE1, 0x5F, 0x36, 0x8B, 0x44, 0x06, 0xC1, 0xF6, + 0x55, 0x57, 0xC8, 0x35, 0x5C, 0xBE, 0x69, 0x4B, + 0x63, 0x3E, 0x26, 0xF1, 0x55, 0xF5, 0x2B, 0x7D, + 0xA9, 0x4C, 0xFB, 0x23, 0xFD, 0x4A, 0x5D, 0x96 + }, + { + 0x43, 0x7A, 0xB2, 0xD7, 0x4F, 0x50, 0xCA, 0x86, + 0xCC, 0x3D, 0xE9, 0xBE, 0x70, 0xE4, 0x55, 0x48, + 0x25, 0xE3, 0x3D, 0x82, 0x4B, 0x3A, 0x49, 0x23, + 0x62, 0xE2, 0xE9, 0xD6, 0x11, 0xBC, 0x57, 0x9D + }, + { + 0x2B, 0x91, 0x58, 0xC7, 0x22, 0x89, 0x8E, 0x52, + 0x6D, 0x2C, 0xDD, 0x3F, 0xC0, 0x88, 0xE9, 0xFF, + 0xA7, 0x9A, 0x9B, 0x73, 0xB7, 0xD2, 0xD2, 0x4B, + 0xC4, 0x78, 0xE2, 0x1C, 0xDB, 0x3B, 0x67, 0x63 + }, + { + 0x0C, 0x8A, 0x36, 0x59, 0x7D, 0x74, 0x61, 0xC6, + 0x3A, 0x94, 0x73, 0x28, 0x21, 0xC9, 0x41, 0x85, + 0x6C, 0x66, 0x83, 0x76, 0x60, 0x6C, 0x86, 0xA5, + 0x2D, 0xE0, 0xEE, 0x41, 0x04, 0xC6, 0x15, 0xDB + }, +}; + + + + +static const uint8_t blake2bp_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0xB5, 0xEF, 0x81, 0x1A, 0x80, 0x38, 0xF7, 0x0B, + 0x62, 0x8F, 0xA8, 0xB2, 0x94, 0xDA, 0xAE, 0x74, + 0x92, 0xB1, 0xEB, 0xE3, 0x43, 0xA8, 0x0E, 0xAA, + 0xBB, 0xF1, 0xF6, 0xAE, 0x66, 0x4D, 0xD6, 0x7B, + 0x9D, 0x90, 0xB0, 0x12, 0x07, 0x91, 0xEA, 0xB8, + 0x1D, 0xC9, 0x69, 0x85, 0xF2, 0x88, 0x49, 0xF6, + 0xA3, 0x05, 0x18, 0x6A, 0x85, 0x50, 0x1B, 0x40, + 0x51, 0x14, 0xBF, 0xA6, 0x78, 0xDF, 0x93, 0x80 + }, + { + 0xA1, 0x39, 0x28, 0x0E, 0x72, 0x75, 0x7B, 0x72, + 0x3E, 0x64, 0x73, 0xD5, 0xBE, 0x59, 0xF3, 0x6E, + 0x9D, 0x50, 0xFC, 0x5C, 0xD7, 0xD4, 0x58, 0x5C, + 0xBC, 0x09, 0x80, 0x48, 0x95, 0xA3, 0x6C, 0x52, + 0x12, 0x42, 0xFB, 0x27, 0x89, 0xF8, 0x5C, 0xB9, + 0xE3, 0x54, 0x91, 0xF3, 0x1D, 0x4A, 0x69, 0x52, + 0xF9, 0xD8, 0xE0, 0x97, 0xAE, 0xF9, 0x4F, 0xA1, + 0xCA, 0x0B, 0x12, 0x52, 0x57, 0x21, 0xF0, 0x3D + }, + { + 0xEF, 0x8C, 0xDA, 0x96, 0x35, 0xD5, 0x06, 0x3A, + 0xF8, 0x11, 0x15, 0xDA, 0x3C, 0x52, 0x32, 0x5A, + 0x86, 0xE8, 0x40, 0x74, 0xF9, 0xF7, 0x24, 0xB7, + 0xCB, 0xD0, 0xB0, 0x85, 0x6F, 0xF0, 0x01, 0x77, + 0xCD, 0xD2, 0x83, 0xC2, 0x98, 0x32, 0x6C, 0xD0, + 0x91, 0x77, 0x54, 0xC5, 0x24, 0x1F, 0x14, 0x80, + 0xFB, 0x50, 0x9C, 0xF2, 0xD2, 0xC4, 0x49, 0x81, + 0x80, 0x77, 0xAE, 0x35, 0xFC, 0x33, 0x07, 0x37 + }, + { + 0x8C, 0xF9, 0x33, 0xA2, 0xD3, 0x61, 0xA3, 0xE6, + 0xA1, 0x36, 0xDB, 0xE4, 0xA0, 0x1E, 0x79, 0x03, + 0x79, 0x7A, 0xD6, 0xCE, 0x76, 0x6E, 0x2B, 0x91, + 0xB9, 0xB4, 0xA4, 0x03, 0x51, 0x27, 0xD6, 0x5F, + 0x4B, 0xE8, 0x65, 0x50, 0x11, 0x94, 0x18, 0xE2, + 0x2D, 0xA0, 0x0F, 0xD0, 0x6B, 0xF2, 0xB2, 0x75, + 0x96, 0xB3, 0x7F, 0x06, 0xBE, 0x0A, 0x15, 0x4A, + 0xAF, 0x7E, 0xCA, 0x54, 0xC4, 0x52, 0x0B, 0x97 + }, + { + 0x24, 0xDC, 0x1E, 0x6D, 0xC4, 0xE5, 0x1A, 0x3A, + 0x3C, 0x8D, 0xA6, 0x7A, 0xAC, 0xB4, 0xC5, 0x41, + 0xE4, 0x18, 0x18, 0xD1, 0x80, 0xE5, 0xBB, 0x69, + 0x75, 0x3D, 0xBB, 0xFF, 0x2F, 0x44, 0xD0, 0xE7, + 0xDA, 0x83, 0x03, 0x86, 0xBF, 0xC8, 0x3B, 0x27, + 0xA5, 0x9D, 0xBB, 0x62, 0xB9, 0x64, 0xFC, 0x8E, + 0xA6, 0xCB, 0xDF, 0x30, 0x49, 0xBF, 0xF8, 0x1F, + 0x24, 0xF3, 0x48, 0xDB, 0x4E, 0xFD, 0x0D, 0x07 + }, + { + 0xBC, 0x23, 0xF5, 0xAB, 0xDF, 0xFD, 0x6A, 0x32, + 0xA5, 0xD4, 0x08, 0x11, 0x26, 0x2E, 0xD4, 0x47, + 0x9E, 0xF7, 0x0B, 0x42, 0x33, 0xCA, 0x20, 0x5B, + 0xC5, 0xB9, 0xBF, 0x85, 0x96, 0x73, 0x19, 0x82, + 0xD0, 0x41, 0x69, 0xA9, 0x04, 0xDD, 0x43, 0xB0, + 0xE0, 0xF9, 0x48, 0x99, 0xF7, 0x33, 0x02, 0x2D, + 0x24, 0xD8, 0x4F, 0xAD, 0x0A, 0x99, 0x16, 0x00, + 0xF1, 0x97, 0x9B, 0x27, 0x2A, 0xD6, 0x20, 0x73 + }, + { + 0xEF, 0x10, 0x7F, 0xCD, 0x0D, 0x92, 0xD8, 0x4E, + 0xF5, 0xEF, 0x94, 0x63, 0xE6, 0xE9, 0x62, 0x41, + 0x25, 0x45, 0x29, 0xD2, 0xB9, 0x7F, 0xDB, 0xE5, + 0x64, 0x19, 0x07, 0x0A, 0xDB, 0xC7, 0xD5, 0x70, + 0x6F, 0xEB, 0x8F, 0x44, 0x95, 0x79, 0x81, 0x9E, + 0xD4, 0xBE, 0x61, 0x97, 0x85, 0xFF, 0xFA, 0xAF, + 0x0D, 0x97, 0x89, 0xCF, 0xE7, 0x26, 0x24, 0x9A, + 0xB0, 0x8C, 0x94, 0x68, 0xCB, 0x5F, 0xDE, 0x22 + }, + { + 0x23, 0x1F, 0xBF, 0xB7, 0xA1, 0xDD, 0xC5, 0xB7, + 0x49, 0x33, 0xA2, 0x85, 0xA4, 0x22, 0x4C, 0x04, + 0x9C, 0xBA, 0x14, 0x85, 0xCE, 0x35, 0x64, 0x0D, + 0x9C, 0x51, 0x6E, 0xD7, 0x8E, 0xAA, 0x22, 0x6D, + 0x36, 0xF6, 0x5B, 0x25, 0x89, 0xB8, 0x26, 0xC4, + 0x59, 0xFA, 0x6A, 0x91, 0xC4, 0x26, 0xFD, 0x2A, + 0x8A, 0xB4, 0x61, 0xC9, 0x76, 0x7E, 0x7B, 0xDD, + 0x99, 0x6B, 0xEF, 0x5A, 0x78, 0xF4, 0x81, 0xB7 + }, + { + 0x3A, 0x83, 0x1F, 0x2D, 0xA9, 0x69, 0xB9, 0xB7, + 0x36, 0x0E, 0x74, 0xEE, 0x53, 0xB5, 0x18, 0x98, + 0x0A, 0x5E, 0xBC, 0xDF, 0xD4, 0xEE, 0x23, 0xED, + 0x80, 0x5C, 0x26, 0x39, 0x4D, 0x18, 0x24, 0x20, + 0x8D, 0x7E, 0x8F, 0x63, 0x27, 0xD4, 0xEC, 0x87, + 0x97, 0x9C, 0xE4, 0xAF, 0x8A, 0xB0, 0x97, 0xD6, + 0x9E, 0x26, 0x1C, 0xA3, 0x2D, 0xB0, 0xEE, 0xFD, + 0xBC, 0x18, 0xD1, 0x63, 0x77, 0xA6, 0xBD, 0x20 + }, + { + 0x83, 0x49, 0xA2, 0x0F, 0xDD, 0xBA, 0xE1, 0xD8, + 0x47, 0x2B, 0x67, 0xF0, 0x34, 0x7A, 0xA0, 0xFD, + 0x40, 0x4D, 0x65, 0xC6, 0xFA, 0x14, 0x72, 0xB3, + 0x10, 0x39, 0x0D, 0x75, 0x65, 0xBA, 0x6B, 0xC1, + 0x02, 0x60, 0xD3, 0xDC, 0xE6, 0xA1, 0x4F, 0x4D, + 0xD9, 0xB8, 0xB3, 0xE0, 0xA0, 0xC4, 0x7F, 0x6D, + 0xB7, 0xE7, 0x10, 0x0A, 0x7A, 0x9B, 0x64, 0xA8, + 0x44, 0xF0, 0x10, 0x64, 0xD0, 0x79, 0x05, 0xC5 + }, + { + 0x23, 0x9A, 0xE3, 0xD6, 0x85, 0x9C, 0x7C, 0x97, + 0x2A, 0x5D, 0xC8, 0xB9, 0xC5, 0x5A, 0xEB, 0x93, + 0x85, 0x90, 0xCF, 0xB8, 0x55, 0x2A, 0xA3, 0x05, + 0xA6, 0xF6, 0xF3, 0x1F, 0xFA, 0x95, 0xA8, 0x40, + 0xF4, 0xEC, 0x36, 0xF6, 0xFB, 0x8F, 0x83, 0xB6, + 0x9C, 0x1D, 0xA9, 0x81, 0xFC, 0x9B, 0xA1, 0x63, + 0x60, 0xDB, 0x0F, 0x4F, 0x7C, 0x68, 0xEB, 0x54, + 0x3E, 0xD5, 0x8B, 0x28, 0x75, 0x6A, 0x1E, 0x0D + }, + { + 0x7C, 0x56, 0x73, 0x28, 0x63, 0x08, 0x40, 0x8F, + 0xBC, 0x62, 0x24, 0x0E, 0x07, 0x47, 0x28, 0xB2, + 0x7A, 0x57, 0x5C, 0xAD, 0x2A, 0x15, 0x6E, 0x00, + 0xB5, 0xC0, 0x8B, 0x21, 0x8D, 0x88, 0x87, 0x79, + 0x1E, 0x47, 0xBF, 0x10, 0xB0, 0xBC, 0x61, 0xA5, + 0x82, 0x54, 0x5A, 0x24, 0x69, 0x63, 0x9C, 0xE6, + 0x28, 0xC4, 0x0F, 0x20, 0xEA, 0x8B, 0x84, 0x9C, + 0xD0, 0x05, 0x44, 0x5F, 0x29, 0xA0, 0x8C, 0xCE + }, + { + 0xDD, 0x07, 0x7E, 0x76, 0x9E, 0x0D, 0xEF, 0x78, + 0xDD, 0x7A, 0xAD, 0xD5, 0x7D, 0x58, 0x42, 0x1B, + 0xDA, 0x3A, 0x1A, 0x4E, 0x69, 0x72, 0x05, 0x9F, + 0x8E, 0x64, 0x9C, 0xD6, 0xBC, 0xA4, 0x4A, 0x13, + 0xAB, 0x71, 0xEB, 0x53, 0x5D, 0x24, 0x49, 0x22, + 0x94, 0x84, 0x65, 0xD7, 0x3B, 0xD6, 0x4E, 0xFB, + 0x09, 0x10, 0x46, 0x94, 0x90, 0x66, 0x65, 0x36, + 0x03, 0x57, 0x5A, 0x2E, 0x89, 0x1E, 0xBD, 0x54 + }, + { + 0xB3, 0x6C, 0xEF, 0x28, 0x53, 0x2B, 0x40, 0xD8, + 0x17, 0x86, 0x28, 0xF0, 0xFA, 0xB5, 0xE5, 0xB4, + 0xA1, 0xDE, 0xC0, 0xC0, 0xE9, 0x11, 0xD7, 0x27, + 0xBF, 0x09, 0x49, 0x0F, 0x5E, 0x8D, 0x9F, 0xAC, + 0x57, 0x21, 0x3F, 0xD2, 0xA2, 0xD1, 0x2E, 0xD3, + 0xD7, 0x7A, 0x41, 0xF5, 0xE2, 0xFE, 0xCC, 0x40, + 0xE4, 0xEE, 0xCA, 0x16, 0x12, 0xF5, 0x1C, 0x45, + 0x23, 0x31, 0xAE, 0x93, 0x96, 0x62, 0x35, 0xBC + }, + { + 0xDE, 0x73, 0x7D, 0xBC, 0x61, 0x2E, 0xBD, 0x31, + 0xBC, 0x49, 0xA2, 0xD7, 0xC6, 0x44, 0xD4, 0xB1, + 0x37, 0x81, 0x74, 0x19, 0x42, 0x1C, 0x32, 0xF4, + 0xE7, 0x51, 0x14, 0xD8, 0x99, 0xE3, 0x13, 0x1D, + 0x45, 0xCA, 0x54, 0x51, 0x24, 0x8F, 0x24, 0x16, + 0x9F, 0xBF, 0x17, 0xEE, 0x60, 0xA9, 0xB7, 0x07, + 0x98, 0xA4, 0xB9, 0x37, 0xCE, 0xA6, 0x27, 0x95, + 0x28, 0x96, 0x39, 0xD1, 0x8F, 0xCD, 0x89, 0xE4 + }, + { + 0xB4, 0xC1, 0xBB, 0xCB, 0xBC, 0xCD, 0xFC, 0xE4, + 0xD2, 0xBE, 0x9D, 0xCD, 0xB9, 0x83, 0xC1, 0xB0, + 0x20, 0xC5, 0xF7, 0x20, 0xDA, 0x5B, 0xEC, 0xF4, + 0xCB, 0x2A, 0x9A, 0x3D, 0x1B, 0x8D, 0x23, 0xCE, + 0xA7, 0xA9, 0xF5, 0xFD, 0x70, 0xD3, 0x74, 0x0E, + 0xCD, 0x67, 0xCE, 0x7D, 0x1E, 0x9C, 0x5E, 0x31, + 0xA3, 0x30, 0x2D, 0xF6, 0x6A, 0x9B, 0x5D, 0x54, + 0x30, 0x44, 0x90, 0xFB, 0xE1, 0xC4, 0xA8, 0xB9 + }, + { + 0xB1, 0xD6, 0x5E, 0x70, 0xC6, 0x9B, 0xA7, 0xE3, + 0xA7, 0x28, 0xE8, 0xB6, 0x44, 0x94, 0x93, 0xF2, + 0x37, 0x51, 0x0B, 0x23, 0xB6, 0xE7, 0x7D, 0x95, + 0x84, 0xD0, 0x5F, 0xF4, 0xD3, 0xF0, 0x87, 0x80, + 0x92, 0x9D, 0x74, 0xFA, 0x5B, 0xED, 0x9B, 0x75, + 0xD4, 0xD6, 0xD1, 0xCA, 0x91, 0xAB, 0x8D, 0x26, + 0x37, 0xDC, 0x2E, 0x79, 0xBA, 0x0F, 0xE0, 0x59, + 0x4A, 0xCD, 0x68, 0xFB, 0x3C, 0xC6, 0x60, 0xB9 + }, + { + 0xDA, 0x79, 0xF7, 0x29, 0xEA, 0xB9, 0x8C, 0x04, + 0xF3, 0x7F, 0xCC, 0x85, 0x4B, 0x69, 0xA8, 0x4E, + 0x46, 0x7D, 0xEA, 0x1E, 0x77, 0x82, 0xE7, 0xAF, + 0x02, 0xCB, 0x44, 0xA4, 0x9D, 0x21, 0x0D, 0x25, + 0x23, 0x68, 0x3D, 0x42, 0x0A, 0xC1, 0xDE, 0xC8, + 0xAD, 0x1F, 0xB4, 0x0E, 0x65, 0xAB, 0x3F, 0xE2, + 0x51, 0xA8, 0x51, 0xE2, 0x83, 0xD8, 0x58, 0x38, + 0x08, 0x42, 0x61, 0x30, 0x1E, 0xCD, 0x08, 0x9B + }, + { + 0x71, 0x40, 0x40, 0x40, 0x39, 0x21, 0xAE, 0x55, + 0x48, 0xA2, 0x03, 0x39, 0xD6, 0x9E, 0x09, 0x3F, + 0x60, 0x9A, 0xA9, 0x9C, 0x22, 0xDB, 0x72, 0x59, + 0x1D, 0x1E, 0xF4, 0xFC, 0xB0, 0xAF, 0x01, 0x61, + 0x73, 0xE5, 0x77, 0xD8, 0xC1, 0xA3, 0x06, 0x3B, + 0x44, 0x3A, 0x0E, 0x48, 0xF3, 0x13, 0xCF, 0x2E, + 0x0F, 0x9B, 0x0C, 0x2E, 0xF9, 0x6A, 0x96, 0xC4, + 0x24, 0x32, 0x2C, 0xCC, 0x0C, 0xD5, 0x30, 0x4C + }, + { + 0x8B, 0x2E, 0x8C, 0x3F, 0x0E, 0x3C, 0x31, 0x9B, + 0xA6, 0x7E, 0x86, 0x01, 0x4B, 0xDA, 0x68, 0x3E, + 0x53, 0x57, 0xA0, 0x40, 0x37, 0xB4, 0x56, 0x32, + 0x86, 0xAC, 0x89, 0xCD, 0xDB, 0x7E, 0xE0, 0x4C, + 0xF6, 0x67, 0x5F, 0x9A, 0xB6, 0x1F, 0xC8, 0x33, + 0x2D, 0x21, 0x8D, 0x2B, 0xCA, 0x97, 0x15, 0xE7, + 0xDB, 0xE5, 0x83, 0x72, 0xD1, 0xEE, 0xBF, 0x6B, + 0xC2, 0x94, 0x84, 0x71, 0xCF, 0xCE, 0xBB, 0x77 + }, + { + 0x32, 0xEE, 0x95, 0x49, 0xD4, 0xE3, 0x2F, 0x4B, + 0xE9, 0xC5, 0x00, 0xBD, 0x85, 0x43, 0xAF, 0xD0, + 0xB6, 0x97, 0x82, 0xD0, 0xB3, 0xFF, 0x7E, 0xD4, + 0x7A, 0x88, 0x1A, 0x0E, 0x49, 0x1F, 0x37, 0x65, + 0x0A, 0x21, 0xB2, 0x6C, 0x3F, 0x5D, 0x0A, 0x64, + 0xE0, 0x90, 0x58, 0xB3, 0x00, 0x4A, 0x23, 0x68, + 0xB9, 0x50, 0xE4, 0x72, 0x30, 0xC2, 0x29, 0x66, + 0xD3, 0xF7, 0x9D, 0xA7, 0xBA, 0xA0, 0xB8, 0x7F + }, + { + 0xCA, 0xE7, 0xF2, 0x92, 0x71, 0x37, 0x82, 0xC4, + 0x71, 0xFE, 0x31, 0x78, 0xA9, 0x42, 0x0C, 0xD4, + 0xC1, 0x1F, 0xCD, 0x3F, 0x6D, 0xBE, 0x5D, 0x15, + 0xC8, 0x4A, 0xB7, 0x35, 0x3C, 0x73, 0x9E, 0xF0, + 0x64, 0x16, 0x39, 0xA2, 0xF9, 0x2A, 0xED, 0x31, + 0xC5, 0x6A, 0x20, 0x21, 0xCC, 0x5E, 0x58, 0xCB, + 0xEA, 0xD3, 0x74, 0xE2, 0xDC, 0x8A, 0x0D, 0xBC, + 0xE5, 0x45, 0x0F, 0xE7, 0xA0, 0x18, 0xCF, 0xA4 + }, + { + 0xF1, 0x7F, 0xEF, 0xAE, 0xAE, 0x7D, 0x40, 0xCD, + 0x88, 0x5D, 0xAC, 0x0B, 0xC3, 0x50, 0xC0, 0x27, + 0x36, 0x68, 0xEA, 0x02, 0x22, 0xDF, 0x5C, 0x75, + 0x69, 0x4F, 0x5C, 0xB3, 0xA3, 0x21, 0x51, 0x9F, + 0x6E, 0x0E, 0xC4, 0x3B, 0xA0, 0xC8, 0x59, 0x3D, + 0xC7, 0x34, 0x13, 0x41, 0xE5, 0x19, 0x48, 0x8F, + 0x20, 0xAB, 0xD5, 0xB8, 0x12, 0x4D, 0xFA, 0xCE, + 0xA5, 0xCD, 0xE0, 0x96, 0x5B, 0x69, 0x70, 0xF9 + }, + { + 0xE2, 0xCF, 0x86, 0xDD, 0xC8, 0x42, 0x4E, 0xE5, + 0x47, 0xEB, 0x72, 0x45, 0xB7, 0x32, 0x5E, 0x02, + 0xF2, 0xE3, 0xAC, 0x01, 0x3C, 0x8D, 0x38, 0x6B, + 0x3D, 0x2E, 0x09, 0x20, 0x8A, 0x9B, 0xCC, 0x0B, + 0x44, 0xC4, 0xC4, 0x38, 0xEA, 0xAF, 0x52, 0xD2, + 0x07, 0x7E, 0x91, 0x77, 0xEB, 0x8E, 0xE1, 0xD5, + 0x90, 0x75, 0xB5, 0x25, 0x92, 0x20, 0x20, 0x62, + 0x22, 0x93, 0x54, 0xBF, 0x23, 0xC9, 0x62, 0x39 + }, + { + 0x38, 0xF2, 0x6A, 0x11, 0x02, 0xCB, 0x16, 0x2D, + 0x35, 0x1F, 0x84, 0x3B, 0x3C, 0x49, 0xF6, 0xFF, + 0x85, 0x44, 0x16, 0x33, 0xB6, 0x70, 0x4A, 0x28, + 0x6A, 0xF8, 0x1C, 0xCB, 0xAE, 0x5A, 0x67, 0xD3, + 0x01, 0x5C, 0xC0, 0xEF, 0xAF, 0xB7, 0x05, 0x7D, + 0xC2, 0xB2, 0x8D, 0x67, 0x66, 0xE8, 0x2A, 0x06, + 0x8A, 0x4C, 0x0B, 0x52, 0x4B, 0x66, 0xD0, 0xA6, + 0x32, 0x77, 0x5D, 0x93, 0x06, 0x15, 0x75, 0xF9 + }, + { + 0xA2, 0xC4, 0x30, 0x2D, 0xAC, 0xA7, 0xA7, 0xC6, + 0x32, 0xF6, 0x76, 0x30, 0x4E, 0x62, 0x75, 0xC1, + 0xC1, 0xF0, 0xDB, 0xFE, 0x38, 0xDC, 0x57, 0x1C, + 0xB2, 0x3E, 0x1F, 0x7B, 0xA5, 0xDC, 0x18, 0x18, + 0x0F, 0xC4, 0x8A, 0x01, 0x5F, 0x92, 0x7C, 0x89, + 0x96, 0x7C, 0x1E, 0x10, 0x4E, 0x66, 0xF5, 0xEA, + 0x5B, 0x2D, 0xD3, 0x1D, 0x78, 0x1C, 0x38, 0x49, + 0xBF, 0xC6, 0x49, 0x22, 0x0C, 0x38, 0x5C, 0x82 + }, + { + 0xC1, 0x9C, 0x6B, 0x3F, 0xB5, 0x35, 0x2B, 0xB3, + 0x94, 0xC2, 0x68, 0x46, 0x52, 0x3C, 0x25, 0xE8, + 0x26, 0x5D, 0x50, 0x5F, 0x50, 0x1F, 0x96, 0x03, + 0xA4, 0xF8, 0xBD, 0x55, 0x38, 0x6C, 0xF4, 0xCC, + 0x9F, 0x4D, 0x71, 0xF3, 0x8F, 0xF4, 0x45, 0xF4, + 0xEF, 0xC8, 0x30, 0x98, 0xD4, 0x79, 0x69, 0x33, + 0x4E, 0x79, 0xA2, 0xBC, 0xB4, 0x02, 0x6B, 0xC6, + 0x3B, 0x79, 0x59, 0xDE, 0xDB, 0x62, 0xB7, 0xBD + }, + { + 0x1F, 0x4A, 0xB9, 0x84, 0x0A, 0x1C, 0xFA, 0x8F, + 0xE6, 0xC5, 0x62, 0x2D, 0x9B, 0x53, 0x8B, 0xEC, + 0xB8, 0x80, 0x7A, 0x87, 0x78, 0xB6, 0x9D, 0x93, + 0x05, 0xF9, 0x08, 0x57, 0x65, 0x73, 0xB2, 0x0C, + 0xA3, 0x70, 0x4E, 0x89, 0x12, 0x97, 0x26, 0xD5, + 0x02, 0xE1, 0x98, 0x58, 0x8D, 0x07, 0x26, 0x68, + 0xBF, 0x03, 0x63, 0x0B, 0x5B, 0x5A, 0x92, 0x32, + 0xFF, 0x39, 0x25, 0x27, 0x24, 0x9D, 0xF9, 0x9B + }, + { + 0xFE, 0x03, 0x17, 0x7B, 0x58, 0xB4, 0x88, 0x83, + 0xA8, 0x6D, 0x42, 0x68, 0x33, 0x4B, 0x95, 0x91, + 0xD9, 0xFB, 0xD8, 0xBF, 0x7C, 0xC2, 0xAA, 0xCC, + 0x50, 0x25, 0xEF, 0x47, 0x6B, 0x45, 0x33, 0xBA, + 0x7B, 0xD7, 0x81, 0xDF, 0x01, 0x11, 0x47, 0xB3, + 0xCF, 0x51, 0x1D, 0x8B, 0x3D, 0xCD, 0x8C, 0x78, + 0x0D, 0x30, 0xD7, 0xDA, 0x71, 0x8C, 0x22, 0x44, + 0x23, 0x19, 0x81, 0x7B, 0xE3, 0x18, 0x6B, 0xC5 + }, + { + 0xF4, 0xC3, 0xB0, 0x59, 0x10, 0x5B, 0x6A, 0xA5, + 0xFE, 0x78, 0x84, 0x3A, 0x07, 0xD9, 0x4F, 0x71, + 0x20, 0x62, 0xCB, 0x5A, 0x4D, 0xD6, 0x05, 0x9F, + 0x97, 0x90, 0x4D, 0x0C, 0x57, 0x97, 0x3B, 0xA8, + 0xDF, 0x71, 0xD1, 0x5A, 0x51, 0x1A, 0x06, 0x68, + 0x64, 0xFE, 0x45, 0x5E, 0xDC, 0x9E, 0x5F, 0x16, + 0x52, 0x4C, 0xEC, 0x7E, 0xE2, 0x48, 0xEE, 0x3E, + 0xC9, 0x29, 0x06, 0x3B, 0xD1, 0x07, 0x98, 0xDA + }, + { + 0x57, 0xA1, 0x6F, 0x96, 0x4B, 0x18, 0x1B, 0x12, + 0x03, 0xA5, 0x80, 0x3B, 0x73, 0x81, 0x7D, 0x77, + 0x44, 0x83, 0x82, 0x6C, 0xEA, 0x11, 0x3B, 0x9C, + 0xCF, 0xCF, 0x0E, 0xB8, 0x7C, 0xB2, 0x30, 0x64, + 0x28, 0x49, 0x62, 0xD8, 0x47, 0xBB, 0x1F, 0xAE, + 0x8C, 0xBF, 0x5C, 0xC6, 0x3B, 0x3C, 0xEA, 0xA1, + 0x24, 0x1E, 0xA4, 0x2C, 0x63, 0xF8, 0x98, 0x01, + 0x1F, 0xC4, 0xDB, 0xCA, 0xE6, 0xF5, 0xE8, 0xC5 + }, + { + 0x79, 0x52, 0xFC, 0x83, 0xAC, 0xF1, 0x3A, 0x95, + 0xCA, 0x9C, 0x27, 0xA2, 0x15, 0x6D, 0x9C, 0x1B, + 0x63, 0x00, 0xB0, 0xEF, 0x79, 0x0F, 0x57, 0x2B, + 0xC3, 0x94, 0xC6, 0x77, 0xF7, 0xC1, 0x46, 0x29, + 0xEB, 0xD8, 0xE7, 0xD5, 0xD7, 0xC7, 0xF1, 0xA5, + 0xEB, 0xBD, 0xC3, 0x90, 0xCC, 0x08, 0xCD, 0x58, + 0xC2, 0x00, 0x89, 0x00, 0xCB, 0x55, 0xEB, 0x05, + 0xE4, 0x44, 0xA6, 0x8C, 0x3B, 0x39, 0x3E, 0x60 + }, + { + 0x2C, 0x22, 0x40, 0xD6, 0xB5, 0x41, 0xF4, 0x29, + 0x4F, 0xF9, 0x76, 0x79, 0x1D, 0x35, 0xE6, 0xA2, + 0xD4, 0x92, 0xF5, 0x7A, 0x91, 0x5F, 0xBA, 0xC5, + 0x83, 0x26, 0x60, 0xC1, 0x0E, 0x9C, 0x96, 0x46, + 0x5C, 0x7B, 0xD5, 0xFC, 0xA7, 0x51, 0xBF, 0x68, + 0xE2, 0x67, 0x3A, 0x63, 0x8E, 0x3A, 0xF7, 0x35, + 0xB0, 0x20, 0x91, 0xD7, 0x5D, 0x1A, 0x7F, 0x89, + 0xE3, 0xF7, 0x61, 0xC5, 0xDF, 0x82, 0x1A, 0x6B + }, + { + 0x59, 0xDC, 0x84, 0x6D, 0x34, 0x05, 0xCC, 0xD8, + 0x06, 0xF8, 0xFA, 0x20, 0xC8, 0x96, 0x9E, 0xF6, + 0x8A, 0x43, 0x85, 0xEF, 0x6C, 0x27, 0x4E, 0xEE, + 0x6D, 0xC0, 0x69, 0x2C, 0x3E, 0xCF, 0xB1, 0xA8, + 0x34, 0xCE, 0x64, 0x43, 0x76, 0xC5, 0x2B, 0x80, + 0x42, 0x1B, 0xAE, 0x94, 0xD6, 0xC7, 0xFD, 0xCC, + 0xA5, 0xA8, 0xF1, 0x85, 0x9C, 0x45, 0xA1, 0x0C, + 0x4E, 0xB2, 0x74, 0x82, 0x6F, 0x1F, 0x08, 0x9F + }, + { + 0xB7, 0x52, 0x96, 0x27, 0x07, 0xA1, 0x7B, 0x66, + 0x4F, 0xAE, 0xB3, 0x13, 0xE2, 0xB9, 0x52, 0xDC, + 0x03, 0xE7, 0x4A, 0x7E, 0x94, 0x47, 0x09, 0x8A, + 0xA6, 0xD4, 0xEA, 0x5B, 0xD2, 0x87, 0xD0, 0x7A, + 0x12, 0x25, 0xEC, 0xED, 0xA9, 0x81, 0x15, 0x70, + 0x58, 0x0A, 0x51, 0x2B, 0x2B, 0x20, 0xB3, 0xFC, + 0xFC, 0xA7, 0x0B, 0x44, 0xF6, 0x45, 0x4E, 0xF3, + 0xC3, 0x52, 0x4C, 0xCA, 0x6B, 0x69, 0x47, 0x5B + }, + { + 0xDA, 0x0D, 0x8E, 0x54, 0x61, 0xF8, 0x10, 0x24, + 0xEF, 0xFE, 0xED, 0x5D, 0x70, 0x76, 0xA0, 0x4F, + 0xED, 0xED, 0xAC, 0x57, 0xE7, 0xC9, 0x8A, 0x59, + 0x45, 0xBF, 0xDE, 0x66, 0x75, 0x58, 0x18, 0x85, + 0x1B, 0xE1, 0x13, 0x6B, 0x71, 0xF4, 0x33, 0xA5, + 0x6B, 0xDA, 0x18, 0x41, 0xAE, 0x71, 0x39, 0x2C, + 0x4B, 0x82, 0x90, 0x82, 0x63, 0x59, 0xF5, 0x87, + 0x22, 0x3C, 0x3E, 0xF7, 0x37, 0xFF, 0x73, 0x2A + }, + { + 0xED, 0xB8, 0x6A, 0x23, 0x7C, 0x6F, 0x13, 0x7D, + 0xFB, 0xB3, 0x47, 0x01, 0x1E, 0xDB, 0x4C, 0x6E, + 0x86, 0x1F, 0x4D, 0x58, 0x14, 0x60, 0x85, 0x46, + 0x34, 0x41, 0x04, 0x2F, 0xA3, 0x63, 0x16, 0xF1, + 0xFA, 0xF8, 0x87, 0x11, 0xBB, 0x0F, 0x18, 0x11, + 0xDF, 0xBB, 0xBF, 0xA7, 0xB5, 0x1F, 0x9C, 0xE2, + 0xD4, 0x96, 0x05, 0x24, 0x3E, 0xD0, 0x16, 0xCB, + 0xAD, 0x68, 0x85, 0xEA, 0xE2, 0x03, 0x67, 0x4F + }, + { + 0xE6, 0xD8, 0xE0, 0xFB, 0xAA, 0x29, 0xDB, 0xEB, + 0x60, 0xF3, 0xC7, 0xF9, 0x85, 0xBA, 0xD7, 0x54, + 0xD7, 0x21, 0xAA, 0xC6, 0x3D, 0xA6, 0xF4, 0x49, + 0x0C, 0x9D, 0x7E, 0xA2, 0x31, 0xD2, 0x62, 0x2F, + 0xDF, 0xDE, 0xF1, 0x48, 0xD0, 0xCA, 0x44, 0x2B, + 0x8D, 0x59, 0xCF, 0x3E, 0x4F, 0x98, 0x35, 0xCB, + 0xC2, 0x40, 0xAF, 0x40, 0xFB, 0xA6, 0x3A, 0x2E, + 0xA5, 0xA2, 0x35, 0xD4, 0x6E, 0xEA, 0x6E, 0xAC + }, + { + 0xD4, 0xE4, 0x63, 0xC4, 0x88, 0x29, 0x87, 0xEB, + 0x44, 0xA5, 0xED, 0x0C, 0x82, 0x1D, 0x68, 0xB0, + 0xFE, 0xF9, 0x9D, 0x6F, 0x53, 0xA5, 0x7B, 0xF3, + 0x19, 0xBD, 0xAC, 0x25, 0xAC, 0x38, 0xEB, 0x0B, + 0x23, 0xE1, 0x13, 0x8C, 0x00, 0x12, 0xF5, 0xF3, + 0x83, 0x46, 0xA1, 0xDE, 0x9D, 0x4A, 0x99, 0x2A, + 0x64, 0xB9, 0x42, 0x83, 0x4A, 0x85, 0x6E, 0xFB, + 0xAA, 0x06, 0x20, 0xBD, 0xA2, 0x9F, 0x6A, 0x86 + }, + { + 0x42, 0xD8, 0x10, 0xD0, 0x1C, 0x2D, 0xA2, 0x47, + 0x35, 0xF0, 0x4A, 0x5E, 0x90, 0x13, 0x38, 0xFD, + 0xFC, 0x2D, 0xE1, 0x71, 0x5F, 0xF6, 0x64, 0x3A, + 0x37, 0x2F, 0x88, 0x0E, 0x6C, 0x5C, 0x6C, 0x13, + 0xD2, 0xB3, 0xAD, 0x70, 0x77, 0x46, 0x9D, 0x64, + 0x33, 0x54, 0x05, 0x4D, 0x32, 0xDD, 0x80, 0x49, + 0xEA, 0x63, 0x73, 0x2B, 0x57, 0x45, 0xBD, 0xB2, + 0x3B, 0xE2, 0xB5, 0x8E, 0x48, 0xC1, 0x01, 0x3A + }, + { + 0xCF, 0xBF, 0x54, 0x30, 0x07, 0x6F, 0x82, 0x5A, + 0x3B, 0xBB, 0x88, 0xC1, 0xBC, 0x0A, 0xEF, 0x61, + 0x25, 0x9E, 0x8F, 0x4D, 0x5F, 0xA3, 0x3C, 0x39, + 0x82, 0x50, 0x62, 0xF1, 0x5D, 0x19, 0xFD, 0x4A, + 0x01, 0x82, 0xCD, 0x97, 0x36, 0xD2, 0xAE, 0xC9, + 0x74, 0x9C, 0xCF, 0x83, 0x18, 0x6C, 0x35, 0x74, + 0xAB, 0x94, 0x42, 0x65, 0x40, 0x66, 0x0A, 0x9D, + 0xB8, 0xC3, 0xAA, 0xBB, 0xCB, 0xDD, 0x9D, 0x0F + }, + { + 0x6C, 0x24, 0x34, 0xA1, 0xAF, 0xA1, 0x57, 0xAC, + 0xCC, 0x34, 0xA5, 0xC4, 0x87, 0x2D, 0xFF, 0x69, + 0xFE, 0x7F, 0x31, 0x96, 0xCB, 0x1A, 0x75, 0x0C, + 0x54, 0x1D, 0x8B, 0x73, 0x92, 0x28, 0x88, 0xBA, + 0xBE, 0x89, 0xB1, 0xC3, 0x82, 0x02, 0x21, 0x86, + 0x20, 0xD8, 0x8D, 0x77, 0xDA, 0xD9, 0xDF, 0xBA, + 0xB3, 0xFB, 0xF7, 0x40, 0xB2, 0xD1, 0xD8, 0xF3, + 0x7E, 0xAD, 0x25, 0x8E, 0x2E, 0xF1, 0x06, 0x52 + }, + { + 0x48, 0xB7, 0x26, 0x8A, 0xA4, 0x34, 0x2F, 0xAB, + 0x02, 0x1D, 0x14, 0x72, 0xE9, 0x25, 0x7F, 0x76, + 0x58, 0x5C, 0xC5, 0x68, 0x10, 0xC8, 0xF2, 0xA6, + 0xE1, 0xD4, 0xA8, 0x94, 0x6B, 0x77, 0x71, 0x42, + 0xD4, 0x4A, 0xE5, 0x13, 0xA8, 0x80, 0x9F, 0x2D, + 0x6D, 0xC7, 0x26, 0x30, 0x5F, 0x79, 0x44, 0x60, + 0x4D, 0x95, 0x2D, 0x4A, 0x9F, 0x08, 0x5C, 0x5C, + 0x10, 0x50, 0xBA, 0xFD, 0xD2, 0x1D, 0x1E, 0x60 + }, + { + 0xCE, 0xCF, 0xCE, 0x4B, 0x12, 0xC6, 0xCF, 0x53, + 0xD1, 0xB1, 0xB2, 0xD4, 0x18, 0xA4, 0x93, 0xE3, + 0xF4, 0x29, 0x17, 0x03, 0x21, 0xE8, 0x1A, 0xA2, + 0x52, 0x63, 0xAA, 0xA7, 0x15, 0xD5, 0xCA, 0x38, + 0x9F, 0x65, 0xC3, 0xAC, 0xF9, 0x9B, 0x18, 0x0E, + 0x44, 0x6B, 0x50, 0xE6, 0x01, 0xFC, 0xBF, 0x44, + 0x61, 0xD0, 0x42, 0x6A, 0x85, 0x92, 0xA0, 0x77, + 0x42, 0x20, 0x18, 0x57, 0x12, 0x5F, 0x71, 0xEE + }, + { + 0x38, 0x5A, 0x75, 0x22, 0x42, 0xEB, 0x9E, 0xD5, + 0x6B, 0x07, 0x4B, 0x70, 0x2C, 0x91, 0xE7, 0x5A, + 0xEC, 0x0B, 0xE9, 0x06, 0x4B, 0xD9, 0xCF, 0x88, + 0x03, 0x04, 0xC2, 0x13, 0x27, 0x0C, 0xB2, 0xEA, + 0xE8, 0xE2, 0x1D, 0x9A, 0xE8, 0xC6, 0x08, 0x15, + 0x19, 0xF7, 0x5D, 0xFA, 0xBB, 0x00, 0x3B, 0x24, + 0x32, 0xB0, 0x47, 0x55, 0xB8, 0xC3, 0x2C, 0x97, + 0xAC, 0x29, 0x14, 0xE8, 0xBF, 0x45, 0xB2, 0x34 + }, + { + 0xD8, 0x9A, 0x12, 0x4A, 0x9B, 0x95, 0x8B, 0xA2, + 0x3D, 0x09, 0x20, 0x7A, 0xCF, 0xA6, 0x2A, 0x33, + 0xB8, 0x70, 0x89, 0xB2, 0x86, 0xE8, 0x43, 0x8B, + 0xDC, 0x01, 0xE2, 0x33, 0xAB, 0x2A, 0x86, 0x30, + 0xA1, 0xEE, 0xB6, 0xB2, 0xB9, 0xBA, 0x6B, 0x7D, + 0x21, 0x00, 0x10, 0x77, 0x33, 0xDE, 0xAF, 0x4C, + 0x20, 0x47, 0x8C, 0x26, 0xF2, 0x49, 0xC6, 0x89, + 0xC5, 0x26, 0x84, 0x73, 0xE2, 0xE9, 0xFA, 0x60 + }, + { + 0x43, 0xDE, 0x10, 0x92, 0xFF, 0x9F, 0xF5, 0x28, + 0x20, 0x6C, 0x6F, 0xCF, 0x81, 0x32, 0x2E, 0xAD, + 0x3D, 0x22, 0xEA, 0xA4, 0xC8, 0x54, 0x52, 0x15, + 0x77, 0xDF, 0x33, 0x62, 0x47, 0x49, 0x5C, 0xE1, + 0x72, 0xFC, 0x87, 0x39, 0x95, 0x30, 0x0B, 0x21, + 0xB9, 0x46, 0x10, 0xC9, 0xD2, 0xF6, 0x33, 0xB5, + 0x33, 0xBD, 0xE4, 0x56, 0x8C, 0xA0, 0x9C, 0x38, + 0x0E, 0x84, 0x68, 0xFE, 0x6A, 0xD8, 0xD8, 0x1D + }, + { + 0x86, 0x8B, 0x60, 0x11, 0x99, 0xEF, 0x00, 0x0B, + 0x70, 0x5C, 0xD6, 0x4D, 0x39, 0x30, 0x26, 0x2A, + 0x5A, 0xB9, 0x10, 0xE3, 0x4E, 0x2D, 0x78, 0xE8, + 0x58, 0x7B, 0x4E, 0x01, 0x0D, 0x37, 0x6D, 0xD4, + 0xA0, 0x0D, 0xE4, 0x48, 0x67, 0xD0, 0xE9, 0x33, + 0xEE, 0x39, 0xA1, 0xFA, 0x91, 0x47, 0xD4, 0x99, + 0xD1, 0x84, 0xF3, 0xA9, 0xCF, 0x35, 0x4F, 0x2D, + 0x3C, 0x51, 0x14, 0x6F, 0xF7, 0x15, 0x2D, 0x68 + }, + { + 0x15, 0x17, 0xF8, 0xF0, 0x44, 0x2F, 0x0D, 0x50, + 0xBB, 0xC0, 0xAA, 0xB6, 0x84, 0x6F, 0xDC, 0xE3, + 0xB7, 0x0F, 0xAE, 0xA4, 0xBB, 0x51, 0x13, 0xAC, + 0xB2, 0x3A, 0xBE, 0x10, 0x1D, 0x99, 0xA4, 0x0A, + 0x1B, 0x76, 0xC1, 0xE8, 0xDC, 0x2E, 0xA1, 0x93, + 0x62, 0x94, 0x82, 0x3A, 0xD8, 0x35, 0x4C, 0x11, + 0xE2, 0xE9, 0x6C, 0x67, 0x12, 0xBE, 0x4C, 0xF7, + 0x7C, 0x58, 0x3F, 0xD0, 0x6B, 0x5E, 0x5C, 0x55 + }, + { + 0xAF, 0x4C, 0x6C, 0x67, 0xC5, 0xCA, 0x38, 0x38, + 0x73, 0x48, 0xCA, 0x3E, 0xC2, 0xBE, 0xD7, 0xFB, + 0xA8, 0xC2, 0xB3, 0xD2, 0x2D, 0xE1, 0x48, 0xD0, + 0x8A, 0x61, 0x8C, 0x29, 0x70, 0x23, 0xFB, 0x7B, + 0x6D, 0x2C, 0x15, 0x3D, 0x5E, 0xFC, 0xD1, 0x68, + 0x89, 0x99, 0x91, 0x0B, 0x20, 0xE1, 0xEA, 0xC7, + 0xC1, 0x00, 0xA2, 0xC5, 0xA6, 0xC1, 0xAC, 0xF5, + 0xE9, 0x8F, 0x14, 0x3B, 0x41, 0xDC, 0x8A, 0x12 + }, + { + 0xA2, 0xAD, 0x94, 0x24, 0x3B, 0x8E, 0xEA, 0x68, + 0xF5, 0xFA, 0xDD, 0x69, 0x08, 0xAD, 0xB0, 0xDA, + 0xCD, 0xAA, 0x6A, 0x6D, 0x24, 0xC2, 0x50, 0xD3, + 0x39, 0x40, 0x3D, 0xBA, 0x82, 0x31, 0xBD, 0x51, + 0xE8, 0x87, 0xCB, 0x5B, 0x1B, 0x7B, 0xDE, 0x27, + 0x74, 0xC6, 0xB0, 0x8A, 0xCC, 0xE0, 0xF7, 0x49, + 0x56, 0x48, 0xDA, 0x3B, 0xEB, 0xC7, 0xB1, 0xC2, + 0x82, 0x15, 0x08, 0xC4, 0xD3, 0x82, 0xF7, 0x30 + }, + { + 0x28, 0xF8, 0x8C, 0xDB, 0xE9, 0x03, 0xAD, 0x63, + 0xA0, 0x23, 0x31, 0xDE, 0x1A, 0x32, 0xAF, 0x6D, + 0xBB, 0xA8, 0x2D, 0x7F, 0xC0, 0x79, 0x87, 0x02, + 0x72, 0x49, 0x33, 0xDA, 0x77, 0x38, 0x07, 0xBC, + 0x80, 0x42, 0x78, 0x13, 0x47, 0x81, 0xF1, 0x26, + 0x23, 0x32, 0x20, 0xE3, 0x07, 0x92, 0x81, 0x31, + 0xB2, 0x47, 0x10, 0xB4, 0x67, 0x4E, 0xD7, 0x05, + 0x11, 0x2F, 0x95, 0xD1, 0xAA, 0x37, 0xA2, 0xDC + }, + { + 0x5B, 0xB2, 0x92, 0x65, 0xE2, 0x46, 0xB8, 0x84, + 0xFF, 0x40, 0x91, 0x4F, 0xFA, 0x93, 0xD9, 0xA1, + 0x2E, 0xDC, 0x19, 0xEE, 0xE9, 0xCC, 0x8A, 0x83, + 0x63, 0x1D, 0x68, 0xBD, 0x46, 0xAA, 0xD3, 0x35, + 0x4B, 0xA6, 0x67, 0x4B, 0x91, 0x3F, 0x4F, 0x82, + 0x3E, 0x79, 0x1F, 0x0C, 0xB1, 0x9E, 0xA6, 0xA6, + 0x7C, 0x6E, 0x32, 0xE9, 0xBE, 0x0D, 0x0F, 0xF5, + 0x76, 0x0F, 0x16, 0xDD, 0x75, 0xA8, 0x7B, 0x5D + }, + { + 0xBF, 0x3C, 0x06, 0xDC, 0x6D, 0x94, 0xE3, 0x85, + 0x9A, 0x4D, 0xAA, 0x50, 0xEC, 0xA1, 0xAF, 0x53, + 0x57, 0xE3, 0x45, 0x79, 0xE5, 0x99, 0xF8, 0x20, + 0x49, 0xE1, 0xCC, 0xA7, 0xA7, 0xD4, 0xF3, 0x3F, + 0xEA, 0x44, 0x3B, 0x44, 0x69, 0x1B, 0xD4, 0x36, + 0x88, 0xF5, 0x55, 0x05, 0x31, 0xCF, 0x22, 0xB7, + 0x12, 0x77, 0x89, 0x0B, 0xFF, 0xAE, 0x1E, 0xCE, + 0x78, 0x3F, 0x56, 0x63, 0xA1, 0xC4, 0xD7, 0x1A + }, + { + 0xC9, 0x0D, 0xF5, 0x32, 0xF2, 0xF1, 0x49, 0x3A, + 0x11, 0x55, 0xBE, 0x8C, 0x2A, 0x44, 0x00, 0x92, + 0x20, 0x49, 0x97, 0x4E, 0x7D, 0x4F, 0x4B, 0x54, + 0xF8, 0x20, 0xC2, 0x26, 0x9D, 0x3B, 0x16, 0x1B, + 0x6E, 0x88, 0xEB, 0x77, 0x6B, 0x85, 0x9B, 0x89, + 0xB8, 0x56, 0x7F, 0xBC, 0x55, 0x0C, 0x4F, 0x54, + 0xAA, 0xD2, 0x7A, 0x16, 0x10, 0x65, 0x6D, 0x62, + 0x5C, 0x32, 0x7F, 0x66, 0x5D, 0xCA, 0x70, 0x7C + }, + { + 0x3D, 0x39, 0xEE, 0xCC, 0x9E, 0x90, 0x42, 0x36, + 0xDC, 0x85, 0x7B, 0xA4, 0x9D, 0x55, 0xD3, 0xBA, + 0xD7, 0x65, 0x72, 0xA9, 0x1A, 0x75, 0x95, 0x03, + 0x37, 0x6B, 0x77, 0x08, 0xD6, 0x2D, 0x5A, 0x78, + 0x5C, 0x23, 0x06, 0x80, 0x59, 0xCF, 0x68, 0x89, + 0x7F, 0x23, 0xEE, 0xC5, 0x07, 0x21, 0x9B, 0x0A, + 0x02, 0xED, 0xA2, 0xD8, 0xBC, 0x94, 0xFA, 0x69, + 0x89, 0xA5, 0x14, 0x82, 0x22, 0x03, 0xC8, 0xD1 + }, + { + 0xE0, 0x8C, 0x54, 0xD9, 0x98, 0xF9, 0x2B, 0x7A, + 0x54, 0xA2, 0x4C, 0xA6, 0xAE, 0xB1, 0x53, 0xA6, + 0x4F, 0x9C, 0x9F, 0x1F, 0xC3, 0x36, 0x58, 0xB3, + 0xED, 0xAC, 0x2C, 0x4B, 0xB5, 0x26, 0x31, 0x58, + 0xDA, 0xDF, 0x00, 0xD3, 0x51, 0x9A, 0x11, 0x9A, + 0x56, 0x14, 0xC7, 0xF3, 0x79, 0x40, 0xE5, 0x5D, + 0x13, 0xCC, 0xE4, 0x66, 0xCB, 0x71, 0xA4, 0x07, + 0xC3, 0x9F, 0xC5, 0x1E, 0x1E, 0xFE, 0x18, 0xDA + }, + { + 0x74, 0x76, 0x76, 0x07, 0x04, 0x1D, 0xD4, 0xB7, + 0xC5, 0x6B, 0x18, 0x9E, 0xE8, 0xF2, 0x77, 0x31, + 0xA5, 0x16, 0x72, 0x23, 0xEB, 0x7A, 0xF9, 0xB9, + 0x39, 0xE1, 0x18, 0xF8, 0x7D, 0x80, 0xB4, 0x9E, + 0xA8, 0xD0, 0xD0, 0x1F, 0x74, 0xF3, 0x98, 0xB1, + 0x72, 0xA8, 0xAD, 0x0D, 0xBF, 0x99, 0x41, 0x4F, + 0x08, 0xD2, 0xB7, 0xD8, 0xD7, 0x52, 0x16, 0xA1, + 0x82, 0x25, 0x27, 0x3D, 0x8D, 0x7F, 0xD0, 0x5D + }, + { + 0xFE, 0xE8, 0x9A, 0x92, 0xCC, 0xF9, 0xF1, 0xEB, + 0x08, 0x4A, 0xAB, 0xA9, 0x54, 0x97, 0xEF, 0x0F, + 0x30, 0x13, 0x4C, 0x19, 0x1C, 0xF9, 0x0A, 0x49, + 0xD2, 0x2C, 0x7D, 0x2F, 0x66, 0x14, 0x99, 0x3C, + 0xBE, 0x1A, 0x4B, 0x65, 0x13, 0xED, 0xC1, 0x53, + 0x86, 0x8A, 0x3D, 0x56, 0x2B, 0x5B, 0x02, 0x26, + 0xBA, 0x8E, 0x1B, 0x0D, 0xCB, 0x69, 0xED, 0x45, + 0xAF, 0x47, 0xCE, 0x4F, 0x86, 0xBA, 0x47, 0x4A + }, + { + 0xCD, 0xAE, 0x94, 0xB6, 0xD1, 0xD8, 0x35, 0xF6, + 0xC7, 0x4C, 0x76, 0xEC, 0x3A, 0x2D, 0xB6, 0x5B, + 0xBD, 0xFA, 0xE1, 0x9D, 0x7B, 0x05, 0x0D, 0xC9, + 0x5D, 0x65, 0x87, 0x33, 0xB8, 0xB2, 0x2C, 0x6F, + 0x9E, 0x0B, 0x63, 0xCC, 0x90, 0x5A, 0x29, 0xEA, + 0x88, 0x78, 0xCA, 0x39, 0x45, 0x56, 0xB3, 0x67, + 0x3C, 0x62, 0x79, 0x15, 0x46, 0xA9, 0xA1, 0xF0, + 0xD1, 0x56, 0x5F, 0xAD, 0xC5, 0x35, 0x36, 0xC1 + }, + { + 0xC7, 0x22, 0x8B, 0x6F, 0x00, 0x00, 0x17, 0xD2, + 0xBE, 0x4B, 0xF2, 0xAE, 0x48, 0xAD, 0xDB, 0x78, + 0x5E, 0x27, 0x35, 0xBF, 0x3C, 0x61, 0x4D, 0x3C, + 0x34, 0x23, 0x1F, 0x1D, 0x0C, 0x88, 0x7D, 0x3A, + 0x8E, 0x88, 0x88, 0x0B, 0x67, 0xAD, 0x3B, 0x2F, + 0x65, 0x23, 0xDD, 0x67, 0x19, 0x34, 0x2C, 0xD4, + 0xF0, 0x59, 0x35, 0xD2, 0xE5, 0x26, 0x7F, 0x36, + 0x80, 0xE7, 0x73, 0xBD, 0x5E, 0xAD, 0xFE, 0x1D + }, + { + 0x12, 0x27, 0x44, 0xFE, 0x3F, 0xFF, 0x9A, 0x05, + 0x5F, 0x0F, 0x3B, 0xDE, 0x01, 0xEB, 0x2F, 0x44, + 0x6B, 0x0C, 0xDA, 0xF3, 0xAE, 0xD7, 0x2C, 0xAA, + 0x29, 0x40, 0x74, 0x19, 0x20, 0x12, 0x0A, 0x96, + 0x4F, 0xCF, 0xF8, 0x70, 0x99, 0xB0, 0x8E, 0xF3, + 0x34, 0x96, 0xE3, 0x99, 0x03, 0x2A, 0x82, 0xDA, + 0xAD, 0x4F, 0xED, 0x30, 0x31, 0x17, 0x2F, 0x77, + 0x47, 0x92, 0x58, 0xFA, 0x39, 0xDB, 0x92, 0xFD + }, + { + 0x1F, 0xB4, 0xE3, 0x67, 0xEA, 0xB6, 0x42, 0xB7, + 0x2E, 0x43, 0xAD, 0x4A, 0xBD, 0xFC, 0xAD, 0x74, + 0x62, 0x0C, 0x3F, 0x6C, 0x63, 0xA8, 0x91, 0x31, + 0x28, 0xD2, 0x22, 0x6E, 0xB1, 0x92, 0xF9, 0x99, + 0x2E, 0xB9, 0xC8, 0xF7, 0x6A, 0xE2, 0x06, 0xD3, + 0xF5, 0xDE, 0xC7, 0x26, 0xA5, 0xA6, 0x86, 0xB4, + 0xAE, 0x37, 0xB5, 0x57, 0xAB, 0x57, 0xF9, 0x56, + 0x48, 0x53, 0x34, 0xF7, 0x3D, 0xCE, 0x02, 0xE0 + }, + { + 0x04, 0x25, 0xCA, 0xAA, 0x92, 0x3B, 0x47, 0xB3, + 0x50, 0x45, 0xEB, 0x50, 0x82, 0x9C, 0x04, 0x8B, + 0xC8, 0x90, 0x44, 0x4A, 0xFE, 0xEF, 0xC0, 0xAF, + 0xC9, 0xD1, 0x87, 0x7B, 0x82, 0x1E, 0x04, 0x3C, + 0x9C, 0x7B, 0x9D, 0x6D, 0xC3, 0x3F, 0xBB, 0xDF, + 0xA5, 0x37, 0xC1, 0xEC, 0xE3, 0x11, 0x96, 0x5B, + 0x2F, 0xEE, 0x89, 0x82, 0xBC, 0x46, 0xA2, 0xA7, + 0x50, 0xBF, 0xC7, 0x1D, 0x79, 0xDB, 0xEA, 0x04 + }, + { + 0x6B, 0x9D, 0x86, 0xF1, 0x5C, 0x09, 0x0A, 0x00, + 0xFC, 0x3D, 0x90, 0x7F, 0x90, 0x6C, 0x5E, 0xB7, + 0x92, 0x65, 0xE5, 0x8B, 0x88, 0xEB, 0x64, 0x29, + 0x4B, 0x4C, 0xC4, 0xE2, 0xB8, 0x9B, 0x1A, 0x7C, + 0x5E, 0xE3, 0x12, 0x7E, 0xD2, 0x1B, 0x45, 0x68, + 0x62, 0xDE, 0x6B, 0x2A, 0xBD, 0xA5, 0x9E, 0xAA, + 0xCF, 0x2D, 0xCB, 0xE9, 0x22, 0xCA, 0x75, 0x5E, + 0x40, 0x73, 0x5B, 0xE8, 0x1D, 0x9C, 0x88, 0xA5 + }, + { + 0x14, 0x6A, 0x18, 0x7A, 0x99, 0xE8, 0xA2, 0xD2, + 0x33, 0xE0, 0xEB, 0x37, 0x3D, 0x43, 0x7B, 0x02, + 0xBF, 0xA8, 0xD6, 0x51, 0x5B, 0x3C, 0xA1, 0xDE, + 0x48, 0xA6, 0xB6, 0xAC, 0xF7, 0x43, 0x7E, 0xB7, + 0xE7, 0xAC, 0x3F, 0x2D, 0x19, 0xEF, 0x3B, 0xB9, + 0xB8, 0x33, 0xCC, 0x57, 0x61, 0xDB, 0xA2, 0x2D, + 0x1A, 0xD0, 0x60, 0xBE, 0x76, 0xCD, 0xCB, 0x81, + 0x2D, 0x64, 0xD5, 0x78, 0xE9, 0x89, 0xA5, 0xA4 + }, + { + 0x25, 0x75, 0x4C, 0xA6, 0x66, 0x9C, 0x48, 0x70, + 0x84, 0x03, 0x88, 0xEA, 0x64, 0xE9, 0x5B, 0xD2, + 0xE0, 0x81, 0x0D, 0x36, 0x3C, 0x4C, 0xF6, 0xA1, + 0x6E, 0xA1, 0xBD, 0x06, 0x68, 0x6A, 0x93, 0xC8, + 0xA1, 0x25, 0xF2, 0x30, 0x22, 0x9D, 0x94, 0x84, + 0x85, 0xE1, 0xA8, 0x2D, 0xE4, 0x82, 0x00, 0x35, + 0x8F, 0x3E, 0x02, 0xB5, 0x05, 0xDA, 0xBC, 0x4F, + 0x13, 0x9C, 0x03, 0x79, 0xDC, 0x2B, 0x30, 0x80 + }, + { + 0x0E, 0x26, 0xCB, 0xC7, 0x8D, 0xC7, 0x54, 0xEC, + 0xA0, 0x6C, 0xF8, 0xCB, 0x31, 0xFC, 0xBA, 0xBB, + 0x18, 0x88, 0x92, 0xC1, 0x04, 0x50, 0x89, 0x05, + 0x49, 0xB2, 0xD4, 0x03, 0xA2, 0xA3, 0xC4, 0x57, + 0x70, 0x01, 0xF7, 0x4A, 0x76, 0xBD, 0x38, 0x99, + 0x0D, 0x75, 0x5B, 0xAE, 0x05, 0x26, 0x64, 0x83, + 0x29, 0xF6, 0x35, 0x45, 0xED, 0x16, 0x99, 0x5C, + 0xB1, 0xE6, 0x34, 0x3F, 0x18, 0x9F, 0x8E, 0x6F + }, + { + 0x58, 0xE7, 0x98, 0x0B, 0x8B, 0x1A, 0x0B, 0x88, + 0xDA, 0x9D, 0xA8, 0x64, 0x0F, 0x2B, 0x96, 0xE3, + 0xE0, 0x48, 0x36, 0x61, 0x30, 0xC2, 0x66, 0x21, + 0x7D, 0xDC, 0x79, 0x53, 0x50, 0x8F, 0x4A, 0x40, + 0xD1, 0x67, 0x4D, 0xAB, 0xD3, 0x92, 0x89, 0xE3, + 0xF1, 0x0C, 0x61, 0x19, 0x68, 0xCC, 0xD1, 0xE9, + 0xCC, 0xC1, 0x8C, 0xAD, 0xC7, 0x77, 0x4A, 0x99, + 0x7D, 0xD1, 0xFA, 0x94, 0xE8, 0x35, 0x47, 0x07 + }, + { + 0x69, 0x6F, 0xB8, 0x47, 0x63, 0xE0, 0x23, 0x58, + 0x4B, 0x35, 0x90, 0x7A, 0x8B, 0x8A, 0xAA, 0x9E, + 0x0E, 0x78, 0x6F, 0x2C, 0xA5, 0x91, 0x45, 0x41, + 0x91, 0x58, 0x48, 0xFB, 0x6D, 0xDA, 0xB8, 0xD3, + 0xD2, 0xEA, 0xB6, 0x00, 0xC1, 0x38, 0xCE, 0x67, + 0x17, 0xB0, 0xC7, 0x02, 0x59, 0xD3, 0x19, 0x3E, + 0xA1, 0x56, 0x95, 0xC8, 0x50, 0x53, 0x7F, 0x2C, + 0x70, 0x6C, 0xA4, 0xAF, 0x15, 0x8E, 0x95, 0x7E + }, + { + 0x23, 0xDE, 0x6E, 0x73, 0x07, 0x9C, 0x8C, 0x20, + 0x47, 0xA7, 0x84, 0x6A, 0x83, 0xCC, 0xAC, 0xAB, + 0xD3, 0x71, 0x16, 0x3B, 0x7B, 0x6D, 0x54, 0xEB, + 0x03, 0x2B, 0xC4, 0x9B, 0x66, 0x97, 0x42, 0xBE, + 0x71, 0x7B, 0x99, 0xDA, 0x12, 0xC6, 0x46, 0xAD, + 0x52, 0x57, 0x06, 0xF2, 0x22, 0xE1, 0xDF, 0x4A, + 0x91, 0xDD, 0x0C, 0xC6, 0x4D, 0xF1, 0x82, 0xDA, + 0x00, 0x73, 0x1D, 0x43, 0x9C, 0x46, 0xF8, 0xD2 + }, + { + 0xBB, 0x74, 0xF3, 0x6A, 0x9D, 0xB6, 0x96, 0xC9, + 0x33, 0x35, 0xE6, 0xC4, 0x6A, 0xAB, 0x58, 0xDB, + 0x10, 0xCB, 0x07, 0xEA, 0x4F, 0x1B, 0x71, 0x93, + 0x63, 0x05, 0x22, 0x83, 0x90, 0x95, 0x94, 0x78, + 0xF8, 0x73, 0x4E, 0x21, 0x54, 0x90, 0xE9, 0xAE, + 0x2A, 0x3E, 0xC8, 0xF7, 0xF7, 0x67, 0x33, 0xAE, + 0x3F, 0x8B, 0x9A, 0x3F, 0xD7, 0xC4, 0x06, 0xC6, + 0xCA, 0xC7, 0x09, 0x97, 0x5C, 0x40, 0xF8, 0x56 + }, + { + 0xEC, 0x63, 0x04, 0xD3, 0x8E, 0x23, 0x2C, 0x09, + 0x6A, 0xB5, 0x86, 0xCA, 0xDF, 0x27, 0x02, 0x6D, + 0xC5, 0xE5, 0x32, 0x17, 0xD0, 0xE8, 0xB0, 0xC6, + 0x0A, 0xDA, 0xAE, 0x22, 0xF4, 0xE8, 0xC2, 0x2D, + 0x30, 0xBC, 0x51, 0x77, 0xF1, 0xC8, 0x3A, 0xCD, + 0x92, 0x5E, 0x02, 0xA2, 0xDA, 0x89, 0x59, 0x5F, + 0xC1, 0x06, 0x09, 0x0E, 0x2E, 0x53, 0xED, 0xB3, + 0x1C, 0xDB, 0x76, 0xFF, 0x37, 0xEB, 0x61, 0x80 + }, + { + 0x92, 0xF9, 0xFC, 0x6B, 0xC5, 0x9A, 0x54, 0x3F, + 0x0D, 0xC9, 0xA1, 0x79, 0x8F, 0xB1, 0xE5, 0xD5, + 0x23, 0x47, 0x4E, 0x48, 0xFF, 0x3E, 0x29, 0x49, + 0x7F, 0x72, 0x80, 0xD1, 0xC4, 0x08, 0xC8, 0x66, + 0x33, 0x48, 0xFE, 0x2A, 0xF7, 0x8F, 0x6C, 0x4E, + 0x5E, 0xF5, 0xC0, 0xA0, 0x17, 0xF3, 0xD3, 0xF2, + 0x15, 0xEC, 0xDD, 0x7A, 0x40, 0x0A, 0xC5, 0x77, + 0x3B, 0x9E, 0x25, 0x60, 0x68, 0x84, 0x5A, 0x92 + }, + { + 0x4A, 0x25, 0xB5, 0x62, 0xF2, 0xFA, 0x01, 0xDD, + 0xEE, 0x7E, 0xA2, 0xE9, 0xFB, 0xF5, 0x2F, 0x8C, + 0x75, 0x6D, 0x28, 0xDB, 0x4A, 0x8B, 0xF7, 0x0E, + 0x74, 0x0E, 0x90, 0x27, 0x42, 0x6E, 0x51, 0x63, + 0x9D, 0xF8, 0x78, 0x8D, 0x13, 0x38, 0x56, 0x85, + 0x8D, 0x01, 0xFD, 0xDB, 0xDD, 0x5B, 0x98, 0x79, + 0x44, 0xC3, 0x00, 0xDC, 0x7F, 0x82, 0x41, 0xFB, + 0xCE, 0xFA, 0x4F, 0x12, 0x94, 0x8A, 0xFE, 0xAE + }, + { + 0x34, 0x21, 0x2D, 0xD9, 0xF0, 0x65, 0x1F, 0x81, + 0x80, 0x9A, 0x14, 0xED, 0xBC, 0xF7, 0xF3, 0xAC, + 0xDE, 0xDE, 0x78, 0x72, 0xC7, 0xA4, 0x84, 0x7B, + 0xEA, 0x9F, 0x7A, 0xB7, 0x59, 0x73, 0x82, 0x47, + 0x7A, 0x4C, 0xB8, 0x47, 0x9A, 0x27, 0x63, 0x21, + 0x23, 0x5E, 0x90, 0x21, 0x57, 0x94, 0x46, 0xA4, + 0x38, 0x8A, 0x99, 0xE5, 0x60, 0xA3, 0x90, 0x7A, + 0xEE, 0xF2, 0xB4, 0x38, 0xFE, 0x6B, 0x90, 0xC4 + }, + { + 0xD6, 0x2C, 0xF7, 0xAB, 0xBC, 0x7D, 0x7B, 0xCD, + 0x5B, 0xEB, 0x1E, 0xE4, 0x8C, 0x43, 0xB8, 0x04, + 0xFD, 0x0D, 0xB4, 0x55, 0xE7, 0xF4, 0xFE, 0xBB, + 0xCF, 0xF1, 0x4B, 0x05, 0xBE, 0x90, 0x47, 0xE2, + 0x7E, 0x51, 0x8D, 0x6D, 0x3A, 0x6A, 0xDA, 0x4D, + 0x58, 0x63, 0xB7, 0xEC, 0x7F, 0x84, 0x92, 0x45, + 0x89, 0x40, 0xAC, 0x6B, 0xDD, 0xB5, 0x06, 0x59, + 0x2C, 0xCB, 0xC8, 0x96, 0xAF, 0xBB, 0x77, 0xA3 + }, + { + 0x33, 0xA3, 0xA2, 0x63, 0x6F, 0x91, 0x98, 0xD3, + 0x7A, 0x5F, 0xF1, 0xBF, 0xF9, 0xEB, 0x10, 0x02, + 0x4B, 0x28, 0x46, 0x80, 0x39, 0xF4, 0x91, 0x40, + 0x2D, 0x39, 0xB7, 0x08, 0xC5, 0x5D, 0x27, 0xE5, + 0xE8, 0xDF, 0x5E, 0x3E, 0x19, 0x49, 0x95, 0x82, + 0x35, 0xCA, 0xD9, 0x80, 0x74, 0x20, 0x96, 0xF2, + 0x77, 0x9A, 0x1D, 0x71, 0xDA, 0xD5, 0x8F, 0xAF, + 0xA3, 0xCD, 0x02, 0xCB, 0x5E, 0xAA, 0x98, 0xC5 + }, + { + 0xB7, 0xA3, 0x89, 0x90, 0xE6, 0xF4, 0x56, 0x4A, + 0xA3, 0xD9, 0x3A, 0x79, 0x37, 0x10, 0x0C, 0x29, + 0xF9, 0x40, 0xAF, 0xF7, 0xCB, 0x20, 0x86, 0x5A, + 0x1C, 0x21, 0x89, 0x81, 0xA5, 0x42, 0x04, 0x86, + 0x08, 0x17, 0x81, 0xF8, 0xD5, 0x0C, 0x86, 0x62, + 0x5C, 0xC5, 0xD7, 0x6D, 0x0F, 0x5C, 0xCC, 0x4E, + 0xB6, 0x5D, 0x43, 0x66, 0x09, 0x62, 0x4F, 0x21, + 0xD0, 0x53, 0x39, 0xAB, 0x0C, 0xF7, 0x9F, 0x4C + }, + { + 0x9D, 0x66, 0x5A, 0x3F, 0xDD, 0x10, 0x45, 0x9E, + 0x77, 0xF0, 0x3A, 0xC8, 0xC0, 0xE2, 0x39, 0x01, + 0x94, 0x89, 0x69, 0x3C, 0xC9, 0x31, 0x5A, 0xA3, + 0xFF, 0x11, 0x29, 0x11, 0xD2, 0xAC, 0xF0, 0xB7, + 0xD2, 0x76, 0xAC, 0x76, 0x9B, 0xED, 0xFD, 0x85, + 0x2D, 0x28, 0x89, 0xDD, 0x12, 0xDB, 0x91, 0x39, + 0x8B, 0x01, 0xC4, 0xF4, 0xA5, 0xDA, 0x27, 0x80, + 0xB1, 0xDE, 0xFE, 0x0D, 0x95, 0xB6, 0x32, 0x70 + }, + { + 0x70, 0xFB, 0x9E, 0xFD, 0x5B, 0xCA, 0x7F, 0x19, + 0xB6, 0xE3, 0x1D, 0x64, 0x0D, 0xCF, 0x88, 0xD7, + 0x7E, 0x76, 0x8A, 0xE2, 0x27, 0xEC, 0xB3, 0xFD, + 0x6B, 0x47, 0x13, 0x78, 0x94, 0xF5, 0x49, 0xBF, + 0x1C, 0xF0, 0x6E, 0x5D, 0xB4, 0x54, 0x60, 0x44, + 0xDD, 0x9F, 0x46, 0x5C, 0x9C, 0x85, 0xF7, 0x28, + 0x4F, 0xE5, 0x4D, 0x2B, 0x71, 0x52, 0x69, 0x9B, + 0xE4, 0xBD, 0x55, 0x5A, 0x90, 0x9A, 0x88, 0xA9 + }, + { + 0x7A, 0xFD, 0xB0, 0x19, 0x30, 0x87, 0xE0, 0xC9, + 0xF8, 0xB4, 0xDD, 0x8B, 0x48, 0xD9, 0xF2, 0x0A, + 0xCE, 0x27, 0x13, 0xAF, 0xC7, 0x1B, 0xCC, 0x93, + 0x82, 0xB5, 0x42, 0x90, 0xAE, 0xBF, 0xFE, 0xB2, + 0xD1, 0x38, 0xF4, 0xDC, 0xF0, 0x28, 0xF9, 0xC4, + 0x3C, 0xC1, 0x80, 0x89, 0x84, 0x77, 0xA3, 0x9E, + 0x3F, 0x53, 0xA8, 0xD1, 0xBF, 0x67, 0xCE, 0xB6, + 0x08, 0x26, 0x1F, 0xAE, 0x6D, 0xDB, 0x1A, 0xBC + }, + { + 0x05, 0x99, 0x0D, 0x7D, 0x7D, 0xF1, 0xD4, 0x84, + 0xF5, 0xB1, 0xCA, 0xE9, 0xEE, 0x5D, 0xFC, 0xB4, + 0x3F, 0x2C, 0xBE, 0x18, 0x6C, 0x1A, 0x5B, 0x18, + 0x1A, 0x37, 0x31, 0xD4, 0xB1, 0x54, 0x8E, 0xBF, + 0xF5, 0xBF, 0x61, 0xCB, 0x0F, 0x6D, 0x9F, 0xC2, + 0x30, 0xF2, 0x5E, 0x86, 0x78, 0xB7, 0x99, 0xE0, + 0xE8, 0x30, 0x26, 0xA0, 0x86, 0x6B, 0xF0, 0xAC, + 0xAB, 0x08, 0x9E, 0x10, 0x2E, 0x67, 0xAB, 0x6B + }, + { + 0x1A, 0xF7, 0xA5, 0xCE, 0x58, 0x7C, 0x8D, 0x87, + 0xC7, 0xB7, 0x9F, 0xA3, 0xE7, 0x23, 0xD7, 0x4C, + 0xE0, 0x26, 0xB5, 0x28, 0x67, 0x52, 0xFD, 0x0C, + 0x37, 0x42, 0xC6, 0xF0, 0x41, 0x8E, 0xD7, 0x85, + 0x99, 0x0D, 0x21, 0xF2, 0x8D, 0xA8, 0x39, 0xCE, + 0x82, 0x12, 0xED, 0x55, 0x0C, 0x37, 0x3E, 0x6D, + 0x3A, 0x75, 0xD5, 0x5C, 0x31, 0x77, 0x04, 0x41, + 0xEE, 0xAF, 0xF2, 0xD5, 0x0F, 0x6E, 0x61, 0xB6 + }, + { + 0xDD, 0xEE, 0x0C, 0x76, 0xC9, 0xBD, 0xD3, 0x2D, + 0x70, 0x49, 0x35, 0x4C, 0xFC, 0x85, 0xDC, 0x68, + 0x67, 0xE2, 0x49, 0x2E, 0x47, 0xFE, 0xB0, 0x8E, + 0x39, 0x83, 0xD0, 0xB6, 0x78, 0x84, 0x5D, 0x7E, + 0xC6, 0xC9, 0x79, 0x3C, 0x33, 0x26, 0xBF, 0xDC, + 0x1E, 0x11, 0x32, 0x76, 0xD1, 0x77, 0xFE, 0x38, + 0x82, 0x52, 0x04, 0xDD, 0x00, 0x07, 0x39, 0x89, + 0xC0, 0x81, 0xCC, 0x3B, 0x71, 0xC6, 0x8D, 0x5F + }, + { + 0xDE, 0x07, 0x06, 0x48, 0xB3, 0x7C, 0x47, 0xDC, + 0x9F, 0x2F, 0x6D, 0x2A, 0xB2, 0x07, 0x73, 0xCD, + 0x82, 0xFA, 0x57, 0x25, 0xA6, 0x90, 0x0E, 0xB7, + 0x1C, 0xDD, 0xB0, 0xC9, 0xF3, 0x9B, 0x31, 0xDF, + 0x6D, 0x07, 0x73, 0x24, 0x6E, 0x8E, 0xF9, 0x03, + 0x49, 0x67, 0x75, 0x2D, 0xB7, 0xED, 0x22, 0x73, + 0x3F, 0x43, 0x79, 0x94, 0x8D, 0xC3, 0x96, 0xDC, + 0x35, 0xAD, 0xBB, 0xE9, 0xF6, 0x53, 0x77, 0x40 + }, + { + 0xA6, 0x45, 0x6F, 0xBC, 0xFF, 0x9E, 0x3D, 0x5B, + 0x11, 0x6A, 0x0E, 0x33, 0x1A, 0x1F, 0x97, 0x4F, + 0x07, 0x0E, 0x95, 0x56, 0x09, 0x78, 0x1F, 0xA5, + 0x99, 0xD6, 0x08, 0xA3, 0x1D, 0xA7, 0x6A, 0xD8, + 0xAB, 0xFE, 0x34, 0x66, 0x17, 0xC2, 0x57, 0x86, + 0x51, 0x3B, 0x2C, 0x44, 0xBF, 0xE2, 0xCB, 0x45, + 0x7C, 0x43, 0xFA, 0x6F, 0x45, 0x36, 0x1C, 0xA9, + 0xC6, 0x34, 0x13, 0x11, 0xB7, 0xDD, 0xFB, 0xD5 + }, + { + 0x5C, 0x95, 0xD3, 0x82, 0x02, 0x18, 0x91, 0x04, + 0x8B, 0x5E, 0xC8, 0x1C, 0xC8, 0x8E, 0x66, 0xB1, + 0xB4, 0xD8, 0x0A, 0x00, 0xB5, 0xEE, 0x66, 0xB3, + 0xC0, 0x30, 0x77, 0x49, 0xE6, 0xF2, 0x4D, 0x17, + 0x0D, 0x23, 0xFA, 0xCC, 0x8E, 0xB2, 0x53, 0xB3, + 0x56, 0x2B, 0xF8, 0xA4, 0x5C, 0x37, 0x99, 0x0C, + 0xD2, 0xD3, 0xE4, 0x43, 0xB1, 0x8C, 0x68, 0xBB, + 0xCC, 0x6C, 0x83, 0x1D, 0xFD, 0xE2, 0xF8, 0xE5 + }, + { + 0xE3, 0x74, 0x00, 0xDB, 0xD9, 0x21, 0x0F, 0x31, + 0x37, 0xAC, 0xAF, 0x49, 0x24, 0x2F, 0xA1, 0x23, + 0xA0, 0x52, 0x95, 0x8A, 0x4C, 0x0D, 0x98, 0x90, + 0x62, 0x47, 0xD5, 0x35, 0xA3, 0x51, 0xFD, 0x52, + 0x29, 0x6E, 0x70, 0x10, 0x32, 0x5B, 0xDA, 0x84, + 0x1F, 0xA2, 0xAA, 0xB4, 0x47, 0x63, 0x76, 0x3C, + 0x55, 0x04, 0xD7, 0xB3, 0x0C, 0x6D, 0x79, 0xFC, + 0x1D, 0xC8, 0xCF, 0x10, 0x24, 0x46, 0x6D, 0xB0 + }, + { + 0x52, 0x73, 0xA3, 0xA1, 0x3C, 0xF0, 0xEC, 0x72, + 0x00, 0x44, 0x2C, 0xBD, 0x7B, 0x37, 0x44, 0x66, + 0xA7, 0x19, 0x0D, 0xDC, 0xA1, 0x31, 0xD9, 0x63, + 0xF8, 0xF8, 0x39, 0x65, 0xAE, 0xD3, 0xDD, 0x86, + 0xE9, 0xD4, 0x5A, 0xB4, 0x89, 0xB9, 0xC5, 0x62, + 0x47, 0xC9, 0xF2, 0xAA, 0x69, 0xFD, 0x7E, 0x31, + 0x87, 0xB8, 0xFA, 0x0D, 0xAC, 0x77, 0xC4, 0x7C, + 0xB2, 0x95, 0xBA, 0x62, 0x96, 0x78, 0x43, 0x94 + }, + { + 0x2A, 0xDB, 0x93, 0x49, 0xA9, 0xEC, 0x37, 0xFF, + 0x49, 0x62, 0xF4, 0x21, 0x7E, 0x80, 0xEB, 0xDC, + 0xD3, 0x60, 0x96, 0x7B, 0x51, 0x3D, 0x12, 0x02, + 0xD9, 0x98, 0x28, 0x31, 0x15, 0x5D, 0x2F, 0x43, + 0xEB, 0x9A, 0xDD, 0x63, 0xB5, 0xEC, 0x10, 0xD3, + 0xD0, 0x43, 0x0D, 0xC9, 0xCF, 0x76, 0x48, 0x11, + 0x7F, 0xC6, 0x0B, 0xAB, 0xBF, 0x8E, 0xBF, 0x19, + 0xFA, 0xCE, 0xE5, 0x50, 0x45, 0x5B, 0x60, 0xC9 + }, + { + 0xAC, 0xAA, 0xDA, 0x3E, 0x47, 0x37, 0xC6, 0x63, + 0xEB, 0xF0, 0x3C, 0x02, 0x49, 0xCC, 0xA6, 0xF3, + 0x17, 0x9A, 0x03, 0x84, 0xEA, 0x2A, 0xB1, 0x35, + 0xD4, 0xD7, 0xA2, 0xBB, 0x8A, 0x2F, 0x40, 0x53, + 0x9C, 0xDC, 0xE8, 0xA3, 0x76, 0x0F, 0xD1, 0x3D, + 0xEE, 0xEC, 0xD1, 0x60, 0x61, 0x7F, 0x72, 0xDE, + 0x63, 0x75, 0x4E, 0x21, 0x57, 0xCA, 0xDC, 0xF0, + 0x67, 0x32, 0x9C, 0x2A, 0x51, 0x98, 0xF8, 0xE0 + }, + { + 0xEF, 0x15, 0xE6, 0xDB, 0x96, 0xE6, 0xD0, 0xC1, + 0x8C, 0x70, 0xAD, 0xC3, 0xCD, 0xB3, 0x2B, 0x28, + 0x67, 0x74, 0x02, 0xE8, 0xEA, 0x44, 0x11, 0xEA, + 0x2F, 0x34, 0x68, 0xED, 0x93, 0x82, 0xE1, 0x9B, + 0xFE, 0xCA, 0xF5, 0xAC, 0xB8, 0x28, 0xA5, 0x2B, + 0xE1, 0x6B, 0x98, 0x1E, 0x48, 0x7E, 0x5B, 0xB4, + 0xA1, 0x43, 0x08, 0x65, 0x35, 0x8E, 0x97, 0x9F, + 0xB1, 0x07, 0x1F, 0xB9, 0x51, 0x14, 0xFF, 0xDD + }, + { + 0x05, 0x7E, 0xAB, 0x8F, 0xA6, 0x1C, 0x23, 0x09, + 0x67, 0xD9, 0x5D, 0xFB, 0x75, 0x45, 0x57, 0x0E, + 0x34, 0x1A, 0xE3, 0xC6, 0x73, 0x7C, 0x7D, 0xB2, + 0xA2, 0x27, 0xD9, 0x0F, 0xF3, 0x15, 0xD0, 0x98, + 0xD4, 0x76, 0xF7, 0x15, 0x77, 0x9E, 0x67, 0x72, + 0xB4, 0xED, 0x37, 0x54, 0x82, 0x66, 0xE6, 0x59, + 0x8C, 0x6F, 0x09, 0x69, 0x13, 0xC2, 0xFD, 0xD8, + 0xD6, 0xE4, 0x4F, 0xE2, 0xB5, 0x4D, 0x97, 0x80 + }, + { + 0xED, 0xE6, 0x8D, 0x1B, 0x13, 0xE7, 0xEF, 0x78, + 0xD9, 0xC4, 0xEE, 0x10, 0xEC, 0xEB, 0x1D, 0x2A, + 0xEE, 0xC3, 0xB8, 0x15, 0x7F, 0xDB, 0x91, 0x41, + 0x8C, 0x22, 0x19, 0xF6, 0x41, 0x49, 0x74, 0x70, + 0x17, 0xAC, 0xA7, 0xD4, 0x65, 0xB8, 0xB4, 0x7F, + 0xFA, 0x53, 0x64, 0x4B, 0x8B, 0xC6, 0xDA, 0x12, + 0xDD, 0x45, 0xD1, 0x05, 0x5E, 0x47, 0xB4, 0xD8, + 0x39, 0x0E, 0xB2, 0xBD, 0x60, 0x2B, 0xA0, 0x30 + }, + { + 0x27, 0xF8, 0x56, 0xE6, 0x3E, 0xB9, 0x4D, 0x08, + 0xFB, 0xBE, 0x50, 0x22, 0xB0, 0xED, 0xDB, 0xC7, + 0xD8, 0xDB, 0x86, 0x5E, 0xF4, 0xFE, 0xC2, 0x05, + 0x86, 0xDF, 0x3D, 0xD9, 0x02, 0xA0, 0x5B, 0x26, + 0x35, 0x9E, 0x26, 0x7C, 0x78, 0x8D, 0x7C, 0x88, + 0x03, 0x2E, 0x76, 0x6B, 0x11, 0x87, 0x40, 0x20, + 0x0F, 0x49, 0xCB, 0x4D, 0x6E, 0xDB, 0x15, 0x61, + 0xB2, 0xDE, 0x7D, 0xC6, 0x5E, 0xE6, 0x42, 0x3B + }, + { + 0xE9, 0xE9, 0x8D, 0x6D, 0xE0, 0xEF, 0x53, 0xFD, + 0x24, 0x27, 0x66, 0x1E, 0x1A, 0xCF, 0x10, 0x3D, + 0x4C, 0xAA, 0x4D, 0xC6, 0x10, 0x03, 0x62, 0x09, + 0xEC, 0x99, 0x74, 0x19, 0xC1, 0x20, 0x63, 0x1C, + 0x2C, 0x09, 0x4A, 0x8E, 0xE7, 0x82, 0x2D, 0x43, + 0xF8, 0x77, 0x80, 0x11, 0xC6, 0x03, 0x11, 0x1F, + 0x26, 0x28, 0xF8, 0x97, 0xC9, 0xB4, 0x31, 0x31, + 0x54, 0x77, 0x75, 0x6B, 0x03, 0x2E, 0x1F, 0x8D + }, + { + 0x52, 0xEB, 0x1E, 0x6C, 0x8A, 0x54, 0x49, 0x2C, + 0xA7, 0x60, 0xB5, 0x6C, 0xA8, 0x7D, 0xA3, 0xE1, + 0xA9, 0xA6, 0xD8, 0xA4, 0x21, 0x92, 0x19, 0x35, + 0x1D, 0x18, 0x71, 0x5A, 0x9A, 0x2C, 0x26, 0x70, + 0x8B, 0xB7, 0x12, 0xCD, 0xAC, 0x04, 0x34, 0x48, + 0x2E, 0x55, 0x1C, 0xB0, 0x9E, 0x3F, 0x16, 0x33, + 0x8D, 0xE2, 0x9B, 0xE2, 0xC6, 0x67, 0x40, 0xC3, + 0x44, 0xDF, 0x54, 0x88, 0xC5, 0xC2, 0xBB, 0x26 + }, + { + 0x47, 0x3F, 0xA6, 0xC5, 0x1A, 0x48, 0x10, 0x5F, + 0x72, 0x1C, 0x5C, 0xB8, 0xDB, 0xA6, 0x1C, 0x64, + 0xA1, 0xE3, 0xDD, 0xCC, 0xC3, 0x25, 0x0E, 0x68, + 0x22, 0x62, 0xF2, 0x12, 0xC0, 0x1A, 0xB4, 0x87, + 0x4A, 0xFF, 0x68, 0x8F, 0xEA, 0x96, 0x37, 0x73, + 0x9E, 0x2A, 0x25, 0xD2, 0xEE, 0x88, 0xDB, 0xDC, + 0xC4, 0xF0, 0x4D, 0x01, 0x47, 0x9B, 0x30, 0x17, + 0x17, 0x53, 0x3A, 0x64, 0x32, 0xB8, 0x50, 0xCD + }, + { + 0x6B, 0x76, 0x60, 0xD4, 0x10, 0xEA, 0xE5, 0xF3, + 0x5A, 0xD0, 0xAE, 0x85, 0xE6, 0x3D, 0xA4, 0x53, + 0xEB, 0xB0, 0x57, 0xE4, 0x3F, 0x42, 0xE8, 0x42, + 0xCB, 0xF6, 0x25, 0x0D, 0xA6, 0x78, 0x66, 0xB4, + 0x24, 0x0D, 0x57, 0xC8, 0x3B, 0x77, 0x1B, 0x0F, + 0x70, 0x66, 0x3E, 0x17, 0xFB, 0xD9, 0x08, 0x7F, + 0x76, 0xB4, 0xCE, 0x6B, 0xCD, 0x0B, 0x50, 0x2E, + 0x33, 0x74, 0xB1, 0x50, 0x9B, 0xBA, 0x55, 0xA8 + }, + { + 0xA4, 0xD0, 0x8A, 0xCA, 0x7A, 0x9E, 0xA6, 0x43, + 0x99, 0x99, 0xEA, 0x21, 0xE4, 0xCF, 0xE9, 0x86, + 0x9B, 0xB9, 0x0E, 0x3A, 0x01, 0x48, 0x71, 0xAD, + 0x88, 0xED, 0x3A, 0x97, 0xAA, 0x89, 0x15, 0x95, + 0x1C, 0x3F, 0xD0, 0xB3, 0x93, 0x3A, 0x50, 0x85, + 0x88, 0x93, 0x8A, 0xF7, 0x54, 0x49, 0x44, 0xEF, + 0x43, 0xC4, 0x40, 0xAA, 0x8F, 0xF1, 0xE5, 0xA8, + 0x18, 0xA4, 0x66, 0x43, 0x5D, 0xE7, 0x0F, 0xA8 + }, + { + 0x85, 0xE0, 0xE9, 0xB5, 0x0D, 0x2D, 0xB0, 0x22, + 0xC2, 0x39, 0xD7, 0x23, 0x2A, 0xE4, 0x7C, 0x02, + 0x59, 0x22, 0xE4, 0xF0, 0x7E, 0x2A, 0xFC, 0x65, + 0x6C, 0xDC, 0x55, 0x53, 0xA2, 0x7D, 0x95, 0xBF, + 0xA5, 0x8A, 0x57, 0x4D, 0x4E, 0xC3, 0xA9, 0x73, + 0x28, 0x1A, 0x8F, 0x4E, 0x46, 0xA7, 0x1A, 0xB0, + 0x34, 0x1C, 0x25, 0x77, 0x28, 0x74, 0x63, 0xE2, + 0x51, 0x04, 0x4D, 0xB2, 0x39, 0x8D, 0x55, 0xE2 + }, + { + 0x81, 0xA0, 0xD0, 0x24, 0x42, 0x90, 0x51, 0x91, + 0x16, 0x33, 0x70, 0xAE, 0x29, 0xC7, 0xF8, 0x9C, + 0x0F, 0x48, 0xBC, 0x1A, 0x1E, 0xB2, 0x94, 0x70, + 0x47, 0xDA, 0x1C, 0x62, 0x2B, 0x86, 0x77, 0xE9, + 0xEA, 0x9B, 0xEC, 0xED, 0x55, 0xD3, 0x3A, 0xDB, + 0x15, 0x53, 0xBD, 0x58, 0x4A, 0xD2, 0xF8, 0x6A, + 0x62, 0x07, 0xE8, 0x4E, 0x40, 0xE4, 0x60, 0x7E, + 0x11, 0x65, 0x0E, 0xE2, 0x87, 0x9F, 0x4E, 0x0B + }, + { + 0x87, 0x79, 0x0D, 0xF6, 0xCF, 0x73, 0x94, 0x45, + 0x1B, 0xCC, 0x73, 0x0E, 0x53, 0xFC, 0x57, 0xBE, + 0x56, 0x45, 0x22, 0x77, 0x1E, 0x14, 0x43, 0x2A, + 0x80, 0xAB, 0x0B, 0x06, 0xB7, 0xB1, 0xD2, 0x09, + 0xAD, 0x69, 0x89, 0x95, 0x12, 0x53, 0x85, 0xDB, + 0x8B, 0x3C, 0x09, 0x59, 0xB8, 0xA5, 0x33, 0x9E, + 0xDA, 0x0A, 0xE6, 0x78, 0x59, 0xD8, 0x47, 0xF4, + 0x4C, 0x81, 0x59, 0x72, 0x72, 0xCB, 0xF1, 0x95 + }, + { + 0xCC, 0x06, 0x4E, 0xA8, 0x53, 0xDC, 0x01, 0x52, + 0xCC, 0x03, 0xFE, 0xB5, 0xFB, 0x5D, 0xE7, 0x8B, + 0x9B, 0x88, 0xE9, 0x61, 0x55, 0xD5, 0x35, 0x8B, + 0xCE, 0x84, 0xA5, 0x4C, 0x0E, 0x0C, 0x42, 0xFB, + 0xDA, 0x09, 0x2F, 0x22, 0xD0, 0x56, 0xDF, 0x99, + 0x93, 0x26, 0x2E, 0x2B, 0xA4, 0x4A, 0x5B, 0x2D, + 0x53, 0xC3, 0x75, 0x9D, 0x09, 0x45, 0xFE, 0xBA, + 0xA6, 0xFD, 0x51, 0xB8, 0xFF, 0x38, 0xD8, 0x39 + }, + { + 0x7E, 0x51, 0x7F, 0xC3, 0x83, 0xEE, 0x8C, 0x9F, + 0x0A, 0x01, 0x68, 0x1D, 0x39, 0xE7, 0x3B, 0xEB, + 0xA5, 0x96, 0x95, 0x95, 0xCE, 0x77, 0x92, 0x7F, + 0x91, 0x69, 0x1F, 0x33, 0xBB, 0x3E, 0x13, 0x07, + 0xEE, 0x03, 0x61, 0x6C, 0x27, 0xE6, 0x79, 0x51, + 0x86, 0xF6, 0x94, 0x0F, 0xED, 0xD9, 0xD5, 0xC7, + 0xF2, 0x1B, 0x6D, 0x2A, 0xAF, 0x70, 0x29, 0x9C, + 0xDD, 0x83, 0x51, 0x25, 0x05, 0x0A, 0x8B, 0x3C + }, + { + 0x84, 0x5F, 0xCF, 0xA6, 0x7F, 0x6E, 0x06, 0x55, + 0x10, 0xD2, 0x62, 0xF1, 0xDD, 0x69, 0x39, 0xEA, + 0x4C, 0x0A, 0x4A, 0x59, 0xC8, 0xEE, 0x39, 0x77, + 0xDB, 0x70, 0x05, 0xE1, 0xAE, 0xE4, 0x20, 0xBD, + 0x3F, 0x38, 0x26, 0xEC, 0xFE, 0x59, 0x01, 0x5B, + 0x4D, 0xFA, 0x0B, 0xD5, 0xBB, 0xF8, 0xD8, 0xA4, + 0x34, 0x48, 0x5D, 0xC1, 0x1C, 0xB9, 0xCC, 0x85, + 0x97, 0xCB, 0x8C, 0x95, 0x66, 0x11, 0x5F, 0x31 + }, + { + 0x17, 0xCF, 0x2C, 0x23, 0x21, 0x5B, 0xCD, 0xFC, + 0x24, 0x3D, 0x8A, 0x94, 0x5F, 0x3C, 0x5C, 0x25, + 0x1D, 0x27, 0x18, 0xA3, 0xF7, 0x5F, 0xED, 0x6F, + 0x33, 0x20, 0xBC, 0xC6, 0xFD, 0x92, 0x73, 0x86, + 0xD5, 0x6F, 0x87, 0x19, 0xCC, 0xA0, 0x2E, 0xC5, + 0xE9, 0x9C, 0xDA, 0xC4, 0xEA, 0x10, 0x95, 0xB4, + 0x65, 0xBA, 0x9A, 0x29, 0x8B, 0x1D, 0x23, 0x8E, + 0x38, 0xB3, 0xFA, 0x15, 0xE8, 0xB1, 0x4E, 0xE4 + }, + { + 0xD7, 0x89, 0xCE, 0xC7, 0xD7, 0x52, 0x0F, 0x10, + 0xE8, 0xB8, 0xB6, 0xC8, 0x40, 0x95, 0x89, 0xDF, + 0x57, 0xB8, 0x56, 0xB8, 0x24, 0x55, 0x68, 0xF6, + 0x4E, 0x2D, 0x21, 0x83, 0xE3, 0x59, 0xA7, 0x84, + 0xC8, 0xD2, 0x6C, 0xF9, 0xB7, 0x20, 0xF5, 0xDF, + 0x56, 0x7B, 0x01, 0xF3, 0xF4, 0x8D, 0xE6, 0x4D, + 0x4F, 0x0D, 0xB1, 0x56, 0xBE, 0x52, 0x5D, 0x7C, + 0x7A, 0x66, 0x5A, 0xAD, 0xC5, 0x91, 0xF0, 0xB6 + }, + { + 0xB5, 0xE2, 0x46, 0xA9, 0x02, 0x77, 0x10, 0xC0, + 0xB0, 0x55, 0xC7, 0x1F, 0x11, 0x67, 0xE0, 0xEE, + 0x36, 0xEB, 0xC4, 0x32, 0xCF, 0x5D, 0x14, 0x27, + 0x75, 0xA7, 0xAE, 0xCC, 0xCE, 0xA7, 0x83, 0x25, + 0xED, 0x8C, 0x12, 0xF5, 0x0F, 0xBE, 0x64, 0x8A, + 0xDD, 0xF0, 0x59, 0xB8, 0xC0, 0x2A, 0x61, 0x49, + 0x2F, 0x83, 0x57, 0xBE, 0xE1, 0x42, 0xE7, 0xF7, + 0xDE, 0x04, 0x33, 0x78, 0xDB, 0xCF, 0x2D, 0x33 + }, + { + 0xB5, 0x23, 0xFD, 0x77, 0xAB, 0x9E, 0xEE, 0x42, + 0x48, 0x72, 0xBC, 0x2E, 0x83, 0xFC, 0x0A, 0x77, + 0xFF, 0x8A, 0x90, 0xC9, 0xA0, 0xCE, 0x9E, 0x8C, + 0x87, 0x68, 0x0A, 0x0F, 0x62, 0x86, 0x33, 0x1F, + 0x15, 0xC9, 0x3A, 0x2A, 0xFE, 0xCF, 0x75, 0x66, + 0x65, 0x3F, 0x24, 0xD9, 0x30, 0xC3, 0x23, 0x19, + 0x2D, 0x30, 0x43, 0xB9, 0x05, 0x72, 0x1C, 0xBD, + 0xB6, 0x31, 0x11, 0xCA, 0x42, 0xF2, 0x8F, 0x4E + }, + { + 0x43, 0x59, 0xA4, 0x58, 0x76, 0xBF, 0x6A, 0xCC, + 0x0A, 0xEC, 0xE7, 0xB9, 0xB4, 0xB4, 0xA8, 0x38, + 0xB9, 0xDB, 0xA5, 0x77, 0x6A, 0x3B, 0x14, 0xDA, + 0x2F, 0xBA, 0x91, 0x02, 0xE7, 0x8B, 0xF6, 0x48, + 0xFF, 0xB4, 0xD8, 0x67, 0xBA, 0xE8, 0x5F, 0xD9, + 0xB7, 0x13, 0x12, 0xDC, 0x46, 0x02, 0xD0, 0xD4, + 0x9C, 0x90, 0x7B, 0xB9, 0x28, 0x9B, 0x22, 0x95, + 0x96, 0x1E, 0x54, 0x13, 0x81, 0x23, 0xF5, 0x4A + }, + { + 0xD3, 0xF2, 0xC8, 0xE7, 0x4F, 0x34, 0x3A, 0x4E, + 0x71, 0x90, 0xD4, 0x75, 0xCF, 0x9A, 0xF7, 0x54, + 0xEE, 0xD5, 0x57, 0x72, 0x62, 0xB3, 0x5B, 0xD9, + 0xA9, 0xC4, 0x2B, 0x58, 0xCE, 0x88, 0x26, 0x2E, + 0x31, 0x14, 0x91, 0x7F, 0xB9, 0xE6, 0x83, 0xC6, + 0x2D, 0x9F, 0x89, 0x47, 0xB5, 0x8A, 0x29, 0x4D, + 0xA5, 0x06, 0xFB, 0x86, 0xB3, 0xED, 0xF2, 0x5C, + 0xB9, 0xE2, 0xD2, 0xDF, 0x61, 0x1C, 0xD4, 0x48 + }, + { + 0x41, 0xB8, 0x90, 0xF8, 0xE8, 0x45, 0x0D, 0xAD, + 0xB6, 0x95, 0x9A, 0xCC, 0xBA, 0x19, 0x49, 0x17, + 0xE0, 0x2F, 0x30, 0x67, 0x82, 0x1D, 0x4E, 0x99, + 0x5A, 0x37, 0xAC, 0x18, 0xBA, 0x3E, 0x47, 0xC7, + 0x50, 0x6E, 0x7A, 0x3D, 0xD1, 0xE1, 0x12, 0xE6, + 0xEC, 0x41, 0xBE, 0xF5, 0x30, 0x85, 0x11, 0x20, + 0x89, 0x4A, 0x7B, 0x34, 0xB3, 0xDB, 0xCD, 0xAE, + 0x40, 0x73, 0x27, 0xF0, 0xC5, 0x73, 0x6E, 0xDF + }, + { + 0x19, 0xD7, 0x14, 0x4F, 0x0C, 0x85, 0x1E, 0xB8, + 0xB0, 0x53, 0xA3, 0xA4, 0x35, 0x86, 0x52, 0x6D, + 0xC5, 0xC7, 0x73, 0xE4, 0x97, 0x97, 0x51, 0x64, + 0xD1, 0x11, 0x51, 0x36, 0x43, 0x68, 0xDF, 0x24, + 0xBC, 0x44, 0xD5, 0x36, 0x07, 0x23, 0x04, 0xD7, + 0x06, 0x31, 0xA8, 0x40, 0xB6, 0x36, 0xB9, 0x66, + 0xFD, 0x02, 0x8F, 0x61, 0x06, 0x2B, 0xFC, 0x52, + 0x85, 0x67, 0x01, 0x53, 0xA6, 0x36, 0x3A, 0x0A + }, + { + 0xC2, 0x18, 0x4C, 0x1A, 0x81, 0xE9, 0x83, 0xBE, + 0x2C, 0x96, 0xE4, 0xCF, 0xD6, 0x5A, 0xFB, 0xDA, + 0x1A, 0xC6, 0xEF, 0x35, 0x26, 0x6E, 0xE4, 0xB3, + 0xAB, 0x1F, 0xB0, 0x3A, 0xBA, 0xDD, 0xFD, 0xD4, + 0x03, 0xFF, 0xFC, 0xAF, 0xB4, 0xAD, 0xE0, 0xE9, + 0x2D, 0xA3, 0x82, 0xDA, 0x8C, 0x40, 0x22, 0x2E, + 0x10, 0xE9, 0xFD, 0xE8, 0x56, 0xC5, 0x1B, 0xDA, + 0xCD, 0xE7, 0x41, 0xA6, 0x49, 0xF7, 0x33, 0x5D + }, + { + 0x48, 0x8C, 0x0D, 0x65, 0x2E, 0x42, 0xFD, 0x78, + 0xAB, 0x3A, 0x2D, 0xC2, 0x8C, 0xF3, 0xEB, 0x35, + 0xFC, 0xDD, 0xC8, 0xDE, 0xF7, 0xEA, 0xD4, 0x81, + 0x7B, 0xFF, 0xB6, 0x4C, 0x1A, 0xE0, 0xF2, 0x08, + 0xF7, 0x8C, 0xF4, 0x09, 0x76, 0xF7, 0xE2, 0xA2, + 0xCB, 0x2D, 0xD3, 0x0F, 0x1C, 0x99, 0x13, 0x02, + 0x08, 0xCE, 0xB6, 0x92, 0xC6, 0x68, 0x80, 0xD9, + 0x52, 0x8C, 0xD6, 0xD3, 0x8A, 0xD2, 0x9D, 0xB2 + }, + { + 0x51, 0x5B, 0x65, 0xBF, 0x65, 0x68, 0x83, 0x99, + 0x57, 0x5F, 0x0E, 0x06, 0x77, 0xBB, 0x6A, 0x91, + 0x9B, 0x66, 0x33, 0x55, 0x46, 0xD6, 0xCA, 0xE3, + 0x36, 0xF5, 0xC6, 0xFE, 0xAE, 0x5E, 0x2B, 0xF7, + 0x45, 0xE3, 0xA7, 0xB1, 0x3C, 0x32, 0x05, 0xDD, + 0x8B, 0x5B, 0x92, 0xCF, 0x05, 0x3B, 0xE9, 0x69, + 0xDF, 0x71, 0x20, 0xFC, 0xEF, 0x77, 0xE3, 0x89, + 0x5F, 0x56, 0x0F, 0xD2, 0x32, 0xFB, 0x89, 0x50 + }, + { + 0x3F, 0xDB, 0xC7, 0xD6, 0x9F, 0x4B, 0x53, 0xC2, + 0x25, 0x66, 0x3D, 0xA3, 0x0D, 0x80, 0xF7, 0x2E, + 0x54, 0x28, 0x10, 0x44, 0xA2, 0x2B, 0x98, 0x82, + 0xC6, 0x63, 0x8F, 0x55, 0x26, 0x83, 0x4B, 0xD3, + 0x16, 0x01, 0xCA, 0x5E, 0xB2, 0xCC, 0xA4, 0xF5, + 0xFF, 0xCF, 0x67, 0x5D, 0xCB, 0xCF, 0xCA, 0x60, + 0xC8, 0xA3, 0x61, 0x2D, 0x1A, 0xA9, 0xDA, 0xB6, + 0x93, 0xB2, 0x35, 0x60, 0x69, 0x60, 0x3A, 0x0E + }, + { + 0x4F, 0xF6, 0xC3, 0x1A, 0x8F, 0xC0, 0x01, 0xAC, + 0x3B, 0x7A, 0xE0, 0x20, 0xC5, 0xF7, 0xC4, 0x5E, + 0xFB, 0x62, 0x71, 0xA2, 0xD7, 0xCC, 0xAB, 0x87, + 0x13, 0xE5, 0x48, 0xB7, 0x29, 0xF0, 0xFF, 0xF9, + 0xC8, 0x2F, 0xD4, 0xDB, 0x5C, 0xF6, 0x56, 0x43, + 0xD4, 0x07, 0x6A, 0x3F, 0xB1, 0x7B, 0x3E, 0x89, + 0x3C, 0x30, 0x2D, 0xC7, 0x5B, 0x61, 0x22, 0xFF, + 0x86, 0x81, 0xD0, 0x37, 0x12, 0x0E, 0x27, 0x6A + }, + { + 0x43, 0xDF, 0xF2, 0x60, 0xDF, 0xEF, 0x1C, 0xB2, + 0xD6, 0x16, 0x00, 0xE2, 0x40, 0xAA, 0xD6, 0xB7, + 0x20, 0xE5, 0xF4, 0xF8, 0x30, 0x86, 0xE2, 0x6A, + 0x49, 0xA0, 0xCE, 0x3E, 0x0C, 0xA4, 0x4B, 0x9A, + 0x60, 0xFC, 0xF4, 0x6A, 0x8C, 0x3F, 0x1B, 0xB1, + 0xA6, 0xF5, 0x76, 0x2B, 0x66, 0x51, 0x3F, 0xE3, + 0xF7, 0xC5, 0xB0, 0xBC, 0x15, 0x0C, 0x08, 0x49, + 0x1A, 0xCB, 0xC4, 0x36, 0x1C, 0xAB, 0xCF, 0xDF + }, + { + 0xB4, 0xDE, 0xA9, 0x4C, 0x9D, 0x36, 0x75, 0xBE, + 0x05, 0x12, 0xEF, 0xDE, 0xA8, 0x16, 0x38, 0x70, + 0xFE, 0x34, 0x25, 0xDC, 0xD7, 0x61, 0xF3, 0x63, + 0xC4, 0x3A, 0x0C, 0xA5, 0x71, 0x6B, 0x76, 0x54, + 0x06, 0x63, 0xFB, 0x2B, 0xE4, 0x9E, 0x2D, 0xB1, + 0x06, 0x48, 0x5C, 0x9C, 0xDD, 0x3C, 0x16, 0x48, + 0x98, 0xA9, 0x54, 0xB5, 0x87, 0x48, 0xC4, 0x2F, + 0xEA, 0x16, 0xA4, 0x0F, 0xC4, 0x53, 0xD2, 0x10 + }, + { + 0xE5, 0x27, 0x7B, 0x6F, 0x93, 0xEA, 0x1D, 0xE3, + 0xE2, 0xD9, 0xFC, 0xD8, 0xC6, 0x79, 0x79, 0x3C, + 0x6C, 0xCB, 0x8A, 0x3B, 0xE2, 0x6E, 0x8E, 0x31, + 0x14, 0xF3, 0x5D, 0xA4, 0xF2, 0xAC, 0x01, 0x4F, + 0x55, 0xC2, 0xF1, 0x5E, 0x09, 0xE9, 0x4A, 0xA0, + 0x71, 0x29, 0x81, 0x67, 0xA2, 0xFB, 0x9B, 0xE3, + 0x11, 0x70, 0x1F, 0xFB, 0xA9, 0xD3, 0xEE, 0xFF, + 0x8F, 0xFC, 0x79, 0x93, 0xA3, 0xCE, 0xCE, 0x18 + }, + { + 0xF0, 0x95, 0xA7, 0xC6, 0xE2, 0xB9, 0x16, 0x64, + 0x73, 0x4F, 0x3E, 0x23, 0xF1, 0x8E, 0xB2, 0xBA, + 0x9B, 0x00, 0xE7, 0x1F, 0xBF, 0xCB, 0x99, 0x31, + 0xC0, 0xA6, 0x14, 0x79, 0x2A, 0x9D, 0x86, 0x75, + 0x62, 0x2A, 0x87, 0x4C, 0x1B, 0xF5, 0x24, 0x1A, + 0x2A, 0x87, 0x41, 0xED, 0x1C, 0x89, 0x3B, 0xDF, + 0xA8, 0xE2, 0x8C, 0x2E, 0x20, 0xBB, 0x1C, 0x58, + 0xEB, 0x4D, 0xE7, 0xD8, 0x01, 0x11, 0x6C, 0x78 + }, + { + 0xDF, 0xA1, 0xFD, 0x80, 0x3A, 0x1D, 0x4A, 0x3E, + 0x66, 0x1D, 0xF0, 0x1F, 0x49, 0x43, 0xEA, 0x66, + 0x26, 0x0A, 0x18, 0xFE, 0xCE, 0x13, 0x4D, 0x62, + 0xF9, 0x7D, 0xAC, 0xDB, 0x8B, 0x3B, 0xF9, 0xC8, + 0x00, 0xAF, 0xE5, 0x79, 0xCF, 0xD1, 0x3F, 0xC0, + 0x14, 0x8B, 0xDE, 0xFB, 0xFF, 0x4E, 0x76, 0x83, + 0x56, 0x1C, 0x06, 0xA6, 0xF7, 0x22, 0x5E, 0x47, + 0x81, 0x99, 0x3B, 0x4F, 0x4F, 0x2B, 0xCB, 0xFA + }, + { + 0x2B, 0x86, 0xCE, 0xB2, 0x70, 0xF6, 0x90, 0x8D, + 0x8B, 0x16, 0x00, 0x75, 0xEA, 0x7F, 0x57, 0x16, + 0x3A, 0xF5, 0xD5, 0xC6, 0xF8, 0xAA, 0xC5, 0x20, + 0x40, 0xCC, 0x68, 0x7C, 0x17, 0xAB, 0xF3, 0xC7, + 0x78, 0xC1, 0x39, 0x06, 0xE0, 0xE6, 0xF2, 0x9A, + 0x6A, 0xB1, 0x23, 0xDE, 0xEB, 0xCE, 0x39, 0x1F, + 0x90, 0x7D, 0x75, 0xD3, 0xA2, 0xCE, 0xFA, 0x0E, + 0xFC, 0xB8, 0x80, 0xA0, 0xE7, 0x0D, 0x71, 0x96 + }, + { + 0x32, 0x46, 0x6B, 0xCB, 0xDE, 0xD5, 0x38, 0xE5, + 0x68, 0x79, 0x54, 0x30, 0x35, 0x25, 0x36, 0xFE, + 0xB9, 0x19, 0xBF, 0x4D, 0x97, 0xCC, 0x44, 0xAB, + 0x1D, 0x80, 0x50, 0x40, 0xF4, 0xBC, 0x4C, 0x2E, + 0x79, 0x52, 0x72, 0x10, 0x18, 0x95, 0x8B, 0x4E, + 0xE7, 0x83, 0x03, 0x59, 0x0E, 0xF6, 0xAC, 0x45, + 0x0D, 0xF9, 0x2E, 0xC7, 0x7F, 0x47, 0x70, 0x54, + 0xBF, 0xF8, 0x67, 0xB8, 0x89, 0x71, 0xD4, 0x21 + }, + { + 0xEA, 0x64, 0xB0, 0x03, 0xA1, 0x35, 0x76, 0x61, + 0x21, 0xCF, 0xBC, 0xCB, 0xDC, 0x08, 0xDC, 0xA2, + 0x40, 0x29, 0x26, 0xBE, 0x78, 0xCE, 0xA3, 0xD0, + 0xA7, 0x25, 0x3D, 0x9E, 0xC9, 0xE6, 0x3B, 0x8A, + 0xCD, 0xD9, 0x94, 0x55, 0x99, 0x17, 0xE0, 0xE0, + 0x3B, 0x5E, 0x15, 0x5F, 0x94, 0x4D, 0x71, 0x98, + 0xD9, 0x92, 0x45, 0xA7, 0x94, 0xCE, 0x19, 0xC9, + 0xB4, 0xDF, 0x4D, 0xA4, 0xA3, 0x39, 0x93, 0x34 + }, + { + 0x05, 0xAD, 0x0F, 0x27, 0x1F, 0xAF, 0x7E, 0x36, + 0x13, 0x20, 0x51, 0x84, 0x52, 0x81, 0x3F, 0xF9, + 0xFB, 0x99, 0x76, 0xAC, 0x37, 0x80, 0x50, 0xB6, + 0xEE, 0xFB, 0x05, 0xF7, 0x86, 0x7B, 0x57, 0x7B, + 0x8F, 0x14, 0x47, 0x57, 0x94, 0xCF, 0xF6, 0x1B, + 0x2B, 0xC0, 0x62, 0xD3, 0x46, 0xA7, 0xC6, 0x5C, + 0x6E, 0x00, 0x67, 0xC6, 0x0A, 0x37, 0x4A, 0xF7, + 0x94, 0x0F, 0x10, 0xAA, 0x44, 0x9D, 0x5F, 0xB9 + }, + { + 0xB5, 0x45, 0x88, 0x02, 0x94, 0xAF, 0xA1, 0x53, + 0xF8, 0xB9, 0xF4, 0x9C, 0x73, 0xD9, 0x52, 0xB5, + 0xD1, 0x22, 0x8F, 0x1A, 0x1A, 0xB5, 0xEB, 0xCB, + 0x05, 0xFF, 0x79, 0xE5, 0x60, 0xC0, 0x30, 0xF7, + 0x50, 0x0F, 0xE2, 0x56, 0xA4, 0x0B, 0x6A, 0x0E, + 0x6C, 0xB3, 0xD4, 0x2A, 0xCD, 0x4B, 0x98, 0x59, + 0x5C, 0x5B, 0x51, 0xEA, 0xEC, 0x5A, 0xD6, 0x9C, + 0xD4, 0x0F, 0x1F, 0xC1, 0x6D, 0x2D, 0x5F, 0x50 + }, + { + 0xBB, 0xFB, 0x94, 0x77, 0xEC, 0x6A, 0x9F, 0x0C, + 0x25, 0x40, 0x5A, 0xCD, 0x8A, 0x30, 0xD5, 0xDD, + 0x7C, 0x73, 0x57, 0x1F, 0x1D, 0x1A, 0x6E, 0x8C, + 0xE7, 0x2F, 0x8B, 0x9C, 0x94, 0x1C, 0xF7, 0x79, + 0xB7, 0x64, 0x03, 0xAC, 0x7F, 0x04, 0x50, 0x05, + 0x25, 0x84, 0x39, 0x0A, 0x14, 0xEA, 0xA3, 0x7C, + 0x20, 0xB5, 0xBD, 0xB0, 0x38, 0x10, 0x54, 0xA9, + 0xA4, 0x95, 0x34, 0xF8, 0x14, 0x66, 0xBA, 0x9D + }, + { + 0xC8, 0x28, 0x7E, 0x93, 0x3D, 0x95, 0x04, 0xBF, + 0xFD, 0x7B, 0xE2, 0xAC, 0x02, 0x2B, 0x32, 0xF3, + 0xF4, 0x6D, 0x87, 0xA7, 0xA0, 0xE7, 0x9B, 0xB2, + 0xA1, 0xCB, 0xAA, 0xCC, 0x2E, 0x84, 0xCD, 0x70, + 0x84, 0x5D, 0x0D, 0x42, 0x78, 0x48, 0xA6, 0xD7, + 0x88, 0xD3, 0x96, 0x22, 0xE1, 0x0F, 0x43, 0x42, + 0x23, 0x7E, 0xEF, 0xA6, 0xD3, 0xC0, 0x12, 0xDA, + 0xE9, 0x6C, 0xC8, 0xA6, 0x50, 0xCC, 0x2E, 0x30 + }, + { + 0xC4, 0x59, 0x6F, 0xCB, 0x0A, 0x28, 0xD2, 0x4A, + 0xAD, 0x70, 0xCF, 0x18, 0x53, 0xEC, 0x29, 0xDA, + 0xC0, 0xFB, 0x20, 0x2D, 0x8E, 0xC1, 0x40, 0xDA, + 0x30, 0x00, 0x88, 0xBB, 0x85, 0xB9, 0x2C, 0x30, + 0x29, 0x19, 0x46, 0xAD, 0x30, 0x7C, 0x09, 0x6E, + 0x3B, 0x28, 0x66, 0x33, 0x5C, 0x93, 0x17, 0xAF, + 0xE2, 0x8C, 0xAD, 0xAB, 0x5D, 0x62, 0xC3, 0x54, + 0x32, 0x9C, 0x98, 0xD9, 0x93, 0xC5, 0xBE, 0x1C + }, + { + 0xE8, 0x8C, 0x38, 0xE6, 0x7E, 0x8D, 0x19, 0x83, + 0x58, 0x08, 0x85, 0x46, 0x70, 0x77, 0x9E, 0xCA, + 0x60, 0xBA, 0xD8, 0x54, 0xC5, 0x77, 0x87, 0x90, + 0xA0, 0x72, 0x54, 0xA3, 0x0A, 0x14, 0xAE, 0x82, + 0xB6, 0x1B, 0xB1, 0x69, 0x11, 0xFE, 0x57, 0x77, + 0x1D, 0x19, 0xE9, 0xB7, 0xF5, 0x02, 0x3C, 0x0D, + 0x4E, 0x8A, 0x8D, 0x37, 0x2E, 0x3D, 0x85, 0xE4, + 0x3B, 0x03, 0xE5, 0xE0, 0x0E, 0x6E, 0xBA, 0x4B + }, + { + 0x2D, 0x66, 0x3E, 0x03, 0xE6, 0xF3, 0x55, 0x2C, + 0xCD, 0xFB, 0xA4, 0x96, 0xA1, 0x4C, 0xC6, 0x22, + 0x4C, 0xEB, 0x1E, 0xB6, 0x1A, 0xA2, 0x65, 0xE6, + 0xA7, 0xD4, 0xA2, 0x6E, 0x54, 0x10, 0x61, 0x04, + 0xA9, 0x6E, 0x33, 0x09, 0x59, 0xF9, 0x71, 0x3B, + 0x34, 0x87, 0xC1, 0xB9, 0x49, 0x7C, 0xCF, 0x82, + 0x61, 0x1D, 0xBF, 0xA3, 0x4F, 0xF1, 0x1D, 0x31, + 0x33, 0xB5, 0xB5, 0xD1, 0xF1, 0xE4, 0xF8, 0xD0 + }, + { + 0x70, 0x7D, 0x6A, 0x58, 0x42, 0x1B, 0x8F, 0x7E, + 0x44, 0xFF, 0x1F, 0x83, 0x62, 0xBC, 0x70, 0x0F, + 0x71, 0xEF, 0x7C, 0x39, 0x35, 0xE0, 0x76, 0x4B, + 0xD1, 0x4D, 0x39, 0x0C, 0x1C, 0x72, 0x79, 0x2A, + 0xF9, 0xC2, 0xC0, 0x2F, 0xB7, 0x2A, 0x2B, 0x9D, + 0x9A, 0x07, 0x29, 0xCB, 0x3E, 0x99, 0x62, 0x6C, + 0xF0, 0x34, 0xDF, 0x54, 0xB5, 0x06, 0xB5, 0xB1, + 0x64, 0x64, 0xF4, 0x75, 0x86, 0x4F, 0x25, 0x90 + }, + { + 0x9D, 0x88, 0xF8, 0xBA, 0xA4, 0xEB, 0x0F, 0x9A, + 0xB2, 0x29, 0x2E, 0x49, 0x82, 0xAC, 0x80, 0x44, + 0x53, 0x58, 0x22, 0x7D, 0x7F, 0x9C, 0xE7, 0xA4, + 0xA6, 0x29, 0xF1, 0x80, 0xF7, 0x14, 0x1E, 0x08, + 0xFE, 0x63, 0x55, 0xC6, 0x45, 0x21, 0xA6, 0x9B, + 0xA2, 0xBF, 0xBD, 0x1C, 0x4A, 0x3E, 0xA0, 0x48, + 0xD0, 0xBC, 0x8A, 0xB3, 0x70, 0x1F, 0x30, 0xEA, + 0x83, 0xFB, 0xE0, 0x24, 0x74, 0xD8, 0x92, 0xBF + }, + { + 0x65, 0xEA, 0x4D, 0xB0, 0x4A, 0x75, 0x81, 0xC1, + 0x81, 0x94, 0xA8, 0x92, 0x1A, 0xFD, 0xFA, 0x4F, + 0x8D, 0x9A, 0xF6, 0x29, 0xDE, 0xD2, 0x77, 0x2C, + 0x65, 0x8E, 0x08, 0x48, 0x5F, 0x67, 0xAD, 0x2C, + 0xE2, 0x1A, 0x98, 0xCD, 0x29, 0x3F, 0xF2, 0x8D, + 0x4D, 0xFC, 0xDF, 0x65, 0x8C, 0xDC, 0x7A, 0xE6, + 0x70, 0x27, 0x84, 0x8E, 0x71, 0xCC, 0xC1, 0x15, + 0xA3, 0xFF, 0xBA, 0xC4, 0xFA, 0x61, 0xBB, 0x73 + }, + { + 0x0B, 0x4A, 0x68, 0x92, 0x9E, 0x7F, 0x15, 0xCA, + 0x91, 0xBB, 0x44, 0x39, 0xF2, 0x40, 0x37, 0x02, + 0x03, 0x4C, 0xD4, 0x74, 0x8E, 0x46, 0x92, 0x7A, + 0xBA, 0x95, 0xCB, 0xEF, 0x80, 0x04, 0x8B, 0x25, + 0xA6, 0x75, 0x97, 0x0F, 0xAC, 0x33, 0xC8, 0x74, + 0xAB, 0xD3, 0xD8, 0x3A, 0xA0, 0xF3, 0x7B, 0xE2, + 0x30, 0x83, 0x10, 0xE8, 0xDD, 0x79, 0x4F, 0x81, + 0x92, 0x93, 0x0E, 0xD5, 0x6E, 0x70, 0xA8, 0xE4 + }, + { + 0xC1, 0xC5, 0xD8, 0xAC, 0xFE, 0x3F, 0xDE, 0x67, + 0x4E, 0xDD, 0x36, 0x20, 0x15, 0x7A, 0x8B, 0x6B, + 0x4C, 0x8E, 0x67, 0xC6, 0xA7, 0xA9, 0x72, 0x67, + 0x41, 0xD9, 0xC3, 0x05, 0xE2, 0xA5, 0x2A, 0x87, + 0x97, 0xFD, 0xA0, 0xB2, 0xF1, 0x3A, 0xC7, 0x87, + 0x34, 0xDB, 0x2F, 0x4F, 0xC8, 0x3E, 0xF3, 0x24, + 0x14, 0xD9, 0x31, 0xEB, 0xAE, 0xAE, 0xCD, 0x82, + 0x6D, 0x7C, 0x2B, 0xE2, 0x03, 0xBD, 0xC2, 0xD1 + }, + { + 0x2D, 0xAD, 0xC8, 0xC9, 0xF7, 0x42, 0x5A, 0x01, + 0x14, 0x49, 0x12, 0x87, 0xBD, 0xC6, 0x8E, 0xAE, + 0x4F, 0xB6, 0x19, 0x4D, 0x1A, 0x10, 0x9D, 0xB9, + 0xB6, 0xE8, 0xA2, 0xAC, 0x94, 0xD4, 0xE4, 0x40, + 0x90, 0x99, 0x85, 0xC4, 0x29, 0x1F, 0xE8, 0x9F, + 0xD8, 0x28, 0x1F, 0x8F, 0xCE, 0xF6, 0xF6, 0xBC, + 0x32, 0x55, 0x0E, 0x53, 0xCB, 0x7A, 0x49, 0x42, + 0x89, 0x81, 0xE8, 0xD5, 0x3C, 0xF5, 0xA2, 0x12 + }, + { + 0xE5, 0x55, 0xF2, 0xA5, 0x8A, 0xCA, 0xC5, 0x50, + 0x3F, 0x9E, 0x2D, 0x97, 0xB2, 0x46, 0x87, 0x2B, + 0x4C, 0xA7, 0x8B, 0xD5, 0x6D, 0x47, 0xB7, 0x65, + 0xF0, 0x52, 0xAA, 0xB3, 0xDC, 0x77, 0xDB, 0xE9, + 0x93, 0x93, 0x6F, 0x22, 0x52, 0xF0, 0xAB, 0x2E, + 0x01, 0xFB, 0x08, 0x74, 0x72, 0xCC, 0xB5, 0xA1, + 0x21, 0xDD, 0xFF, 0xDE, 0x53, 0x1D, 0x3D, 0xC4, + 0x02, 0x2A, 0x7D, 0x19, 0x56, 0xCE, 0x0E, 0x20 + }, + { + 0x9B, 0x4E, 0xAE, 0x12, 0x95, 0x00, 0x0A, 0xEA, + 0x79, 0x83, 0xEC, 0x3B, 0xCB, 0x48, 0x57, 0xCC, + 0x71, 0x25, 0xFD, 0x73, 0x06, 0x78, 0x7C, 0x63, + 0x13, 0x24, 0x73, 0xCF, 0xE8, 0xF4, 0xEB, 0x45, + 0x31, 0x8A, 0x60, 0xDA, 0xAD, 0x64, 0x6D, 0x63, + 0xA2, 0x7C, 0x4B, 0x9D, 0x1F, 0x50, 0x73, 0x70, + 0x0A, 0x30, 0x57, 0xDE, 0x22, 0xA7, 0xFD, 0xF0, + 0x9A, 0x87, 0xAA, 0xC6, 0x6E, 0xBE, 0x47, 0x58 + }, + { + 0x96, 0x64, 0xAC, 0xC2, 0xDC, 0x72, 0x98, 0xB9, + 0x86, 0x8D, 0xB4, 0x95, 0xEE, 0xBC, 0x6B, 0x59, + 0x65, 0x7D, 0x13, 0x9A, 0x6A, 0xF0, 0x60, 0xA7, + 0x2F, 0xB6, 0x91, 0x24, 0xBD, 0xD3, 0xA6, 0x59, + 0x18, 0x88, 0xF0, 0x35, 0x4F, 0x70, 0x2B, 0x1B, + 0x88, 0x86, 0x84, 0x41, 0x10, 0x58, 0xA3, 0x75, + 0x9F, 0x7F, 0xD3, 0x7F, 0x06, 0xEA, 0xFB, 0x3B, + 0x58, 0xEC, 0xF2, 0x6F, 0x45, 0x53, 0xBE, 0x27 + }, + { + 0xFC, 0x16, 0xE0, 0x92, 0x5A, 0x35, 0xAA, 0xD4, + 0x7A, 0xD6, 0x95, 0x54, 0xB2, 0x57, 0x96, 0xFC, + 0xF9, 0x26, 0x0C, 0xB5, 0x0E, 0x6C, 0xC3, 0x74, + 0x75, 0x35, 0x55, 0x9E, 0x99, 0xC8, 0x58, 0x81, + 0xC7, 0x58, 0x89, 0xAC, 0x79, 0x3A, 0xB7, 0x8B, + 0x88, 0xB0, 0x5F, 0xB1, 0x60, 0x89, 0x56, 0x55, + 0xE4, 0xD6, 0x63, 0xA2, 0xA0, 0x9B, 0xA9, 0xFA, + 0x61, 0x4A, 0x10, 0xC2, 0x29, 0x47, 0x21, 0x0D + }, + { + 0x22, 0x5E, 0x73, 0x41, 0xF8, 0x57, 0x52, 0x4F, + 0x78, 0x90, 0x37, 0x6C, 0x50, 0xE6, 0x35, 0x4B, + 0x16, 0xC1, 0xCD, 0xFB, 0xF5, 0x8F, 0xE5, 0xF3, + 0xA4, 0x03, 0x94, 0x93, 0xB5, 0xDD, 0x40, 0x8D, + 0x79, 0xD4, 0x8C, 0x56, 0xE1, 0xF8, 0x9B, 0x68, + 0x7F, 0xBE, 0x33, 0x62, 0xA7, 0x7F, 0xA7, 0x5A, + 0x54, 0x37, 0x4B, 0x7A, 0x48, 0x5E, 0x91, 0xB1, + 0x89, 0xAF, 0x2E, 0x2F, 0x74, 0x9E, 0x2A, 0xDB + }, + { + 0xA0, 0x7A, 0x4C, 0x02, 0x3A, 0xC7, 0x04, 0xCE, + 0x7C, 0x09, 0xDD, 0x6C, 0x92, 0xC6, 0xF1, 0x84, + 0xF5, 0x3E, 0x8D, 0xD9, 0x6F, 0xE3, 0xBE, 0x9E, + 0x93, 0xC3, 0x9C, 0x53, 0x44, 0x85, 0xB6, 0x4B, + 0x39, 0xD5, 0xBE, 0x7F, 0x7B, 0x71, 0x70, 0x60, + 0x4D, 0xE7, 0x7C, 0xE5, 0xA4, 0x37, 0xA9, 0x8E, + 0x71, 0x2C, 0xC4, 0x4F, 0x19, 0xE2, 0x1D, 0x41, + 0xF0, 0xE6, 0xE3, 0xEC, 0x1E, 0x00, 0xAC, 0x55 + }, + { + 0x62, 0x85, 0x84, 0x63, 0x58, 0x2D, 0x22, 0xE6, + 0x8E, 0x52, 0x27, 0xBF, 0xBA, 0xB5, 0x40, 0x04, + 0x8F, 0x65, 0xED, 0xD6, 0xA6, 0x75, 0x5F, 0x6F, + 0xAB, 0x53, 0xC0, 0x25, 0xB6, 0x63, 0xCA, 0x37, + 0x7A, 0x0E, 0xD5, 0xEF, 0xD6, 0xAF, 0x16, 0x6C, + 0xA5, 0x5A, 0x9C, 0x73, 0x3F, 0xCA, 0x80, 0x5A, + 0xC4, 0xE4, 0x09, 0xCA, 0x56, 0x17, 0x7A, 0xA7, + 0x49, 0x40, 0xDB, 0x9F, 0x40, 0xC3, 0xB9, 0xFF + }, + { + 0xA1, 0xAC, 0x53, 0x9D, 0x1A, 0xBB, 0xC2, 0xB0, + 0x96, 0xFF, 0xAB, 0x81, 0x3B, 0x64, 0x45, 0x7F, + 0xE6, 0xEB, 0x3B, 0x50, 0xFC, 0xD8, 0x89, 0x53, + 0xD0, 0xCD, 0x9F, 0x65, 0x02, 0xF6, 0x89, 0x62, + 0x0A, 0xD4, 0x42, 0xB5, 0x51, 0x70, 0x90, 0xB5, + 0x0C, 0xFF, 0xB9, 0x58, 0x86, 0x6D, 0x7C, 0x16, + 0x1D, 0x8A, 0x7D, 0x75, 0x60, 0xC8, 0x93, 0xE1, + 0xDE, 0xF6, 0xAE, 0xC4, 0x37, 0xAD, 0x6D, 0x06 + }, + { + 0xB5, 0x86, 0xB7, 0x5D, 0xA7, 0x0F, 0x6C, 0xC0, + 0x62, 0x7E, 0xF3, 0xCF, 0x12, 0x37, 0xC9, 0x4B, + 0x12, 0xD0, 0xF7, 0x4D, 0xCB, 0xA2, 0x6A, 0x9E, + 0x7C, 0x7B, 0xC6, 0xC2, 0x1A, 0x33, 0x53, 0x37, + 0xBF, 0x9F, 0x5B, 0x83, 0x0C, 0x63, 0x24, 0xAF, + 0xA6, 0xEF, 0x64, 0x9E, 0x95, 0xAF, 0x87, 0x90, + 0x87, 0x52, 0x34, 0xC6, 0xE6, 0x61, 0xD3, 0xF5, + 0xE9, 0x8C, 0xA0, 0x12, 0xAE, 0x81, 0x48, 0x8A + }, + { + 0x56, 0x68, 0xA2, 0x98, 0x21, 0x37, 0xCB, 0xC6, + 0x22, 0xEF, 0x8D, 0x06, 0xCF, 0x4E, 0x86, 0x16, + 0x8C, 0xDD, 0x4A, 0x89, 0x9C, 0xD4, 0x46, 0x2A, + 0xF6, 0xC3, 0xD4, 0x15, 0x42, 0x61, 0x56, 0xA5, + 0xD8, 0xDD, 0x67, 0xC9, 0x60, 0x4F, 0x31, 0xB5, + 0x7D, 0x6C, 0x9D, 0x59, 0x72, 0x50, 0x45, 0x7E, + 0x4A, 0xB5, 0x2A, 0x58, 0x11, 0x55, 0x42, 0xAC, + 0xF2, 0x7F, 0x92, 0x59, 0x30, 0xF6, 0xA1, 0x12 + }, + { + 0xF2, 0xB1, 0xBD, 0x16, 0xD8, 0x8E, 0x37, 0xF3, + 0xA5, 0x18, 0xD1, 0x93, 0xED, 0x06, 0x1A, 0x1D, + 0xF7, 0xB4, 0x43, 0xA1, 0x8C, 0xE9, 0xF8, 0x44, + 0x45, 0xEF, 0x86, 0xEF, 0xFB, 0xDF, 0xF1, 0x60, + 0x55, 0x02, 0x3C, 0xD4, 0xE7, 0x8D, 0x03, 0x4D, + 0xE4, 0x03, 0x2A, 0x77, 0xDD, 0xC1, 0xD3, 0x43, + 0x52, 0xFE, 0x61, 0x7F, 0x82, 0x56, 0x24, 0x45, + 0x9B, 0xC3, 0x26, 0x9F, 0x70, 0x4F, 0x34, 0x5B + }, + { + 0xF0, 0x85, 0xF3, 0xD8, 0xBD, 0x13, 0x8E, 0x05, + 0x69, 0x24, 0x3F, 0x74, 0x52, 0x3E, 0x87, 0xFF, + 0x37, 0x6F, 0x04, 0xEA, 0xBD, 0x5A, 0x2F, 0x6E, + 0x53, 0xDF, 0x38, 0x99, 0x00, 0x0E, 0x2E, 0x94, + 0xAF, 0x0D, 0x2B, 0xC7, 0x1C, 0x3F, 0x71, 0x10, + 0x25, 0xC5, 0x38, 0xA6, 0xC8, 0xB1, 0x0B, 0x09, + 0x04, 0xDF, 0xC3, 0x46, 0xAD, 0xAD, 0x7E, 0xF3, + 0x6B, 0x1A, 0xE8, 0x8A, 0x6C, 0xFE, 0xAB, 0xBD + }, + { + 0x82, 0x91, 0xA4, 0xAF, 0xD2, 0xE4, 0xB7, 0x16, + 0x61, 0x77, 0x3A, 0x46, 0xB3, 0xD4, 0x45, 0x5A, + 0x8D, 0x33, 0xA7, 0x26, 0xD9, 0xD3, 0x87, 0x30, + 0x83, 0xAB, 0x33, 0x70, 0x20, 0xC2, 0x7B, 0x4D, + 0xD6, 0x43, 0xE2, 0x8C, 0x2F, 0xE4, 0x7A, 0xB2, + 0xFB, 0xF5, 0xD1, 0x40, 0x81, 0xA3, 0xFC, 0x1C, + 0x83, 0x9B, 0x12, 0xEA, 0x31, 0xD1, 0x3C, 0xF4, + 0x9E, 0xEE, 0x97, 0xEF, 0x2E, 0xD7, 0xFA, 0x3E + }, + { + 0xB1, 0x26, 0xAE, 0x46, 0xA7, 0xA4, 0x59, 0x5E, + 0x31, 0x60, 0x7E, 0xF8, 0x07, 0xA5, 0x60, 0x1F, + 0x4E, 0xCD, 0x9E, 0x7D, 0x66, 0xC8, 0x2D, 0xAE, + 0xB9, 0x71, 0x5F, 0x8D, 0xA1, 0xC1, 0x7D, 0x7D, + 0x71, 0xC3, 0xE6, 0x82, 0x50, 0xC9, 0xDC, 0x01, + 0xAC, 0x40, 0xA3, 0x6D, 0x2E, 0x63, 0x8B, 0xEF, + 0x3D, 0x7B, 0xC7, 0x0E, 0xA2, 0xD0, 0xE3, 0x31, + 0xE3, 0xD3, 0x3E, 0x17, 0x04, 0xEB, 0xA9, 0x2D + }, + { + 0x63, 0xB1, 0x4D, 0x8E, 0xD2, 0x47, 0x9C, 0xAA, + 0x17, 0xC3, 0xE4, 0xCF, 0x20, 0x3B, 0x23, 0x3A, + 0x7E, 0x37, 0x3E, 0xDB, 0x0C, 0x2F, 0x19, 0x71, + 0x29, 0xA9, 0xA3, 0x6C, 0x5B, 0x3E, 0x1F, 0x38, + 0x38, 0xF2, 0xE8, 0x2A, 0xC2, 0xC2, 0xAD, 0x9D, + 0x52, 0xB3, 0x35, 0x79, 0x0B, 0xFF, 0x57, 0x73, + 0x04, 0xA3, 0x78, 0xE3, 0x8E, 0xB6, 0xBB, 0x41, + 0x62, 0x03, 0x0C, 0xE2, 0xA8, 0xBA, 0x29, 0x3C + }, + { + 0x34, 0x42, 0x2A, 0x32, 0x29, 0x66, 0x99, 0x28, + 0xC4, 0x90, 0xF5, 0x7B, 0x8E, 0x76, 0x88, 0x52, + 0xE5, 0xB7, 0xC0, 0x0D, 0xCA, 0xD6, 0x0B, 0x01, + 0x2A, 0x5D, 0xB3, 0x9A, 0x2D, 0x59, 0x7C, 0x3D, + 0x0A, 0x63, 0xBE, 0x6A, 0x26, 0x3E, 0xA5, 0x36, + 0x08, 0xB7, 0x06, 0x92, 0xD7, 0x8E, 0x1B, 0x42, + 0x7E, 0xAC, 0xEC, 0x01, 0xF4, 0xBE, 0xE0, 0xBD, + 0xBB, 0x8F, 0x08, 0x81, 0x48, 0x8E, 0xFC, 0x28 + }, + { + 0xE2, 0x6B, 0x7E, 0xD6, 0xB9, 0x07, 0xB5, 0x4C, + 0xA2, 0x65, 0x67, 0xF1, 0x1E, 0xE5, 0xBB, 0x6D, + 0x73, 0x9A, 0x00, 0x08, 0xA5, 0x34, 0x37, 0xAD, + 0x75, 0x90, 0xA3, 0x13, 0x4C, 0xEB, 0x95, 0x19, + 0x6E, 0x49, 0xB3, 0x44, 0x3F, 0x32, 0x49, 0x22, + 0x51, 0x75, 0x23, 0xC0, 0xCD, 0x5A, 0x00, 0xD7, + 0x7E, 0x4C, 0x4D, 0xE7, 0xA0, 0xDE, 0x96, 0x8A, + 0x84, 0xFB, 0x1B, 0x3B, 0xE7, 0xB3, 0xB9, 0x63 + }, + { + 0x26, 0x01, 0x97, 0xCA, 0xFB, 0xF4, 0x56, 0xB4, + 0x11, 0xFA, 0x26, 0xD3, 0x83, 0xD6, 0x4D, 0x61, + 0xE8, 0x1E, 0x5E, 0x52, 0xF8, 0x4C, 0xD9, 0xD5, + 0x73, 0x86, 0xC7, 0x76, 0x23, 0x0C, 0x65, 0xA2, + 0x68, 0x1C, 0xD2, 0xFD, 0xFD, 0x28, 0x67, 0x9F, + 0x67, 0xFE, 0x1B, 0xD7, 0x46, 0x9C, 0xF7, 0x26, + 0x95, 0x85, 0xFC, 0xCB, 0xAE, 0xCC, 0x22, 0xF5, + 0x03, 0xD6, 0xE3, 0xFC, 0x39, 0x30, 0x14, 0x36 + }, + { + 0xCB, 0xD5, 0xAB, 0xE3, 0x7B, 0xCC, 0x4F, 0x9A, + 0x12, 0x70, 0xAD, 0xD0, 0xA5, 0x27, 0x0F, 0x42, + 0x83, 0x9C, 0x7D, 0x24, 0x93, 0x20, 0xD1, 0xF1, + 0xD8, 0x85, 0x53, 0xD0, 0x5F, 0xAF, 0x9A, 0x26, + 0x79, 0xF4, 0x9B, 0x49, 0xC9, 0xE2, 0x0C, 0x1C, + 0x85, 0xC6, 0x29, 0xAA, 0x0F, 0x09, 0x0C, 0xAE, + 0x8F, 0x6E, 0x32, 0xC6, 0xCA, 0xD7, 0x17, 0x21, + 0xFD, 0x06, 0x23, 0xE4, 0xED, 0x25, 0xB2, 0x56 + }, + { + 0x78, 0x0E, 0x31, 0x4F, 0xD6, 0x97, 0xD2, 0xA9, + 0x7D, 0x22, 0x1A, 0x22, 0xC3, 0x90, 0x11, 0xE2, + 0x50, 0x69, 0x16, 0x3C, 0xD0, 0x8F, 0x00, 0x70, + 0xD0, 0x67, 0xE8, 0xCD, 0xB0, 0xBC, 0x86, 0x73, + 0xFD, 0xB0, 0xEC, 0x4F, 0x46, 0xE3, 0x1D, 0x74, + 0x8C, 0xD3, 0xBB, 0x3D, 0x61, 0xB9, 0x01, 0x0A, + 0x66, 0x12, 0xF3, 0x41, 0xD4, 0x71, 0xD9, 0xC5, + 0xA2, 0xDE, 0x6B, 0x6D, 0xD5, 0x38, 0xA6, 0xB5 + }, + { + 0x40, 0x8F, 0x16, 0xCE, 0x86, 0xF8, 0x01, 0xD0, + 0x8B, 0xD0, 0x51, 0x36, 0x4B, 0x3E, 0xCD, 0x9A, + 0x39, 0x45, 0x71, 0x58, 0x88, 0xDF, 0x46, 0x63, + 0x21, 0x9A, 0x19, 0x0B, 0x35, 0x04, 0xE4, 0x61, + 0x8E, 0x7B, 0xF5, 0x51, 0x71, 0x17, 0x8B, 0x04, + 0x00, 0xFB, 0xEB, 0xFA, 0xA0, 0x1F, 0x6E, 0xEA, + 0xB5, 0x4F, 0xF5, 0xE3, 0x1E, 0x6D, 0x7A, 0x55, + 0xB8, 0x4A, 0xDB, 0x9E, 0x03, 0xDF, 0x48, 0x36 + }, + { + 0x0B, 0xF9, 0x88, 0x69, 0xEC, 0x05, 0x80, 0x19, + 0x9C, 0xA3, 0x70, 0x8E, 0xC9, 0xC4, 0x2C, 0x37, + 0x6C, 0x5C, 0x36, 0xE0, 0xFB, 0x74, 0x92, 0x42, + 0x57, 0x23, 0x98, 0xA0, 0xDA, 0x57, 0xF9, 0x8D, + 0x1C, 0x4C, 0xD2, 0x96, 0x3B, 0x37, 0xC3, 0xC6, + 0x5A, 0x10, 0xF1, 0x06, 0xB5, 0x6D, 0xCB, 0x96, + 0xDC, 0xDD, 0x32, 0x57, 0x96, 0x29, 0x7A, 0xDB, + 0xF6, 0xEE, 0x62, 0x70, 0xED, 0xD4, 0x59, 0x2A + }, + { + 0x05, 0x2C, 0x32, 0x98, 0x43, 0x87, 0xB1, 0x93, + 0x0D, 0x3A, 0x96, 0xBE, 0x72, 0x36, 0x85, 0x35, + 0x44, 0x4F, 0x13, 0x07, 0x57, 0xBF, 0x87, 0xE0, + 0x76, 0x2D, 0x8B, 0x1C, 0x4F, 0x65, 0x70, 0xF4, + 0xDC, 0x67, 0x4C, 0x4E, 0x6F, 0x5E, 0x21, 0xAB, + 0xD0, 0xB3, 0x5E, 0x1C, 0xA1, 0x9D, 0xB8, 0x40, + 0x68, 0x8D, 0x1B, 0x6E, 0x9E, 0xC9, 0x1F, 0x37, + 0x30, 0xE8, 0xB2, 0x88, 0x0E, 0xC2, 0xC3, 0xDF + }, + { + 0x4B, 0xB7, 0x14, 0x09, 0xC1, 0x5A, 0x0D, 0x39, + 0x32, 0xC5, 0x99, 0xEF, 0x0F, 0xF3, 0xEF, 0xF5, + 0xC7, 0x60, 0x2D, 0x70, 0x00, 0xCD, 0xA9, 0x74, + 0x08, 0x2C, 0x4A, 0x46, 0x82, 0x24, 0x9A, 0x19, + 0xD4, 0x3A, 0x5C, 0x14, 0xE0, 0xAE, 0xEF, 0x89, + 0x78, 0x21, 0x05, 0x63, 0x80, 0xAF, 0xF2, 0x75, + 0x20, 0x1D, 0x74, 0x59, 0x14, 0x84, 0x96, 0xEA, + 0xE9, 0x42, 0x0E, 0x71, 0x82, 0x88, 0xB4, 0x14 + }, + { + 0x47, 0x95, 0xB2, 0x51, 0xCC, 0x7B, 0x35, 0xE6, + 0x96, 0x92, 0xDB, 0x7F, 0xB4, 0x0E, 0xFD, 0x34, + 0xF2, 0x94, 0xF5, 0x1A, 0xEC, 0x15, 0xD6, 0xC8, + 0x67, 0x3E, 0x59, 0xF2, 0x04, 0xBE, 0xCF, 0x4C, + 0xF9, 0xDF, 0x84, 0x95, 0x23, 0xF1, 0xDB, 0x73, + 0xBE, 0x2A, 0x66, 0xC8, 0x39, 0xD8, 0x01, 0x97, + 0x4D, 0x43, 0x3B, 0x47, 0x80, 0x67, 0x01, 0xA1, + 0x63, 0xA7, 0x94, 0xB2, 0x6A, 0x84, 0x6B, 0x06 + }, + { + 0xDD, 0x50, 0xF9, 0x65, 0xB6, 0x0B, 0xAF, 0x16, + 0x8F, 0x5E, 0xA0, 0x5A, 0xC2, 0x0B, 0x8A, 0x78, + 0xF4, 0x47, 0x5C, 0x18, 0x61, 0x0B, 0x9D, 0x9F, + 0xC2, 0xB7, 0xC3, 0xAD, 0x5C, 0x6F, 0x97, 0xA4, + 0xCF, 0x5E, 0xA4, 0x8E, 0xE4, 0x0A, 0x3C, 0xA2, + 0x29, 0x3C, 0xC4, 0x21, 0x40, 0x82, 0xCF, 0x0F, + 0x8E, 0xC8, 0x95, 0x55, 0x32, 0x69, 0xE1, 0x4D, + 0xA9, 0xBD, 0x1A, 0x19, 0x65, 0x62, 0xCA, 0x59 + }, + { + 0xE0, 0xB5, 0x4B, 0x61, 0x7F, 0x44, 0x92, 0x2C, + 0x7F, 0x61, 0xC6, 0xA5, 0x4C, 0x98, 0xC6, 0x1E, + 0x93, 0x2D, 0xED, 0x1F, 0xA9, 0x34, 0x02, 0x66, + 0xEE, 0xA2, 0x5F, 0x01, 0xE8, 0x18, 0x0D, 0x1D, + 0xDC, 0x6A, 0xD8, 0xDD, 0x6A, 0x0B, 0x8F, 0xAB, + 0x8C, 0x73, 0xAE, 0xBB, 0x97, 0x73, 0x17, 0x1B, + 0xBA, 0x04, 0xA7, 0x81, 0xB1, 0x13, 0x14, 0xD5, + 0xA3, 0x0A, 0x9D, 0x1C, 0x28, 0x12, 0xCA, 0x7C + }, + { + 0x2D, 0xC4, 0xAD, 0x06, 0x89, 0xA4, 0x46, 0x0B, + 0x5B, 0x39, 0x9E, 0x91, 0x1B, 0xDB, 0x41, 0x58, + 0x6A, 0xC8, 0xAD, 0x36, 0x7B, 0x7A, 0xA3, 0x9E, + 0x3E, 0xAE, 0xC8, 0x89, 0x9A, 0x2D, 0x3C, 0xE3, + 0x8E, 0x34, 0xAB, 0x46, 0x08, 0x23, 0x4D, 0x75, + 0xEB, 0x67, 0x37, 0xFE, 0x21, 0x58, 0x24, 0xC2, + 0xA9, 0x78, 0x83, 0x59, 0x6F, 0x6F, 0x18, 0xDD, + 0xEB, 0xBF, 0x16, 0x27, 0xDE, 0xD9, 0x1D, 0x84 + }, + { + 0xF5, 0x6A, 0x11, 0xCB, 0xBF, 0x8A, 0x99, 0x7E, + 0x14, 0x77, 0xEC, 0x76, 0xE5, 0x3C, 0x89, 0x4B, + 0x14, 0x8D, 0x69, 0x25, 0xA4, 0x33, 0x6F, 0x0C, + 0xB7, 0xAA, 0xB9, 0xD8, 0x02, 0xAC, 0x9B, 0x45, + 0x36, 0xF4, 0x80, 0x10, 0x1F, 0x3F, 0x9A, 0x77, + 0xEE, 0xCD, 0xCB, 0xAE, 0x7A, 0xA6, 0xEA, 0x44, + 0x7A, 0x85, 0xDA, 0x90, 0xB5, 0x01, 0xF7, 0xDB, + 0x2E, 0xF8, 0xDD, 0xF5, 0xDE, 0x17, 0x33, 0x63 + }, + { + 0x6E, 0x17, 0x1D, 0x19, 0x6D, 0x0F, 0xC8, 0x2F, + 0xB4, 0x73, 0xE2, 0x9D, 0xA8, 0xF4, 0x0F, 0x37, + 0xEE, 0x97, 0x41, 0xAC, 0x3E, 0xAF, 0x17, 0x5D, + 0xD4, 0x9F, 0xDB, 0x56, 0x53, 0x0D, 0xB5, 0x98, + 0x98, 0xBA, 0xF3, 0xCE, 0xE7, 0x2E, 0xEF, 0x5E, + 0x77, 0x27, 0x6C, 0xAD, 0xAB, 0xCD, 0x75, 0x2C, + 0xA3, 0xA1, 0xB8, 0x64, 0xC1, 0x0A, 0xD2, 0x8D, + 0x27, 0xEA, 0xAD, 0x86, 0xE3, 0xF2, 0x1D, 0x33 + }, + { + 0x95, 0x20, 0x12, 0x33, 0x0D, 0x92, 0xBB, 0x9C, + 0x18, 0x92, 0xF2, 0x5B, 0x7B, 0x5A, 0xA0, 0xFE, + 0xD3, 0xC0, 0x39, 0x8A, 0x17, 0x08, 0x50, 0x9A, + 0x66, 0x14, 0x74, 0xA3, 0xF5, 0xE5, 0x11, 0xD0, + 0x9F, 0x21, 0xC3, 0x00, 0x08, 0x00, 0x2F, 0x10, + 0x42, 0xD8, 0x3D, 0x2F, 0x7B, 0x11, 0x33, 0x6B, + 0x8C, 0x2F, 0xE1, 0xD9, 0x79, 0xC1, 0xE3, 0x86, + 0xE0, 0x20, 0x97, 0x48, 0x9B, 0x2D, 0xFC, 0xF5 + }, + { + 0x2D, 0xCE, 0x47, 0xC3, 0x3A, 0x7E, 0x7F, 0x21, + 0x5D, 0x34, 0xA5, 0x47, 0x1B, 0xCD, 0x11, 0x10, + 0x60, 0x6C, 0x77, 0x13, 0x8F, 0x19, 0xD4, 0x17, + 0x41, 0xED, 0x5D, 0x1B, 0x89, 0xE8, 0xF7, 0xC7, + 0x74, 0xEE, 0xC4, 0xBB, 0xC1, 0x02, 0x76, 0x6E, + 0xA1, 0x53, 0x2F, 0x2E, 0x43, 0x13, 0x4A, 0xD3, + 0x66, 0xBD, 0xCC, 0x27, 0xD1, 0xA0, 0xCC, 0x95, + 0x9E, 0x16, 0x48, 0x65, 0x9E, 0x44, 0xCB, 0xBE + }, + { + 0x7F, 0x06, 0x59, 0x59, 0x7E, 0x7A, 0xD1, 0x22, + 0xD1, 0xC9, 0xED, 0x91, 0x93, 0x0B, 0x07, 0xDE, + 0x40, 0xE2, 0x55, 0x20, 0x1A, 0x33, 0xEB, 0x2B, + 0x31, 0x81, 0x37, 0x6E, 0x36, 0x8D, 0xF7, 0x76, + 0x4C, 0x0C, 0x14, 0xBF, 0x79, 0x9F, 0x16, 0x1B, + 0x9B, 0x00, 0x79, 0x57, 0x8B, 0x47, 0x09, 0x71, + 0x3E, 0x24, 0xE4, 0x2F, 0xE7, 0xDD, 0x71, 0xB5, + 0x09, 0x43, 0xF4, 0x40, 0xE2, 0x3C, 0xD1, 0xBE + }, + { + 0x1E, 0x66, 0xF7, 0xB3, 0x58, 0x80, 0x5D, 0xDD, + 0xFF, 0xC5, 0x82, 0x68, 0x3E, 0x0B, 0xAD, 0x81, + 0x8C, 0x87, 0x34, 0x03, 0xD4, 0xBA, 0x15, 0x06, + 0xB9, 0x2F, 0xB3, 0x20, 0xCA, 0x8C, 0xF9, 0xCE, + 0xE8, 0x15, 0x47, 0x15, 0xD6, 0xDB, 0x6F, 0x04, + 0x09, 0x3D, 0x4B, 0x3F, 0xD8, 0xA6, 0xFC, 0x8E, + 0x7E, 0xDD, 0xEA, 0xF2, 0x79, 0x5B, 0x3D, 0x22, + 0xDE, 0x7C, 0x75, 0xEC, 0xFF, 0x6F, 0x92, 0xAF + }, + { + 0x1F, 0x60, 0xC1, 0x8D, 0xB1, 0x68, 0xD9, 0x0D, + 0x2B, 0x46, 0x60, 0xE7, 0x58, 0xA3, 0xCD, 0x28, + 0x02, 0x3D, 0x4C, 0x0B, 0x84, 0x8B, 0x5E, 0x33, + 0xEA, 0x5C, 0xC1, 0x56, 0x29, 0xFD, 0x35, 0x2E, + 0xAC, 0xB1, 0x4F, 0x05, 0xFD, 0xEC, 0x07, 0xAC, + 0x23, 0xDA, 0x92, 0x04, 0x74, 0x5F, 0xA9, 0x73, + 0xC3, 0x29, 0x55, 0x13, 0x5F, 0x8E, 0xC7, 0x41, + 0x0A, 0x1C, 0xB5, 0x3B, 0xC7, 0x58, 0x06, 0x84 + }, + { + 0xB9, 0xDF, 0x57, 0xB3, 0x45, 0xEE, 0x6F, 0x87, + 0x0E, 0xE0, 0xE6, 0x3C, 0x55, 0x8B, 0x81, 0xC1, + 0xBC, 0x38, 0x42, 0x97, 0x6F, 0xD3, 0xCF, 0xB1, + 0xB5, 0x3B, 0x76, 0x6B, 0xF4, 0x36, 0xD1, 0xD1, + 0x75, 0xF4, 0xD4, 0xC5, 0xF1, 0xBD, 0x8D, 0x7A, + 0xF6, 0x5B, 0x5D, 0x18, 0xA7, 0x2F, 0x95, 0x71, + 0xF2, 0x34, 0x70, 0x19, 0x32, 0xAF, 0xB7, 0xC3, + 0xC9, 0x4A, 0x8C, 0x8F, 0xA0, 0x23, 0xDB, 0x4F + }, + { + 0xD8, 0xC8, 0x24, 0x95, 0xA2, 0xB5, 0xF6, 0x64, + 0x51, 0xF8, 0xC5, 0xB2, 0xE8, 0xA1, 0x73, 0x33, + 0xC2, 0xBE, 0x32, 0x20, 0xCE, 0x06, 0xA8, 0x14, + 0xC2, 0xCE, 0xA9, 0x5C, 0xC8, 0x65, 0x92, 0xAA, + 0x02, 0x15, 0xBF, 0x29, 0x46, 0x14, 0xA3, 0x28, + 0xCF, 0x07, 0x22, 0x2B, 0x73, 0xF9, 0x3F, 0x24, + 0x2A, 0x94, 0x8B, 0xCA, 0xE9, 0x56, 0x5F, 0xC9, + 0x70, 0x57, 0xB5, 0x2E, 0x02, 0x80, 0xEB, 0x82 + }, + { + 0x81, 0x34, 0xCE, 0x66, 0xD9, 0x5C, 0x40, 0x88, + 0xA5, 0x66, 0xD4, 0xE4, 0x35, 0x99, 0x06, 0x9A, + 0xD0, 0x45, 0x53, 0xB0, 0xFE, 0xA3, 0xD7, 0x48, + 0x19, 0xA6, 0xFD, 0x76, 0x6F, 0x43, 0x67, 0x42, + 0xF6, 0xB6, 0xEC, 0xC8, 0x27, 0x93, 0x98, 0x60, + 0x9F, 0x60, 0xB4, 0xE4, 0xBB, 0x44, 0xFD, 0x72, + 0xCD, 0xFB, 0xFF, 0x18, 0xD8, 0x03, 0x8A, 0xA7, + 0x12, 0x30, 0x83, 0x8B, 0x12, 0x6B, 0xC3, 0x00 + }, + { + 0x3D, 0xA8, 0x9F, 0x5C, 0x52, 0xB0, 0x52, 0xE0, + 0x42, 0xE5, 0x11, 0x7B, 0x96, 0x80, 0x6E, 0xDB, + 0x1C, 0x55, 0x22, 0x7E, 0x85, 0x14, 0xB3, 0x9E, + 0x8B, 0x22, 0xBE, 0xA4, 0xC9, 0x53, 0x30, 0x80, + 0xA4, 0xD7, 0xA9, 0x24, 0x92, 0xB7, 0x51, 0x76, + 0x9B, 0x0E, 0x11, 0x9E, 0xF4, 0xDB, 0x2B, 0xB8, + 0x8D, 0x5C, 0x1E, 0x75, 0xB4, 0x03, 0x10, 0x74, + 0xD7, 0xF2, 0x1A, 0x78, 0x01, 0x4A, 0x1F, 0x96 + }, + { + 0x9B, 0xDC, 0xB4, 0x69, 0xC2, 0x66, 0x5D, 0xD8, + 0x46, 0x83, 0xE5, 0x81, 0x01, 0xFD, 0xAE, 0x5C, + 0x88, 0x29, 0x2A, 0x4E, 0x05, 0xC4, 0x00, 0xCA, + 0x08, 0x26, 0xDA, 0x79, 0x38, 0x2B, 0x8A, 0x28, + 0x26, 0xFF, 0x24, 0xFC, 0xD5, 0x56, 0xC9, 0xD5, + 0xB5, 0xAA, 0x89, 0x2F, 0x02, 0xB1, 0x67, 0x04, + 0x77, 0x27, 0x9B, 0xD7, 0x5F, 0x1B, 0x2B, 0x7B, + 0x67, 0x5E, 0xFA, 0xC3, 0x80, 0x60, 0x70, 0x36 + }, + { + 0x6C, 0x77, 0x85, 0x7B, 0x38, 0x53, 0x3E, 0x41, + 0x4A, 0xF7, 0x38, 0x7C, 0x98, 0x56, 0x8D, 0x71, + 0xC8, 0xF0, 0xE3, 0x5E, 0x22, 0xB0, 0x2E, 0x2A, + 0x1C, 0x0D, 0xC6, 0xD5, 0x7E, 0x37, 0xD8, 0x68, + 0x72, 0x5A, 0xD8, 0x23, 0x58, 0x6A, 0x0B, 0xEE, + 0xF3, 0x98, 0x89, 0xCC, 0x31, 0xF1, 0xF7, 0xFA, + 0xD0, 0x96, 0x0A, 0x12, 0x5E, 0x29, 0xDF, 0xEA, + 0x74, 0x55, 0x12, 0xD1, 0x79, 0xE5, 0xF5, 0x89 + }, + { + 0x88, 0xC9, 0x83, 0x3A, 0x6D, 0x44, 0xFC, 0x25, + 0xBB, 0x64, 0xF3, 0xE9, 0x8E, 0x83, 0x8F, 0xB4, + 0xFF, 0x56, 0x48, 0x96, 0xDC, 0xD3, 0x58, 0x3A, + 0x8B, 0x57, 0xC9, 0x46, 0x6E, 0x74, 0x0C, 0x62, + 0x8B, 0x2D, 0x26, 0xEA, 0x14, 0x7C, 0xB3, 0x11, + 0x10, 0xFB, 0xAD, 0xCF, 0x9D, 0x01, 0x08, 0xAC, + 0xCE, 0xBE, 0x04, 0x31, 0x7D, 0x19, 0xFC, 0x03, + 0x66, 0xDE, 0x0C, 0x28, 0xA1, 0xA4, 0x5E, 0x2A + }, + { + 0x0A, 0xAB, 0xB3, 0xA1, 0x78, 0x46, 0x4A, 0x01, + 0x47, 0x64, 0x5F, 0x05, 0x71, 0x2A, 0x0A, 0x15, + 0x55, 0xC5, 0xB9, 0xA3, 0xE9, 0x99, 0xAB, 0x25, + 0x5A, 0xCA, 0x35, 0xC5, 0x03, 0x81, 0xF4, 0x90, + 0x55, 0x1A, 0x40, 0x89, 0x31, 0xAA, 0x6B, 0xE9, + 0xA4, 0xEF, 0x49, 0x7A, 0x16, 0x5B, 0x36, 0x66, + 0x3B, 0x1E, 0x1F, 0x05, 0x13, 0x48, 0x02, 0xB1, + 0x78, 0xB7, 0xC7, 0x04, 0x68, 0xCB, 0x98, 0xE8 + }, + { + 0x58, 0x50, 0xD8, 0x93, 0x70, 0x6B, 0x3B, 0xC2, + 0xDB, 0xBA, 0x9C, 0xFA, 0xB0, 0x28, 0xBE, 0xD8, + 0x19, 0xA2, 0x83, 0x11, 0xD2, 0xD6, 0xF0, 0xCD, + 0x8E, 0x27, 0x2E, 0xE6, 0x77, 0xBC, 0x87, 0x8A, + 0x0C, 0xED, 0x6C, 0x0D, 0xEA, 0x9E, 0x5C, 0xC9, + 0x4B, 0x2B, 0x4F, 0x59, 0x1A, 0x40, 0xEC, 0x9F, + 0xB1, 0x82, 0x22, 0xD6, 0xDE, 0xAC, 0xE1, 0xF9, + 0xC0, 0x83, 0xDC, 0x05, 0xDE, 0x11, 0x7A, 0x53 + }, + { + 0xBE, 0xE6, 0x96, 0xA4, 0x76, 0x4F, 0x94, 0x25, + 0xD9, 0x1B, 0x14, 0x17, 0x38, 0x62, 0x5A, 0x04, + 0x47, 0xA8, 0x22, 0xBB, 0xA7, 0xA8, 0x47, 0x78, + 0xCC, 0x3A, 0x77, 0xA3, 0x86, 0xCB, 0x18, 0x24, + 0x87, 0xDB, 0x51, 0x3B, 0xB8, 0xF3, 0x6F, 0xC2, + 0xF7, 0xE6, 0xD2, 0x89, 0x6E, 0x44, 0x56, 0xA5, + 0x23, 0x46, 0xC4, 0x94, 0x8E, 0x3E, 0xC6, 0x34, + 0xCB, 0xF1, 0x8F, 0x39, 0xC4, 0x46, 0xCB, 0xAB + }, + { + 0x3D, 0x9F, 0x75, 0xD3, 0xE5, 0x0D, 0x9B, 0xA3, + 0xBC, 0xAC, 0x4A, 0x4E, 0x11, 0x6B, 0x9B, 0x30, + 0x8D, 0xC6, 0x45, 0x99, 0xA3, 0x86, 0x4A, 0x9D, + 0xAF, 0xD7, 0x5C, 0xB7, 0x1F, 0x2D, 0xE3, 0x10, + 0x9F, 0x79, 0x56, 0xA7, 0xD2, 0xDD, 0x37, 0x4F, + 0x84, 0x06, 0xD7, 0x7F, 0x79, 0x63, 0x11, 0xE3, + 0xD3, 0x00, 0x89, 0xE5, 0x4D, 0xD6, 0xCE, 0x8A, + 0xBB, 0x02, 0xA8, 0x5A, 0x85, 0xAE, 0x92, 0xE4 + }, + { + 0xEF, 0x39, 0x51, 0x47, 0x5A, 0x16, 0xDF, 0x64, + 0x98, 0x32, 0x24, 0x04, 0x65, 0x30, 0xDC, 0x7C, + 0xB0, 0x53, 0xD2, 0x93, 0x94, 0x75, 0x39, 0x11, + 0xC4, 0x94, 0x99, 0x50, 0xF2, 0x3E, 0x8A, 0x92, + 0xC7, 0x09, 0xF4, 0x63, 0x69, 0xB2, 0x3A, 0x0D, + 0x70, 0x3A, 0x6F, 0x36, 0x49, 0x0F, 0x75, 0xBE, + 0x1E, 0x3E, 0x81, 0x29, 0xA8, 0x29, 0xF3, 0xDC, + 0xD7, 0x2D, 0x0E, 0x55, 0x49, 0x7B, 0x81, 0x33 + }, + { + 0xD4, 0x19, 0x7D, 0x2A, 0x68, 0x5B, 0xCA, 0x6B, + 0xFB, 0xDD, 0x0E, 0x3D, 0x84, 0xC7, 0x48, 0x01, + 0x35, 0x48, 0xBC, 0x84, 0x9F, 0xE6, 0x49, 0xDA, + 0xE7, 0xC4, 0xA2, 0x77, 0xFC, 0xBD, 0x8F, 0x81, + 0x8A, 0x9E, 0xDF, 0xA6, 0xCA, 0x14, 0xD7, 0xFE, + 0xEA, 0x72, 0x6B, 0x23, 0xB4, 0xA3, 0x3A, 0xA8, + 0xA3, 0xF5, 0xA6, 0x61, 0x67, 0x21, 0x5C, 0x61, + 0x48, 0xC0, 0x6B, 0x94, 0xCD, 0x8B, 0xFE, 0x37 + }, + { + 0x7A, 0x24, 0x40, 0x33, 0x35, 0xB8, 0x64, 0x10, + 0xD8, 0xD6, 0x93, 0xF1, 0x63, 0xD6, 0x19, 0x8A, + 0x68, 0x0F, 0x7E, 0x3A, 0xC0, 0x25, 0xEC, 0x44, + 0x74, 0x24, 0x9B, 0x01, 0x16, 0x77, 0xFE, 0x1C, + 0x86, 0x6A, 0xAF, 0x45, 0x3D, 0xB0, 0xE8, 0xF6, + 0x54, 0x33, 0x51, 0x50, 0x86, 0x3A, 0xCE, 0x57, + 0x66, 0x50, 0x80, 0x31, 0x91, 0x27, 0x8E, 0x9D, + 0x4B, 0x54, 0x7A, 0x43, 0x4C, 0x56, 0x54, 0xE2 + }, + { + 0xAF, 0x07, 0xC6, 0x7D, 0x58, 0x74, 0x3A, 0xEB, + 0x18, 0x50, 0xEB, 0x53, 0xB2, 0xDA, 0x78, 0xEC, + 0xF7, 0x09, 0x58, 0x18, 0x32, 0x5B, 0xEB, 0x86, + 0x6F, 0xF3, 0x13, 0xE3, 0x94, 0xC0, 0x07, 0xE0, + 0xC0, 0xB5, 0xA1, 0xCD, 0x7A, 0xE6, 0xBB, 0x37, + 0xCD, 0x27, 0x81, 0xB5, 0x2D, 0x15, 0x4D, 0x18, + 0x86, 0x5D, 0x5E, 0x37, 0xDB, 0xAA, 0x5F, 0x96, + 0x73, 0x9B, 0xF7, 0x69, 0x59, 0x96, 0xAE, 0x30 + }, + { + 0x28, 0xB3, 0xC2, 0x60, 0xFA, 0x7F, 0x23, 0xB9, + 0xCC, 0xAD, 0xD6, 0x15, 0xA1, 0x14, 0x69, 0x49, + 0x8A, 0xDB, 0x18, 0xD7, 0xA9, 0xF6, 0x84, 0xFD, + 0xE4, 0x35, 0xC0, 0x65, 0x33, 0xF5, 0xF5, 0x08, + 0xB2, 0x9B, 0x5E, 0xCD, 0x0E, 0xCD, 0x57, 0x36, + 0x9F, 0x22, 0xF1, 0xC5, 0x4E, 0x61, 0xBE, 0x6C, + 0xD1, 0x04, 0xC8, 0xF7, 0xD3, 0xE1, 0x84, 0x7A, + 0xAD, 0x67, 0x07, 0x3A, 0x47, 0x86, 0xE1, 0xDB + }, + { + 0xD6, 0x43, 0x23, 0x33, 0x25, 0x23, 0x9E, 0x2E, + 0xBD, 0x41, 0x1F, 0x0E, 0x00, 0x23, 0x30, 0x56, + 0x2E, 0xB1, 0xBB, 0x08, 0xE6, 0x88, 0x24, 0xB7, + 0x1B, 0x98, 0x19, 0x9C, 0x76, 0xD5, 0x31, 0x58, + 0xD9, 0x1D, 0xDD, 0x6F, 0x4F, 0x82, 0x61, 0xEC, + 0x1D, 0x72, 0xFC, 0x77, 0xC2, 0xCC, 0x23, 0x7E, + 0xDA, 0x15, 0xF0, 0x25, 0x7C, 0xF0, 0x7B, 0x84, + 0xCF, 0x1F, 0xBD, 0x1D, 0xBA, 0xFA, 0x1D, 0xFC + }, + { + 0x3D, 0x7B, 0x44, 0xCC, 0x82, 0xEF, 0xCA, 0xFC, + 0xAB, 0xA6, 0xB1, 0x91, 0x05, 0x48, 0x95, 0x8C, + 0x18, 0x0A, 0x0E, 0x8D, 0x84, 0xBC, 0x66, 0x3E, + 0x8E, 0xF9, 0x53, 0x3B, 0xD8, 0x0C, 0x4B, 0xBA, + 0xAA, 0x25, 0x5B, 0x19, 0x81, 0xF7, 0x56, 0xEB, + 0x10, 0x79, 0xAD, 0x0F, 0x34, 0x71, 0xA1, 0xFC, + 0x9D, 0x7A, 0x43, 0x23, 0x39, 0x30, 0x3A, 0x57, + 0x81, 0xA3, 0x45, 0x35, 0x30, 0x9E, 0x5A, 0x24 + }, + { + 0xEB, 0x08, 0x12, 0xC9, 0x67, 0x06, 0x46, 0xD5, + 0x63, 0x19, 0x8B, 0x11, 0x7A, 0xAF, 0xC5, 0x6F, + 0xA1, 0xB6, 0x56, 0x0F, 0x88, 0xB5, 0x75, 0x4E, + 0xBF, 0xC3, 0x1B, 0x35, 0x52, 0x16, 0xD8, 0xD7, + 0x4D, 0x34, 0x1E, 0x35, 0xB2, 0x43, 0xBC, 0x93, + 0x8C, 0xF5, 0x46, 0xAF, 0x1F, 0x73, 0xC1, 0xB0, + 0x04, 0x55, 0xDC, 0x06, 0xB2, 0xC6, 0xC5, 0x35, + 0x27, 0x9E, 0x87, 0x67, 0x49, 0x8F, 0x14, 0xE6 + }, + { + 0x7B, 0xBA, 0x7D, 0x73, 0x04, 0x02, 0x1C, 0x75, + 0xB5, 0xD6, 0xCE, 0x66, 0xB4, 0xEF, 0xA5, 0x50, + 0x19, 0xD9, 0x42, 0xD2, 0x08, 0xAF, 0xAC, 0x82, + 0x11, 0xAA, 0x7E, 0x5E, 0x11, 0x1E, 0x27, 0x69, + 0x76, 0x70, 0xE4, 0xEC, 0x91, 0xBA, 0x30, 0x8E, + 0xBD, 0xFB, 0x19, 0x15, 0x4C, 0x3B, 0xAD, 0x05, + 0x26, 0xA6, 0x25, 0x41, 0xAE, 0x5D, 0x43, 0xD0, + 0xF5, 0x47, 0xB9, 0xD9, 0x8E, 0x07, 0x36, 0x60 + }, + { + 0xA8, 0xE2, 0xA9, 0x46, 0x8D, 0xA3, 0xE3, 0x54, + 0x3A, 0x23, 0xA5, 0x78, 0x78, 0x0E, 0x25, 0x62, + 0xC7, 0xCE, 0x57, 0xFD, 0x11, 0x20, 0xE1, 0xC0, + 0x24, 0xD7, 0xEA, 0x32, 0x90, 0x31, 0x70, 0x46, + 0x61, 0x6E, 0x14, 0xCD, 0x0F, 0x15, 0xA8, 0x6B, + 0x99, 0x39, 0x54, 0x9B, 0x14, 0x76, 0x11, 0xB6, + 0xA5, 0x5D, 0x85, 0xAB, 0xC2, 0x5F, 0x63, 0x95, + 0x46, 0xB8, 0x9D, 0xD2, 0x3D, 0x39, 0xA9, 0x85 + }, + { + 0xCE, 0x87, 0x4C, 0xD6, 0xE1, 0x95, 0x8B, 0x9D, + 0x7F, 0x11, 0xFF, 0x44, 0xAB, 0x08, 0x32, 0xE8, + 0x48, 0x70, 0x2C, 0x8F, 0x26, 0x65, 0x6B, 0xA1, + 0x0B, 0xF5, 0x72, 0x0A, 0x7C, 0xAA, 0x1F, 0x59, + 0x08, 0xC9, 0x9A, 0x96, 0x03, 0xA9, 0x8B, 0x41, + 0x6C, 0x57, 0x22, 0x8C, 0x81, 0x9C, 0xEA, 0xF8, + 0x27, 0x01, 0x3B, 0x2E, 0x6D, 0x6B, 0x2D, 0xAE, + 0x59, 0xDF, 0xF1, 0x04, 0xB9, 0x02, 0xC3, 0x1B + }, + { + 0x30, 0xFF, 0xFE, 0x37, 0x21, 0x8D, 0xB1, 0x94, + 0xB2, 0x32, 0x73, 0x49, 0x8F, 0x45, 0x44, 0xD3, + 0x84, 0x14, 0xBE, 0xE4, 0x1B, 0x17, 0x55, 0xA0, + 0xC6, 0xC2, 0xDB, 0xCB, 0x41, 0x19, 0x42, 0xD5, + 0xEC, 0xB9, 0xD4, 0x52, 0x3F, 0xB4, 0x79, 0x4B, + 0xA3, 0x6E, 0x57, 0x9A, 0xF2, 0xF8, 0xDD, 0x85, + 0x19, 0x99, 0x23, 0x31, 0x83, 0xFA, 0xB2, 0x7B, + 0x47, 0xAD, 0xD8, 0x7D, 0xF3, 0x59, 0x14, 0xBB + }, + { + 0xCE, 0xF4, 0x43, 0x1D, 0xCE, 0x9F, 0xF5, 0x5A, + 0x00, 0x30, 0x0E, 0xC8, 0x64, 0x9E, 0x27, 0x58, + 0x36, 0x18, 0x22, 0x43, 0x69, 0xF6, 0x0A, 0x5C, + 0x89, 0x6B, 0x2A, 0x31, 0x10, 0xB0, 0x32, 0xB8, + 0x7C, 0x9E, 0xE4, 0xF2, 0x6C, 0x5F, 0x0B, 0xDB, + 0x50, 0x3E, 0xA7, 0x44, 0x7A, 0x5D, 0xB3, 0xF7, + 0x07, 0xFE, 0x34, 0x10, 0xDA, 0xCD, 0xD7, 0x57, + 0x22, 0x19, 0xBD, 0xEA, 0x8E, 0x17, 0xDC, 0x04 + }, + { + 0x8F, 0xF0, 0xBC, 0xB7, 0x5F, 0x00, 0x61, 0xB5, + 0xF9, 0x09, 0x29, 0x8F, 0x56, 0x9E, 0x45, 0xC7, + 0x5E, 0xD2, 0xD6, 0x4A, 0x81, 0x89, 0xCE, 0xBD, + 0x4E, 0x02, 0x56, 0x6E, 0x1A, 0x1B, 0x8B, 0xE5, + 0x3A, 0x78, 0x32, 0x28, 0x55, 0x8E, 0x28, 0xB5, + 0xF8, 0x7C, 0xCC, 0x2F, 0x42, 0x8F, 0x7F, 0x87, + 0x97, 0x44, 0xB5, 0x25, 0xB2, 0x49, 0x62, 0xB3, + 0x60, 0x4B, 0x12, 0x0F, 0x06, 0x77, 0x9F, 0x2E + }, + { + 0x7F, 0x8D, 0xDF, 0xFB, 0x4D, 0xC1, 0x51, 0x91, + 0xDE, 0x3D, 0xDB, 0xE4, 0xA0, 0xF8, 0x8B, 0x7A, + 0xB0, 0x2D, 0x48, 0xE2, 0x5C, 0xFC, 0x1F, 0xE9, + 0x1D, 0xA5, 0x57, 0xE8, 0x85, 0xD0, 0x12, 0xB8, + 0xF6, 0x55, 0x26, 0xC5, 0xB7, 0xB1, 0x01, 0x3F, + 0xC8, 0x16, 0x58, 0x50, 0x43, 0xA3, 0x45, 0x60, + 0x5A, 0x39, 0xD8, 0xDA, 0xD7, 0x0D, 0x8A, 0x64, + 0x48, 0x51, 0x32, 0x50, 0xAA, 0xC4, 0xF3, 0xD5 + }, + { + 0xB1, 0xFE, 0x8C, 0x68, 0xAE, 0xF6, 0xB4, 0xD4, + 0xB2, 0x33, 0x54, 0xEB, 0x8C, 0x1D, 0x8F, 0x5A, + 0x56, 0xE3, 0x2E, 0x76, 0xB9, 0x6A, 0xC8, 0x44, + 0x3B, 0x2A, 0xB8, 0x35, 0xE4, 0xC8, 0xB6, 0x74, + 0xB3, 0x3E, 0x4C, 0x6C, 0x6D, 0xC1, 0x21, 0xD7, + 0xC2, 0xD3, 0x4B, 0x59, 0xB3, 0x7A, 0x56, 0x8A, + 0x1C, 0x98, 0xD5, 0x00, 0x32, 0x4E, 0x53, 0x08, + 0x87, 0x85, 0xB6, 0xB0, 0x80, 0x63, 0x47, 0xD1 + }, + { + 0x8E, 0x87, 0x34, 0xFC, 0xF9, 0x25, 0x9E, 0xE3, + 0x7F, 0xE9, 0xC6, 0xCD, 0xA2, 0x82, 0xC2, 0xD5, + 0xEB, 0x83, 0xD0, 0xCF, 0x43, 0x9C, 0x86, 0x19, + 0xD4, 0xB0, 0x42, 0xFF, 0x69, 0x96, 0x6B, 0x03, + 0x56, 0x5B, 0xE4, 0xDF, 0x96, 0x39, 0x3F, 0xE6, + 0xBF, 0x35, 0xAF, 0xA1, 0x6E, 0x02, 0x73, 0xB6, + 0xD3, 0x39, 0xC0, 0x09, 0x95, 0xBF, 0x6F, 0x60, + 0xA7, 0x14, 0xEF, 0x18, 0x0E, 0xBB, 0x93, 0x15 + }, + { + 0xAE, 0x15, 0x6D, 0x43, 0xA7, 0x2C, 0x04, 0x29, + 0x42, 0x59, 0x58, 0x78, 0xA7, 0x83, 0x07, 0x97, + 0x60, 0xF5, 0x21, 0xED, 0xB8, 0xB2, 0xC3, 0xD4, + 0x1A, 0x56, 0x6B, 0x7C, 0xF7, 0x4A, 0x4A, 0x08, + 0xEA, 0x0F, 0x11, 0x9D, 0x24, 0x0A, 0x62, 0xEC, + 0x73, 0xB9, 0x50, 0x97, 0x88, 0xFA, 0x3A, 0xED, + 0xF1, 0x20, 0xEE, 0x88, 0xCB, 0x95, 0x1B, 0x69, + 0x3F, 0x8F, 0x7C, 0xAF, 0x8C, 0xBA, 0x37, 0x7F + }, + { + 0x93, 0x30, 0xAA, 0xCA, 0x8C, 0x08, 0x84, 0x46, + 0x58, 0xC2, 0x95, 0x06, 0xB1, 0xC3, 0x42, 0x72, + 0xE2, 0xB3, 0xC7, 0xB4, 0xE7, 0x5E, 0x6F, 0xE9, + 0x9A, 0x01, 0x07, 0xEC, 0x5D, 0xA4, 0x53, 0x0F, + 0xB1, 0xC8, 0x8C, 0xAA, 0x66, 0xDD, 0x9C, 0x47, + 0x1E, 0x01, 0xCA, 0x21, 0xA1, 0x3A, 0x5D, 0x6F, + 0x82, 0x15, 0xDE, 0xD3, 0x14, 0x7E, 0x94, 0xDE, + 0x20, 0x88, 0x57, 0x1F, 0xD1, 0xBF, 0x23, 0xB6 + }, + { + 0xC1, 0x29, 0xF2, 0x2C, 0x50, 0xF5, 0x99, 0x72, + 0x32, 0xE2, 0xB9, 0xF9, 0x3D, 0xFA, 0xA0, 0x0A, + 0xD8, 0xA5, 0x34, 0x29, 0xF9, 0xD1, 0x5B, 0x98, + 0x42, 0xE3, 0xAE, 0x08, 0xD8, 0x49, 0xEB, 0xDD, + 0x45, 0x23, 0x8C, 0x85, 0xF9, 0x2C, 0x6F, 0x91, + 0x7E, 0x0F, 0x8F, 0x6F, 0x94, 0xE2, 0x34, 0xBE, + 0x07, 0x61, 0x68, 0xE0, 0xDF, 0x43, 0xD0, 0x28, + 0x45, 0x52, 0x79, 0xA6, 0xFF, 0x65, 0xDC, 0x84 + }, + { + 0x0E, 0x2B, 0x4B, 0xC2, 0xF6, 0xA7, 0x5B, 0xE4, + 0xB7, 0xC9, 0xD4, 0xB5, 0x3D, 0x10, 0x4D, 0xA0, + 0x65, 0x85, 0x8D, 0x38, 0x7B, 0x34, 0x0B, 0xC1, + 0x63, 0x4F, 0x3A, 0x83, 0x32, 0xD5, 0x4C, 0xAA, + 0x94, 0x30, 0x24, 0xB2, 0x13, 0xDC, 0x8D, 0x4F, + 0x21, 0x9E, 0xC8, 0xE1, 0xDE, 0xCA, 0xC7, 0xD5, + 0xC6, 0xAE, 0x69, 0xC9, 0xEF, 0xD8, 0x81, 0x49, + 0x36, 0x78, 0x38, 0x20, 0x5D, 0x0D, 0xC7, 0xC0 + }, + { + 0x83, 0xB5, 0x43, 0x85, 0x3B, 0x81, 0x42, 0xA8, + 0x3B, 0xEF, 0xF0, 0x73, 0x5F, 0x20, 0x18, 0x91, + 0xE7, 0xFF, 0xC6, 0x7D, 0xBD, 0xCD, 0x21, 0xA4, + 0x22, 0xBB, 0x33, 0x6D, 0xE3, 0x29, 0x72, 0xAE, + 0x03, 0x92, 0x64, 0x6F, 0x68, 0x27, 0xD8, 0x0C, + 0xDA, 0x65, 0x4F, 0xD3, 0xA0, 0x77, 0x4C, 0xD2, + 0xF9, 0x95, 0x51, 0x7C, 0xF0, 0x64, 0xC6, 0x17, + 0xF2, 0x1A, 0x54, 0x27, 0x5F, 0xE5, 0x0C, 0x8D + }, + { + 0x09, 0xBE, 0x15, 0xEB, 0x6A, 0x5C, 0x22, 0x6F, + 0x6D, 0x95, 0x08, 0xCB, 0xA4, 0xA2, 0x51, 0x9F, + 0xBA, 0x17, 0x2A, 0xF8, 0x37, 0x58, 0x27, 0xD7, + 0x54, 0xA7, 0xA1, 0xBC, 0x19, 0x25, 0xD1, 0x3F, + 0x5E, 0x63, 0x43, 0xF3, 0xE1, 0x4D, 0x08, 0xA0, + 0x6E, 0x8D, 0x37, 0xF8, 0xEC, 0x56, 0xFB, 0x43, + 0x8E, 0x62, 0x36, 0x66, 0xB6, 0xFB, 0x0E, 0x23, + 0xFB, 0x50, 0x47, 0x7D, 0x41, 0x1B, 0x0C, 0x3A + }, + { + 0xC3, 0x57, 0x97, 0xE9, 0x83, 0x2D, 0x3E, 0x23, + 0x23, 0x33, 0x5B, 0x8C, 0x19, 0xC5, 0xFA, 0x74, + 0x91, 0x60, 0x2D, 0xBF, 0x6B, 0xEA, 0x77, 0xFA, + 0xEE, 0xC9, 0x51, 0x0B, 0xC2, 0xE8, 0x91, 0xC8, + 0xC3, 0x46, 0x21, 0x99, 0xF6, 0x04, 0x18, 0xD2, + 0xE0, 0xAB, 0xFF, 0xE3, 0x1B, 0x61, 0x3B, 0xB9, + 0x80, 0xEA, 0x32, 0xB7, 0x6C, 0x82, 0x43, 0x8D, + 0x02, 0x5F, 0x67, 0x8C, 0xAF, 0x48, 0x24, 0xA4 + }, + { + 0xCF, 0xC0, 0x57, 0xFD, 0xA7, 0x8A, 0x50, 0x31, + 0x8F, 0x49, 0x78, 0xFF, 0xFF, 0xAF, 0x77, 0x17, + 0x98, 0xE1, 0x2C, 0x3E, 0xA8, 0xC7, 0x98, 0x19, + 0x5B, 0xC5, 0xB4, 0xE6, 0x89, 0x1E, 0x61, 0xAA, + 0x25, 0xF7, 0xAF, 0x4A, 0xA7, 0x28, 0x6A, 0xC8, + 0x50, 0x76, 0x62, 0xC9, 0x07, 0xED, 0x91, 0x3E, + 0xDA, 0x65, 0x8F, 0x63, 0xFC, 0x47, 0x99, 0x7C, + 0x59, 0xB8, 0x59, 0x70, 0xF8, 0x78, 0xCA, 0x18 + }, + { + 0xD8, 0xEB, 0xE0, 0xE6, 0x38, 0xFC, 0x53, 0x5B, + 0x52, 0xCB, 0x0A, 0xFC, 0xE0, 0xF8, 0x2D, 0xDE, + 0x28, 0x57, 0x01, 0xAF, 0xF3, 0x29, 0xA5, 0x4B, + 0xA0, 0x6D, 0xFD, 0x3D, 0x1B, 0x4B, 0x31, 0xF9, + 0xF4, 0xB2, 0x4D, 0x9D, 0x68, 0x36, 0xF1, 0x22, + 0x3D, 0x6D, 0xE6, 0x6B, 0xAE, 0x78, 0x88, 0xFE, + 0xBC, 0x20, 0x40, 0xCF, 0xE9, 0x30, 0xE6, 0x9C, + 0xED, 0x59, 0xDA, 0x6D, 0xA8, 0xA0, 0xA6, 0xA6 + }, + { + 0x16, 0xB8, 0xC5, 0x5C, 0xF2, 0xF1, 0x35, 0xA4, + 0x32, 0x59, 0x0D, 0x2D, 0x4C, 0xFA, 0x38, 0x59, + 0x2F, 0x59, 0x35, 0xF8, 0xE7, 0x1C, 0xE0, 0x8A, + 0x02, 0x06, 0xA0, 0xE5, 0xAB, 0xEA, 0x90, 0xB2, + 0xE1, 0x07, 0xEB, 0x86, 0xB9, 0x18, 0x82, 0x3B, + 0xDD, 0x3B, 0xD2, 0x66, 0x07, 0x22, 0xC8, 0xDB, + 0xFA, 0x66, 0xAB, 0xB9, 0xF8, 0x63, 0x8E, 0x46, + 0x34, 0x02, 0xF6, 0x57, 0xA1, 0x68, 0x64, 0x0A + }, + { + 0x6A, 0x6E, 0x89, 0x38, 0x4F, 0x53, 0x5F, 0x02, + 0x17, 0x6C, 0x48, 0xA9, 0x93, 0xD3, 0x68, 0x7B, + 0x38, 0x9B, 0xFC, 0x03, 0x05, 0x0C, 0x77, 0x70, + 0x86, 0x35, 0x5C, 0x1A, 0x55, 0x59, 0x77, 0x42, + 0xF0, 0xB7, 0x48, 0x34, 0xA7, 0x1D, 0x05, 0x2A, + 0xE8, 0xA8, 0x3D, 0xC3, 0x4A, 0x8F, 0xD7, 0xBA, + 0x5A, 0xA6, 0x9D, 0xBD, 0x61, 0x2A, 0x4C, 0x22, + 0xDF, 0x4F, 0x74, 0xE2, 0x52, 0x8F, 0xB7, 0xA3 + }, + { + 0x1E, 0x40, 0x38, 0xCF, 0xA5, 0x0D, 0x8B, 0x13, + 0xEF, 0x68, 0xBE, 0xC3, 0xB0, 0xFF, 0xD5, 0x62, + 0xA0, 0x7A, 0xD6, 0x34, 0xB5, 0x82, 0x82, 0x57, + 0xDB, 0xA8, 0x73, 0x04, 0xF8, 0x23, 0xA9, 0x00, + 0x49, 0x2A, 0x31, 0x37, 0x19, 0x8B, 0x60, 0x5C, + 0xC7, 0xF7, 0x7C, 0x33, 0xB8, 0xCA, 0x3D, 0x94, + 0x0F, 0xD9, 0xB3, 0x38, 0xCF, 0x6B, 0x7B, 0x36, + 0xE7, 0xD9, 0xD9, 0x27, 0x20, 0x97, 0x93, 0xD0 + }, + { + 0x5B, 0xA6, 0xCD, 0x98, 0x8F, 0xF9, 0xA4, 0x81, + 0x91, 0x42, 0x21, 0x7E, 0xD6, 0x5D, 0x43, 0x7B, + 0x41, 0x3B, 0xA5, 0x02, 0x6B, 0x55, 0x4D, 0x8D, + 0x94, 0xEA, 0x27, 0x02, 0xC0, 0x96, 0xD1, 0x01, + 0x47, 0x75, 0xDB, 0xA2, 0xCA, 0xE9, 0x6F, 0x1E, + 0x2E, 0x72, 0x29, 0xC3, 0x78, 0xF2, 0x0B, 0x03, + 0x89, 0xE1, 0x19, 0x54, 0x7F, 0xDD, 0x35, 0x22, + 0x4A, 0x61, 0x7F, 0xCD, 0xCD, 0x0C, 0xB3, 0xAF + }, + { + 0x2D, 0x20, 0x96, 0x12, 0x30, 0xE2, 0x50, 0xF8, + 0x1D, 0xDC, 0xD2, 0xD2, 0xAB, 0x3E, 0xF0, 0xDA, + 0xCF, 0x96, 0x85, 0x1E, 0xBA, 0xE5, 0x96, 0x34, + 0x47, 0x19, 0x2C, 0xDB, 0x89, 0xE4, 0x8E, 0x84, + 0xF3, 0x96, 0xEC, 0x9A, 0x09, 0x25, 0x27, 0x84, + 0xE1, 0x73, 0xAD, 0xA5, 0x2A, 0x9C, 0x81, 0xAC, + 0xDA, 0xB3, 0xD8, 0xD6, 0x83, 0x80, 0x24, 0x7A, + 0xE9, 0x75, 0x23, 0x9B, 0x01, 0x7D, 0xC1, 0xCE + }, + { + 0x35, 0x38, 0x3E, 0xA7, 0x76, 0x2B, 0x55, 0x31, + 0x0A, 0x7D, 0x57, 0xFB, 0xD5, 0xA5, 0x49, 0x97, + 0x57, 0x9B, 0x0B, 0xA3, 0x9A, 0x4E, 0xB8, 0x87, + 0x94, 0x2B, 0xD1, 0x4F, 0xD8, 0x48, 0x31, 0x88, + 0xE5, 0x00, 0x48, 0x83, 0x8D, 0x6C, 0x02, 0xDC, + 0x75, 0x89, 0x59, 0xA9, 0xF7, 0x4D, 0x83, 0x37, + 0x27, 0x43, 0xE8, 0x64, 0xC6, 0x01, 0xED, 0x70, + 0x40, 0xA9, 0xE8, 0x71, 0x52, 0xD4, 0xCF, 0xFB + }, + { + 0x0B, 0x22, 0x3B, 0x6A, 0x1C, 0x2D, 0x3A, 0xB3, + 0xF9, 0x07, 0x7A, 0x31, 0x7B, 0x7F, 0xE3, 0x2F, + 0x6F, 0x95, 0x7B, 0x7B, 0x17, 0x41, 0xF2, 0x71, + 0x77, 0x71, 0x83, 0x4D, 0x37, 0x96, 0xA1, 0x9B, + 0xA3, 0x62, 0x73, 0xC9, 0xEE, 0xD6, 0x4C, 0x07, + 0xFA, 0x4E, 0x9A, 0xF7, 0xA9, 0x8A, 0xCE, 0x9C, + 0x78, 0x9A, 0x79, 0xA5, 0xA0, 0xF9, 0x4D, 0x04, + 0x05, 0xAA, 0xF0, 0x4A, 0xF3, 0x1E, 0xD7, 0x97 + }, + { + 0x5A, 0x00, 0x7F, 0x58, 0x95, 0x52, 0x4A, 0x5E, + 0x80, 0x37, 0x03, 0x6E, 0x0F, 0x26, 0x39, 0xFD, + 0xA8, 0xC5, 0xC1, 0x51, 0x2D, 0x76, 0xE9, 0xD1, + 0x9B, 0x3D, 0xD2, 0xD5, 0xBA, 0x43, 0xF5, 0x07, + 0x97, 0x41, 0xA4, 0x58, 0x31, 0x3C, 0x5E, 0x02, + 0x40, 0x0C, 0xE0, 0x2C, 0xB6, 0x56, 0x80, 0xBE, + 0x28, 0x2E, 0xAC, 0xD9, 0xA2, 0x54, 0xEF, 0x1C, + 0xDD, 0xEE, 0xBD, 0xCE, 0xE8, 0x5D, 0x41, 0x87 + }, + { + 0xBE, 0x4D, 0xD1, 0xCC, 0xBD, 0xE1, 0x67, 0x00, + 0x04, 0xD0, 0xEF, 0xAB, 0x65, 0x43, 0xE9, 0x1C, + 0x4E, 0x46, 0x64, 0xE5, 0xA2, 0xA8, 0x8B, 0xAC, + 0x6D, 0xD2, 0x7D, 0x27, 0x64, 0x8D, 0x30, 0x2A, + 0x06, 0x5B, 0xE6, 0x07, 0x8B, 0x22, 0xE4, 0xC4, + 0xAB, 0x4F, 0x7F, 0x7C, 0xBF, 0xAF, 0xC1, 0xAD, + 0x86, 0xEC, 0x2A, 0x50, 0x4F, 0xE5, 0x85, 0x17, + 0x66, 0xF7, 0xA3, 0x24, 0x47, 0x57, 0xCB, 0x6F + }, + { + 0x0F, 0xB4, 0x48, 0x3F, 0x96, 0x59, 0x29, 0x6C, + 0xB9, 0x24, 0x5B, 0x57, 0x79, 0x2A, 0x1E, 0x6A, + 0x99, 0xF2, 0x87, 0x90, 0x07, 0x72, 0x87, 0x96, + 0x8A, 0xB3, 0xEF, 0x35, 0x89, 0xE6, 0x90, 0x24, + 0x06, 0xF1, 0xF3, 0x9D, 0xCC, 0xE0, 0x06, 0x1D, + 0xEA, 0x94, 0x0F, 0xC8, 0xC1, 0xC4, 0x9F, 0x4B, + 0x54, 0x5E, 0xED, 0x59, 0xE9, 0x6D, 0xDA, 0xE9, + 0x6A, 0x6C, 0x35, 0xB5, 0x59, 0x3C, 0x29, 0x77 + }, + { + 0x41, 0xD1, 0xFA, 0xDC, 0x60, 0xA4, 0x6C, 0x9A, + 0xD0, 0x12, 0x0A, 0x3F, 0x54, 0xD0, 0x05, 0xF5, + 0xA1, 0x07, 0x5E, 0x2F, 0x71, 0xEE, 0x0D, 0xA6, + 0x18, 0xBA, 0xC1, 0x46, 0x1E, 0xFA, 0xE9, 0x69, + 0xEC, 0xCD, 0x7A, 0xA5, 0x75, 0xC4, 0xCD, 0xAE, + 0x97, 0x1D, 0xED, 0x13, 0xAE, 0x13, 0xC5, 0x06, + 0x87, 0x2C, 0xEC, 0xB5, 0xB2, 0x08, 0xFA, 0x72, + 0xA9, 0x48, 0x40, 0x02, 0x3E, 0xDB, 0x3E, 0xFE + }, + { + 0x2F, 0x7F, 0xDC, 0x1D, 0xA4, 0x4B, 0x6E, 0x5D, + 0x2D, 0xEC, 0xDE, 0x82, 0x1A, 0xAF, 0x4B, 0x49, + 0x16, 0x8C, 0x02, 0xE8, 0xD5, 0xF2, 0x5D, 0x5C, + 0x69, 0x98, 0x71, 0x08, 0x3A, 0xEB, 0xD9, 0x28, + 0xB7, 0x4D, 0xC2, 0x2D, 0xCB, 0xED, 0xFA, 0xBA, + 0x93, 0x16, 0xAE, 0xFC, 0xA8, 0x48, 0xD1, 0x5F, + 0x05, 0x17, 0x32, 0x99, 0x03, 0xD3, 0x4B, 0x83, + 0x70, 0xDD, 0xF9, 0xBD, 0x58, 0xC6, 0xD0, 0xCD + }, + { + 0x88, 0x55, 0x8A, 0x46, 0x4E, 0xE1, 0xA8, 0x80, + 0x3B, 0x23, 0x95, 0xAF, 0x6A, 0x64, 0x90, 0x84, + 0x2B, 0x5C, 0xD4, 0x3D, 0x41, 0xF6, 0xC0, 0x7C, + 0xD6, 0xC5, 0xF8, 0x5F, 0x82, 0xF5, 0x84, 0x32, + 0xA0, 0xB1, 0x62, 0xB4, 0x38, 0xBF, 0x0C, 0xB7, + 0x08, 0x2A, 0x76, 0x73, 0xE2, 0x87, 0xD6, 0xB9, + 0x0F, 0x8D, 0x0D, 0xC8, 0xAA, 0x5C, 0xEB, 0xA3, + 0x6B, 0xFA, 0x77, 0xB1, 0x5B, 0xA0, 0x69, 0x16 + }, + { + 0xEC, 0xC1, 0x49, 0x91, 0x7B, 0x26, 0x63, 0x98, + 0xB6, 0xF3, 0x29, 0x7E, 0x96, 0x96, 0x73, 0xB1, + 0x4E, 0xAE, 0x69, 0xCE, 0x43, 0x67, 0x1F, 0xD3, + 0xC6, 0xC2, 0x15, 0xC7, 0xCF, 0x42, 0xDE, 0xA1, + 0x02, 0xFC, 0x6B, 0xD9, 0x0C, 0x87, 0xDB, 0xD4, + 0x29, 0x02, 0x51, 0x12, 0x9C, 0xC1, 0x9B, 0x38, + 0xCC, 0xF0, 0x0C, 0xBD, 0xB1, 0x6D, 0xD8, 0xDE, + 0x51, 0x58, 0x60, 0x1A, 0x41, 0x6B, 0x1F, 0x00 + }, + { + 0xED, 0x30, 0x12, 0xF8, 0x9D, 0x71, 0xED, 0x13, + 0xBB, 0x82, 0x72, 0xEC, 0xDC, 0x3D, 0x0F, 0x51, + 0xE1, 0x4A, 0x37, 0xC1, 0xEF, 0x77, 0x57, 0x77, + 0x7A, 0xDA, 0x67, 0x12, 0x78, 0x4B, 0xE1, 0x6E, + 0xCF, 0xD3, 0xE6, 0x40, 0x58, 0x30, 0xF5, 0x1D, + 0xB3, 0x3D, 0xCB, 0x85, 0x52, 0x92, 0x93, 0xE2, + 0x3E, 0x47, 0x3A, 0xBF, 0x8C, 0x5C, 0x76, 0x55, + 0xD0, 0xC4, 0xF1, 0x52, 0xD0, 0x48, 0xBA, 0xB2 + }, + { + 0x09, 0x7A, 0x81, 0x19, 0x1E, 0x10, 0x05, 0x67, + 0x6D, 0x6E, 0x22, 0xA9, 0x63, 0x48, 0xFA, 0x4A, + 0x7C, 0x95, 0x61, 0xFD, 0x4D, 0x22, 0x8E, 0xB2, + 0x5F, 0x29, 0x47, 0x56, 0xBB, 0x87, 0xA2, 0xBA, + 0x88, 0x47, 0x5B, 0x03, 0x6F, 0x79, 0xFE, 0x37, + 0x3D, 0x75, 0x40, 0x87, 0x05, 0x52, 0x00, 0x1D, + 0x54, 0x79, 0x5F, 0x25, 0x92, 0x39, 0xBE, 0x6D, + 0x32, 0xC4, 0x87, 0xD1, 0x94, 0x4F, 0x1F, 0xE7 + }, + { + 0x3F, 0xC7, 0x98, 0xE4, 0x69, 0xD3, 0x90, 0x86, + 0xBA, 0x0B, 0xB4, 0x06, 0x3E, 0x80, 0x5F, 0xDF, + 0xB2, 0x20, 0x8D, 0xE4, 0x99, 0x18, 0x41, 0x73, + 0xF9, 0xA2, 0x36, 0x4D, 0x56, 0xBC, 0xD5, 0x63, + 0xED, 0x61, 0x9B, 0xB6, 0x87, 0x32, 0x24, 0x25, + 0x01, 0x4A, 0x1A, 0xAD, 0x3B, 0xCF, 0x50, 0xD2, + 0x2D, 0x83, 0xA9, 0x9D, 0x09, 0x73, 0x0A, 0x92, + 0xEC, 0x65, 0x46, 0xB3, 0xFC, 0x40, 0xA2, 0xC6 + }, + { + 0x69, 0x12, 0xB4, 0xB3, 0x41, 0xC7, 0xDD, 0x70, + 0x68, 0x37, 0x38, 0xBA, 0x0E, 0x7D, 0xEB, 0xBA, + 0xBF, 0xCA, 0x5F, 0x4F, 0xB0, 0x76, 0x0C, 0x84, + 0x97, 0x76, 0xE9, 0x20, 0x75, 0x0B, 0xF1, 0x37, + 0x89, 0xA6, 0x99, 0x97, 0x96, 0x23, 0x4E, 0x9E, + 0x24, 0x07, 0x15, 0xB2, 0x67, 0x67, 0x78, 0x2B, + 0x85, 0xA6, 0x4D, 0x68, 0x0C, 0x6D, 0x4C, 0xD4, + 0x26, 0xAD, 0x72, 0xB2, 0xFC, 0xE0, 0x81, 0xE8 + }, + { + 0xCE, 0xCD, 0x14, 0x01, 0x50, 0x15, 0x7D, 0xC9, + 0x06, 0xC0, 0xFF, 0x7F, 0x87, 0xC0, 0x08, 0x8F, + 0x31, 0x64, 0x80, 0x78, 0x3B, 0x4F, 0xE0, 0xA5, + 0x94, 0x45, 0x10, 0xC6, 0x4A, 0x87, 0xE3, 0xED, + 0x06, 0x67, 0x97, 0xA2, 0x7C, 0xE9, 0xD0, 0xF2, + 0x84, 0xDC, 0xA5, 0x18, 0x44, 0x18, 0x08, 0xAC, + 0x18, 0x29, 0x0A, 0xFD, 0xC0, 0x31, 0x29, 0x4B, + 0x31, 0xAA, 0x8B, 0x4A, 0x9F, 0xCD, 0x78, 0xF8 + }, + { + 0x2A, 0x2B, 0xED, 0x5D, 0x6A, 0xC0, 0x89, 0x28, + 0x11, 0xA4, 0x09, 0xD9, 0xF1, 0xFF, 0x63, 0x03, + 0xCC, 0xF9, 0x55, 0x44, 0x57, 0x46, 0x99, 0xCD, + 0xA7, 0xF7, 0x35, 0x03, 0x01, 0xF6, 0xD0, 0xC4, + 0xE8, 0x6E, 0x63, 0x5C, 0x80, 0x87, 0x56, 0x66, + 0xE2, 0xBB, 0x39, 0x07, 0x51, 0x0D, 0x0E, 0x72, + 0x12, 0x0F, 0x04, 0x86, 0x5E, 0xDC, 0x4C, 0x6C, + 0xEE, 0xCB, 0x44, 0x62, 0xD6, 0xAF, 0x60, 0xFB + }, + { + 0x03, 0x85, 0xAE, 0x9B, 0x73, 0x5D, 0xC5, 0x9F, + 0x30, 0x4D, 0x41, 0x4C, 0xA0, 0x43, 0x74, 0x9A, + 0xB5, 0x1A, 0xB6, 0x65, 0xEE, 0x01, 0xBE, 0x5E, + 0x52, 0xDC, 0xF7, 0x25, 0xEE, 0x7D, 0xFE, 0xFE, + 0xA6, 0xAD, 0x73, 0xF3, 0x35, 0xEE, 0xCF, 0x2A, + 0x51, 0x02, 0xE8, 0x88, 0x07, 0xFD, 0xC7, 0x5A, + 0xE6, 0xDC, 0x49, 0x0D, 0x7B, 0x8B, 0x5F, 0x11, + 0x63, 0x03, 0xEF, 0x60, 0xA5, 0xF1, 0x7C, 0x06 + }, + { + 0x0C, 0xA3, 0xFF, 0x03, 0x89, 0x65, 0xC0, 0x3B, + 0xC6, 0x5B, 0xBE, 0x2D, 0x86, 0x6C, 0xE9, 0xE0, + 0xE4, 0xE7, 0xD0, 0x3D, 0xC7, 0xF8, 0x6B, 0xA5, + 0x65, 0x0F, 0x82, 0xDD, 0xB3, 0xA9, 0xAA, 0x84, + 0x6B, 0x2B, 0x1F, 0x55, 0x3B, 0xD8, 0x9F, 0xB4, + 0xF9, 0xB6, 0x2E, 0x3C, 0x7F, 0xAF, 0x9E, 0xC3, + 0x10, 0x9F, 0xA9, 0x0E, 0xE5, 0x6C, 0x24, 0x63, + 0xE6, 0xEF, 0xD1, 0xAB, 0xAD, 0x8E, 0x28, 0xE6 + }, + { + 0x6D, 0xFD, 0x4F, 0x22, 0x18, 0x4E, 0xD0, 0x91, + 0xFD, 0x5A, 0xBA, 0x03, 0x9F, 0xCD, 0x3D, 0xB9, + 0x22, 0xF5, 0xE5, 0x9B, 0xF8, 0x38, 0xC0, 0x37, + 0x35, 0x7F, 0xAD, 0x93, 0x4B, 0x45, 0x10, 0x60, + 0x3F, 0x43, 0xA7, 0x31, 0x9F, 0xFF, 0xA6, 0x23, + 0x86, 0xF8, 0x78, 0x8F, 0xDF, 0x9D, 0xED, 0x40, + 0xC6, 0x66, 0xB4, 0xBD, 0xCA, 0x86, 0xD9, 0x32, + 0x8F, 0xE5, 0x5A, 0xD8, 0x6B, 0x37, 0x2F, 0xC8 + }, + { + 0xA3, 0x18, 0x97, 0x61, 0x02, 0x74, 0x7D, 0x80, + 0x0F, 0x58, 0x4D, 0xF6, 0x5B, 0xFB, 0x44, 0x3B, + 0x85, 0x6F, 0x00, 0x9E, 0x74, 0xF7, 0x29, 0x46, + 0xD0, 0x07, 0x6C, 0xED, 0xAC, 0x04, 0x37, 0x6F, + 0xAB, 0x97, 0x34, 0x53, 0xAD, 0xAD, 0xC3, 0x10, + 0xF7, 0x20, 0x81, 0xCB, 0xBA, 0x96, 0x26, 0x4F, + 0xFE, 0x2B, 0x21, 0xA3, 0xB1, 0x8B, 0xE9, 0xD8, + 0x8C, 0x42, 0x46, 0xCB, 0xA6, 0xD3, 0x09, 0x01 + }, + { + 0xB5, 0xE6, 0xE4, 0xFC, 0xA0, 0xCF, 0x98, 0x48, + 0xA0, 0x05, 0x89, 0xC6, 0x54, 0x57, 0xDB, 0x68, + 0xB3, 0x25, 0x3A, 0x6E, 0x17, 0x78, 0x85, 0x41, + 0x47, 0x2E, 0x1F, 0xB9, 0x48, 0x17, 0xF8, 0x04, + 0x05, 0x4D, 0x07, 0xA5, 0xD3, 0x2D, 0xFA, 0x0C, + 0xDB, 0x6F, 0xB4, 0x4E, 0xED, 0x50, 0xD2, 0x0E, + 0x5F, 0x22, 0x64, 0x36, 0x11, 0x32, 0xFA, 0x5F, + 0xCF, 0xD6, 0xE1, 0xB3, 0x67, 0xC1, 0xBE, 0x28 + }, + { + 0x2E, 0xA4, 0x57, 0x38, 0x29, 0x25, 0xE0, 0x3C, + 0xF8, 0x11, 0x10, 0x05, 0x0E, 0x63, 0x6A, 0xD6, + 0x78, 0xE0, 0xAA, 0x3C, 0xBC, 0x69, 0x00, 0xBD, + 0xEF, 0x27, 0x8A, 0xAA, 0x18, 0xF2, 0x35, 0xE2, + 0x51, 0x60, 0xA2, 0x0E, 0x23, 0xFE, 0x0E, 0x62, + 0xA8, 0x51, 0x1B, 0x5D, 0xD0, 0x59, 0x2F, 0x79, + 0xCB, 0xC8, 0xEB, 0x7D, 0xEA, 0x64, 0xAC, 0x86, + 0x67, 0x49, 0x43, 0x45, 0xC6, 0x89, 0x2D, 0xD4 + }, + { + 0x96, 0xB3, 0x49, 0x8B, 0xCC, 0xD7, 0x8B, 0x5A, + 0x40, 0x1B, 0x27, 0x38, 0x78, 0x7D, 0x28, 0xA9, + 0x8A, 0x0E, 0xDF, 0xDC, 0x7C, 0x0B, 0x5F, 0xF9, + 0x43, 0xCF, 0xE1, 0xB1, 0x4E, 0x9C, 0xF5, 0xD9, + 0xED, 0x43, 0x10, 0x7D, 0xFB, 0xDD, 0x9E, 0x97, + 0x28, 0xD5, 0xFD, 0xD6, 0xF7, 0x1F, 0xBC, 0x77, + 0x0E, 0xAD, 0xDC, 0x4F, 0x2E, 0x40, 0x9A, 0xBE, + 0x71, 0x92, 0x7B, 0xAE, 0x1F, 0x8F, 0x73, 0xD1 + }, + { + 0xCE, 0x1B, 0xFB, 0x9A, 0xFE, 0xD2, 0x8A, 0xF4, + 0xDC, 0x75, 0x35, 0xAD, 0xEF, 0x71, 0xB8, 0xF1, + 0xB8, 0x0A, 0x8D, 0x72, 0x94, 0xB4, 0x11, 0xFD, + 0x1E, 0xD3, 0x93, 0xCF, 0x23, 0x2D, 0x3A, 0x5C, + 0x5D, 0xF2, 0x3D, 0xBB, 0x1D, 0xB2, 0x6D, 0xDD, + 0xF6, 0xF7, 0x45, 0xF8, 0xBC, 0x24, 0xC3, 0x78, + 0x1F, 0x2D, 0xBB, 0xC8, 0x18, 0xA0, 0x0A, 0xE1, + 0xFB, 0x9D, 0x64, 0x63, 0xE9, 0x5F, 0x29, 0x86 + }, + { + 0xE6, 0x4D, 0x37, 0x35, 0x6B, 0x29, 0x6B, 0x36, + 0x93, 0x0E, 0xAB, 0xE4, 0x54, 0xDB, 0x11, 0xB2, + 0x09, 0x7B, 0x0C, 0x04, 0x0B, 0xED, 0x57, 0x98, + 0x87, 0x8D, 0x38, 0xA8, 0xC4, 0xD1, 0xC6, 0xF3, + 0x26, 0x1F, 0x36, 0xBF, 0xF7, 0x64, 0xE3, 0xB4, + 0xD6, 0x06, 0xB3, 0x17, 0xE5, 0xFF, 0x50, 0x04, + 0x18, 0x45, 0x92, 0xB0, 0xB7, 0xDD, 0xFB, 0x8C, + 0x2F, 0xD8, 0x35, 0x23, 0x26, 0xCD, 0xDD, 0xB1 + }, + { + 0x85, 0xE6, 0xFE, 0x54, 0xE1, 0xE7, 0x60, 0x46, + 0xAF, 0x68, 0xF5, 0xC6, 0x04, 0x4C, 0x1E, 0x3F, + 0xFF, 0x3B, 0xFC, 0xA0, 0xBA, 0xEC, 0xAE, 0xF6, + 0xA1, 0xDF, 0x90, 0x35, 0x0D, 0xF2, 0xB0, 0xBE, + 0xC6, 0xA4, 0x20, 0xEE, 0x8F, 0x49, 0xAD, 0x44, + 0x64, 0xEC, 0x4C, 0x1E, 0x7D, 0x71, 0xF6, 0x67, + 0x61, 0x4A, 0xCE, 0xBD, 0xAD, 0xA3, 0xDF, 0x32, + 0x07, 0x79, 0x07, 0x83, 0x23, 0xF6, 0xA8, 0xAF + }, + { + 0xB1, 0x2F, 0xF1, 0xEB, 0x3B, 0xAB, 0x32, 0x0D, + 0x78, 0x55, 0xB5, 0x49, 0xD7, 0x2B, 0x72, 0x47, + 0x59, 0x91, 0x68, 0x11, 0xCB, 0xCF, 0x3E, 0x1A, + 0x12, 0x82, 0x3F, 0x98, 0xB6, 0x4A, 0xB5, 0xC4, + 0x59, 0x41, 0x61, 0x0F, 0x6B, 0x47, 0x1E, 0x35, + 0xFF, 0x79, 0x28, 0x29, 0xDD, 0x5A, 0xDE, 0x51, + 0x79, 0x12, 0x57, 0x38, 0xF3, 0xF2, 0x37, 0x28, + 0x63, 0x0F, 0x1E, 0xEC, 0x57, 0x77, 0x5A, 0x19 + }, + { + 0xB4, 0xDB, 0xE7, 0x2A, 0x1E, 0x21, 0x69, 0x7A, + 0x47, 0x44, 0xBE, 0x65, 0x00, 0x0C, 0xB1, 0xBA, + 0xD3, 0x7C, 0xE2, 0x14, 0x16, 0xEE, 0x6F, 0xCE, + 0xA8, 0x4E, 0xBA, 0xF1, 0x2A, 0x59, 0xC1, 0x1D, + 0x7C, 0x08, 0x0D, 0xF9, 0x2F, 0xB2, 0xAA, 0x8F, + 0x1C, 0x4E, 0xE8, 0xE2, 0xA2, 0x2D, 0x30, 0xBE, + 0x49, 0x85, 0x82, 0xD7, 0xC5, 0xFB, 0xBA, 0x16, + 0x5A, 0x47, 0x26, 0x89, 0xAF, 0xF6, 0x01, 0xB6 + }, + { + 0x34, 0x82, 0x18, 0xBE, 0x4D, 0xE0, 0x8D, 0xFB, + 0x24, 0x5B, 0xF2, 0x52, 0x86, 0xE3, 0x66, 0x18, + 0x63, 0x1D, 0x3B, 0xDB, 0x58, 0x27, 0xD9, 0xF7, + 0x4F, 0xA0, 0x43, 0x01, 0x66, 0x11, 0x31, 0xA4, + 0xD5, 0x5C, 0x76, 0x09, 0xB1, 0xA6, 0xA0, 0x3B, + 0x85, 0x3F, 0x07, 0x33, 0xE0, 0xAE, 0xC0, 0x26, + 0x16, 0xA0, 0xA4, 0x0E, 0x84, 0x91, 0xF4, 0x94, + 0xD7, 0x6C, 0x15, 0x43, 0xCF, 0xC6, 0x82, 0x14 + }, + { + 0x42, 0x87, 0xE1, 0x9B, 0xAB, 0x1D, 0x4F, 0x75, + 0xE1, 0xD1, 0x97, 0xCB, 0xB4, 0x3F, 0x11, 0x33, + 0x13, 0x07, 0xF2, 0xF7, 0x5B, 0x8D, 0x0D, 0x50, + 0x27, 0x8E, 0xEC, 0x54, 0x09, 0x99, 0xA0, 0x09, + 0xC0, 0x33, 0x73, 0x52, 0x96, 0x07, 0xFD, 0xA6, + 0x05, 0xAA, 0x0F, 0x07, 0x39, 0xE2, 0x0B, 0xD1, + 0xFD, 0xAA, 0x27, 0xD7, 0xC0, 0xCD, 0xC8, 0x28, + 0x4D, 0x98, 0xE6, 0xC7, 0x55, 0xA7, 0x56, 0x2E + }, + { + 0x08, 0x56, 0x0C, 0x99, 0x88, 0xC8, 0xCE, 0x5A, + 0x88, 0x76, 0xA6, 0x00, 0xB6, 0xE5, 0x12, 0xB4, + 0xE2, 0x43, 0xA4, 0xA4, 0x30, 0x0A, 0xD5, 0xAB, + 0x2F, 0xF0, 0x63, 0x7C, 0xC5, 0x6A, 0x04, 0x41, + 0x64, 0x5B, 0x3D, 0xEB, 0x16, 0x84, 0x06, 0x4E, + 0xA4, 0x3B, 0xAE, 0x1C, 0xB6, 0x2D, 0x3B, 0xC4, + 0x15, 0x37, 0xFE, 0x8D, 0x7D, 0xEC, 0xA7, 0x17, + 0x29, 0x37, 0x77, 0x6B, 0xBE, 0xD7, 0x93, 0xA9 + }, + { + 0xB5, 0x36, 0x16, 0x23, 0x94, 0x77, 0x6F, 0xA7, + 0xDD, 0x5E, 0x9F, 0xDD, 0x01, 0x53, 0x0F, 0xDA, + 0x52, 0xBE, 0x1D, 0x39, 0xBD, 0x60, 0x9B, 0x3F, + 0x3B, 0xD0, 0x47, 0x6B, 0x81, 0x60, 0xAA, 0x18, + 0xAB, 0x2D, 0x37, 0xD2, 0x99, 0x16, 0x28, 0xBE, + 0x2F, 0xCC, 0x12, 0x56, 0xCD, 0x48, 0x55, 0x25, + 0xD1, 0xFA, 0x35, 0x6B, 0x04, 0xD3, 0x0E, 0x4A, + 0x0F, 0x9F, 0xFF, 0xC9, 0x93, 0x5C, 0xF4, 0x32 + }, + { + 0x02, 0xAB, 0xC9, 0x71, 0x75, 0xED, 0xB4, 0x7A, + 0x4C, 0xB4, 0xBD, 0x38, 0xD8, 0x2F, 0x86, 0xAA, + 0x09, 0x9C, 0x8B, 0x8F, 0xA8, 0xAB, 0x3F, 0xE1, + 0xCE, 0x10, 0x5A, 0x22, 0xBD, 0x61, 0x65, 0x78, + 0xC6, 0xDD, 0x15, 0x15, 0xDF, 0xB0, 0x39, 0x7E, + 0x1D, 0x9D, 0x06, 0x71, 0x91, 0x6D, 0xE4, 0xB5, + 0x22, 0xE7, 0x4E, 0x63, 0x75, 0x23, 0x68, 0x93, + 0xC8, 0xFD, 0xA6, 0xD2, 0x36, 0xBC, 0x8D, 0xA1 + }, + { + 0x21, 0xE1, 0xEB, 0x73, 0x12, 0x76, 0xA8, 0x35, + 0xA6, 0xDD, 0xEA, 0x71, 0x78, 0xB2, 0x3E, 0xBC, + 0x9A, 0xEC, 0xAA, 0xBC, 0x7C, 0xCD, 0x70, 0x65, + 0x87, 0xD7, 0x1B, 0x85, 0x44, 0x97, 0x93, 0xB0, + 0x7E, 0x7B, 0x17, 0x9A, 0x3D, 0xA7, 0xA5, 0x71, + 0x98, 0x29, 0x97, 0xE8, 0xF5, 0xA6, 0x7F, 0x8C, + 0x93, 0xDA, 0xF1, 0x1A, 0xAA, 0x23, 0xF0, 0x7E, + 0x4D, 0xF7, 0xA1, 0x31, 0x05, 0xA5, 0x42, 0x09 + }, + { + 0x1C, 0xC5, 0x37, 0xD3, 0xE5, 0x0E, 0xD9, 0xFD, + 0xCD, 0xC4, 0xF3, 0xCC, 0xB4, 0x81, 0x93, 0x75, + 0x41, 0x53, 0x04, 0xD8, 0xE5, 0xA6, 0xC0, 0x58, + 0x05, 0xB6, 0xB5, 0xD9, 0xE1, 0xFC, 0x18, 0x25, + 0x68, 0x64, 0xF1, 0x0C, 0xD8, 0x12, 0xF8, 0x48, + 0x01, 0xB8, 0x61, 0x6A, 0x92, 0xB4, 0x07, 0x95, + 0xA1, 0x55, 0x93, 0x24, 0x64, 0xF6, 0x2D, 0xBF, + 0x6E, 0xBD, 0x2F, 0x9A, 0xC3, 0xEE, 0x28, 0x16 + }, + { + 0x6F, 0x6C, 0xD2, 0x60, 0x05, 0xC8, 0xA5, 0x61, + 0xCF, 0xF5, 0x1E, 0x30, 0x1D, 0x1A, 0x06, 0x8F, + 0xC2, 0x8B, 0x9B, 0x65, 0x0D, 0xDD, 0x27, 0xAE, + 0x97, 0xB5, 0x22, 0xDA, 0xE9, 0x63, 0x91, 0x34, + 0xD5, 0xA1, 0x50, 0x58, 0x7B, 0x0A, 0x90, 0x1F, + 0x3B, 0x9A, 0xAB, 0xC7, 0xE3, 0x97, 0x84, 0x98, + 0x4C, 0xC5, 0x85, 0x23, 0x5D, 0x8E, 0x17, 0xCE, + 0x9E, 0x3B, 0x42, 0x10, 0x5B, 0xF9, 0x03, 0x4C + }, + { + 0x69, 0xC1, 0x7C, 0x28, 0x64, 0xC3, 0x37, 0x9F, + 0xAF, 0xB7, 0x14, 0xC0, 0x47, 0x5E, 0x00, 0xCF, + 0x7C, 0x9B, 0x37, 0x7D, 0x57, 0xA8, 0xBC, 0x96, + 0x98, 0xB4, 0xD3, 0x4A, 0x54, 0x85, 0x41, 0x76, + 0xA2, 0xF8, 0xD1, 0x5A, 0xFB, 0x54, 0x77, 0x56, + 0x04, 0x78, 0x73, 0x90, 0xD6, 0x00, 0x74, 0xCD, + 0x4B, 0xCA, 0x69, 0x02, 0xEA, 0x23, 0xD3, 0xAE, + 0x1A, 0xC0, 0x83, 0x40, 0x9F, 0xE3, 0x8A, 0x4D + }, + { + 0x86, 0x69, 0xB0, 0xAD, 0x35, 0x82, 0x9E, 0xDC, + 0x2A, 0x8A, 0x09, 0x85, 0x2B, 0x0E, 0xE9, 0xB3, + 0x90, 0x3B, 0xF6, 0xC1, 0xF8, 0x2F, 0x90, 0xA3, + 0xF0, 0xED, 0x95, 0x24, 0x19, 0x2F, 0x10, 0x91, + 0xFD, 0x64, 0x84, 0xE0, 0x4C, 0x3F, 0xEA, 0x8B, + 0x02, 0x2F, 0x4A, 0x89, 0x50, 0xDB, 0x17, 0xD4, + 0x73, 0x41, 0x45, 0xC0, 0xCE, 0xC5, 0xDC, 0x38, + 0x74, 0x55, 0xC1, 0x26, 0x90, 0x3F, 0x77, 0x66 + }, + { + 0x3F, 0x35, 0xC4, 0x5D, 0x24, 0xFC, 0xFB, 0x4A, + 0xCC, 0xA6, 0x51, 0x07, 0x6C, 0x08, 0x00, 0x0E, + 0x27, 0x9E, 0xBB, 0xFF, 0x37, 0xA1, 0x33, 0x3C, + 0xE1, 0x9F, 0xD5, 0x77, 0x20, 0x2D, 0xBD, 0x24, + 0xB5, 0x8C, 0x51, 0x4E, 0x36, 0xDD, 0x9B, 0xA6, + 0x4A, 0xF4, 0xD7, 0x8E, 0xEA, 0x4E, 0x2D, 0xD1, + 0x3B, 0xC1, 0x8D, 0x79, 0x88, 0x87, 0xDD, 0x97, + 0x13, 0x76, 0xBC, 0xAE, 0x00, 0x87, 0xE1, 0x7E + }, +}; + + + + +static const uint8_t blake2bp_keyed_kat[KAT_LENGTH][BLAKE2B_OUTBYTES] = +{ + { + 0x9D, 0x94, 0x61, 0x07, 0x3E, 0x4E, 0xB6, 0x40, + 0xA2, 0x55, 0x35, 0x7B, 0x83, 0x9F, 0x39, 0x4B, + 0x83, 0x8C, 0x6F, 0xF5, 0x7C, 0x9B, 0x68, 0x6A, + 0x3F, 0x76, 0x10, 0x7C, 0x10, 0x66, 0x72, 0x8F, + 0x3C, 0x99, 0x56, 0xBD, 0x78, 0x5C, 0xBC, 0x3B, + 0xF7, 0x9D, 0xC2, 0xAB, 0x57, 0x8C, 0x5A, 0x0C, + 0x06, 0x3B, 0x9D, 0x9C, 0x40, 0x58, 0x48, 0xDE, + 0x1D, 0xBE, 0x82, 0x1C, 0xD0, 0x5C, 0x94, 0x0A + }, + { + 0xFF, 0x8E, 0x90, 0xA3, 0x7B, 0x94, 0x62, 0x39, + 0x32, 0xC5, 0x9F, 0x75, 0x59, 0xF2, 0x60, 0x35, + 0x02, 0x9C, 0x37, 0x67, 0x32, 0xCB, 0x14, 0xD4, + 0x16, 0x02, 0x00, 0x1C, 0xBB, 0x73, 0xAD, 0xB7, + 0x92, 0x93, 0xA2, 0xDB, 0xDA, 0x5F, 0x60, 0x70, + 0x30, 0x25, 0x14, 0x4D, 0x15, 0x8E, 0x27, 0x35, + 0x52, 0x95, 0x96, 0x25, 0x1C, 0x73, 0xC0, 0x34, + 0x5C, 0xA6, 0xFC, 0xCB, 0x1F, 0xB1, 0xE9, 0x7E + }, + { + 0xD6, 0x22, 0x0C, 0xA1, 0x95, 0xA0, 0xF3, 0x56, + 0xA4, 0x79, 0x5E, 0x07, 0x1C, 0xEE, 0x1F, 0x54, + 0x12, 0xEC, 0xD9, 0x5D, 0x8A, 0x5E, 0x01, 0xD7, + 0xC2, 0xB8, 0x67, 0x50, 0xCA, 0x53, 0xD7, 0xF6, + 0x4C, 0x29, 0xCB, 0xB3, 0xD2, 0x89, 0xC6, 0xF4, + 0xEC, 0xC6, 0xC0, 0x1E, 0x3C, 0xA9, 0x33, 0x89, + 0x71, 0x17, 0x03, 0x88, 0xE3, 0xE4, 0x02, 0x28, + 0x47, 0x90, 0x06, 0xD1, 0xBB, 0xEB, 0xAD, 0x51 + }, + { + 0x30, 0x30, 0x2C, 0x3F, 0xC9, 0x99, 0x06, 0x5D, + 0x10, 0xDC, 0x98, 0x2C, 0x8F, 0xEE, 0xF4, 0x1B, + 0xBB, 0x66, 0x42, 0x71, 0x8F, 0x62, 0x4A, 0xF6, + 0xE3, 0xEA, 0xBE, 0xA0, 0x83, 0xE7, 0xFE, 0x78, + 0x53, 0x40, 0xDB, 0x4B, 0x08, 0x97, 0xEF, 0xFF, + 0x39, 0xCE, 0xE1, 0xDC, 0x1E, 0xB7, 0x37, 0xCD, + 0x1E, 0xEA, 0x0F, 0xE7, 0x53, 0x84, 0x98, 0x4E, + 0x7D, 0x8F, 0x44, 0x6F, 0xAA, 0x68, 0x3B, 0x80 + }, + { + 0x32, 0xF3, 0x98, 0xA6, 0x0C, 0x1E, 0x53, 0xF1, + 0xF8, 0x1D, 0x6D, 0x8D, 0xA2, 0xEC, 0x11, 0x75, + 0x42, 0x2D, 0x6B, 0x2C, 0xFA, 0x0C, 0x0E, 0x66, + 0xD8, 0xC4, 0xE7, 0x30, 0xB2, 0x96, 0xA4, 0xB5, + 0x3E, 0x39, 0x2E, 0x39, 0x85, 0x98, 0x22, 0xA1, + 0x45, 0xAE, 0x5F, 0x1A, 0x24, 0xC2, 0x7F, 0x55, + 0x33, 0x9E, 0x2B, 0x4B, 0x44, 0x58, 0xE8, 0xC5, + 0xEB, 0x19, 0xAA, 0x14, 0x20, 0x64, 0x27, 0xAA + }, + { + 0x23, 0x6D, 0xB9, 0x33, 0xF1, 0x8A, 0x9D, 0xBD, + 0x4E, 0x50, 0xB7, 0x29, 0x53, 0x90, 0x65, 0xBD, + 0xA4, 0x20, 0xDF, 0x97, 0xAC, 0x78, 0x0B, 0xE4, + 0x3F, 0x59, 0x10, 0x3C, 0x47, 0x2E, 0x0B, 0xCC, + 0xA6, 0xD4, 0x97, 0x38, 0x97, 0x86, 0xAF, 0x22, + 0xBA, 0x94, 0x30, 0xB7, 0x4D, 0x6F, 0x74, 0xB1, + 0x3F, 0x6F, 0x94, 0x9E, 0x25, 0x6A, 0x14, 0x0A, + 0xA3, 0x4B, 0x47, 0x70, 0x0B, 0x10, 0x03, 0x43 + }, + { + 0x23, 0x8C, 0x9D, 0x08, 0x02, 0x85, 0xE3, 0x54, + 0x35, 0xCB, 0x53, 0x15, 0x5D, 0x9F, 0x79, 0x2C, + 0xA1, 0xBB, 0x27, 0xDE, 0x4F, 0x9B, 0x6C, 0x87, + 0x26, 0xE1, 0x1C, 0x02, 0x8E, 0x7B, 0x87, 0x87, + 0x33, 0x54, 0x91, 0x12, 0xA3, 0x28, 0xB5, 0x0E, + 0x8C, 0xD8, 0xBA, 0x27, 0x87, 0x21, 0x7E, 0x46, + 0xB8, 0x16, 0x8D, 0x57, 0x11, 0x3D, 0xD4, 0x04, + 0xD9, 0x14, 0xE2, 0x9A, 0x6A, 0x54, 0x70, 0xE6 + }, + { + 0x9A, 0x02, 0x1E, 0xBD, 0x50, 0x4A, 0x97, 0x59, + 0x6D, 0x0E, 0x85, 0x04, 0x8A, 0xE1, 0xDA, 0x89, + 0x99, 0xE3, 0xA0, 0x47, 0x01, 0x6F, 0x17, 0xC6, + 0xC5, 0x55, 0x6C, 0x27, 0x31, 0xE9, 0xB1, 0x39, + 0x26, 0x1F, 0x84, 0x3F, 0xAD, 0x6B, 0xD4, 0x3F, + 0x7C, 0x7C, 0x58, 0x7F, 0x69, 0x8D, 0x69, 0xB6, + 0x82, 0xE5, 0x68, 0xB4, 0x42, 0xAC, 0x45, 0x88, + 0x98, 0x57, 0xB7, 0x69, 0x07, 0x34, 0xCD, 0xBB + }, + { + 0x3A, 0xBA, 0x07, 0xAE, 0x98, 0x0E, 0x33, 0x86, + 0x37, 0x47, 0x9D, 0xCA, 0x1E, 0x35, 0x28, 0x00, + 0xF4, 0x58, 0x8E, 0x62, 0xD8, 0x23, 0x36, 0x5A, + 0xA6, 0x9C, 0x5B, 0x25, 0xFC, 0xE1, 0x29, 0x68, + 0xD2, 0x6C, 0x9B, 0xDB, 0xEE, 0x9A, 0x32, 0xBF, + 0xFD, 0x42, 0xE6, 0xB2, 0x2C, 0x81, 0x38, 0xA6, + 0x1C, 0x1F, 0xCE, 0x49, 0xFF, 0xBC, 0x19, 0x0E, + 0x1E, 0x15, 0x16, 0x01, 0x53, 0xCC, 0xB6, 0xB4 + }, + { + 0x77, 0x4C, 0xDF, 0x9A, 0xBB, 0x50, 0x81, 0xFE, + 0x07, 0xEB, 0x57, 0x25, 0xE6, 0x06, 0x9B, 0x8D, + 0x6C, 0x7E, 0x60, 0x04, 0xA2, 0x4D, 0x70, 0xF7, + 0xDF, 0xAB, 0xFC, 0x03, 0x82, 0x5B, 0xBC, 0x3B, + 0x30, 0xE6, 0x20, 0xB6, 0x04, 0x1F, 0x3C, 0xC2, + 0x89, 0x6B, 0x14, 0xAB, 0x66, 0x0A, 0xF7, 0x2E, + 0x24, 0x95, 0x10, 0xAC, 0x2F, 0xE8, 0x10, 0xCC, + 0x77, 0x63, 0xA2, 0xE5, 0xC3, 0xFC, 0xA7, 0xFC + }, + { + 0x9E, 0x08, 0x9F, 0x51, 0x65, 0x7B, 0x29, 0xC2, + 0x66, 0x8E, 0x28, 0x50, 0x52, 0x4E, 0x53, 0xAE, + 0xAA, 0xA7, 0x30, 0x6F, 0x2A, 0xD5, 0xA2, 0x32, + 0xB5, 0xF0, 0x7F, 0x68, 0x8D, 0x8A, 0xB2, 0xB4, + 0x25, 0xDF, 0x7E, 0xA5, 0xBD, 0x3E, 0x9F, 0xFD, + 0x61, 0x68, 0x38, 0x90, 0x15, 0x1D, 0x78, 0xBB, + 0x94, 0x03, 0x11, 0x85, 0xAC, 0xA4, 0x81, 0xE2, + 0x14, 0x0F, 0xE3, 0x79, 0x85, 0x36, 0x76, 0x43 + }, + { + 0xB3, 0x5B, 0xD5, 0x4E, 0x4F, 0x81, 0x69, 0x6B, + 0x4F, 0x22, 0x31, 0x6A, 0x1E, 0x33, 0x7D, 0x98, + 0xD1, 0xC6, 0xB0, 0x61, 0x10, 0x99, 0x87, 0x63, + 0xB5, 0x91, 0x33, 0x35, 0x92, 0x3A, 0x40, 0x76, + 0xCB, 0x80, 0xD6, 0xD8, 0xA5, 0x18, 0x62, 0x91, + 0x13, 0x47, 0x7B, 0x30, 0xA1, 0x32, 0xA6, 0xB2, + 0x7F, 0xC1, 0xEE, 0x79, 0xF6, 0xB2, 0xE0, 0xD3, + 0x5D, 0x5B, 0xC2, 0x97, 0x27, 0x46, 0x3D, 0xB5 + }, + { + 0x12, 0x39, 0x30, 0xD5, 0xA4, 0xB7, 0x3B, 0x49, + 0x1F, 0x50, 0xE5, 0x6E, 0x2B, 0x73, 0x97, 0xA4, + 0x3D, 0x2E, 0x47, 0x87, 0x23, 0x76, 0x02, 0xB6, + 0x6F, 0xE0, 0xA8, 0x47, 0xBD, 0x13, 0xCB, 0xE8, + 0xB3, 0x7D, 0xC7, 0x03, 0xD7, 0xB2, 0xB4, 0xEA, + 0xA8, 0xBF, 0xB9, 0xA5, 0x8A, 0x7D, 0x71, 0x9C, + 0x90, 0x8F, 0x19, 0x66, 0xA2, 0xF1, 0x9F, 0xE6, + 0xEB, 0x1A, 0x78, 0x96, 0x2A, 0xFA, 0x5B, 0xF9 + }, + { + 0x08, 0x9C, 0xBC, 0x7E, 0xE1, 0xB1, 0x2C, 0x0C, + 0xC9, 0xC8, 0x3F, 0xF6, 0x66, 0xFE, 0xC8, 0x02, + 0x6B, 0xB7, 0x1B, 0x90, 0x84, 0x97, 0x9B, 0x0E, + 0xA8, 0xB7, 0x23, 0xBB, 0xBE, 0x8B, 0x00, 0xD4, + 0x10, 0x08, 0xB6, 0x04, 0x99, 0xF2, 0x4F, 0x24, + 0x1B, 0x63, 0x28, 0x1F, 0xE5, 0xB4, 0xD8, 0x89, + 0x66, 0x30, 0x9C, 0x0D, 0x7E, 0x64, 0x66, 0x91, + 0x05, 0xE5, 0x1E, 0x69, 0xD7, 0xAF, 0x8C, 0xE5 + }, + { + 0x6B, 0x3C, 0x67, 0x89, 0x47, 0xF6, 0x12, 0x52, + 0x65, 0x7C, 0x35, 0x49, 0x78, 0xC1, 0x01, 0xB2, + 0xFD, 0xD2, 0x72, 0x9E, 0xC3, 0x49, 0x27, 0xDD, + 0x5E, 0xFF, 0x0A, 0x7C, 0x0A, 0x86, 0x58, 0x26, + 0xE8, 0x33, 0xC3, 0x63, 0x23, 0x21, 0x31, 0xB1, + 0x05, 0x93, 0xBE, 0x1C, 0xCF, 0x6B, 0xA5, 0x4E, + 0xCC, 0x14, 0x31, 0x2F, 0x45, 0xBF, 0xFC, 0x24, + 0x04, 0x62, 0x9F, 0xF8, 0x02, 0x67, 0xF0, 0x94 + }, + { + 0xAA, 0x0C, 0x23, 0xEA, 0x1C, 0x6F, 0xE2, 0xE9, + 0x0A, 0x77, 0x18, 0xEF, 0x4A, 0xA4, 0x75, 0x1F, + 0xF6, 0xBE, 0xB9, 0xD4, 0x61, 0x63, 0x59, 0x5B, + 0x5D, 0x4F, 0xB8, 0x96, 0x00, 0x52, 0x5C, 0x5B, + 0x6C, 0xF1, 0x9E, 0xCD, 0xB2, 0x47, 0x78, 0x72, + 0xA7, 0xA1, 0x2D, 0x40, 0xE5, 0x06, 0x36, 0x08, + 0xE5, 0xF0, 0x00, 0x8E, 0x79, 0x72, 0xA9, 0xC0, + 0x1A, 0x4B, 0xE2, 0xAF, 0xE9, 0x53, 0x2F, 0x9C + }, + { + 0x63, 0x34, 0x7A, 0xB4, 0xCB, 0xB6, 0xF2, 0x89, + 0x52, 0x99, 0x2C, 0x07, 0x9D, 0x18, 0xD4, 0x20, + 0x01, 0xB7, 0xF3, 0xA9, 0xD0, 0xFD, 0x90, 0xB0, + 0xA4, 0x77, 0x1F, 0x69, 0x72, 0xF0, 0xC5, 0x32, + 0x89, 0xC8, 0xAE, 0xE1, 0x43, 0x29, 0x4B, 0x50, + 0xC6, 0x34, 0x12, 0x58, 0x5C, 0xDC, 0xE4, 0xFF, + 0x7B, 0xED, 0x11, 0x2C, 0xD0, 0x3C, 0x9B, 0x1D, + 0xF3, 0xDE, 0xF0, 0xCC, 0x32, 0x0D, 0x6B, 0x70 + }, + { + 0x23, 0x96, 0xC0, 0xCB, 0x9E, 0xDA, 0xAC, 0xA9, + 0xD8, 0xB1, 0x04, 0x65, 0x2C, 0xB7, 0xF1, 0x25, + 0xF1, 0x93, 0x55, 0x1A, 0xE5, 0xD7, 0xBC, 0x94, + 0x63, 0x30, 0x7C, 0x9E, 0x69, 0xCA, 0x7D, 0xA2, + 0x3A, 0x9F, 0xBC, 0xBC, 0xB8, 0x66, 0x69, 0xD5, + 0xBA, 0x63, 0x43, 0x85, 0x93, 0xE1, 0x32, 0xF9, + 0x92, 0xB5, 0x7C, 0x00, 0x17, 0xC8, 0x6D, 0xDB, + 0x9B, 0x47, 0x28, 0x6E, 0xF5, 0xB6, 0x87, 0x18 + }, + { + 0xA9, 0x4B, 0x80, 0x22, 0x57, 0xFD, 0x03, 0x1E, + 0xE6, 0x0F, 0x1B, 0xE1, 0x84, 0x38, 0x3A, 0x76, + 0x32, 0x85, 0x39, 0xF9, 0xD8, 0x06, 0x08, 0x72, + 0xEF, 0x35, 0x73, 0xBE, 0xB6, 0xF2, 0x73, 0x68, + 0x08, 0x95, 0x90, 0xED, 0xBB, 0x21, 0xF4, 0xD8, + 0xF1, 0x81, 0xBA, 0x66, 0x20, 0x75, 0xF9, 0x19, + 0x05, 0x97, 0x4B, 0xEE, 0xEF, 0x1F, 0xC5, 0xCB, + 0x9B, 0xCF, 0xB2, 0x8A, 0xAE, 0x1E, 0x4D, 0xE3 + }, + { + 0x52, 0xC7, 0xD3, 0x39, 0x9A, 0x03, 0x80, 0x04, + 0xBE, 0xA5, 0x2D, 0x3E, 0xA9, 0xE9, 0x1E, 0x25, + 0x44, 0xC8, 0x65, 0x2A, 0xB8, 0xF5, 0x28, 0x5C, + 0x9D, 0x32, 0x18, 0x63, 0x7A, 0x6D, 0x9F, 0xCA, + 0xF0, 0xD9, 0x65, 0xB3, 0x58, 0x8E, 0xE6, 0xD7, + 0x3F, 0xA5, 0x99, 0xDE, 0xCA, 0x1F, 0x41, 0xDE, + 0xD8, 0x02, 0x5B, 0xF7, 0x76, 0x8E, 0x0E, 0x20, + 0x0E, 0x8C, 0xD3, 0xFF, 0x86, 0x8C, 0x38, 0x00 + }, + { + 0xB6, 0x29, 0xF5, 0x71, 0x62, 0x87, 0x6A, 0xDB, + 0x8F, 0xA9, 0x57, 0x2E, 0xBA, 0x4E, 0x1E, 0xCD, + 0x75, 0xA6, 0x56, 0x73, 0x08, 0xDE, 0x90, 0xDB, + 0xB8, 0xFF, 0xDE, 0x77, 0xDE, 0x82, 0x13, 0xA4, + 0xD7, 0xF7, 0xCB, 0x85, 0xAE, 0x1B, 0x71, 0xE6, + 0x45, 0x7B, 0xC4, 0xE8, 0x9C, 0x0D, 0x9D, 0xE2, + 0x41, 0xB6, 0xB9, 0xF3, 0x74, 0xB7, 0x34, 0x19, + 0x4D, 0xB2, 0xB2, 0x67, 0x02, 0xD7, 0xCB, 0x7C + }, + { + 0x72, 0x28, 0x46, 0xDD, 0xAC, 0xAA, 0x94, 0xFD, + 0xE6, 0x63, 0x2A, 0x2D, 0xC7, 0xDC, 0x70, 0x8B, + 0xDF, 0x98, 0x31, 0x1C, 0x9F, 0xB6, 0x3C, 0x61, + 0xE5, 0x25, 0xFD, 0x4B, 0x0D, 0x87, 0xB6, 0x38, + 0x8B, 0x5A, 0xF7, 0x04, 0x20, 0x18, 0xDD, 0xCA, + 0x06, 0x5E, 0x8A, 0x55, 0xBB, 0xFD, 0x68, 0xEE, + 0x61, 0xFC, 0xD3, 0xC6, 0x87, 0x8F, 0x5B, 0x09, + 0xBC, 0xC2, 0x7B, 0xED, 0x61, 0xDD, 0x93, 0xED + }, + { + 0x1C, 0xED, 0x6A, 0x0C, 0x78, 0x9D, 0xDB, 0x29, + 0x56, 0x78, 0xAD, 0x43, 0xA3, 0x22, 0xD8, 0x96, + 0x61, 0x7F, 0xDE, 0x27, 0x5F, 0x13, 0x8C, 0xCC, + 0xFB, 0x13, 0x26, 0xCD, 0x3F, 0x76, 0x09, 0xC2, + 0xAA, 0xA5, 0xEC, 0x10, 0x26, 0x97, 0x17, 0x3E, + 0x12, 0x1A, 0xE1, 0x63, 0x02, 0x4F, 0x42, 0x8C, + 0x98, 0x28, 0x35, 0xB4, 0xFA, 0x6D, 0xA6, 0xD6, + 0x78, 0xAE, 0xB9, 0xEE, 0x10, 0x6A, 0x3F, 0x6C + }, + { + 0xE8, 0x69, 0x14, 0x8C, 0x05, 0x45, 0xB3, 0x58, + 0x0E, 0x39, 0x5A, 0xFD, 0xC7, 0x45, 0xCD, 0x24, + 0x3B, 0x6B, 0x5F, 0xE3, 0xB6, 0x7E, 0x29, 0x43, + 0xF6, 0xF8, 0xD9, 0xF2, 0x4F, 0xFA, 0x40, 0xE8, + 0x81, 0x75, 0x6E, 0x1C, 0x18, 0xD9, 0x2F, 0x3E, + 0xBE, 0x84, 0x55, 0x9B, 0x57, 0xE2, 0xEE, 0x3A, + 0x65, 0xD9, 0xEC, 0xE0, 0x49, 0x72, 0xB3, 0x5D, + 0x4C, 0x4E, 0xBE, 0x78, 0x6C, 0x88, 0xDA, 0x62 + }, + { + 0xDA, 0xDA, 0x15, 0x5E, 0x55, 0x42, 0x32, 0xB1, + 0x6E, 0xCA, 0xD9, 0x31, 0xCB, 0x42, 0xE3, 0x25, + 0xB5, 0x86, 0xDB, 0xF1, 0xCB, 0xD0, 0xCE, 0x38, + 0x14, 0x45, 0x16, 0x6B, 0xD1, 0xBF, 0xA3, 0x32, + 0x49, 0x85, 0xE7, 0x7C, 0x6F, 0x0D, 0x51, 0x2A, + 0x02, 0x6E, 0x09, 0xD4, 0x86, 0x1C, 0x3B, 0xB8, + 0x52, 0x9D, 0x72, 0x02, 0xEA, 0xC1, 0xC0, 0x44, + 0x27, 0x44, 0xD3, 0x7C, 0x7F, 0x5A, 0xB8, 0xAF + }, + { + 0x2D, 0x14, 0x8C, 0x8E, 0x8F, 0x76, 0xFA, 0xAC, + 0x6F, 0x7F, 0x01, 0xF2, 0x03, 0x9E, 0xA0, 0x2A, + 0x42, 0xD9, 0x32, 0x57, 0x94, 0xC2, 0xC7, 0xA0, + 0x0F, 0x83, 0xF4, 0xA7, 0x79, 0x8A, 0xFB, 0xA9, + 0x93, 0xFF, 0x94, 0x91, 0x1E, 0x09, 0x8B, 0x00, + 0x1A, 0x0B, 0xDF, 0xF4, 0xC8, 0x5A, 0x2A, 0x61, + 0x31, 0xE0, 0xCF, 0xE7, 0x0F, 0x1D, 0x2E, 0x07, + 0xAF, 0x02, 0x09, 0xDA, 0x77, 0x96, 0x09, 0x1F + }, + { + 0x99, 0x98, 0x3A, 0x75, 0x9C, 0xCF, 0x9C, 0xAC, + 0xAE, 0x70, 0x2D, 0xCB, 0xFC, 0xDF, 0x72, 0x04, + 0xDD, 0xF0, 0x33, 0x4B, 0xC6, 0x5D, 0xAD, 0x84, + 0x6F, 0x83, 0x1F, 0x9F, 0x9D, 0x8A, 0x45, 0x3F, + 0x0D, 0x24, 0x93, 0x5C, 0x4C, 0x65, 0x7F, 0xFF, + 0x2E, 0xBB, 0xDB, 0xAF, 0x7B, 0xCE, 0x6A, 0xAC, + 0xDB, 0xB8, 0x87, 0x6F, 0x16, 0x04, 0x59, 0xB1, + 0xA4, 0xAA, 0xC9, 0x56, 0x97, 0xE0, 0x0D, 0x98 + }, + { + 0x7E, 0x4A, 0x02, 0x12, 0x6D, 0x75, 0x52, 0xF4, + 0xC9, 0xB9, 0x4D, 0x80, 0xE3, 0xCF, 0x7B, 0x89, + 0x7E, 0x09, 0x84, 0xE4, 0x06, 0xF0, 0x78, 0x13, + 0x5C, 0xF4, 0x56, 0xC0, 0xD5, 0x1E, 0x13, 0x91, + 0xFF, 0x18, 0xA8, 0x8F, 0x93, 0x12, 0x2C, 0x83, + 0x2C, 0xAC, 0x7D, 0x79, 0x6A, 0x6B, 0x42, 0x51, + 0x9B, 0x1D, 0xB4, 0xEA, 0xD8, 0xF4, 0x98, 0x40, + 0xCE, 0xB5, 0x52, 0x33, 0x6B, 0x29, 0xDE, 0x44 + }, + { + 0xD7, 0xE1, 0x6F, 0xD1, 0x59, 0x65, 0x8A, 0xD7, + 0xEE, 0x25, 0x1E, 0x51, 0x7D, 0xCE, 0x5A, 0x29, + 0xF4, 0x6F, 0xD4, 0xB8, 0xD3, 0x19, 0xDB, 0x80, + 0x5F, 0xC2, 0x5A, 0xA6, 0x20, 0x35, 0x0F, 0xF4, + 0x23, 0xAD, 0x8D, 0x05, 0x37, 0xCD, 0x20, 0x69, + 0x43, 0x2E, 0xBF, 0xF2, 0x92, 0x36, 0xF8, 0xC2, + 0xA8, 0xA0, 0x4D, 0x04, 0xB3, 0xB4, 0x8C, 0x59, + 0xA3, 0x55, 0xFC, 0xC6, 0x2D, 0x27, 0xF8, 0xEE + }, + { + 0x0D, 0x45, 0x17, 0xD4, 0xF1, 0xD0, 0x47, 0x30, + 0xC6, 0x91, 0x69, 0x18, 0xA0, 0x4C, 0x9E, 0x90, + 0xCC, 0xA3, 0xAC, 0x1C, 0x63, 0xD6, 0x45, 0x97, + 0x8A, 0x7F, 0x07, 0x03, 0x9F, 0x92, 0x20, 0x64, + 0x7C, 0x25, 0xC0, 0x4E, 0x85, 0xF6, 0xE2, 0x28, + 0x6D, 0x2E, 0x35, 0x46, 0x0D, 0x0B, 0x2C, 0x1E, + 0x25, 0xAF, 0x9D, 0x35, 0x37, 0xEF, 0x33, 0xFD, + 0x7F, 0xE5, 0x1E, 0x2B, 0xA8, 0x76, 0x4B, 0x36 + }, + { + 0x56, 0xB7, 0x2E, 0x51, 0x37, 0xC6, 0x89, 0xB2, + 0x73, 0x66, 0xFB, 0x22, 0xC7, 0xC6, 0x75, 0x44, + 0xF6, 0xBC, 0xE5, 0x76, 0x19, 0x41, 0x31, 0xC5, + 0xBF, 0xAB, 0x1C, 0xF9, 0x3C, 0x2B, 0x51, 0xAA, + 0xA3, 0x03, 0x36, 0x8A, 0xA8, 0x44, 0xD5, 0x8D, + 0xF0, 0xEE, 0x5D, 0x4E, 0x31, 0x9F, 0xCD, 0x8E, + 0xFF, 0xC6, 0x02, 0xCE, 0xE4, 0x35, 0x1B, 0xD2, + 0xF5, 0x51, 0x43, 0x0B, 0x92, 0x11, 0xE7, 0x3C + }, + { + 0xF3, 0x35, 0xCC, 0x22, 0xFF, 0xEA, 0x5A, 0xA5, + 0x9C, 0xDF, 0xC8, 0xF5, 0x02, 0x89, 0xCC, 0x92, + 0x31, 0x9B, 0x8B, 0x14, 0x40, 0x8D, 0x7A, 0x5A, + 0xA1, 0x23, 0x2A, 0xE2, 0x3A, 0xA1, 0xEA, 0x7F, + 0x77, 0x48, 0xCF, 0xEF, 0x03, 0x20, 0x10, 0xF8, + 0x62, 0x6D, 0x93, 0x18, 0xED, 0xBA, 0x98, 0xD4, + 0x16, 0x62, 0x03, 0x35, 0xC9, 0x01, 0xED, 0x02, + 0xEA, 0xBD, 0x27, 0x6A, 0x1B, 0x82, 0x9C, 0x9D + }, + { + 0xA9, 0x9A, 0x3D, 0x10, 0xF9, 0x5B, 0x44, 0x2F, + 0xFF, 0xF7, 0xC4, 0x18, 0xFA, 0x94, 0x9D, 0x48, + 0x30, 0x86, 0x9B, 0x0E, 0x60, 0xEC, 0x8B, 0x97, + 0x2C, 0x30, 0xA3, 0x16, 0x9C, 0x27, 0xBE, 0xB5, + 0xCF, 0x33, 0x05, 0x94, 0xF0, 0x14, 0xB6, 0x6B, + 0x22, 0x00, 0xA7, 0xF0, 0x86, 0xD2, 0xC2, 0xF3, + 0xF9, 0xFD, 0x85, 0x32, 0xA5, 0x71, 0x88, 0x76, + 0xDF, 0xCA, 0x66, 0x1B, 0xA0, 0xF7, 0xB3, 0x6D + }, + { + 0x15, 0x8E, 0x25, 0x70, 0xD0, 0x84, 0xA4, 0x86, + 0x9D, 0x96, 0x93, 0x43, 0xC0, 0x10, 0x86, 0x07, + 0x17, 0xFF, 0x74, 0x11, 0x61, 0x88, 0x17, 0x5F, + 0x2E, 0xD7, 0x4C, 0xD5, 0x78, 0xFA, 0x0D, 0x80, + 0x91, 0xB0, 0x3F, 0xAD, 0x0C, 0x65, 0xCF, 0x59, + 0xAB, 0x91, 0xDD, 0x73, 0xB3, 0x7F, 0xE3, 0xF5, + 0x8A, 0x58, 0xE7, 0xB4, 0x47, 0x9C, 0x87, 0x5A, + 0xCD, 0x63, 0xEC, 0x52, 0x58, 0x12, 0x35, 0x3F + }, + { + 0x7C, 0x49, 0x50, 0x1C, 0x58, 0x08, 0xB1, 0x5C, + 0x0D, 0x31, 0xBD, 0xD5, 0xBB, 0x56, 0x31, 0xD5, + 0x3A, 0xE0, 0x0D, 0xF4, 0x31, 0x02, 0x5F, 0xEA, + 0x51, 0xEB, 0x47, 0x62, 0x54, 0x4E, 0xFD, 0xEE, + 0x97, 0x8A, 0x83, 0x50, 0x8D, 0xEA, 0x6B, 0xFD, + 0x3B, 0x93, 0x1A, 0x0E, 0x95, 0x83, 0xCC, 0xFC, + 0x04, 0x9E, 0xA8, 0x46, 0x44, 0x70, 0x5D, 0x31, + 0x9F, 0xDC, 0x5C, 0x16, 0x3B, 0xF4, 0x82, 0x24 + }, + { + 0xFE, 0xF4, 0x36, 0xB3, 0x5F, 0x71, 0x7D, 0x59, + 0xAC, 0xA1, 0x7E, 0x9B, 0xF5, 0xFF, 0xDA, 0x28, + 0xF5, 0xF4, 0x01, 0x94, 0x3E, 0xFE, 0x93, 0xEB, + 0x58, 0x0F, 0xFB, 0x98, 0xF1, 0x3B, 0xEA, 0x80, + 0x94, 0x69, 0xA3, 0x44, 0xE7, 0x82, 0xA4, 0x43, + 0xC6, 0x4E, 0xB2, 0x5A, 0xD0, 0x9D, 0x8D, 0xE2, + 0x05, 0xFE, 0xE7, 0xD5, 0x63, 0x96, 0x86, 0xA1, + 0x9E, 0x7C, 0x42, 0xB4, 0x0F, 0x70, 0x6A, 0x08 + }, + { + 0x4D, 0x47, 0xA6, 0x7A, 0x5F, 0x8E, 0x17, 0xB7, + 0x22, 0xDF, 0x98, 0x58, 0xAE, 0xB6, 0x7B, 0x99, + 0x56, 0xB4, 0x59, 0x62, 0xEC, 0x35, 0x3D, 0xC2, + 0xE2, 0x7F, 0x0F, 0x50, 0x1C, 0x39, 0x8E, 0x34, + 0x39, 0x7B, 0xEB, 0xE0, 0x2B, 0x54, 0x92, 0x7E, + 0x2D, 0x31, 0xF1, 0x2E, 0xCF, 0x55, 0xE8, 0x82, + 0x69, 0xFA, 0xB5, 0x37, 0x0E, 0x7F, 0xA5, 0x70, + 0x35, 0x26, 0x6F, 0x89, 0xD5, 0xC2, 0x64, 0x41 + }, + { + 0x1B, 0x58, 0xDC, 0x7A, 0xAC, 0x36, 0x3B, 0x00, + 0x44, 0x6E, 0xA8, 0x03, 0xBC, 0xD7, 0x49, 0xC3, + 0xF5, 0xCA, 0xBE, 0xAA, 0xF2, 0x23, 0x99, 0x4C, + 0x0C, 0x3E, 0xCC, 0x1B, 0x28, 0x47, 0x73, 0x44, + 0xD7, 0xBF, 0x97, 0xC0, 0x8A, 0x95, 0x9D, 0x1A, + 0xC2, 0x06, 0x0B, 0x47, 0x27, 0x89, 0x86, 0x92, + 0x91, 0x88, 0xAD, 0x73, 0xDE, 0x67, 0x07, 0x8B, + 0xA6, 0x80, 0x96, 0x3B, 0x9D, 0x3B, 0x12, 0xA4 + }, + { + 0x3C, 0x52, 0x2C, 0x84, 0x3E, 0x69, 0x74, 0xEC, + 0x75, 0x0D, 0xF2, 0x20, 0xD4, 0x1A, 0x00, 0x4A, + 0xC2, 0xAD, 0xF0, 0x94, 0x56, 0xFA, 0x78, 0x7F, + 0x7C, 0x65, 0x43, 0xAB, 0x17, 0x97, 0x9C, 0x77, + 0x7B, 0x3E, 0x79, 0xD1, 0x78, 0x7D, 0xA5, 0xA8, + 0x3F, 0x17, 0x8D, 0xA9, 0xF0, 0x4C, 0xF6, 0xF5, + 0xB2, 0x55, 0xDD, 0xCB, 0x18, 0x74, 0x84, 0x1B, + 0xBF, 0x70, 0x16, 0xE6, 0x13, 0x2B, 0x99, 0x8A + }, + { + 0x5A, 0x4F, 0xEB, 0x8F, 0x70, 0x75, 0xB4, 0xDC, + 0x9C, 0xA1, 0x6C, 0x6F, 0x05, 0xCD, 0x6B, 0x70, + 0x27, 0x48, 0x5F, 0xFE, 0xD9, 0x15, 0x7D, 0x82, + 0x4D, 0x9D, 0x1A, 0x17, 0x20, 0xEE, 0xEE, 0xEA, + 0x3F, 0x6C, 0x12, 0x5F, 0xDA, 0x4B, 0xA4, 0x40, + 0x9D, 0x79, 0x80, 0x49, 0xFD, 0x18, 0x82, 0xC6, + 0x90, 0x28, 0x8F, 0x33, 0x54, 0x7A, 0x3D, 0x8D, + 0x62, 0x60, 0xB6, 0x54, 0x54, 0x88, 0x53, 0xD7 + }, + { + 0xBC, 0xAA, 0x79, 0x36, 0x32, 0x56, 0x9E, 0x2F, + 0x84, 0x17, 0xCC, 0x60, 0x32, 0x53, 0x53, 0x5B, + 0xD7, 0xD8, 0x5F, 0x38, 0x53, 0x19, 0x92, 0x59, + 0x1E, 0x56, 0xC1, 0xA4, 0xB6, 0xF5, 0x8E, 0xE7, + 0xF8, 0x18, 0xFA, 0xE0, 0x27, 0x88, 0x8A, 0x86, + 0x28, 0x43, 0x05, 0x10, 0x1E, 0xC0, 0x46, 0x61, + 0xF5, 0x99, 0x53, 0x47, 0xA4, 0x67, 0xED, 0x8B, + 0x92, 0x79, 0xF1, 0xAC, 0xC2, 0xB4, 0xBB, 0x1F + }, + { + 0x34, 0xAF, 0x91, 0xCC, 0x22, 0xA6, 0x9B, 0xCB, + 0x55, 0xDD, 0xBF, 0x7F, 0x0F, 0x43, 0xEC, 0x56, + 0x48, 0x40, 0x43, 0x32, 0x13, 0xEA, 0x55, 0xD9, + 0xF8, 0x1A, 0xC4, 0x75, 0x20, 0x8D, 0x74, 0x85, + 0x1D, 0xB7, 0x0F, 0xE4, 0x96, 0xAF, 0x9D, 0xA1, + 0xD3, 0x93, 0xEC, 0xF8, 0x78, 0x69, 0x5D, 0xD3, + 0x3F, 0xD5, 0x43, 0x49, 0xA6, 0xF8, 0x24, 0xAE, + 0xED, 0x18, 0x3C, 0xB1, 0xB0, 0x8C, 0x54, 0x85 + }, + { + 0xB8, 0xB7, 0xAD, 0x2E, 0xA2, 0xB6, 0xFA, 0x06, + 0xD0, 0x0B, 0xCD, 0x59, 0x9C, 0x99, 0x71, 0xC5, + 0xB4, 0xE1, 0x65, 0x58, 0xE1, 0x52, 0x12, 0xC9, + 0xBF, 0xD3, 0x73, 0xE4, 0xBC, 0x79, 0x17, 0x05, + 0x26, 0x01, 0xFF, 0xDB, 0x68, 0x01, 0xBE, 0x80, + 0xBA, 0x50, 0x9D, 0xB8, 0x2A, 0x0B, 0x71, 0x95, + 0x92, 0x91, 0x33, 0xAD, 0x53, 0x99, 0x56, 0x06, + 0x52, 0x33, 0xF4, 0x9D, 0x07, 0x1C, 0x84, 0xE4 + }, + { + 0xDC, 0xEE, 0x9C, 0x45, 0xBC, 0x5D, 0x1F, 0xE6, + 0x30, 0xB1, 0x8B, 0x06, 0x3C, 0xE8, 0x2C, 0x38, + 0x57, 0xE3, 0x0D, 0x20, 0xC6, 0x4B, 0x5C, 0xC2, + 0x58, 0x84, 0x94, 0x3E, 0x7A, 0xE9, 0x4E, 0xDF, + 0xF8, 0x50, 0xEB, 0x0E, 0x82, 0x44, 0x02, 0x3D, + 0x3D, 0x07, 0xA8, 0xA0, 0x07, 0x06, 0xF0, 0x58, + 0x2C, 0xC1, 0x02, 0xB6, 0x6C, 0x6D, 0xDA, 0x86, + 0xE8, 0xF2, 0xDF, 0x32, 0x56, 0x59, 0x88, 0x6F + }, + { + 0x04, 0xF6, 0xE8, 0x22, 0xF1, 0x7C, 0xC7, 0xA5, + 0x94, 0x6D, 0xF8, 0x0D, 0x95, 0x8A, 0xEF, 0x06, + 0x5D, 0x87, 0x49, 0x16, 0xE1, 0x03, 0xA6, 0x83, + 0x0C, 0x6E, 0x46, 0xB6, 0x05, 0x59, 0x18, 0x18, + 0x0D, 0x14, 0x52, 0x29, 0x3C, 0x58, 0xA9, 0x74, + 0x9C, 0xBC, 0x8F, 0x0A, 0xC4, 0x08, 0xA9, 0xCA, + 0x89, 0x57, 0x61, 0xCF, 0xC4, 0x51, 0x16, 0x46, + 0x41, 0xA1, 0x79, 0xFB, 0x5C, 0xD8, 0xFE, 0xBC + }, + { + 0x51, 0x1F, 0xDB, 0x7C, 0x88, 0x26, 0x85, 0x35, + 0xE9, 0x7E, 0x4E, 0xD8, 0x92, 0xF3, 0xC0, 0x65, + 0x83, 0x2B, 0x26, 0x59, 0x14, 0xFC, 0x61, 0x07, + 0xA1, 0xD2, 0x7D, 0xBB, 0x7D, 0x51, 0xC3, 0x7E, + 0x95, 0x98, 0x15, 0x06, 0xC1, 0x14, 0x72, 0x44, + 0xD5, 0xBA, 0xE9, 0x0E, 0xE9, 0x0D, 0x08, 0x49, + 0x84, 0xBA, 0xA7, 0x58, 0x7F, 0x41, 0xFF, 0x6F, + 0x4B, 0xA7, 0x22, 0xC8, 0xB9, 0x2A, 0xEB, 0x99 + }, + { + 0x2B, 0xA2, 0xBD, 0x17, 0xE9, 0x26, 0x27, 0x5B, + 0x06, 0x83, 0xB2, 0x36, 0xBF, 0xE3, 0x76, 0x30, + 0x26, 0x6E, 0x37, 0xF4, 0x18, 0x2F, 0x53, 0xA9, + 0x82, 0x34, 0xE9, 0x15, 0xAB, 0x64, 0xC9, 0x59, + 0x96, 0xC6, 0xCB, 0x7A, 0xE8, 0x80, 0xC3, 0xDF, + 0xCB, 0x47, 0xD0, 0x5A, 0xAD, 0xD2, 0x1A, 0xBF, + 0x8E, 0x40, 0xB7, 0x3F, 0x40, 0xF3, 0x98, 0xDC, + 0x5B, 0x02, 0x14, 0x14, 0x57, 0x45, 0x6A, 0x09 + }, + { + 0x9B, 0x66, 0x8D, 0x9B, 0x44, 0x47, 0xE3, 0x76, + 0xF6, 0xC6, 0xCF, 0xA6, 0x8D, 0xBC, 0x79, 0x19, + 0x83, 0x81, 0xAB, 0x60, 0x5F, 0x55, 0xD5, 0xA7, + 0xEF, 0x68, 0x3B, 0xCE, 0xD4, 0x6F, 0x9A, 0xFD, + 0x36, 0x85, 0x41, 0x1A, 0x66, 0xE2, 0x34, 0x6F, + 0x96, 0x07, 0x77, 0xD0, 0xC9, 0x22, 0x71, 0x24, + 0x30, 0xE0, 0x18, 0xBF, 0xAE, 0x86, 0x53, 0x01, + 0x7E, 0xA2, 0x0E, 0xCD, 0x5F, 0x1F, 0x95, 0x6C + }, + { + 0x56, 0x81, 0x02, 0x4F, 0x53, 0x85, 0x88, 0xA0, + 0x1B, 0x2C, 0x83, 0x94, 0xCA, 0xE8, 0x73, 0xC6, + 0xD8, 0x5D, 0x6A, 0xA0, 0x6E, 0xDD, 0xB3, 0xA5, + 0x02, 0x09, 0x6F, 0xC0, 0x82, 0xBB, 0x89, 0xCB, + 0x24, 0x15, 0x31, 0xB3, 0x15, 0x75, 0x0D, 0x31, + 0xBB, 0x0B, 0x63, 0x01, 0x28, 0xD1, 0x9D, 0x11, + 0x39, 0x2B, 0xCF, 0x4B, 0x34, 0x78, 0xD5, 0x23, + 0xD7, 0xD2, 0x13, 0xE4, 0x75, 0x0F, 0x55, 0x92 + }, + { + 0x2A, 0xA9, 0x1B, 0xA6, 0xDE, 0x60, 0x17, 0xF1, + 0x93, 0x0F, 0xC7, 0xD9, 0x6D, 0xCC, 0xD6, 0x70, + 0x74, 0x8B, 0x7E, 0xB1, 0xD0, 0x94, 0xDF, 0xB4, + 0xB3, 0xB1, 0x47, 0x8A, 0x61, 0x2E, 0xBF, 0x03, + 0xDD, 0xD7, 0x21, 0x27, 0x9A, 0x26, 0x6D, 0xE3, + 0x88, 0x45, 0xE6, 0x12, 0xC9, 0x30, 0x98, 0xC2, + 0xEF, 0xFF, 0x34, 0xFE, 0x50, 0x06, 0x17, 0x20, + 0x5B, 0x1D, 0xE2, 0xFE, 0xA1, 0xD8, 0x02, 0x46 + }, + { + 0x82, 0x4D, 0x89, 0xC0, 0x63, 0x7C, 0xE1, 0x78, + 0xB6, 0x30, 0x68, 0x4C, 0x72, 0x9E, 0x26, 0x65, + 0x3F, 0x34, 0xEA, 0xC7, 0xE9, 0x04, 0x12, 0xE9, + 0x63, 0xD3, 0xF1, 0x9D, 0x64, 0x51, 0xE8, 0x25, + 0x85, 0x21, 0x67, 0xC4, 0x8D, 0xF7, 0xCC, 0x55, + 0xB2, 0x57, 0xB2, 0x50, 0xA7, 0x0C, 0x7B, 0xCC, + 0xFA, 0x9A, 0xA1, 0x5C, 0x18, 0x8A, 0xC4, 0x63, + 0x7A, 0x52, 0x22, 0x89, 0xC0, 0x87, 0x6A, 0xD4 + }, + { + 0x87, 0xE4, 0xAE, 0x11, 0xDA, 0x1A, 0x2C, 0xA8, + 0x82, 0x2A, 0xE3, 0x30, 0xDC, 0x97, 0xAB, 0x2E, + 0x47, 0xFF, 0x62, 0x32, 0x30, 0x93, 0xC2, 0xB7, + 0xA6, 0xC0, 0xE2, 0xC1, 0x68, 0x21, 0xCD, 0x7C, + 0xEC, 0x92, 0x18, 0x4D, 0xF4, 0xBB, 0x6E, 0x2B, + 0x62, 0x6A, 0x44, 0x78, 0x03, 0x90, 0x63, 0xAF, + 0xEE, 0xB0, 0xD2, 0x87, 0xF2, 0x42, 0x19, 0x20, + 0x78, 0x98, 0xCC, 0xE7, 0xAD, 0xE0, 0x63, 0x9C + }, + { + 0xDD, 0x7F, 0x2F, 0x44, 0xA4, 0x02, 0xA0, 0x1E, + 0x82, 0x16, 0xB1, 0x03, 0xA4, 0xE7, 0x23, 0x5C, + 0x28, 0x30, 0x31, 0x9D, 0x56, 0xAF, 0x63, 0x9F, + 0x23, 0xC4, 0x8C, 0x27, 0x59, 0xAB, 0xA6, 0xEB, + 0x5E, 0xEE, 0xE3, 0x8C, 0x29, 0x8E, 0xBE, 0x41, + 0x98, 0x26, 0x7A, 0x00, 0xEB, 0x2A, 0x08, 0xD9, + 0x3A, 0x50, 0x37, 0x03, 0x17, 0x1C, 0x77, 0x33, + 0x38, 0x62, 0x10, 0x10, 0x55, 0xBD, 0x7A, 0xD2 + }, + { + 0x4C, 0xB8, 0x46, 0x59, 0x61, 0x93, 0xF7, 0xF2, + 0x78, 0xAA, 0xAA, 0xC5, 0xCC, 0xFF, 0xD5, 0x35, + 0x7A, 0xB0, 0xD1, 0x24, 0x5F, 0x69, 0x79, 0xD1, + 0x41, 0xA4, 0x71, 0xBD, 0xAB, 0x55, 0xE2, 0x38, + 0xB1, 0xAE, 0xD6, 0x7B, 0x73, 0x39, 0x95, 0x04, + 0xB9, 0x7D, 0xF1, 0xA2, 0x5E, 0xB6, 0xFE, 0x27, + 0x2B, 0x5C, 0xD4, 0x96, 0xA7, 0xC8, 0xA0, 0x60, + 0x92, 0x6E, 0x74, 0x04, 0xFD, 0xA0, 0x79, 0x0D + }, + { + 0x6F, 0x44, 0xEC, 0xDA, 0xE1, 0x4E, 0x3B, 0x81, + 0xA1, 0x91, 0x22, 0x03, 0x01, 0x5F, 0x59, 0x18, + 0xEA, 0xC6, 0xFB, 0xF4, 0x96, 0x60, 0x10, 0xF4, + 0x9D, 0x2B, 0xC2, 0xBC, 0xEF, 0xE7, 0xB1, 0xDF, + 0xEC, 0x5C, 0x83, 0x5D, 0x7D, 0x87, 0xA4, 0x43, + 0x71, 0xF1, 0x5A, 0x6C, 0x08, 0x42, 0x52, 0xB9, + 0x34, 0x65, 0x26, 0x42, 0x72, 0xA4, 0x10, 0xD5, + 0x0F, 0x89, 0xA1, 0x17, 0xF3, 0x1A, 0xF4, 0x63 + }, + { + 0x1F, 0x70, 0x5F, 0x6E, 0x9F, 0x07, 0x0D, 0x87, + 0xFD, 0xE8, 0xE2, 0x77, 0x46, 0x74, 0xFA, 0x9B, + 0xF1, 0x20, 0xD2, 0x88, 0xEB, 0x0B, 0xE7, 0xAA, + 0x12, 0x8D, 0xFB, 0x5D, 0x10, 0x11, 0xCE, 0x1F, + 0xDA, 0x99, 0xB2, 0x55, 0x22, 0x66, 0x65, 0xD8, + 0x3F, 0x63, 0x4E, 0x8F, 0xCA, 0xBD, 0xA9, 0xA2, + 0x3C, 0x03, 0x51, 0x5E, 0x9C, 0xFE, 0xCE, 0x6E, + 0x94, 0xA8, 0xEC, 0x92, 0xE4, 0xED, 0xEC, 0xB7 + }, + { + 0x2D, 0x96, 0xC5, 0xB0, 0x15, 0x74, 0x72, 0x2B, + 0x81, 0x7F, 0xEB, 0x48, 0x6C, 0x5F, 0xC9, 0x8F, + 0x5F, 0x84, 0x61, 0xF4, 0xCE, 0xE9, 0x90, 0x5A, + 0xF2, 0x06, 0xD4, 0x72, 0x33, 0x86, 0xD1, 0xC4, + 0xC7, 0xCA, 0xC5, 0x84, 0x00, 0x28, 0xD7, 0xAF, + 0xED, 0x0E, 0x38, 0xAD, 0x13, 0x96, 0x28, 0xEB, + 0x6A, 0xF9, 0x2B, 0x4B, 0x88, 0xEB, 0xF0, 0x9B, + 0x1F, 0xA0, 0x47, 0xFB, 0xE1, 0x0B, 0xC3, 0x1D + }, + { + 0x65, 0xDA, 0x78, 0x0A, 0x0A, 0x37, 0x47, 0x9D, + 0xD8, 0xF4, 0xD6, 0x55, 0x64, 0xF9, 0xA7, 0x08, + 0x9E, 0x42, 0x07, 0xEB, 0x16, 0xAC, 0xA3, 0xF6, + 0x55, 0x31, 0xCF, 0xEE, 0x76, 0x25, 0xBA, 0x13, + 0x80, 0xA4, 0x97, 0xB6, 0x24, 0x72, 0xFC, 0x7E, + 0x00, 0x07, 0xA6, 0xB0, 0x35, 0x61, 0x04, 0x16, + 0xA5, 0xF8, 0x2C, 0x10, 0x82, 0xFA, 0x06, 0x5C, + 0x46, 0xDD, 0xEE, 0x49, 0x40, 0xD1, 0xFC, 0x46 + }, + { + 0x1C, 0x09, 0xA3, 0xB3, 0x80, 0xB8, 0xA7, 0xFC, + 0x33, 0x3F, 0xD2, 0x71, 0x4D, 0xF7, 0x12, 0x9B, + 0x44, 0xA4, 0x67, 0x68, 0xBA, 0xCF, 0x0A, 0x67, + 0xA3, 0x8A, 0x47, 0xB3, 0xAB, 0x31, 0xF5, 0x1B, + 0x05, 0x33, 0xC2, 0xAA, 0x2B, 0x4B, 0x7B, 0xBB, + 0x6A, 0xE5, 0xED, 0xF3, 0xDC, 0xB0, 0xEC, 0xC1, + 0xA2, 0x83, 0xE8, 0x43, 0xF2, 0x90, 0x7B, 0x34, + 0x1F, 0x17, 0x9A, 0xFD, 0x8B, 0x67, 0xDA, 0x90 + }, + { + 0x67, 0x88, 0x8B, 0x83, 0xFA, 0xAF, 0xBB, 0x62, + 0x29, 0x34, 0xB8, 0xD5, 0x59, 0x63, 0xE1, 0x86, + 0x15, 0x3E, 0x59, 0x51, 0x88, 0x7C, 0x7F, 0x4A, + 0x76, 0x35, 0xC7, 0x98, 0xD9, 0xA5, 0x82, 0x94, + 0xBE, 0x26, 0xA3, 0xC5, 0x49, 0xC9, 0xFD, 0x59, + 0x86, 0xAB, 0xD1, 0x9F, 0x40, 0x1E, 0xE2, 0x4E, + 0xDA, 0x36, 0x02, 0x04, 0x2A, 0xD3, 0x83, 0x35, + 0x7A, 0x31, 0x7D, 0x38, 0x07, 0x3B, 0x38, 0xCE + }, + { + 0xB4, 0xF7, 0x99, 0x63, 0xCA, 0x31, 0xBB, 0x62, + 0x26, 0x5D, 0xD9, 0x29, 0xAF, 0x7D, 0x51, 0x27, + 0x2F, 0xA6, 0x63, 0x1D, 0xE7, 0xFA, 0x35, 0xF7, + 0xA6, 0xB0, 0x3F, 0x9F, 0xCF, 0xDB, 0x8E, 0x3B, + 0x5B, 0xAC, 0xE3, 0x35, 0x91, 0xB7, 0xEC, 0x2C, + 0xFA, 0xB4, 0x9C, 0x91, 0xA6, 0xDB, 0x1F, 0xF8, + 0xF6, 0x78, 0x6D, 0x08, 0xF4, 0x4E, 0x80, 0x62, + 0xD2, 0xFF, 0x69, 0x6A, 0x7D, 0x98, 0x41, 0x42 + }, + { + 0x40, 0x84, 0x83, 0x69, 0x7B, 0xB6, 0xF9, 0xD0, + 0x11, 0xA1, 0xF2, 0x9A, 0x23, 0xC2, 0x78, 0xA8, + 0x1D, 0x37, 0x57, 0x8D, 0xCC, 0xCF, 0x42, 0x3B, + 0xDF, 0x48, 0x93, 0x37, 0xF1, 0x82, 0xEA, 0xB7, + 0x9A, 0x50, 0xB0, 0x5F, 0x3D, 0x2C, 0xCC, 0x49, + 0x13, 0x37, 0xC7, 0xE4, 0x1F, 0x30, 0x79, 0x3B, + 0xD2, 0x7D, 0x76, 0x61, 0xC2, 0xE3, 0x04, 0xC9, + 0x46, 0xA5, 0xA4, 0x01, 0xAF, 0x8D, 0x94, 0x6F + }, + { + 0xEE, 0xB5, 0xAD, 0xE1, 0xAB, 0x97, 0xE7, 0x15, + 0x43, 0x43, 0xA4, 0x6E, 0xB4, 0xCD, 0xD2, 0xA7, + 0x73, 0xF3, 0x63, 0x01, 0xED, 0xC6, 0xA1, 0xBC, + 0x1D, 0xD6, 0x48, 0x0E, 0x08, 0xF5, 0x87, 0x65, + 0xCB, 0x93, 0x87, 0x82, 0x92, 0x3B, 0xC0, 0x1F, + 0x8E, 0x0C, 0x61, 0xC6, 0xBE, 0x0D, 0xD1, 0xAB, + 0x4C, 0x18, 0xCB, 0x15, 0xED, 0x52, 0x10, 0x11, + 0x24, 0x05, 0xF1, 0xEA, 0x8F, 0x2E, 0x8C, 0x4E + }, + { + 0x71, 0x4A, 0xD1, 0x85, 0xF1, 0xEE, 0xC4, 0x3F, + 0x46, 0xB6, 0x7E, 0x99, 0x2D, 0x2D, 0x38, 0xBC, + 0x31, 0x49, 0xE3, 0x7D, 0xA7, 0xB4, 0x47, 0x48, + 0xD4, 0xD1, 0x4C, 0x16, 0x1E, 0x08, 0x78, 0x02, + 0x04, 0x42, 0x14, 0x95, 0x79, 0xA8, 0x65, 0xD8, + 0x04, 0xB0, 0x49, 0xCD, 0x01, 0x55, 0xBA, 0x98, + 0x33, 0x78, 0x75, 0x7A, 0x13, 0x88, 0x30, 0x1B, + 0xDC, 0x0F, 0xAE, 0x2C, 0xEA, 0xEA, 0x07, 0xDD + }, + { + 0x22, 0xB8, 0x24, 0x9E, 0xAF, 0x72, 0x29, 0x64, + 0xCE, 0x42, 0x4F, 0x71, 0xA7, 0x4D, 0x03, 0x8F, + 0xF9, 0xB6, 0x15, 0xFB, 0xA5, 0xC7, 0xC2, 0x2C, + 0xB6, 0x27, 0x97, 0xF5, 0x39, 0x82, 0x24, 0xC3, + 0xF0, 0x72, 0xEB, 0xC1, 0xDA, 0xCB, 0xA3, 0x2F, + 0xC6, 0xF6, 0x63, 0x60, 0xB3, 0xE1, 0x65, 0x8D, + 0x0F, 0xA0, 0xDA, 0x1E, 0xD1, 0xC1, 0xDA, 0x66, + 0x2A, 0x20, 0x37, 0xDA, 0x82, 0x3A, 0x33, 0x83 + }, + { + 0xB8, 0xE9, 0x03, 0xE6, 0x91, 0xB9, 0x92, 0x78, + 0x25, 0x28, 0xF8, 0xDB, 0x96, 0x4D, 0x08, 0xE3, + 0xBA, 0xAF, 0xBD, 0x08, 0xBA, 0x60, 0xC7, 0x2A, + 0xEC, 0x0C, 0x28, 0xEC, 0x6B, 0xFE, 0xCA, 0x4B, + 0x2E, 0xC4, 0xC4, 0x6F, 0x22, 0xBF, 0x62, 0x1A, + 0x5D, 0x74, 0xF7, 0x5C, 0x0D, 0x29, 0x69, 0x3E, + 0x56, 0xC5, 0xC5, 0x84, 0xF4, 0x39, 0x9E, 0x94, + 0x2F, 0x3B, 0xD8, 0xD3, 0x86, 0x13, 0xE6, 0x39 + }, + { + 0xD5, 0xB4, 0x66, 0xFF, 0x1F, 0xD6, 0x8C, 0xFA, + 0x8E, 0xDF, 0x0B, 0x68, 0x02, 0x44, 0x8F, 0x30, + 0x2D, 0xCC, 0xDA, 0xF5, 0x66, 0x28, 0x78, 0x6B, + 0x9D, 0xA0, 0xF6, 0x62, 0xFD, 0xA6, 0x90, 0x26, + 0x6B, 0xD4, 0x0A, 0xB6, 0xF0, 0xBE, 0xC0, 0x43, + 0xF1, 0x01, 0x28, 0xB3, 0x3D, 0x05, 0xDB, 0x82, + 0xD4, 0xAB, 0x26, 0x8A, 0x4F, 0x91, 0xAC, 0x42, + 0x86, 0x79, 0x5F, 0xC0, 0xF7, 0xCB, 0x48, 0x5C + }, + { + 0x0A, 0x1E, 0x8C, 0x0A, 0x8C, 0x48, 0xB8, 0x4B, + 0x71, 0xBA, 0x0F, 0xE5, 0x6F, 0xA0, 0x56, 0x09, + 0x8C, 0xA6, 0x92, 0xE9, 0x2F, 0x27, 0x6E, 0x85, + 0xB3, 0x38, 0x26, 0xCD, 0x78, 0x75, 0xFC, 0xF8, + 0x83, 0x85, 0x13, 0x1B, 0x43, 0xDF, 0x74, 0x53, + 0x2E, 0xAA, 0x86, 0xCF, 0x17, 0x1F, 0x50, 0x76, + 0xE6, 0xD1, 0x7B, 0x1C, 0x75, 0xFB, 0xA1, 0xDB, + 0x00, 0x1B, 0x6E, 0x66, 0x97, 0x7C, 0xB8, 0xD7 + }, + { + 0x65, 0xAA, 0x17, 0x99, 0x14, 0x36, 0x93, 0xAB, + 0xD9, 0xCB, 0x21, 0x8D, 0x9B, 0x5E, 0xC6, 0x0C, + 0x0E, 0xDD, 0xB0, 0x67, 0xE6, 0xA3, 0x2F, 0x76, + 0x79, 0x60, 0x10, 0xAC, 0xB1, 0x1A, 0xD0, 0x13, + 0x6C, 0xE4, 0x9F, 0x97, 0x6E, 0x74, 0xF8, 0x95, + 0x04, 0x2F, 0x7C, 0xBF, 0x13, 0xFB, 0x73, 0xD1, + 0x9D, 0xC8, 0x89, 0xD7, 0xE9, 0x03, 0x46, 0x9D, + 0xEB, 0x33, 0x73, 0x1F, 0x24, 0x06, 0xB6, 0x63 + }, + { + 0xDE, 0xB7, 0x12, 0xB9, 0xCC, 0x64, 0xF5, 0x88, + 0x14, 0x86, 0x0B, 0x51, 0xFA, 0x89, 0xAD, 0x8A, + 0x92, 0x6A, 0x69, 0x08, 0xC7, 0x96, 0xDE, 0x55, + 0x7F, 0x90, 0xCF, 0xAD, 0xB0, 0xC6, 0x2C, 0x07, + 0x87, 0x2F, 0x33, 0xFE, 0x18, 0x4E, 0x5E, 0x21, + 0x2A, 0x3C, 0x5C, 0x37, 0x31, 0x74, 0x18, 0x44, + 0x6E, 0xFD, 0x95, 0x61, 0x3F, 0x61, 0x8A, 0x35, + 0xF7, 0xD2, 0x78, 0x9E, 0xFE, 0x0D, 0x96, 0x60 + }, + { + 0xB4, 0x2F, 0x4A, 0x40, 0xB3, 0xC8, 0x8B, 0xCE, + 0xCF, 0xE3, 0x28, 0xC8, 0x46, 0xBF, 0x06, 0x48, + 0xA1, 0x69, 0x90, 0xCA, 0x53, 0x91, 0x95, 0xC0, + 0xC1, 0xDC, 0x8D, 0x70, 0x30, 0x80, 0x67, 0x68, + 0x5A, 0xF6, 0x77, 0xAD, 0x65, 0xAC, 0x0C, 0x7A, + 0x9B, 0xCF, 0xA8, 0xF7, 0xAC, 0xC0, 0xAA, 0xCF, + 0x45, 0xCA, 0x18, 0xAC, 0x83, 0x1F, 0xED, 0x64, + 0x4E, 0xC3, 0xD9, 0x28, 0x31, 0x01, 0xFF, 0xEF + }, + { + 0xED, 0xCF, 0x6C, 0x81, 0xCC, 0xF1, 0x6E, 0x11, + 0xDD, 0xF7, 0x19, 0xA3, 0x3D, 0xD0, 0xE5, 0x34, + 0x9C, 0xAB, 0xAC, 0x5C, 0xFA, 0xE5, 0x97, 0x00, + 0x98, 0x40, 0xE1, 0xC3, 0x93, 0x62, 0xC0, 0xF1, + 0x19, 0x82, 0xFE, 0x2C, 0x27, 0x65, 0x85, 0x9A, + 0x94, 0x26, 0x2D, 0xA2, 0x8D, 0xD3, 0x37, 0x3D, + 0x52, 0x26, 0x93, 0x89, 0x75, 0x11, 0xEB, 0xA5, + 0xE0, 0x7B, 0x8B, 0xC6, 0xB6, 0x06, 0x4D, 0xC0 + }, + { + 0x46, 0xB9, 0x62, 0xD2, 0x28, 0x36, 0x94, 0xD2, + 0x79, 0x75, 0xDC, 0xBF, 0x32, 0x56, 0x4C, 0x9B, + 0x04, 0x03, 0x2B, 0x30, 0xA9, 0x3E, 0x05, 0x8F, + 0xB7, 0x7B, 0x2B, 0x71, 0x8B, 0x4A, 0xD5, 0xFB, + 0x78, 0x9A, 0xB7, 0xD7, 0xAA, 0x90, 0x85, 0x2D, + 0xA2, 0xBF, 0xB6, 0xB3, 0x93, 0xB0, 0x9F, 0x98, + 0xE8, 0x69, 0xB1, 0x6E, 0x41, 0x0E, 0x7D, 0xE2, + 0x30, 0xB1, 0x79, 0xF6, 0x2E, 0xB5, 0x74, 0x71 + }, + { + 0x29, 0x03, 0x6C, 0x3F, 0x53, 0x82, 0xE3, 0x5D, + 0xE7, 0xA6, 0x9F, 0xA7, 0xA6, 0x3E, 0xC7, 0xBD, + 0xCB, 0xC4, 0xE0, 0xCC, 0x5A, 0x7B, 0x64, 0x14, + 0xCF, 0x44, 0xBF, 0x9A, 0x83, 0x83, 0xEF, 0xB5, + 0x97, 0x23, 0x50, 0x6F, 0x0D, 0x51, 0xAD, 0x50, + 0xAC, 0x1E, 0xAC, 0xF7, 0x04, 0x30, 0x8E, 0x8A, + 0xEC, 0xB9, 0x66, 0xF6, 0xAC, 0x94, 0x1D, 0xB1, + 0xCD, 0xE4, 0xB5, 0x9E, 0x84, 0xC1, 0xEB, 0xBA + }, + { + 0x17, 0x3F, 0x8A, 0xB8, 0x93, 0x3E, 0xB0, 0x7C, + 0xC5, 0xFD, 0x6E, 0x4B, 0xCE, 0xBA, 0xE1, 0xFF, + 0x35, 0xC7, 0x87, 0x9B, 0x93, 0x8A, 0x5A, 0x15, + 0x79, 0xEA, 0x02, 0xF3, 0x83, 0x32, 0x48, 0x86, + 0xC7, 0x0E, 0xD9, 0x10, 0x9D, 0xE1, 0x69, 0x0B, + 0x8E, 0xE8, 0x01, 0xBC, 0x95, 0x9B, 0x21, 0xD3, + 0x81, 0x17, 0xEB, 0xB8, 0x4A, 0xB5, 0x6F, 0x88, + 0xF8, 0xA3, 0x72, 0x62, 0x00, 0x2D, 0xD9, 0x8E + }, + { + 0xC6, 0xAF, 0xA6, 0xA1, 0x91, 0x93, 0x1F, 0xD4, + 0x5C, 0x3B, 0xAD, 0xBA, 0x72, 0x6E, 0x68, 0xA9, + 0xBC, 0x73, 0x88, 0xC8, 0xCF, 0x37, 0xAD, 0xEC, + 0x7C, 0x64, 0x56, 0x1C, 0xF4, 0x81, 0xFD, 0x25, + 0x9A, 0x64, 0x6C, 0x8B, 0xD8, 0x43, 0xE7, 0x70, + 0x9E, 0x11, 0xE6, 0x4D, 0xCF, 0xD5, 0xDF, 0xFF, + 0xED, 0x79, 0x23, 0x5C, 0x68, 0x9B, 0x42, 0x00, + 0xFE, 0x7A, 0xC8, 0xDF, 0xDA, 0xDD, 0xEC, 0xE0 + }, + { + 0xA6, 0xDC, 0xCD, 0x8C, 0x19, 0x26, 0x64, 0x88, + 0xBF, 0x77, 0xB9, 0xF2, 0x4B, 0x91, 0x43, 0xDE, + 0xF1, 0xFE, 0xD6, 0x1D, 0x0C, 0x60, 0xB5, 0x00, + 0x0A, 0x52, 0x3F, 0x45, 0x0D, 0xA2, 0x3D, 0x74, + 0xE4, 0xE3, 0xF6, 0xEF, 0x04, 0x09, 0x0D, 0x10, + 0x66, 0xB6, 0xAC, 0xE8, 0x5A, 0xBC, 0x0F, 0x03, + 0x01, 0x73, 0xF5, 0x28, 0x17, 0x72, 0x7C, 0x4E, + 0x40, 0x43, 0x2D, 0xD3, 0x4C, 0x6E, 0xF9, 0xF0 + }, + { + 0xAA, 0xF8, 0x90, 0x8D, 0x54, 0x6E, 0x4F, 0x1E, + 0x31, 0x4C, 0x00, 0xE9, 0xD2, 0xE8, 0x85, 0x5C, + 0xB2, 0x56, 0x44, 0x5A, 0xAE, 0x3E, 0xCA, 0x44, + 0x23, 0x83, 0x22, 0xAE, 0xC7, 0x40, 0x34, 0xA1, + 0x45, 0x8A, 0x29, 0x36, 0x75, 0xDA, 0xD9, 0x49, + 0x40, 0x8D, 0xE5, 0x55, 0x4F, 0x22, 0xD7, 0x34, + 0x54, 0xF3, 0xF0, 0x70, 0x9C, 0xBC, 0xCC, 0x85, + 0xCB, 0x05, 0x3A, 0x6F, 0x50, 0x38, 0x91, 0xA1 + }, + { + 0x52, 0x5F, 0x4A, 0xAB, 0x9C, 0x32, 0x7D, 0x2A, + 0x6A, 0x3C, 0x9D, 0xF8, 0x1F, 0xB7, 0xBE, 0x97, + 0xEE, 0x03, 0xE3, 0xF7, 0xCE, 0x33, 0x21, 0x1C, + 0x47, 0x78, 0x8A, 0xCD, 0x13, 0x46, 0x40, 0xDD, + 0x90, 0xAD, 0x74, 0x99, 0x2D, 0x3D, 0xD6, 0xAC, + 0x80, 0x63, 0x50, 0xF3, 0xBA, 0xBC, 0x7F, 0xE1, + 0x98, 0xA6, 0x1D, 0xB3, 0x2D, 0x4A, 0xD1, 0xD6, + 0x56, 0x9A, 0xE8, 0x41, 0x31, 0x04, 0xDE, 0xA4 + }, + { + 0x2D, 0xAC, 0xCD, 0x88, 0x71, 0x9D, 0x0A, 0x00, + 0xB5, 0x2C, 0x6E, 0xB7, 0x9E, 0x1C, 0xA8, 0xB4, + 0xA1, 0xB4, 0xB4, 0x4F, 0xFA, 0x20, 0x88, 0x9F, + 0x23, 0x63, 0xEF, 0x5C, 0x0D, 0x73, 0x7F, 0x1F, + 0x81, 0xF5, 0x0D, 0xA1, 0xCA, 0xAC, 0x23, 0x1D, + 0x6F, 0xCB, 0x48, 0x89, 0x5E, 0x72, 0x99, 0xB7, + 0x7A, 0xF8, 0x1F, 0x0A, 0xA4, 0xA7, 0x61, 0x8A, + 0xD2, 0x4B, 0x7A, 0xAF, 0xC8, 0xE3, 0xA2, 0xBE + }, + { + 0x7D, 0x28, 0x6F, 0x1F, 0x72, 0x1E, 0xC2, 0xD2, + 0x11, 0x5E, 0xF4, 0xCC, 0xD8, 0x28, 0x58, 0xA4, + 0xD5, 0x12, 0x21, 0x13, 0x55, 0xD4, 0xFC, 0x58, + 0xE5, 0x34, 0xBF, 0xA5, 0x9C, 0x2E, 0x1B, 0xF5, + 0x52, 0xA9, 0x6D, 0xC4, 0xB3, 0xE4, 0x6B, 0x01, + 0x28, 0x65, 0xDA, 0x88, 0x13, 0x4C, 0xF0, 0x4E, + 0x73, 0x1B, 0x19, 0x30, 0x75, 0x9E, 0x15, 0x8F, + 0xF6, 0x20, 0xB6, 0xEC, 0x5A, 0xAF, 0xD0, 0x12 + }, + { + 0x21, 0x82, 0x6B, 0x95, 0x29, 0xC4, 0xBC, 0x51, + 0x91, 0x47, 0xF5, 0xF9, 0xFE, 0x6D, 0xB8, 0x78, + 0x34, 0x52, 0x15, 0xE5, 0x09, 0x4F, 0x4E, 0x99, + 0xB1, 0x31, 0xED, 0x54, 0xE2, 0x49, 0x53, 0xCE, + 0xE9, 0xAD, 0xB7, 0x18, 0xD1, 0x74, 0x3E, 0x6C, + 0x27, 0xFC, 0x94, 0x51, 0x6A, 0x99, 0x22, 0xFB, + 0x97, 0x5A, 0x78, 0x16, 0xB8, 0xAA, 0xB0, 0x21, + 0x12, 0x60, 0x8C, 0x03, 0x2B, 0xF1, 0x38, 0xE3 + }, + { + 0xC1, 0x68, 0x9C, 0x69, 0x8A, 0xB0, 0x65, 0xF6, + 0x2E, 0xEE, 0x65, 0xDD, 0xCA, 0x67, 0x6B, 0xAA, + 0x45, 0xB5, 0x2F, 0x30, 0x8A, 0xFA, 0x80, 0x4A, + 0xB4, 0xAA, 0x6A, 0xB8, 0x4B, 0x7A, 0xC1, 0xAA, + 0x1D, 0xFF, 0x07, 0x17, 0x56, 0x10, 0xB1, 0x2A, + 0xE1, 0x1F, 0x27, 0xB7, 0xC4, 0x30, 0xAF, 0xD5, + 0x75, 0x56, 0xBD, 0x18, 0x1D, 0x02, 0x83, 0x2C, + 0xD8, 0xD0, 0xA5, 0xFD, 0xC3, 0x02, 0x01, 0x24 + }, + { + 0xA1, 0xA6, 0x28, 0x17, 0x47, 0xE3, 0x4D, 0x3E, + 0xDE, 0x5E, 0x93, 0x34, 0x01, 0x74, 0x7C, 0xA7, + 0xF7, 0x66, 0x28, 0xB6, 0x14, 0xC8, 0xA3, 0x94, + 0xF5, 0x02, 0x56, 0x2B, 0xFE, 0xE0, 0xB9, 0x94, + 0xEC, 0xB6, 0x5F, 0xBF, 0xE1, 0xFF, 0x70, 0x67, + 0xDC, 0xB0, 0x1D, 0x02, 0xA9, 0x2B, 0xA4, 0x62, + 0x20, 0x75, 0x87, 0xCE, 0xF7, 0xDC, 0x2C, 0xFD, + 0xB4, 0x58, 0x48, 0x48, 0xAD, 0x55, 0x91, 0x4A + }, + { + 0x00, 0x70, 0xA0, 0x19, 0x0A, 0xA6, 0x96, 0x57, + 0x2D, 0x85, 0x3F, 0x1D, 0x24, 0xAB, 0x63, 0x08, + 0x48, 0xAC, 0x56, 0xAD, 0x5C, 0x2E, 0xBF, 0xCF, + 0xDE, 0x27, 0xD1, 0x11, 0xCD, 0x55, 0x93, 0x9C, + 0x1E, 0x4D, 0x07, 0x87, 0x2D, 0xDE, 0x7C, 0xE7, + 0x8B, 0x53, 0x4B, 0x53, 0x0F, 0x0A, 0x39, 0x6E, + 0x86, 0xAF, 0x9D, 0x57, 0x53, 0x54, 0xB5, 0xD7, + 0xE3, 0x4A, 0xCD, 0xE1, 0x8C, 0xC7, 0x67, 0xAE + }, + { + 0x51, 0xB9, 0xB5, 0xED, 0x19, 0x3F, 0xD4, 0xB1, + 0xA3, 0xA9, 0x2B, 0x46, 0xBD, 0x4B, 0xD1, 0xF6, + 0xEC, 0x6B, 0x38, 0xA6, 0x0F, 0x2D, 0x02, 0x61, + 0xD7, 0x2A, 0xBF, 0xD1, 0x64, 0x36, 0x12, 0x8D, + 0xCB, 0xF2, 0x2C, 0x25, 0xE3, 0xE3, 0xC4, 0x3F, + 0xE4, 0xD2, 0x9D, 0xB9, 0x12, 0x4D, 0x03, 0x33, + 0x30, 0x18, 0x45, 0x92, 0xD2, 0x0C, 0x5B, 0x08, + 0x2C, 0x23, 0x20, 0x64, 0x54, 0xCB, 0x3D, 0xD7 + }, + { + 0x57, 0x8F, 0x24, 0x27, 0x46, 0x91, 0x4E, 0x36, + 0xD0, 0xD9, 0xD4, 0x80, 0x96, 0x89, 0x57, 0x12, + 0x16, 0xA4, 0x3E, 0x47, 0x33, 0x32, 0x39, 0x51, + 0x62, 0x0F, 0x5E, 0xE7, 0x8C, 0xCF, 0xEE, 0x91, + 0x9B, 0xF5, 0x5F, 0x28, 0x7B, 0x45, 0xA7, 0x3D, + 0x44, 0x85, 0xAC, 0x74, 0x22, 0x87, 0x92, 0x39, + 0x65, 0x3B, 0x05, 0x91, 0xC3, 0x6C, 0x86, 0x69, + 0x41, 0xF8, 0xAF, 0xFE, 0x4A, 0xE5, 0x6E, 0x9E + }, + { + 0x94, 0x71, 0x30, 0xEF, 0x0B, 0x94, 0x8E, 0xE0, + 0x45, 0x81, 0xAB, 0xA3, 0xE2, 0xCC, 0x4C, 0xEF, + 0xC3, 0x8C, 0xCE, 0xDC, 0x86, 0x17, 0x92, 0xB7, + 0xB5, 0xDC, 0xD9, 0xD9, 0x36, 0x1C, 0x72, 0x4A, + 0x12, 0x20, 0x03, 0xBF, 0x79, 0x6C, 0xE0, 0x97, + 0x98, 0x00, 0xAD, 0xAB, 0xC7, 0x45, 0x6F, 0x17, + 0x3A, 0xE5, 0x26, 0x93, 0x15, 0xAF, 0xC0, 0x1B, + 0x60, 0x6D, 0xB2, 0x9C, 0x75, 0x50, 0xE8, 0xCA + }, + { + 0xC8, 0x52, 0xE6, 0x77, 0xF7, 0x7B, 0x14, 0xB5, + 0x85, 0xBD, 0x10, 0x2A, 0x0F, 0x14, 0x42, 0x43, + 0x05, 0x9D, 0xAB, 0xEC, 0x7C, 0xB0, 0x1F, 0xFA, + 0x61, 0xDF, 0x19, 0xFC, 0xE8, 0xAB, 0x43, 0x6B, + 0xF5, 0xE2, 0xD5, 0xC7, 0x9A, 0xA2, 0xD7, 0xB6, + 0x77, 0xF6, 0xC3, 0x75, 0xE9, 0x34, 0x3D, 0x34, + 0x2E, 0x4F, 0xF4, 0xE3, 0xAB, 0x00, 0x1B, 0xC7, + 0x98, 0x8C, 0x3C, 0x7A, 0x83, 0xCC, 0xB6, 0x9F + }, + { + 0x01, 0x19, 0x75, 0x26, 0x91, 0x7A, 0xC2, 0xC7, + 0xBC, 0x53, 0x95, 0x19, 0xE6, 0x8B, 0xB2, 0x79, + 0x81, 0x35, 0xF6, 0x03, 0x3E, 0xD5, 0x8F, 0x5C, + 0x45, 0x1E, 0x0C, 0xE9, 0x46, 0xAF, 0xF0, 0xF9, + 0x8D, 0xFD, 0xD1, 0x51, 0x01, 0x73, 0x1A, 0xC1, + 0x66, 0x12, 0x6E, 0xAF, 0xB5, 0xE7, 0xCB, 0xE2, + 0xE2, 0x72, 0xEE, 0x23, 0x3F, 0x34, 0xE5, 0xF3, + 0xF8, 0xEA, 0x3D, 0x2D, 0x12, 0x24, 0x82, 0xFB + }, + { + 0x05, 0x9C, 0x90, 0x85, 0x89, 0x5E, 0xB7, 0x18, + 0x30, 0x4E, 0x2D, 0xDA, 0x78, 0x68, 0x6B, 0xD9, + 0x57, 0x49, 0x81, 0x5A, 0x5E, 0xE9, 0x02, 0x51, + 0x0B, 0x00, 0x9A, 0xF6, 0x92, 0x48, 0xB6, 0xA7, + 0xA7, 0x2F, 0xF8, 0xA6, 0x28, 0xD8, 0x17, 0x73, + 0xE1, 0x1D, 0x5A, 0x1E, 0x7F, 0x69, 0x7A, 0x44, + 0x9B, 0x7A, 0x1E, 0x27, 0x12, 0xD5, 0xCF, 0xAE, + 0x7A, 0xB2, 0x65, 0x07, 0xD1, 0x11, 0x29, 0x18 + }, + { + 0x29, 0x52, 0x43, 0xBD, 0x75, 0x8C, 0xF2, 0x1C, + 0x80, 0x31, 0x25, 0xFC, 0xF3, 0x21, 0xDE, 0x5F, + 0x97, 0x98, 0x7C, 0x8D, 0xB3, 0xBB, 0x3C, 0xB5, + 0x1F, 0xF9, 0x7C, 0x4C, 0xDA, 0xC9, 0xD3, 0xBF, + 0x0A, 0x67, 0xCE, 0xE7, 0xED, 0x35, 0x0A, 0x41, + 0xFD, 0xE6, 0xAB, 0xCC, 0x25, 0x4F, 0xBC, 0x9F, + 0x8E, 0x6B, 0x3E, 0x3C, 0xCE, 0xCB, 0xD0, 0xE4, + 0xA6, 0x40, 0xA2, 0x0F, 0x36, 0x2B, 0xA3, 0xA0 + }, + { + 0xDD, 0x82, 0x32, 0xD2, 0x41, 0x2C, 0xCE, 0xEC, + 0xB5, 0x12, 0x31, 0x91, 0xF6, 0xE9, 0x22, 0x1E, + 0x85, 0x1E, 0xCC, 0xE0, 0xFA, 0xEB, 0xF0, 0x50, + 0x5F, 0x2A, 0xEE, 0xFF, 0x8A, 0x8C, 0x92, 0xD4, + 0x1D, 0xAC, 0xF1, 0x77, 0xBD, 0xAE, 0x27, 0x76, + 0x3E, 0xA4, 0xA8, 0x62, 0x05, 0xEF, 0x76, 0x34, + 0xF7, 0xA6, 0x87, 0xCC, 0x44, 0xBB, 0xBB, 0xDE, + 0xEE, 0x5E, 0x11, 0xE6, 0x5F, 0x9F, 0xBD, 0x69 + }, + { + 0xB0, 0x46, 0xB6, 0x83, 0x71, 0x6D, 0x31, 0xC9, + 0x14, 0xC7, 0x0B, 0x10, 0xF7, 0x64, 0x6D, 0xA3, + 0x1E, 0xFA, 0xB2, 0x23, 0x63, 0x47, 0x45, 0x9C, + 0xF8, 0xFA, 0x2C, 0x09, 0x12, 0x34, 0x31, 0xF7, + 0x28, 0x07, 0xF1, 0x1D, 0x86, 0x7C, 0x37, 0x70, + 0xB1, 0xF0, 0x61, 0xD5, 0x6C, 0xA0, 0xE5, 0xB1, + 0xE8, 0x8A, 0x6B, 0x44, 0xA3, 0x3C, 0xF9, 0x3E, + 0x18, 0xBC, 0xC9, 0xCE, 0xBB, 0xA5, 0xAD, 0xE7 + }, + { + 0x20, 0xE5, 0xA2, 0x55, 0x05, 0x8B, 0xE5, 0x1E, + 0x1A, 0x62, 0x9B, 0x4E, 0xBF, 0x81, 0xE5, 0xCB, + 0xE0, 0x78, 0x1C, 0xB6, 0x7C, 0xA4, 0xE5, 0x7B, + 0xA8, 0x6B, 0x30, 0x88, 0x96, 0xBC, 0xE7, 0x38, + 0x20, 0xEB, 0x08, 0x43, 0x1C, 0xE8, 0xC9, 0xBC, + 0x58, 0x10, 0xCC, 0x8D, 0x8B, 0x9C, 0x9D, 0x6F, + 0xCF, 0x83, 0x4E, 0x42, 0xEA, 0x33, 0xEF, 0x73, + 0xCE, 0xC4, 0x7D, 0x71, 0x3B, 0x6D, 0x8D, 0xFD + }, + { + 0x1E, 0x48, 0x04, 0xF9, 0xC0, 0xB1, 0xE8, 0x2B, + 0x9E, 0xD3, 0x63, 0xBD, 0xE4, 0x47, 0x28, 0xAC, + 0xF7, 0xD0, 0x90, 0xA1, 0xBF, 0xE2, 0xDD, 0xF8, + 0x81, 0x9D, 0x65, 0x92, 0xEF, 0x45, 0x3B, 0x83, + 0x5B, 0xD2, 0xEF, 0xE8, 0xB0, 0x20, 0x6E, 0x29, + 0x25, 0x5B, 0x07, 0xFB, 0x90, 0xC7, 0xD3, 0x0D, + 0x2C, 0x11, 0x48, 0x00, 0xB8, 0x6C, 0xB0, 0xE3, + 0xE0, 0x7D, 0x38, 0x7E, 0x98, 0xCE, 0x95, 0x37 + }, + { + 0x41, 0xC9, 0x53, 0xD8, 0xD2, 0x2A, 0x86, 0xC3, + 0x63, 0x4D, 0xF4, 0x22, 0xB6, 0xDE, 0x4A, 0x4F, + 0x14, 0x96, 0x66, 0xBE, 0x8C, 0x4F, 0x58, 0x1B, + 0x26, 0x23, 0xEE, 0x65, 0xC3, 0x92, 0xA5, 0xC3, + 0x28, 0x36, 0x63, 0x9E, 0xF5, 0x6B, 0x93, 0x68, + 0x62, 0x20, 0xF4, 0x5C, 0xE6, 0x5B, 0x4F, 0xA8, + 0x58, 0x9C, 0x91, 0x25, 0x64, 0x17, 0x90, 0xB6, + 0x92, 0x5F, 0xAA, 0xD9, 0x48, 0xB8, 0xBE, 0x04 + }, + { + 0x8B, 0xFC, 0xA4, 0xC8, 0xDF, 0xE3, 0xFD, 0xE4, + 0x25, 0x7B, 0x75, 0xC3, 0xDB, 0x01, 0x86, 0x2E, + 0xD3, 0x11, 0x67, 0xDE, 0x66, 0xC2, 0xE0, 0x3A, + 0x25, 0x56, 0xC4, 0xF4, 0x6C, 0x9D, 0xFF, 0xC1, + 0xAC, 0x45, 0xF7, 0xBC, 0x59, 0xA6, 0x7A, 0xB9, + 0x36, 0x24, 0xBE, 0xB8, 0x6D, 0xDD, 0x0D, 0x02, + 0x60, 0x3F, 0x0D, 0xCD, 0x03, 0x64, 0xF0, 0xF8, + 0x08, 0x81, 0x9B, 0xE9, 0x6C, 0xD8, 0xD3, 0xB6 + }, + { + 0xF6, 0xBF, 0x59, 0xD8, 0xD4, 0x5A, 0x55, 0x71, + 0x11, 0xA2, 0x36, 0xCB, 0xBA, 0x52, 0x61, 0x9A, + 0xE3, 0xDF, 0xCC, 0x43, 0x16, 0x94, 0x38, 0x43, + 0xAF, 0xD1, 0x28, 0x1B, 0x28, 0x21, 0x4A, 0x4A, + 0x5E, 0x85, 0x1E, 0xF8, 0xC5, 0x4F, 0x50, 0x5E, + 0x3C, 0x4B, 0x60, 0x0E, 0xFF, 0xBE, 0xBB, 0x3E, + 0xAC, 0x17, 0x08, 0x7F, 0x22, 0x27, 0x58, 0x12, + 0x63, 0xF1, 0x7D, 0x7E, 0x5F, 0x68, 0xEA, 0x83 + }, + { + 0x1B, 0xC9, 0xED, 0xE4, 0xD4, 0x1A, 0x4D, 0xF6, + 0xE8, 0xE6, 0xF4, 0x7C, 0x2F, 0x4A, 0xD8, 0x73, + 0x37, 0xB6, 0x9B, 0x19, 0xF7, 0x10, 0xF7, 0x66, + 0xE1, 0xFA, 0xF5, 0xAA, 0x05, 0xA4, 0x3B, 0x66, + 0x45, 0x39, 0x6E, 0x7F, 0xBE, 0xF4, 0x3B, 0xB7, + 0x79, 0x5D, 0x39, 0x40, 0x7B, 0x58, 0x15, 0xB9, + 0x2E, 0xCC, 0x23, 0xA6, 0xC1, 0x24, 0x14, 0x21, + 0x15, 0x3A, 0x55, 0xD5, 0x1F, 0x12, 0xBF, 0xD8 + }, + { + 0x76, 0xB3, 0x8B, 0x36, 0x31, 0x55, 0x5D, 0xBC, + 0xFB, 0x21, 0x21, 0x8F, 0xF9, 0xE4, 0x12, 0xA2, + 0x29, 0x88, 0x9E, 0xF2, 0xCE, 0x8A, 0xD7, 0x05, + 0xE9, 0x0F, 0x96, 0xAA, 0xBB, 0xD5, 0xBE, 0x7E, + 0x53, 0x29, 0xA4, 0x26, 0x53, 0x4C, 0x81, 0x5A, + 0x56, 0x53, 0x77, 0x13, 0x18, 0x72, 0x66, 0x41, + 0x42, 0x4E, 0x3B, 0x88, 0x29, 0x2F, 0xB1, 0xD8, + 0x95, 0x44, 0x40, 0x6A, 0xDE, 0x9B, 0xCC, 0xB5 + }, + { + 0xE5, 0x3F, 0x60, 0x07, 0x40, 0x22, 0x4E, 0x4D, + 0x10, 0xD3, 0x1D, 0x24, 0x38, 0x00, 0x31, 0x43, + 0xAF, 0xDB, 0x43, 0x6E, 0xB1, 0x79, 0x1B, 0x15, + 0x0D, 0xE3, 0x56, 0x76, 0xF0, 0xE3, 0x2F, 0x80, + 0xB0, 0xB6, 0x5F, 0x0A, 0xCF, 0x48, 0x1A, 0x5F, + 0xBF, 0x95, 0x96, 0xC0, 0xCB, 0x0A, 0x27, 0xC7, + 0xAF, 0xC1, 0x1D, 0x1E, 0x2C, 0x4D, 0x54, 0x02, + 0x47, 0x5E, 0x4F, 0xFC, 0xC1, 0xCD, 0xA8, 0x11 + }, + { + 0x62, 0x06, 0xB9, 0x1F, 0xC0, 0xB6, 0xF1, 0x21, + 0x1E, 0x9F, 0xDE, 0xCD, 0xC9, 0xD5, 0x1A, 0x6F, + 0x1E, 0xEE, 0x65, 0x54, 0xB1, 0x38, 0xAD, 0xCD, + 0x4A, 0x82, 0x3D, 0xF0, 0x0D, 0xDE, 0xF6, 0x75, + 0x9A, 0x9B, 0xFD, 0x7A, 0x4E, 0x98, 0x1E, 0x04, + 0x52, 0x36, 0x83, 0x8F, 0x4A, 0xF6, 0x93, 0xF6, + 0x93, 0x77, 0x93, 0x14, 0x84, 0xB3, 0xE8, 0x1E, + 0x3E, 0x3B, 0xC2, 0xCB, 0x7E, 0xF7, 0x9F, 0xE9 + }, + { + 0x76, 0xFD, 0x02, 0xDA, 0xDD, 0x96, 0x3B, 0xC0, + 0x35, 0x39, 0x91, 0x46, 0xCE, 0x42, 0x98, 0x8C, + 0xC0, 0x99, 0xD3, 0xCF, 0x4D, 0x32, 0xDF, 0x5C, + 0x0B, 0xBF, 0x64, 0x10, 0x12, 0x46, 0xB1, 0xC7, + 0x08, 0xD1, 0x67, 0xE2, 0x95, 0x95, 0xD1, 0x1D, + 0x09, 0xB3, 0xF6, 0x34, 0x86, 0xB4, 0x05, 0x26, + 0xAC, 0x1D, 0xFE, 0x31, 0xBC, 0x22, 0xDE, 0xC7, + 0x0B, 0x74, 0x5E, 0x90, 0xE2, 0xEA, 0xAF, 0x5A + }, + { + 0xF0, 0xA1, 0xFB, 0xE3, 0x11, 0x63, 0xE4, 0x21, + 0x01, 0x50, 0x72, 0x18, 0x3D, 0x68, 0xEE, 0x51, + 0x91, 0xA9, 0x9C, 0xFD, 0xA1, 0x69, 0xBA, 0x5A, + 0x19, 0x54, 0xC9, 0xF3, 0x10, 0x7D, 0x4E, 0xCA, + 0x06, 0x3E, 0x13, 0x7A, 0x71, 0x14, 0xD3, 0x97, + 0xC9, 0xDB, 0x67, 0x2B, 0x9F, 0x47, 0x8D, 0x41, + 0xC3, 0x4E, 0x99, 0x1B, 0x06, 0x69, 0xA9, 0x51, + 0x53, 0x92, 0x90, 0xC8, 0xED, 0x65, 0xE4, 0x6A + }, + { + 0x13, 0xC7, 0x2A, 0x6A, 0xA5, 0x71, 0xB1, 0x43, + 0xDC, 0xCF, 0x45, 0xAD, 0xCD, 0x98, 0xEA, 0xE6, + 0x99, 0xA1, 0x54, 0xB1, 0x10, 0xF2, 0x5E, 0x7E, + 0x9E, 0x82, 0xB7, 0x65, 0xB9, 0xA0, 0x89, 0x23, + 0x68, 0x8E, 0x8E, 0x0F, 0xF3, 0x11, 0xA6, 0x8A, + 0x77, 0x1E, 0x14, 0x50, 0x96, 0xD6, 0x07, 0x76, + 0xC6, 0xD6, 0xEE, 0x70, 0xAD, 0x6F, 0x69, 0xFA, + 0x2B, 0x76, 0x77, 0x63, 0x40, 0x55, 0xA0, 0x0E + }, + { + 0x0E, 0x06, 0x2B, 0xFE, 0x81, 0x8E, 0xE1, 0x0F, + 0x33, 0x48, 0x1D, 0xEA, 0x43, 0x02, 0x8B, 0x2C, + 0xFB, 0xB4, 0x9E, 0xC9, 0x5E, 0x0F, 0x75, 0xA9, + 0xE1, 0x6D, 0x40, 0x4B, 0xC5, 0x19, 0xB9, 0xAD, + 0x50, 0xB4, 0xA7, 0x33, 0x69, 0x2C, 0xA5, 0x4E, + 0xFB, 0x68, 0x04, 0x69, 0xED, 0x83, 0xDD, 0xEF, + 0xBD, 0xDD, 0xB1, 0x39, 0x04, 0x2E, 0x0E, 0x1C, + 0x09, 0xC3, 0xEB, 0x79, 0x03, 0xFA, 0x08, 0xDF + }, + { + 0x45, 0x3B, 0xE4, 0xAA, 0xB9, 0xF4, 0x23, 0xB3, + 0x36, 0x52, 0xA0, 0xB5, 0xD0, 0x2A, 0x9A, 0xF8, + 0x55, 0xDD, 0x0D, 0x42, 0xDD, 0x83, 0x11, 0x0B, + 0xA3, 0xBC, 0x4B, 0x39, 0x94, 0xEA, 0x3F, 0x88, + 0x5A, 0x71, 0x30, 0x89, 0x75, 0x08, 0x9B, 0x49, + 0x03, 0xE2, 0xE4, 0xD6, 0xBA, 0x6D, 0xC2, 0xE8, + 0x40, 0x31, 0xFF, 0xE9, 0xC8, 0x56, 0x39, 0x75, + 0xC8, 0x61, 0x6A, 0xCA, 0x07, 0x42, 0xE8, 0x29 + }, + { + 0x53, 0x61, 0xE3, 0xE8, 0x93, 0xDD, 0x36, 0x0B, + 0xCB, 0xF5, 0x1C, 0x79, 0x3E, 0xC0, 0x92, 0xA6, + 0xB0, 0x52, 0x05, 0x4F, 0x5F, 0x00, 0x0B, 0x9F, + 0xCE, 0x50, 0x7B, 0x66, 0x45, 0xF8, 0xD4, 0x70, + 0x13, 0xA8, 0x70, 0x6A, 0x58, 0xD4, 0xB1, 0x06, + 0x29, 0xCC, 0x82, 0xB8, 0xD2, 0xD7, 0x96, 0xFD, + 0xD3, 0x7B, 0x60, 0x8A, 0x58, 0x79, 0x52, 0xD6, + 0x55, 0x3E, 0x01, 0xD1, 0xAF, 0x0E, 0x04, 0xB8 + }, + { + 0x74, 0xB5, 0x67, 0x39, 0xF0, 0x1F, 0x82, 0x09, + 0xA4, 0x04, 0x44, 0xDF, 0x4C, 0xCD, 0xEE, 0xEA, + 0x8F, 0x97, 0xE8, 0xE7, 0x6E, 0xFA, 0x3C, 0x04, + 0x33, 0x7F, 0x69, 0x94, 0x5C, 0x4D, 0x44, 0xC0, + 0x85, 0xF1, 0xF4, 0x78, 0x96, 0x96, 0x36, 0x1E, + 0x3C, 0x97, 0x77, 0x4A, 0x93, 0x5F, 0x86, 0x0D, + 0x67, 0x46, 0x86, 0xDC, 0xBA, 0x3D, 0x45, 0xEC, + 0xD8, 0x63, 0x9A, 0x64, 0xAE, 0xA0, 0x62, 0x1B + }, + { + 0xB4, 0xD3, 0x15, 0x87, 0xB9, 0x2B, 0x53, 0x61, + 0xCD, 0xC2, 0xD3, 0xC4, 0x10, 0x86, 0xC1, 0x55, + 0x3E, 0x7B, 0x55, 0xA1, 0xF6, 0x1E, 0x94, 0xD2, + 0xBC, 0x30, 0xBC, 0x25, 0x1D, 0xAF, 0x8A, 0x5E, + 0xBF, 0xC5, 0x07, 0x09, 0xCC, 0x04, 0xCB, 0xAF, + 0x4B, 0x3B, 0x4D, 0xA2, 0xD2, 0x6B, 0x81, 0x23, + 0x8F, 0xBA, 0x71, 0x8F, 0xA9, 0x17, 0x59, 0xB8, + 0x0B, 0xD3, 0x10, 0x3A, 0xEC, 0x11, 0xE0, 0x6F + }, + { + 0xAA, 0xF6, 0x12, 0x7F, 0x00, 0xA0, 0x3D, 0x96, + 0x40, 0x6B, 0x9F, 0xB4, 0xAC, 0x70, 0x16, 0x0D, + 0xB5, 0x22, 0x42, 0x9B, 0x5C, 0xD9, 0x4E, 0x7F, + 0xA0, 0x30, 0x3A, 0x74, 0x94, 0x78, 0xFE, 0x31, + 0x89, 0xC8, 0xEA, 0x23, 0x93, 0x0A, 0x66, 0x25, + 0x2A, 0x80, 0x26, 0x74, 0xDC, 0xAF, 0x77, 0x00, + 0x46, 0x82, 0x0D, 0xD9, 0x64, 0xC6, 0x6F, 0x0F, + 0x54, 0x75, 0x1A, 0x72, 0xF9, 0x7D, 0x9C, 0x35 + }, + { + 0x2C, 0x30, 0xD4, 0x8D, 0xF9, 0x98, 0x4E, 0x02, + 0xF7, 0x5A, 0x94, 0x54, 0x92, 0x17, 0x18, 0x4D, + 0xD0, 0x2A, 0xAD, 0x3B, 0x57, 0x68, 0x3D, 0x09, + 0xB5, 0xA8, 0xC2, 0xEF, 0x53, 0xA9, 0x6A, 0xFB, + 0x73, 0xFE, 0xB6, 0xF9, 0x14, 0xE2, 0xD8, 0x15, + 0xBB, 0x3B, 0x08, 0x65, 0x43, 0x32, 0xFC, 0xFE, + 0x79, 0xF8, 0x0E, 0xC5, 0xF0, 0x51, 0xDA, 0x10, + 0xD7, 0x21, 0x41, 0x3D, 0xDD, 0xE8, 0xFA, 0x60 + }, + { + 0x92, 0xE2, 0xC5, 0xF7, 0x5D, 0x0C, 0xEA, 0xFC, + 0x81, 0x8F, 0xA7, 0x93, 0x59, 0x39, 0xE4, 0x8B, + 0x91, 0x59, 0x41, 0xEF, 0x73, 0x4D, 0x75, 0x27, + 0x0E, 0xB3, 0x21, 0xBA, 0x20, 0x80, 0xEF, 0x6D, + 0x25, 0x5E, 0x90, 0xEF, 0x96, 0xC6, 0x4C, 0xFF, + 0x1D, 0x8C, 0x18, 0xF3, 0x3C, 0x2E, 0xAB, 0x10, + 0x7F, 0xEF, 0x53, 0xE0, 0xD8, 0xBB, 0x16, 0x05, + 0x16, 0x80, 0x74, 0x80, 0xFC, 0xBA, 0x53, 0x73 + }, + { + 0x6E, 0x03, 0xA9, 0x1E, 0x20, 0x44, 0x46, 0x27, + 0xE3, 0xD2, 0xE2, 0x22, 0x26, 0xCF, 0x47, 0x00, + 0x26, 0x69, 0x44, 0x34, 0xED, 0x64, 0x79, 0x82, + 0x8C, 0xB6, 0xDC, 0x8F, 0x27, 0x96, 0x0A, 0xEE, + 0xE2, 0xF4, 0xAB, 0x87, 0x2A, 0x5C, 0xA2, 0xF7, + 0xF6, 0x52, 0xF7, 0xDC, 0x77, 0xD5, 0xF9, 0x6D, + 0x85, 0x82, 0x8B, 0x8F, 0x9C, 0x2D, 0x6C, 0x23, + 0x9E, 0x79, 0x77, 0x24, 0xA1, 0x31, 0x31, 0xB1 + }, + { + 0xBA, 0x43, 0x2D, 0xB0, 0xA3, 0x31, 0xBB, 0x8C, + 0x39, 0xB1, 0x7B, 0xEE, 0x34, 0x46, 0x2B, 0x26, + 0xDD, 0xB7, 0xAD, 0x91, 0xB6, 0xC7, 0x5A, 0xEC, + 0x27, 0x65, 0xFB, 0xAE, 0x3A, 0x0E, 0x60, 0xEC, + 0x54, 0x6D, 0x45, 0xF8, 0xE5, 0x84, 0x37, 0xB9, + 0xD7, 0x7C, 0x3D, 0x2E, 0x8D, 0x7C, 0xE0, 0x69, + 0x73, 0x15, 0x66, 0x51, 0xD4, 0x08, 0x22, 0x2A, + 0xA2, 0x90, 0xCB, 0x58, 0xCA, 0xBC, 0x0A, 0xE5 + }, + { + 0x83, 0xA0, 0x1E, 0x23, 0xAB, 0x27, 0x7B, 0x1F, + 0xC2, 0x8C, 0xD8, 0xBB, 0x8D, 0xA7, 0xE9, 0x4C, + 0x70, 0xF1, 0xDE, 0xE3, 0x2D, 0x19, 0x55, 0xCE, + 0xE2, 0x50, 0xEE, 0x58, 0x41, 0x9A, 0x1F, 0xEE, + 0x10, 0xA8, 0x99, 0x17, 0x97, 0xCE, 0x3D, 0x20, + 0x93, 0x80, 0xCA, 0x9F, 0x98, 0x93, 0x39, 0xE2, + 0xD8, 0xA8, 0x1C, 0x67, 0xD7, 0x37, 0xD8, 0x28, + 0x8C, 0x7F, 0xAE, 0x46, 0x02, 0x83, 0x4A, 0x8B + }, + { + 0x0E, 0xA3, 0x21, 0x72, 0xCC, 0x19, 0x1D, 0xFC, + 0x13, 0x1C, 0xD8, 0x8A, 0xA0, 0x3F, 0xF4, 0x18, + 0x5C, 0x0B, 0xFA, 0x7B, 0x19, 0x11, 0x12, 0x19, + 0xEE, 0xCB, 0x45, 0xB0, 0xFF, 0x60, 0x4D, 0x3E, + 0xDB, 0x00, 0x55, 0x0A, 0xBB, 0xA1, 0x11, 0x52, + 0x2B, 0x77, 0xAE, 0x61, 0xC9, 0xA8, 0xD6, 0xE9, + 0x4F, 0xCA, 0x9D, 0x96, 0xC3, 0x8D, 0x6B, 0x7C, + 0xCE, 0x27, 0x52, 0xF0, 0xD0, 0xC3, 0x7E, 0x78 + }, + { + 0x54, 0xAD, 0xD6, 0x55, 0x2B, 0x08, 0x85, 0x8B, + 0x23, 0xD6, 0x64, 0x5F, 0x6C, 0xE7, 0x9E, 0x92, + 0xF3, 0x8B, 0x66, 0xAE, 0x91, 0x86, 0x77, 0xE6, + 0xD9, 0x1F, 0x71, 0x87, 0xC4, 0x16, 0x05, 0x24, + 0xDF, 0xA8, 0xD0, 0x1F, 0x00, 0xEA, 0x93, 0xDD, + 0x29, 0x9F, 0x3C, 0xC4, 0x09, 0x01, 0xBD, 0x33, + 0x27, 0xA0, 0xF1, 0x8C, 0xCD, 0x7B, 0x6B, 0x8E, + 0x4E, 0x47, 0xCD, 0x28, 0xCF, 0x83, 0x8F, 0xAB + }, + { + 0xEF, 0x84, 0x74, 0x6D, 0xC2, 0x01, 0x56, 0xB6, + 0x6B, 0xA5, 0xC7, 0x8A, 0x50, 0x83, 0x0A, 0xBD, + 0x2A, 0xEF, 0x90, 0xE6, 0x67, 0xB9, 0x7E, 0xB5, + 0x22, 0x91, 0xBC, 0x86, 0x9D, 0x8A, 0xA2, 0x45, + 0x59, 0xA1, 0x42, 0xC6, 0x8F, 0xEA, 0x2E, 0xF3, + 0x2A, 0xF2, 0x2D, 0xFC, 0xEA, 0x4C, 0x90, 0xB3, + 0xD4, 0x90, 0x8C, 0xC9, 0xEA, 0x5C, 0xFC, 0x4E, + 0x91, 0xBF, 0x11, 0xCE, 0x6A, 0x7E, 0x57, 0x61 + }, + { + 0x5A, 0x1B, 0xF3, 0x81, 0xA0, 0x41, 0x19, 0xF9, + 0x42, 0xE4, 0x63, 0xAB, 0xA2, 0xB1, 0x64, 0x38, + 0x82, 0x46, 0x8A, 0xEC, 0xC1, 0xB1, 0xAA, 0x1E, + 0x7B, 0xCA, 0xAB, 0x3B, 0x47, 0x8F, 0xC5, 0xF0, + 0x56, 0xF1, 0x0D, 0xA9, 0x03, 0x7D, 0x40, 0xFA, + 0x7F, 0x55, 0x70, 0x8E, 0x10, 0x3B, 0xDA, 0x96, + 0x5E, 0x92, 0x0C, 0xF6, 0x7C, 0xE3, 0xAD, 0xF7, + 0xE2, 0x00, 0xE8, 0x61, 0x01, 0x4D, 0xEC, 0xC6 + }, + { + 0xAC, 0xF7, 0x8A, 0xA3, 0x28, 0x45, 0x96, 0xF3, + 0x30, 0xB7, 0xE8, 0x47, 0x51, 0xB9, 0x4C, 0x31, + 0x4C, 0xD8, 0x36, 0x36, 0x27, 0xBA, 0x99, 0x78, + 0x81, 0x30, 0x85, 0x78, 0x87, 0x37, 0x59, 0x89, + 0x5D, 0x13, 0xDF, 0xFF, 0xA5, 0xE5, 0x74, 0x50, + 0x13, 0x61, 0xF0, 0x43, 0xC7, 0x4F, 0x57, 0xD2, + 0xD0, 0xF1, 0x5C, 0x7A, 0x41, 0xC7, 0xC4, 0x5E, + 0x3C, 0x09, 0xAD, 0x89, 0xD6, 0x99, 0xA9, 0x77 + }, + { + 0x18, 0xB3, 0xE9, 0x04, 0x38, 0x44, 0xD4, 0xF3, + 0xA2, 0xD0, 0x21, 0xF5, 0x4C, 0x38, 0xFA, 0xCC, + 0x36, 0x4F, 0x84, 0xBA, 0x10, 0x58, 0xF2, 0x10, + 0x09, 0xFC, 0x37, 0x1D, 0x2E, 0x4F, 0x38, 0xC7, + 0x27, 0x51, 0x8A, 0xAB, 0xA6, 0xA2, 0x9E, 0x0F, + 0xDA, 0xE6, 0xE7, 0x60, 0xA4, 0xF1, 0xA6, 0xD7, + 0x58, 0xEB, 0xE4, 0x2C, 0x2A, 0xFC, 0x9D, 0x2C, + 0xDC, 0x6D, 0xD5, 0x80, 0x77, 0x8C, 0x4B, 0x32 + }, + { + 0x18, 0x96, 0xB2, 0x31, 0x70, 0x33, 0xCF, 0x31, + 0x04, 0x68, 0x73, 0xD8, 0x7F, 0x26, 0xE6, 0xA4, + 0x2A, 0x9D, 0x77, 0x0B, 0xBA, 0xF6, 0xE0, 0x62, + 0xDF, 0x11, 0xF9, 0xB4, 0xA0, 0xEA, 0xB2, 0x75, + 0xAA, 0xB1, 0x2C, 0xAA, 0xC2, 0xD3, 0xF5, 0x29, + 0xEB, 0x20, 0xD0, 0x70, 0xFD, 0x84, 0x4D, 0x86, + 0xD0, 0xA5, 0x71, 0xCD, 0xF6, 0x28, 0x5F, 0x80, + 0xE2, 0x30, 0x8B, 0xB8, 0x2C, 0x6C, 0x5B, 0x3B + }, + { + 0x8C, 0x3D, 0xC4, 0x01, 0x94, 0xAA, 0x02, 0x1F, + 0x3C, 0x4A, 0x1F, 0x9A, 0x05, 0x5E, 0x4D, 0x41, + 0x9E, 0xB3, 0xA2, 0x6D, 0x4C, 0x2F, 0x1A, 0x8C, + 0x7E, 0x18, 0x8B, 0x73, 0x48, 0x13, 0x40, 0x80, + 0xB6, 0x3F, 0x6E, 0x57, 0x0A, 0xD1, 0x1C, 0x28, + 0x78, 0x66, 0x53, 0x55, 0x41, 0x9C, 0x10, 0x20, + 0xDE, 0x4B, 0x65, 0x5E, 0x7A, 0x6C, 0x2C, 0xCD, + 0xE9, 0x07, 0x2C, 0xD4, 0x27, 0xFE, 0x8C, 0x4E + }, + { + 0x70, 0xAE, 0x04, 0x30, 0xD5, 0x45, 0xEC, 0x42, + 0x7F, 0x85, 0x41, 0x21, 0x1D, 0x4F, 0xE0, 0x42, + 0xB9, 0x82, 0x3A, 0xCE, 0xC0, 0x4B, 0x15, 0xC9, + 0x0B, 0x7F, 0x4B, 0x8B, 0xDD, 0x3D, 0xC7, 0x85, + 0x19, 0x90, 0xF3, 0x70, 0xE7, 0x14, 0x16, 0x75, + 0x10, 0x66, 0x49, 0xD3, 0x91, 0x51, 0x09, 0x03, + 0x18, 0x23, 0x1E, 0x4D, 0xED, 0x51, 0x22, 0x5D, + 0x9A, 0x6F, 0xA6, 0xC4, 0x24, 0x69, 0x5D, 0xE2 + }, + { + 0x07, 0x33, 0x6C, 0x42, 0xBD, 0x51, 0x49, 0x0E, + 0xF8, 0x4D, 0xFB, 0xDF, 0xAB, 0x74, 0x66, 0xF6, + 0xB6, 0x39, 0x99, 0xA5, 0xC0, 0x88, 0x72, 0xDF, + 0xED, 0xA0, 0x20, 0x6F, 0xDA, 0x80, 0xB9, 0xA6, + 0x2D, 0xE7, 0x28, 0xE3, 0xE3, 0xC3, 0xFD, 0x6B, + 0x7D, 0x21, 0xA4, 0x38, 0xAA, 0xD1, 0xB8, 0xDD, + 0x22, 0x38, 0x63, 0xC0, 0xD2, 0x6A, 0xCA, 0x27, + 0x79, 0x01, 0x74, 0xD9, 0xD4, 0x42, 0xA6, 0x4C + }, + { + 0x79, 0x26, 0x70, 0x88, 0x59, 0xE6, 0xE2, 0xAB, + 0x68, 0xF6, 0x04, 0xDA, 0x69, 0xA9, 0xFB, 0x50, + 0x87, 0xBB, 0x33, 0xF4, 0xE8, 0xD8, 0x95, 0x73, + 0x0E, 0x30, 0x1A, 0xB2, 0xD7, 0xDF, 0x74, 0x8B, + 0x67, 0xDF, 0x0B, 0x6B, 0x86, 0x22, 0xE5, 0x2D, + 0xD5, 0x7D, 0x8D, 0x3A, 0xD8, 0x7D, 0x58, 0x20, + 0xD4, 0xEC, 0xFD, 0x24, 0x17, 0x8B, 0x2D, 0x2B, + 0x78, 0xD6, 0x4F, 0x4F, 0xBD, 0x38, 0x75, 0x82 + }, + { + 0x92, 0x80, 0xF4, 0xD1, 0x15, 0x70, 0x32, 0xAB, + 0x31, 0x5C, 0x10, 0x0D, 0x63, 0x62, 0x83, 0xFB, + 0xF4, 0xFB, 0xA2, 0xFB, 0xAD, 0x0F, 0x8B, 0xC0, + 0x20, 0x72, 0x1D, 0x76, 0xBC, 0x1C, 0x89, 0x73, + 0xCE, 0xD2, 0x88, 0x71, 0xCC, 0x90, 0x7D, 0xAB, + 0x60, 0xE5, 0x97, 0x56, 0x98, 0x7B, 0x0E, 0x0F, + 0x86, 0x7F, 0xA2, 0xFE, 0x9D, 0x90, 0x41, 0xF2, + 0xC9, 0x61, 0x80, 0x74, 0xE4, 0x4F, 0xE5, 0xE9 + }, + { + 0x55, 0x30, 0xC2, 0xD5, 0x9F, 0x14, 0x48, 0x72, + 0xE9, 0x87, 0xE4, 0xE2, 0x58, 0xA7, 0xD8, 0xC3, + 0x8C, 0xE8, 0x44, 0xE2, 0xCC, 0x2E, 0xED, 0x94, + 0x0F, 0xFC, 0x68, 0x3B, 0x49, 0x88, 0x15, 0xE5, + 0x3A, 0xDB, 0x1F, 0xAA, 0xF5, 0x68, 0x94, 0x61, + 0x22, 0x80, 0x5A, 0xC3, 0xB8, 0xE2, 0xFE, 0xD4, + 0x35, 0xFE, 0xD6, 0x16, 0x2E, 0x76, 0xF5, 0x64, + 0xE5, 0x86, 0xBA, 0x46, 0x44, 0x24, 0xE8, 0x85 + }, + { + 0xDA, 0x85, 0x0A, 0x2F, 0x54, 0xE9, 0x44, 0x89, + 0x17, 0xD0, 0xDC, 0xAA, 0x63, 0x93, 0x7B, 0x95, + 0xA4, 0xDA, 0x1E, 0xAC, 0x8A, 0xF4, 0xDD, 0xF2, + 0x11, 0x3E, 0x5C, 0x8B, 0x0D, 0x4D, 0xB2, 0x66, + 0x9A, 0xF3, 0xC2, 0xAC, 0xB0, 0x80, 0x3D, 0x05, + 0x32, 0x3F, 0x3E, 0xC5, 0x5A, 0xBD, 0x33, 0xBD, + 0xF9, 0xB2, 0xBE, 0x89, 0x0E, 0xE7, 0x9E, 0x7F, + 0x3F, 0xCE, 0x4E, 0x19, 0x86, 0x96, 0xA7, 0xA3 + }, + { + 0xF1, 0x60, 0x95, 0xDD, 0x9F, 0x1E, 0xEB, 0x77, + 0xD5, 0xB9, 0x2F, 0x4B, 0x1F, 0xAC, 0x3A, 0x2C, + 0x5D, 0xA6, 0xAE, 0x5D, 0x0A, 0xB3, 0xF2, 0x54, + 0xE2, 0xA7, 0xFE, 0x52, 0x67, 0x24, 0x11, 0xD0, + 0x1C, 0xFA, 0x6A, 0xC0, 0x5B, 0xF3, 0x9E, 0xF6, + 0x5F, 0x4B, 0x22, 0x26, 0x4B, 0x41, 0xC3, 0xF3, + 0x63, 0x56, 0x3A, 0xBF, 0x0E, 0x92, 0x42, 0x90, + 0xC1, 0xC6, 0x80, 0xB1, 0x8A, 0xA6, 0x5B, 0x44 + }, + { + 0x76, 0xD0, 0x0A, 0x09, 0xC5, 0xBD, 0xD3, 0x9E, + 0xD3, 0x28, 0x71, 0x72, 0x2C, 0xFA, 0x00, 0x47, + 0x67, 0x4B, 0xEC, 0x8D, 0x35, 0x17, 0x5A, 0xF9, + 0x0D, 0x7A, 0xE9, 0x10, 0x74, 0x40, 0xA2, 0xA0, + 0x63, 0x88, 0x56, 0xD8, 0x38, 0x4C, 0x81, 0x7D, + 0x77, 0x2A, 0x4A, 0x59, 0x7A, 0x89, 0x55, 0x49, + 0xC8, 0x48, 0x66, 0x37, 0x56, 0x31, 0xCB, 0xA0, + 0x42, 0xF0, 0xEF, 0x6F, 0xFE, 0xB8, 0x9D, 0x44 + }, + { + 0xA6, 0x51, 0x13, 0x7B, 0x2C, 0x47, 0xFB, 0x79, + 0x51, 0xE7, 0xBD, 0xA7, 0x15, 0x43, 0xA6, 0xEB, + 0xC6, 0x24, 0x2A, 0xCA, 0xB4, 0x34, 0x7D, 0x38, + 0x8B, 0xE8, 0x35, 0x0F, 0x0C, 0x3F, 0xA3, 0xDF, + 0x8D, 0x95, 0x2C, 0x7C, 0x8A, 0x3D, 0xAF, 0x01, + 0xE0, 0x6C, 0x1D, 0xA6, 0x94, 0x96, 0xBB, 0xA8, + 0xDE, 0x62, 0xD8, 0x6B, 0x50, 0x93, 0x25, 0x6F, + 0x77, 0xA1, 0x87, 0xB5, 0x3D, 0xB0, 0x39, 0x88 + }, + { + 0xF3, 0x2F, 0x15, 0x0C, 0x2D, 0x67, 0xC0, 0xC4, + 0x37, 0x40, 0x1B, 0x70, 0xF6, 0x0B, 0x38, 0xF0, + 0xA3, 0xA4, 0x70, 0x59, 0x03, 0x3E, 0x75, 0x05, + 0xE6, 0x9A, 0x1D, 0x30, 0x12, 0x96, 0x03, 0x0B, + 0xC9, 0xB2, 0x95, 0x19, 0xC7, 0xF8, 0xB7, 0xD5, + 0x9A, 0x71, 0xFA, 0xB9, 0x05, 0x57, 0xDC, 0x3D, + 0xC8, 0x23, 0xFA, 0xC9, 0x5B, 0x9E, 0x85, 0xE6, + 0x52, 0x52, 0x8C, 0xBF, 0xB0, 0x1B, 0x11, 0x78 + }, + { + 0x27, 0x02, 0x56, 0x61, 0x36, 0xC4, 0x92, 0xF4, + 0x10, 0x89, 0xB0, 0x60, 0x10, 0x84, 0x60, 0xFA, + 0x30, 0x22, 0xC9, 0xC2, 0x5D, 0x34, 0x3B, 0xCB, + 0xD8, 0xAF, 0x2A, 0xF1, 0x9C, 0x17, 0xEF, 0x4C, + 0xA9, 0xF2, 0x22, 0x4F, 0xE7, 0xC4, 0x70, 0x0A, + 0x10, 0x19, 0x8E, 0xE5, 0x24, 0x8F, 0x30, 0x0B, + 0x54, 0x8E, 0xBF, 0x5C, 0x8E, 0x71, 0x16, 0x32, + 0x0C, 0xC8, 0x93, 0xFF, 0x7E, 0x23, 0x1F, 0xFB + }, + { + 0xFF, 0xE6, 0x87, 0x9F, 0x46, 0xB6, 0x29, 0x2B, + 0x21, 0x96, 0x97, 0x2E, 0x3F, 0xDF, 0x4F, 0xE9, + 0xEA, 0x4A, 0x81, 0x6D, 0x18, 0x07, 0xA3, 0x1C, + 0xAE, 0xAD, 0x6A, 0xAC, 0x5F, 0x06, 0x3C, 0x8F, + 0xE8, 0x77, 0x79, 0x75, 0x59, 0xA7, 0x59, 0xA0, + 0x0F, 0x8B, 0xA8, 0xF6, 0x68, 0xD8, 0x96, 0x8F, + 0xB3, 0x1D, 0x8A, 0x3B, 0x84, 0x57, 0x35, 0x90, + 0x2C, 0x5E, 0x42, 0xE2, 0x89, 0xEE, 0x0B, 0x62 + }, + { + 0x14, 0x48, 0x84, 0x28, 0x68, 0x22, 0xC2, 0x51, + 0x2D, 0x61, 0xB0, 0x46, 0xE6, 0x74, 0xD8, 0x6B, + 0x26, 0x4E, 0x9C, 0xC6, 0x89, 0x3E, 0xFF, 0x36, + 0x73, 0x11, 0x24, 0xF5, 0x9D, 0x1A, 0x82, 0x00, + 0x1E, 0x63, 0xF3, 0xE8, 0x05, 0x1C, 0xFE, 0x52, + 0xE7, 0x59, 0x7E, 0x28, 0x73, 0x8E, 0x3C, 0x3A, + 0x70, 0xF1, 0xBE, 0xD9, 0x68, 0x0E, 0x2C, 0x0E, + 0xF3, 0x72, 0x8B, 0x10, 0xA5, 0x6E, 0xD9, 0x87 + }, + { + 0x17, 0xC3, 0xF1, 0x46, 0xEE, 0x8D, 0xEC, 0x3B, + 0xAF, 0xCB, 0x51, 0xC0, 0xDA, 0x37, 0xF1, 0x78, + 0x71, 0xF2, 0x34, 0xC4, 0xA0, 0xFB, 0x7F, 0xA6, + 0xD0, 0x70, 0x7A, 0x54, 0x3E, 0x3C, 0xBF, 0x3A, + 0xDB, 0x81, 0xE3, 0x0C, 0x1E, 0x0A, 0xE9, 0xE1, + 0xAC, 0xE7, 0x22, 0x3B, 0xDA, 0x99, 0xBD, 0x59, + 0x19, 0xA3, 0xCF, 0xCC, 0x92, 0xC6, 0xA7, 0x55, + 0xE4, 0x56, 0xF0, 0x93, 0x82, 0x3B, 0xD3, 0x3E + }, + { + 0x1B, 0x83, 0x7A, 0xF2, 0x33, 0xA8, 0xA6, 0x8B, + 0xE7, 0x09, 0x52, 0xF7, 0x83, 0xC4, 0x96, 0x1A, + 0x81, 0x52, 0xD1, 0xE0, 0xB0, 0xFA, 0x32, 0x5F, + 0xF0, 0x86, 0xEA, 0x5B, 0x5F, 0x13, 0x12, 0xB8, + 0x9C, 0x42, 0xE0, 0x1B, 0x8C, 0x3A, 0x47, 0x7C, + 0xB5, 0x40, 0xC0, 0x6B, 0x2F, 0x37, 0xEE, 0x0E, + 0x39, 0x24, 0xD7, 0x45, 0xB4, 0xFF, 0x5C, 0x6A, + 0xF7, 0xD6, 0x1E, 0x0E, 0x37, 0xAC, 0x19, 0x31 + }, + { + 0x78, 0x97, 0x88, 0x0C, 0x1E, 0xB0, 0x0F, 0xD2, + 0x56, 0x7A, 0xE8, 0xA5, 0x9E, 0x64, 0x82, 0xAF, + 0xE1, 0x73, 0x49, 0xCF, 0x93, 0x92, 0x4A, 0x91, + 0x5F, 0x8C, 0x59, 0x26, 0x93, 0xD4, 0x52, 0x07, + 0x55, 0x19, 0x68, 0x9D, 0xFC, 0xD2, 0x93, 0xE3, + 0x76, 0x89, 0x7B, 0x3B, 0x0E, 0x03, 0x6F, 0x11, + 0x4F, 0xE8, 0x1E, 0xBC, 0xB3, 0x15, 0x36, 0x71, + 0xBD, 0x23, 0xBC, 0x2B, 0xED, 0x46, 0xF9, 0xC2 + }, + { + 0xCA, 0x7B, 0x6C, 0x77, 0x5D, 0x20, 0x1E, 0x5B, + 0x5A, 0x77, 0x22, 0x61, 0xDE, 0x52, 0x8E, 0x47, + 0x5F, 0x4B, 0xDE, 0x51, 0x76, 0x60, 0x52, 0x9F, + 0x41, 0xBE, 0xEB, 0x15, 0x78, 0xB2, 0x4B, 0xCB, + 0x94, 0xB9, 0x41, 0x0F, 0x9B, 0xF3, 0x36, 0xC1, + 0x09, 0xF9, 0xD4, 0x70, 0x93, 0xA1, 0x0B, 0xA6, + 0xDE, 0xBE, 0x50, 0x43, 0x80, 0xD9, 0xD1, 0x50, + 0x73, 0xBD, 0xD1, 0x11, 0xC8, 0xD1, 0x29, 0xFA + }, + { + 0x57, 0x18, 0xE0, 0xD4, 0x5D, 0xEB, 0xC3, 0x00, + 0x2D, 0x52, 0xB2, 0x2C, 0x52, 0x73, 0x29, 0xAE, + 0x5E, 0xBF, 0x27, 0xE8, 0xFA, 0x9C, 0x8F, 0xEA, + 0xB4, 0x6C, 0x40, 0xBC, 0x64, 0x22, 0xCA, 0x03, + 0x35, 0x30, 0x4C, 0xF9, 0xE7, 0xF1, 0x41, 0xDE, + 0x7F, 0xA6, 0xAD, 0xB6, 0x78, 0x9B, 0xDB, 0xF3, + 0x8D, 0x14, 0xDA, 0xBA, 0x3E, 0x62, 0x97, 0xD2, + 0x5B, 0xF1, 0x7D, 0xE1, 0x70, 0xD6, 0xE3, 0xC8 + }, + { + 0x48, 0xD0, 0xED, 0x24, 0x9F, 0x90, 0x28, 0x41, + 0x99, 0x7C, 0x25, 0x5D, 0xAF, 0x99, 0x08, 0x9C, + 0x9A, 0x31, 0x24, 0x69, 0x8B, 0x16, 0x4A, 0x30, + 0x28, 0x33, 0x0F, 0xDD, 0x4C, 0xEE, 0x41, 0xE1, + 0x68, 0x3F, 0xA4, 0xD9, 0xDC, 0x66, 0xB2, 0xA7, + 0x9C, 0x8A, 0xA4, 0xC8, 0x28, 0x4E, 0x27, 0xBE, + 0xE2, 0xA4, 0x28, 0xA6, 0x71, 0x9D, 0x6E, 0xC6, + 0x55, 0xED, 0x76, 0x9D, 0xCB, 0x62, 0x4E, 0x24 + }, + { + 0x79, 0x4E, 0x0B, 0x64, 0xAC, 0xE1, 0xFE, 0x5A, + 0xE3, 0x79, 0x93, 0x70, 0x68, 0xD8, 0x2D, 0xF0, + 0x48, 0x68, 0x61, 0x6C, 0xAE, 0x0C, 0x17, 0xD3, + 0x05, 0x72, 0xC2, 0x02, 0x4E, 0x77, 0x48, 0x94, + 0xE0, 0x66, 0x8C, 0x47, 0x2D, 0x62, 0x3C, 0x90, + 0x3C, 0xC5, 0x88, 0x5F, 0x17, 0x84, 0x94, 0x51, + 0x10, 0x32, 0x9E, 0xB4, 0x98, 0xA8, 0x95, 0xA9, + 0xE5, 0x9A, 0x75, 0xE5, 0x27, 0x15, 0x8A, 0x5C + }, + { + 0x21, 0x79, 0xAA, 0x82, 0x0E, 0x03, 0xFA, 0x33, + 0xD9, 0xBD, 0xE5, 0x56, 0x8C, 0x26, 0x2E, 0x2D, + 0x34, 0x17, 0xA4, 0x02, 0xE0, 0x7A, 0x59, 0x1F, + 0x9D, 0x55, 0x70, 0x68, 0x2D, 0xB5, 0xF9, 0xBB, + 0xA4, 0xBB, 0x9D, 0x5A, 0x82, 0xEE, 0x5E, 0xFD, + 0xB4, 0xF6, 0x5B, 0xBB, 0xFE, 0xEE, 0x2F, 0x4A, + 0xB9, 0xE4, 0x6C, 0xF2, 0xCE, 0x7E, 0x3B, 0x05, + 0x43, 0x27, 0xA7, 0x18, 0xD3, 0xF1, 0x08, 0x06 + }, + { + 0xB0, 0xA4, 0x8C, 0x6A, 0xDA, 0x54, 0x87, 0x25, + 0x79, 0x9B, 0x59, 0x86, 0xBA, 0xB4, 0x32, 0x69, + 0x79, 0x60, 0x92, 0x24, 0xD8, 0x97, 0x18, 0x4B, + 0x89, 0x97, 0x10, 0x4E, 0x0C, 0x6A, 0x24, 0xB3, + 0xAB, 0xE5, 0x62, 0x16, 0x54, 0x22, 0xA4, 0x5D, + 0x8A, 0xC8, 0x19, 0xB9, 0x9D, 0x37, 0x56, 0xEB, + 0xBB, 0x64, 0xF8, 0x43, 0xE3, 0xE0, 0x93, 0x4D, + 0xEC, 0x48, 0x7A, 0xED, 0x12, 0x13, 0x72, 0x79 + }, + { + 0x84, 0x8D, 0x7F, 0x2E, 0xAD, 0x41, 0x29, 0x1D, + 0x05, 0x38, 0x68, 0x0C, 0x64, 0x9D, 0x07, 0x89, + 0x7E, 0x45, 0xC7, 0x0A, 0x0A, 0xA4, 0xF9, 0x35, + 0x3F, 0x82, 0xC3, 0xF6, 0xFB, 0xB8, 0xE8, 0x48, + 0x9C, 0x75, 0x3E, 0x90, 0xDB, 0xE8, 0x89, 0x00, + 0x41, 0xA1, 0xAE, 0xEF, 0x84, 0xCD, 0x31, 0x36, + 0x43, 0x4F, 0x53, 0x0E, 0x9D, 0xD9, 0xC2, 0x3F, + 0xA5, 0x4F, 0xE1, 0x24, 0xEA, 0xFB, 0x72, 0xAD + }, + { + 0x0E, 0xD1, 0x46, 0x26, 0xEE, 0x6D, 0x0C, 0x8E, + 0xD3, 0xF0, 0xC2, 0x00, 0xC1, 0x29, 0x85, 0x0F, + 0xFF, 0x76, 0x31, 0x8F, 0xFF, 0xA1, 0xDD, 0xD7, + 0xDD, 0x56, 0x3A, 0x01, 0xB7, 0x77, 0x97, 0x06, + 0x86, 0x2B, 0x23, 0x99, 0x59, 0xB6, 0x15, 0xAE, + 0x2E, 0xBE, 0x27, 0xC4, 0x50, 0x37, 0xE6, 0xFF, + 0xAF, 0x99, 0x14, 0xDA, 0x8F, 0xF2, 0x77, 0x2B, + 0xA5, 0xEE, 0x08, 0x11, 0xCD, 0x9E, 0xD5, 0x32 + }, + { + 0x52, 0x03, 0xC0, 0x76, 0x38, 0xC4, 0xB6, 0x5F, + 0x78, 0x43, 0x1E, 0x8B, 0x02, 0xE2, 0x0F, 0x6D, + 0x68, 0x3F, 0x19, 0xFA, 0x8F, 0x83, 0xB5, 0x13, + 0x4C, 0xD0, 0xF4, 0xE4, 0x68, 0xC9, 0x7E, 0xAC, + 0xB5, 0x26, 0x7C, 0x7D, 0x3E, 0xAB, 0x58, 0x3C, + 0xCA, 0xAC, 0xD0, 0xDB, 0xA4, 0xD5, 0x8A, 0xCE, + 0x52, 0x19, 0x3A, 0x51, 0x78, 0xA7, 0xB1, 0x2D, + 0x27, 0x95, 0xF5, 0xFD, 0xE8, 0xA3, 0x7B, 0xB9 + }, + { + 0x48, 0xBE, 0x43, 0xD5, 0xE0, 0x04, 0x36, 0x88, + 0xDF, 0x35, 0x32, 0xF7, 0x12, 0x1A, 0xFF, 0xFA, + 0x16, 0x7D, 0xAB, 0xE4, 0xA4, 0x84, 0xFB, 0x75, + 0xA0, 0x3A, 0xF3, 0x04, 0xA5, 0xC6, 0xF8, 0x25, + 0xF3, 0x6C, 0xEC, 0xCB, 0xBB, 0xC0, 0x75, 0xEE, + 0xF3, 0x20, 0xC4, 0xCD, 0x8D, 0x7E, 0xF8, 0xCB, + 0x49, 0xE6, 0xDD, 0x59, 0x73, 0x37, 0x9E, 0xEC, + 0x4C, 0x23, 0x3C, 0x45, 0x43, 0xD1, 0x32, 0xCE + }, + { + 0xB5, 0x46, 0x4E, 0x6A, 0xBA, 0xF5, 0xD3, 0xD4, + 0x08, 0x3D, 0x1D, 0x7D, 0x2A, 0x8B, 0x0B, 0xAB, + 0x78, 0xB6, 0x17, 0x09, 0x50, 0x0B, 0xBF, 0x77, + 0x82, 0x3F, 0x60, 0x2D, 0x57, 0xD5, 0x13, 0xCA, + 0x9E, 0x9F, 0xFF, 0x65, 0xEF, 0xAA, 0x89, 0x9C, + 0xFE, 0x7B, 0xF8, 0x8A, 0x01, 0x88, 0x82, 0x9C, + 0x24, 0xE4, 0x98, 0xAD, 0x00, 0x23, 0x5A, 0xBE, + 0x8E, 0xEF, 0xA7, 0x19, 0xFA, 0x6A, 0xE6, 0xF6 + }, + { + 0xAF, 0xE5, 0xE5, 0xE8, 0x3F, 0x19, 0xAD, 0xAD, + 0x9E, 0x95, 0x90, 0x3E, 0xA9, 0xB2, 0x98, 0x10, + 0x7D, 0x37, 0xDD, 0x38, 0x63, 0x2C, 0x95, 0x90, + 0xBB, 0xFF, 0xC6, 0x24, 0xD4, 0xDE, 0x95, 0x8C, + 0xB6, 0xB6, 0x1A, 0xF0, 0x80, 0xF0, 0x37, 0xAD, + 0x17, 0xD0, 0x35, 0xB6, 0xBF, 0x58, 0xF7, 0x80, + 0xFA, 0xDF, 0x70, 0xF3, 0xC9, 0x59, 0x66, 0x8A, + 0x1B, 0x47, 0x21, 0x98, 0xA5, 0x9A, 0x8A, 0x00 + }, + { + 0xEF, 0xA2, 0xC7, 0xC8, 0x02, 0xE2, 0x10, 0xD2, + 0xD8, 0x0F, 0xB3, 0x50, 0xB3, 0xC2, 0xCB, 0x31, + 0x56, 0x13, 0x18, 0x11, 0xE7, 0x18, 0xEE, 0xE5, + 0xC9, 0xC6, 0x64, 0x0F, 0x87, 0x68, 0x2A, 0x55, + 0x81, 0x2B, 0x10, 0xF4, 0x03, 0x10, 0xBA, 0xA7, + 0xB8, 0x2B, 0x27, 0x3E, 0xF3, 0xAC, 0xC5, 0x5F, + 0xED, 0xE0, 0xB5, 0xF1, 0x94, 0x9D, 0xE4, 0x29, + 0x3D, 0x91, 0xB5, 0x89, 0xA2, 0x17, 0x5F, 0xF7 + }, + { + 0xD6, 0xC6, 0x2A, 0x61, 0x82, 0x71, 0xF3, 0xBC, + 0xBE, 0x00, 0x79, 0x24, 0xA0, 0xC9, 0x81, 0x2F, + 0x83, 0x17, 0x44, 0x5F, 0xB6, 0xFB, 0x19, 0xEB, + 0x58, 0x9A, 0x62, 0x9F, 0x51, 0x2F, 0xB3, 0x8A, + 0x0B, 0x4E, 0x24, 0x7D, 0xEA, 0x88, 0xC5, 0x6A, + 0x1B, 0xAF, 0x17, 0x88, 0x33, 0x65, 0xB4, 0x36, + 0xF2, 0x84, 0x46, 0xFF, 0x66, 0xEA, 0x43, 0x18, + 0x0B, 0xD0, 0x1E, 0xB5, 0xA6, 0x50, 0x9B, 0xD5 + }, + { + 0x0B, 0x41, 0x16, 0x6B, 0xE6, 0x2F, 0x65, 0xE1, + 0x93, 0xB3, 0xB8, 0x65, 0xE6, 0xC4, 0x7A, 0xAD, + 0x26, 0x0A, 0xF5, 0xFC, 0xEE, 0xC9, 0xAB, 0x44, + 0xAB, 0xAA, 0x46, 0x0A, 0x0C, 0x02, 0x46, 0xB6, + 0xC6, 0x9B, 0x67, 0xD7, 0x1D, 0x3A, 0xDF, 0xEC, + 0x60, 0xDC, 0x8E, 0x77, 0x37, 0x2F, 0x09, 0x49, + 0x52, 0x34, 0x4F, 0xE1, 0x0C, 0x0D, 0x59, 0xEF, + 0xEC, 0x0E, 0x11, 0xC4, 0xA5, 0x16, 0x93, 0x6D + }, + { + 0x79, 0xD5, 0xF9, 0xFF, 0xC0, 0x5E, 0xCF, 0x33, + 0x7D, 0xE9, 0xF1, 0xE0, 0xF1, 0xD8, 0x9B, 0x30, + 0xAC, 0xFE, 0xBB, 0xB8, 0x8A, 0x69, 0x35, 0x86, + 0x78, 0x18, 0xCD, 0x8D, 0x45, 0xDA, 0x3D, 0x25, + 0x18, 0xDE, 0x61, 0xA7, 0xFE, 0x28, 0x75, 0x1B, + 0x61, 0x8F, 0x7A, 0x87, 0x5E, 0x11, 0x89, 0x8F, + 0xFF, 0x74, 0x15, 0x7A, 0xB9, 0x06, 0x81, 0xBD, + 0x53, 0xFA, 0x69, 0x62, 0x67, 0x1E, 0xD9, 0x9D + }, + { + 0xBE, 0xA9, 0x83, 0xD7, 0x6F, 0x24, 0xB1, 0xEE, + 0xDE, 0x1D, 0x06, 0x71, 0x48, 0x05, 0x76, 0x8F, + 0xAA, 0xAD, 0x47, 0x08, 0xC9, 0xA4, 0xFF, 0x9C, + 0xD2, 0x42, 0x2F, 0x70, 0x6B, 0x6F, 0x0C, 0x30, + 0x6D, 0x8B, 0x67, 0xF3, 0x40, 0x89, 0xC6, 0x5E, + 0xD3, 0x88, 0x0C, 0x75, 0xF6, 0x7B, 0xBC, 0x4D, + 0x89, 0xAD, 0x87, 0x12, 0x0A, 0x77, 0xD0, 0xFF, + 0xE4, 0x36, 0xFB, 0x7B, 0x58, 0xB2, 0xCA, 0x41 + }, + { + 0x46, 0x6F, 0xD9, 0x15, 0xEF, 0xD9, 0x50, 0xBC, + 0x96, 0x65, 0x78, 0xCD, 0x92, 0xC6, 0x85, 0x92, + 0x9D, 0x7B, 0x51, 0xA6, 0x3D, 0xB1, 0x42, 0xC7, + 0xB9, 0xA9, 0x3D, 0x16, 0x52, 0x04, 0x95, 0x31, + 0x9B, 0x87, 0xF6, 0x58, 0xE6, 0xAF, 0xDA, 0x1B, + 0x42, 0x77, 0x3E, 0x2D, 0x49, 0xDA, 0x81, 0x45, + 0x94, 0xA5, 0x54, 0x90, 0x89, 0xEF, 0xB1, 0xF3, + 0xAB, 0x5F, 0x15, 0x90, 0xCA, 0x0A, 0x02, 0xAF + }, + { + 0xF6, 0x46, 0x11, 0x13, 0x7A, 0xD2, 0x95, 0x46, + 0x70, 0xEA, 0xEC, 0xD6, 0x26, 0xD2, 0x12, 0xCF, + 0xC5, 0xB9, 0xF6, 0xBB, 0x41, 0xAA, 0xEB, 0xB1, + 0xD7, 0x1E, 0x89, 0x79, 0x2E, 0xB1, 0x31, 0x7A, + 0xED, 0xC6, 0x38, 0x13, 0xFE, 0x63, 0xDE, 0x40, + 0x17, 0x98, 0xDF, 0x75, 0x6C, 0xA1, 0xF2, 0x20, + 0x35, 0xA0, 0xFA, 0xBD, 0x37, 0xFB, 0x11, 0x03, + 0x43, 0x7F, 0x89, 0x1E, 0xAD, 0x5E, 0x64, 0x29 + }, + { + 0x32, 0xE1, 0xF9, 0x38, 0xA2, 0x7F, 0xAA, 0xD8, + 0xAC, 0x4A, 0x13, 0xFD, 0x4F, 0x6A, 0x8B, 0xF3, + 0xDA, 0xBE, 0x4B, 0xC7, 0x2A, 0xF1, 0x1C, 0x8F, + 0x0E, 0x1A, 0x06, 0x56, 0x7E, 0xD7, 0x04, 0xB8, + 0xE7, 0x8E, 0x11, 0x40, 0xA0, 0xC7, 0x72, 0x4E, + 0x3E, 0xFB, 0x70, 0xD2, 0x38, 0x07, 0xCF, 0x38, + 0xE6, 0x27, 0xE3, 0x26, 0xAF, 0xC1, 0x64, 0xCD, + 0xED, 0x52, 0xB4, 0x41, 0x39, 0xFF, 0xB3, 0xF3 + }, + { + 0x48, 0x33, 0xAC, 0x92, 0xE3, 0x02, 0xAC, 0x2B, + 0x67, 0xB0, 0x2B, 0x88, 0x27, 0x14, 0x3B, 0xAD, + 0xA1, 0x5C, 0xED, 0x22, 0x0E, 0x1D, 0x1F, 0x5B, + 0x71, 0x12, 0x0C, 0x51, 0xEE, 0x54, 0xC1, 0x9D, + 0x30, 0x1F, 0x29, 0x60, 0xBD, 0xB5, 0xA2, 0xCE, + 0x27, 0xD4, 0x41, 0xD1, 0x4A, 0xF0, 0x80, 0xCB, + 0x01, 0x0A, 0x8A, 0x23, 0xEE, 0xFF, 0x58, 0x11, + 0xDF, 0xA4, 0x4D, 0x1D, 0x7B, 0x35, 0x8B, 0x48 + }, + { + 0x9A, 0x03, 0x88, 0xCE, 0xE1, 0xAD, 0x01, 0x46, + 0x17, 0x7C, 0x48, 0xB5, 0xA0, 0x8A, 0x2D, 0xB3, + 0xC4, 0x89, 0xE8, 0x4C, 0xE2, 0xAB, 0xA8, 0xC6, + 0x45, 0x11, 0x2A, 0x02, 0x1E, 0x41, 0x1C, 0xF8, + 0x29, 0x12, 0x7F, 0xA2, 0xF1, 0xD1, 0xAE, 0x1B, + 0xAF, 0x3A, 0x33, 0xEA, 0x53, 0x09, 0x84, 0x77, + 0xA7, 0xD1, 0x2B, 0xA7, 0x48, 0xD2, 0xAF, 0x24, + 0xD1, 0x66, 0x02, 0xE9, 0x19, 0x07, 0x76, 0x23 + }, + { + 0xE3, 0xDF, 0x00, 0x74, 0xA9, 0x37, 0x35, 0x13, + 0x0D, 0x99, 0x22, 0xD2, 0xBE, 0x91, 0x6F, 0x35, + 0x34, 0x3D, 0x98, 0x8C, 0xE5, 0x9D, 0x76, 0x97, + 0x15, 0xA9, 0x83, 0xB4, 0xBA, 0x80, 0x7C, 0xE1, + 0xEE, 0x70, 0xA3, 0x13, 0xE5, 0x92, 0x31, 0x58, + 0x4F, 0x55, 0x6E, 0xBB, 0xA1, 0xB9, 0x0B, 0x1B, + 0xB6, 0xA6, 0xC5, 0x81, 0xA4, 0xB4, 0x7C, 0x3F, + 0xF5, 0x21, 0x89, 0x65, 0x2A, 0xAB, 0x36, 0xF5 + }, + { + 0x91, 0x91, 0xCF, 0x46, 0x1B, 0x69, 0x59, 0xBE, + 0xC9, 0x3E, 0xAE, 0x7F, 0xB1, 0xC6, 0xE3, 0x70, + 0x73, 0xD1, 0xA6, 0x15, 0x27, 0xAD, 0x75, 0xD1, + 0x0B, 0x7F, 0x89, 0x49, 0xD9, 0xB8, 0xAF, 0x70, + 0xA2, 0x3A, 0xD1, 0x31, 0x2E, 0xD5, 0x1F, 0x70, + 0xF0, 0xE9, 0xDF, 0x60, 0x1D, 0xDA, 0xE2, 0x38, + 0x90, 0x6C, 0x0F, 0xE3, 0xF7, 0x66, 0xB1, 0x4F, + 0x11, 0x3B, 0x26, 0xBC, 0x85, 0x42, 0xD1, 0xD2 + }, + { + 0x2A, 0x8B, 0xAD, 0xE2, 0x72, 0xEE, 0x7A, 0xC6, + 0x43, 0xC5, 0xE3, 0x71, 0x47, 0xFA, 0xAC, 0x92, + 0xC3, 0x97, 0x0B, 0xD3, 0x86, 0x2F, 0x53, 0x1E, + 0x5D, 0xCE, 0xA5, 0xCE, 0xAC, 0xD1, 0x83, 0x74, + 0x53, 0xAA, 0x49, 0x8D, 0x78, 0x5B, 0x4D, 0x1F, + 0x89, 0xE1, 0xB2, 0xA7, 0x39, 0xCA, 0x4A, 0x38, + 0x49, 0x87, 0x30, 0x27, 0x46, 0xB4, 0xF1, 0x13, + 0x42, 0x43, 0x02, 0xC4, 0xA1, 0xE0, 0xF9, 0xDF + }, + { + 0x32, 0x3E, 0x67, 0x93, 0xC7, 0xDD, 0x9B, 0x4D, + 0x7B, 0xB7, 0xFB, 0xF2, 0x15, 0x31, 0xD3, 0x7F, + 0x72, 0x64, 0x53, 0x2C, 0x58, 0xF1, 0x22, 0x55, + 0x48, 0xD0, 0x6E, 0x69, 0x40, 0xC6, 0x3E, 0x91, + 0x27, 0x09, 0x90, 0xE7, 0xF5, 0x64, 0x32, 0x03, + 0xC9, 0x87, 0x64, 0x7E, 0x5C, 0xF6, 0x61, 0x03, + 0xE7, 0x9B, 0x71, 0x4C, 0x58, 0x1B, 0xD8, 0x77, + 0x2E, 0x19, 0xD0, 0xF0, 0x05, 0xDC, 0x86, 0x33 + }, + { + 0xF9, 0x22, 0x07, 0x6D, 0x29, 0x5D, 0x23, 0xE2, + 0x98, 0x58, 0x30, 0xAA, 0xD2, 0xF2, 0x3F, 0x65, + 0x2F, 0x7F, 0x4D, 0xB4, 0x2C, 0x11, 0x9E, 0xD2, + 0x20, 0xA5, 0x45, 0x14, 0x88, 0xA4, 0x53, 0xF5, + 0x9F, 0xA8, 0xA2, 0xDE, 0x23, 0x03, 0x00, 0x0D, + 0x6B, 0xFD, 0x8C, 0x48, 0x23, 0xA8, 0x5F, 0xAD, + 0xB4, 0xFB, 0x8E, 0x7E, 0xAC, 0x12, 0x2B, 0xF0, + 0x12, 0x47, 0xD7, 0x6F, 0x65, 0x24, 0x7D, 0x45 + }, + { + 0xDC, 0x40, 0x00, 0x95, 0x60, 0x95, 0x92, 0x91, + 0x55, 0x8E, 0xBE, 0x07, 0x20, 0x64, 0xCE, 0x67, + 0x12, 0xC9, 0x21, 0xB5, 0x40, 0x9B, 0x44, 0xE0, + 0x4F, 0x9A, 0x56, 0x5E, 0xEA, 0xDD, 0x39, 0xA7, + 0x71, 0x6E, 0x21, 0xB4, 0x6D, 0xD8, 0x61, 0x65, + 0x17, 0xA2, 0x1A, 0x0C, 0x03, 0x41, 0x9E, 0x94, + 0xDB, 0x82, 0x0A, 0x35, 0x3F, 0x15, 0x2D, 0x10, + 0x83, 0x84, 0xBE, 0x94, 0x70, 0x09, 0x3F, 0x89 + }, + { + 0x7F, 0xA4, 0xBE, 0x91, 0xCA, 0x52, 0x07, 0xFF, + 0x08, 0x7D, 0xE9, 0x2F, 0x1D, 0xB0, 0x9B, 0xF7, + 0x1A, 0x67, 0x87, 0x8B, 0xED, 0x19, 0x3A, 0x5C, + 0x2C, 0xC4, 0xE3, 0x53, 0x23, 0xB8, 0xDF, 0x99, + 0xA2, 0x6E, 0xCB, 0x98, 0x88, 0xD7, 0xB3, 0x4A, + 0x73, 0x9D, 0x64, 0x1A, 0x0E, 0xCD, 0x0A, 0x66, + 0x47, 0xA6, 0xA0, 0x64, 0x26, 0xF3, 0xCC, 0x1F, + 0xEF, 0xDF, 0x90, 0x69, 0x92, 0x2F, 0xAE, 0x4C + }, + { + 0xBA, 0xD3, 0xCD, 0x75, 0x90, 0x5D, 0x7B, 0xFD, + 0xA3, 0x32, 0x2B, 0x44, 0xA7, 0xD3, 0x58, 0x87, + 0x14, 0xD3, 0x33, 0xEE, 0x86, 0x85, 0x5A, 0x87, + 0x27, 0x47, 0xE7, 0x04, 0xF6, 0x11, 0x94, 0x84, + 0xBD, 0xB7, 0xD0, 0x77, 0xFA, 0x08, 0xED, 0xC4, + 0xA7, 0x9D, 0xE0, 0xF4, 0x3F, 0xCA, 0x8D, 0x43, + 0x6E, 0x8A, 0x10, 0x08, 0x57, 0xF5, 0x9B, 0xC7, + 0xB0, 0x55, 0xB9, 0x87, 0xF9, 0x7A, 0xC6, 0xB9 + }, + { + 0xB7, 0xDE, 0xE8, 0xE8, 0x33, 0x9D, 0xB2, 0x97, + 0xFD, 0xAA, 0x3C, 0xA5, 0xC1, 0xDC, 0x19, 0x88, + 0xD9, 0x7F, 0x5F, 0xB6, 0x20, 0x8C, 0x64, 0xDE, + 0xA9, 0x5E, 0x1C, 0x78, 0xF3, 0x37, 0xCE, 0x20, + 0xA2, 0xB4, 0xDF, 0x17, 0xA7, 0xB8, 0x23, 0x6A, + 0x90, 0xD6, 0x28, 0x67, 0x33, 0x16, 0x35, 0x72, + 0xC8, 0x67, 0xD9, 0x3D, 0xE8, 0x9E, 0xF6, 0x2F, + 0xA0, 0x5D, 0xAB, 0x70, 0x7E, 0xC3, 0xA7, 0x70 + }, + { + 0xA0, 0xF7, 0xE9, 0x3C, 0xF3, 0x25, 0x02, 0xB9, + 0xFD, 0x79, 0xEC, 0x20, 0x54, 0x62, 0x07, 0xF3, + 0x31, 0xC5, 0x29, 0x9E, 0xCE, 0xF3, 0x50, 0xD6, + 0x6E, 0xA8, 0x55, 0xC8, 0x7F, 0xBD, 0xDF, 0x18, + 0xE6, 0x91, 0xC2, 0x0D, 0x04, 0x5A, 0x30, 0x8F, + 0x83, 0xF6, 0xCB, 0x8F, 0xCA, 0x69, 0xD7, 0xE2, + 0xB3, 0x9B, 0x34, 0xD2, 0xF8, 0x77, 0x27, 0x6C, + 0x19, 0x6B, 0xF5, 0x14, 0xBA, 0xC6, 0x02, 0x70 + }, + { + 0x6F, 0x50, 0x93, 0xCF, 0xC8, 0x83, 0x00, 0xBF, + 0x68, 0x8E, 0x88, 0x4B, 0x4C, 0x5E, 0xC2, 0xC3, + 0x1A, 0x8C, 0xC2, 0x8D, 0x63, 0x31, 0xAD, 0x7C, + 0xA7, 0x1D, 0x97, 0x60, 0x21, 0x64, 0x82, 0x05, + 0x28, 0x15, 0xD4, 0x4F, 0xC6, 0x9E, 0x18, 0xA8, + 0xDC, 0x8B, 0xD7, 0x1B, 0x31, 0xF2, 0xB5, 0x89, + 0xA7, 0xC0, 0x78, 0x0B, 0x61, 0x99, 0x38, 0x5F, + 0x8D, 0xAE, 0x6C, 0x9B, 0x79, 0x74, 0xC4, 0xCB + }, + { + 0x3C, 0xFF, 0x46, 0xAC, 0x35, 0x46, 0xF6, 0x5A, + 0xD7, 0xA7, 0x20, 0x87, 0x1A, 0xFA, 0x20, 0xA9, + 0x21, 0x6D, 0xDA, 0x5C, 0x45, 0x18, 0x81, 0x56, + 0xA5, 0xBB, 0xED, 0xF2, 0x15, 0x46, 0xD4, 0xBB, + 0x39, 0x40, 0xB2, 0x1A, 0x41, 0xA3, 0x94, 0x03, + 0xE3, 0xCF, 0xD5, 0xE7, 0xA0, 0xE7, 0x90, 0x4D, + 0xA9, 0x5F, 0x4D, 0x8E, 0x0C, 0x5B, 0xF5, 0xB7, + 0x0E, 0xB0, 0x29, 0x55, 0x6E, 0xFD, 0x49, 0x7E + }, + { + 0xAF, 0x66, 0x8A, 0x80, 0x5E, 0x6D, 0x70, 0x4B, + 0x1E, 0x58, 0x1F, 0x1E, 0x8E, 0x3C, 0x00, 0xCF, + 0x4C, 0xF3, 0xE5, 0x46, 0x14, 0x7C, 0x40, 0x6D, + 0x17, 0xCA, 0x97, 0x4D, 0x19, 0xA0, 0x14, 0xC7, + 0x8B, 0x44, 0xE7, 0x2D, 0xDE, 0xEB, 0x65, 0x26, + 0x07, 0xE8, 0x6D, 0x69, 0x02, 0x59, 0xDC, 0xAB, + 0x0D, 0xDA, 0x81, 0xC7, 0x7C, 0x7E, 0xE2, 0x72, + 0x1E, 0x82, 0xBB, 0xB1, 0x39, 0x43, 0x07, 0x1D + }, + { + 0x79, 0xDD, 0xEB, 0x5C, 0x54, 0xDE, 0xD1, 0xE4, + 0x48, 0x40, 0x71, 0xC4, 0x6B, 0xB4, 0x28, 0x02, + 0xD2, 0x3B, 0x3A, 0x08, 0xC1, 0x23, 0x11, 0xBE, + 0x36, 0x3C, 0x7C, 0x7A, 0x02, 0x5A, 0x17, 0x64, + 0xC8, 0xD8, 0x50, 0x69, 0xFD, 0xA8, 0xD5, 0x17, + 0x77, 0x7D, 0x8D, 0xD8, 0x09, 0xE3, 0xD4, 0xA9, + 0x56, 0x04, 0x1A, 0x70, 0x79, 0xF9, 0x16, 0x7B, + 0x0F, 0xE9, 0x71, 0x2E, 0x5F, 0x12, 0x29, 0xF5 + }, + { + 0x99, 0x8E, 0x82, 0xF4, 0x26, 0x3D, 0x53, 0xAE, + 0xDA, 0xC9, 0x39, 0xEB, 0xB6, 0xEB, 0x8B, 0x19, + 0x69, 0x74, 0x6C, 0xB8, 0x15, 0xBD, 0x72, 0x1F, + 0x17, 0xA4, 0x8B, 0xEE, 0x9E, 0xCF, 0xF2, 0xFE, + 0x59, 0x8C, 0x53, 0x9C, 0x41, 0x9A, 0x60, 0xE0, + 0xD5, 0xA0, 0x4F, 0x1C, 0xB5, 0x23, 0xA2, 0xFD, + 0x05, 0x38, 0xBB, 0x17, 0x8E, 0x44, 0x75, 0x8D, + 0x31, 0x59, 0xAB, 0x9E, 0x02, 0x84, 0x01, 0xA3 + }, + { + 0x33, 0x96, 0xCF, 0xD5, 0xCD, 0xE1, 0x4A, 0xEC, + 0x1A, 0xAE, 0xD3, 0xE1, 0x22, 0x52, 0xCF, 0xD6, + 0xE3, 0x42, 0xED, 0x25, 0x5E, 0x8E, 0x9E, 0x1B, + 0xE1, 0x0F, 0x1F, 0x27, 0x38, 0x77, 0xF3, 0x63, + 0x33, 0x81, 0xE3, 0xC9, 0x61, 0xE6, 0x7E, 0xC4, + 0x1E, 0x8F, 0x9E, 0x16, 0x11, 0x0F, 0xC0, 0x3D, + 0xDE, 0x88, 0xBF, 0xC0, 0x96, 0xFC, 0x15, 0x14, + 0x46, 0x1D, 0x70, 0xD0, 0xBE, 0xCE, 0x0A, 0xF6 + }, + { + 0x77, 0x7D, 0x9D, 0xC5, 0x5A, 0x2F, 0x57, 0xA4, + 0x6E, 0xA0, 0x6A, 0x2F, 0x4C, 0xB9, 0x76, 0x0D, + 0x00, 0xD7, 0xA8, 0x62, 0xD0, 0xA2, 0xAA, 0x19, + 0x46, 0x7B, 0x57, 0x0F, 0x7C, 0x7D, 0x5E, 0xA7, + 0x62, 0x9A, 0x95, 0xEB, 0x20, 0x0E, 0x1F, 0x9D, + 0xB0, 0x66, 0x10, 0xCF, 0x8E, 0x30, 0xD5, 0xE6, + 0xAD, 0x0A, 0x7B, 0x63, 0x29, 0x77, 0xFC, 0x21, + 0xBB, 0x17, 0x89, 0x67, 0xF3, 0xB0, 0xE0, 0x9B + }, + { + 0x32, 0xEE, 0x35, 0x7F, 0xC9, 0x16, 0x36, 0xA8, + 0x55, 0xBA, 0x01, 0xA0, 0xB8, 0xDA, 0x6F, 0x35, + 0x53, 0xB1, 0xD5, 0x20, 0xAD, 0xCF, 0xE8, 0xFE, + 0x9D, 0xEB, 0xCC, 0xB2, 0x6C, 0x5C, 0x4C, 0xE8, + 0x50, 0x5B, 0xB1, 0xEF, 0xB5, 0xED, 0x5B, 0xAA, + 0x4C, 0x52, 0x45, 0xB5, 0x0D, 0x74, 0x46, 0x3F, + 0x07, 0x67, 0xB2, 0xC7, 0x83, 0xC4, 0x7A, 0x93, + 0xB0, 0xFD, 0xA6, 0x68, 0x95, 0x69, 0x3C, 0xE6 + }, + { + 0x34, 0x0C, 0x0A, 0x7C, 0xE4, 0x96, 0xFE, 0xBD, + 0xA1, 0x3F, 0xA2, 0x40, 0x7A, 0x21, 0xDC, 0x19, + 0x83, 0x9B, 0xED, 0xAE, 0x1A, 0x08, 0x6A, 0xD0, + 0xFE, 0xD3, 0x91, 0x7D, 0xF9, 0xBF, 0x40, 0x94, + 0x4A, 0x78, 0x7F, 0x64, 0x1E, 0x90, 0xDD, 0xBA, + 0xE0, 0x3A, 0x93, 0x37, 0x72, 0x3E, 0x51, 0x66, + 0x8F, 0xB8, 0x93, 0x77, 0x2C, 0x0F, 0xBD, 0xB3, + 0xEB, 0x7E, 0xF7, 0x90, 0xDF, 0xCB, 0xB9, 0xAB + }, + { + 0xD8, 0x6A, 0x5B, 0xAA, 0x33, 0x65, 0xAB, 0xD8, + 0xF4, 0x42, 0xCD, 0x6E, 0xBB, 0x93, 0x11, 0x38, + 0x19, 0xF0, 0xB4, 0x60, 0x61, 0xE1, 0x34, 0x04, + 0xEF, 0xAA, 0x1A, 0x58, 0xE1, 0xFF, 0x27, 0x2A, + 0xD4, 0xBF, 0xD3, 0x08, 0x15, 0xAD, 0xD8, 0x8A, + 0xD9, 0x8F, 0xCE, 0x9A, 0xF0, 0x18, 0x37, 0x4C, + 0xA6, 0x0D, 0x89, 0x79, 0x0F, 0x71, 0xA6, 0x07, + 0x5F, 0x3D, 0x68, 0xD3, 0x20, 0x21, 0xA9, 0xEB + }, + { + 0xA6, 0x7E, 0x6E, 0xC6, 0x57, 0xC9, 0x5E, 0xAB, + 0x3C, 0x3C, 0x32, 0xE4, 0x1F, 0xBF, 0x39, 0xCF, + 0x20, 0x33, 0xAB, 0x4B, 0xE2, 0xE2, 0xB8, 0x21, + 0x10, 0x4A, 0xDB, 0xE6, 0x9D, 0x16, 0xE9, 0x48, + 0xDC, 0xE4, 0xC4, 0xC6, 0xA3, 0xCF, 0x22, 0x76, + 0x90, 0x1F, 0x7D, 0x4F, 0xFD, 0x69, 0x65, 0x46, + 0x49, 0x88, 0x2C, 0x01, 0x4D, 0x2C, 0x10, 0xA1, + 0x30, 0x2B, 0x79, 0xC6, 0x15, 0x69, 0xCD, 0x36 + }, + { + 0x55, 0xCE, 0x19, 0x2A, 0xE4, 0xB3, 0xEA, 0xF8, + 0x55, 0x59, 0x0E, 0x2D, 0x44, 0xE6, 0x25, 0xD9, + 0xBA, 0x14, 0x6E, 0xB7, 0x50, 0x48, 0xE6, 0xB5, + 0x6E, 0x02, 0x50, 0x31, 0xEF, 0xBA, 0x0B, 0xDA, + 0x8A, 0xAA, 0xFA, 0x04, 0x70, 0xB7, 0xAC, 0x3D, + 0x40, 0x6E, 0x5A, 0xBA, 0x3E, 0x83, 0x2F, 0x27, + 0xA5, 0x07, 0x24, 0x6D, 0x1B, 0x5F, 0x33, 0xDE, + 0xA1, 0xF7, 0x24, 0xE2, 0xB8, 0x1B, 0x0C, 0x98 + }, + { + 0xB3, 0xA2, 0x0C, 0x1F, 0xB0, 0xB4, 0xF0, 0xD3, + 0x77, 0x26, 0xC2, 0x3B, 0x58, 0x77, 0xDD, 0x8E, + 0x72, 0xF6, 0x98, 0x86, 0xE0, 0x9A, 0x8C, 0x68, + 0xCF, 0xC3, 0x01, 0xD2, 0xA3, 0xF2, 0xF9, 0x5C, + 0xEF, 0xCF, 0xAB, 0xB8, 0x88, 0x99, 0x03, 0xC7, + 0x32, 0xF4, 0xE8, 0x14, 0x32, 0xD3, 0xF6, 0x78, + 0xCC, 0xDF, 0xC3, 0x98, 0xAC, 0xD8, 0xA2, 0xF0, + 0x66, 0x41, 0x10, 0x04, 0x50, 0xD8, 0x9F, 0x32 + }, + { + 0xF7, 0x27, 0x2D, 0x93, 0xC7, 0x01, 0x2D, 0x38, + 0xB2, 0x7F, 0x0C, 0x9A, 0xE2, 0x01, 0x79, 0x58, + 0xBB, 0xA6, 0x66, 0xA9, 0xDE, 0x1E, 0x88, 0x12, + 0xE9, 0x74, 0x37, 0xAE, 0xB2, 0xE0, 0x3C, 0x99, + 0x94, 0x38, 0xF0, 0xBE, 0x33, 0x3D, 0x09, 0xAD, + 0xDB, 0xCF, 0xAA, 0xC7, 0xAA, 0x73, 0xF7, 0xB6, + 0xCC, 0xEC, 0x67, 0xDC, 0x07, 0x79, 0x98, 0xDE, + 0xDB, 0x8C, 0x13, 0x32, 0xBA, 0xC0, 0xFB, 0xA8 + }, + { + 0x1F, 0xE7, 0xB3, 0xDE, 0x34, 0xC0, 0x47, 0x9C, + 0xA8, 0x40, 0x5F, 0x3C, 0xBC, 0xD2, 0xDB, 0x64, + 0xBB, 0x18, 0xDB, 0xB2, 0x91, 0xA5, 0xFE, 0xAA, + 0x16, 0xC5, 0x22, 0x8C, 0x93, 0xEE, 0x21, 0xC7, + 0x11, 0xD6, 0x8A, 0x01, 0x0C, 0x2A, 0xE8, 0x80, + 0x05, 0xEB, 0xAC, 0x95, 0x9E, 0x3A, 0x32, 0x24, + 0x52, 0xF8, 0x62, 0xDD, 0xE9, 0x4B, 0xB9, 0x41, + 0x81, 0x3E, 0x52, 0x4D, 0x23, 0x47, 0xFE, 0xEE + }, + { + 0x4E, 0xE1, 0xD3, 0x88, 0x05, 0xC3, 0x22, 0x84, + 0xEC, 0xEB, 0xE9, 0x2E, 0x3D, 0xF6, 0xCD, 0x98, + 0xC7, 0xD6, 0x68, 0x0E, 0xAB, 0x0D, 0x68, 0x66, + 0x4F, 0x96, 0x70, 0x6C, 0x45, 0x63, 0x3B, 0x1E, + 0x26, 0x82, 0x22, 0xAA, 0x5A, 0x52, 0x79, 0xEF, + 0x01, 0xFC, 0x28, 0x54, 0x32, 0xAB, 0xEE, 0xD7, + 0x4B, 0xA3, 0xDF, 0x18, 0x9F, 0x50, 0xA9, 0x89, + 0xD5, 0x8E, 0x71, 0x30, 0x62, 0x2D, 0xAA, 0x59 + }, + { + 0x0E, 0x14, 0x05, 0x87, 0x1C, 0x87, 0xA5, 0xEA, + 0x40, 0x83, 0x42, 0xF3, 0x9D, 0x34, 0x94, 0xF9, + 0x39, 0xF7, 0x3C, 0x22, 0x60, 0xC2, 0xA4, 0x3A, + 0x5C, 0x9F, 0x1B, 0x57, 0x33, 0x0C, 0xCA, 0x40, + 0x93, 0xFC, 0x1F, 0x42, 0xF9, 0x6D, 0x83, 0x00, + 0x56, 0x77, 0x03, 0x7D, 0xB5, 0x1A, 0xEF, 0x26, + 0xF0, 0x54, 0x38, 0x05, 0x7A, 0xE7, 0x9E, 0xD1, + 0x44, 0x64, 0xFD, 0x8E, 0x57, 0xD1, 0x55, 0x86 + }, + { + 0x17, 0xC5, 0xCA, 0xB4, 0x09, 0x10, 0x73, 0x62, + 0x1B, 0x5C, 0x24, 0xC3, 0x36, 0x31, 0x6D, 0x0C, + 0xF6, 0x49, 0xBA, 0x1E, 0xFF, 0xEB, 0xFC, 0x87, + 0xE0, 0x43, 0x9C, 0xDF, 0x57, 0x88, 0x87, 0xB2, + 0x21, 0x65, 0x6D, 0x33, 0x9A, 0x6F, 0xD1, 0x98, + 0xAB, 0xAE, 0xE6, 0x7E, 0xA1, 0x88, 0xDD, 0x66, + 0x56, 0x78, 0x23, 0xFC, 0x22, 0x0C, 0x52, 0xB5, + 0x74, 0x90, 0x25, 0x14, 0x69, 0xD2, 0x5D, 0x8C + }, + { + 0x57, 0xDC, 0x27, 0x97, 0xD1, 0x42, 0x68, 0x1C, + 0x94, 0xFE, 0x48, 0x86, 0x26, 0x98, 0x6E, 0xD4, + 0xB2, 0x67, 0x03, 0xCB, 0xF6, 0xBF, 0xE5, 0x93, + 0x91, 0x64, 0x36, 0x57, 0x06, 0x5B, 0x2D, 0x46, + 0xE4, 0xB1, 0xDD, 0xB3, 0xAA, 0x83, 0x2C, 0x9B, + 0xD4, 0x49, 0x75, 0x5A, 0xC8, 0xB1, 0xBF, 0x93, + 0x68, 0x97, 0xFB, 0xC6, 0xAD, 0xE3, 0x78, 0xF2, + 0xBD, 0x64, 0x93, 0xE4, 0x86, 0xF4, 0x20, 0x29 + }, + { + 0x44, 0x12, 0xDD, 0x6B, 0xED, 0x6D, 0xB2, 0xA8, + 0x03, 0xC2, 0xE0, 0xDF, 0x8F, 0x58, 0x29, 0xE7, + 0xA4, 0xB0, 0x41, 0x78, 0x89, 0x51, 0x0D, 0xF7, + 0xDF, 0xEE, 0x49, 0x57, 0x4A, 0x71, 0xEC, 0x0D, + 0x9E, 0x0D, 0x46, 0x06, 0x50, 0x17, 0xC7, 0x2D, + 0xD9, 0x74, 0x39, 0x33, 0xCA, 0x83, 0x9A, 0x76, + 0x8D, 0xD1, 0x5A, 0xB0, 0xB7, 0xC1, 0x4C, 0x62, + 0x6A, 0x35, 0x41, 0x09, 0x69, 0x01, 0x96, 0xAE + }, + { + 0xD0, 0xEB, 0xC7, 0x71, 0x03, 0x1B, 0x7C, 0x16, + 0x00, 0x21, 0xC9, 0xB6, 0xFB, 0xB2, 0xB6, 0x70, + 0xE3, 0xB4, 0x02, 0x70, 0x02, 0x69, 0x07, 0xA3, + 0x91, 0x63, 0xDB, 0x18, 0x73, 0xEC, 0xC3, 0xB8, + 0x00, 0x11, 0x1D, 0xD7, 0xBF, 0x13, 0x8F, 0x83, + 0xA6, 0x10, 0xDC, 0x04, 0x6D, 0xA2, 0x68, 0xB7, + 0x2B, 0x8C, 0x90, 0x86, 0x92, 0x23, 0x77, 0xDB, + 0xED, 0x73, 0x94, 0x82, 0x43, 0xCA, 0x1E, 0x14 + }, + { + 0x10, 0xC4, 0xBA, 0x31, 0x55, 0x91, 0x69, 0x8D, + 0xFB, 0x91, 0xA5, 0x73, 0x37, 0x63, 0x18, 0x84, + 0xB4, 0x73, 0x8D, 0x9F, 0x59, 0x80, 0x78, 0x51, + 0xA6, 0x79, 0x84, 0x0C, 0xC2, 0x87, 0xAC, 0xE3, + 0x01, 0x1C, 0xCD, 0xC8, 0xF4, 0xA4, 0x85, 0xBB, + 0x19, 0x73, 0x40, 0x4E, 0xF9, 0xEE, 0x9B, 0x9C, + 0xF1, 0xEA, 0xDB, 0xC5, 0x40, 0x74, 0xC6, 0xD1, + 0x13, 0xDE, 0x8F, 0xC9, 0x1D, 0x07, 0x97, 0xEB + }, + { + 0x14, 0x64, 0x34, 0x7B, 0xE3, 0x2C, 0x79, 0x59, + 0x17, 0x2B, 0x74, 0x72, 0xD1, 0x1F, 0xE0, 0x78, + 0x44, 0xA5, 0x2E, 0x2D, 0x3B, 0x2D, 0x05, 0x8C, + 0xC6, 0xBC, 0xC0, 0xA8, 0xA2, 0x75, 0xD6, 0xB8, + 0x2B, 0x2D, 0x62, 0x63, 0x75, 0x5E, 0xAF, 0x2A, + 0x65, 0x88, 0xB6, 0xA1, 0xEB, 0x79, 0x9A, 0xF8, + 0x3A, 0x4C, 0xE7, 0x53, 0xF8, 0xC7, 0x5A, 0x22, + 0x84, 0xD0, 0x28, 0x5B, 0xAB, 0x5F, 0x7C, 0x1C + }, + { + 0xF4, 0x09, 0x23, 0x1E, 0xD1, 0x87, 0xF5, 0xC4, + 0xE8, 0x33, 0xFA, 0x9E, 0x30, 0x42, 0xAC, 0xA6, + 0xC8, 0x58, 0xB0, 0x8B, 0x49, 0x6B, 0x25, 0x31, + 0xF8, 0x4F, 0xD5, 0xCE, 0xA9, 0x3E, 0xCD, 0x06, + 0xDA, 0xFE, 0x0A, 0x10, 0xC3, 0xFF, 0x23, 0x76, + 0xC7, 0x4D, 0xC8, 0x0D, 0xA0, 0x7D, 0xA0, 0x18, + 0x64, 0xFB, 0xF2, 0x68, 0x59, 0x60, 0xB5, 0x40, + 0xB3, 0xA2, 0xE9, 0x42, 0xCB, 0x8D, 0x90, 0x9F + }, + { + 0x39, 0x51, 0x32, 0xC5, 0x80, 0xC3, 0x55, 0xB5, + 0xB0, 0xE2, 0x35, 0x33, 0x6C, 0x8D, 0xC1, 0x08, + 0x5E, 0x59, 0x59, 0x64, 0x04, 0x3D, 0x38, 0x9E, + 0x08, 0x1E, 0xFE, 0x48, 0x5B, 0xA4, 0xC6, 0x37, + 0x72, 0xDB, 0x8D, 0x7E, 0x0F, 0x18, 0x6C, 0x50, + 0x98, 0x2E, 0x12, 0x23, 0xEA, 0x78, 0x5A, 0xDC, + 0x74, 0x0B, 0x0C, 0xF2, 0x18, 0x70, 0x74, 0x58, + 0xB8, 0xB8, 0x03, 0x40, 0x42, 0xF9, 0x23, 0xC2 + }, + { + 0xF9, 0x2A, 0xBA, 0xCA, 0x21, 0x32, 0x29, 0x66, + 0x06, 0x49, 0xEF, 0x2D, 0x8F, 0x88, 0x11, 0x5B, + 0x5B, 0xED, 0x8A, 0xB5, 0xB9, 0xBC, 0xA9, 0xA1, + 0xB4, 0xC5, 0x24, 0x57, 0x03, 0x53, 0x10, 0xC4, + 0x1A, 0x6B, 0xEA, 0x2B, 0x23, 0xB7, 0x91, 0x8B, + 0x5B, 0x8B, 0xF3, 0x8B, 0x52, 0xEA, 0xC6, 0xFF, + 0x3B, 0x62, 0x13, 0xA5, 0x22, 0xF3, 0x81, 0xBE, + 0x7F, 0xF0, 0x90, 0x6D, 0xBA, 0x7B, 0xD0, 0x0C + }, + { + 0xCB, 0xAD, 0xE7, 0xAD, 0x3B, 0x5D, 0xEE, 0x0F, + 0xF1, 0xA4, 0x6B, 0x08, 0x2C, 0xF4, 0xE1, 0xE1, + 0xDC, 0x21, 0x62, 0x0D, 0xD2, 0xCC, 0x0E, 0xDC, + 0x2C, 0x70, 0x7A, 0x21, 0x62, 0xD2, 0x14, 0x99, + 0x69, 0xAB, 0xBB, 0x29, 0xC5, 0x72, 0x0B, 0x04, + 0xBD, 0x15, 0x68, 0xA9, 0x55, 0x61, 0x95, 0xE6, + 0x7F, 0x24, 0x32, 0x2D, 0xD9, 0xAA, 0x4E, 0x83, + 0x65, 0x19, 0x1A, 0xA5, 0xB6, 0xC4, 0x45, 0x79 + }, + { + 0xF5, 0x1B, 0x4A, 0xE4, 0xD4, 0xC5, 0x4A, 0x29, + 0xCF, 0x71, 0x35, 0xA8, 0xFE, 0x1E, 0xAB, 0xD5, + 0xE1, 0xBC, 0xBF, 0x82, 0x08, 0x96, 0x96, 0x7D, + 0xC4, 0x1E, 0x38, 0x49, 0xDA, 0xC2, 0x25, 0x07, + 0x69, 0x42, 0x10, 0xCA, 0x11, 0xC4, 0xEB, 0xF1, + 0xC2, 0x9A, 0x8D, 0x4F, 0x71, 0xB3, 0x0F, 0x76, + 0xC9, 0xB6, 0x01, 0x0A, 0xD9, 0x5B, 0xDF, 0xB0, + 0xDE, 0x83, 0x79, 0x25, 0xF0, 0x61, 0x25, 0x97 + }, + { + 0xCE, 0x38, 0x72, 0x11, 0x5D, 0x83, 0x3B, 0x34, + 0x56, 0xCA, 0x94, 0x2E, 0x6E, 0x38, 0x5F, 0x28, + 0xA9, 0x03, 0xBE, 0xAB, 0xFB, 0x75, 0x3F, 0x8A, + 0xFC, 0xCC, 0x12, 0xF2, 0x58, 0x2C, 0xE1, 0xF3, + 0x62, 0x12, 0xBD, 0x05, 0xE0, 0x5A, 0x46, 0xFC, + 0x88, 0xD3, 0x19, 0x50, 0xB4, 0x91, 0x1A, 0xE5, + 0xDC, 0xD8, 0xFF, 0x7A, 0x0B, 0x50, 0x47, 0x4C, + 0xB4, 0x88, 0xCC, 0xF2, 0xA8, 0x9C, 0xD0, 0xEB + }, + { + 0x9B, 0xB7, 0x4C, 0xBD, 0x47, 0xA6, 0x24, 0xCB, + 0xEA, 0xFC, 0xC1, 0x6D, 0x46, 0x29, 0x47, 0xBB, + 0xEA, 0x13, 0x70, 0xB8, 0x5C, 0x96, 0x1A, 0x40, + 0x7D, 0xF9, 0x86, 0x3E, 0x54, 0xE6, 0xD9, 0xE6, + 0xA8, 0xD2, 0xEF, 0x0C, 0x64, 0x97, 0x20, 0x5E, + 0x5E, 0xB7, 0xC3, 0xE5, 0x9E, 0x69, 0x8D, 0x99, + 0x24, 0x63, 0xCA, 0x9D, 0xD4, 0xCF, 0x28, 0xCF, + 0x9A, 0x2D, 0x4E, 0x30, 0xC1, 0x33, 0xE8, 0x55 + }, + { + 0x72, 0x96, 0x33, 0x82, 0x0B, 0xF0, 0x13, 0xD9, + 0xD2, 0xBD, 0x37, 0x3C, 0xCA, 0xC7, 0xBC, 0x9F, + 0x37, 0x16, 0xF6, 0x9E, 0x16, 0xA4, 0x4E, 0x94, + 0x9C, 0x7A, 0x9A, 0x93, 0xDC, 0xA1, 0x26, 0xBB, + 0x1A, 0xA5, 0x4E, 0x5E, 0x70, 0x40, 0x70, 0x7F, + 0x02, 0x87, 0x6A, 0xFD, 0x02, 0x0A, 0xF4, 0x72, + 0x63, 0x9D, 0x49, 0xF5, 0x42, 0x0D, 0x29, 0x4C, + 0x3A, 0xA3, 0x1D, 0x06, 0x7E, 0x3E, 0x85, 0x75 + }, + { + 0x06, 0x86, 0x1D, 0xB3, 0x07, 0xC6, 0x78, 0x08, + 0x6E, 0x8B, 0x2A, 0xEC, 0xDF, 0x18, 0x29, 0xD2, + 0x88, 0x3D, 0x28, 0xB7, 0x31, 0xAB, 0xD0, 0xF1, + 0xE7, 0x2F, 0x1C, 0xED, 0x6C, 0x7A, 0xD4, 0x17, + 0x2E, 0xCA, 0x63, 0x22, 0xA8, 0x3F, 0xB6, 0xA6, + 0x5A, 0xFA, 0x37, 0xE9, 0x4A, 0x3E, 0x2B, 0xA2, + 0x05, 0xB8, 0x7B, 0xF3, 0x82, 0xD9, 0x15, 0x88, + 0x49, 0x7A, 0x46, 0x50, 0x88, 0x3B, 0xD8, 0x75 + }, + { + 0x35, 0x6E, 0xCE, 0xAF, 0x17, 0x02, 0xB3, 0x70, + 0xF4, 0xAA, 0xB8, 0xEA, 0x82, 0x84, 0x86, 0xF3, + 0x30, 0x13, 0xF7, 0x44, 0xB3, 0x9E, 0x7E, 0xA2, + 0x6C, 0x69, 0x18, 0xD6, 0x0E, 0x1A, 0xBC, 0xF4, + 0x4F, 0xB1, 0x6E, 0xDC, 0xA7, 0x72, 0x0A, 0xCF, + 0xC6, 0xA7, 0x01, 0xBF, 0x1E, 0x2C, 0x35, 0xDD, + 0xBD, 0x69, 0x5A, 0x8D, 0x40, 0x8E, 0x8C, 0x96, + 0x32, 0xE8, 0xCD, 0x27, 0x23, 0x0C, 0xAD, 0x8D + }, + { + 0x48, 0x9A, 0x39, 0xD0, 0xFC, 0x3C, 0xDE, 0xAF, + 0x42, 0x89, 0x2E, 0xD8, 0x03, 0x85, 0xC1, 0x1C, + 0xE2, 0x93, 0xC9, 0x32, 0x21, 0x5B, 0xB2, 0x31, + 0x88, 0x69, 0x2A, 0x86, 0xE6, 0x1B, 0xCA, 0xD9, + 0x2C, 0x2A, 0x1D, 0x11, 0x42, 0x60, 0x1B, 0x1B, + 0xDF, 0x09, 0x82, 0xD1, 0xCD, 0x1E, 0x05, 0xC0, + 0x52, 0xDE, 0x81, 0x9E, 0x64, 0xF2, 0x47, 0xDB, + 0x35, 0x91, 0x5D, 0xD1, 0xDB, 0x79, 0xA3, 0xB5 + }, + { + 0xC0, 0x2F, 0x46, 0x4B, 0x4D, 0xD1, 0x81, 0x17, + 0xE3, 0x0A, 0x8D, 0xB8, 0xEF, 0x1D, 0xA0, 0x67, + 0x13, 0x4B, 0x60, 0x4E, 0xFA, 0x19, 0x51, 0x76, + 0x7E, 0xE6, 0x32, 0xDC, 0x02, 0x4D, 0x64, 0xC0, + 0x0F, 0x24, 0x49, 0xF0, 0x42, 0xDB, 0x3A, 0xEA, + 0x01, 0x74, 0xEB, 0xCD, 0xBB, 0x4F, 0xF5, 0x9D, + 0xAE, 0x75, 0x4F, 0x72, 0x39, 0x46, 0xF1, 0xB9, + 0x0A, 0x77, 0xFD, 0x95, 0x23, 0x69, 0x0B, 0x7B + }, + { + 0xFB, 0x31, 0xE6, 0xDD, 0xB8, 0x6D, 0xBF, 0xF3, + 0x72, 0x64, 0x6D, 0x1E, 0x3A, 0x3F, 0x31, 0xDD, + 0x61, 0x15, 0x9F, 0xC3, 0x93, 0x65, 0x8C, 0x2E, + 0xE9, 0x57, 0x10, 0x3B, 0xF2, 0x11, 0x6B, 0xDE, + 0xF8, 0x2C, 0x33, 0xE8, 0x69, 0xF3, 0xC8, 0x3A, + 0xC3, 0xC2, 0xF6, 0x38, 0x0C, 0xF6, 0x92, 0xF7, + 0xB1, 0xDC, 0xBA, 0xE0, 0xBB, 0x22, 0x7A, 0xD3, + 0x47, 0xE7, 0x54, 0x13, 0x74, 0x66, 0xC6, 0x9F + }, + { + 0x00, 0x60, 0x62, 0xAB, 0xE1, 0x6C, 0x2F, 0xE7, + 0x9A, 0xF8, 0x80, 0x85, 0xE0, 0xB5, 0x82, 0xB1, + 0x06, 0xE7, 0xF7, 0x9F, 0x01, 0xA4, 0x39, 0x46, + 0xC7, 0x8B, 0x19, 0xF9, 0xBD, 0xD7, 0x25, 0x99, + 0x76, 0x36, 0xA3, 0x32, 0xEB, 0x9A, 0x3A, 0xAA, + 0x6D, 0xE0, 0xD4, 0xA8, 0xE9, 0xE2, 0x8E, 0x8C, + 0x77, 0x87, 0x74, 0x22, 0x4C, 0x66, 0x5B, 0xF7, + 0xBC, 0x36, 0x44, 0xFC, 0xE4, 0x11, 0x22, 0x8C + }, + { + 0xD4, 0x4A, 0x6D, 0xB3, 0xDE, 0x9F, 0xD4, 0xE4, + 0xA7, 0xEF, 0x15, 0x5A, 0x01, 0xBC, 0xCB, 0x91, + 0xC1, 0xBC, 0xF1, 0xCB, 0x53, 0x22, 0x56, 0x89, + 0xA7, 0x7A, 0x0D, 0x23, 0xB4, 0xD3, 0x9A, 0x89, + 0xA1, 0x89, 0xF2, 0x89, 0x80, 0xF9, 0x1C, 0x56, + 0xEA, 0xC5, 0x87, 0x9E, 0xAE, 0x93, 0x3C, 0xED, + 0x7F, 0x26, 0x7E, 0x2F, 0x70, 0x40, 0xEB, 0x38, + 0x0F, 0xDB, 0xBF, 0x34, 0xA6, 0xB7, 0xB6, 0x15 + }, + { + 0x5A, 0xFB, 0xFE, 0xA1, 0xDE, 0xDA, 0x5A, 0xEA, + 0xB9, 0x2E, 0x4D, 0x0C, 0x31, 0xD1, 0x6A, 0x9A, + 0x86, 0xBF, 0x7C, 0x75, 0x23, 0x27, 0x4A, 0x05, + 0xC5, 0x05, 0x29, 0xF5, 0xC1, 0x39, 0xDB, 0x10, + 0x93, 0x3A, 0x52, 0xC6, 0x22, 0x9C, 0xD3, 0x11, + 0x08, 0xF0, 0x83, 0xFB, 0x0C, 0x85, 0xCF, 0x52, + 0x83, 0x1B, 0x5A, 0x05, 0xF2, 0x55, 0x0A, 0x77, + 0xB5, 0x70, 0x3C, 0xC6, 0x68, 0x91, 0x2D, 0xBC + }, + { + 0xD1, 0x7F, 0xCA, 0xD4, 0xE0, 0xD8, 0xBD, 0xE2, + 0xED, 0xFD, 0xA1, 0x68, 0xBA, 0x47, 0x10, 0x4B, + 0xBC, 0xA4, 0xD2, 0x6D, 0xA2, 0xD3, 0x1A, 0x07, + 0x0B, 0x0F, 0xBA, 0x0B, 0x26, 0xEE, 0xDD, 0x95, + 0xEE, 0xC1, 0xFC, 0x34, 0xD7, 0x6C, 0xD4, 0xA1, + 0xCB, 0x15, 0xF2, 0x62, 0x16, 0x88, 0xA9, 0xCC, + 0x0E, 0x96, 0x35, 0x8D, 0xE9, 0x93, 0x22, 0x2B, + 0xB3, 0xE3, 0xCD, 0x0B, 0xFD, 0xCB, 0x74, 0x6C + }, + { + 0xBD, 0x6A, 0x59, 0x21, 0x63, 0x37, 0xB4, 0x5D, + 0x6B, 0x71, 0xAE, 0xAC, 0x01, 0x36, 0x6B, 0xFE, + 0x96, 0x60, 0xE0, 0xFB, 0xC2, 0x95, 0x9A, 0xDB, + 0xB6, 0x8D, 0x52, 0x6C, 0x43, 0xD4, 0x8F, 0xFF, + 0xFE, 0x2F, 0xFC, 0x43, 0x05, 0x88, 0xE7, 0x8E, + 0x66, 0x54, 0x6A, 0x3C, 0x70, 0x9B, 0x0A, 0xCE, + 0xA1, 0x7C, 0xBC, 0x5A, 0x21, 0x8C, 0x53, 0xCD, + 0x47, 0xAA, 0x48, 0x71, 0xC1, 0xDD, 0x98, 0x4A + }, + { + 0x83, 0xEA, 0x5A, 0xE1, 0x89, 0x11, 0x45, 0xC4, + 0x1A, 0x7C, 0x6C, 0x87, 0xFE, 0x92, 0x24, 0x87, + 0xF5, 0xD2, 0x82, 0x93, 0x35, 0x69, 0xB7, 0xAE, + 0x0E, 0x34, 0x56, 0x53, 0x38, 0x1E, 0xDE, 0x6D, + 0x4B, 0x16, 0xE1, 0x44, 0xD1, 0xC3, 0xE8, 0xF0, + 0x60, 0x5D, 0xAA, 0x0D, 0xB5, 0x96, 0x5A, 0x7B, + 0x79, 0xD9, 0x1A, 0x8A, 0xFE, 0x11, 0xF1, 0xE0, + 0xBC, 0x54, 0x9A, 0xC0, 0x74, 0xA0, 0x1A, 0xB7 + }, + { + 0x37, 0x50, 0x50, 0xCF, 0x2E, 0x43, 0x0D, 0x0E, + 0x29, 0x87, 0x58, 0x35, 0x20, 0x8E, 0x89, 0x06, + 0xD7, 0x05, 0x2E, 0x47, 0x29, 0x2C, 0x5A, 0x38, + 0xA6, 0x30, 0x82, 0x87, 0x3D, 0x31, 0xD5, 0x83, + 0x13, 0x5C, 0x07, 0xA2, 0x0C, 0x52, 0xD9, 0x5B, + 0x2D, 0x5D, 0xC3, 0xEA, 0xDE, 0x6B, 0xE1, 0x43, + 0xCA, 0x34, 0x38, 0xF4, 0x4D, 0x02, 0x0A, 0xAE, + 0x16, 0x0E, 0xD7, 0x7A, 0xB9, 0x88, 0x4F, 0x7D + }, + { + 0x30, 0x28, 0xB0, 0xE8, 0x24, 0x95, 0x7F, 0xF3, + 0xB3, 0x05, 0xE9, 0x7F, 0xF5, 0x92, 0xAA, 0x8E, + 0xF2, 0x9B, 0x3B, 0xEC, 0x1D, 0xC4, 0x7B, 0x76, + 0x13, 0x3D, 0x10, 0x3F, 0xFE, 0x38, 0x71, 0xBF, + 0x05, 0x12, 0xA2, 0x31, 0xAF, 0xCB, 0x1D, 0xF8, + 0x65, 0x97, 0xEC, 0x5E, 0x46, 0xE9, 0x23, 0xC8, + 0xB9, 0x85, 0xC2, 0x85, 0x08, 0x57, 0xC6, 0x40, + 0x01, 0xB2, 0xC5, 0x51, 0xEA, 0x83, 0x3D, 0x0E + }, + { + 0x08, 0x7C, 0xCB, 0x1E, 0x5B, 0xD1, 0x72, 0x22, + 0xB8, 0xAF, 0x20, 0x6D, 0xD6, 0x39, 0x08, 0xF8, + 0x91, 0x72, 0x97, 0x62, 0x1A, 0x8C, 0xB9, 0x33, + 0x0A, 0xE0, 0xBA, 0x4A, 0xF3, 0xE9, 0xD6, 0x0C, + 0x98, 0xFC, 0xF1, 0xEF, 0xFC, 0xEC, 0x20, 0x13, + 0x6B, 0x4F, 0x91, 0x88, 0x12, 0x6D, 0xFA, 0x04, + 0x4E, 0x1C, 0x1C, 0xCD, 0xA3, 0xCE, 0xD8, 0x73, + 0x73, 0xD9, 0x37, 0x9C, 0xCB, 0xED, 0xBD, 0xB3 + }, + { + 0x7F, 0x17, 0x06, 0x24, 0x98, 0xBF, 0xA2, 0xBB, + 0x58, 0x56, 0xCD, 0x0A, 0x62, 0xC5, 0x68, 0xC5, + 0xC6, 0xB8, 0x97, 0x43, 0x24, 0x74, 0xEF, 0xB2, + 0xE6, 0xA2, 0xEE, 0x18, 0xCA, 0xFF, 0xD2, 0x1E, + 0x1E, 0xF3, 0x0D, 0x06, 0x47, 0x23, 0x85, 0x0F, + 0x79, 0x90, 0xD2, 0x1B, 0xA3, 0x4E, 0x8F, 0x2B, + 0x3B, 0xB0, 0x67, 0x02, 0x3A, 0x77, 0x27, 0x82, + 0x15, 0x8A, 0x27, 0xC6, 0xC4, 0x67, 0xC9, 0x28 + }, + { + 0x6B, 0xA9, 0x86, 0xA9, 0x42, 0x49, 0x7F, 0xD3, + 0x84, 0x62, 0x97, 0x2F, 0x50, 0xA6, 0x19, 0x68, + 0xC0, 0x65, 0x2D, 0xAC, 0x56, 0xCE, 0x9B, 0x9A, + 0xC1, 0xBC, 0x06, 0x1A, 0xB6, 0x34, 0xFE, 0x5A, + 0x77, 0xAC, 0xD0, 0x27, 0x5F, 0x83, 0x96, 0xE3, + 0xC0, 0xBE, 0xF0, 0x12, 0xAE, 0x93, 0xB7, 0x27, + 0x58, 0xB8, 0xD7, 0x67, 0x9C, 0x87, 0xE8, 0x47, + 0xE6, 0x30, 0x17, 0xB5, 0x5A, 0x69, 0xC5, 0xC6 + }, + { + 0x96, 0x7C, 0x81, 0xF5, 0x61, 0x95, 0x18, 0x33, + 0xFA, 0x56, 0x6F, 0x6B, 0x36, 0x07, 0x7E, 0xAD, + 0xB2, 0xA6, 0x15, 0xCC, 0x15, 0xF0, 0xED, 0xBB, + 0xAE, 0x4F, 0x84, 0x4D, 0xDC, 0x8E, 0x9C, 0x1F, + 0xB8, 0x3D, 0x31, 0xA9, 0x3F, 0xCB, 0x17, 0x74, + 0xD7, 0x40, 0xD6, 0x92, 0x08, 0xCA, 0x59, 0x30, + 0xBC, 0xFA, 0xC4, 0xA1, 0xF9, 0x44, 0x46, 0x9F, + 0xEF, 0xD1, 0x9B, 0x6E, 0x93, 0x75, 0xE0, 0xB5 + }, + { + 0xE8, 0xAE, 0xF1, 0x78, 0xE6, 0xDA, 0x3E, 0xF5, + 0xCA, 0xED, 0x65, 0x30, 0xF7, 0xEB, 0x25, 0x60, + 0x82, 0x56, 0xC2, 0x37, 0x7C, 0x4C, 0xF9, 0x6B, + 0x0C, 0xFD, 0x0D, 0x76, 0xEE, 0xB4, 0xBB, 0x86, + 0xEE, 0xFF, 0x7B, 0x7D, 0xF1, 0x58, 0x5C, 0x8D, + 0x7A, 0x20, 0xC0, 0x63, 0x3A, 0x67, 0x90, 0x7F, + 0x6D, 0x28, 0x67, 0xC3, 0x26, 0x4A, 0x91, 0xC0, + 0x51, 0xAB, 0xAE, 0x6E, 0xEA, 0x5A, 0x91, 0xD8 + }, + { + 0x64, 0x81, 0xDC, 0xC8, 0x15, 0x7A, 0xE6, 0x28, + 0xB5, 0xCD, 0x52, 0x6B, 0xAC, 0x8F, 0x93, 0x31, + 0x56, 0xDE, 0xDA, 0xC9, 0x56, 0xA2, 0xB2, 0x2A, + 0x97, 0x4B, 0xF5, 0xF7, 0xEC, 0x2D, 0xB5, 0x80, + 0x6F, 0x53, 0xDD, 0x0E, 0x2D, 0xD5, 0x3D, 0xB8, + 0x7C, 0xD8, 0xF5, 0x8A, 0x58, 0x6F, 0x9B, 0x3C, + 0x5C, 0x52, 0x23, 0x31, 0xA3, 0x11, 0x74, 0xC4, + 0xE7, 0xB9, 0xB6, 0xF7, 0xF0, 0x57, 0xC2, 0x8F + }, + { + 0xA7, 0x1E, 0xA4, 0x5C, 0xE6, 0x61, 0x6A, 0x3D, + 0x2F, 0x0A, 0x59, 0x2D, 0x5D, 0x02, 0x86, 0x93, + 0x2D, 0xA6, 0x3C, 0x6D, 0xB1, 0x1D, 0x59, 0xC6, + 0x69, 0x1C, 0x35, 0xA5, 0x6F, 0x7E, 0xE4, 0xF8, + 0x0B, 0x6F, 0xC3, 0x40, 0xB4, 0xDB, 0xC1, 0x84, + 0x4C, 0x50, 0x40, 0xE6, 0x68, 0xD2, 0x89, 0x2F, + 0x4A, 0x4A, 0xE8, 0x53, 0x3F, 0x1B, 0x67, 0x71, + 0xBC, 0xFC, 0xE7, 0xC3, 0xA2, 0x3E, 0x0D, 0x97 + }, + { + 0x96, 0x93, 0x44, 0x87, 0x70, 0xFE, 0xAE, 0x42, + 0x17, 0x26, 0xEB, 0x20, 0x3B, 0x01, 0xC7, 0x08, + 0x23, 0xD5, 0xF4, 0x4C, 0xC5, 0x21, 0x3E, 0x6A, + 0x68, 0x28, 0x47, 0x29, 0xBD, 0x11, 0x7D, 0x9B, + 0xD1, 0x8F, 0xEC, 0x4A, 0x0A, 0x82, 0x4A, 0x24, + 0x08, 0x0F, 0x29, 0x8B, 0xAC, 0xD2, 0x96, 0xD7, + 0xB4, 0x97, 0x83, 0x8F, 0xBD, 0x7B, 0x0D, 0x57, + 0x5C, 0x52, 0x49, 0x2B, 0x3E, 0x6F, 0x92, 0x6B + }, + { + 0x37, 0xA1, 0x50, 0x66, 0xF2, 0xB9, 0xF9, 0x4C, + 0x24, 0x61, 0x1B, 0xC4, 0x53, 0xED, 0x02, 0x74, + 0x07, 0x8D, 0x1F, 0x70, 0xB2, 0xD3, 0x4C, 0x8B, + 0x96, 0x36, 0x08, 0x48, 0x9D, 0xCB, 0xE8, 0xDF, + 0x44, 0x8E, 0xDD, 0x9C, 0x73, 0x36, 0x2B, 0xB2, + 0xB6, 0x6B, 0xEE, 0xF6, 0x1F, 0xCE, 0x60, 0x10, + 0x6F, 0x70, 0x19, 0xED, 0x37, 0x3C, 0x69, 0x22, + 0x59, 0xD9, 0x55, 0x6A, 0x94, 0x0B, 0x1A, 0x06 + }, + { + 0xBD, 0x44, 0xE7, 0x39, 0xE1, 0xF9, 0xDB, 0x1C, + 0x6B, 0xAF, 0x42, 0xCA, 0x4A, 0x12, 0xAC, 0x09, + 0x9B, 0x96, 0xF6, 0xB3, 0x6C, 0x4B, 0xCB, 0x1B, + 0x72, 0xEE, 0xFF, 0x08, 0xA6, 0x49, 0x68, 0x35, + 0xEC, 0x65, 0x15, 0x0B, 0xE8, 0xFE, 0x16, 0xCB, + 0xE3, 0x27, 0x07, 0xE3, 0x47, 0x54, 0x7D, 0xC5, + 0xA5, 0x83, 0xD2, 0x65, 0x74, 0x6F, 0xA5, 0x95, + 0xC5, 0xE7, 0x73, 0x0F, 0xCF, 0x24, 0x58, 0x1E + }, + { + 0xFA, 0xB2, 0x03, 0x8E, 0x94, 0x98, 0xA1, 0xC3, + 0x9E, 0x05, 0x78, 0xA0, 0xA5, 0xEA, 0x6B, 0x44, + 0xF3, 0xC1, 0xB4, 0x1A, 0xE5, 0x67, 0xF9, 0x91, + 0x4A, 0x95, 0xB1, 0x31, 0xC4, 0x8D, 0x12, 0x1E, + 0xCA, 0xCE, 0xA8, 0x95, 0xA0, 0x9B, 0x1D, 0x4E, + 0x04, 0x42, 0xBE, 0xC9, 0xC5, 0x0C, 0x50, 0xE0, + 0x0A, 0x9F, 0xAF, 0xEF, 0xFA, 0xE0, 0x70, 0x88, + 0x4C, 0x26, 0x25, 0xA8, 0xB1, 0xA2, 0x17, 0x26 + }, + { + 0x05, 0xA1, 0xB7, 0x6B, 0x2F, 0xD5, 0x62, 0x11, + 0xE0, 0xF2, 0xD7, 0x5A, 0x25, 0x16, 0x54, 0xA7, + 0x72, 0xF5, 0x5E, 0x18, 0xCA, 0x02, 0x2A, 0xF5, + 0x2C, 0xB3, 0x30, 0x19, 0x1E, 0x98, 0xA3, 0xB8, + 0xEB, 0x87, 0xE5, 0x11, 0x7B, 0xAE, 0x58, 0x04, + 0x4D, 0x94, 0x4C, 0x1F, 0x18, 0x85, 0x45, 0x12, + 0x25, 0x41, 0x77, 0x35, 0xFC, 0x72, 0xF7, 0x39, + 0x36, 0x69, 0x3C, 0xFF, 0x45, 0x46, 0x9F, 0x8C + }, + { + 0x2A, 0x30, 0xC9, 0x6B, 0xDA, 0xC7, 0x8A, 0x39, + 0x94, 0xEE, 0xCA, 0xA5, 0xA5, 0x3F, 0x82, 0x7F, + 0x58, 0xE1, 0x32, 0x31, 0xA0, 0xD1, 0x13, 0x08, + 0x6C, 0x06, 0xB1, 0xBD, 0xAB, 0xDA, 0x38, 0xD0, + 0x8F, 0x1A, 0xE2, 0x7D, 0xE2, 0x5F, 0xD2, 0x2E, + 0xEA, 0x70, 0xC0, 0x5F, 0x01, 0x32, 0xBF, 0x7A, + 0x50, 0x1C, 0x82, 0xAE, 0x62, 0x15, 0xBF, 0xEF, + 0x3C, 0x01, 0x63, 0x98, 0xBA, 0xF2, 0xCB, 0x62 + }, + { + 0x48, 0xDB, 0x53, 0x76, 0x5B, 0x82, 0xBD, 0x6F, + 0x25, 0x33, 0xEA, 0xE1, 0x7F, 0x67, 0x69, 0xD7, + 0xA4, 0xE3, 0xB2, 0x43, 0x74, 0x60, 0x1C, 0xDD, + 0x8E, 0xC0, 0xCA, 0x3A, 0xAB, 0x30, 0x93, 0xFD, + 0x2B, 0x99, 0x24, 0x38, 0x46, 0x0B, 0xAF, 0x8D, + 0xA5, 0x8F, 0xB9, 0xA8, 0x9B, 0x2C, 0x58, 0xF9, + 0x68, 0xE6, 0x36, 0x17, 0xCB, 0xEB, 0x18, 0x44, + 0xB0, 0x2D, 0x6A, 0x27, 0xC5, 0xB4, 0xAD, 0x41 + }, + { + 0x5C, 0x8B, 0x2E, 0x0E, 0x1B, 0x5C, 0x8F, 0x45, + 0x7D, 0x7F, 0x7B, 0xD9, 0xF0, 0x5A, 0x97, 0xE5, + 0x8D, 0xDA, 0x1D, 0x28, 0xDB, 0x9F, 0x34, 0xD1, + 0xCE, 0x73, 0x25, 0x28, 0xF9, 0x68, 0xBE, 0xDD, + 0x9E, 0x1C, 0xC9, 0x35, 0x2D, 0x0A, 0x5D, 0xF6, + 0x67, 0x29, 0x28, 0xBD, 0xD3, 0xEA, 0x6F, 0x5C, + 0xB0, 0x60, 0x77, 0xCF, 0x3A, 0xD3, 0xA7, 0x6E, + 0x29, 0xB2, 0x2E, 0x82, 0xBA, 0xC6, 0x7B, 0x61 + }, + { + 0x5B, 0x73, 0x91, 0xAA, 0x52, 0xF2, 0x76, 0xFA, + 0xB9, 0xC1, 0x38, 0x77, 0xF1, 0x22, 0x32, 0x70, + 0x84, 0x97, 0xFC, 0x02, 0x8F, 0xAA, 0x17, 0x32, + 0xA5, 0xDB, 0x07, 0x9E, 0x7F, 0xE0, 0x73, 0xED, + 0x0C, 0xC9, 0x52, 0x9C, 0xFC, 0x86, 0x3A, 0x4E, + 0xCB, 0xA4, 0xDC, 0x2F, 0x1E, 0xA9, 0xF6, 0xBD, + 0x69, 0x04, 0xF3, 0xA0, 0xC1, 0x07, 0x19, 0x3C, + 0x5E, 0x71, 0x1C, 0xB9, 0x11, 0xF3, 0x80, 0x25 + }, + { + 0x1D, 0x5A, 0xF7, 0x0F, 0x09, 0xA5, 0xFC, 0x69, + 0x16, 0xEF, 0x59, 0xA3, 0x8A, 0x86, 0x92, 0x6D, + 0xCA, 0xAE, 0x39, 0xA8, 0x95, 0x4D, 0x73, 0xFC, + 0x80, 0xA3, 0x50, 0x75, 0x1A, 0xDD, 0xA3, 0x8C, + 0x9D, 0x59, 0x75, 0x06, 0xDC, 0x05, 0xE1, 0xED, + 0x37, 0xBD, 0x2D, 0xB1, 0x59, 0x0F, 0x99, 0xAA, + 0x29, 0x6A, 0xEA, 0x13, 0xAB, 0x84, 0x43, 0xD5, + 0xA9, 0x23, 0x47, 0xFB, 0x85, 0xFC, 0x81, 0x6D + }, + { + 0x80, 0xE3, 0x70, 0x92, 0x97, 0xD4, 0x41, 0x14, + 0xB9, 0xFB, 0xDF, 0x55, 0x67, 0xF0, 0x5F, 0x33, + 0x00, 0x94, 0xCF, 0x09, 0xF4, 0xC0, 0xEF, 0xCF, + 0xAC, 0x05, 0x09, 0x5C, 0x36, 0x08, 0x10, 0x77, + 0x30, 0xC1, 0xAA, 0x07, 0xFF, 0x23, 0x00, 0x25, + 0x62, 0xC7, 0xE8, 0x41, 0xA9, 0xF5, 0x66, 0x24, + 0xFF, 0xE2, 0xAB, 0xEC, 0x61, 0x1E, 0xB9, 0xE7, + 0x3E, 0x1C, 0xCB, 0xD8, 0xF6, 0x2B, 0x11, 0x49 + }, + { + 0xF9, 0x94, 0x5C, 0x19, 0x06, 0x77, 0x84, 0x61, + 0x94, 0x13, 0x2B, 0x49, 0x6E, 0xC6, 0x01, 0x2C, + 0x08, 0x75, 0x0E, 0x02, 0x5F, 0xD5, 0x52, 0xED, + 0x32, 0x4D, 0x3A, 0x49, 0xD8, 0x63, 0x66, 0xC0, + 0x3D, 0xCC, 0xDE, 0x8D, 0x5B, 0x5A, 0xC9, 0xA4, + 0xBC, 0xB7, 0x19, 0x5E, 0x63, 0xBC, 0xAA, 0x93, + 0x9E, 0x8E, 0xDA, 0x18, 0xF1, 0x16, 0x94, 0xB6, + 0xFA, 0x69, 0x37, 0x39, 0x3B, 0xFF, 0xDB, 0xF4 + }, + { + 0x8D, 0x8F, 0x2E, 0xD9, 0xAE, 0x39, 0x80, 0x9A, + 0xAC, 0xAD, 0x2F, 0xCE, 0xDB, 0xD2, 0xDC, 0xA7, + 0x30, 0xC7, 0x83, 0xE6, 0x2F, 0xF7, 0x0B, 0x8D, + 0x3C, 0x53, 0x62, 0xF0, 0x73, 0xF8, 0x34, 0x67, + 0x19, 0x7D, 0x37, 0x56, 0xB4, 0x45, 0x19, 0x5F, + 0xE7, 0x52, 0x11, 0x73, 0x64, 0xD9, 0x2C, 0xF4, + 0x2C, 0x02, 0x6E, 0x40, 0x9D, 0x5F, 0xF7, 0xA9, + 0x53, 0x3E, 0xAB, 0x78, 0xF1, 0x75, 0x4A, 0x2D + }, + { + 0x3A, 0xC9, 0x9A, 0xC5, 0x3A, 0xC4, 0x9A, 0x56, + 0xFA, 0xA1, 0x86, 0x46, 0xB8, 0xE0, 0x8A, 0x2D, + 0x35, 0xBE, 0x80, 0xDF, 0x3E, 0xFB, 0xBB, 0xA6, + 0xBD, 0xA4, 0xAE, 0x90, 0x2B, 0x8D, 0x3E, 0x17, + 0x0A, 0x7B, 0xE8, 0x60, 0x5C, 0x34, 0xA4, 0xDC, + 0x9A, 0x73, 0x62, 0xB1, 0xC2, 0x01, 0xD7, 0x02, + 0x39, 0x1B, 0xD7, 0xD5, 0x20, 0x7F, 0x95, 0xFA, + 0x39, 0x0C, 0xE3, 0x3C, 0x43, 0x14, 0xD4, 0x11 + }, + { + 0xE4, 0x69, 0x4B, 0xDB, 0x31, 0x01, 0x6F, 0x25, + 0x53, 0x2C, 0x04, 0x3C, 0x5C, 0x63, 0x08, 0xCC, + 0x61, 0x9B, 0x0F, 0x87, 0x16, 0xF0, 0xC2, 0x9E, + 0xEB, 0x9F, 0x34, 0x0F, 0x47, 0xB0, 0x7B, 0x4A, + 0x4C, 0xE0, 0x98, 0x4C, 0x47, 0x24, 0xB1, 0x2A, + 0xB3, 0xD3, 0x2A, 0xF5, 0x16, 0xAD, 0xA2, 0x64, + 0x4C, 0xA6, 0x55, 0x8C, 0x1C, 0xB5, 0x81, 0x5C, + 0x12, 0x12, 0xA9, 0xB5, 0xFA, 0x83, 0x44, 0x12 + }, + { + 0xC6, 0x3C, 0x70, 0x3E, 0x62, 0x10, 0x8A, 0xA0, + 0xED, 0xC6, 0x83, 0xF3, 0x67, 0x8A, 0x00, 0x78, + 0x8F, 0xB1, 0x00, 0xC0, 0x96, 0x0B, 0x4E, 0x98, + 0xB7, 0x6A, 0x48, 0xE4, 0xE5, 0x92, 0x3D, 0x34, + 0x13, 0x44, 0x8D, 0xB8, 0x87, 0x5E, 0x3B, 0xCE, + 0xA7, 0xB6, 0xB8, 0x5D, 0x9E, 0x3E, 0xEA, 0xB7, + 0x2C, 0xD1, 0x50, 0x96, 0xFB, 0xBB, 0x2C, 0xC4, + 0x27, 0x03, 0x17, 0xFC, 0x34, 0xD4, 0x04, 0x71 + }, + { + 0x90, 0x80, 0xB7, 0xE8, 0x41, 0xEF, 0x51, 0x9C, + 0x54, 0x17, 0xE6, 0x90, 0xAA, 0xF4, 0x32, 0x79, + 0x07, 0xA8, 0x3D, 0xBC, 0xB7, 0x38, 0xD0, 0xF7, + 0x30, 0x8B, 0x1D, 0x61, 0x1D, 0xEF, 0x16, 0x9A, + 0x4F, 0x47, 0x42, 0x3E, 0x69, 0x0F, 0x27, 0xA7, + 0xE2, 0x74, 0x1A, 0xE7, 0x86, 0x5D, 0xA2, 0x3C, + 0x5D, 0x3F, 0x13, 0xC3, 0x16, 0x06, 0x3C, 0x7A, + 0xA1, 0xA9, 0x58, 0xE5, 0xBE, 0x83, 0x8F, 0x04 + }, + { + 0x29, 0x8D, 0xF6, 0x46, 0x91, 0x5F, 0x04, 0xD6, + 0x65, 0xE9, 0x67, 0x5E, 0x6A, 0x10, 0x31, 0x87, + 0x0D, 0x28, 0xEB, 0x7A, 0x04, 0x05, 0x66, 0x3E, + 0xAC, 0x3B, 0x10, 0xD1, 0xB4, 0xFA, 0x2E, 0x86, + 0x8E, 0x63, 0x73, 0xA5, 0x86, 0xCD, 0x73, 0xE0, + 0x6D, 0x8E, 0x7A, 0xD7, 0x71, 0xB4, 0xFB, 0x0A, + 0x8B, 0x4F, 0xC2, 0xDC, 0x6C, 0xE0, 0x9C, 0x64, + 0x2E, 0xE8, 0x99, 0x26, 0xFD, 0xC6, 0x52, 0x60 + }, + { + 0x4F, 0x2D, 0xE9, 0xC4, 0xF4, 0x34, 0x8B, 0xDB, + 0x32, 0x3A, 0x66, 0x83, 0x72, 0xE7, 0x71, 0x42, + 0x99, 0xC7, 0x76, 0xF9, 0x60, 0x2F, 0x3A, 0xF8, + 0xFB, 0x77, 0x46, 0xF1, 0x76, 0x86, 0x8D, 0xF3, + 0x54, 0x2B, 0x2F, 0xA6, 0x9E, 0xAE, 0x38, 0xB6, + 0xA2, 0x6A, 0x06, 0xCA, 0x89, 0x42, 0xF8, 0x82, + 0x78, 0xC6, 0x4E, 0x3D, 0x01, 0x7F, 0xEE, 0x67, + 0xA9, 0x4E, 0xA0, 0x23, 0xB2, 0xB5, 0xBE, 0x5F + }, + { + 0x40, 0x18, 0xC5, 0xEE, 0x90, 0x93, 0xA6, 0x81, + 0x11, 0x2F, 0x4C, 0xE1, 0x93, 0xA1, 0xD6, 0x5E, + 0x05, 0x48, 0x72, 0x5F, 0x96, 0xAE, 0x31, 0x53, + 0x87, 0xCD, 0x76, 0x5C, 0x2B, 0x9C, 0x30, 0x68, + 0xAE, 0x4C, 0xBE, 0x5C, 0xD5, 0x40, 0x2C, 0x11, + 0xC5, 0x5A, 0x9D, 0x78, 0x5F, 0xFD, 0xFC, 0x2B, + 0xDE, 0x6E, 0x7A, 0xCF, 0x19, 0x61, 0x74, 0x75, + 0xDA, 0xE0, 0xEB, 0x01, 0x44, 0x56, 0xCE, 0x45 + }, + { + 0x6F, 0xCE, 0x66, 0x75, 0xE8, 0x6D, 0x7E, 0x85, + 0x70, 0x4C, 0x96, 0xC2, 0x95, 0x70, 0x3C, 0xD9, + 0x54, 0x98, 0x59, 0x0E, 0x50, 0x76, 0x4D, 0x23, + 0xD7, 0xA7, 0xA3, 0xA3, 0x22, 0x68, 0xA0, 0xB3, + 0xC9, 0x91, 0xE8, 0xF7, 0x84, 0x87, 0x69, 0x9A, + 0x55, 0x4B, 0x58, 0x1E, 0x33, 0x9C, 0x09, 0xAE, + 0xC9, 0x82, 0xE0, 0xBA, 0xA4, 0x31, 0x87, 0x93, + 0x62, 0x06, 0x35, 0xE1, 0xE2, 0xC8, 0xD9, 0xF2 + }, + { + 0xEB, 0xA9, 0x37, 0x85, 0x91, 0x97, 0xC7, 0xFD, + 0x41, 0x2D, 0xBC, 0x9A, 0xFC, 0x0D, 0x67, 0xCC, + 0x19, 0x81, 0x60, 0xB5, 0xA9, 0xCC, 0xEE, 0x87, + 0xC4, 0x1A, 0x86, 0x64, 0x85, 0x9F, 0x3E, 0xFD, + 0x96, 0x13, 0x66, 0xA8, 0x09, 0xC7, 0xC6, 0xBC, + 0x6F, 0xA8, 0x44, 0x92, 0x68, 0x14, 0xE0, 0xB4, + 0xEF, 0xA3, 0x7E, 0xDE, 0x2C, 0x88, 0x44, 0x26, + 0x8D, 0x7F, 0x35, 0x56, 0xE4, 0x46, 0x58, 0x1D + }, + { + 0x83, 0xF4, 0x33, 0xE4, 0xF1, 0xC5, 0x07, 0x97, + 0x49, 0x3C, 0x58, 0xC2, 0x64, 0xCF, 0xFA, 0x70, + 0xC4, 0xA7, 0xA2, 0x4C, 0x33, 0x4D, 0xBA, 0xA3, + 0xC5, 0x74, 0x89, 0xD9, 0x70, 0xD4, 0x9D, 0x69, + 0x49, 0xFE, 0x45, 0xB7, 0x04, 0xF2, 0x65, 0xEF, + 0xD2, 0xAE, 0xE1, 0xAC, 0x1B, 0x46, 0xF4, 0xAA, + 0x3E, 0x4F, 0xAD, 0x68, 0xB3, 0x79, 0x61, 0xD2, + 0xC7, 0x28, 0x0A, 0xE1, 0x96, 0x72, 0xC8, 0x50 + }, + { + 0xB5, 0x57, 0xEC, 0xE1, 0x22, 0x72, 0x49, 0x3D, + 0xC2, 0x7E, 0x88, 0xA0, 0x5A, 0xDC, 0xD8, 0x61, + 0x87, 0x5A, 0x0C, 0xD0, 0x0B, 0xD6, 0x8A, 0xDC, + 0x3A, 0x30, 0x1D, 0x26, 0x3A, 0x9C, 0xD9, 0x93, + 0xA9, 0x6A, 0xE1, 0x4C, 0xFC, 0xDD, 0xCB, 0x99, + 0x7C, 0xC9, 0x86, 0x23, 0x93, 0x50, 0x50, 0xEA, + 0x43, 0x55, 0x2A, 0x34, 0x11, 0x07, 0x18, 0x7D, + 0xE7, 0x5C, 0x4E, 0xDE, 0xD7, 0xC7, 0x86, 0xBD + }, + { + 0x95, 0x89, 0xC0, 0x81, 0x3B, 0x73, 0x93, 0xDB, + 0xAA, 0xAF, 0xE4, 0x7A, 0xF5, 0xB4, 0x08, 0xB2, + 0x3C, 0x8A, 0x8C, 0x8B, 0xAC, 0x62, 0x55, 0x4B, + 0x8F, 0xA1, 0x32, 0xA3, 0x58, 0xCE, 0x30, 0x83, + 0xB1, 0xD4, 0xE3, 0x97, 0x07, 0xCD, 0x54, 0xA5, + 0x5F, 0x67, 0x3D, 0x48, 0x11, 0x6E, 0xB1, 0xF9, + 0xED, 0x8D, 0xE9, 0xC9, 0x43, 0xCD, 0x2D, 0xE4, + 0x60, 0xA6, 0x8B, 0xDD, 0xF7, 0x1E, 0x98, 0x03 + }, + { + 0xAE, 0x4C, 0xCF, 0x27, 0xAB, 0x00, 0xA4, 0x0C, + 0x36, 0x37, 0xD3, 0xD2, 0xCE, 0x51, 0xA8, 0x3E, + 0xFB, 0xA6, 0x2D, 0x4A, 0x6F, 0xDA, 0xD6, 0x95, + 0x06, 0x3F, 0xBC, 0x60, 0xA2, 0xD8, 0x2E, 0xC5, + 0xA5, 0x4A, 0xCB, 0xE0, 0x9B, 0xA9, 0x38, 0x8F, + 0x49, 0xAA, 0xC2, 0x7C, 0x99, 0x2D, 0x84, 0x63, + 0x20, 0x36, 0xE1, 0xBD, 0xD4, 0xC5, 0x29, 0xBB, + 0xF1, 0x85, 0x1E, 0xAE, 0x0C, 0x6E, 0xA9, 0x02 + }, + { + 0xA3, 0x94, 0x4B, 0x2C, 0x31, 0xCB, 0x49, 0x40, + 0x80, 0xB7, 0xEE, 0x1D, 0xB0, 0x81, 0x68, 0x53, + 0xE4, 0x25, 0xB5, 0x4C, 0x48, 0xD6, 0x31, 0x44, + 0x7E, 0xA5, 0x2C, 0x1D, 0x29, 0x52, 0x07, 0x9B, + 0xD8, 0x8F, 0xAB, 0x9E, 0xD0, 0xB7, 0xD8, 0xC0, + 0xBA, 0xAF, 0x0C, 0x4E, 0xCA, 0x19, 0x10, 0xDB, + 0x6F, 0x98, 0x53, 0x4F, 0x0D, 0x42, 0xE5, 0xEB, + 0xB6, 0xC0, 0xA7, 0x5E, 0xF0, 0xD8, 0xB2, 0xC0 + }, + { + 0xCF, 0xA1, 0xA2, 0x24, 0x68, 0x5A, 0x5F, 0xB2, + 0x01, 0x04, 0x58, 0x20, 0x1C, 0xEB, 0x0C, 0xDA, + 0x21, 0xC8, 0x2B, 0x16, 0x02, 0xDC, 0x41, 0x35, + 0x85, 0xFB, 0xCE, 0x80, 0x97, 0x6F, 0x06, 0x1C, + 0x23, 0x5B, 0x13, 0x67, 0x71, 0x24, 0x98, 0x14, + 0x4A, 0xC1, 0x6A, 0x98, 0x54, 0xF6, 0xFB, 0x32, + 0x3C, 0xBE, 0xB6, 0x23, 0x69, 0xCF, 0x9B, 0x75, + 0x2B, 0x92, 0x52, 0xA2, 0xA7, 0xAC, 0xE1, 0xFD + }, + { + 0xFA, 0x62, 0xC6, 0xCF, 0xC8, 0xF0, 0x79, 0xE5, + 0x8F, 0x3D, 0x3F, 0xEF, 0xD7, 0xC2, 0x24, 0xE7, + 0x1E, 0xBC, 0x69, 0xA9, 0x5B, 0x18, 0x35, 0xCC, + 0xC3, 0x2F, 0x35, 0x07, 0x77, 0x05, 0x11, 0x02, + 0x61, 0x54, 0x92, 0xD6, 0x7F, 0xB6, 0xDE, 0x62, + 0xCF, 0x2A, 0xD5, 0xB1, 0x84, 0x67, 0xFE, 0x87, + 0x15, 0x74, 0x88, 0x82, 0xDB, 0x89, 0xFF, 0x86, + 0xEF, 0xDF, 0x2F, 0x96, 0xF8, 0x13, 0x5E, 0xD2 + }, + { + 0xCC, 0x63, 0x3F, 0xD4, 0xEA, 0x6A, 0xC4, 0x08, + 0xC3, 0x87, 0x57, 0x56, 0xB9, 0x01, 0x28, 0x8A, + 0x1D, 0xE1, 0x91, 0x89, 0x28, 0x32, 0xBE, 0x2E, + 0x90, 0x26, 0xDC, 0x65, 0xC2, 0xFF, 0x00, 0x00, + 0x9F, 0x14, 0x36, 0xDD, 0xFF, 0x42, 0x06, 0x26, + 0x0A, 0x3D, 0x66, 0xEF, 0x61, 0x92, 0x14, 0x3E, + 0x57, 0x2F, 0x1E, 0x4B, 0xB8, 0xE5, 0xA7, 0x4B, + 0x12, 0x05, 0x5E, 0x42, 0x41, 0x1C, 0x18, 0xBC + }, + { + 0x44, 0xD2, 0xBF, 0x7F, 0x36, 0x96, 0xB8, 0x93, + 0x3F, 0x25, 0x5B, 0x9B, 0xE1, 0xA4, 0xA6, 0xAE, + 0x33, 0x16, 0xC2, 0x5D, 0x03, 0x95, 0xF5, 0x90, + 0xB9, 0xB9, 0x89, 0x8F, 0x12, 0x7E, 0x40, 0xD3, + 0xF4, 0x12, 0x4D, 0x7B, 0xDB, 0xC8, 0x72, 0x5F, + 0x00, 0xB0, 0xD2, 0x81, 0x50, 0xFF, 0x05, 0xB4, + 0xA7, 0x9E, 0x5E, 0x04, 0xE3, 0x4A, 0x47, 0xE9, + 0x08, 0x7B, 0x3F, 0x79, 0xD4, 0x13, 0xAB, 0x7F + }, + { + 0x96, 0xFB, 0xCB, 0xB6, 0x0B, 0xD3, 0x13, 0xB8, + 0x84, 0x50, 0x33, 0xE5, 0xBC, 0x05, 0x8A, 0x38, + 0x02, 0x74, 0x38, 0x57, 0x2D, 0x7E, 0x79, 0x57, + 0xF3, 0x68, 0x4F, 0x62, 0x68, 0xAA, 0xDD, 0x3A, + 0xD0, 0x8D, 0x21, 0x76, 0x7E, 0xD6, 0x87, 0x86, + 0x85, 0x33, 0x1B, 0xA9, 0x85, 0x71, 0x48, 0x7E, + 0x12, 0x47, 0x0A, 0xAD, 0x66, 0x93, 0x26, 0x71, + 0x6E, 0x46, 0x66, 0x7F, 0x69, 0xF8, 0xD7, 0xE8 + }, +}; + + + + +#endif + + + diff --git a/Modules/_blake2/impl/blake2.h b/Modules/_blake2/impl/blake2.h index 1a9fdf4302bcc8..5ca17f610742c9 100644 --- a/Modules/_blake2/impl/blake2.h +++ b/Modules/_blake2/impl/blake2.h @@ -1,16 +1,14 @@ /* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2_H__ @@ -19,16 +17,36 @@ #include #include -#ifdef BLAKE2_NO_INLINE -#define BLAKE2_LOCAL_INLINE(type) static type +#if defined(_WIN32) || defined(__CYGWIN__) + #define BLAKE2_DLL_IMPORT __declspec(dllimport) + #define BLAKE2_DLL_EXPORT __declspec(dllexport) + #define BLAKE2_DLL_PRIVATE +#elif __GNUC__ >= 4 + #define BLAKE2_DLL_IMPORT __attribute__ ((visibility ("default"))) + #define BLAKE2_DLL_EXPORT __attribute__ ((visibility ("default"))) + #define BLAKE2_DLL_PRIVATE __attribute__ ((visibility ("hidden"))) +#else + #define BLAKE2_DLL_IMPORT + #define BLAKE2_DLL_EXPORT + #define BLAKE2_DLL_PRIVATE #endif -#ifndef BLAKE2_LOCAL_INLINE -#define BLAKE2_LOCAL_INLINE(type) static inline type +#if defined(BLAKE2_DLL) + #if defined(BLAKE2_DLL_EXPORTS) // defined if we are building the DLL + #define BLAKE2_API BLAKE2_DLL_EXPORT + #else + #define BLAKE2_API BLAKE2_DLL_IMPORT + #endif + #define BLAKE2_PRIVATE BLAKE2_DLL_PRIVATE // must only be used by hidden logic +#else + #define BLAKE2_API + #define BLAKE2_PRIVATE #endif #if defined(__cplusplus) extern "C" { +#elif defined(_MSC_VER) && !defined(inline) +#define inline __inline #endif enum blake2s_constant @@ -49,23 +67,56 @@ extern "C" { BLAKE2B_PERSONALBYTES = 16 }; +#pragma pack(push, 1) + typedef struct __blake2s_param + { + uint8_t digest_length; // 1 + uint8_t key_length; // 2 + uint8_t fanout; // 3 + uint8_t depth; // 4 + uint32_t leaf_length; // 8 + uint8_t node_offset[6];// 14 + uint8_t node_depth; // 15 + uint8_t inner_length; // 16 + // uint8_t reserved[0]; + uint8_t salt[BLAKE2S_SALTBYTES]; // 24 + uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32 + } blake2s_param; + typedef struct __blake2s_state { uint32_t h[8]; uint32_t t[2]; uint32_t f[2]; uint8_t buf[2 * BLAKE2S_BLOCKBYTES]; - size_t buflen; + uint32_t buflen; + uint8_t outlen; uint8_t last_node; } blake2s_state; + typedef struct __blake2b_param + { + uint8_t digest_length; // 1 + uint8_t key_length; // 2 + uint8_t fanout; // 3 + uint8_t depth; // 4 + uint32_t leaf_length; // 8 + uint64_t node_offset; // 16 + uint8_t node_depth; // 17 + uint8_t inner_length; // 18 + uint8_t reserved[14]; // 32 + uint8_t salt[BLAKE2B_SALTBYTES]; // 48 + uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64 + } blake2b_param; + typedef struct __blake2b_state { uint64_t h[8]; uint64_t t[2]; uint64_t f[2]; uint8_t buf[2 * BLAKE2B_BLOCKBYTES]; - size_t buflen; + uint32_t buflen; + uint8_t outlen; uint8_t last_node; } blake2b_state; @@ -73,82 +124,52 @@ extern "C" { { blake2s_state S[8][1]; blake2s_state R[1]; - uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; - size_t buflen; + uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; + uint32_t buflen; + uint8_t outlen; } blake2sp_state; typedef struct __blake2bp_state { blake2b_state S[4][1]; blake2b_state R[1]; - uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; - size_t buflen; + uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; + uint32_t buflen; + uint8_t outlen; } blake2bp_state; - - -#pragma pack(push, 1) - typedef struct __blake2s_param - { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint8_t node_offset[6];// 14 - uint8_t node_depth; /* 15 */ - uint8_t inner_length; /* 16 */ - /* uint8_t reserved[0]; */ - uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ - uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ - } blake2s_param; - - typedef struct __blake2b_param - { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint64_t node_offset; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ - } blake2b_param; #pragma pack(pop) - /* Streaming API */ - int blake2s_init( blake2s_state *S, const uint8_t outlen ); - int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); - int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); - int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ); - int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ); - - int blake2b_init( blake2b_state *S, const uint8_t outlen ); - int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); - int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); - int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ); - int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ); - - int blake2sp_init( blake2sp_state *S, const uint8_t outlen ); - int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); - int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen ); - int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen ); - - int blake2bp_init( blake2bp_state *S, const uint8_t outlen ); - int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ); - int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen ); - int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen ); - - /* Simple API */ - int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); - int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); - - int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); - int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ); - - static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) + // Streaming API + BLAKE2_API int blake2s_init( blake2s_state *S, size_t outlen ); + BLAKE2_API int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + BLAKE2_API int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + BLAKE2_API int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ); + BLAKE2_API int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ); + + BLAKE2_API int blake2b_init( blake2b_state *S, size_t outlen ); + BLAKE2_API int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + BLAKE2_API int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + BLAKE2_API int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ); + BLAKE2_API int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ); + + BLAKE2_API int blake2sp_init( blake2sp_state *S, size_t outlen ); + BLAKE2_API int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); + BLAKE2_API int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen ); + BLAKE2_API int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen ); + + BLAKE2_API int blake2bp_init( blake2bp_state *S, size_t outlen ); + BLAKE2_API int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); + BLAKE2_API int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen ); + BLAKE2_API int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen ); + + // Simple API + BLAKE2_API int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + BLAKE2_API int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + BLAKE2_API int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + BLAKE2_API int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); + + static inline int blake2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) { return blake2b( out, in, key, outlen, inlen, keylen ); } diff --git a/Modules/_blake2/impl/blake2b-load-sse2.h b/Modules/_blake2/impl/blake2b-load-sse2.h index 0004a985648713..1ba153c87d7352 100644 --- a/Modules/_blake2/impl/blake2b-load-sse2.h +++ b/Modules/_blake2/impl/blake2b-load-sse2.h @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2B_LOAD_SSE2_H__ diff --git a/Modules/_blake2/impl/blake2b-load-sse41.h b/Modules/_blake2/impl/blake2b-load-sse41.h index 42a13493512a6a..f6c1bc8393f167 100644 --- a/Modules/_blake2/impl/blake2b-load-sse41.h +++ b/Modules/_blake2/impl/blake2b-load-sse41.h @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2B_LOAD_SSE41_H__ diff --git a/Modules/_blake2/impl/blake2b-ref.c b/Modules/_blake2/impl/blake2b-ref.c index ab375a499cbaca..699f1a1da1dece 100644 --- a/Modules/_blake2/impl/blake2b-ref.c +++ b/Modules/_blake2/impl/blake2b-ref.c @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #include @@ -45,41 +43,36 @@ static const uint8_t blake2b_sigma[12][16] = }; -BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S ) +static inline int blake2b_set_lastnode( blake2b_state *S ) { - S->f[1] = -1; + S->f[1] = ~0ULL; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S ) +static inline int blake2b_clear_lastnode( blake2b_state *S ) { - S->f[1] = 0; + S->f[1] = 0ULL; return 0; } /* Some helper functions, not necessarily useful */ -BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S ) -{ - return S->f[0] != 0; -} - -BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S ) +static inline int blake2b_set_lastblock( blake2b_state *S ) { if( S->last_node ) blake2b_set_lastnode( S ); - S->f[0] = -1; + S->f[0] = ~0ULL; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S ) +static inline int blake2b_clear_lastblock( blake2b_state *S ) { if( S->last_node ) blake2b_clear_lastnode( S ); - S->f[0] = 0; + S->f[0] = 0ULL; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) +static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) { S->t[0] += inc; S->t[1] += ( S->t[0] < inc ); @@ -88,95 +81,106 @@ BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint -/* Parameter-related functions */ -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) +// Parameter-related functions +static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) { P->digest_length = digest_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) +static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) { P->fanout = fanout; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) +static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) { P->depth = depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) +static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) { store32( &P->leaf_length, leaf_length ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) +static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) { store64( &P->node_offset, node_offset ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) +static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) { P->node_depth = node_depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) +static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) { P->inner_length = inner_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) +static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) { memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) +static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) { memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S ) +static inline int blake2b_init0( blake2b_state *S ) { - int i; memset( S, 0, sizeof( blake2b_state ) ); - for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; return 0; } +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init( blake2b_state *S, size_t outlen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + /* init xors IV with input parameter block */ int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) { - const uint8_t *p = ( const uint8_t * )( P ); - size_t i; - blake2b_init0( S ); + uint8_t *p = ( uint8_t * )( P ); /* IV XOR ParamBlock */ - for( i = 0; i < 8; ++i ) + for( size_t i = 0; i < 8; ++i ) S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); + S->outlen = P->digest_length; return 0; } -int blake2b_init( blake2b_state *S, const uint8_t outlen ) +int blake2b_init( blake2b_state *S, size_t outlen ) { blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - P->digest_length = outlen; + P->digest_length = ( uint8_t ) outlen; P->key_length = 0; P->fanout = 1; P->depth = 1; @@ -191,7 +195,7 @@ int blake2b_init( blake2b_state *S, const uint8_t outlen ) } -int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) { blake2b_param P[1]; @@ -199,8 +203,8 @@ int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, c if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; - P->digest_length = outlen; - P->key_length = keylen; + P->digest_length = ( uint8_t ) outlen; + P->key_length = ( uint8_t ) keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); @@ -227,7 +231,7 @@ static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCK { uint64_t m[16]; uint64_t v[16]; - int i; + size_t i; for( i = 0; i < 16; ++i ) m[i] = load64( block + i * sizeof( m[i] ) ); @@ -286,29 +290,29 @@ static int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCK return 0; } -/* inlen now in bytes */ -int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) + +int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) { while( inlen > 0 ) { - size_t left = S->buflen; - size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + uint32_t left = S->buflen; + uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) { - memcpy( S->buf + left, in, fill ); /* Fill buffer */ + memcpy( S->buf + left, in, fill ); // Fill buffer S->buflen += fill; blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); /* Compress */ - memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ + blake2b_compress( S, S->buf ); // Compress + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left S->buflen -= BLAKE2B_BLOCKBYTES; in += fill; inlen -= fill; } - else /* inlen <= fill */ + else // inlen <= fill { - memcpy( S->buf + left, in, (size_t)inlen ); - S->buflen += (size_t)inlen; /* Be lazy, do not compress */ + memcpy( S->buf + left, in, inlen ); + S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress in += inlen; inlen -= inlen; } @@ -317,24 +321,19 @@ int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) return 0; } -/* Is this correct? */ -int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) +int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) { - uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; - int i; - - if( out == NULL || outlen == 0 || outlen > BLAKE2B_OUTBYTES ) - return -1; + uint8_t buffer[BLAKE2B_OUTBYTES]; + size_t i; - if( blake2b_is_lastblock( S ) ) - return -1; + if(S->outlen != outlen) return -1; if( S->buflen > BLAKE2B_BLOCKBYTES ) { blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); S->buflen -= BLAKE2B_BLOCKBYTES; - memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); } blake2b_increment_counter( S, S->buflen ); @@ -349,8 +348,7 @@ int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) return 0; } -/* inlen, at least, should be uint64_t. Others can be size_t. */ -int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) { blake2b_state S[1]; @@ -374,47 +372,8 @@ int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen if( blake2b_init( S, outlen ) < 0 ) return -1; } - blake2b_update( S, ( const uint8_t * )in, inlen ); - blake2b_final( S, out, outlen ); - return 0; + if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0 ) return -1; + return blake2b_final( S, out, outlen ); } -#if defined(SUPERCOP) -int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) -{ - return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 ); -} -#endif - -#if defined(BLAKE2B_SELFTEST) -#include -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2B_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - size_t i; - - for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2B_OUTBYTES]; - blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ); - - if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} -#endif diff --git a/Modules/_blake2/impl/blake2b-round.h b/Modules/_blake2/impl/blake2b-round.h index 4ce2255409644f..cebc22550da4cd 100644 --- a/Modules/_blake2/impl/blake2b-round.h +++ b/Modules/_blake2/impl/blake2b-round.h @@ -1,22 +1,23 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2B_ROUND_H__ #define __BLAKE2B_ROUND_H__ -#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) +#define LOAD(p) _mm_load_si128( (__m128i *)(p) ) +#define STORE(p,r) _mm_store_si128((__m128i *)(p), r) + +#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) ) #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) #define TOF(reg) _mm_castsi128_ps((reg)) @@ -137,7 +138,7 @@ #endif -#if defined(HAVE_SSE41) +#if defined(HAVE_SSE4_1) #include "blake2b-load-sse41.h" #else #include "blake2b-load-sse2.h" diff --git a/Modules/_blake2/impl/blake2b-test.c b/Modules/_blake2/impl/blake2b-test.c new file mode 100644 index 00000000000000..9310a273a51728 --- /dev/null +++ b/Modules/_blake2/impl/blake2b-test.c @@ -0,0 +1,43 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + + if( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/Modules/_blake2/impl/blake2b.c b/Modules/_blake2/impl/blake2b.c index ebb65bb139af57..ca150462235433 100644 --- a/Modules/_blake2/impl/blake2b.c +++ b/Modules/_blake2/impl/blake2b.c @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #include @@ -22,23 +20,36 @@ #include "blake2-config.h" -#ifdef _MSC_VER -#include /* for _mm_set_epi64x */ +#if defined(_MSC_VER) +#include #endif + +#if defined(HAVE_SSE2) #include +// MSVC only defines _mm_set_epi64x for x86_64... +#if defined(_MSC_VER) && !defined(_M_X64) +static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 ) +{ + return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 ); +} +#endif +#endif + #if defined(HAVE_SSSE3) #include #endif -#if defined(HAVE_SSE41) +#if defined(HAVE_SSE4_1) #include #endif #if defined(HAVE_AVX) #include #endif -#if defined(HAVE_XOP) +#if defined(HAVE_XOP) && !defined(_MSC_VER) #include #endif + + #include "blake2b-round.h" static const uint64_t blake2b_IV[8] = @@ -67,44 +78,39 @@ static const uint8_t blake2b_sigma[12][16] = /* Some helper functions, not necessarily useful */ -BLAKE2_LOCAL_INLINE(int) blake2b_set_lastnode( blake2b_state *S ) +static inline int blake2b_set_lastnode( blake2b_state *S ) { - S->f[1] = -1; + S->f[1] = ~0ULL; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastnode( blake2b_state *S ) +static inline int blake2b_clear_lastnode( blake2b_state *S ) { - S->f[1] = 0; + S->f[1] = 0ULL; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_is_lastblock( const blake2b_state *S ) -{ - return S->f[0] != 0; -} - -BLAKE2_LOCAL_INLINE(int) blake2b_set_lastblock( blake2b_state *S ) +static inline int blake2b_set_lastblock( blake2b_state *S ) { if( S->last_node ) blake2b_set_lastnode( S ); - S->f[0] = -1; + S->f[0] = ~0ULL; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_clear_lastblock( blake2b_state *S ) +static inline int blake2b_clear_lastblock( blake2b_state *S ) { if( S->last_node ) blake2b_clear_lastnode( S ); - S->f[0] = 0; + S->f[0] = 0ULL; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) +static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) { -#if __x86_64__ - /* ADD/ADC chain */ +#if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__)) + // ADD/ADC chain __uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0]; t += inc; S->t[0] = ( uint64_t )( t >> 0 ); @@ -117,94 +123,119 @@ BLAKE2_LOCAL_INLINE(int) blake2b_increment_counter( blake2b_state *S, const uint } -/* Parameter-related functions */ -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) +// Parameter-related functions +static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length ) { P->digest_length = digest_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) +static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout ) { P->fanout = fanout; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) +static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth ) { P->depth = depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) +static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length ) { P->leaf_length = leaf_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) +static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset ) { P->node_offset = node_offset; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) +static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth ) { P->node_depth = node_depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) +static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length ) { P->inner_length = inner_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) +static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] ) { memcpy( P->salt, salt, BLAKE2B_SALTBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) +static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] ) { memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_init0( blake2b_state *S ) +static inline int blake2b_init0( blake2b_state *S ) { - int i; memset( S, 0, sizeof( blake2b_state ) ); - for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; + for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; return 0; } + + +#define blake2b_init BLAKE2_IMPL_NAME(blake2b_init) +#define blake2b_init_param BLAKE2_IMPL_NAME(blake2b_init_param) +#define blake2b_init_key BLAKE2_IMPL_NAME(blake2b_init_key) +#define blake2b_update BLAKE2_IMPL_NAME(blake2b_update) +#define blake2b_final BLAKE2_IMPL_NAME(blake2b_final) +#define blake2b BLAKE2_IMPL_NAME(blake2b) + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2b_init( blake2b_state *S, size_t outlen ); + int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); + int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ); + int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ); + int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + /* init xors IV with input parameter block */ int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) { - /*blake2b_init0( S ); */ - const uint8_t * v = ( const uint8_t * )( blake2b_IV ); - const uint8_t * p = ( const uint8_t * )( P ); - uint8_t * h = ( uint8_t * )( S->h ); - int i; + uint8_t *p, *h, *v; + //blake2b_init0( S ); + v = ( uint8_t * )( blake2b_IV ); + h = ( uint8_t * )( S->h ); + p = ( uint8_t * )( P ); /* IV XOR ParamBlock */ memset( S, 0, sizeof( blake2b_state ) ); - for( i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + S->outlen = P->digest_length; return 0; } /* Some sort of default parameter block initialization, for sequential blake2b */ -int blake2b_init( blake2b_state *S, const uint8_t outlen ) + +int blake2b_init( blake2b_state *S, size_t outlen ) { + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + const blake2b_param P = { - outlen, + ( uint8_t ) outlen, 0, 1, 1, @@ -216,18 +247,19 @@ int blake2b_init( blake2b_state *S, const uint8_t outlen ) {0}, {0} }; - - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - return blake2b_init_param( S, &P ); } -int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) { + if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; + + if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; + const blake2b_param P = { - outlen, - keylen, + ( uint8_t ) outlen, + ( uint8_t ) keylen, 1, 1, 0, @@ -239,10 +271,6 @@ int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, c {0} }; - if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; - - if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; - if( blake2b_init_param( S, &P ) < 0 ) return 0; @@ -256,7 +284,7 @@ int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, c return 0; } -BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) +static inline int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) { __m128i row1l, row1h; __m128i row2l, row2h; @@ -268,7 +296,7 @@ BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 ); const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 ); #endif -#if defined(HAVE_SSE41) +#if defined(HAVE_SSE4_1) const __m128i m0 = LOADU( block + 00 ); const __m128i m1 = LOADU( block + 16 ); const __m128i m2 = LOADU( block + 32 ); @@ -327,28 +355,28 @@ BLAKE2_LOCAL_INLINE(int) blake2b_compress( blake2b_state *S, const uint8_t block } -int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) +int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen ) { while( inlen > 0 ) { - size_t left = S->buflen; - size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + uint32_t left = S->buflen; + uint32_t fill = 2 * BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) { - memcpy( S->buf + left, in, fill ); /* Fill buffer */ + memcpy( S->buf + left, in, fill ); // Fill buffer S->buflen += fill; blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); - blake2b_compress( S, S->buf ); /* Compress */ - memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); /* Shift buffer left */ + blake2b_compress( S, S->buf ); // Compress + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left S->buflen -= BLAKE2B_BLOCKBYTES; in += fill; inlen -= fill; } - else /* inlen <= fill */ + else // inlen <= fill { memcpy( S->buf + left, in, inlen ); - S->buflen += inlen; /* Be lazy, do not compress */ + S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress in += inlen; inlen -= inlen; } @@ -358,20 +386,16 @@ int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen ) } -int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) +int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen ) { - if( outlen > BLAKE2B_OUTBYTES ) - return -1; - - if( blake2b_is_lastblock( S ) ) - return -1; + if(S->outlen != outlen) return -1; if( S->buflen > BLAKE2B_BLOCKBYTES ) { blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); S->buflen -= BLAKE2B_BLOCKBYTES; - memmove( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); + memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen ); } blake2b_increment_counter( S, S->buflen ); @@ -383,7 +407,7 @@ int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen ) } -int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) { blake2b_state S[1]; @@ -407,9 +431,8 @@ int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen if( blake2b_init( S, outlen ) < 0 ) return -1; } - blake2b_update( S, ( const uint8_t * )in, inlen ); - blake2b_final( S, out, outlen ); - return 0; + if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0) return -1; + return blake2b_final( S, out, outlen ); } #if defined(SUPERCOP) @@ -418,36 +441,3 @@ int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 ); } #endif - -#if defined(BLAKE2B_SELFTEST) -#include -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2B_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - size_t i; - - for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2B_OUTBYTES]; - blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ); - - if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} -#endif - diff --git a/Modules/_blake2/impl/blake2bp-test.c b/Modules/_blake2/impl/blake2bp-test.c new file mode 100644 index 00000000000000..849666cc1d5ecc --- /dev/null +++ b/Modules/_blake2/impl/blake2bp-test.c @@ -0,0 +1,44 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" + +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2B_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2B_OUTBYTES]; + + if( blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/Modules/_blake2/impl/blake2bp.c b/Modules/_blake2/impl/blake2bp.c new file mode 100644 index 00000000000000..45221611710108 --- /dev/null +++ b/Modules/_blake2/impl/blake2bp.c @@ -0,0 +1,274 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ + +#include +#include +#include +#include + +#if defined(_OPENMP) +#include +#endif + +#include "blake2.h" +#include "blake2-impl.h" + +#define PARALLELISM_DEGREE 4 + +static int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) +{ + blake2b_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + store32(&P->leaf_length, 0); + store64(&P->node_offset, offset); + P->node_depth = 0; + P->inner_length = BLAKE2B_OUTBYTES; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2b_init_param( S, P ); + S->outlen = P->inner_length; + return 0; +} + +static int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen ) +{ + blake2b_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + store32(&P->leaf_length, 0); + store64(&P->node_offset, 0); + P->node_depth = 1; + P->inner_length = BLAKE2B_OUTBYTES; + memset( P->reserved, 0, sizeof( P->reserved ) ); + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2b_init_param( S, P ); + S->outlen = P->digest_length; + return 0; +} + + +int blake2bp_init( blake2bp_state *S, size_t outlen ) +{ + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2bp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + return 0; +} + +int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) +{ + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2bp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2bp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + + +int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen ) +{ + size_t left = S->buflen; + size_t fill = sizeof( S->buf ) - left; + + if( left && inlen >= fill ) + { + memcpy( S->buf + left, in, fill ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); + + in += fill; + inlen -= fill; + left = 0; + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S) +#else + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2B_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) + { + blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + } + } + + in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); + inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + + if( inlen > 0 ) + memcpy( S->buf + left, in, inlen ); + + S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; + return 0; +} + + + +int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; + + if(S->outlen != outlen) return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + { + if( S->buflen > i * BLAKE2B_BLOCKBYTES ) + { + size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; + + if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; + + blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); + } + + blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); + } + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); + + return blake2b_final( S->R, out, outlen ); +} + +int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; + blake2b_state S[PARALLELISM_DEGREE][1]; + blake2b_state FS[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if ( NULL == key && keylen > 0) return -1; + + if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; + + if( keylen > BLAKE2B_KEYBYTES ) return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2bp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node + + if( keylen > 0 ) + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset( block, 0, BLAKE2B_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S,hash) +#else + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2B_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) + { + blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; + } + + if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) + { + const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; + const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; + blake2b_update( S[id__], in__, len ); + } + + blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); + } + + if( blake2bp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + FS->last_node = 1; // Mark as last node + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); + + return blake2b_final( FS, out, outlen ); +} + + + diff --git a/Modules/_blake2/impl/blake2s-load-sse2.h b/Modules/_blake2/impl/blake2s-load-sse2.h index eadefa7a52800e..b24483cf931c1f 100644 --- a/Modules/_blake2/impl/blake2s-load-sse2.h +++ b/Modules/_blake2/impl/blake2s-load-sse2.h @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2S_LOAD_SSE2_H__ diff --git a/Modules/_blake2/impl/blake2s-load-sse41.h b/Modules/_blake2/impl/blake2s-load-sse41.h index 54bf0cdd6143cc..3ac12eb6f5d082 100644 --- a/Modules/_blake2/impl/blake2s-load-sse41.h +++ b/Modules/_blake2/impl/blake2s-load-sse41.h @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2S_LOAD_SSE41_H__ diff --git a/Modules/_blake2/impl/blake2s-load-xop.h b/Modules/_blake2/impl/blake2s-load-xop.h index 2797722b37b15e..ac591a77d191a7 100644 --- a/Modules/_blake2/impl/blake2s-load-xop.h +++ b/Modules/_blake2/impl/blake2s-load-xop.h @@ -1,35 +1,31 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2S_LOAD_XOP_H__ #define __BLAKE2S_LOAD_XOP_H__ -#define TOB(x) ((x)*4*0x01010101 + 0x03020100) /* ..or not TOB */ +#define TOB(x) ((x)*4*0x01010101 + 0x03020100) // ..or not TOB -#if 0 /* Basic VPPERM emulation, for testing purposes */ -static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel) +/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel) { const __m128i sixteen = _mm_set1_epi8(16); const __m128i t0 = _mm_shuffle_epi8(src1, sel); const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen)); const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen), - _mm_cmpgt_epi8(sel, sixteen)); /* (>=16) = 0xff : 00 */ + _mm_cmpgt_epi8(sel, sixteen)); // (>=16) = 0xff : 00 return _mm_blendv_epi8(t0, s1, mask); -} -#endif +}*/ #define LOAD_MSG_0_1(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); diff --git a/Modules/_blake2/impl/blake2s-ref.c b/Modules/_blake2/impl/blake2s-ref.c index 6636753bf49d41..baf0b58351aef4 100644 --- a/Modules/_blake2/impl/blake2s-ref.c +++ b/Modules/_blake2/impl/blake2s-ref.c @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #include @@ -40,137 +38,143 @@ static const uint8_t blake2s_sigma[10][16] = { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , }; -BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S ) +static inline int blake2s_set_lastnode( blake2s_state *S ) { - S->f[1] = -1; + S->f[1] = ~0U; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S ) +static inline int blake2s_clear_lastnode( blake2s_state *S ) { - S->f[1] = 0; + S->f[1] = 0U; return 0; } /* Some helper functions, not necessarily useful */ -BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S ) -{ - return S->f[0] != 0; -} - -BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S ) +static inline int blake2s_set_lastblock( blake2s_state *S ) { if( S->last_node ) blake2s_set_lastnode( S ); - S->f[0] = -1; + S->f[0] = ~0U; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S ) +static inline int blake2s_clear_lastblock( blake2s_state *S ) { if( S->last_node ) blake2s_clear_lastnode( S ); - S->f[0] = 0; + S->f[0] = 0U; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) { S->t[0] += inc; S->t[1] += ( S->t[0] < inc ); return 0; } -/* Parameter-related functions */ -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) +// Parameter-related functions +static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) { P->digest_length = digest_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) +static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) { P->fanout = fanout; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) +static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) { P->depth = depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) +static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) { store32( &P->leaf_length, leaf_length ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) +static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) { store48( P->node_offset, node_offset ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) +static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) { P->node_depth = node_depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) +static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) { P->inner_length = inner_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) +static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) { memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) +static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) { memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S ) +static inline int blake2s_init0( blake2s_state *S ) { - int i; memset( S, 0, sizeof( blake2s_state ) ); - for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; return 0; } +#if defined(__cplusplus) +extern "C" { +#endif + int blake2s_init( blake2s_state *S, size_t outlen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + /* init2 xors IV with input parameter block */ int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) { - const uint32_t *p = ( const uint32_t * )( P ); - size_t i; - blake2s_init0( S ); + uint32_t *p = ( uint32_t * )( P ); /* IV XOR ParamBlock */ - for( i = 0; i < 8; ++i ) + for( size_t i = 0; i < 8; ++i ) S->h[i] ^= load32( &p[i] ); + S->outlen = P->digest_length; return 0; } -/* Sequential blake2s initialization */ -int blake2s_init( blake2s_state *S, const uint8_t outlen ) +// Sequential blake2s initialization +int blake2s_init( blake2s_state *S, size_t outlen ) { blake2s_param P[1]; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - P->digest_length = outlen; + P->digest_length = ( uint8_t) outlen; P->key_length = 0; P->fanout = 1; P->depth = 1; @@ -178,13 +182,13 @@ int blake2s_init( blake2s_state *S, const uint8_t outlen ) store48( &P->node_offset, 0 ); P->node_depth = 0; P->inner_length = 0; - /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + // memset(P->reserved, 0, sizeof(P->reserved) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); } -int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) { blake2s_param P[1]; @@ -192,15 +196,15 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - P->digest_length = outlen; - P->key_length = keylen; + P->digest_length = ( uint8_t ) outlen; + P->key_length = ( uint8_t ) keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store48( &P->node_offset, 0 ); P->node_depth = 0; P->inner_length = 0; - /* memset(P->reserved, 0, sizeof(P->reserved) ); */ + // memset(P->reserved, 0, sizeof(P->reserved) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); @@ -220,12 +224,11 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK { uint32_t m[16]; uint32_t v[16]; - size_t i; - for( i = 0; i < 16; ++i ) + for( size_t i = 0; i < 16; ++i ) m[i] = load32( block + i * sizeof( m[i] ) ); - for( i = 0; i < 8; ++i ) + for( size_t i = 0; i < 8; ++i ) v[i] = S->h[i]; v[ 8] = blake2s_IV[0]; @@ -269,7 +272,7 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK ROUND( 8 ); ROUND( 9 ); - for( i = 0; i < 8; ++i ) + for( size_t i = 0; i < 8; ++i ) S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; #undef G @@ -278,28 +281,28 @@ static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCK } -int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) +int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) { while( inlen > 0 ) { - size_t left = S->buflen; - size_t fill = 2 * BLAKE2S_BLOCKBYTES - left; + uint32_t left = S->buflen; + uint32_t fill = 2 * BLAKE2S_BLOCKBYTES - left; if( inlen > fill ) { - memcpy( S->buf + left, in, fill ); /* Fill buffer */ + memcpy( S->buf + left, in, fill ); // Fill buffer S->buflen += fill; blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); /* Compress */ - memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */ + blake2s_compress( S, S->buf ); // Compress + memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left S->buflen -= BLAKE2S_BLOCKBYTES; in += fill; inlen -= fill; } - else /* inlen <= fill */ + else // inlen <= fill { - memcpy( S->buf + left, in, (size_t)inlen ); - S->buflen += (size_t)inlen; /* Be lazy, do not compress */ + memcpy( S->buf + left, in, inlen ); + S->buflen += ( uint32_t ) inlen; // Be lazy, do not compress in += inlen; inlen -= inlen; } @@ -308,24 +311,19 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) return 0; } -int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) +int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) { - uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; - int i; - - if( out == NULL || outlen == 0 || outlen > BLAKE2S_OUTBYTES ) - return -1; - - if( blake2s_is_lastblock( S ) ) - return -1; + uint8_t buffer[BLAKE2S_OUTBYTES]; + size_t i; + if(S->outlen != outlen) return -1; if( S->buflen > BLAKE2S_BLOCKBYTES ) { blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S->buf ); S->buflen -= BLAKE2S_BLOCKBYTES; - memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); + memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); } blake2s_increment_counter( S, ( uint32_t )S->buflen ); @@ -335,12 +333,12 @@ int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - + memcpy( out, buffer, outlen ); return 0; } -int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) { blake2s_state S[1]; @@ -349,7 +347,7 @@ int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen if ( NULL == out ) return -1; - if ( NULL == key && keylen > 0) return -1; + if ( NULL == key && keylen > 0 ) return -1; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; @@ -364,48 +362,7 @@ int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen if( blake2s_init( S, outlen ) < 0 ) return -1; } - blake2s_update( S, ( const uint8_t * )in, inlen ); - blake2s_final( S, out, outlen ); - return 0; + if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1; + return blake2s_final( S, out, outlen ); } -#if defined(SUPERCOP) -int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) -{ - return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 ); -} -#endif - -#if defined(BLAKE2S_SELFTEST) -#include -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - size_t i; - - for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ); - - if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; -} -#endif - - diff --git a/Modules/_blake2/impl/blake2s-round.h b/Modules/_blake2/impl/blake2s-round.h index 7470d928a21581..1e2f2b7f59bd6c 100644 --- a/Modules/_blake2/impl/blake2s-round.h +++ b/Modules/_blake2/impl/blake2s-round.h @@ -1,22 +1,23 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #pragma once #ifndef __BLAKE2S_ROUND_H__ #define __BLAKE2S_ROUND_H__ -#define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) +#define LOAD(p) _mm_load_si128( (__m128i *)(p) ) +#define STORE(p,r) _mm_store_si128((__m128i *)(p), r) + +#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) ) #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) #define TOF(reg) _mm_castsi128_ps((reg)) @@ -68,7 +69,7 @@ #if defined(HAVE_XOP) #include "blake2s-load-xop.h" -#elif defined(HAVE_SSE41) +#elif defined(HAVE_SSE4_1) #include "blake2s-load-sse41.h" #else #include "blake2s-load-sse2.h" diff --git a/Modules/_blake2/impl/blake2s-test.c b/Modules/_blake2/impl/blake2s-test.c new file mode 100644 index 00000000000000..5c3f1f189d79cd --- /dev/null +++ b/Modules/_blake2/impl/blake2s-test.c @@ -0,0 +1,43 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + + if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/Modules/_blake2/impl/blake2s.c b/Modules/_blake2/impl/blake2s.c index 69385dcc38ca90..0c3636ef6fc5e8 100644 --- a/Modules/_blake2/impl/blake2s.c +++ b/Modules/_blake2/impl/blake2s.c @@ -1,16 +1,14 @@ /* BLAKE2 reference source code package - optimized C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . */ #include @@ -22,18 +20,32 @@ #include "blake2-config.h" +#if defined(_MSC_VER) +#include +#endif +#if defined(HAVE_SSE2) #include +// MSVC only defines _mm_set_epi64x for x86_64... +#if defined(_MSC_VER) && !defined(_M_X64) +static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 ) +{ + return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 ); +} +#endif +#endif + + #if defined(HAVE_SSSE3) #include #endif -#if defined(HAVE_SSE41) +#if defined(HAVE_SSE4_1) #include #endif #if defined(HAVE_AVX) #include #endif -#if defined(HAVE_XOP) +#if defined(HAVE_XOP) && !defined(_MSC_VER) #include #endif @@ -61,40 +73,35 @@ static const uint8_t blake2s_sigma[10][16] = /* Some helper functions, not necessarily useful */ -BLAKE2_LOCAL_INLINE(int) blake2s_set_lastnode( blake2s_state *S ) +static inline int blake2s_set_lastnode( blake2s_state *S ) { - S->f[1] = -1; + S->f[1] = ~0U; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastnode( blake2s_state *S ) +static inline int blake2s_clear_lastnode( blake2s_state *S ) { - S->f[1] = 0; + S->f[1] = 0U; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_is_lastblock( const blake2s_state *S ) -{ - return S->f[0] != 0; -} - -BLAKE2_LOCAL_INLINE(int) blake2s_set_lastblock( blake2s_state *S ) +static inline int blake2s_set_lastblock( blake2s_state *S ) { if( S->last_node ) blake2s_set_lastnode( S ); - S->f[0] = -1; + S->f[0] = ~0U; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_clear_lastblock( blake2s_state *S ) +static inline int blake2s_clear_lastblock( blake2s_state *S ) { if( S->last_node ) blake2s_clear_lastnode( S ); - S->f[0] = 0; + S->f[0] = 0U; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) +static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) { uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0]; t += inc; @@ -104,91 +111,114 @@ BLAKE2_LOCAL_INLINE(int) blake2s_increment_counter( blake2s_state *S, const uint } -/* Parameter-related functions */ -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) +// Parameter-related functions +static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length ) { P->digest_length = digest_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) +static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout ) { P->fanout = fanout; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) +static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth ) { P->depth = depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) +static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length ) { P->leaf_length = leaf_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) +static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset ) { store48( P->node_offset, node_offset ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) +static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth ) { P->node_depth = node_depth; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) +static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length ) { P->inner_length = inner_length; return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) +static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] ) { memcpy( P->salt, salt, BLAKE2S_SALTBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) +static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] ) { memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES ); return 0; } -BLAKE2_LOCAL_INLINE(int) blake2s_init0( blake2s_state *S ) +static inline int blake2s_init0( blake2s_state *S ) { - int i; memset( S, 0, sizeof( blake2s_state ) ); - for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; + for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; return 0; } +#define blake2s_init BLAKE2_IMPL_NAME(blake2s_init) +#define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param) +#define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key) +#define blake2s_update BLAKE2_IMPL_NAME(blake2s_update) +#define blake2s_final BLAKE2_IMPL_NAME(blake2s_final) +#define blake2s BLAKE2_IMPL_NAME(blake2s) + +#if defined(__cplusplus) +extern "C" { +#endif + int blake2s_init( blake2s_state *S, size_t outlen ); + int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); + int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); + int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ); + int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ); + int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ); +#if defined(__cplusplus) +} +#endif + + /* init2 xors IV with input parameter block */ int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) { - /*blake2s_init0( S ); */ - const uint8_t * v = ( const uint8_t * )( blake2s_IV ); - const uint8_t * p = ( const uint8_t * )( P ); - uint8_t * h = ( uint8_t * )( S->h ); - int i; + uint8_t *p, *h, *v; + //blake2s_init0( S ); + v = ( uint8_t * )( blake2s_IV ); + h = ( uint8_t * )( S->h ); + p = ( uint8_t * )( P ); /* IV XOR ParamBlock */ memset( S, 0, sizeof( blake2s_state ) ); - for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; + S->outlen = P->digest_length; return 0; } /* Some sort of default parameter block initialization, for sequential blake2s */ -int blake2s_init( blake2s_state *S, const uint8_t outlen ) +int blake2s_init( blake2s_state *S, size_t outlen ) { + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + const blake2s_param P = { outlen, @@ -202,14 +232,16 @@ int blake2s_init( blake2s_state *S, const uint8_t outlen ) {0}, {0} }; - /* Move interval verification here? */ - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; return blake2s_init_param( S, &P ); } -int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen ) +int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) { + if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; + + if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; + const blake2s_param P = { outlen, @@ -224,11 +256,6 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c {0} }; - /* Move interval verification here? */ - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; - if( blake2s_init_param( S, &P ) < 0 ) return -1; @@ -243,11 +270,11 @@ int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, c } -BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) +static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) { __m128i row1, row2, row3, row4; __m128i buf1, buf2, buf3, buf4; -#if defined(HAVE_SSE41) +#if defined(HAVE_SSE4_1) __m128i t0, t1; #if !defined(HAVE_XOP) __m128i t2; @@ -258,7 +285,7 @@ BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); #endif -#if defined(HAVE_SSE41) +#if defined(HAVE_SSE4_1) const __m128i m0 = LOADU( block + 00 ); const __m128i m1 = LOADU( block + 16 ); const __m128i m2 = LOADU( block + 32 ); @@ -300,8 +327,8 @@ BLAKE2_LOCAL_INLINE(int) blake2s_compress( blake2s_state *S, const uint8_t block return 0; } -/* inlen now in bytes */ -int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) + +int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen ) { while( inlen > 0 ) { @@ -310,11 +337,11 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) if( inlen > fill ) { - memcpy( S->buf + left, in, fill ); /* Fill buffer */ + memcpy( S->buf + left, in, fill ); // Fill buffer S->buflen += fill; blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); /* Compress */ - memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); /* Shift buffer left */ + blake2s_compress( S, S->buf ); // Compress + memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left S->buflen -= BLAKE2S_BLOCKBYTES; in += fill; inlen -= fill; @@ -322,7 +349,7 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) else /* inlen <= fill */ { memcpy( S->buf + left, in, inlen ); - S->buflen += inlen; /* Be lazy, do not compress */ + S->buflen += inlen; // Be lazy, do not compress in += inlen; inlen -= inlen; } @@ -331,24 +358,19 @@ int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen ) return 0; } -/* Is this correct? */ -int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) -{ - uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; - int i; - if( outlen > BLAKE2S_OUTBYTES ) - return -1; +int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen ) +{ + uint8_t buffer[BLAKE2S_OUTBYTES]; - if( blake2s_is_lastblock( S ) ) - return -1; + if(outlen != S->outlen ) return -1; if( S->buflen > BLAKE2S_BLOCKBYTES ) { blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S->buf ); S->buflen -= BLAKE2S_BLOCKBYTES; - memmove( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); + memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen ); } blake2s_increment_counter( S, ( uint32_t )S->buflen ); @@ -356,15 +378,14 @@ int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen ) memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ blake2s_compress( S, S->buf ); - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ + for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); memcpy( out, buffer, outlen ); return 0; } -/* inlen, at least, should be uint64_t. Others can be size_t. */ -int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen ) +int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) { blake2s_state S[1]; @@ -388,48 +409,14 @@ int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen if( blake2s_init( S, outlen ) < 0 ) return -1; } - blake2s_update( S, ( const uint8_t * )in, inlen ); - blake2s_final( S, out, outlen ); - return 0; + if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1; + return blake2s_final( S, out, outlen ); } #if defined(SUPERCOP) int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) { - return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, inlen, 0 ); -} -#endif - -#if defined(BLAKE2S_SELFTEST) -#include -#include "blake2-kat.h" -int main( int argc, char **argv ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[KAT_LENGTH]; - size_t i; - - for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - for( i = 0; i < KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - - if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || - 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - puts( "error" ); - return -1; - } - } - - puts( "ok" ); - return 0; + return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, (size_t)inlen, 0 ); } #endif - diff --git a/Modules/_blake2/impl/blake2sp-test.c b/Modules/_blake2/impl/blake2sp-test.c new file mode 100644 index 00000000000000..621e3506cfbdf7 --- /dev/null +++ b/Modules/_blake2/impl/blake2sp-test.c @@ -0,0 +1,43 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ +#include +#include +#include "blake2.h" +#include "blake2-kat.h" + +int main( int argc, char **argv ) +{ + uint8_t key[BLAKE2S_KEYBYTES]; + uint8_t buf[KAT_LENGTH]; + + for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i ) + key[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + buf[i] = ( uint8_t )i; + + for( size_t i = 0; i < KAT_LENGTH; ++i ) + { + uint8_t hash[BLAKE2S_OUTBYTES]; + if( blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 || + 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) + { + puts( "error" ); + return -1; + } + } + + puts( "ok" ); + return 0; +} + diff --git a/Modules/_blake2/impl/blake2sp.c b/Modules/_blake2/impl/blake2sp.c new file mode 100644 index 00000000000000..2f32bf3a226bf6 --- /dev/null +++ b/Modules/_blake2/impl/blake2sp.c @@ -0,0 +1,274 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see . +*/ + +#include +#include +#include + +#if defined(_OPENMP) +#include +#endif + +#include "blake2.h" +#include "blake2-impl.h" + +#define PARALLELISM_DEGREE 8 + +static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset ) +{ + blake2s_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + P->leaf_length = 0; + store48( P->node_offset, offset ); + P->node_depth = 0; + P->inner_length = BLAKE2S_OUTBYTES; + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2s_init_param( S, P ); + S->outlen = P->inner_length; + return 0; +} + +static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen ) +{ + blake2s_param P[1]; + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = PARALLELISM_DEGREE; + P->depth = 2; + P->leaf_length = 0; + store48( P->node_offset, 0ULL ); + P->node_depth = 1; + P->inner_length = BLAKE2S_OUTBYTES; + memset( P->salt, 0, sizeof( P->salt ) ); + memset( P->personal, 0, sizeof( P->personal ) ); + blake2s_init_param( S, P ); + S->outlen = P->digest_length; + return 0; +} + + +int blake2sp_init( blake2sp_state *S, size_t outlen ) +{ + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2sp_init_root( S->R, ( uint8_t ) outlen, 0 ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, 0, i ) < 0 ) return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + return 0; +} + +int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) +{ + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; + + memset( S->buf, 0, sizeof( S->buf ) ); + S->buflen = 0; + + if( blake2sp_init_root( S->R, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2sp_init_leaf( S->S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S->R->last_node = 1; + S->S[PARALLELISM_DEGREE - 1]->last_node = 1; + S->outlen = ( uint8_t ) outlen; + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + return 0; +} + + +int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen ) +{ + size_t left = S->buflen; + size_t fill = sizeof( S->buf ) - left; + + if( left && inlen >= fill ) + { + memcpy( S->buf + left, in, fill ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); + + in += fill; + inlen -= fill; + left = 0; + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S) +#else + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2S_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) + { + blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + } + } + + in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); + inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + + if( inlen > 0 ) + memcpy( S->buf + left, in, inlen ); + + S->buflen = ( uint32_t ) left + ( uint32_t ) inlen; + return 0; +} + + +int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; + + if(S->outlen != outlen) return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + { + if( S->buflen > i * BLAKE2S_BLOCKBYTES ) + { + size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; + + if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; + + blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); + } + + blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); + } + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); + + blake2s_final( S->R, out, outlen ); + return 0; +} + + +int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen ) +{ + uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; + blake2s_state S[PARALLELISM_DEGREE][1]; + blake2s_state FS[1]; + + /* Verify parameters */ + if ( NULL == in && inlen > 0 ) return -1; + + if ( NULL == out ) return -1; + + if ( NULL == key && keylen > 0 ) return -1; + + if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; + + if( keylen > BLAKE2S_KEYBYTES ) return -1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + if( blake2sp_init_leaf( S[i], ( uint8_t ) outlen, ( uint8_t ) keylen, i ) < 0 ) + return -1; + + S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node + + if( keylen > 0 ) + { + uint8_t block[BLAKE2S_BLOCKBYTES]; + memset( block, 0, BLAKE2S_BLOCKBYTES ); + memcpy( block, key, keylen ); + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); + + secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ + } + +#if defined(_OPENMP) + omp_set_num_threads(PARALLELISM_DEGREE); + #pragma omp parallel shared(S,hash) +#else + + for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) +#endif + { +#if defined(_OPENMP) + size_t id__ = ( size_t ) omp_get_thread_num(); +#endif + size_t inlen__ = inlen; + const uint8_t *in__ = ( const uint8_t * )in; + in__ += id__ * BLAKE2S_BLOCKBYTES; + + while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) + { + blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES ); + in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; + } + + if( inlen__ > id__ * BLAKE2S_BLOCKBYTES ) + { + const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES; + const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; + blake2s_update( S[id__], in__, len ); + } + + blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES ); + } + + if( blake2sp_init_root( FS, ( uint8_t ) outlen, ( uint8_t ) keylen ) < 0 ) + return -1; + + FS->last_node = 1; + + for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) + blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); + + return blake2s_final( FS, out, outlen ); +} + + + + diff --git a/aclocal.m4 b/aclocal.m4 index 85f00dd5fac7f2..038bd4e2cea25d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -55,7 +55,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.1]) +[m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -156,7 +156,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -166,11 +166,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -187,7 +187,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full diff --git a/configure b/configure index 72889b9d2efcdf..9f2007fed32560 100755 --- a/configure +++ b/configure @@ -11462,14 +11462,14 @@ fi # checks for library functions for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \ + clock confstr ctermid dup3 execv explicit_bzero explicit_memset faccessat fchmod fchmodat fchown fchownat \ fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ - initgroups kill killpg lchown lockf linkat lstat lutimes mmap \ + initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ diff --git a/configure.ac b/configure.ac index f548d644327a59..0baf0d6660aafe 100644 --- a/configure.ac +++ b/configure.ac @@ -3519,15 +3519,13 @@ fi # checks for library functions AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \ + clock confstr ctermid dup3 execv explicit_bzero explicit_memset faccessat fchmod fchmodat fchown fchownat \ fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ - initgroups kill killpg lchown lockf linkat lstat lutimes mmap \ - memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ diff --git a/pyconfig.h.in b/pyconfig.h.in index 1cafb9ae42ddb8..dd5f2e393be094 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -302,6 +302,12 @@ /* Define to 1 if you have the `execv' function. */ #undef HAVE_EXECV +/* Define to 1 if you have the `explicit_bzero' function. */ +#undef HAVE_EXPLICIT_BZERO + +/* Define to 1 if you have the `explicit_memset' function. */ +#undef HAVE_EXPLICIT_MEMSET + /* Define to 1 if you have the `expm1' function. */ #undef HAVE_EXPM1 @@ -664,6 +670,9 @@ /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR +/* Define to 1 if you have the `memset_s' function. */ +#undef HAVE_MEMSET_S + /* Define to 1 if you have the `mkdirat' function. */ #undef HAVE_MKDIRAT From 394119afc6611f17bac96f5ec6fefa00000ae795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damien=20Nad=C3=A9?= Date: Thu, 23 May 2019 12:03:25 +0200 Subject: [PATCH 077/441] bpo-37008: make mock_open handle able to honor next() (GH-13492) I've reported the issue on https://bugs.python.org/issue37008 and now I'm trying to bring a solution to this minor issue. I think it could be trivially backported to 3.7 branch. https://bugs.python.org/issue37008 --- Lib/unittest/mock.py | 6 ++++++ Lib/unittest/test/testmock/testmock.py | 13 +++++++++++++ Lib/unittest/test/testmock/testwith.py | 15 +++++++++++++++ .../2019-05-22-15-26-08.bpo-37008.WPbv31.rst | 2 ++ 4 files changed, 36 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 654462cbf7e792..b14bf01b28fdbd 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -2680,6 +2680,11 @@ def _iter_side_effect(): for line in _state[0]: yield line + def _next_side_effect(): + if handle.readline.return_value is not None: + return handle.readline.return_value + return next(_state[0]) + global file_spec if file_spec is None: import _io @@ -2701,6 +2706,7 @@ def _iter_side_effect(): handle.readline.side_effect = _state[1] handle.readlines.side_effect = _readlines_side_effect handle.__iter__.side_effect = _iter_side_effect + handle.__next__.side_effect = _next_side_effect def reset_data(*args, **kwargs): _state[0] = _to_stream(read_data) diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index 307b8b7657afa1..0f30bccc9cf0df 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -1702,6 +1702,19 @@ def test_mock_open_dunder_iter_issue(self): self.assertEqual(lines[1], 'Norwegian Blue') self.assertEqual(list(f1), []) + def test_mock_open_using_next(self): + mocked_open = mock.mock_open(read_data='1st line\n2nd line\n3rd line') + f1 = mocked_open('a-name') + line1 = next(f1) + line2 = f1.__next__() + lines = [line for line in f1] + self.assertEqual(line1, '1st line\n') + self.assertEqual(line2, '2nd line\n') + self.assertEqual(lines[0], '3rd line') + self.assertEqual(list(f1), []) + with self.assertRaises(StopIteration): + next(f1) + def test_mock_open_write(self): # Test exception in file writing write() mock_namedtemp = mock.mock_open(mock.MagicMock(name='JLV')) diff --git a/Lib/unittest/test/testmock/testwith.py b/Lib/unittest/test/testmock/testwith.py index 5172c222d97a78..42ebf3898c89e6 100644 --- a/Lib/unittest/test/testmock/testwith.py +++ b/Lib/unittest/test/testmock/testwith.py @@ -230,7 +230,22 @@ def test_dunder_iter_data(self): self.assertEqual(lines[1], 'bar\n') self.assertEqual(lines[2], 'baz\n') self.assertEqual(h.readline(), '') + with self.assertRaises(StopIteration): + next(h) + def test_next_data(self): + # Check that next will correctly return the next available + # line and plays well with the dunder_iter part. + mock = mock_open(read_data='foo\nbar\nbaz\n') + with patch('%s.open' % __name__, mock, create=True): + h = open('bar') + line1 = next(h) + line2 = next(h) + lines = [l for l in h] + self.assertEqual(line1, 'foo\n') + self.assertEqual(line2, 'bar\n') + self.assertEqual(lines[0], 'baz\n') + self.assertEqual(h.readline(), '') def test_readlines_data(self): # Test that emulating a file that ends in a newline character works diff --git a/Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst b/Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst new file mode 100644 index 00000000000000..42747aead49a49 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst @@ -0,0 +1,2 @@ +Add support for calling :func:`next` with the mock resulting from +:func:`unittest.mock.mock_open` From e788057a9188ff37e232729815dfda2529079420 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Fri, 24 May 2019 00:06:39 +1000 Subject: [PATCH 078/441] bpo-36797: Reduce levels of indirection in outdated distutils docs (#13462) --- Doc/distributing/index.rst | 12 +++++++++--- Doc/distutils/index.rst | 1 - Doc/distutils/packageindex.rst | 7 +++---- Doc/distutils/uploading.rst | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst index 5dd14b1f7a60b9..2e46c7ac8635e8 100644 --- a/Doc/distributing/index.rst +++ b/Doc/distributing/index.rst @@ -113,11 +113,17 @@ recommended tools`_. .. _currently recommended tools: https://packaging.python.org/guides/tool-recommendations/#packaging-tool-recommendations -Reading the guide -================= +.. index:: + single: Python Package Index (PyPI) + single: PyPI; (see Python Package Index (PyPI)) + +.. _publishing-python-packages: + +Reading the Python Packaging User Guide +======================================= The Python Packaging User Guide covers the various key steps and elements -involved in creating a project: +involved in creating and publishing a project: * `Project structure`_ * `Building and packaging the project`_ diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst index c56fafd68d8fdc..1f72a25542494a 100644 --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -36,7 +36,6 @@ and extensions readily available to a wider audience. configfile.rst sourcedist.rst builtdist.rst - packageindex.rst examples.rst extending.rst commandref.rst diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst index f74c4396e54581..ccb9a598b2b7a2 100644 --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -1,6 +1,4 @@ -.. index:: - single: Python Package Index (PyPI) - single: PyPI; (see Python Package Index (PyPI)) +:orphan: .. _package-index: @@ -12,6 +10,7 @@ The `Python Package Index (PyPI)`_ stores metadata describing distributions packaged with distutils and other publishing tools, as well the distribution archives themselves. -Detailed instructions on using PyPI at :ref:`distributing-index`. +References to up to date PyPI documentation can be found at +:ref:`publishing-python-packages`. .. _Python Package Index (PyPI): https://pypi.org diff --git a/Doc/distutils/uploading.rst b/Doc/distutils/uploading.rst index 4bce6997f9f83a..4c391cab072ea6 100644 --- a/Doc/distutils/uploading.rst +++ b/Doc/distutils/uploading.rst @@ -4,4 +4,5 @@ Uploading Packages to the Package Index *************************************** -The contents of this page have moved to the section :ref:`package-index`. +References to up to date PyPI documentation can be found at +:ref:`publishing-python-packages`. From b82e17e626f7b1cd98aada0b1ebb65cb9f8fb184 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 23 May 2019 08:45:22 -0700 Subject: [PATCH 079/441] bpo-36842: Implement PEP 578 (GH-12613) Adds sys.audit, sys.addaudithook, io.open_code, and associated C APIs. --- Doc/c-api/code.rst | 1 + Doc/c-api/file.rst | 26 + Doc/c-api/sys.rst | 50 + Doc/howto/instrumentation.rst | 9 + Doc/library/array.rst | 1 + Doc/library/ctypes.rst | 17 + Doc/library/functions.rst | 31 + Doc/library/io.rst | 21 + Doc/library/mmap.rst | 2 + Doc/library/os.rst | 12 +- Doc/library/pickle.rst | 1 + Doc/library/socket.rst | 28 + Doc/library/sys.rst | 63 + Doc/library/urllib.request.rst | 7 + Doc/tools/extensions/pyspecific.py | 40 + Include/cpython/fileobject.h | 32 + Include/cpython/sysmodule.h | 21 + Include/fileobject.h | 25 +- Include/internal/pycore_pystate.h | 16 + Include/pydtrace.d | 1 + Include/pydtrace.h | 2 + Include/sysmodule.h | 8 +- Lib/_pyio.py | 23 + Lib/importlib/_bootstrap_external.py | 8 +- Lib/io.py | 6 +- Lib/pickle.py | 1 + Lib/test/libregrtest/setup.py | 6 + Lib/test/test_audit.py | 260 ++ Lib/test/test_embed.py | 11 + Lib/test/test_fileio.py | 23 + Lib/test/test_io.py | 2 +- Lib/urllib/request.py | 1 + Lib/zipimport.py | 4 +- Makefile.pre.in | 2 + .../2019-05-07-16-50-12.bpo-36842.NYww_N.rst | 1 + Modules/_ctypes/_ctypes.c | 16 + Modules/_ctypes/callproc.c | 7 + Modules/_io/_iomodule.c | 20 + Modules/_io/clinic/_iomodule.c.h | 44 +- Modules/_io/fileio.c | 4 + Modules/_pickle.c | 5 + Modules/_winapi.c | 47 +- Modules/arraymodule.c | 5 + Modules/mmapmodule.c | 10 + Modules/posixmodule.c | 22 + Modules/socketmodule.c | 80 + Objects/codeobject.c | 6 + Objects/descrobject.c | 8 + Objects/fileobject.c | 70 +- Objects/funcobject.c | 40 + Objects/object.c | 8 + Objects/typeobject.c | 11 + PCbuild/pythoncore.vcxproj | 2 + PCbuild/pythoncore.vcxproj.filters | 6 + Parser/asdl_c.py | 4 + Parser/parsetok.c | 9 + Programs/_testembed.c | 161 ++ Python/Python-ast.c | 4 + Python/bltinmodule.c | 30 +- Python/ceval.c | 23 + Python/clinic/sysmodule.c.h | 34 +- Python/fileutils.c | 18 + Python/import.c | 11 + Python/importdl.c | 5 + Python/importlib_external.h | 2438 +++++++++-------- Python/importlib_zipimport.h | 1117 ++++---- Python/pylifecycle.c | 7 + Python/pystate.c | 28 + Python/pythonrun.c | 6 + Python/sysmodule.c | 311 +++ 70 files changed, 3564 insertions(+), 1815 deletions(-) create mode 100644 Include/cpython/fileobject.h create mode 100644 Include/cpython/sysmodule.h create mode 100644 Lib/test/test_audit.py create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 27d3f76d7a3dd5..fd3f6919d6d75e 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -40,6 +40,7 @@ bound into a function. :c:func:`PyCode_New` directly can bind you to a precise Python version since the definition of the bytecode changes often. + .. audit-event:: code.__new__ "code filename name argcount kwonlyargcount nlocals stacksize flags" .. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index defc859dd5c478..543dc60b9f55ab 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -60,6 +60,32 @@ the :mod:`io` APIs instead. raised if the end of the file is reached immediately. +.. c:function:: int PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction handler) + + Overrides the normal behavior of :func:`io.open_code` to pass its parameter + through the provided handler. + + The handler is a function of type :c:type:`PyObject *(\*)(PyObject *path, + void *userData)`, where *path* is guaranteed to be :c:type:`PyUnicodeObject`. + + The *userData* pointer is passed into the hook function. Since hook + functions may be called from different runtimes, this pointer should not + refer directly to Python state. + + As this hook is intentionally used during import, avoid importing new modules + during its execution unless they are known to be frozen or available in + ``sys.modules``. + + Once a hook has been set, it cannot be removed or replaced, and later calls to + :c:func:`PyFile_SetOpenCodeHook` will fail. On failure, the function returns + -1 and sets an exception if the interpreter has been initialized. + + This function is safe to call before :c:func:`Py_Initialize`. + + .. versionadded:: 3.8 + + + .. c:function:: int PyFile_WriteObject(PyObject *obj, PyObject *p, int flags) .. index:: single: Py_PRINT_RAW diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 04e169a00dc699..2091da6af0be53 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -289,6 +289,56 @@ accessible to C code. They all work with the current interpreter thread's .. versionadded:: 3.2 +.. c:function:: int PySys_Audit(const char *event, const char *format, ...) + + .. index:: single: audit events + + Raises an auditing event with any active hooks. Returns zero for success + and non-zero with an exception set on failure. + + If any hooks have been added, *format* and other arguments will be used + to construct a tuple to pass. Apart from ``N``, the same format characters + as used in :c:func:`Py_BuildValue` are available. If the built value is not + a tuple, it will be added into a single-element tuple. (The ``N`` format + option consumes a reference, but since there is no way to know whether + arguments to this function will be consumed, using it may cause reference + leaks.) + + :func:`sys.audit` performs the same function from Python code. + + .. versionadded:: 3.8 + + +.. c:function:: int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) + + .. index:: single: audit events + + Adds to the collection of active auditing hooks. Returns zero for success + and non-zero on failure. If the runtime has been initialized, also sets an + error on failure. Hooks added through this API are called for all + interpreters created by the runtime. + + This function is safe to call before :c:func:`Py_Initialize`. When called + after runtime initialization, existing audit hooks are notified and may + silently abort the operation by raising an error subclassed from + :class:`Exception` (other errors will not be silenced). + + The hook function is of type :c:type:`int (*)(const char *event, PyObject + *args, void *userData)`, where *args* is guaranteed to be a + :c:type:`PyTupleObject`. The hook function is always called with the GIL + held by the Python interpreter that raised the event. + + The *userData* pointer is passed into the hook function. Since hook + functions may be called from different runtimes, this pointer should not + refer directly to Python state. + + See :pep:`578` for a detailed decription of auditing. Functions in the + runtime and standard library that raise events include the details in each + function's documentation. + + .. versionadded:: 3.8 + + .. _processcontrol: Process Control diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index 50cde3595034b5..909deb5fed33ff 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -332,6 +332,15 @@ Available static markers .. versionadded:: 3.7 +.. c:function:: audit(str event, void *tuple) + + Fires when :func:`sys.audit` or :c:func:`PySys_Audit` is called. + ``arg0`` is the event name as C string, ``arg1`` is a :c:type:`PyObject` + pointer to a tuple object. + + .. versionadded:: 3.8 + + SystemTap Tapsets ----------------- diff --git a/Doc/library/array.rst b/Doc/library/array.rst index 4ac7bb5391a7a4..1f95dd61b9fcd7 100644 --- a/Doc/library/array.rst +++ b/Doc/library/array.rst @@ -83,6 +83,7 @@ The module defines the following type: to add initial items to the array. Otherwise, the iterable initializer is passed to the :meth:`extend` method. + .. audit-event:: array.__new__ "typecode initializer" .. data:: typecodes diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 1c60b4bbda13ec..97172c588ae97f 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -1509,6 +1509,17 @@ object is available: :c:type:`int`, which is of course not always the truth, so you have to assign the correct :attr:`restype` attribute to use these functions. +.. audit-event:: ctypes.dlopen name + + Loading a library through any of these objects raises an + :ref:`auditing event ` ``ctypes.dlopen`` with string argument + ``name``, the name used to load the library. + +.. audit-event:: ctypes.dlsym "library name" + + Accessing a function on a loaded library raises an auditing event + ``ctypes.dlsym`` with arguments ``library`` (the library object) and ``name`` + (the symbol's name as a string or integer). .. _ctypes-foreign-functions: @@ -2032,6 +2043,12 @@ Data types This method returns a ctypes type instance using the memory specified by *address* which must be an integer. + .. audit-event:: ctypes.cdata address + + This method, and others that indirectly call this method, raises an + :func:`auditing event ` ``ctypes.cdata`` with argument + ``address``. + .. method:: from_param(obj) This method adapts *obj* to a ctypes type. It is called with the actual diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 1a9a8b5beeeebe..7170a7817205b7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -275,6 +275,12 @@ are always available. They are listed here in alphabetical order. If you want to parse Python code into its AST representation, see :func:`ast.parse`. + .. audit-event:: compile "source filename" + + Raises an :func:`auditing event ` ``compile`` with arguments + ``source`` and ``filename``. This event may also be raised by implicit + compilation. + .. note:: When compiling a string with multi-line code in ``'single'`` or @@ -473,6 +479,11 @@ are always available. They are listed here in alphabetical order. See :func:`ast.literal_eval` for a function that can safely evaluate strings with expressions containing only literals. + .. audit-event:: exec code_object + + Raises an :func:`auditing event ` ``exec`` with the code object as + the argument. Code compilation events may also be raised. + .. index:: builtin: exec .. function:: exec(object[, globals[, locals]]) @@ -502,6 +513,11 @@ are always available. They are listed here in alphabetical order. builtins are available to the executed code by inserting your own ``__builtins__`` dictionary into *globals* before passing it to :func:`exec`. + .. audit-event:: exec code_object + + Raises an :func:`auditing event ` ``exec`` with the code object as + the argument. Code compilation events may also be raised. + .. note:: The built-in functions :func:`globals` and :func:`locals` return the current @@ -747,6 +763,16 @@ are always available. They are listed here in alphabetical order. If the :mod:`readline` module was loaded, then :func:`input` will use it to provide elaborate line editing and history features. + .. audit-event:: builtins.input prompt + + Raises an :func:`auditing event ` ``builtins.input`` with + argument ``prompt`` before reading input + + .. audit-event:: builtins.input/result result + + Raises an auditing event ``builtins.input/result`` with the result after + successfully reading input. + .. class:: int([x]) int(x, base=10) @@ -1176,6 +1202,11 @@ are always available. They are listed here in alphabetical order. (where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`, and :mod:`shutil`. + .. audit-event:: open "file mode flags" + + The ``mode`` and ``flags`` arguments may have been modified or inferred from + the original call. + .. versionchanged:: 3.3 diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 0f1251687aeb13..2fb27c3aad78b9 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -120,6 +120,27 @@ High-level Module Interface This is an alias for the builtin :func:`open` function. + .. audit-event:: open "path mode flags" + + This function raises an :func:`auditing event ` ``open`` with + arguments ``path``, ``mode`` and ``flags``. The ``mode`` and ``flags`` + arguments may have been modified or inferred from the original call. + + +.. function:: open_code(path) + + Opens the provided file with mode ``'rb'``. This function should be used + when the intent is to treat the contents as executable code. + + ``path`` should be an absolute path. + + The behavior of this function may be overridden by an earlier call to the + :c:func:`PyFile_SetOpenCodeHook`, however, it should always be considered + interchangeable with ``open(path, 'rb')``. Overriding the behavior is + intended for additional validation or preprocessing of the file. + + .. versionadded:: 3.8 + .. exception:: BlockingIOError diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index 0f895d76b83fa8..a82caf86e8018a 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -67,6 +67,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length will be relative to the offset from the beginning of the file. *offset* defaults to 0. *offset* must be a multiple of the :const:`ALLOCATIONGRANULARITY`. + .. audit-event:: mmap.__new__ "fileno length access offset" .. class:: mmap(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE|PROT_READ, access=ACCESS_DEFAULT[, offset]) :noindex: @@ -155,6 +156,7 @@ To map anonymous memory, -1 should be passed as the fileno along with the length mm.close() + .. audit-event:: mmap.__new__ "fileno length access offset" Memory-mapped file objects support the following methods: diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 0bbfce97c54ba6..6df2b49c5325e6 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -651,7 +651,7 @@ process and user. File Object Creation -------------------- -This function creates new :term:`file objects `. (See also +These functions create new :term:`file objects `. (See also :func:`~os.open` for opening file descriptors.) @@ -829,11 +829,14 @@ as internal buffering of data. most *length* bytes in size. As of Python 3.3, this is equivalent to ``os.truncate(fd, length)``. + .. audit-event:: os.truncate "fd length" + .. availability:: Unix, Windows. .. versionchanged:: 3.5 Added support for Windows + .. function:: get_blocking(fd) Get the blocking mode of the file descriptor: ``False`` if the @@ -845,6 +848,7 @@ as internal buffering of data. .. versionadded:: 3.5 + .. function:: isatty(fd) Return ``True`` if the file descriptor *fd* is open and connected to a @@ -912,6 +916,8 @@ as internal buffering of data. This function can support :ref:`paths relative to directory descriptors ` with the *dir_fd* parameter. + .. audit-event:: open "path mode flags" + .. versionchanged:: 3.4 The new file descriptor is now non-inheritable. @@ -2756,6 +2762,8 @@ features: This function can support :ref:`specifying a file descriptor `. + .. audit-event:: os.truncate "path length" + .. availability:: Unix, Windows. .. versionadded:: 3.3 @@ -3715,6 +3723,8 @@ written in Python, such as a mail server's external command delivery program. to using this function. See the :ref:`subprocess-replacements` section in the :mod:`subprocess` documentation for some helpful recipes. + .. audit-event:: os.system command + .. availability:: Unix, Windows. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 27721e698826a1..f4c41ac68d2f79 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -427,6 +427,7 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and how they can be loaded, potentially reducing security risks. Refer to :ref:`pickle-restrict` for details. + .. audit-event:: pickle.find_class "module name" .. _pickle-picklable: diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 379633a3b6052b..e23a4f5380bd7b 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -526,6 +526,8 @@ The following functions all create :ref:`socket objects `. The newly created socket is :ref:`non-inheritable `. + .. audit-event:: socket.__new__ "self family type protocol" + .. versionchanged:: 3.3 The AF_CAN family was added. The AF_RDS family was added. @@ -718,6 +720,8 @@ The :mod:`socket` module also offers various network-related services: :const:`AF_INET6`), and is meant to be passed to the :meth:`socket.connect` method. + .. audit-event:: socket.getaddrinfo "host port family type protocol" + The following example fetches address information for a hypothetical TCP connection to ``example.org`` on port 80 (results may differ on your system if IPv6 isn't enabled):: @@ -753,6 +757,8 @@ The :mod:`socket` module also offers various network-related services: interface. :func:`gethostbyname` does not support IPv6 name resolution, and :func:`getaddrinfo` should be used instead for IPv4/v6 dual stack support. + .. audit-event:: socket.gethostbyname hostname + .. function:: gethostbyname_ex(hostname) @@ -765,12 +771,16 @@ The :mod:`socket` module also offers various network-related services: resolution, and :func:`getaddrinfo` should be used instead for IPv4/v6 dual stack support. + .. audit-event:: socket.gethostbyname hostname + .. function:: gethostname() Return a string containing the hostname of the machine where the Python interpreter is currently executing. + .. audit-event:: socket.gethostname + Note: :func:`gethostname` doesn't always return the fully qualified domain name; use :func:`getfqdn` for that. @@ -785,6 +795,8 @@ The :mod:`socket` module also offers various network-related services: domain name, use the function :func:`getfqdn`. :func:`gethostbyaddr` supports both IPv4 and IPv6. + .. audit-event:: socket.gethostbyaddr ip_address + .. function:: getnameinfo(sockaddr, flags) @@ -798,6 +810,8 @@ The :mod:`socket` module also offers various network-related services: For more information about *flags* you can consult :manpage:`getnameinfo(3)`. + .. audit-event:: socket.getnameinfo sockaddr + .. function:: getprotobyname(protocolname) Translate an Internet protocol name (for example, ``'icmp'``) to a constant @@ -813,6 +827,8 @@ The :mod:`socket` module also offers various network-related services: service. The optional protocol name, if given, should be ``'tcp'`` or ``'udp'``, otherwise any protocol will match. + .. audit-event:: socket.getservbyname "servicename protocolname" + .. function:: getservbyport(port[, protocolname]) @@ -820,6 +836,8 @@ The :mod:`socket` module also offers various network-related services: service. The optional protocol name, if given, should be ``'tcp'`` or ``'udp'``, otherwise any protocol will match. + .. audit-event:: socket.getservbyport "port protocolname" + .. function:: ntohl(x) @@ -1003,6 +1021,8 @@ The :mod:`socket` module also offers various network-related services: Set the machine's hostname to *name*. This will raise an :exc:`OSError` if you don't have enough rights. + .. audit-event:: socket.sethostname name + .. availability:: Unix. .. versionadded:: 3.3 @@ -1078,6 +1098,7 @@ to sockets. Bind the socket to *address*. The socket must not already be bound. (The format of *address* depends on the address family --- see above.) + .. audit-event:: socket.bind "self address" .. method:: socket.close() @@ -1115,6 +1136,8 @@ to sockets. :exc:`InterruptedError` exception if the connection is interrupted by a signal (or the exception raised by the signal handler). + .. audit-event:: socket.connect "self address" + .. versionchanged:: 3.5 The method now waits until the connection completes instead of raising an :exc:`InterruptedError` exception if the connection is interrupted by a @@ -1131,6 +1154,7 @@ to sockets. :c:data:`errno` variable. This is useful to support, for example, asynchronous connects. + .. audit-event:: socket.connect "self address" .. method:: socket.detach() @@ -1472,6 +1496,8 @@ to sockets. bytes sent. (The format of *address* depends on the address family --- see above.) + .. audit-event:: socket.sendto "self address" + .. versionchanged:: 3.5 If the system call is interrupted and the signal handler does not raise an exception, the method now retries the system call instead of raising @@ -1511,6 +1537,8 @@ to sockets. .. availability:: most Unix platforms, possibly others. + .. audit-event:: socket.sendmsg "self address" + .. versionadded:: 3.3 .. versionchanged:: 3.5 diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 3b754bd4e27677..0294f74368c0fa 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -19,6 +19,30 @@ always available. .. versionadded:: 3.2 +.. function:: addaudithook(hook) + + Adds the callable *hook* to the collection of active auditing hooks for the + current interpreter. + + When an auditing event is raised through the :func:`sys.audit` function, each + hook will be called in the order it was added with the event name and the + tuple of arguments. Native hooks added by :c:func:`PySys_AddAuditHook` are + called first, followed by hooks added in the current interpreter. + + Calling this function will trigger an event for all existing hooks, and if + any raise an exception derived from :class:`Exception`, the add will be + silently ignored. As a result, callers cannot assume that their hook has been + added unless they control all existing hooks. + + .. versionadded:: 3.8 + + .. impl-detail:: + + When tracing is enabled, Python hooks are only traced if the callable has + a ``__cantrace__`` member that is set to a true value. Otherwise, trace + functions will not see the hook. + + .. data:: argv The list of command line arguments passed to a Python script. ``argv[0]`` is the @@ -37,6 +61,30 @@ always available. ``[os.fsencode(arg) for arg in sys.argv]``. +.. _auditing: + +.. function:: audit(event, *args) + + .. index:: single: auditing + + Raises an auditing event with any active hooks. The event name is a string + identifying the event and its associated schema, which is the number and + types of arguments. The schema for a given event is considered public and + stable API and should not be modified between releases. + + This function will raise the first exception raised by any hook. In general, + these errors should not be handled and should terminate the process as + quickly as possible. + + Hooks are added using the :func:`sys.addaudithook` or + :c:func:`PySys_AddAuditHook` functions. + + The native equivalent of this function is :c:func:`PySys_Audit`. Using the + native function is preferred when possible. + + .. versionadded:: 3.8 + + .. data:: base_exec_prefix Set during Python startup, before ``site.py`` is run, to the same value as @@ -114,6 +162,8 @@ always available. This function should be used for internal and specialized purposes only. + .. audit-event:: sys._current_frames + .. function:: breakpointhook() @@ -617,6 +667,8 @@ always available. that is deeper than the call stack, :exc:`ValueError` is raised. The default for *depth* is zero, returning the frame at the top of the call stack. + .. audit-event:: sys._getframe + .. impl-detail:: This function should be used for internal and specialized purposes only. @@ -1146,6 +1198,8 @@ always available. ``'return'``, ``'c_call'``, ``'c_return'``, or ``'c_exception'``. *arg* depends on the event type. + .. audit-event:: sys.setprofile + The events have the following meaning: ``'call'`` @@ -1266,6 +1320,8 @@ always available. For more information on code and frame objects, refer to :ref:`types`. + .. audit-event:: sys.settrace + .. impl-detail:: The :func:`settrace` function is intended only for implementing debuggers, @@ -1286,6 +1342,13 @@ always available. first time. The *finalizer* will be called when an asynchronous generator is about to be garbage collected. + .. audit-event:: sys.set_asyncgen_hooks_firstiter + + .. audit-event:: sys.set_asyncgen_hooks_finalizer + + Two auditing events are raised because the underlying API consists of two + calls, each of which must raise its own event. + .. versionadded:: 3.6 See :pep:`525` for more details, and for a reference example of a *finalizer* method see the implementation of diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 14fa27bb08af20..1895ae74b4f5de 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -95,6 +95,12 @@ The :mod:`urllib.request` module defines the following functions: parameter to ``urllib.urlopen``, can be obtained by using :class:`ProxyHandler` objects. + .. audit-event:: urllib.request "fullurl data headers method" + + The default opener raises an :func:`auditing event ` + ``urllib.request`` with arguments ``fullurl``, ``data``, ``headers``, + ``method`` taken from the request object. + .. versionchanged:: 3.2 *cafile* and *capath* were added. @@ -118,6 +124,7 @@ The :mod:`urllib.request` module defines the following functions: :func:`ssl.create_default_context` select the system's trusted CA certificates for you. + .. function:: install_opener(opener) Install an :class:`OpenerDirector` instance as the default global opener. diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index e097c13eab5f4b..f79b25048a5a64 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -151,6 +151,45 @@ def run(self): return [pnode] +# Support for documenting audit event + +class AuditEvent(Directive): + + has_content = True + required_arguments = 1 + optional_arguments = 1 + final_argument_whitespace = True + + _label = [ + "Raises an :ref:`auditing event ` {name} with no arguments.", + "Raises an :ref:`auditing event ` {name} with argument {args}.", + "Raises an :ref:`auditing event ` {name} with arguments {args}.", + ] + + def run(self): + if len(self.arguments) >= 2 and self.arguments[1]: + args = [ + "``{}``".format(a.strip()) + for a in self.arguments[1].strip("'\"").split() + if a.strip() + ] + else: + args = [] + + label = translators['sphinx'].gettext(self._label[min(2, len(args))]) + text = label.format(name="``{}``".format(self.arguments[0]), + args=", ".join(args)) + + pnode = nodes.paragraph(text, classes=["audit-hook"]) + if self.content: + self.state.nested_parse(self.content, self.content_offset, pnode) + else: + n, m = self.state.inline_text(text, self.lineno) + pnode.extend(n + m) + + return [pnode] + + # Support for documenting decorators class PyDecoratorMixin(object): @@ -424,6 +463,7 @@ def setup(app): app.add_role('source', source_role) app.add_directive('impl-detail', ImplementationDetail) app.add_directive('availability', Availability) + app.add_directive('audit-event', AuditEvent) app.add_directive('deprecated-removed', DeprecatedRemoved) app.add_builder(PydocTopicsBuilder) app.add_builder(suspicious.CheckSuspiciousMarkupBuilder) diff --git a/Include/cpython/fileobject.h b/Include/cpython/fileobject.h new file mode 100644 index 00000000000000..57eac13c064c2e --- /dev/null +++ b/Include/cpython/fileobject.h @@ -0,0 +1,32 @@ +#ifndef Py_CPYTHON_FILEOBJECT_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 +PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; +#endif + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 +PyAPI_DATA(int) Py_UTF8Mode; +#endif + +/* The std printer acts as a preliminary sys.stderr until the new io + infrastructure is in place. */ +PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); +PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; + +typedef PyObject * (*Py_OpenCodeHookFunction)(PyObject *, void *); + +PyAPI_FUNC(PyObject *) PyFile_OpenCode(const char *utf8path); +PyAPI_FUNC(PyObject *) PyFile_OpenCodeObject(PyObject *path); +PyAPI_FUNC(int) PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData); + +#ifdef __cplusplus +} +#endif diff --git a/Include/cpython/sysmodule.h b/Include/cpython/sysmodule.h new file mode 100644 index 00000000000000..72d8ffed29fd6f --- /dev/null +++ b/Include/cpython/sysmodule.h @@ -0,0 +1,21 @@ +#ifndef Py_CPYTHON_SYSMODULE_H +# error "this header file must not be included directly" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); +PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); + +PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); + +typedef int(*Py_AuditHookFunction)(const char *, PyObject *, void *); + +PyAPI_FUNC(int) PySys_Audit(const char*, const char *, ...); +PyAPI_FUNC(int) PySys_AddAuditHook(Py_AuditHookFunction, void*); + +#ifdef __cplusplus +} +#endif diff --git a/Include/fileobject.h b/Include/fileobject.h index 89e8dd6a2850ca..456887ef9d045d 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -15,32 +15,13 @@ PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); -#endif /* The default encoding used by the platform file system APIs If non-NULL, this is different than the default encoding for strings */ PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; -#endif PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -PyAPI_DATA(int) Py_UTF8Mode; -#endif - -/* Internal API - - The std printer acts as a preliminary sys.stderr until the new io - infrastructure is in place. */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); -PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; -#endif /* Py_LIMITED_API */ - /* A routine to check if a file descriptor can be select()-ed. */ #ifdef _MSC_VER /* On Windows, any socket fd can be select()-ed, no matter how high */ @@ -49,6 +30,12 @@ PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; #define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE) #endif +#ifndef Py_LIMITED_API +# define Py_CPYTHON_FILEOBJECT_H +# include "cpython/fileobject.h" +# undef Py_CPYTHON_FILEOBJECT_H +#endif + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 1561328e607903..ef1d8a061f17f5 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -9,8 +9,10 @@ extern "C" { #endif #include "cpython/coreconfig.h" +#include "fileobject.h" #include "pystate.h" #include "pythread.h" +#include "sysmodule.h" #include "pycore_gil.h" /* _gil_runtime_state */ #include "pycore_pathconfig.h" @@ -131,6 +133,8 @@ struct _is { uint64_t tstate_next_unique_id; struct _warnings_runtime_state warnings; + + PyObject *audit_hooks; }; PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T); @@ -154,6 +158,13 @@ struct _xidregitem { struct _xidregitem *next; }; +/* runtime audit hook state */ + +typedef struct _Py_AuditHookEntry { + struct _Py_AuditHookEntry *next; + Py_AuditHookFunction hookCFunction; + void *userData; +} _Py_AuditHookEntry; /* GIL state */ @@ -224,6 +235,11 @@ typedef struct pyruntimestate { struct _gilstate_runtime_state gilstate; _PyPreConfig preconfig; + + Py_OpenCodeHookFunction open_code_hook; + void *open_code_userdata; + _Py_AuditHookEntry *audit_hook_head; + // XXX Consolidate globals found via the check-c-globals script. } _PyRuntimeState; diff --git a/Include/pydtrace.d b/Include/pydtrace.d index a6a5e7ec224f48..5e6a626b01b82f 100644 --- a/Include/pydtrace.d +++ b/Include/pydtrace.d @@ -12,6 +12,7 @@ provider python { probe gc__done(long); probe import__find__load__start(const char *); probe import__find__load__done(const char *, int); + probe audit(const char *, void *); }; #pragma D attributes Evolving/Evolving/Common provider python provider diff --git a/Include/pydtrace.h b/Include/pydtrace.h index 7a04278166b0ce..75f8e7f70979c5 100644 --- a/Include/pydtrace.h +++ b/Include/pydtrace.h @@ -36,6 +36,7 @@ static inline void PyDTrace_INSTANCE_DELETE_START(int arg0) {} static inline void PyDTrace_INSTANCE_DELETE_DONE(int arg0) {} static inline void PyDTrace_IMPORT_FIND_LOAD_START(const char *arg0) {} static inline void PyDTrace_IMPORT_FIND_LOAD_DONE(const char *arg0, int arg1) {} +static inline void PyDTrace_AUDIT(const char *arg0, void *arg1) {} static inline int PyDTrace_LINE_ENABLED(void) { return 0; } static inline int PyDTrace_FUNCTION_ENTRY_ENABLED(void) { return 0; } @@ -48,6 +49,7 @@ static inline int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) { return 0; } static inline int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) { return 0; } static inline int PyDTrace_IMPORT_FIND_LOAD_START_ENABLED(void) { return 0; } static inline int PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_AUDIT_ENABLED(void) { return 0; } #endif /* !WITH_DTRACE */ diff --git a/Include/sysmodule.h b/Include/sysmodule.h index c5547ff6742e06..670e5d283f7701 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -9,10 +9,6 @@ extern "C" { PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); -PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); -#endif PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **); PyAPI_FUNC(void) PySys_SetArgvEx(int, wchar_t **, int); @@ -34,7 +30,9 @@ PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *); PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); #ifndef Py_LIMITED_API -PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); +# define Py_CPYTHON_SYSMODULE_H +# include "cpython/sysmodule.h" +# undef Py_CPYTHON_SYSMODULE_H #endif #ifdef __cplusplus diff --git a/Lib/_pyio.py b/Lib/_pyio.py index be5e4266daffd8..5baca4df82ff44 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -254,6 +254,29 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None, result.close() raise +# Define a default pure-Python implementation for open_code() +# that does not allow hooks. Warn on first use. Defined for tests. +def _open_code_with_warning(path): + """Opens the provided file with mode ``'rb'``. This function + should be used when the intent is to treat the contents as + executable code. + + ``path`` should be an absolute path. + + When supported by the runtime, this function can be hooked + in order to allow embedders more control over code files. + This functionality is not supported on the current runtime. + """ + import warnings + warnings.warn("_pyio.open_code() may not be using hooks", + RuntimeWarning, 2) + return open(path, "rb") + +try: + open_code = io.open_code +except AttributeError: + open_code = _open_code_with_warning + class DocDescriptor: """Helper for builtins.open.__doc__ diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index f8ff5f4f2c5c69..7da0cd0f196554 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -963,8 +963,12 @@ def get_filename(self, fullname): def get_data(self, path): """Return the data from path as raw bytes.""" - with _io.FileIO(path, 'r') as file: - return file.read() + if isinstance(self, (SourceLoader, ExtensionFileLoader)): + with _io.open_code(str(path)) as file: + return file.read() + else: + with _io.FileIO(path, 'r') as file: + return file.read() # ResourceReader ABC API. diff --git a/Lib/io.py b/Lib/io.py index 968ee5073df1be..fbce6efc010c07 100644 --- a/Lib/io.py +++ b/Lib/io.py @@ -41,8 +41,8 @@ "Amaury Forgeot d'Arc , " "Benjamin Peterson ") -__all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO", - "BytesIO", "StringIO", "BufferedIOBase", +__all__ = ["BlockingIOError", "open", "open_code", "IOBase", "RawIOBase", + "FileIO", "BytesIO", "StringIO", "BufferedIOBase", "BufferedReader", "BufferedWriter", "BufferedRWPair", "BufferedRandom", "TextIOBase", "TextIOWrapper", "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"] @@ -52,7 +52,7 @@ import abc from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, - open, FileIO, BytesIO, StringIO, BufferedReader, + open, open_code, FileIO, BytesIO, StringIO, BufferedReader, BufferedWriter, BufferedRWPair, BufferedRandom, IncrementalNewlineDecoder, TextIOWrapper) diff --git a/Lib/pickle.py b/Lib/pickle.py index 595beda4765afe..be8e3811947b74 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -1436,6 +1436,7 @@ def get_extension(self, code): def find_class(self, module, name): # Subclasses may override this. + sys.audit('pickle.find_class', module, name) if self.proto < 3 and self.fix_imports: if (module, name) in _compat_pickle.NAME_MAPPING: module, name = _compat_pickle.NAME_MAPPING[(module, name)] diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index 9a6585af9d0dd6..84931140b10286 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -107,6 +107,12 @@ def setup_tests(ns): support.use_resources = ns.use_resources + if hasattr(sys, 'addaudithook'): + # Add an auditing hook for all tests to ensure PySys_Audit is tested + def _test_audit_hook(name, args): + pass + sys.addaudithook(_test_audit_hook) + def replace_stdout(): """Set stdout encoder error handler to backslashreplace (as stderr error diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py new file mode 100644 index 00000000000000..5b33d978f99d48 --- /dev/null +++ b/Lib/test/test_audit.py @@ -0,0 +1,260 @@ +"""Tests for sys.audit and sys.addaudithook +""" + +import os +import subprocess +import sys +import unittest +from test import support + +if not hasattr(sys, "addaudithook") or not hasattr(sys, "audit"): + raise unittest.SkipTest("test only relevant when sys.audit is available") + + +class TestHook: + """Used in standard hook tests to collect any logged events. + + Should be used in a with block to ensure that it has no impact + after the test completes. Audit hooks cannot be removed, so the + best we can do for the test run is disable it by calling close(). + """ + + def __init__(self, raise_on_events=None, exc_type=RuntimeError): + self.raise_on_events = raise_on_events or () + self.exc_type = exc_type + self.seen = [] + self.closed = False + + def __enter__(self, *a): + sys.addaudithook(self) + return self + + def __exit__(self, *a): + self.close() + + def close(self): + self.closed = True + + @property + def seen_events(self): + return [i[0] for i in self.seen] + + def __call__(self, event, args): + if self.closed: + return + self.seen.append((event, args)) + if event in self.raise_on_events: + raise self.exc_type("saw event " + event) + + +class TestFinalizeHook: + """Used in the test_finalize_hooks function to ensure that hooks + are correctly cleaned up, that they are notified about the cleanup, + and are unable to prevent it. + """ + + def __init__(self): + print("Created", id(self), file=sys.stderr, flush=True) + + def __call__(self, event, args): + # Avoid recursion when we call id() below + if event == "builtins.id": + return + + print(event, id(self), file=sys.stderr, flush=True) + + if event == "cpython._PySys_ClearAuditHooks": + raise RuntimeError("Should be ignored") + elif event == "cpython.PyInterpreterState_Clear": + raise RuntimeError("Should be ignored") + + +def run_finalize_test(): + """Called by test_finalize_hooks in a subprocess.""" + sys.addaudithook(TestFinalizeHook()) + + +class AuditTest(unittest.TestCase): + def test_basic(self): + with TestHook() as hook: + sys.audit("test_event", 1, 2, 3) + self.assertEqual(hook.seen[0][0], "test_event") + self.assertEqual(hook.seen[0][1], (1, 2, 3)) + + def test_block_add_hook(self): + # Raising an exception should prevent a new hook from being added, + # but will not propagate out. + with TestHook(raise_on_events="sys.addaudithook") as hook1: + with TestHook() as hook2: + sys.audit("test_event") + self.assertIn("test_event", hook1.seen_events) + self.assertNotIn("test_event", hook2.seen_events) + + def test_block_add_hook_baseexception(self): + # Raising BaseException will propagate out when adding a hook + with self.assertRaises(BaseException): + with TestHook( + raise_on_events="sys.addaudithook", exc_type=BaseException + ) as hook1: + # Adding this next hook should raise BaseException + with TestHook() as hook2: + pass + + def test_finalize_hooks(self): + events = [] + with subprocess.Popen( + [ + sys.executable, + "-c", + "import test.test_audit; test.test_audit.run_finalize_test()", + ], + encoding="utf-8", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as p: + p.wait() + for line in p.stderr: + events.append(line.strip().partition(" ")) + firstId = events[0][2] + self.assertSequenceEqual( + [ + ("Created", " ", firstId), + ("cpython._PySys_ClearAuditHooks", " ", firstId), + ], + events, + ) + + def test_pickle(self): + pickle = support.import_module("pickle") + + class PicklePrint: + def __reduce_ex__(self, p): + return str, ("Pwned!",) + + payload_1 = pickle.dumps(PicklePrint()) + payload_2 = pickle.dumps(("a", "b", "c", 1, 2, 3)) + + # Before we add the hook, ensure our malicious pickle loads + self.assertEqual("Pwned!", pickle.loads(payload_1)) + + with TestHook(raise_on_events="pickle.find_class") as hook: + with self.assertRaises(RuntimeError): + # With the hook enabled, loading globals is not allowed + pickle.loads(payload_1) + # pickles with no globals are okay + pickle.loads(payload_2) + + def test_monkeypatch(self): + class A: + pass + + class B: + pass + + class C(A): + pass + + a = A() + + with TestHook() as hook: + # Catch name changes + C.__name__ = "X" + # Catch type changes + C.__bases__ = (B,) + # Ensure bypassing __setattr__ is still caught + type.__dict__["__bases__"].__set__(C, (B,)) + # Catch attribute replacement + C.__init__ = B.__init__ + # Catch attribute addition + C.new_attr = 123 + # Catch class changes + a.__class__ = B + + actual = [(a[0], a[1]) for e, a in hook.seen if e == "object.__setattr__"] + self.assertSequenceEqual( + [(C, "__name__"), (C, "__bases__"), (C, "__bases__"), (a, "__class__")], + actual, + ) + + def test_open(self): + # SSLContext.load_dh_params uses _Py_fopen_obj rather than normal open() + try: + import ssl + + load_dh_params = ssl.create_default_context().load_dh_params + except ImportError: + load_dh_params = None + + # Try a range of "open" functions. + # All of them should fail + with TestHook(raise_on_events={"open"}) as hook: + for fn, *args in [ + (open, support.TESTFN, "r"), + (open, sys.executable, "rb"), + (open, 3, "wb"), + (open, support.TESTFN, "w", -1, None, None, None, False, lambda *a: 1), + (load_dh_params, support.TESTFN), + ]: + if not fn: + continue + self.assertRaises(RuntimeError, fn, *args) + + actual_mode = [(a[0], a[1]) for e, a in hook.seen if e == "open" and a[1]] + actual_flag = [(a[0], a[2]) for e, a in hook.seen if e == "open" and not a[1]] + self.assertSequenceEqual( + [ + i + for i in [ + (support.TESTFN, "r"), + (sys.executable, "r"), + (3, "w"), + (support.TESTFN, "w"), + (support.TESTFN, "rb") if load_dh_params else None, + ] + if i is not None + ], + actual_mode, + ) + self.assertSequenceEqual([], actual_flag) + + def test_cantrace(self): + traced = [] + + def trace(frame, event, *args): + if frame.f_code == TestHook.__call__.__code__: + traced.append(event) + + old = sys.settrace(trace) + try: + with TestHook() as hook: + # No traced call + eval("1") + + # No traced call + hook.__cantrace__ = False + eval("2") + + # One traced call + hook.__cantrace__ = True + eval("3") + + # Two traced calls (writing to private member, eval) + hook.__cantrace__ = 1 + eval("4") + + # One traced call (writing to private member) + hook.__cantrace__ = 0 + finally: + sys.settrace(old) + + self.assertSequenceEqual(["call"] * 4, traced) + + +if __name__ == "__main__": + if len(sys.argv) >= 2 and sys.argv[1] == "spython_test": + # Doesn't matter what we add - it will be blocked + sys.addaudithook(None) + + sys.exit(0) + + unittest.main() diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 32aabe30a5c8c3..87e90f74bb13db 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -927,5 +927,16 @@ def test_init_dont_parse_argv(self): api=API_PYTHON) +class AuditingTests(EmbeddingTestsMixin, unittest.TestCase): + def test_open_code_hook(self): + self.run_embedded_interpreter("test_open_code_hook") + + def test_audit(self): + self.run_embedded_interpreter("test_audit") + + def test_audit_subinterpreter(self): + self.run_embedded_interpreter("test_audit_subinterpreter") + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index 57a02656206ff4..26e4500ae8cfcd 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -565,6 +565,7 @@ def __setattr__(self, name, value): self.assertRaises(MyException, MyFileIO, fd) os.close(fd) # should not raise OSError(EBADF) + class COtherFileTests(OtherFileTests, unittest.TestCase): FileIO = _io.FileIO modulename = '_io' @@ -576,10 +577,32 @@ def testInvalidFd_overflow(self): self.assertRaises(TypeError, self.FileIO, _testcapi.INT_MAX + 1) self.assertRaises(TypeError, self.FileIO, _testcapi.INT_MIN - 1) + def test_open_code(self): + # Check that the default behaviour of open_code matches + # open("rb") + with self.FileIO(__file__, "rb") as f: + expected = f.read() + with _io.open_code(__file__) as f: + actual = f.read() + self.assertEqual(expected, actual) + + class PyOtherFileTests(OtherFileTests, unittest.TestCase): FileIO = _pyio.FileIO modulename = '_pyio' + def test_open_code(self): + # Check that the default behaviour of open_code matches + # open("rb") + with self.FileIO(__file__, "rb") as f: + expected = f.read() + with check_warnings(quiet=True) as w: + # Always test _open_code_with_warning + with _pyio._open_code_with_warning(__file__) as f: + actual = f.read() + self.assertEqual(expected, actual) + self.assertNotEqual(w.warnings, []) + def test_main(): # Historically, these tests have been sloppy about removing TESTFN. diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 2c3bf890667997..6f22b35a9ab9f1 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3861,7 +3861,7 @@ def test___all__(self): for name in self.io.__all__: obj = getattr(self.io, name, None) self.assertIsNotNone(obj, name) - if name == "open": + if name in ("open", "open_code"): continue elif "error" in name.lower() or name == "UnsupportedOperation": self.assertTrue(issubclass(obj, Exception), name) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 9b21afb74e6e27..afce8eb1a1b165 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -521,6 +521,7 @@ def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): meth = getattr(processor, meth_name) req = meth(req) + sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method()) response = self._open(req, data) # post-process response diff --git a/Lib/zipimport.py b/Lib/zipimport.py index f430abd6a77c59..fd917c16b01535 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -351,7 +351,7 @@ def _get_module_info(self, fullname): # data_size and file_offset are 0. def _read_directory(archive): try: - fp = _io.open(archive, 'rb') + fp = _io.open_code(archive) except OSError: raise ZipImportError(f"can't open Zip file: {archive!r}", path=archive) @@ -533,7 +533,7 @@ def _get_data(archive, toc_entry): if data_size < 0: raise ZipImportError('negative data size') - with _io.open(archive, 'rb') as fp: + with _io.open_code(archive) as fp: # Check to make sure the local file header is correct try: fp.seek(file_offset) diff --git a/Makefile.pre.in b/Makefile.pre.in index d006a73c38bed6..12891e938236a4 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1052,6 +1052,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/abstract.h \ $(srcdir)/Include/cpython/coreconfig.h \ $(srcdir)/Include/cpython/dictobject.h \ + $(srcdir)/Include/cpython/fileobject.h \ $(srcdir)/Include/cpython/interpreteridobject.h \ $(srcdir)/Include/cpython/object.h \ $(srcdir)/Include/cpython/objimpl.h \ @@ -1059,6 +1060,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/pylifecycle.h \ $(srcdir)/Include/cpython/pymem.h \ $(srcdir)/Include/cpython/pystate.h \ + $(srcdir)/Include/cpython/sysmodule.h \ $(srcdir)/Include/cpython/traceback.h \ $(srcdir)/Include/cpython/tupleobject.h \ $(srcdir)/Include/cpython/unicodeobject.h \ diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst new file mode 100644 index 00000000000000..5e23d31a24855f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst @@ -0,0 +1 @@ +Implement PEP 578, adding sys.audit, io.open_code and related APIs. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 7b5115359ed7e8..f4eb53657dd408 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2920,6 +2920,10 @@ PyCData_AtAddress(PyObject *type, void *buf) CDataObject *pd; StgDictObject *dict; + if (PySys_Audit("ctypes.cdata", "n", (Py_ssize_t)buf) < 0) { + return NULL; + } + assert(PyType_Check(type)); dict = PyType_stgdict(type); if (!dict) { @@ -3455,6 +3459,18 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } +#ifdef MS_WIN32 + if (PySys_Audit("ctypes.dlsym", + ((uintptr_t)name & ~0xFFFF) ? "Os" : "On", + dll, name) < 0) { + return NULL; + } +#else + if (PySys_Audit("ctypes.dlsym", "Os", dll, name) < 0) { + return NULL; + } +#endif + obj = PyObject_GetAttrString(dll, "_handle"); if (!obj) { Py_DECREF(ftuple); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index a8ba84be4a7612..8682d548722015 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1277,6 +1277,10 @@ static PyObject *load_library(PyObject *self, PyObject *args) if (!name) return NULL; + if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS /* bpo-36085: Limit DLL search directories to avoid pre-loading * attacks and enable use of the AddDllDirectory function. @@ -1382,6 +1386,9 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args) name_str = NULL; name2 = NULL; } + if (PySys_Audit("ctypes.dlopen", "s", name_str) < 0) { + return NULL; + } handle = ctypes_dlopen(name_str, mode); Py_XDECREF(name2); if (!handle) { diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 590d6ce9f1e52e..ba8f0018043f7d 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -503,6 +503,25 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, Py_XDECREF(modeobj); return NULL; } + +/*[clinic input] +_io.open_code + + path : unicode + +Opens the provided file with the intent to import the contents. + +This may perform extra validation beyond open(), but is otherwise interchangeable +with calling open(path, 'rb'). + +[clinic start generated code]*/ + +static PyObject * +_io_open_code_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=2fe4ecbd6f3d6844 input=f5c18e23f4b2ed9f]*/ +{ + return PyFile_OpenCodeObject(path); +} /* * Private helpers for the io module. @@ -630,6 +649,7 @@ iomodule_free(PyObject *mod) { static PyMethodDef module_methods[] = { _IO_OPEN_METHODDEF + _IO_OPEN_CODE_METHODDEF {NULL, NULL} }; diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 990c81c355747a..00ad616b41fe6e 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -281,4 +281,46 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw exit: return return_value; } -/*[clinic end generated code: output=19fc9b69a5166f63 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_io_open_code__doc__, +"open_code($module, /, path)\n" +"--\n" +"\n" +"Opens the provided file with the intent to import the contents.\n" +"\n" +"This may perform extra validation beyond open(), but is otherwise interchangeable\n" +"with calling open(path, \'rb\')."); + +#define _IO_OPEN_CODE_METHODDEF \ + {"open_code", (PyCFunction)(void(*)(void))_io_open_code, METH_FASTCALL|METH_KEYWORDS, _io_open_code__doc__}, + +static PyObject * +_io_open_code_impl(PyObject *module, PyObject *path); + +static PyObject * +_io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "open_code", 0}; + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("open_code", 1, "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + path = args[0]; + return_value = _io_open_code_impl(module, path); + +exit: + return return_value; +} +/*[clinic end generated code: output=d479285078750d68 input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index c502c430134ef6..52a6f49e1d325b 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -358,6 +358,10 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, flags |= O_CLOEXEC; #endif + if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) { + goto error; + } + if (fd >= 0) { self->fd = fd; self->closefd = closefd; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 87f3cf7b614aab..24a5d227701274 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -6659,6 +6659,11 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *global; PyObject *module; + if (PySys_Audit("pickle.find_class", "OO", + module_name, global_name) < 0) { + return NULL; + } + /* Try to map the old names used in Python 2.x to the new ones used in Python 3.x. We do this only with old pickle protocols and when the user has not disabled the feature. */ diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 8873519e6ce5df..1317fc9a172c0d 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -461,6 +461,12 @@ _winapi_CreateFile_impl(PyObject *module, LPCTSTR file_name, { HANDLE handle; + if (PySys_Audit("_winapi.CreateFile", "uIIII", + file_name, desired_access, share_mode, + creation_disposition, flags_and_attributes) < 0) { + return INVALID_HANDLE_VALUE; + } + Py_BEGIN_ALLOW_THREADS handle = CreateFile(file_name, desired_access, share_mode, security_attributes, @@ -542,6 +548,10 @@ _winapi_CreateJunction_impl(PyObject *module, LPWSTR src_path, if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0) return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER); + if (PySys_Audit("_winapi.CreateJunction", "uu", src_path, dst_path) < 0) { + return NULL; + } + /* Adjust privileges to allow rewriting directory entry as a junction point. */ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) @@ -670,6 +680,11 @@ _winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode, { HANDLE handle; + if (PySys_Audit("_winapi.CreateNamedPipe", "uII", + name, open_mode, pipe_mode) < 0) { + return INVALID_HANDLE_VALUE; + } + Py_BEGIN_ALLOW_THREADS handle = CreateNamedPipe(name, open_mode, pipe_mode, max_instances, out_buffer_size, @@ -704,6 +719,10 @@ _winapi_CreatePipe_impl(PyObject *module, PyObject *pipe_attrs, DWORD size) HANDLE write_pipe; BOOL result; + if (PySys_Audit("_winapi.CreatePipe", NULL) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS result = CreatePipe(&read_pipe, &write_pipe, NULL, size); Py_END_ALLOW_THREADS @@ -1055,6 +1074,11 @@ _winapi_CreateProcess_impl(PyObject *module, wchar_t *command_line_copy = NULL; AttributeList attribute_list = {0}; + if (PySys_Audit("_winapi.CreateProcess", "uuu", application_name, + command_line, current_directory) < 0) { + return NULL; + } + ZeroMemory(&si, sizeof(si)); si.StartupInfo.cb = sizeof(si); @@ -1270,8 +1294,10 @@ _winapi_GetModuleFileName_impl(PyObject *module, HMODULE module_handle) BOOL result; WCHAR filename[MAX_PATH]; + Py_BEGIN_ALLOW_THREADS result = GetModuleFileNameW(module_handle, filename, MAX_PATH); filename[MAX_PATH-1] = '\0'; + Py_END_ALLOW_THREADS if (! result) return PyErr_SetFromWindowsErr(GetLastError()); @@ -1402,9 +1428,16 @@ _winapi_OpenProcess_impl(PyObject *module, DWORD desired_access, { HANDLE handle; + if (PySys_Audit("_winapi.OpenProcess", "II", + process_id, desired_access) < 0) { + return INVALID_HANDLE_VALUE; + } + + Py_BEGIN_ALLOW_THREADS handle = OpenProcess(desired_access, inherit_handle, process_id); + Py_END_ALLOW_THREADS if (handle == NULL) { - PyErr_SetFromWindowsErr(0); + PyErr_SetFromWindowsErr(GetLastError()); handle = INVALID_HANDLE_VALUE; } @@ -1539,6 +1572,7 @@ _winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe, PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout}; DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL}; int i; + BOOL b; for (i = 0 ; i < 3 ; i++) { if (oArgs[i] != Py_None) { @@ -1549,7 +1583,11 @@ _winapi_SetNamedPipeHandleState_impl(PyObject *module, HANDLE named_pipe, } } - if (!SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2])) + Py_BEGIN_ALLOW_THREADS + b = SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2]); + Py_END_ALLOW_THREADS + + if (!b) return PyErr_SetFromWindowsErr(0); Py_RETURN_NONE; @@ -1573,6 +1611,11 @@ _winapi_TerminateProcess_impl(PyObject *module, HANDLE handle, { BOOL result; + if (PySys_Audit("_winapi.TerminateProcess", "nI", + (Py_ssize_t)handle, exit_code) < 0) { + return NULL; + } + result = TerminateProcess(handle, exit_code); if (! result) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 523afb99e8ae6e..423cac9910a293 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2635,6 +2635,11 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial)) return NULL; + if (PySys_Audit("array.__new__", "CO", + c, initial ? initial : Py_None) < 0) { + return NULL; + } + if (initial && c != 'u') { if (PyUnicode_Check(initial)) { PyErr_Format(PyExc_TypeError, "cannot use a str to initialize " diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 917c6362c11d9a..fdd60bbb6eefca 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1110,6 +1110,11 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) "mmap invalid access parameter."); } + if (PySys_Audit("mmap.__new__", "ini" _Py_PARSE_OFF_T, + fileno, map_size, access, offset) < 0) { + return NULL; + } + #ifdef __APPLE__ /* Issue #11277: fsync(2) is not enough on OS X - a special, OS X specific fcntl(2) is necessary to force DISKSYNC and get around mmap(2) bug */ @@ -1240,6 +1245,11 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) return NULL; } + if (PySys_Audit("mmap.__new__", "iniL", + fileno, map_size, access, offset) < 0) { + return NULL; + } + switch((access_mode)access) { case ACCESS_READ: flProtect = PAGE_READONLY; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9f15866d9d3db4..8ebe3a0be05350 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4264,6 +4264,11 @@ os_system_impl(PyObject *module, const Py_UNICODE *command) /*[clinic end generated code: output=5b7c3599c068ca42 input=303f5ce97df606b0]*/ { long result; + + if (PySys_Audit("system", "(u)", command) < 0) { + return -1; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH result = _wsystem(command); @@ -4286,6 +4291,11 @@ os_system_impl(PyObject *module, PyObject *command) { long result; const char *bytes = PyBytes_AsString(command); + + if (PySys_Audit("system", "(O)", command) < 0) { + return -1; + } + Py_BEGIN_ALLOW_THREADS result = system(bytes); Py_END_ALLOW_THREADS @@ -8279,6 +8289,10 @@ os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd) flags |= O_CLOEXEC; #endif + if (PySys_Audit("open", "OOi", path->object, Py_None, flags) < 0) { + return -1; + } + _Py_BEGIN_SUPPRESS_IPH do { Py_BEGIN_ALLOW_THREADS @@ -9598,6 +9612,10 @@ os_ftruncate_impl(PyObject *module, int fd, Py_off_t length) int result; int async_err = 0; + if (PySys_Audit("os.truncate", "in", fd, length) < 0) { + return NULL; + } + do { Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH @@ -9641,6 +9659,10 @@ os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) if (path->fd != -1) return os_ftruncate_impl(module, path->fd, length); + if (PySys_Audit("os.truncate", "On", path->object, length) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index c024542fe70923..74cdc0f2f6caed 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -3053,6 +3053,11 @@ sock_bind(PySocketSockObject *s, PyObject *addro) if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen, "bind")) { return NULL; } + + if (PySys_Audit("socket.bind", "OO", s, addro) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS res = bind(s->sock_fd, SAS2SA(&addrbuf), addrlen); Py_END_ALLOW_THREADS @@ -3219,6 +3224,10 @@ sock_connect(PySocketSockObject *s, PyObject *addro) return NULL; } + if (PySys_Audit("socket.connect", "OO", s, addro) < 0) { + return NULL; + } + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 1); if (res < 0) return NULL; @@ -3246,6 +3255,10 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro) return NULL; } + if (PySys_Audit("socket.connect", "OO", s, addro) < 0) { + return NULL; + } + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 0); if (res < 0) return NULL; @@ -4248,6 +4261,10 @@ sock_sendto(PySocketSockObject *s, PyObject *args) return NULL; } + if (PySys_Audit("socket.sendto", "OO", s, addro) < 0) { + return NULL; + } + ctx.buf = pbuf.buf; ctx.len = pbuf.len; ctx.flags = flags; @@ -4379,8 +4396,15 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) { goto finally; } + if (PySys_Audit("socket.sendmsg", "OO", s, addr_arg) < 0) { + return NULL; + } msg.msg_name = &addrbuf; msg.msg_namelen = addrlen; + } else { + if (PySys_Audit("socket.sendmsg", "OO", s, Py_None) < 0) { + return NULL; + } } /* Fill in an iovec for each message part, and save the Py_buffer @@ -5030,6 +5054,17 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) &family, &type, &proto, &fdobj)) return -1; +#ifdef MS_WINDOWS + /* In this case, we don't use the family, type and proto args */ + if (fdobj != NULL && fdobj != Py_None) +#endif + { + if (PySys_Audit("socket.__new__", "Oiii", + s, family, type, proto) < 0) { + return -1; + } + } + if (fdobj != NULL && fdobj != Py_None) { #ifdef MS_WINDOWS /* recreate a socket that was duplicated */ @@ -5042,6 +5077,12 @@ sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) return -1; } memcpy(&info, PyBytes_AS_STRING(fdobj), sizeof(info)); + + if (PySys_Audit("socket()", "iii", info.iAddressFamily, + info.iSocketType, info.iProtocol) < 0) { + return -1; + } + Py_BEGIN_ALLOW_THREADS fd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &info, 0, WSA_FLAG_OVERLAPPED); @@ -5284,6 +5325,10 @@ static PyTypeObject sock_type = { static PyObject * socket_gethostname(PyObject *self, PyObject *unused) { + if (PySys_Audit("socket.gethostname", NULL) < 0) { + return NULL; + } + #ifdef MS_WINDOWS /* Don't use winsock's gethostname, as this returns the ANSI version of the hostname, whereas we need a Unicode string. @@ -5362,6 +5407,11 @@ extern int sethostname(const char *, size_t); return NULL; flag = 1; } + + if (PySys_Audit("socket.sethostname", "(O)", hnobj) < 0) { + return NULL; + } + res = PyObject_GetBuffer(hnobj, &buf, PyBUF_SIMPLE); if (!res) { res = sethostname(buf.buf, buf.len); @@ -5387,6 +5437,9 @@ socket_gethostbyname(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "et:gethostbyname", "idna", &name)) return NULL; + if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { + goto finally; + } if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0) goto finally; ret = make_ipv4_addr(&addrbuf); @@ -5571,6 +5624,9 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "et:gethostbyname_ex", "idna", &name)) return NULL; + if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { + goto finally; + } if (setipaddr(name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) goto finally; Py_BEGIN_ALLOW_THREADS @@ -5649,6 +5705,9 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "et:gethostbyaddr", "idna", &ip_num)) return NULL; + if (PySys_Audit("socket.gethostbyaddr", "O", args) < 0) { + goto finally; + } af = AF_UNSPEC; if (setipaddr(ip_num, sa, sizeof(addr), af) < 0) goto finally; @@ -5720,6 +5779,11 @@ socket_getservbyname(PyObject *self, PyObject *args) struct servent *sp; if (!PyArg_ParseTuple(args, "s|s:getservbyname", &name, &proto)) return NULL; + + if (PySys_Audit("socket.getservbyname", "ss", name, proto) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS sp = getservbyname(name, proto); Py_END_ALLOW_THREADS @@ -5757,6 +5821,11 @@ socket_getservbyport(PyObject *self, PyObject *args) "getservbyport: port must be 0-65535."); return NULL; } + + if (PySys_Audit("socket.getservbyport", "is", port, proto) < 0) { + return NULL; + } + Py_BEGIN_ALLOW_THREADS sp = getservbyport(htons((short)port), proto); Py_END_ALLOW_THREADS @@ -6392,6 +6461,12 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) pptr = "00"; } #endif + + if (PySys_Audit("socket.getaddrinfo", "OOiii", + hobj, pobj, family, socktype, protocol) < 0) { + return NULL; + } + memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = socktype; @@ -6483,6 +6558,11 @@ socket_getnameinfo(PyObject *self, PyObject *args) "getnameinfo(): flowinfo must be 0-1048575."); return NULL; } + + if (PySys_Audit("socket.getnameinfo", "(O)", sa) < 0) { + return NULL; + } + PyOS_snprintf(pbuf, sizeof(pbuf), "%d", port); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 62d7c5d329f07b..f4e48a9757e587 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -380,6 +380,12 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) &PyTuple_Type, &cellvars)) return NULL; + if (PySys_Audit("code.__new__", "OOOiiiii", + code, filename, name, argcount, kwonlyargcount, + nlocals, stacksize, flags) < 0) { + goto cleanup; + } + if (argcount < 0) { PyErr_SetString( PyExc_ValueError, diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 8f1a823768f393..0db8057334fd36 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -144,6 +144,14 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) if (descr_check((PyDescrObject *)descr, obj, &res)) return res; + + if (descr->d_member->flags & READ_RESTRICTED) { + if (PySys_Audit("object.__getattr__", "Os", + obj ? obj : Py_None, descr->d_member->name) < 0) { + return NULL; + } + } + return PyMember_GetOne((char *)obj, descr->d_member); } diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 39c7c109979a48..3b026335d3f8f2 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -2,6 +2,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_pystate.h" #if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER) /* clang MemorySanitizer doesn't yet understand getc_unlocked. */ @@ -33,7 +34,8 @@ PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const c PyObject *io, *stream; _Py_IDENTIFIER(open); - io = PyImport_ImportModule("io"); + /* import _io in case we are being used to open io.py */ + io = PyImport_ImportModule("_io"); if (io == NULL) return NULL; stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode, @@ -514,6 +516,72 @@ PyTypeObject PyStdPrinter_Type = { }; +/* ************************** open_code hook *************************** + * The open_code hook allows embedders to override the method used to + * open files that are going to be used by the runtime to execute code + */ + +int +PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) { + if (Py_IsInitialized() && + PySys_Audit("setopencodehook", NULL) < 0) { + return -1; + } + + if (_PyRuntime.open_code_hook) { + if (Py_IsInitialized()) { + PyErr_SetString(PyExc_SystemError, + "failed to change existing open_code hook"); + } + return -1; + } + + _PyRuntime.open_code_hook = hook; + _PyRuntime.open_code_userdata = userData; + return 0; +} + +PyObject * +PyFile_OpenCodeObject(PyObject *path) +{ + PyObject *iomod, *f = NULL; + _Py_IDENTIFIER(open); + + if (!PyUnicode_Check(path)) { + PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'", + Py_TYPE(path)->tp_name); + return NULL; + } + + Py_OpenCodeHookFunction hook = _PyRuntime.open_code_hook; + if (hook) { + f = hook(path, _PyRuntime.open_code_userdata); + } else { + iomod = PyImport_ImportModule("_io"); + if (iomod) { + f = _PyObject_CallMethodId(iomod, &PyId_open, "Os", + path, "rb"); + Py_DECREF(iomod); + } + } + + return f; +} + +PyObject * +PyFile_OpenCode(const char *utf8path) +{ + PyObject *pathobj = PyUnicode_FromString(utf8path); + PyObject *f; + if (!pathobj) { + return NULL; + } + f = PyFile_OpenCodeObject(pathobj); + Py_DECREF(pathobj); + return f; +} + + #ifdef __cplusplus } #endif diff --git a/Objects/funcobject.c b/Objects/funcobject.c index e8e2d2e15ccabf..09b94c26423666 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -250,6 +250,10 @@ static PyMemberDef func_memberlist[] = { static PyObject * func_get_code(PyFunctionObject *op, void *Py_UNUSED(ignored)) { + if (PySys_Audit("object.__getattr__", "Os", op, "__code__") < 0) { + return NULL; + } + Py_INCREF(op->func_code); return op->func_code; } @@ -266,6 +270,12 @@ func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__code__ must be set to a code object"); return -1; } + + if (PySys_Audit("object.__setattr__", "OsO", + op, "__code__", value) < 0) { + return -1; + } + nfree = PyCode_GetNumFree((PyCodeObject *)value); nclosure = (op->func_closure == NULL ? 0 : PyTuple_GET_SIZE(op->func_closure)); @@ -329,6 +339,9 @@ func_set_qualname(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored static PyObject * func_get_defaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) { + if (PySys_Audit("object.__getattr__", "Os", op, "__defaults__") < 0) { + return NULL; + } if (op->func_defaults == NULL) { Py_RETURN_NONE; } @@ -348,6 +361,16 @@ func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored "__defaults__ must be set to a tuple object"); return -1; } + if (value) { + if (PySys_Audit("object.__setattr__", "OsO", + op, "__defaults__", value) < 0) { + return -1; + } + } else if (PySys_Audit("object.__delattr__", "Os", + op, "__defaults__") < 0) { + return -1; + } + Py_XINCREF(value); Py_XSETREF(op->func_defaults, value); return 0; @@ -356,6 +379,10 @@ func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored static PyObject * func_get_kwdefaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) { + if (PySys_Audit("object.__getattr__", "Os", + op, "__kwdefaults__") < 0) { + return NULL; + } if (op->func_kwdefaults == NULL) { Py_RETURN_NONE; } @@ -375,6 +402,16 @@ func_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignor "__kwdefaults__ must be set to a dict object"); return -1; } + if (value) { + if (PySys_Audit("object.__setattr__", "OsO", + op, "__kwdefaults__", value) < 0) { + return -1; + } + } else if (PySys_Audit("object.__delattr__", "Os", + op, "__kwdefaults__") < 0) { + return -1; + } + Py_XINCREF(value); Py_XSETREF(op->func_kwdefaults, value); return 0; @@ -507,6 +544,9 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, } } } + if (PySys_Audit("function.__new__", "O", code) < 0) { + return NULL; + } newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code, globals); diff --git a/Objects/object.c b/Objects/object.c index 604f5e0d488259..f842ab3889675e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1366,6 +1366,14 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, } } + /* XXX [Steve Dower] These are really noisy - worth it? */ + /*if (PyType_Check(obj) || PyModule_Check(obj)) { + if (value && PySys_Audit("object.__setattr__", "OOO", obj, name, value) < 0) + return -1; + if (!value && PySys_Audit("object.__delattr__", "OO", obj, name) < 0) + return -1; + }*/ + if (dict == NULL) { dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c086f182aa958a..49b45b8518cc45 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -392,6 +392,12 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam "can't delete %s.%s", type->tp_name, name); return 0; } + + if (PySys_Audit("object.__setattr__", "OsO", + type, name, value) < 0) { + return 0; + } + return 1; } @@ -3956,6 +3962,11 @@ object_set_class(PyObject *self, PyObject *value, void *closure) Py_TYPE(value)->tp_name); return -1; } + if (PySys_Audit("object.__setattr__", "OsO", + self, "__class__", value) < 0) { + return -1; + } + newto = (PyTypeObject *)value; /* In versions of CPython prior to 3.5, the code in compatible_for_assignment was not set up to correctly check for memory diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index df57adcfd6050c..681c4db65df0ac 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -129,12 +129,14 @@ + + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 5515d9bedeb166..32964c008aa257 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -90,6 +90,9 @@ Include + + Include + Include @@ -108,6 +111,9 @@ Include + + Include + Include diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index cb0e6d7f9df26a..d84c1b13cf103c 100644 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1201,6 +1201,10 @@ class PartingShots(StaticVisitor): char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; + if (PySys_Audit("compile", "OO", ast, Py_None) < 0) { + return NULL; + } + req_type[0] = (PyObject*)Module_type; req_type[1] = (PyObject*)Expression_type; req_type[2] = (PyObject*)Interactive_type; diff --git a/Parser/parsetok.c b/Parser/parsetok.c index 55fd7f7db3da81..a5d78974b871b3 100644 --- a/Parser/parsetok.c +++ b/Parser/parsetok.c @@ -94,6 +94,11 @@ PyParser_ParseStringObject(const char *s, PyObject *filename, if (initerr(err_ret, filename) < 0) return NULL; + if (PySys_Audit("compile", "yO", s, err_ret->filename) < 0) { + err_ret->error = E_ERROR; + return NULL; + } + if (*flags & PyPARSE_IGNORE_COOKIE) tok = PyTokenizer_FromUTF8(s, exec_input); else @@ -165,6 +170,10 @@ PyParser_ParseFileObject(FILE *fp, PyObject *filename, if (initerr(err_ret, filename) < 0) return NULL; + if (PySys_Audit("compile", "OO", Py_None, err_ret->filename) < 0) { + return NULL; + } + if ((tok = PyTokenizer_FromFile(fp, enc, ps1, ps2)) == NULL) { err_ret->error = E_NOMEM; return NULL; diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 6bd55deab4012a..21d3b445d7752c 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1091,6 +1091,164 @@ static int test_init_dev_mode(void) return 0; } +static PyObject *_open_code_hook(PyObject *path, void *data) +{ + if (PyUnicode_CompareWithASCIIString(path, "$$test-filename") == 0) { + return PyLong_FromVoidPtr(data); + } + PyObject *io = PyImport_ImportModule("_io"); + if (!io) { + return NULL; + } + return PyObject_CallMethod(io, "open", "Os", path, "rb"); +} + +static int test_open_code_hook(void) +{ + int result = 0; + + /* Provide a hook */ + result = PyFile_SetOpenCodeHook(_open_code_hook, &result); + if (result) { + printf("Failed to set hook\n"); + return 1; + } + /* A second hook should fail */ + result = PyFile_SetOpenCodeHook(_open_code_hook, &result); + if (!result) { + printf("Should have failed to set second hook\n"); + return 2; + } + + Py_IgnoreEnvironmentFlag = 0; + _testembed_Py_Initialize(); + result = 0; + + PyObject *r = PyFile_OpenCode("$$test-filename"); + if (!r) { + PyErr_Print(); + result = 3; + } else { + void *cmp = PyLong_AsVoidPtr(r); + Py_DECREF(r); + if (cmp != &result) { + printf("Did not get expected result from hook\n"); + result = 4; + } + } + + if (!result) { + PyObject *io = PyImport_ImportModule("_io"); + PyObject *r = io + ? PyObject_CallMethod(io, "open_code", "s", "$$test-filename") + : NULL; + if (!r) { + PyErr_Print(); + result = 5; + } else { + void *cmp = PyLong_AsVoidPtr(r); + Py_DECREF(r); + if (cmp != &result) { + printf("Did not get expected result from hook\n"); + result = 6; + } + } + Py_XDECREF(io); + } + + Py_Finalize(); + return result; +} + +static int _audit_hook(const char *event, PyObject *args, void *userdata) +{ + if (strcmp(event, "_testembed.raise") == 0) { + PyErr_SetString(PyExc_RuntimeError, "Intentional error"); + return -1; + } else if (strcmp(event, "_testembed.set") == 0) { + if (!PyArg_ParseTuple(args, "n", userdata)) { + return -1; + } + return 0; + } + return 0; +} + +static int _test_audit(Py_ssize_t setValue) +{ + Py_ssize_t sawSet = 0; + + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_hook, &sawSet); + _testembed_Py_Initialize(); + + if (PySys_Audit("_testembed.raise", NULL) == 0) { + printf("No error raised"); + return 1; + } + if (PySys_Audit("_testembed.nop", NULL) != 0) { + printf("Nop event failed"); + /* Exception from above may still remain */ + PyErr_Clear(); + return 2; + } + if (!PyErr_Occurred()) { + printf("Exception not preserved"); + return 3; + } + PyErr_Clear(); + + if (PySys_Audit("_testembed.set", "n", setValue) != 0) { + PyErr_Print(); + printf("Set event failed"); + return 4; + } + + if (sawSet != 42) { + printf("Failed to see *userData change\n"); + return 5; + } + return 0; +} + +static int test_audit(void) +{ + int result = _test_audit(42); + Py_Finalize(); + return result; +} + +static volatile int _audit_subinterpreter_interpreter_count = 0; + +static int _audit_subinterpreter_hook(const char *event, PyObject *args, void *userdata) +{ + printf("%s\n", event); + if (strcmp(event, "cpython.PyInterpreterState_New") == 0) { + _audit_subinterpreter_interpreter_count += 1; + } + return 0; +} + +static int test_audit_subinterpreter(void) +{ + PyThreadState *ts; + + Py_IgnoreEnvironmentFlag = 0; + PySys_AddAuditHook(_audit_subinterpreter_hook, NULL); + _testembed_Py_Initialize(); + + ts = Py_NewInterpreter(); + ts = Py_NewInterpreter(); + ts = Py_NewInterpreter(); + + Py_Finalize(); + + switch (_audit_subinterpreter_interpreter_count) { + case 3: return 0; + case 0: return -1; + default: return _audit_subinterpreter_interpreter_count; + } +} static int test_init_read_set(void) { @@ -1299,6 +1457,9 @@ static struct TestCase TestCases[] = { {"test_init_run_main", test_init_run_main}, {"test_init_main", test_init_main}, {"test_run_main", test_run_main}, + {"test_open_code_hook", test_open_code_hook}, + {"test_audit", test_audit}, + {"test_audit_subinterpreter", test_audit_subinterpreter}, {NULL, NULL} }; diff --git a/Python/Python-ast.c b/Python/Python-ast.c index e84a7586a70723..39a40eedca3267 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -9024,6 +9024,10 @@ mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_ver char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; + if (PySys_Audit("compile", "OO", ast, Py_None) < 0) { + return NULL; + } + req_type[0] = (PyObject*)Module_type; req_type[1] = (PyObject*)Expression_type; req_type[2] = (PyObject*)Interactive_type; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 047cca057b41ae..ff5a51216939e7 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -977,9 +977,13 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, } if (PyCode_Check(source)) { + if (PySys_Audit("exec", "O", source) < 0) { + return NULL; + } + if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { PyErr_SetString(PyExc_TypeError, - "code object passed to eval() may not contain free variables"); + "code object passed to eval() may not contain free variables"); return NULL; } return PyEval_EvalCode(source, globals, locals); @@ -1061,6 +1065,10 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, } if (PyCode_Check(source)) { + if (PySys_Audit("exec", "O", source) < 0) { + return NULL; + } + if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { PyErr_SetString(PyExc_TypeError, "code object passed to exec() may not " @@ -1207,7 +1215,14 @@ static PyObject * builtin_id(PyModuleDef *self, PyObject *v) /*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/ { - return PyLong_FromVoidPtr(v); + PyObject *id = PyLong_FromVoidPtr(v); + + if (id && PySys_Audit("builtins.id", "O", id) < 0) { + Py_DECREF(id); + return NULL; + } + + return id; } @@ -1986,6 +2001,10 @@ builtin_input_impl(PyObject *module, PyObject *prompt) return NULL; } + if (PySys_Audit("builtins.input", "O", prompt ? prompt : Py_None) < 0) { + return NULL; + } + /* First of all, flush stderr */ tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL); if (tmp == NULL) @@ -2116,6 +2135,13 @@ builtin_input_impl(PyObject *module, PyObject *prompt) Py_DECREF(stdin_errors); Py_XDECREF(po); PyMem_FREE(s); + + if (result != NULL) { + if (PySys_Audit("builtins.input/result", "O", result) < 0) { + return NULL; + } + } + return result; _readline_errors: diff --git a/Python/ceval.c b/Python/ceval.c index 1bb4704572b44b..781b10dfac9aef 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4555,6 +4555,10 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, void PyEval_SetProfile(Py_tracefunc func, PyObject *arg) { + if (PySys_Audit("sys.setprofile", NULL) < 0) { + return; + } + PyThreadState *tstate = _PyThreadState_GET(); PyObject *temp = tstate->c_profileobj; Py_XINCREF(arg); @@ -4572,6 +4576,10 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg) void PyEval_SetTrace(Py_tracefunc func, PyObject *arg) { + if (PySys_Audit("sys.settrace", NULL) < 0) { + return; + } + _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); PyObject *temp = tstate->c_traceobj; @@ -4608,6 +4616,11 @@ void _PyEval_SetCoroutineWrapper(PyObject *wrapper) { PyThreadState *tstate = _PyThreadState_GET(); + + if (PySys_Audit("sys.set_coroutine_wrapper", NULL) < 0) { + return; + } + Py_XINCREF(wrapper); Py_XSETREF(tstate->coroutine_wrapper, wrapper); } @@ -4623,6 +4636,11 @@ void _PyEval_SetAsyncGenFirstiter(PyObject *firstiter) { PyThreadState *tstate = _PyThreadState_GET(); + + if (PySys_Audit("sys.set_asyncgen_hook_firstiter", NULL) < 0) { + return; + } + Py_XINCREF(firstiter); Py_XSETREF(tstate->async_gen_firstiter, firstiter); } @@ -4638,6 +4656,11 @@ void _PyEval_SetAsyncGenFinalizer(PyObject *finalizer) { PyThreadState *tstate = _PyThreadState_GET(); + + if (PySys_Audit("sys.set_asyncgen_hook_finalizer", NULL) < 0) { + return; + } + Py_XINCREF(finalizer); Py_XSETREF(tstate->async_gen_finalizer, finalizer); } diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index aede60ac85b519..2a4ec72b0dc34e 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -2,6 +2,38 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(sys_addaudithook__doc__, +"addaudithook($module, /, hook)\n" +"--\n" +"\n" +"Adds a new audit hook callback."); + +#define SYS_ADDAUDITHOOK_METHODDEF \ + {"addaudithook", (PyCFunction)(void(*)(void))sys_addaudithook, METH_FASTCALL|METH_KEYWORDS, sys_addaudithook__doc__}, + +static PyObject * +sys_addaudithook_impl(PyObject *module, PyObject *hook); + +static PyObject * +sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"hook", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0}; + PyObject *argsbuf[1]; + PyObject *hook; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + hook = args[0]; + return_value = sys_addaudithook_impl(module, hook); + +exit: + return return_value; +} + PyDoc_STRVAR(sys_displayhook__doc__, "displayhook($module, object, /)\n" "--\n" @@ -1076,4 +1108,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=603e4d5a453dc769 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3c32bc91ec659509 input=a9049054013a1b77]*/ diff --git a/Python/fileutils.c b/Python/fileutils.c index dfad48edb81a1d..178e2f1268f831 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -1262,6 +1262,10 @@ _Py_open_impl(const char *pathname, int flags, int gil_held) #endif if (gil_held) { + if (PySys_Audit("open", "sOi", pathname, Py_None, flags) < 0) { + return -1; + } + do { Py_BEGIN_ALLOW_THREADS fd = open(pathname, flags); @@ -1331,6 +1335,9 @@ FILE * _Py_wfopen(const wchar_t *path, const wchar_t *mode) { FILE *f; + if (PySys_Audit("open", "uui", path, mode, 0) < 0) { + return NULL; + } #ifndef MS_WINDOWS char *cpath; char cmode[10]; @@ -1366,6 +1373,10 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode) FILE* _Py_fopen(const char *pathname, const char *mode) { + if (PySys_Audit("open", "ssi", pathname, mode, 0) < 0) { + return NULL; + } + FILE *f = fopen(pathname, mode); if (f == NULL) return NULL; @@ -1401,6 +1412,9 @@ _Py_fopen_obj(PyObject *path, const char *mode) assert(PyGILState_Check()); + if (PySys_Audit("open", "Osi", path, mode, 0) < 0) { + return NULL; + } if (!PyUnicode_Check(path)) { PyErr_Format(PyExc_TypeError, "str file path expected under Windows, got %R", @@ -1434,6 +1448,10 @@ _Py_fopen_obj(PyObject *path, const char *mode) return NULL; path_bytes = PyBytes_AS_STRING(bytes); + if (PySys_Audit("open", "Osi", path, mode, 0) < 0) { + return NULL; + } + do { Py_BEGIN_ALLOW_THREADS f = fopen(path_bytes, mode); diff --git a/Python/import.c b/Python/import.c index c634edb4c7fcb7..ec172b29f739fc 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1661,6 +1661,17 @@ import_find_and_load(PyObject *abs_name) _PyTime_t t1 = 0, accumulated_copy = accumulated; + PyObject *sys_path = PySys_GetObject("path"); + PyObject *sys_meta_path = PySys_GetObject("meta_path"); + PyObject *sys_path_hooks = PySys_GetObject("path_hooks"); + if (PySys_Audit("import", "OOOOO", + abs_name, Py_None, sys_path ? sys_path : Py_None, + sys_meta_path ? sys_meta_path : Py_None, + sys_path_hooks ? sys_path_hooks : Py_None) < 0) { + return NULL; + } + + /* XOptions is initialized after first some imports. * So we can't have negative cache before completed initialization. * Anyway, importlib._find_and_load is much slower than diff --git a/Python/importdl.c b/Python/importdl.c index 50231ff28848a1..1d0d32a2371f80 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -119,6 +119,11 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) if (path == NULL) goto error; + if (PySys_Audit("import", "OOOOO", name_unicode, path, + Py_None, Py_None, Py_None) < 0) { + return NULL; + } + #ifdef MS_WINDOWS exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf, path, fp); diff --git a/Python/importlib_external.h b/Python/importlib_external.h index b5b4df228057a3..36b95d99b23706 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -1460,1235 +1460,1241 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 3,0,0,115,2,0,0,0,0,3,122,23,70,105,108,101, 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, 97,109,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,10,0,0,0,67,0,0,0,115,44,0,0, - 0,116,0,160,1,124,1,100,1,161,2,143,22,125,2,124, - 2,160,2,161,0,87,0,2,0,53,0,81,0,82,0,163, - 0,83,0,81,0,82,0,88,0,100,2,83,0,41,3,122, - 39,82,101,116,117,114,110,32,116,104,101,32,100,97,116,97, - 32,102,114,111,109,32,112,97,116,104,32,97,115,32,114,97, - 119,32,98,121,116,101,115,46,218,1,114,78,41,3,114,64, - 0,0,0,114,65,0,0,0,90,4,114,101,97,100,41,3, - 114,119,0,0,0,114,44,0,0,0,114,68,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,227, - 0,0,0,196,3,0,0,115,4,0,0,0,0,2,14,1, - 122,19,70,105,108,101,76,111,97,100,101,114,46,103,101,116, - 95,100,97,116,97,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,18, - 0,0,0,124,0,160,0,124,1,161,1,114,14,124,0,83, - 0,100,0,83,0,114,110,0,0,0,41,1,114,182,0,0, - 0,169,2,114,119,0,0,0,114,216,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,19,103,101, - 116,95,114,101,115,111,117,114,99,101,95,114,101,97,100,101, - 114,203,3,0,0,115,6,0,0,0,0,2,10,1,4,1, - 122,30,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 3,0,0,0,10,0,0,0,67,0,0,0,115,102,0,0, + 0,116,0,124,0,116,1,116,2,102,2,131,2,114,58,116, + 3,160,4,116,5,124,1,131,1,161,1,143,22,125,2,124, + 2,160,6,161,0,87,0,2,0,53,0,81,0,82,0,163, + 0,83,0,81,0,82,0,88,0,110,40,116,3,160,7,124, + 1,100,1,161,2,143,22,125,2,124,2,160,6,161,0,87, + 0,2,0,53,0,81,0,82,0,163,0,83,0,81,0,82, + 0,88,0,100,2,83,0,41,3,122,39,82,101,116,117,114, + 110,32,116,104,101,32,100,97,116,97,32,102,114,111,109,32, + 112,97,116,104,32,97,115,32,114,97,119,32,98,121,116,101, + 115,46,218,1,114,78,41,8,114,161,0,0,0,114,221,0, + 0,0,218,19,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,114,64,0,0,0,90,9,111,112, + 101,110,95,99,111,100,101,114,85,0,0,0,90,4,114,101, + 97,100,114,65,0,0,0,41,3,114,119,0,0,0,114,44, + 0,0,0,114,68,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,227,0,0,0,196,3,0,0, + 115,10,0,0,0,0,2,14,1,16,1,28,2,14,1,122, + 19,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, + 100,97,116,97,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,3,0,0,0,67,0,0,0,115,18,0, + 0,0,124,0,160,0,124,1,161,1,114,14,124,0,83,0, + 100,0,83,0,114,110,0,0,0,41,1,114,182,0,0,0, + 169,2,114,119,0,0,0,114,216,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,19,103,101,116, 95,114,101,115,111,117,114,99,101,95,114,101,97,100,101,114, + 207,3,0,0,115,6,0,0,0,0,2,10,1,4,1,122, + 30,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, + 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 4,0,0,0,67,0,0,0,115,32,0,0,0,116,0,116, + 1,124,0,106,2,131,1,100,1,25,0,124,1,131,2,125, + 2,116,3,160,4,124,2,100,2,161,2,83,0,41,3,78, + 114,73,0,0,0,114,251,0,0,0,41,5,114,38,0,0, + 0,114,47,0,0,0,114,44,0,0,0,114,64,0,0,0, + 114,65,0,0,0,169,3,114,119,0,0,0,90,8,114,101, + 115,111,117,114,99,101,114,44,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,13,111,112,101,110, + 95,114,101,115,111,117,114,99,101,213,3,0,0,115,4,0, + 0,0,0,1,20,1,122,24,70,105,108,101,76,111,97,100, + 101,114,46,111,112,101,110,95,114,101,115,111,117,114,99,101, 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,4,0,0,0,67,0,0,0,115,32,0,0,0,116,0, - 116,1,124,0,106,2,131,1,100,1,25,0,124,1,131,2, - 125,2,116,3,160,4,124,2,100,2,161,2,83,0,41,3, - 78,114,73,0,0,0,114,251,0,0,0,41,5,114,38,0, - 0,0,114,47,0,0,0,114,44,0,0,0,114,64,0,0, - 0,114,65,0,0,0,169,3,114,119,0,0,0,90,8,114, - 101,115,111,117,114,99,101,114,44,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,13,111,112,101, - 110,95,114,101,115,111,117,114,99,101,209,3,0,0,115,4, - 0,0,0,0,1,20,1,122,24,70,105,108,101,76,111,97, - 100,101,114,46,111,112,101,110,95,114,101,115,111,117,114,99, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,3,0,0,0,67,0,0,0,115,38,0,0,0,124, - 0,160,0,124,1,161,1,115,14,116,1,130,1,116,2,116, - 3,124,0,106,4,131,1,100,1,25,0,124,1,131,2,125, - 2,124,2,83,0,169,2,78,114,73,0,0,0,41,5,218, - 11,105,115,95,114,101,115,111,117,114,99,101,218,17,70,105, - 108,101,78,111,116,70,111,117,110,100,69,114,114,111,114,114, - 38,0,0,0,114,47,0,0,0,114,44,0,0,0,114,254, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,13,114,101,115,111,117,114,99,101,95,112,97,116, - 104,213,3,0,0,115,8,0,0,0,0,1,10,1,4,1, - 20,1,122,24,70,105,108,101,76,111,97,100,101,114,46,114, - 101,115,111,117,114,99,101,95,112,97,116,104,99,2,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, - 0,67,0,0,0,115,40,0,0,0,116,0,124,1,107,6, - 114,12,100,1,83,0,116,1,116,2,124,0,106,3,131,1, - 100,2,25,0,124,1,131,2,125,2,116,4,124,2,131,1, - 83,0,41,3,78,70,114,73,0,0,0,41,5,114,35,0, - 0,0,114,38,0,0,0,114,47,0,0,0,114,44,0,0, - 0,114,54,0,0,0,169,3,114,119,0,0,0,114,117,0, - 0,0,114,44,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,1,1,0,0,219,3,0,0,115, - 8,0,0,0,0,1,8,1,4,1,20,1,122,22,70,105, - 108,101,76,111,97,100,101,114,46,105,115,95,114,101,115,111, - 117,114,99,101,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,5,0,0,0,67,0,0,0,115,24,0, - 0,0,116,0,116,1,160,2,116,3,124,0,106,4,131,1, - 100,1,25,0,161,1,131,1,83,0,114,0,1,0,0,41, - 5,218,4,105,116,101,114,114,2,0,0,0,218,7,108,105, - 115,116,100,105,114,114,47,0,0,0,114,44,0,0,0,114, - 246,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,8,99,111,110,116,101,110,116,115,225,3,0, - 0,115,2,0,0,0,0,1,122,19,70,105,108,101,76,111, - 97,100,101,114,46,99,111,110,116,101,110,116,115,41,17,114, - 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, - 0,0,0,114,209,0,0,0,114,243,0,0,0,114,247,0, - 0,0,114,136,0,0,0,114,220,0,0,0,114,179,0,0, - 0,114,227,0,0,0,114,253,0,0,0,114,255,0,0,0, - 114,3,1,0,0,114,1,1,0,0,114,7,1,0,0,90, - 13,95,95,99,108,97,115,115,99,101,108,108,95,95,114,3, - 0,0,0,114,3,0,0,0,114,249,0,0,0,114,6,0, - 0,0,114,239,0,0,0,161,3,0,0,115,30,0,0,0, - 8,2,4,3,8,6,8,4,8,3,2,1,14,11,2,1, - 10,4,8,7,2,1,10,5,8,4,8,6,8,6,114,239, - 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,64,0,0,0,115,46,0,0, - 0,101,0,90,1,100,0,90,2,100,1,90,3,100,2,100, - 3,132,0,90,4,100,4,100,5,132,0,90,5,100,6,100, - 7,156,1,100,8,100,9,132,2,90,6,100,10,83,0,41, - 11,218,16,83,111,117,114,99,101,70,105,108,101,76,111,97, - 100,101,114,122,62,67,111,110,99,114,101,116,101,32,105,109, - 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, - 83,111,117,114,99,101,76,111,97,100,101,114,32,117,115,105, - 110,103,32,116,104,101,32,102,105,108,101,32,115,121,115,116, - 101,109,46,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,67,0,0,0,115,22,0,0, - 0,116,0,124,1,131,1,125,2,124,2,106,1,124,2,106, - 2,100,1,156,2,83,0,41,2,122,33,82,101,116,117,114, - 110,32,116,104,101,32,109,101,116,97,100,97,116,97,32,102, - 111,114,32,116,104,101,32,112,97,116,104,46,41,2,114,169, - 0,0,0,114,234,0,0,0,41,3,114,49,0,0,0,218, - 8,115,116,95,109,116,105,109,101,90,7,115,116,95,115,105, - 122,101,41,3,114,119,0,0,0,114,44,0,0,0,114,238, + 0,3,0,0,0,67,0,0,0,115,38,0,0,0,124,0, + 160,0,124,1,161,1,115,14,116,1,130,1,116,2,116,3, + 124,0,106,4,131,1,100,1,25,0,124,1,131,2,125,2, + 124,2,83,0,169,2,78,114,73,0,0,0,41,5,218,11, + 105,115,95,114,101,115,111,117,114,99,101,218,17,70,105,108, + 101,78,111,116,70,111,117,110,100,69,114,114,111,114,114,38, + 0,0,0,114,47,0,0,0,114,44,0,0,0,114,255,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,13,114,101,115,111,117,114,99,101,95,112,97,116,104, + 217,3,0,0,115,8,0,0,0,0,1,10,1,4,1,20, + 1,122,24,70,105,108,101,76,111,97,100,101,114,46,114,101, + 115,111,117,114,99,101,95,112,97,116,104,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, + 67,0,0,0,115,40,0,0,0,116,0,124,1,107,6,114, + 12,100,1,83,0,116,1,116,2,124,0,106,3,131,1,100, + 2,25,0,124,1,131,2,125,2,116,4,124,2,131,1,83, + 0,41,3,78,70,114,73,0,0,0,41,5,114,35,0,0, + 0,114,38,0,0,0,114,47,0,0,0,114,44,0,0,0, + 114,54,0,0,0,169,3,114,119,0,0,0,114,117,0,0, + 0,114,44,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,2,1,0,0,223,3,0,0,115,8, + 0,0,0,0,1,8,1,4,1,20,1,122,22,70,105,108, + 101,76,111,97,100,101,114,46,105,115,95,114,101,115,111,117, + 114,99,101,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,5,0,0,0,67,0,0,0,115,24,0,0, + 0,116,0,116,1,160,2,116,3,124,0,106,4,131,1,100, + 1,25,0,161,1,131,1,83,0,114,1,1,0,0,41,5, + 218,4,105,116,101,114,114,2,0,0,0,218,7,108,105,115, + 116,100,105,114,114,47,0,0,0,114,44,0,0,0,114,246, 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,224,0,0,0,233,3,0,0,115,4,0,0,0, - 0,2,8,1,122,27,83,111,117,114,99,101,70,105,108,101, - 76,111,97,100,101,114,46,112,97,116,104,95,115,116,97,116, - 115,99,4,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,5,0,0,0,67,0,0,0,115,24,0,0,0,116, - 0,124,1,131,1,125,4,124,0,106,1,124,2,124,3,124, - 4,100,1,141,3,83,0,41,2,78,169,1,218,5,95,109, - 111,100,101,41,2,114,115,0,0,0,114,225,0,0,0,41, - 5,114,119,0,0,0,114,108,0,0,0,114,107,0,0,0, - 114,26,0,0,0,114,52,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,226,0,0,0,238,3, - 0,0,115,4,0,0,0,0,2,8,1,122,32,83,111,117, - 114,99,101,70,105,108,101,76,111,97,100,101,114,46,95,99, - 97,99,104,101,95,98,121,116,101,99,111,100,101,114,60,0, - 0,0,114,10,1,0,0,99,3,0,0,0,0,0,0,0, - 1,0,0,0,9,0,0,0,11,0,0,0,67,0,0,0, - 115,0,1,0,0,116,0,124,1,131,1,92,2,125,4,125, - 5,103,0,125,6,124,4,114,52,116,1,124,4,131,1,115, - 52,116,0,124,4,131,1,92,2,125,4,125,7,124,6,160, - 2,124,7,161,1,1,0,113,16,116,3,124,6,131,1,68, - 0,93,112,125,7,116,4,124,4,124,7,131,2,125,4,122, - 14,116,5,160,6,124,4,161,1,1,0,87,0,110,82,4, - 0,116,7,107,10,114,112,1,0,1,0,1,0,89,0,113, - 60,89,0,110,60,4,0,116,8,107,10,114,170,1,0,125, - 8,1,0,122,30,116,9,160,10,100,1,124,4,124,8,161, - 3,1,0,87,0,89,0,162,10,1,0,100,2,83,0,87, - 0,53,0,100,2,125,8,126,8,88,0,89,0,110,2,88, - 0,113,60,122,28,116,11,124,1,124,2,124,3,131,3,1, - 0,116,9,160,10,100,3,124,1,161,2,1,0,87,0,110, - 48,4,0,116,8,107,10,114,250,1,0,125,8,1,0,122, - 18,116,9,160,10,100,1,124,1,124,8,161,3,1,0,87, - 0,53,0,100,2,125,8,126,8,88,0,89,0,110,2,88, - 0,100,2,83,0,41,4,122,27,87,114,105,116,101,32,98, - 121,116,101,115,32,100,97,116,97,32,116,111,32,97,32,102, - 105,108,101,46,122,27,99,111,117,108,100,32,110,111,116,32, - 99,114,101,97,116,101,32,123,33,114,125,58,32,123,33,114, - 125,78,122,12,99,114,101,97,116,101,100,32,123,33,114,125, - 41,12,114,47,0,0,0,114,56,0,0,0,114,186,0,0, - 0,114,42,0,0,0,114,38,0,0,0,114,2,0,0,0, - 90,5,109,107,100,105,114,218,15,70,105,108,101,69,120,105, - 115,116,115,69,114,114,111,114,114,50,0,0,0,114,134,0, - 0,0,114,149,0,0,0,114,69,0,0,0,41,9,114,119, - 0,0,0,114,44,0,0,0,114,26,0,0,0,114,11,1, - 0,0,218,6,112,97,114,101,110,116,114,97,0,0,0,114, - 37,0,0,0,114,33,0,0,0,114,228,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,225,0, - 0,0,243,3,0,0,115,48,0,0,0,0,2,12,1,4, - 2,12,1,12,1,12,2,12,1,10,1,2,1,14,1,14, - 2,8,1,16,3,6,1,2,0,2,255,4,2,32,1,2, - 1,12,1,16,1,16,2,8,1,2,255,122,25,83,111,117, - 114,99,101,70,105,108,101,76,111,97,100,101,114,46,115,101, - 116,95,100,97,116,97,78,41,7,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,127,0,0,0,114,224,0, - 0,0,114,226,0,0,0,114,225,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,8,1,0,0,229,3,0,0,115,8,0,0,0,8,2, - 4,2,8,5,8,5,114,8,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 64,0,0,0,115,32,0,0,0,101,0,90,1,100,0,90, - 2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100, - 5,132,0,90,5,100,6,83,0,41,7,218,20,83,111,117, - 114,99,101,108,101,115,115,70,105,108,101,76,111,97,100,101, - 114,122,45,76,111,97,100,101,114,32,119,104,105,99,104,32, - 104,97,110,100,108,101,115,32,115,111,117,114,99,101,108,101, - 115,115,32,102,105,108,101,32,105,109,112,111,114,116,115,46, - 99,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,5,0,0,0,67,0,0,0,115,68,0,0,0,124,0, - 160,0,124,1,161,1,125,2,124,0,160,1,124,2,161,1, - 125,3,124,1,124,2,100,1,156,2,125,4,116,2,124,3, - 124,1,124,4,131,3,1,0,116,3,116,4,124,3,131,1, - 100,2,100,0,133,2,25,0,124,1,124,2,100,3,141,3, - 83,0,41,4,78,114,159,0,0,0,114,145,0,0,0,41, - 2,114,117,0,0,0,114,107,0,0,0,41,5,114,179,0, - 0,0,114,227,0,0,0,114,152,0,0,0,114,165,0,0, - 0,114,235,0,0,0,41,5,114,119,0,0,0,114,139,0, - 0,0,114,44,0,0,0,114,26,0,0,0,114,151,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,213,0,0,0,22,4,0,0,115,22,0,0,0,0,1, - 10,1,10,4,2,1,2,254,6,4,12,1,2,1,14,1, - 2,1,2,253,122,29,83,111,117,114,99,101,108,101,115,115, - 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,99, - 111,100,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, - 0,100,1,83,0,41,2,122,39,82,101,116,117,114,110,32, - 78,111,110,101,32,97,115,32,116,104,101,114,101,32,105,115, - 32,110,111,32,115,111,117,114,99,101,32,99,111,100,101,46, - 78,114,3,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,229,0,0,0,38, - 4,0,0,115,2,0,0,0,0,2,122,31,83,111,117,114, - 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, - 46,103,101,116,95,115,111,117,114,99,101,78,41,6,114,125, + 0,0,218,8,99,111,110,116,101,110,116,115,229,3,0,0, + 115,2,0,0,0,0,1,122,19,70,105,108,101,76,111,97, + 100,101,114,46,99,111,110,116,101,110,116,115,41,17,114,125, 0,0,0,114,124,0,0,0,114,126,0,0,0,114,127,0, - 0,0,114,213,0,0,0,114,229,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,14,1,0,0,18,4,0,0,115,6,0,0,0,8,2, - 4,2,8,16,114,14,1,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0, - 0,0,115,92,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, - 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, - 0,90,7,100,10,100,11,132,0,90,8,100,12,100,13,132, - 0,90,9,100,14,100,15,132,0,90,10,100,16,100,17,132, - 0,90,11,101,12,100,18,100,19,132,0,131,1,90,13,100, - 20,83,0,41,21,218,19,69,120,116,101,110,115,105,111,110, - 70,105,108,101,76,111,97,100,101,114,122,93,76,111,97,100, - 101,114,32,102,111,114,32,101,120,116,101,110,115,105,111,110, - 32,109,111,100,117,108,101,115,46,10,10,32,32,32,32,84, - 104,101,32,99,111,110,115,116,114,117,99,116,111,114,32,105, - 115,32,100,101,115,105,103,110,101,100,32,116,111,32,119,111, - 114,107,32,119,105,116,104,32,70,105,108,101,70,105,110,100, - 101,114,46,10,10,32,32,32,32,99,3,0,0,0,0,0, - 0,0,0,0,0,0,3,0,0,0,2,0,0,0,67,0, - 0,0,115,16,0,0,0,124,1,124,0,95,0,124,2,124, - 0,95,1,100,0,83,0,114,110,0,0,0,114,159,0,0, - 0,114,4,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,209,0,0,0,55,4,0,0,115,4, - 0,0,0,0,1,6,1,122,28,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,95,95,105, - 110,105,116,95,95,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,24, - 0,0,0,124,0,106,0,124,1,106,0,107,2,111,22,124, - 0,106,1,124,1,106,1,107,2,83,0,114,110,0,0,0, - 114,240,0,0,0,114,242,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,243,0,0,0,59,4, - 0,0,115,6,0,0,0,0,1,12,1,10,255,122,26,69, - 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, - 101,114,46,95,95,101,113,95,95,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,20,0,0,0,116,0,124,0,106,1,131,1,116, - 0,124,0,106,2,131,1,65,0,83,0,114,110,0,0,0, - 114,244,0,0,0,114,246,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,247,0,0,0,63,4, - 0,0,115,2,0,0,0,0,1,122,28,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,95, - 95,104,97,115,104,95,95,99,2,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,5,0,0,0,67,0,0,0, - 115,36,0,0,0,116,0,160,1,116,2,106,3,124,1,161, - 2,125,2,116,0,160,4,100,1,124,1,106,5,124,0,106, - 6,161,3,1,0,124,2,83,0,41,2,122,38,67,114,101, - 97,116,101,32,97,110,32,117,110,105,116,105,97,108,105,122, - 101,100,32,101,120,116,101,110,115,105,111,110,32,109,111,100, - 117,108,101,122,38,101,120,116,101,110,115,105,111,110,32,109, - 111,100,117,108,101,32,123,33,114,125,32,108,111,97,100,101, - 100,32,102,114,111,109,32,123,33,114,125,41,7,114,134,0, - 0,0,114,214,0,0,0,114,163,0,0,0,90,14,99,114, - 101,97,116,101,95,100,121,110,97,109,105,99,114,149,0,0, - 0,114,117,0,0,0,114,44,0,0,0,41,3,114,119,0, - 0,0,114,187,0,0,0,114,216,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,212,0,0,0, - 66,4,0,0,115,18,0,0,0,0,2,4,1,4,0,2, - 255,4,2,6,1,4,0,4,255,4,2,122,33,69,120,116, - 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, - 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,5, - 0,0,0,67,0,0,0,115,36,0,0,0,116,0,160,1, - 116,2,106,3,124,1,161,2,1,0,116,0,160,4,100,1, - 124,0,106,5,124,0,106,6,161,3,1,0,100,2,83,0, - 41,3,122,30,73,110,105,116,105,97,108,105,122,101,32,97, - 110,32,101,120,116,101,110,115,105,111,110,32,109,111,100,117, - 108,101,122,40,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,32,123,33,114,125,32,101,120,101,99,117,116, - 101,100,32,102,114,111,109,32,123,33,114,125,78,41,7,114, - 134,0,0,0,114,214,0,0,0,114,163,0,0,0,90,12, - 101,120,101,99,95,100,121,110,97,109,105,99,114,149,0,0, - 0,114,117,0,0,0,114,44,0,0,0,114,252,0,0,0, + 0,0,114,209,0,0,0,114,243,0,0,0,114,247,0,0, + 0,114,136,0,0,0,114,220,0,0,0,114,179,0,0,0, + 114,227,0,0,0,114,254,0,0,0,114,0,1,0,0,114, + 4,1,0,0,114,2,1,0,0,114,8,1,0,0,90,13, + 95,95,99,108,97,115,115,99,101,108,108,95,95,114,3,0, + 0,0,114,3,0,0,0,114,249,0,0,0,114,6,0,0, + 0,114,239,0,0,0,161,3,0,0,115,30,0,0,0,8, + 2,4,3,8,6,8,4,8,3,2,1,14,11,2,1,10, + 4,8,11,2,1,10,5,8,4,8,6,8,6,114,239,0, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,64,0,0,0,115,46,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, + 132,0,90,4,100,4,100,5,132,0,90,5,100,6,100,7, + 156,1,100,8,100,9,132,2,90,6,100,10,83,0,41,11, + 218,16,83,111,117,114,99,101,70,105,108,101,76,111,97,100, + 101,114,122,62,67,111,110,99,114,101,116,101,32,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,83, + 111,117,114,99,101,76,111,97,100,101,114,32,117,115,105,110, + 103,32,116,104,101,32,102,105,108,101,32,115,121,115,116,101, + 109,46,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,3,0,0,0,67,0,0,0,115,22,0,0,0, + 116,0,124,1,131,1,125,2,124,2,106,1,124,2,106,2, + 100,1,156,2,83,0,41,2,122,33,82,101,116,117,114,110, + 32,116,104,101,32,109,101,116,97,100,97,116,97,32,102,111, + 114,32,116,104,101,32,112,97,116,104,46,41,2,114,169,0, + 0,0,114,234,0,0,0,41,3,114,49,0,0,0,218,8, + 115,116,95,109,116,105,109,101,90,7,115,116,95,115,105,122, + 101,41,3,114,119,0,0,0,114,44,0,0,0,114,238,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,224,0,0,0,237,3,0,0,115,4,0,0,0,0, + 2,8,1,122,27,83,111,117,114,99,101,70,105,108,101,76, + 111,97,100,101,114,46,112,97,116,104,95,115,116,97,116,115, + 99,4,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,5,0,0,0,67,0,0,0,115,24,0,0,0,116,0, + 124,1,131,1,125,4,124,0,106,1,124,2,124,3,124,4, + 100,1,141,3,83,0,41,2,78,169,1,218,5,95,109,111, + 100,101,41,2,114,115,0,0,0,114,225,0,0,0,41,5, + 114,119,0,0,0,114,108,0,0,0,114,107,0,0,0,114, + 26,0,0,0,114,52,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,226,0,0,0,242,3,0, + 0,115,4,0,0,0,0,2,8,1,122,32,83,111,117,114, + 99,101,70,105,108,101,76,111,97,100,101,114,46,95,99,97, + 99,104,101,95,98,121,116,101,99,111,100,101,114,60,0,0, + 0,114,11,1,0,0,99,3,0,0,0,0,0,0,0,1, + 0,0,0,9,0,0,0,11,0,0,0,67,0,0,0,115, + 0,1,0,0,116,0,124,1,131,1,92,2,125,4,125,5, + 103,0,125,6,124,4,114,52,116,1,124,4,131,1,115,52, + 116,0,124,4,131,1,92,2,125,4,125,7,124,6,160,2, + 124,7,161,1,1,0,113,16,116,3,124,6,131,1,68,0, + 93,112,125,7,116,4,124,4,124,7,131,2,125,4,122,14, + 116,5,160,6,124,4,161,1,1,0,87,0,110,82,4,0, + 116,7,107,10,114,112,1,0,1,0,1,0,89,0,113,60, + 89,0,110,60,4,0,116,8,107,10,114,170,1,0,125,8, + 1,0,122,30,116,9,160,10,100,1,124,4,124,8,161,3, + 1,0,87,0,89,0,162,10,1,0,100,2,83,0,87,0, + 53,0,100,2,125,8,126,8,88,0,89,0,110,2,88,0, + 113,60,122,28,116,11,124,1,124,2,124,3,131,3,1,0, + 116,9,160,10,100,3,124,1,161,2,1,0,87,0,110,48, + 4,0,116,8,107,10,114,250,1,0,125,8,1,0,122,18, + 116,9,160,10,100,1,124,1,124,8,161,3,1,0,87,0, + 53,0,100,2,125,8,126,8,88,0,89,0,110,2,88,0, + 100,2,83,0,41,4,122,27,87,114,105,116,101,32,98,121, + 116,101,115,32,100,97,116,97,32,116,111,32,97,32,102,105, + 108,101,46,122,27,99,111,117,108,100,32,110,111,116,32,99, + 114,101,97,116,101,32,123,33,114,125,58,32,123,33,114,125, + 78,122,12,99,114,101,97,116,101,100,32,123,33,114,125,41, + 12,114,47,0,0,0,114,56,0,0,0,114,186,0,0,0, + 114,42,0,0,0,114,38,0,0,0,114,2,0,0,0,90, + 5,109,107,100,105,114,218,15,70,105,108,101,69,120,105,115, + 116,115,69,114,114,111,114,114,50,0,0,0,114,134,0,0, + 0,114,149,0,0,0,114,69,0,0,0,41,9,114,119,0, + 0,0,114,44,0,0,0,114,26,0,0,0,114,12,1,0, + 0,218,6,112,97,114,101,110,116,114,97,0,0,0,114,37, + 0,0,0,114,33,0,0,0,114,228,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,225,0,0, + 0,247,3,0,0,115,48,0,0,0,0,2,12,1,4,2, + 12,1,12,1,12,2,12,1,10,1,2,1,14,1,14,2, + 8,1,16,3,6,1,2,0,2,255,4,2,32,1,2,1, + 12,1,16,1,16,2,8,1,2,255,122,25,83,111,117,114, + 99,101,70,105,108,101,76,111,97,100,101,114,46,115,101,116, + 95,100,97,116,97,78,41,7,114,125,0,0,0,114,124,0, + 0,0,114,126,0,0,0,114,127,0,0,0,114,224,0,0, + 0,114,226,0,0,0,114,225,0,0,0,114,3,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 217,0,0,0,74,4,0,0,115,10,0,0,0,0,2,14, - 1,6,1,4,0,4,255,122,31,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,101,120,101, - 99,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,3,0,0, - 0,115,36,0,0,0,116,0,124,0,106,1,131,1,100,1, - 25,0,137,0,116,2,135,0,102,1,100,2,100,3,132,8, - 116,3,68,0,131,1,131,1,83,0,41,4,122,49,82,101, - 116,117,114,110,32,84,114,117,101,32,105,102,32,116,104,101, - 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, - 101,32,105,115,32,97,32,112,97,99,107,97,103,101,46,114, - 39,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,4,0,0,0,51,0,0,0,115,26,0, - 0,0,124,0,93,18,125,1,136,0,100,0,124,1,23,0, - 107,2,86,0,1,0,113,2,100,1,83,0,41,2,114,209, - 0,0,0,78,114,3,0,0,0,169,2,114,32,0,0,0, - 218,6,115,117,102,102,105,120,169,1,90,9,102,105,108,101, - 95,110,97,109,101,114,3,0,0,0,114,6,0,0,0,218, - 9,60,103,101,110,101,120,112,114,62,83,4,0,0,115,4, - 0,0,0,4,1,2,255,122,49,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,105,115,95, - 112,97,99,107,97,103,101,46,60,108,111,99,97,108,115,62, - 46,60,103,101,110,101,120,112,114,62,41,4,114,47,0,0, - 0,114,44,0,0,0,218,3,97,110,121,218,18,69,88,84, - 69,78,83,73,79,78,95,83,85,70,70,73,88,69,83,114, - 219,0,0,0,114,3,0,0,0,114,18,1,0,0,114,6, - 0,0,0,114,182,0,0,0,80,4,0,0,115,8,0,0, - 0,0,2,14,1,12,1,2,255,122,30,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,105, - 115,95,112,97,99,107,97,103,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, - 0,0,115,4,0,0,0,100,1,83,0,41,2,122,63,82, - 101,116,117,114,110,32,78,111,110,101,32,97,115,32,97,110, + 9,1,0,0,233,3,0,0,115,8,0,0,0,8,2,4, + 2,8,5,8,5,114,9,1,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, + 0,0,0,115,32,0,0,0,101,0,90,1,100,0,90,2, + 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, + 132,0,90,5,100,6,83,0,41,7,218,20,83,111,117,114, + 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, + 122,45,76,111,97,100,101,114,32,119,104,105,99,104,32,104, + 97,110,100,108,101,115,32,115,111,117,114,99,101,108,101,115, + 115,32,102,105,108,101,32,105,109,112,111,114,116,115,46,99, + 2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, + 5,0,0,0,67,0,0,0,115,68,0,0,0,124,0,160, + 0,124,1,161,1,125,2,124,0,160,1,124,2,161,1,125, + 3,124,1,124,2,100,1,156,2,125,4,116,2,124,3,124, + 1,124,4,131,3,1,0,116,3,116,4,124,3,131,1,100, + 2,100,0,133,2,25,0,124,1,124,2,100,3,141,3,83, + 0,41,4,78,114,159,0,0,0,114,145,0,0,0,41,2, + 114,117,0,0,0,114,107,0,0,0,41,5,114,179,0,0, + 0,114,227,0,0,0,114,152,0,0,0,114,165,0,0,0, + 114,235,0,0,0,41,5,114,119,0,0,0,114,139,0,0, + 0,114,44,0,0,0,114,26,0,0,0,114,151,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 213,0,0,0,26,4,0,0,115,22,0,0,0,0,1,10, + 1,10,4,2,1,2,254,6,4,12,1,2,1,14,1,2, + 1,2,253,122,29,83,111,117,114,99,101,108,101,115,115,70, + 105,108,101,76,111,97,100,101,114,46,103,101,116,95,99,111, + 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, + 100,1,83,0,41,2,122,39,82,101,116,117,114,110,32,78, + 111,110,101,32,97,115,32,116,104,101,114,101,32,105,115,32, + 110,111,32,115,111,117,114,99,101,32,99,111,100,101,46,78, + 114,3,0,0,0,114,219,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,229,0,0,0,42,4, + 0,0,115,2,0,0,0,0,2,122,31,83,111,117,114,99, + 101,108,101,115,115,70,105,108,101,76,111,97,100,101,114,46, + 103,101,116,95,115,111,117,114,99,101,78,41,6,114,125,0, + 0,0,114,124,0,0,0,114,126,0,0,0,114,127,0,0, + 0,114,213,0,0,0,114,229,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 15,1,0,0,22,4,0,0,115,6,0,0,0,8,2,4, + 2,8,16,114,15,1,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, + 0,115,92,0,0,0,101,0,90,1,100,0,90,2,100,1, + 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, + 90,5,100,6,100,7,132,0,90,6,100,8,100,9,132,0, + 90,7,100,10,100,11,132,0,90,8,100,12,100,13,132,0, + 90,9,100,14,100,15,132,0,90,10,100,16,100,17,132,0, + 90,11,101,12,100,18,100,19,132,0,131,1,90,13,100,20, + 83,0,41,21,114,252,0,0,0,122,93,76,111,97,100,101, + 114,32,102,111,114,32,101,120,116,101,110,115,105,111,110,32, + 109,111,100,117,108,101,115,46,10,10,32,32,32,32,84,104, + 101,32,99,111,110,115,116,114,117,99,116,111,114,32,105,115, + 32,100,101,115,105,103,110,101,100,32,116,111,32,119,111,114, + 107,32,119,105,116,104,32,70,105,108,101,70,105,110,100,101, + 114,46,10,10,32,32,32,32,99,3,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,0, + 0,115,16,0,0,0,124,1,124,0,95,0,124,2,124,0, + 95,1,100,0,83,0,114,110,0,0,0,114,159,0,0,0, + 114,5,1,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,209,0,0,0,59,4,0,0,115,4,0, + 0,0,0,1,6,1,122,28,69,120,116,101,110,115,105,111, + 110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110, + 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,2,0,0,0,67,0,0,0,115,24,0, + 0,0,124,0,106,0,124,1,106,0,107,2,111,22,124,0, + 106,1,124,1,106,1,107,2,83,0,114,110,0,0,0,114, + 240,0,0,0,114,242,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,243,0,0,0,63,4,0, + 0,115,6,0,0,0,0,1,12,1,10,255,122,26,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, + 0,115,20,0,0,0,116,0,124,0,106,1,131,1,116,0, + 124,0,106,2,131,1,65,0,83,0,114,110,0,0,0,114, + 244,0,0,0,114,246,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,247,0,0,0,67,4,0, + 0,115,2,0,0,0,0,1,122,28,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,95,95, + 104,97,115,104,95,95,99,2,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,5,0,0,0,67,0,0,0,115, + 36,0,0,0,116,0,160,1,116,2,106,3,124,1,161,2, + 125,2,116,0,160,4,100,1,124,1,106,5,124,0,106,6, + 161,3,1,0,124,2,83,0,41,2,122,38,67,114,101,97, + 116,101,32,97,110,32,117,110,105,116,105,97,108,105,122,101, + 100,32,101,120,116,101,110,115,105,111,110,32,109,111,100,117, + 108,101,122,38,101,120,116,101,110,115,105,111,110,32,109,111, + 100,117,108,101,32,123,33,114,125,32,108,111,97,100,101,100, + 32,102,114,111,109,32,123,33,114,125,41,7,114,134,0,0, + 0,114,214,0,0,0,114,163,0,0,0,90,14,99,114,101, + 97,116,101,95,100,121,110,97,109,105,99,114,149,0,0,0, + 114,117,0,0,0,114,44,0,0,0,41,3,114,119,0,0, + 0,114,187,0,0,0,114,216,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,212,0,0,0,70, + 4,0,0,115,18,0,0,0,0,2,4,1,4,0,2,255, + 4,2,6,1,4,0,4,255,4,2,122,33,69,120,116,101, + 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, + 99,114,101,97,116,101,95,109,111,100,117,108,101,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,5,0, + 0,0,67,0,0,0,115,36,0,0,0,116,0,160,1,116, + 2,106,3,124,1,161,2,1,0,116,0,160,4,100,1,124, + 0,106,5,124,0,106,6,161,3,1,0,100,2,83,0,41, + 3,122,30,73,110,105,116,105,97,108,105,122,101,32,97,110, 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, - 101,32,99,97,110,110,111,116,32,99,114,101,97,116,101,32, - 97,32,99,111,100,101,32,111,98,106,101,99,116,46,78,114, - 3,0,0,0,114,219,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,213,0,0,0,86,4,0, - 0,115,2,0,0,0,0,2,122,28,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,103,101, - 116,95,99,111,100,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,83,0,41,2,122,53,82,101,116,117, - 114,110,32,78,111,110,101,32,97,115,32,101,120,116,101,110, - 115,105,111,110,32,109,111,100,117,108,101,115,32,104,97,118, - 101,32,110,111,32,115,111,117,114,99,101,32,99,111,100,101, - 46,78,114,3,0,0,0,114,219,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,229,0,0,0, - 90,4,0,0,115,2,0,0,0,0,2,122,30,69,120,116, - 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, - 46,103,101,116,95,115,111,117,114,99,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,6,0,0,0,124,0,106,0,83,0,114, - 250,0,0,0,114,48,0,0,0,114,219,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,179,0, - 0,0,94,4,0,0,115,2,0,0,0,0,3,122,32,69, - 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, - 101,114,46,103,101,116,95,102,105,108,101,110,97,109,101,78, - 41,14,114,125,0,0,0,114,124,0,0,0,114,126,0,0, - 0,114,127,0,0,0,114,209,0,0,0,114,243,0,0,0, - 114,247,0,0,0,114,212,0,0,0,114,217,0,0,0,114, - 182,0,0,0,114,213,0,0,0,114,229,0,0,0,114,136, - 0,0,0,114,179,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,15,1,0, - 0,47,4,0,0,115,22,0,0,0,8,2,4,6,8,4, - 8,4,8,3,8,8,8,6,8,6,8,4,8,4,2,1, - 114,15,1,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,104, - 0,0,0,101,0,90,1,100,0,90,2,100,1,90,3,100, - 2,100,3,132,0,90,4,100,4,100,5,132,0,90,5,100, - 6,100,7,132,0,90,6,100,8,100,9,132,0,90,7,100, - 10,100,11,132,0,90,8,100,12,100,13,132,0,90,9,100, - 14,100,15,132,0,90,10,100,16,100,17,132,0,90,11,100, - 18,100,19,132,0,90,12,100,20,100,21,132,0,90,13,100, - 22,100,23,132,0,90,14,100,24,83,0,41,25,218,14,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,97,38,1, - 0,0,82,101,112,114,101,115,101,110,116,115,32,97,32,110, - 97,109,101,115,112,97,99,101,32,112,97,99,107,97,103,101, - 39,115,32,112,97,116,104,46,32,32,73,116,32,117,115,101, - 115,32,116,104,101,32,109,111,100,117,108,101,32,110,97,109, - 101,10,32,32,32,32,116,111,32,102,105,110,100,32,105,116, - 115,32,112,97,114,101,110,116,32,109,111,100,117,108,101,44, - 32,97,110,100,32,102,114,111,109,32,116,104,101,114,101,32, - 105,116,32,108,111,111,107,115,32,117,112,32,116,104,101,32, - 112,97,114,101,110,116,39,115,10,32,32,32,32,95,95,112, - 97,116,104,95,95,46,32,32,87,104,101,110,32,116,104,105, - 115,32,99,104,97,110,103,101,115,44,32,116,104,101,32,109, - 111,100,117,108,101,39,115,32,111,119,110,32,112,97,116,104, - 32,105,115,32,114,101,99,111,109,112,117,116,101,100,44,10, - 32,32,32,32,117,115,105,110,103,32,112,97,116,104,95,102, - 105,110,100,101,114,46,32,32,70,111,114,32,116,111,112,45, - 108,101,118,101,108,32,109,111,100,117,108,101,115,44,32,116, - 104,101,32,112,97,114,101,110,116,32,109,111,100,117,108,101, - 39,115,32,112,97,116,104,10,32,32,32,32,105,115,32,115, - 121,115,46,112,97,116,104,46,99,4,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,3,0,0,0,67,0,0, - 0,115,36,0,0,0,124,1,124,0,95,0,124,2,124,0, - 95,1,116,2,124,0,160,3,161,0,131,1,124,0,95,4, - 124,3,124,0,95,5,100,0,83,0,114,110,0,0,0,41, - 6,218,5,95,110,97,109,101,218,5,95,112,97,116,104,114, - 112,0,0,0,218,16,95,103,101,116,95,112,97,114,101,110, - 116,95,112,97,116,104,218,17,95,108,97,115,116,95,112,97, - 114,101,110,116,95,112,97,116,104,218,12,95,112,97,116,104, - 95,102,105,110,100,101,114,169,4,114,119,0,0,0,114,117, - 0,0,0,114,44,0,0,0,90,11,112,97,116,104,95,102, - 105,110,100,101,114,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,209,0,0,0,107,4,0,0,115,8,0, - 0,0,0,1,6,1,6,1,14,1,122,23,95,78,97,109, - 101,115,112,97,99,101,80,97,116,104,46,95,95,105,110,105, - 116,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,3,0,0,0,67,0,0,0,115,38,0,0, - 0,124,0,106,0,160,1,100,1,161,1,92,3,125,1,125, - 2,125,3,124,2,100,2,107,2,114,30,100,3,83,0,124, - 1,100,4,102,2,83,0,41,5,122,62,82,101,116,117,114, - 110,115,32,97,32,116,117,112,108,101,32,111,102,32,40,112, - 97,114,101,110,116,45,109,111,100,117,108,101,45,110,97,109, - 101,44,32,112,97,114,101,110,116,45,112,97,116,104,45,97, - 116,116,114,45,110,97,109,101,41,114,71,0,0,0,114,40, - 0,0,0,41,2,114,8,0,0,0,114,44,0,0,0,90, - 8,95,95,112,97,116,104,95,95,41,2,114,23,1,0,0, - 114,41,0,0,0,41,4,114,119,0,0,0,114,13,1,0, - 0,218,3,100,111,116,90,2,109,101,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,23,95,102,105,110,100, - 95,112,97,114,101,110,116,95,112,97,116,104,95,110,97,109, - 101,115,113,4,0,0,115,8,0,0,0,0,2,18,1,8, - 2,4,3,122,38,95,78,97,109,101,115,112,97,99,101,80, - 97,116,104,46,95,102,105,110,100,95,112,97,114,101,110,116, - 95,112,97,116,104,95,110,97,109,101,115,99,1,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,28,0,0,0,124,0,160,0,161,0,92, - 2,125,1,125,2,116,1,116,2,106,3,124,1,25,0,124, - 2,131,2,83,0,114,110,0,0,0,41,4,114,30,1,0, - 0,114,130,0,0,0,114,8,0,0,0,218,7,109,111,100, - 117,108,101,115,41,3,114,119,0,0,0,90,18,112,97,114, - 101,110,116,95,109,111,100,117,108,101,95,110,97,109,101,90, - 14,112,97,116,104,95,97,116,116,114,95,110,97,109,101,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,25, - 1,0,0,123,4,0,0,115,4,0,0,0,0,1,12,1, - 122,31,95,78,97,109,101,115,112,97,99,101,80,97,116,104, - 46,95,103,101,116,95,112,97,114,101,110,116,95,112,97,116, - 104,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,4,0,0,0,67,0,0,0,115,80,0,0,0,116, - 0,124,0,160,1,161,0,131,1,125,1,124,1,124,0,106, - 2,107,3,114,74,124,0,160,3,124,0,106,4,124,1,161, - 2,125,2,124,2,100,0,107,9,114,68,124,2,106,5,100, - 0,107,8,114,68,124,2,106,6,114,68,124,2,106,6,124, - 0,95,7,124,1,124,0,95,2,124,0,106,7,83,0,114, - 110,0,0,0,41,8,114,112,0,0,0,114,25,1,0,0, - 114,26,1,0,0,114,27,1,0,0,114,23,1,0,0,114, - 140,0,0,0,114,178,0,0,0,114,24,1,0,0,41,3, - 114,119,0,0,0,90,11,112,97,114,101,110,116,95,112,97, - 116,104,114,187,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,12,95,114,101,99,97,108,99,117, - 108,97,116,101,127,4,0,0,115,16,0,0,0,0,2,12, - 1,10,1,14,3,18,1,6,1,8,1,6,1,122,27,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,114, - 101,99,97,108,99,117,108,97,116,101,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, - 0,0,0,115,12,0,0,0,116,0,124,0,160,1,161,0, - 131,1,83,0,114,110,0,0,0,41,2,114,5,1,0,0, - 114,32,1,0,0,114,246,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,8,95,95,105,116,101, - 114,95,95,140,4,0,0,115,2,0,0,0,0,1,122,23, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,105,116,101,114,95,95,99,2,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, - 115,12,0,0,0,124,0,160,0,161,0,124,1,25,0,83, - 0,114,110,0,0,0,169,1,114,32,1,0,0,41,2,114, - 119,0,0,0,218,5,105,110,100,101,120,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,11,95,95,103,101, - 116,105,116,101,109,95,95,143,4,0,0,115,2,0,0,0, - 0,1,122,26,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,95,103,101,116,105,116,101,109,95,95,99,3, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3, - 0,0,0,67,0,0,0,115,14,0,0,0,124,2,124,0, - 106,0,124,1,60,0,100,0,83,0,114,110,0,0,0,41, - 1,114,24,1,0,0,41,3,114,119,0,0,0,114,35,1, - 0,0,114,44,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,11,95,95,115,101,116,105,116,101, - 109,95,95,146,4,0,0,115,2,0,0,0,0,1,122,26, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,115,101,116,105,116,101,109,95,95,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, - 0,0,0,115,12,0,0,0,116,0,124,0,160,1,161,0, - 131,1,83,0,114,110,0,0,0,41,2,114,22,0,0,0, - 114,32,1,0,0,114,246,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,7,95,95,108,101,110, - 95,95,149,4,0,0,115,2,0,0,0,0,1,122,22,95, + 101,122,40,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,32,123,33,114,125,32,101,120,101,99,117,116,101, + 100,32,102,114,111,109,32,123,33,114,125,78,41,7,114,134, + 0,0,0,114,214,0,0,0,114,163,0,0,0,90,12,101, + 120,101,99,95,100,121,110,97,109,105,99,114,149,0,0,0, + 114,117,0,0,0,114,44,0,0,0,114,253,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,217, + 0,0,0,78,4,0,0,115,10,0,0,0,0,2,14,1, + 6,1,4,0,4,255,122,31,69,120,116,101,110,115,105,111, + 110,70,105,108,101,76,111,97,100,101,114,46,101,120,101,99, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0, + 115,36,0,0,0,116,0,124,0,106,1,131,1,100,1,25, + 0,137,0,116,2,135,0,102,1,100,2,100,3,132,8,116, + 3,68,0,131,1,131,1,83,0,41,4,122,49,82,101,116, + 117,114,110,32,84,114,117,101,32,105,102,32,116,104,101,32, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 32,105,115,32,97,32,112,97,99,107,97,103,101,46,114,39, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,4,0,0,0,51,0,0,0,115,26,0,0, + 0,124,0,93,18,125,1,136,0,100,0,124,1,23,0,107, + 2,86,0,1,0,113,2,100,1,83,0,41,2,114,209,0, + 0,0,78,114,3,0,0,0,169,2,114,32,0,0,0,218, + 6,115,117,102,102,105,120,169,1,90,9,102,105,108,101,95, + 110,97,109,101,114,3,0,0,0,114,6,0,0,0,218,9, + 60,103,101,110,101,120,112,114,62,87,4,0,0,115,4,0, + 0,0,4,1,2,255,122,49,69,120,116,101,110,115,105,111, + 110,70,105,108,101,76,111,97,100,101,114,46,105,115,95,112, + 97,99,107,97,103,101,46,60,108,111,99,97,108,115,62,46, + 60,103,101,110,101,120,112,114,62,41,4,114,47,0,0,0, + 114,44,0,0,0,218,3,97,110,121,218,18,69,88,84,69, + 78,83,73,79,78,95,83,85,70,70,73,88,69,83,114,219, + 0,0,0,114,3,0,0,0,114,18,1,0,0,114,6,0, + 0,0,114,182,0,0,0,84,4,0,0,115,8,0,0,0, + 0,2,14,1,12,1,2,255,122,30,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,105,115, + 95,112,97,99,107,97,103,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,115,4,0,0,0,100,1,83,0,41,2,122,63,82,101, + 116,117,114,110,32,78,111,110,101,32,97,115,32,97,110,32, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 32,99,97,110,110,111,116,32,99,114,101,97,116,101,32,97, + 32,99,111,100,101,32,111,98,106,101,99,116,46,78,114,3, + 0,0,0,114,219,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,213,0,0,0,90,4,0,0, + 115,2,0,0,0,0,2,122,28,69,120,116,101,110,115,105, + 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 95,99,111,100,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, + 0,0,0,100,1,83,0,41,2,122,53,82,101,116,117,114, + 110,32,78,111,110,101,32,97,115,32,101,120,116,101,110,115, + 105,111,110,32,109,111,100,117,108,101,115,32,104,97,118,101, + 32,110,111,32,115,111,117,114,99,101,32,99,111,100,101,46, + 78,114,3,0,0,0,114,219,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,229,0,0,0,94, + 4,0,0,115,2,0,0,0,0,2,122,30,69,120,116,101, + 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, + 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,6,0,0,0,124,0,106,0,83,0,114,250, + 0,0,0,114,48,0,0,0,114,219,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,179,0,0, + 0,98,4,0,0,115,2,0,0,0,0,3,122,32,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,103,101,116,95,102,105,108,101,110,97,109,101,78,41, + 14,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, + 114,127,0,0,0,114,209,0,0,0,114,243,0,0,0,114, + 247,0,0,0,114,212,0,0,0,114,217,0,0,0,114,182, + 0,0,0,114,213,0,0,0,114,229,0,0,0,114,136,0, + 0,0,114,179,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,252,0,0,0, + 51,4,0,0,115,22,0,0,0,8,2,4,6,8,4,8, + 4,8,3,8,8,8,6,8,6,8,4,8,4,2,1,114, + 252,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,64,0,0,0,115,104,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, + 100,7,132,0,90,6,100,8,100,9,132,0,90,7,100,10, + 100,11,132,0,90,8,100,12,100,13,132,0,90,9,100,14, + 100,15,132,0,90,10,100,16,100,17,132,0,90,11,100,18, + 100,19,132,0,90,12,100,20,100,21,132,0,90,13,100,22, + 100,23,132,0,90,14,100,24,83,0,41,25,218,14,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,97,38,1,0, + 0,82,101,112,114,101,115,101,110,116,115,32,97,32,110,97, + 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,39, + 115,32,112,97,116,104,46,32,32,73,116,32,117,115,101,115, + 32,116,104,101,32,109,111,100,117,108,101,32,110,97,109,101, + 10,32,32,32,32,116,111,32,102,105,110,100,32,105,116,115, + 32,112,97,114,101,110,116,32,109,111,100,117,108,101,44,32, + 97,110,100,32,102,114,111,109,32,116,104,101,114,101,32,105, + 116,32,108,111,111,107,115,32,117,112,32,116,104,101,32,112, + 97,114,101,110,116,39,115,10,32,32,32,32,95,95,112,97, + 116,104,95,95,46,32,32,87,104,101,110,32,116,104,105,115, + 32,99,104,97,110,103,101,115,44,32,116,104,101,32,109,111, + 100,117,108,101,39,115,32,111,119,110,32,112,97,116,104,32, + 105,115,32,114,101,99,111,109,112,117,116,101,100,44,10,32, + 32,32,32,117,115,105,110,103,32,112,97,116,104,95,102,105, + 110,100,101,114,46,32,32,70,111,114,32,116,111,112,45,108, + 101,118,101,108,32,109,111,100,117,108,101,115,44,32,116,104, + 101,32,112,97,114,101,110,116,32,109,111,100,117,108,101,39, + 115,32,112,97,116,104,10,32,32,32,32,105,115,32,115,121, + 115,46,112,97,116,104,46,99,4,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,3,0,0,0,67,0,0,0, + 115,36,0,0,0,124,1,124,0,95,0,124,2,124,0,95, + 1,116,2,124,0,160,3,161,0,131,1,124,0,95,4,124, + 3,124,0,95,5,100,0,83,0,114,110,0,0,0,41,6, + 218,5,95,110,97,109,101,218,5,95,112,97,116,104,114,112, + 0,0,0,218,16,95,103,101,116,95,112,97,114,101,110,116, + 95,112,97,116,104,218,17,95,108,97,115,116,95,112,97,114, + 101,110,116,95,112,97,116,104,218,12,95,112,97,116,104,95, + 102,105,110,100,101,114,169,4,114,119,0,0,0,114,117,0, + 0,0,114,44,0,0,0,90,11,112,97,116,104,95,102,105, + 110,100,101,114,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,209,0,0,0,111,4,0,0,115,8,0,0, + 0,0,1,6,1,6,1,14,1,122,23,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,95,105,110,105,116, + 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 124,0,106,0,160,1,100,1,161,1,92,3,125,1,125,2, + 125,3,124,2,100,2,107,2,114,30,100,3,83,0,124,1, + 100,4,102,2,83,0,41,5,122,62,82,101,116,117,114,110, + 115,32,97,32,116,117,112,108,101,32,111,102,32,40,112,97, + 114,101,110,116,45,109,111,100,117,108,101,45,110,97,109,101, + 44,32,112,97,114,101,110,116,45,112,97,116,104,45,97,116, + 116,114,45,110,97,109,101,41,114,71,0,0,0,114,40,0, + 0,0,41,2,114,8,0,0,0,114,44,0,0,0,90,8, + 95,95,112,97,116,104,95,95,41,2,114,23,1,0,0,114, + 41,0,0,0,41,4,114,119,0,0,0,114,14,1,0,0, + 218,3,100,111,116,90,2,109,101,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,23,95,102,105,110,100,95, + 112,97,114,101,110,116,95,112,97,116,104,95,110,97,109,101, + 115,117,4,0,0,115,8,0,0,0,0,2,18,1,8,2, + 4,3,122,38,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,46,95,102,105,110,100,95,112,97,114,101,110,116,95, + 112,97,116,104,95,110,97,109,101,115,99,1,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, + 0,0,0,115,28,0,0,0,124,0,160,0,161,0,92,2, + 125,1,125,2,116,1,116,2,106,3,124,1,25,0,124,2, + 131,2,83,0,114,110,0,0,0,41,4,114,30,1,0,0, + 114,130,0,0,0,114,8,0,0,0,218,7,109,111,100,117, + 108,101,115,41,3,114,119,0,0,0,90,18,112,97,114,101, + 110,116,95,109,111,100,117,108,101,95,110,97,109,101,90,14, + 112,97,116,104,95,97,116,116,114,95,110,97,109,101,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,25,1, + 0,0,127,4,0,0,115,4,0,0,0,0,1,12,1,122, + 31,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104, + 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,4,0,0,0,67,0,0,0,115,80,0,0,0,116,0, + 124,0,160,1,161,0,131,1,125,1,124,1,124,0,106,2, + 107,3,114,74,124,0,160,3,124,0,106,4,124,1,161,2, + 125,2,124,2,100,0,107,9,114,68,124,2,106,5,100,0, + 107,8,114,68,124,2,106,6,114,68,124,2,106,6,124,0, + 95,7,124,1,124,0,95,2,124,0,106,7,83,0,114,110, + 0,0,0,41,8,114,112,0,0,0,114,25,1,0,0,114, + 26,1,0,0,114,27,1,0,0,114,23,1,0,0,114,140, + 0,0,0,114,178,0,0,0,114,24,1,0,0,41,3,114, + 119,0,0,0,90,11,112,97,114,101,110,116,95,112,97,116, + 104,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,12,95,114,101,99,97,108,99,117,108, + 97,116,101,131,4,0,0,115,16,0,0,0,0,2,12,1, + 10,1,14,3,18,1,6,1,8,1,6,1,122,27,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,114,101, + 99,97,108,99,117,108,97,116,101,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, + 1,83,0,114,110,0,0,0,41,2,114,6,1,0,0,114, + 32,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,8,95,95,105,116,101,114, + 95,95,144,4,0,0,115,2,0,0,0,0,1,122,23,95, 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 108,101,110,95,95,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,12, - 0,0,0,100,1,160,0,124,0,106,1,161,1,83,0,41, - 2,78,122,20,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,40,123,33,114,125,41,41,2,114,62,0,0,0,114, - 24,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,8,95,95,114,101,112,114, - 95,95,152,4,0,0,115,2,0,0,0,0,1,122,23,95, + 105,116,101,114,95,95,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 12,0,0,0,124,0,160,0,161,0,124,1,25,0,83,0, + 114,110,0,0,0,169,1,114,32,1,0,0,41,2,114,119, + 0,0,0,218,5,105,110,100,101,120,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,11,95,95,103,101,116, + 105,116,101,109,95,95,147,4,0,0,115,2,0,0,0,0, + 1,122,26,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,46,95,95,103,101,116,105,116,101,109,95,95,99,3,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,14,0,0,0,124,2,124,0,106, + 0,124,1,60,0,100,0,83,0,114,110,0,0,0,41,1, + 114,24,1,0,0,41,3,114,119,0,0,0,114,35,1,0, + 0,114,44,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,11,95,95,115,101,116,105,116,101,109, + 95,95,150,4,0,0,115,2,0,0,0,0,1,122,26,95, 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 114,101,112,114,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, - 12,0,0,0,124,1,124,0,160,0,161,0,107,6,83,0, - 114,110,0,0,0,114,34,1,0,0,169,2,114,119,0,0, - 0,218,4,105,116,101,109,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,12,95,95,99,111,110,116,97,105, - 110,115,95,95,155,4,0,0,115,2,0,0,0,0,1,122, - 27,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 95,95,99,111,110,116,97,105,110,115,95,95,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, - 0,67,0,0,0,115,16,0,0,0,124,0,106,0,160,1, - 124,1,161,1,1,0,100,0,83,0,114,110,0,0,0,41, - 2,114,24,1,0,0,114,186,0,0,0,114,40,1,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 186,0,0,0,158,4,0,0,115,2,0,0,0,0,1,122, - 21,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 97,112,112,101,110,100,78,41,15,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,127,0,0,0,114,209,0, - 0,0,114,30,1,0,0,114,25,1,0,0,114,32,1,0, - 0,114,33,1,0,0,114,36,1,0,0,114,37,1,0,0, - 114,38,1,0,0,114,39,1,0,0,114,42,1,0,0,114, - 186,0,0,0,114,3,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,22,1,0,0,100,4,0, - 0,115,24,0,0,0,8,1,4,6,8,6,8,10,8,4, - 8,13,8,3,8,3,8,3,8,3,8,3,8,3,114,22, - 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,64,0,0,0,115,80,0,0, - 0,101,0,90,1,100,0,90,2,100,1,100,2,132,0,90, - 3,101,4,100,3,100,4,132,0,131,1,90,5,100,5,100, - 6,132,0,90,6,100,7,100,8,132,0,90,7,100,9,100, - 10,132,0,90,8,100,11,100,12,132,0,90,9,100,13,100, - 14,132,0,90,10,100,15,100,16,132,0,90,11,100,17,83, - 0,41,18,218,16,95,78,97,109,101,115,112,97,99,101,76, - 111,97,100,101,114,99,4,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,4,0,0,0,67,0,0,0,115,18, - 0,0,0,116,0,124,1,124,2,124,3,131,3,124,0,95, - 1,100,0,83,0,114,110,0,0,0,41,2,114,22,1,0, - 0,114,24,1,0,0,114,28,1,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,209,0,0,0,164, - 4,0,0,115,2,0,0,0,0,1,122,25,95,78,97,109, - 101,115,112,97,99,101,76,111,97,100,101,114,46,95,95,105, - 110,105,116,95,95,99,2,0,0,0,0,0,0,0,0,0, + 115,101,116,105,116,101,109,95,95,99,1,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, + 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, + 1,83,0,114,110,0,0,0,41,2,114,22,0,0,0,114, + 32,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,7,95,95,108,101,110,95, + 95,153,4,0,0,115,2,0,0,0,0,1,122,22,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,108, + 101,110,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,67,0,0,0,115,12,0, + 0,0,100,1,160,0,124,0,106,1,161,1,83,0,41,2, + 78,122,20,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,40,123,33,114,125,41,41,2,114,62,0,0,0,114,24, + 1,0,0,114,246,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,8,95,95,114,101,112,114,95, + 95,156,4,0,0,115,2,0,0,0,0,1,122,23,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,114, + 101,112,114,95,95,99,2,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,12, - 0,0,0,100,1,160,0,124,1,106,1,161,1,83,0,41, - 2,122,115,82,101,116,117,114,110,32,114,101,112,114,32,102, - 111,114,32,116,104,101,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,101,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,84,104,101,32,105,109,112,111,114,116,32,109,97, - 99,104,105,110,101,114,121,32,100,111,101,115,32,116,104,101, - 32,106,111,98,32,105,116,115,101,108,102,46,10,10,32,32, - 32,32,32,32,32,32,122,25,60,109,111,100,117,108,101,32, - 123,33,114,125,32,40,110,97,109,101,115,112,97,99,101,41, - 62,41,2,114,62,0,0,0,114,125,0,0,0,41,2,114, - 193,0,0,0,114,216,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,11,109,111,100,117,108,101, - 95,114,101,112,114,167,4,0,0,115,2,0,0,0,0,7, - 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,109,111,100,117,108,101,95,114,101,112,114,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, - 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0, - 41,2,78,84,114,3,0,0,0,114,219,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,182,0, - 0,0,176,4,0,0,115,2,0,0,0,0,1,122,27,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,83,0,41,2,78,114, - 40,0,0,0,114,3,0,0,0,114,219,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,229,0, - 0,0,179,4,0,0,115,2,0,0,0,0,1,122,27,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,67, - 0,0,0,115,16,0,0,0,116,0,100,1,100,2,100,3, - 100,4,100,5,141,4,83,0,41,6,78,114,40,0,0,0, - 122,8,60,115,116,114,105,110,103,62,114,215,0,0,0,84, - 41,1,114,231,0,0,0,41,1,114,232,0,0,0,114,219, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,213,0,0,0,182,4,0,0,115,2,0,0,0, - 0,1,122,25,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,103,101,116,95,99,111,100,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,114, - 210,0,0,0,114,3,0,0,0,114,211,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,212,0, - 0,0,185,4,0,0,115,2,0,0,0,0,1,122,30,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 99,114,101,97,116,101,95,109,111,100,117,108,101,99,2,0, + 0,0,0,124,1,124,0,160,0,161,0,107,6,83,0,114, + 110,0,0,0,114,34,1,0,0,169,2,114,119,0,0,0, + 218,4,105,116,101,109,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,12,95,95,99,111,110,116,97,105,110, + 115,95,95,159,4,0,0,115,2,0,0,0,0,1,122,27, + 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, + 95,99,111,110,116,97,105,110,115,95,95,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 67,0,0,0,115,16,0,0,0,124,0,106,0,160,1,124, + 1,161,1,1,0,100,0,83,0,114,110,0,0,0,41,2, + 114,24,1,0,0,114,186,0,0,0,114,40,1,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,186, + 0,0,0,162,4,0,0,115,2,0,0,0,0,1,122,21, + 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,97, + 112,112,101,110,100,78,41,15,114,125,0,0,0,114,124,0, + 0,0,114,126,0,0,0,114,127,0,0,0,114,209,0,0, + 0,114,30,1,0,0,114,25,1,0,0,114,32,1,0,0, + 114,33,1,0,0,114,36,1,0,0,114,37,1,0,0,114, + 38,1,0,0,114,39,1,0,0,114,42,1,0,0,114,186, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,22,1,0,0,104,4,0,0, + 115,24,0,0,0,8,1,4,6,8,6,8,10,8,4,8, + 13,8,3,8,3,8,3,8,3,8,3,8,3,114,22,1, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,64,0,0,0,115,80,0,0,0, + 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, + 101,4,100,3,100,4,132,0,131,1,90,5,100,5,100,6, + 132,0,90,6,100,7,100,8,132,0,90,7,100,9,100,10, + 132,0,90,8,100,11,100,12,132,0,90,9,100,13,100,14, + 132,0,90,10,100,15,100,16,132,0,90,11,100,17,83,0, + 41,18,218,16,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,99,4,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,4,0,0,0,67,0,0,0,115,18,0, + 0,0,116,0,124,1,124,2,124,3,131,3,124,0,95,1, + 100,0,83,0,114,110,0,0,0,41,2,114,22,1,0,0, + 114,24,1,0,0,114,28,1,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,209,0,0,0,168,4, + 0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101, + 115,112,97,99,101,76,111,97,100,101,114,46,95,95,105,110, + 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,3,0,0,0,67,0,0,0,115,12,0, + 0,0,100,1,160,0,124,1,106,1,161,1,83,0,41,2, + 122,115,82,101,116,117,114,110,32,114,101,112,114,32,102,111, + 114,32,116,104,101,32,109,111,100,117,108,101,46,10,10,32, + 32,32,32,32,32,32,32,84,104,101,32,109,101,116,104,111, + 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, + 32,32,84,104,101,32,105,109,112,111,114,116,32,109,97,99, + 104,105,110,101,114,121,32,100,111,101,115,32,116,104,101,32, + 106,111,98,32,105,116,115,101,108,102,46,10,10,32,32,32, + 32,32,32,32,32,122,25,60,109,111,100,117,108,101,32,123, + 33,114,125,32,40,110,97,109,101,115,112,97,99,101,41,62, + 41,2,114,62,0,0,0,114,125,0,0,0,41,2,114,193, + 0,0,0,114,216,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,11,109,111,100,117,108,101,95, + 114,101,112,114,171,4,0,0,115,2,0,0,0,0,7,122, + 28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,109,111,100,117,108,101,95,114,101,112,114,99,2,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,0,83,0,114, - 110,0,0,0,114,3,0,0,0,114,252,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,217,0, - 0,0,188,4,0,0,115,2,0,0,0,0,1,122,28,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 101,120,101,99,95,109,111,100,117,108,101,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, - 67,0,0,0,115,26,0,0,0,116,0,160,1,100,1,124, - 0,106,2,161,2,1,0,116,0,160,3,124,0,124,1,161, - 2,83,0,41,2,122,98,76,111,97,100,32,97,32,110,97, - 109,101,115,112,97,99,101,32,109,111,100,117,108,101,46,10, - 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, - 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, - 101,100,46,32,32,85,115,101,32,101,120,101,99,95,109,111, - 100,117,108,101,40,41,32,105,110,115,116,101,97,100,46,10, - 10,32,32,32,32,32,32,32,32,122,38,110,97,109,101,115, - 112,97,99,101,32,109,111,100,117,108,101,32,108,111,97,100, - 101,100,32,119,105,116,104,32,112,97,116,104,32,123,33,114, - 125,41,4,114,134,0,0,0,114,149,0,0,0,114,24,1, - 0,0,114,218,0,0,0,114,219,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,220,0,0,0, - 191,4,0,0,115,8,0,0,0,0,7,6,1,4,255,4, - 2,122,28,95,78,97,109,101,115,112,97,99,101,76,111,97, - 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,78, - 41,12,114,125,0,0,0,114,124,0,0,0,114,126,0,0, - 0,114,209,0,0,0,114,207,0,0,0,114,44,1,0,0, - 114,182,0,0,0,114,229,0,0,0,114,213,0,0,0,114, - 212,0,0,0,114,217,0,0,0,114,220,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,43,1,0,0,163,4,0,0,115,18,0,0,0, - 8,1,8,3,2,1,10,8,8,3,8,3,8,3,8,3, - 8,3,114,43,1,0,0,99,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,4,0,0,0,64,0,0,0, - 115,106,0,0,0,101,0,90,1,100,0,90,2,100,1,90, - 3,101,4,100,2,100,3,132,0,131,1,90,5,101,4,100, - 4,100,5,132,0,131,1,90,6,101,4,100,6,100,7,132, - 0,131,1,90,7,101,4,100,8,100,9,132,0,131,1,90, - 8,101,4,100,17,100,11,100,12,132,1,131,1,90,9,101, - 4,100,18,100,13,100,14,132,1,131,1,90,10,101,4,100, - 19,100,15,100,16,132,1,131,1,90,11,100,10,83,0,41, - 20,218,10,80,97,116,104,70,105,110,100,101,114,122,62,77, - 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32, - 102,111,114,32,115,121,115,46,112,97,116,104,32,97,110,100, - 32,112,97,99,107,97,103,101,32,95,95,112,97,116,104,95, - 95,32,97,116,116,114,105,98,117,116,101,115,46,99,1,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, - 0,0,67,0,0,0,115,64,0,0,0,116,0,116,1,106, - 2,160,3,161,0,131,1,68,0,93,44,92,2,125,1,125, - 2,124,2,100,1,107,8,114,40,116,1,106,2,124,1,61, - 0,113,14,116,4,124,2,100,2,131,2,114,14,124,2,160, - 5,161,0,1,0,113,14,100,1,83,0,41,3,122,125,67, - 97,108,108,32,116,104,101,32,105,110,118,97,108,105,100,97, - 116,101,95,99,97,99,104,101,115,40,41,32,109,101,116,104, - 111,100,32,111,110,32,97,108,108,32,112,97,116,104,32,101, - 110,116,114,121,32,102,105,110,100,101,114,115,10,32,32,32, - 32,32,32,32,32,115,116,111,114,101,100,32,105,110,32,115, - 121,115,46,112,97,116,104,95,105,109,112,111,114,116,101,114, - 95,99,97,99,104,101,115,32,40,119,104,101,114,101,32,105, - 109,112,108,101,109,101,110,116,101,100,41,46,78,218,17,105, - 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115, - 41,6,218,4,108,105,115,116,114,8,0,0,0,218,19,112, - 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, - 104,101,218,5,105,116,101,109,115,114,128,0,0,0,114,46, - 1,0,0,41,3,114,193,0,0,0,114,117,0,0,0,218, - 6,102,105,110,100,101,114,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,46,1,0,0,209,4,0,0,115, - 10,0,0,0,0,4,22,1,8,1,10,1,10,1,122,28, - 80,97,116,104,70,105,110,100,101,114,46,105,110,118,97,108, - 105,100,97,116,101,95,99,97,99,104,101,115,99,2,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,9,0,0, - 0,67,0,0,0,115,84,0,0,0,116,0,106,1,100,1, - 107,9,114,28,116,0,106,1,115,28,116,2,160,3,100,2, - 116,4,161,2,1,0,116,0,106,1,68,0,93,44,125,2, - 122,14,124,2,124,1,131,1,87,0,2,0,1,0,83,0, - 4,0,116,5,107,10,114,76,1,0,1,0,1,0,89,0, - 113,34,89,0,113,34,88,0,113,34,100,1,83,0,41,3, - 122,46,83,101,97,114,99,104,32,115,121,115,46,112,97,116, - 104,95,104,111,111,107,115,32,102,111,114,32,97,32,102,105, - 110,100,101,114,32,102,111,114,32,39,112,97,116,104,39,46, - 78,122,23,115,121,115,46,112,97,116,104,95,104,111,111,107, - 115,32,105,115,32,101,109,112,116,121,41,6,114,8,0,0, - 0,218,10,112,97,116,104,95,104,111,111,107,115,114,75,0, - 0,0,114,76,0,0,0,114,138,0,0,0,114,118,0,0, - 0,41,3,114,193,0,0,0,114,44,0,0,0,90,4,104, - 111,111,107,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,11,95,112,97,116,104,95,104,111,111,107,115,219, - 4,0,0,115,16,0,0,0,0,3,16,1,12,1,10,1, - 2,1,14,1,14,1,12,2,122,22,80,97,116,104,70,105, - 110,100,101,114,46,95,112,97,116,104,95,104,111,111,107,115, - 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,8,0,0,0,67,0,0,0,115,104,0,0,0,124,1, - 100,1,107,2,114,44,122,12,116,0,160,1,161,0,125,1, - 87,0,110,22,4,0,116,2,107,10,114,42,1,0,1,0, - 1,0,89,0,100,2,83,0,88,0,122,14,116,3,106,4, - 124,1,25,0,125,2,87,0,110,40,4,0,116,5,107,10, - 114,98,1,0,1,0,1,0,124,0,160,6,124,1,161,1, - 125,2,124,2,116,3,106,4,124,1,60,0,89,0,110,2, - 88,0,124,2,83,0,41,3,122,210,71,101,116,32,116,104, - 101,32,102,105,110,100,101,114,32,102,111,114,32,116,104,101, - 32,112,97,116,104,32,101,110,116,114,121,32,102,114,111,109, - 32,115,121,115,46,112,97,116,104,95,105,109,112,111,114,116, - 101,114,95,99,97,99,104,101,46,10,10,32,32,32,32,32, - 32,32,32,73,102,32,116,104,101,32,112,97,116,104,32,101, - 110,116,114,121,32,105,115,32,110,111,116,32,105,110,32,116, - 104,101,32,99,97,99,104,101,44,32,102,105,110,100,32,116, - 104,101,32,97,112,112,114,111,112,114,105,97,116,101,32,102, - 105,110,100,101,114,10,32,32,32,32,32,32,32,32,97,110, - 100,32,99,97,99,104,101,32,105,116,46,32,73,102,32,110, - 111,32,102,105,110,100,101,114,32,105,115,32,97,118,97,105, - 108,97,98,108,101,44,32,115,116,111,114,101,32,78,111,110, - 101,46,10,10,32,32,32,32,32,32,32,32,114,40,0,0, - 0,78,41,7,114,2,0,0,0,114,55,0,0,0,114,2, - 1,0,0,114,8,0,0,0,114,48,1,0,0,218,8,75, - 101,121,69,114,114,111,114,114,52,1,0,0,41,3,114,193, - 0,0,0,114,44,0,0,0,114,50,1,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,20,95,112, - 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, - 104,101,232,4,0,0,115,22,0,0,0,0,8,8,1,2, - 1,12,1,14,3,8,1,2,1,14,1,14,1,10,1,16, - 1,122,31,80,97,116,104,70,105,110,100,101,114,46,95,112, - 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, - 104,101,99,3,0,0,0,0,0,0,0,0,0,0,0,6, - 0,0,0,4,0,0,0,67,0,0,0,115,82,0,0,0, - 116,0,124,2,100,1,131,2,114,26,124,2,160,1,124,1, - 161,1,92,2,125,3,125,4,110,14,124,2,160,2,124,1, - 161,1,125,3,103,0,125,4,124,3,100,0,107,9,114,60, - 116,3,160,4,124,1,124,3,161,2,83,0,116,3,160,5, - 124,1,100,0,161,2,125,5,124,4,124,5,95,6,124,5, - 83,0,41,2,78,114,137,0,0,0,41,7,114,128,0,0, - 0,114,137,0,0,0,114,206,0,0,0,114,134,0,0,0, - 114,201,0,0,0,114,183,0,0,0,114,178,0,0,0,41, - 6,114,193,0,0,0,114,139,0,0,0,114,50,1,0,0, - 114,140,0,0,0,114,141,0,0,0,114,187,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,16, - 95,108,101,103,97,99,121,95,103,101,116,95,115,112,101,99, - 254,4,0,0,115,18,0,0,0,0,4,10,1,16,2,10, - 1,4,1,8,1,12,1,12,1,6,1,122,27,80,97,116, - 104,70,105,110,100,101,114,46,95,108,101,103,97,99,121,95, - 103,101,116,95,115,112,101,99,78,99,4,0,0,0,0,0, - 0,0,0,0,0,0,9,0,0,0,5,0,0,0,67,0, - 0,0,115,166,0,0,0,103,0,125,4,124,2,68,0,93, - 134,125,5,116,0,124,5,116,1,116,2,102,2,131,2,115, - 28,113,8,124,0,160,3,124,5,161,1,125,6,124,6,100, - 1,107,9,114,8,116,4,124,6,100,2,131,2,114,70,124, - 6,160,5,124,1,124,3,161,2,125,7,110,12,124,0,160, - 6,124,1,124,6,161,2,125,7,124,7,100,1,107,8,114, - 92,113,8,124,7,106,7,100,1,107,9,114,110,124,7,2, - 0,1,0,83,0,124,7,106,8,125,8,124,8,100,1,107, - 8,114,132,116,9,100,3,131,1,130,1,124,4,160,10,124, - 8,161,1,1,0,113,8,116,11,160,12,124,1,100,1,161, - 2,125,7,124,4,124,7,95,8,124,7,83,0,41,4,122, - 63,70,105,110,100,32,116,104,101,32,108,111,97,100,101,114, - 32,111,114,32,110,97,109,101,115,112,97,99,101,95,112,97, - 116,104,32,102,111,114,32,116,104,105,115,32,109,111,100,117, - 108,101,47,112,97,99,107,97,103,101,32,110,97,109,101,46, - 78,114,203,0,0,0,122,19,115,112,101,99,32,109,105,115, - 115,105,110,103,32,108,111,97,100,101,114,41,13,114,161,0, - 0,0,114,85,0,0,0,218,5,98,121,116,101,115,114,54, - 1,0,0,114,128,0,0,0,114,203,0,0,0,114,55,1, - 0,0,114,140,0,0,0,114,178,0,0,0,114,118,0,0, - 0,114,167,0,0,0,114,134,0,0,0,114,183,0,0,0, - 41,9,114,193,0,0,0,114,139,0,0,0,114,44,0,0, - 0,114,202,0,0,0,218,14,110,97,109,101,115,112,97,99, - 101,95,112,97,116,104,90,5,101,110,116,114,121,114,50,1, - 0,0,114,187,0,0,0,114,141,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,9,95,103,101, - 116,95,115,112,101,99,13,5,0,0,115,40,0,0,0,0, - 5,4,1,8,1,14,1,2,1,10,1,8,1,10,1,14, - 2,12,1,8,1,2,1,10,1,8,1,6,1,8,1,8, - 5,12,2,12,1,6,1,122,20,80,97,116,104,70,105,110, - 100,101,114,46,95,103,101,116,95,115,112,101,99,99,4,0, - 0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0, - 0,0,67,0,0,0,115,100,0,0,0,124,2,100,1,107, - 8,114,14,116,0,106,1,125,2,124,0,160,2,124,1,124, - 2,124,3,161,3,125,4,124,4,100,1,107,8,114,40,100, - 1,83,0,124,4,106,3,100,1,107,8,114,92,124,4,106, - 4,125,5,124,5,114,86,100,1,124,4,95,5,116,6,124, - 1,124,5,124,0,106,2,131,3,124,4,95,4,124,4,83, - 0,100,1,83,0,110,4,124,4,83,0,100,1,83,0,41, - 2,122,141,84,114,121,32,116,111,32,102,105,110,100,32,97, - 32,115,112,101,99,32,102,111,114,32,39,102,117,108,108,110, - 97,109,101,39,32,111,110,32,115,121,115,46,112,97,116,104, - 32,111,114,32,39,112,97,116,104,39,46,10,10,32,32,32, - 32,32,32,32,32,84,104,101,32,115,101,97,114,99,104,32, - 105,115,32,98,97,115,101,100,32,111,110,32,115,121,115,46, - 112,97,116,104,95,104,111,111,107,115,32,97,110,100,32,115, - 121,115,46,112,97,116,104,95,105,109,112,111,114,116,101,114, - 95,99,97,99,104,101,46,10,32,32,32,32,32,32,32,32, - 78,41,7,114,8,0,0,0,114,44,0,0,0,114,58,1, - 0,0,114,140,0,0,0,114,178,0,0,0,114,181,0,0, - 0,114,22,1,0,0,41,6,114,193,0,0,0,114,139,0, - 0,0,114,44,0,0,0,114,202,0,0,0,114,187,0,0, - 0,114,57,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,203,0,0,0,45,5,0,0,115,26, - 0,0,0,0,6,8,1,6,1,14,1,8,1,4,1,10, - 1,6,1,4,3,6,1,16,1,4,2,6,2,122,20,80, - 97,116,104,70,105,110,100,101,114,46,102,105,110,100,95,115, - 112,101,99,99,3,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,4,0,0,0,67,0,0,0,115,30,0,0, - 0,124,0,160,0,124,1,124,2,161,2,125,3,124,3,100, - 1,107,8,114,24,100,1,83,0,124,3,106,1,83,0,41, - 2,122,170,102,105,110,100,32,116,104,101,32,109,111,100,117, - 108,101,32,111,110,32,115,121,115,46,112,97,116,104,32,111, - 114,32,39,112,97,116,104,39,32,98,97,115,101,100,32,111, - 110,32,115,121,115,46,112,97,116,104,95,104,111,111,107,115, - 32,97,110,100,10,32,32,32,32,32,32,32,32,115,121,115, - 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, - 97,99,104,101,46,10,10,32,32,32,32,32,32,32,32,84, - 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, - 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,102, - 105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,101, - 97,100,46,10,10,32,32,32,32,32,32,32,32,78,114,204, - 0,0,0,114,205,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,206,0,0,0,69,5,0,0, - 115,8,0,0,0,0,8,12,1,8,1,4,1,122,22,80, - 97,116,104,70,105,110,100,101,114,46,102,105,110,100,95,109, - 111,100,117,108,101,41,1,78,41,2,78,78,41,1,78,41, - 12,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,127,0,0,0,114,207,0,0,0,114,46,1,0,0,114, - 52,1,0,0,114,54,1,0,0,114,55,1,0,0,114,58, - 1,0,0,114,203,0,0,0,114,206,0,0,0,114,3,0, + 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, + 2,78,84,114,3,0,0,0,114,219,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,182,0,0, + 0,180,4,0,0,115,2,0,0,0,0,1,122,27,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,78,114,40, + 0,0,0,114,3,0,0,0,114,219,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,229,0,0, + 0,183,4,0,0,115,2,0,0,0,0,1,122,27,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,103, + 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,6,0,0,0,67,0, + 0,0,115,16,0,0,0,116,0,100,1,100,2,100,3,100, + 4,100,5,141,4,83,0,41,6,78,114,40,0,0,0,122, + 8,60,115,116,114,105,110,103,62,114,215,0,0,0,84,41, + 1,114,231,0,0,0,41,1,114,232,0,0,0,114,219,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,45,1,0,0,205,4,0,0,115,30,0,0,0,8, - 2,4,2,2,1,10,9,2,1,10,12,2,1,10,21,2, - 1,10,14,2,1,12,31,2,1,12,23,2,1,114,45,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,64,0,0,0,115,90,0,0,0, - 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, - 132,0,90,4,100,4,100,5,132,0,90,5,101,6,90,7, - 100,6,100,7,132,0,90,8,100,8,100,9,132,0,90,9, - 100,19,100,11,100,12,132,1,90,10,100,13,100,14,132,0, - 90,11,101,12,100,15,100,16,132,0,131,1,90,13,100,17, - 100,18,132,0,90,14,100,10,83,0,41,20,218,10,70,105, - 108,101,70,105,110,100,101,114,122,172,70,105,108,101,45,98, - 97,115,101,100,32,102,105,110,100,101,114,46,10,10,32,32, - 32,32,73,110,116,101,114,97,99,116,105,111,110,115,32,119, - 105,116,104,32,116,104,101,32,102,105,108,101,32,115,121,115, - 116,101,109,32,97,114,101,32,99,97,99,104,101,100,32,102, - 111,114,32,112,101,114,102,111,114,109,97,110,99,101,44,32, - 98,101,105,110,103,10,32,32,32,32,114,101,102,114,101,115, - 104,101,100,32,119,104,101,110,32,116,104,101,32,100,105,114, - 101,99,116,111,114,121,32,116,104,101,32,102,105,110,100,101, - 114,32,105,115,32,104,97,110,100,108,105,110,103,32,104,97, - 115,32,98,101,101,110,32,109,111,100,105,102,105,101,100,46, - 10,10,32,32,32,32,99,2,0,0,0,0,0,0,0,0, - 0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,115, - 84,0,0,0,103,0,125,3,124,2,68,0,93,32,92,2, - 137,0,125,4,124,3,160,0,135,0,102,1,100,1,100,2, - 132,8,124,4,68,0,131,1,161,1,1,0,113,8,124,3, - 124,0,95,1,124,1,112,54,100,3,124,0,95,2,100,4, - 124,0,95,3,116,4,131,0,124,0,95,5,116,4,131,0, - 124,0,95,6,100,5,83,0,41,6,122,154,73,110,105,116, - 105,97,108,105,122,101,32,119,105,116,104,32,116,104,101,32, - 112,97,116,104,32,116,111,32,115,101,97,114,99,104,32,111, - 110,32,97,110,100,32,97,32,118,97,114,105,97,98,108,101, - 32,110,117,109,98,101,114,32,111,102,10,32,32,32,32,32, - 32,32,32,50,45,116,117,112,108,101,115,32,99,111,110,116, - 97,105,110,105,110,103,32,116,104,101,32,108,111,97,100,101, - 114,32,97,110,100,32,116,104,101,32,102,105,108,101,32,115, - 117,102,102,105,120,101,115,32,116,104,101,32,108,111,97,100, - 101,114,10,32,32,32,32,32,32,32,32,114,101,99,111,103, - 110,105,122,101,115,46,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,51,0,0,0,115, - 22,0,0,0,124,0,93,14,125,1,124,1,136,0,102,2, - 86,0,1,0,113,2,100,0,83,0,114,110,0,0,0,114, - 3,0,0,0,114,16,1,0,0,169,1,114,140,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,19,1,0,0,98, - 5,0,0,115,4,0,0,0,4,0,2,0,122,38,70,105, - 108,101,70,105,110,100,101,114,46,95,95,105,110,105,116,95, - 95,46,60,108,111,99,97,108,115,62,46,60,103,101,110,101, - 120,112,114,62,114,71,0,0,0,114,105,0,0,0,78,41, - 7,114,167,0,0,0,218,8,95,108,111,97,100,101,114,115, - 114,44,0,0,0,218,11,95,112,97,116,104,95,109,116,105, - 109,101,218,3,115,101,116,218,11,95,112,97,116,104,95,99, - 97,99,104,101,218,19,95,114,101,108,97,120,101,100,95,112, - 97,116,104,95,99,97,99,104,101,41,5,114,119,0,0,0, - 114,44,0,0,0,218,14,108,111,97,100,101,114,95,100,101, - 116,97,105,108,115,90,7,108,111,97,100,101,114,115,114,189, - 0,0,0,114,3,0,0,0,114,60,1,0,0,114,6,0, - 0,0,114,209,0,0,0,92,5,0,0,115,16,0,0,0, - 0,4,4,1,12,1,26,1,6,2,10,1,6,1,8,1, - 122,19,70,105,108,101,70,105,110,100,101,114,46,95,95,105, - 110,105,116,95,95,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,2,0,0,0,67,0,0,0,115,10, - 0,0,0,100,1,124,0,95,0,100,2,83,0,41,3,122, - 31,73,110,118,97,108,105,100,97,116,101,32,116,104,101,32, - 100,105,114,101,99,116,111,114,121,32,109,116,105,109,101,46, - 114,105,0,0,0,78,41,1,114,62,1,0,0,114,246,0, + 0,114,213,0,0,0,186,4,0,0,115,2,0,0,0,0, + 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, + 100,101,114,46,103,101,116,95,99,111,100,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,115,4,0,0,0,100,1,83,0,114,210, + 0,0,0,114,3,0,0,0,114,211,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,212,0,0, + 0,189,4,0,0,115,2,0,0,0,0,1,122,30,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,99, + 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,115,4,0,0,0,100,0,83,0,114,110, + 0,0,0,114,3,0,0,0,114,253,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,217,0,0, + 0,192,4,0,0,115,2,0,0,0,0,1,122,28,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, + 0,0,0,115,26,0,0,0,116,0,160,1,100,1,124,0, + 106,2,161,2,1,0,116,0,160,3,124,0,124,1,161,2, + 83,0,41,2,122,98,76,111,97,100,32,97,32,110,97,109, + 101,115,112,97,99,101,32,109,111,100,117,108,101,46,10,10, + 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, + 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, + 100,46,32,32,85,115,101,32,101,120,101,99,95,109,111,100, + 117,108,101,40,41,32,105,110,115,116,101,97,100,46,10,10, + 32,32,32,32,32,32,32,32,122,38,110,97,109,101,115,112, + 97,99,101,32,109,111,100,117,108,101,32,108,111,97,100,101, + 100,32,119,105,116,104,32,112,97,116,104,32,123,33,114,125, + 41,4,114,134,0,0,0,114,149,0,0,0,114,24,1,0, + 0,114,218,0,0,0,114,219,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,220,0,0,0,195, + 4,0,0,115,8,0,0,0,0,7,6,1,4,255,4,2, + 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, + 101,114,46,108,111,97,100,95,109,111,100,117,108,101,78,41, + 12,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, + 114,209,0,0,0,114,207,0,0,0,114,44,1,0,0,114, + 182,0,0,0,114,229,0,0,0,114,213,0,0,0,114,212, + 0,0,0,114,217,0,0,0,114,220,0,0,0,114,3,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,46,1,0,0,106,5,0,0,115,2,0,0,0,0, - 2,122,28,70,105,108,101,70,105,110,100,101,114,46,105,110, - 118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,99, + 0,114,43,1,0,0,167,4,0,0,115,18,0,0,0,8, + 1,8,3,2,1,10,8,8,3,8,3,8,3,8,3,8, + 3,114,43,1,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, + 106,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, + 101,4,100,2,100,3,132,0,131,1,90,5,101,4,100,4, + 100,5,132,0,131,1,90,6,101,4,100,6,100,7,132,0, + 131,1,90,7,101,4,100,8,100,9,132,0,131,1,90,8, + 101,4,100,17,100,11,100,12,132,1,131,1,90,9,101,4, + 100,18,100,13,100,14,132,1,131,1,90,10,101,4,100,19, + 100,15,100,16,132,1,131,1,90,11,100,10,83,0,41,20, + 218,10,80,97,116,104,70,105,110,100,101,114,122,62,77,101, + 116,97,32,112,97,116,104,32,102,105,110,100,101,114,32,102, + 111,114,32,115,121,115,46,112,97,116,104,32,97,110,100,32, + 112,97,99,107,97,103,101,32,95,95,112,97,116,104,95,95, + 32,97,116,116,114,105,98,117,116,101,115,46,99,1,0,0, + 0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, + 0,67,0,0,0,115,64,0,0,0,116,0,116,1,106,2, + 160,3,161,0,131,1,68,0,93,44,92,2,125,1,125,2, + 124,2,100,1,107,8,114,40,116,1,106,2,124,1,61,0, + 113,14,116,4,124,2,100,2,131,2,114,14,124,2,160,5, + 161,0,1,0,113,14,100,1,83,0,41,3,122,125,67,97, + 108,108,32,116,104,101,32,105,110,118,97,108,105,100,97,116, + 101,95,99,97,99,104,101,115,40,41,32,109,101,116,104,111, + 100,32,111,110,32,97,108,108,32,112,97,116,104,32,101,110, + 116,114,121,32,102,105,110,100,101,114,115,10,32,32,32,32, + 32,32,32,32,115,116,111,114,101,100,32,105,110,32,115,121, + 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,115,32,40,119,104,101,114,101,32,105,109, + 112,108,101,109,101,110,116,101,100,41,46,78,218,17,105,110, + 118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,41, + 6,218,4,108,105,115,116,114,8,0,0,0,218,19,112,97, + 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, + 101,218,5,105,116,101,109,115,114,128,0,0,0,114,46,1, + 0,0,41,3,114,193,0,0,0,114,117,0,0,0,218,6, + 102,105,110,100,101,114,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,46,1,0,0,213,4,0,0,115,10, + 0,0,0,0,4,22,1,8,1,10,1,10,1,122,28,80, + 97,116,104,70,105,110,100,101,114,46,105,110,118,97,108,105, + 100,97,116,101,95,99,97,99,104,101,115,99,2,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,9,0,0,0, + 67,0,0,0,115,84,0,0,0,116,0,106,1,100,1,107, + 9,114,28,116,0,106,1,115,28,116,2,160,3,100,2,116, + 4,161,2,1,0,116,0,106,1,68,0,93,44,125,2,122, + 14,124,2,124,1,131,1,87,0,2,0,1,0,83,0,4, + 0,116,5,107,10,114,76,1,0,1,0,1,0,89,0,113, + 34,89,0,113,34,88,0,113,34,100,1,83,0,41,3,122, + 46,83,101,97,114,99,104,32,115,121,115,46,112,97,116,104, + 95,104,111,111,107,115,32,102,111,114,32,97,32,102,105,110, + 100,101,114,32,102,111,114,32,39,112,97,116,104,39,46,78, + 122,23,115,121,115,46,112,97,116,104,95,104,111,111,107,115, + 32,105,115,32,101,109,112,116,121,41,6,114,8,0,0,0, + 218,10,112,97,116,104,95,104,111,111,107,115,114,75,0,0, + 0,114,76,0,0,0,114,138,0,0,0,114,118,0,0,0, + 41,3,114,193,0,0,0,114,44,0,0,0,90,4,104,111, + 111,107,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,11,95,112,97,116,104,95,104,111,111,107,115,223,4, + 0,0,115,16,0,0,0,0,3,16,1,12,1,10,1,2, + 1,14,1,14,1,12,2,122,22,80,97,116,104,70,105,110, + 100,101,114,46,95,112,97,116,104,95,104,111,111,107,115,99, 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 3,0,0,0,67,0,0,0,115,42,0,0,0,124,0,160, - 0,124,1,161,1,125,2,124,2,100,1,107,8,114,26,100, - 1,103,0,102,2,83,0,124,2,106,1,124,2,106,2,112, - 38,103,0,102,2,83,0,41,2,122,197,84,114,121,32,116, - 111,32,102,105,110,100,32,97,32,108,111,97,100,101,114,32, - 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101, - 100,32,109,111,100,117,108,101,44,32,111,114,32,116,104,101, - 32,110,97,109,101,115,112,97,99,101,10,32,32,32,32,32, - 32,32,32,112,97,99,107,97,103,101,32,112,111,114,116,105, - 111,110,115,46,32,82,101,116,117,114,110,115,32,40,108,111, - 97,100,101,114,44,32,108,105,115,116,45,111,102,45,112,111, - 114,116,105,111,110,115,41,46,10,10,32,32,32,32,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, - 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, - 78,41,3,114,203,0,0,0,114,140,0,0,0,114,178,0, - 0,0,41,3,114,119,0,0,0,114,139,0,0,0,114,187, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,137,0,0,0,112,5,0,0,115,8,0,0,0, - 0,7,10,1,8,1,8,1,122,22,70,105,108,101,70,105, - 110,100,101,114,46,102,105,110,100,95,108,111,97,100,101,114, - 99,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0, - 0,6,0,0,0,67,0,0,0,115,26,0,0,0,124,1, - 124,2,124,3,131,2,125,6,116,0,124,2,124,3,124,6, - 124,4,100,1,141,4,83,0,41,2,78,114,177,0,0,0, - 41,1,114,190,0,0,0,41,7,114,119,0,0,0,114,188, - 0,0,0,114,139,0,0,0,114,44,0,0,0,90,4,115, - 109,115,108,114,202,0,0,0,114,140,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,58,1,0, - 0,124,5,0,0,115,8,0,0,0,0,1,10,1,8,1, - 2,255,122,20,70,105,108,101,70,105,110,100,101,114,46,95, - 103,101,116,95,115,112,101,99,78,99,3,0,0,0,0,0, - 0,0,0,0,0,0,14,0,0,0,8,0,0,0,67,0, - 0,0,115,102,1,0,0,100,1,125,3,124,1,160,0,100, - 2,161,1,100,3,25,0,125,4,122,24,116,1,124,0,106, - 2,112,34,116,3,160,4,161,0,131,1,106,5,125,5,87, - 0,110,24,4,0,116,6,107,10,114,66,1,0,1,0,1, - 0,100,4,125,5,89,0,110,2,88,0,124,5,124,0,106, - 7,107,3,114,92,124,0,160,8,161,0,1,0,124,5,124, - 0,95,7,116,9,131,0,114,114,124,0,106,10,125,6,124, - 4,160,11,161,0,125,7,110,10,124,0,106,12,125,6,124, - 4,125,7,124,7,124,6,107,6,114,218,116,13,124,0,106, - 2,124,4,131,2,125,8,124,0,106,14,68,0,93,58,92, - 2,125,9,125,10,100,5,124,9,23,0,125,11,116,13,124, - 8,124,11,131,2,125,12,116,15,124,12,131,1,114,208,124, - 0,160,16,124,10,124,1,124,12,124,8,103,1,124,2,161, - 5,2,0,1,0,83,0,113,150,116,17,124,8,131,1,125, - 3,124,0,106,14,68,0,93,86,92,2,125,9,125,10,116, - 13,124,0,106,2,124,4,124,9,23,0,131,2,125,12,116, - 18,106,19,100,6,124,12,100,3,100,7,141,3,1,0,124, - 7,124,9,23,0,124,6,107,6,144,1,114,54,116,15,124, - 12,131,1,144,1,114,54,124,0,160,16,124,10,124,1,124, - 12,100,8,124,2,161,5,2,0,1,0,83,0,113,224,124, - 3,144,1,114,98,116,18,160,19,100,9,124,8,161,2,1, - 0,116,18,160,20,124,1,100,8,161,2,125,13,124,8,103, - 1,124,13,95,21,124,13,83,0,100,8,83,0,41,10,122, - 111,84,114,121,32,116,111,32,102,105,110,100,32,97,32,115, - 112,101,99,32,102,111,114,32,116,104,101,32,115,112,101,99, - 105,102,105,101,100,32,109,111,100,117,108,101,46,10,10,32, - 32,32,32,32,32,32,32,82,101,116,117,114,110,115,32,116, - 104,101,32,109,97,116,99,104,105,110,103,32,115,112,101,99, - 44,32,111,114,32,78,111,110,101,32,105,102,32,110,111,116, - 32,102,111,117,110,100,46,10,32,32,32,32,32,32,32,32, - 70,114,71,0,0,0,114,28,0,0,0,114,105,0,0,0, - 114,209,0,0,0,122,9,116,114,121,105,110,103,32,123,125, - 41,1,90,9,118,101,114,98,111,115,105,116,121,78,122,25, - 112,111,115,115,105,98,108,101,32,110,97,109,101,115,112,97, - 99,101,32,102,111,114,32,123,125,41,22,114,41,0,0,0, - 114,49,0,0,0,114,44,0,0,0,114,2,0,0,0,114, - 55,0,0,0,114,9,1,0,0,114,50,0,0,0,114,62, - 1,0,0,218,11,95,102,105,108,108,95,99,97,99,104,101, - 114,7,0,0,0,114,65,1,0,0,114,106,0,0,0,114, - 64,1,0,0,114,38,0,0,0,114,61,1,0,0,114,54, - 0,0,0,114,58,1,0,0,114,56,0,0,0,114,134,0, - 0,0,114,149,0,0,0,114,183,0,0,0,114,178,0,0, - 0,41,14,114,119,0,0,0,114,139,0,0,0,114,202,0, - 0,0,90,12,105,115,95,110,97,109,101,115,112,97,99,101, - 90,11,116,97,105,108,95,109,111,100,117,108,101,114,169,0, - 0,0,90,5,99,97,99,104,101,90,12,99,97,99,104,101, - 95,109,111,100,117,108,101,90,9,98,97,115,101,95,112,97, - 116,104,114,17,1,0,0,114,188,0,0,0,90,13,105,110, - 105,116,95,102,105,108,101,110,97,109,101,90,9,102,117,108, - 108,95,112,97,116,104,114,187,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,203,0,0,0,129, - 5,0,0,115,74,0,0,0,0,5,4,1,14,1,2,1, - 24,1,14,1,10,1,10,1,8,1,6,2,6,1,6,1, - 10,2,6,1,4,2,8,1,12,1,14,1,8,1,10,1, - 8,1,26,4,8,2,14,1,16,1,16,1,14,1,10,1, - 10,1,2,0,2,255,10,2,6,1,12,1,12,1,8,1, - 4,1,122,20,70,105,108,101,70,105,110,100,101,114,46,102, - 105,110,100,95,115,112,101,99,99,1,0,0,0,0,0,0, - 0,0,0,0,0,9,0,0,0,10,0,0,0,67,0,0, - 0,115,190,0,0,0,124,0,106,0,125,1,122,22,116,1, - 160,2,124,1,112,22,116,1,160,3,161,0,161,1,125,2, - 87,0,110,30,4,0,116,4,116,5,116,6,102,3,107,10, - 114,58,1,0,1,0,1,0,103,0,125,2,89,0,110,2, - 88,0,116,7,106,8,160,9,100,1,161,1,115,84,116,10, - 124,2,131,1,124,0,95,11,110,74,116,10,131,0,125,3, - 124,2,68,0,93,56,125,4,124,4,160,12,100,2,161,1, - 92,3,125,5,125,6,125,7,124,6,114,136,100,3,160,13, - 124,5,124,7,160,14,161,0,161,2,125,8,110,4,124,5, - 125,8,124,3,160,15,124,8,161,1,1,0,113,94,124,3, - 124,0,95,11,116,7,106,8,160,9,116,16,161,1,114,186, - 100,4,100,5,132,0,124,2,68,0,131,1,124,0,95,17, - 100,6,83,0,41,7,122,68,70,105,108,108,32,116,104,101, - 32,99,97,99,104,101,32,111,102,32,112,111,116,101,110,116, - 105,97,108,32,109,111,100,117,108,101,115,32,97,110,100,32, - 112,97,99,107,97,103,101,115,32,102,111,114,32,116,104,105, - 115,32,100,105,114,101,99,116,111,114,121,46,114,0,0,0, - 0,114,71,0,0,0,114,61,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, - 83,0,0,0,115,20,0,0,0,104,0,124,0,93,12,125, - 1,124,1,160,0,161,0,146,2,113,4,83,0,114,3,0, - 0,0,41,1,114,106,0,0,0,41,2,114,32,0,0,0, - 90,2,102,110,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,9,60,115,101,116,99,111,109,112,62,206,5, - 0,0,115,4,0,0,0,6,0,2,0,122,41,70,105,108, - 101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,97, - 99,104,101,46,60,108,111,99,97,108,115,62,46,60,115,101, - 116,99,111,109,112,62,78,41,18,114,44,0,0,0,114,2, - 0,0,0,114,6,1,0,0,114,55,0,0,0,114,2,1, - 0,0,218,15,80,101,114,109,105,115,115,105,111,110,69,114, - 114,111,114,218,18,78,111,116,65,68,105,114,101,99,116,111, - 114,121,69,114,114,111,114,114,8,0,0,0,114,9,0,0, - 0,114,10,0,0,0,114,63,1,0,0,114,64,1,0,0, - 114,101,0,0,0,114,62,0,0,0,114,106,0,0,0,218, - 3,97,100,100,114,11,0,0,0,114,65,1,0,0,41,9, - 114,119,0,0,0,114,44,0,0,0,114,7,1,0,0,90, - 21,108,111,119,101,114,95,115,117,102,102,105,120,95,99,111, - 110,116,101,110,116,115,114,41,1,0,0,114,117,0,0,0, - 114,29,1,0,0,114,17,1,0,0,90,8,110,101,119,95, - 110,97,109,101,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,67,1,0,0,177,5,0,0,115,34,0,0, - 0,0,2,6,1,2,1,22,1,20,3,10,3,12,1,12, - 7,6,1,8,1,16,1,4,1,18,2,4,1,12,1,6, - 1,12,1,122,22,70,105,108,101,70,105,110,100,101,114,46, - 95,102,105,108,108,95,99,97,99,104,101,99,1,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 7,0,0,0,115,18,0,0,0,135,0,135,1,102,2,100, - 1,100,2,132,8,125,2,124,2,83,0,41,3,97,20,1, - 0,0,65,32,99,108,97,115,115,32,109,101,116,104,111,100, - 32,119,104,105,99,104,32,114,101,116,117,114,110,115,32,97, - 32,99,108,111,115,117,114,101,32,116,111,32,117,115,101,32, - 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, - 10,32,32,32,32,32,32,32,32,119,104,105,99,104,32,119, - 105,108,108,32,114,101,116,117,114,110,32,97,110,32,105,110, - 115,116,97,110,99,101,32,117,115,105,110,103,32,116,104,101, - 32,115,112,101,99,105,102,105,101,100,32,108,111,97,100,101, - 114,115,32,97,110,100,32,116,104,101,32,112,97,116,104,10, - 32,32,32,32,32,32,32,32,99,97,108,108,101,100,32,111, - 110,32,116,104,101,32,99,108,111,115,117,114,101,46,10,10, - 32,32,32,32,32,32,32,32,73,102,32,116,104,101,32,112, - 97,116,104,32,99,97,108,108,101,100,32,111,110,32,116,104, - 101,32,99,108,111,115,117,114,101,32,105,115,32,110,111,116, - 32,97,32,100,105,114,101,99,116,111,114,121,44,32,73,109, - 112,111,114,116,69,114,114,111,114,32,105,115,10,32,32,32, - 32,32,32,32,32,114,97,105,115,101,100,46,10,10,32,32, - 32,32,32,32,32,32,99,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,4,0,0,0,19,0,0,0,115, - 34,0,0,0,116,0,124,0,131,1,115,20,116,1,100,1, - 124,0,100,2,141,2,130,1,136,0,124,0,102,1,136,1, - 158,2,142,0,83,0,41,3,122,45,80,97,116,104,32,104, - 111,111,107,32,102,111,114,32,105,109,112,111,114,116,108,105, - 98,46,109,97,99,104,105,110,101,114,121,46,70,105,108,101, - 70,105,110,100,101,114,46,122,30,111,110,108,121,32,100,105, - 114,101,99,116,111,114,105,101,115,32,97,114,101,32,115,117, - 112,112,111,114,116,101,100,114,48,0,0,0,41,2,114,56, - 0,0,0,114,118,0,0,0,114,48,0,0,0,169,2,114, - 193,0,0,0,114,66,1,0,0,114,3,0,0,0,114,6, - 0,0,0,218,24,112,97,116,104,95,104,111,111,107,95,102, - 111,114,95,70,105,108,101,70,105,110,100,101,114,218,5,0, - 0,115,6,0,0,0,0,2,8,1,12,1,122,54,70,105, - 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, - 111,107,46,60,108,111,99,97,108,115,62,46,112,97,116,104, - 95,104,111,111,107,95,102,111,114,95,70,105,108,101,70,105, - 110,100,101,114,114,3,0,0,0,41,3,114,193,0,0,0, - 114,66,1,0,0,114,73,1,0,0,114,3,0,0,0,114, - 72,1,0,0,114,6,0,0,0,218,9,112,97,116,104,95, - 104,111,111,107,208,5,0,0,115,4,0,0,0,0,10,14, - 6,122,20,70,105,108,101,70,105,110,100,101,114,46,112,97, - 116,104,95,104,111,111,107,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, - 115,12,0,0,0,100,1,160,0,124,0,106,1,161,1,83, - 0,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, - 40,123,33,114,125,41,41,2,114,62,0,0,0,114,44,0, - 0,0,114,246,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,39,1,0,0,226,5,0,0,115, - 2,0,0,0,0,1,122,19,70,105,108,101,70,105,110,100, - 101,114,46,95,95,114,101,112,114,95,95,41,1,78,41,15, + 8,0,0,0,67,0,0,0,115,104,0,0,0,124,1,100, + 1,107,2,114,44,122,12,116,0,160,1,161,0,125,1,87, + 0,110,22,4,0,116,2,107,10,114,42,1,0,1,0,1, + 0,89,0,100,2,83,0,88,0,122,14,116,3,106,4,124, + 1,25,0,125,2,87,0,110,40,4,0,116,5,107,10,114, + 98,1,0,1,0,1,0,124,0,160,6,124,1,161,1,125, + 2,124,2,116,3,106,4,124,1,60,0,89,0,110,2,88, + 0,124,2,83,0,41,3,122,210,71,101,116,32,116,104,101, + 32,102,105,110,100,101,114,32,102,111,114,32,116,104,101,32, + 112,97,116,104,32,101,110,116,114,121,32,102,114,111,109,32, + 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, + 114,95,99,97,99,104,101,46,10,10,32,32,32,32,32,32, + 32,32,73,102,32,116,104,101,32,112,97,116,104,32,101,110, + 116,114,121,32,105,115,32,110,111,116,32,105,110,32,116,104, + 101,32,99,97,99,104,101,44,32,102,105,110,100,32,116,104, + 101,32,97,112,112,114,111,112,114,105,97,116,101,32,102,105, + 110,100,101,114,10,32,32,32,32,32,32,32,32,97,110,100, + 32,99,97,99,104,101,32,105,116,46,32,73,102,32,110,111, + 32,102,105,110,100,101,114,32,105,115,32,97,118,97,105,108, + 97,98,108,101,44,32,115,116,111,114,101,32,78,111,110,101, + 46,10,10,32,32,32,32,32,32,32,32,114,40,0,0,0, + 78,41,7,114,2,0,0,0,114,55,0,0,0,114,3,1, + 0,0,114,8,0,0,0,114,48,1,0,0,218,8,75,101, + 121,69,114,114,111,114,114,52,1,0,0,41,3,114,193,0, + 0,0,114,44,0,0,0,114,50,1,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,20,95,112,97, + 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, + 101,236,4,0,0,115,22,0,0,0,0,8,8,1,2,1, + 12,1,14,3,8,1,2,1,14,1,14,1,10,1,16,1, + 122,31,80,97,116,104,70,105,110,100,101,114,46,95,112,97, + 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, + 101,99,3,0,0,0,0,0,0,0,0,0,0,0,6,0, + 0,0,4,0,0,0,67,0,0,0,115,82,0,0,0,116, + 0,124,2,100,1,131,2,114,26,124,2,160,1,124,1,161, + 1,92,2,125,3,125,4,110,14,124,2,160,2,124,1,161, + 1,125,3,103,0,125,4,124,3,100,0,107,9,114,60,116, + 3,160,4,124,1,124,3,161,2,83,0,116,3,160,5,124, + 1,100,0,161,2,125,5,124,4,124,5,95,6,124,5,83, + 0,41,2,78,114,137,0,0,0,41,7,114,128,0,0,0, + 114,137,0,0,0,114,206,0,0,0,114,134,0,0,0,114, + 201,0,0,0,114,183,0,0,0,114,178,0,0,0,41,6, + 114,193,0,0,0,114,139,0,0,0,114,50,1,0,0,114, + 140,0,0,0,114,141,0,0,0,114,187,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,16,95, + 108,101,103,97,99,121,95,103,101,116,95,115,112,101,99,2, + 5,0,0,115,18,0,0,0,0,4,10,1,16,2,10,1, + 4,1,8,1,12,1,12,1,6,1,122,27,80,97,116,104, + 70,105,110,100,101,114,46,95,108,101,103,97,99,121,95,103, + 101,116,95,115,112,101,99,78,99,4,0,0,0,0,0,0, + 0,0,0,0,0,9,0,0,0,5,0,0,0,67,0,0, + 0,115,166,0,0,0,103,0,125,4,124,2,68,0,93,134, + 125,5,116,0,124,5,116,1,116,2,102,2,131,2,115,28, + 113,8,124,0,160,3,124,5,161,1,125,6,124,6,100,1, + 107,9,114,8,116,4,124,6,100,2,131,2,114,70,124,6, + 160,5,124,1,124,3,161,2,125,7,110,12,124,0,160,6, + 124,1,124,6,161,2,125,7,124,7,100,1,107,8,114,92, + 113,8,124,7,106,7,100,1,107,9,114,110,124,7,2,0, + 1,0,83,0,124,7,106,8,125,8,124,8,100,1,107,8, + 114,132,116,9,100,3,131,1,130,1,124,4,160,10,124,8, + 161,1,1,0,113,8,116,11,160,12,124,1,100,1,161,2, + 125,7,124,4,124,7,95,8,124,7,83,0,41,4,122,63, + 70,105,110,100,32,116,104,101,32,108,111,97,100,101,114,32, + 111,114,32,110,97,109,101,115,112,97,99,101,95,112,97,116, + 104,32,102,111,114,32,116,104,105,115,32,109,111,100,117,108, + 101,47,112,97,99,107,97,103,101,32,110,97,109,101,46,78, + 114,203,0,0,0,122,19,115,112,101,99,32,109,105,115,115, + 105,110,103,32,108,111,97,100,101,114,41,13,114,161,0,0, + 0,114,85,0,0,0,218,5,98,121,116,101,115,114,54,1, + 0,0,114,128,0,0,0,114,203,0,0,0,114,55,1,0, + 0,114,140,0,0,0,114,178,0,0,0,114,118,0,0,0, + 114,167,0,0,0,114,134,0,0,0,114,183,0,0,0,41, + 9,114,193,0,0,0,114,139,0,0,0,114,44,0,0,0, + 114,202,0,0,0,218,14,110,97,109,101,115,112,97,99,101, + 95,112,97,116,104,90,5,101,110,116,114,121,114,50,1,0, + 0,114,187,0,0,0,114,141,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,9,95,103,101,116, + 95,115,112,101,99,17,5,0,0,115,40,0,0,0,0,5, + 4,1,8,1,14,1,2,1,10,1,8,1,10,1,14,2, + 12,1,8,1,2,1,10,1,8,1,6,1,8,1,8,5, + 12,2,12,1,6,1,122,20,80,97,116,104,70,105,110,100, + 101,114,46,95,103,101,116,95,115,112,101,99,99,4,0,0, + 0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0, + 0,67,0,0,0,115,100,0,0,0,124,2,100,1,107,8, + 114,14,116,0,106,1,125,2,124,0,160,2,124,1,124,2, + 124,3,161,3,125,4,124,4,100,1,107,8,114,40,100,1, + 83,0,124,4,106,3,100,1,107,8,114,92,124,4,106,4, + 125,5,124,5,114,86,100,1,124,4,95,5,116,6,124,1, + 124,5,124,0,106,2,131,3,124,4,95,4,124,4,83,0, + 100,1,83,0,110,4,124,4,83,0,100,1,83,0,41,2, + 122,141,84,114,121,32,116,111,32,102,105,110,100,32,97,32, + 115,112,101,99,32,102,111,114,32,39,102,117,108,108,110,97, + 109,101,39,32,111,110,32,115,121,115,46,112,97,116,104,32, + 111,114,32,39,112,97,116,104,39,46,10,10,32,32,32,32, + 32,32,32,32,84,104,101,32,115,101,97,114,99,104,32,105, + 115,32,98,97,115,101,100,32,111,110,32,115,121,115,46,112, + 97,116,104,95,104,111,111,107,115,32,97,110,100,32,115,121, + 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,46,10,32,32,32,32,32,32,32,32,78, + 41,7,114,8,0,0,0,114,44,0,0,0,114,58,1,0, + 0,114,140,0,0,0,114,178,0,0,0,114,181,0,0,0, + 114,22,1,0,0,41,6,114,193,0,0,0,114,139,0,0, + 0,114,44,0,0,0,114,202,0,0,0,114,187,0,0,0, + 114,57,1,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,203,0,0,0,49,5,0,0,115,26,0, + 0,0,0,6,8,1,6,1,14,1,8,1,4,1,10,1, + 6,1,4,3,6,1,16,1,4,2,6,2,122,20,80,97, + 116,104,70,105,110,100,101,114,46,102,105,110,100,95,115,112, + 101,99,99,3,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,4,0,0,0,67,0,0,0,115,30,0,0,0, + 124,0,160,0,124,1,124,2,161,2,125,3,124,3,100,1, + 107,8,114,24,100,1,83,0,124,3,106,1,83,0,41,2, + 122,170,102,105,110,100,32,116,104,101,32,109,111,100,117,108, + 101,32,111,110,32,115,121,115,46,112,97,116,104,32,111,114, + 32,39,112,97,116,104,39,32,98,97,115,101,100,32,111,110, + 32,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32, + 97,110,100,10,32,32,32,32,32,32,32,32,115,121,115,46, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,46,32,32,85,115,101,32,102,105, + 110,100,95,115,112,101,99,40,41,32,105,110,115,116,101,97, + 100,46,10,10,32,32,32,32,32,32,32,32,78,114,204,0, + 0,0,114,205,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,206,0,0,0,73,5,0,0,115, + 8,0,0,0,0,8,12,1,8,1,4,1,122,22,80,97, + 116,104,70,105,110,100,101,114,46,102,105,110,100,95,109,111, + 100,117,108,101,41,1,78,41,2,78,78,41,1,78,41,12, 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, - 127,0,0,0,114,209,0,0,0,114,46,1,0,0,114,143, - 0,0,0,114,206,0,0,0,114,137,0,0,0,114,58,1, - 0,0,114,203,0,0,0,114,67,1,0,0,114,207,0,0, - 0,114,74,1,0,0,114,39,1,0,0,114,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 59,1,0,0,83,5,0,0,115,22,0,0,0,8,2,4, - 7,8,14,8,4,4,2,8,12,8,5,10,48,8,31,2, - 1,10,17,114,59,1,0,0,99,4,0,0,0,0,0,0, - 0,0,0,0,0,6,0,0,0,8,0,0,0,67,0,0, - 0,115,146,0,0,0,124,0,160,0,100,1,161,1,125,4, - 124,0,160,0,100,2,161,1,125,5,124,4,115,66,124,5, - 114,36,124,5,106,1,125,4,110,30,124,2,124,3,107,2, - 114,56,116,2,124,1,124,2,131,2,125,4,110,10,116,3, - 124,1,124,2,131,2,125,4,124,5,115,84,116,4,124,1, - 124,2,124,4,100,3,141,3,125,5,122,36,124,5,124,0, - 100,2,60,0,124,4,124,0,100,1,60,0,124,2,124,0, - 100,4,60,0,124,3,124,0,100,5,60,0,87,0,110,20, - 4,0,116,5,107,10,114,140,1,0,1,0,1,0,89,0, - 110,2,88,0,100,0,83,0,41,6,78,218,10,95,95,108, - 111,97,100,101,114,95,95,218,8,95,95,115,112,101,99,95, - 95,114,60,1,0,0,90,8,95,95,102,105,108,101,95,95, - 90,10,95,95,99,97,99,104,101,100,95,95,41,6,218,3, - 103,101,116,114,140,0,0,0,114,14,1,0,0,114,8,1, - 0,0,114,190,0,0,0,218,9,69,120,99,101,112,116,105, - 111,110,41,6,90,2,110,115,114,117,0,0,0,90,8,112, - 97,116,104,110,97,109,101,90,9,99,112,97,116,104,110,97, - 109,101,114,140,0,0,0,114,187,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,14,95,102,105, - 120,95,117,112,95,109,111,100,117,108,101,232,5,0,0,115, - 34,0,0,0,0,2,10,1,10,1,4,1,4,1,8,1, - 8,1,12,2,10,1,4,1,14,1,2,1,8,1,8,1, - 8,1,12,1,14,2,114,79,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,38,0,0,0,116,0,116,1,160,2,161, - 0,102,2,125,0,116,3,116,4,102,2,125,1,116,5,116, - 6,102,2,125,2,124,0,124,1,124,2,103,3,83,0,41, - 1,122,95,82,101,116,117,114,110,115,32,97,32,108,105,115, - 116,32,111,102,32,102,105,108,101,45,98,97,115,101,100,32, - 109,111,100,117,108,101,32,108,111,97,100,101,114,115,46,10, - 10,32,32,32,32,69,97,99,104,32,105,116,101,109,32,105, - 115,32,97,32,116,117,112,108,101,32,40,108,111,97,100,101, - 114,44,32,115,117,102,102,105,120,101,115,41,46,10,32,32, - 32,32,41,7,114,15,1,0,0,114,163,0,0,0,218,18, - 101,120,116,101,110,115,105,111,110,95,115,117,102,102,105,120, - 101,115,114,8,1,0,0,114,102,0,0,0,114,14,1,0, - 0,114,89,0,0,0,41,3,90,10,101,120,116,101,110,115, - 105,111,110,115,90,6,115,111,117,114,99,101,90,8,98,121, - 116,101,99,111,100,101,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,184,0,0,0,255,5,0,0,115,8, - 0,0,0,0,5,12,1,8,1,8,1,114,184,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,12,0,0, - 0,9,0,0,0,67,0,0,0,115,178,1,0,0,124,0, - 97,0,116,0,106,1,97,1,116,0,106,2,97,2,116,1, - 106,3,116,4,25,0,125,1,100,1,68,0,93,48,125,2, - 124,2,116,1,106,3,107,7,114,56,116,0,160,5,124,2, - 161,1,125,3,110,10,116,1,106,3,124,2,25,0,125,3, - 116,6,124,1,124,2,124,3,131,3,1,0,113,30,100,2, - 100,3,103,1,102,2,100,4,100,5,100,3,103,2,102,2, - 102,2,125,4,124,4,68,0,93,110,92,2,125,5,125,6, - 116,7,100,6,100,7,132,0,124,6,68,0,131,1,131,1, - 115,136,116,8,130,1,124,6,100,8,25,0,125,7,124,5, - 116,1,106,3,107,6,114,170,116,1,106,3,124,5,25,0, - 125,8,1,0,113,226,113,106,122,20,116,0,160,5,124,5, - 161,1,125,8,87,0,1,0,113,226,87,0,113,106,4,0, - 116,9,107,10,114,214,1,0,1,0,1,0,89,0,113,106, - 89,0,113,106,88,0,113,106,116,9,100,9,131,1,130,1, - 116,6,124,1,100,10,124,8,131,3,1,0,116,6,124,1, - 100,11,124,7,131,3,1,0,116,6,124,1,100,12,100,13, - 160,10,124,6,161,1,131,3,1,0,116,6,124,1,100,14, - 100,15,100,16,132,0,124,6,68,0,131,1,131,3,1,0, - 116,0,160,5,100,17,161,1,125,9,116,6,124,1,100,17, - 124,9,131,3,1,0,116,0,160,5,100,18,161,1,125,10, - 116,6,124,1,100,18,124,10,131,3,1,0,124,5,100,4, - 107,2,144,1,114,110,116,0,160,5,100,19,161,1,125,11, - 116,6,124,1,100,20,124,11,131,3,1,0,116,6,124,1, - 100,21,116,11,131,0,131,3,1,0,116,12,160,13,116,2, - 160,14,161,0,161,1,1,0,124,5,100,4,107,2,144,1, - 114,174,116,15,160,16,100,22,161,1,1,0,100,23,116,12, - 107,6,144,1,114,174,100,24,116,17,95,18,100,25,83,0, - 41,26,122,205,83,101,116,117,112,32,116,104,101,32,112,97, - 116,104,45,98,97,115,101,100,32,105,109,112,111,114,116,101, - 114,115,32,102,111,114,32,105,109,112,111,114,116,108,105,98, - 32,98,121,32,105,109,112,111,114,116,105,110,103,32,110,101, - 101,100,101,100,10,32,32,32,32,98,117,105,108,116,45,105, - 110,32,109,111,100,117,108,101,115,32,97,110,100,32,105,110, - 106,101,99,116,105,110,103,32,116,104,101,109,32,105,110,116, - 111,32,116,104,101,32,103,108,111,98,97,108,32,110,97,109, - 101,115,112,97,99,101,46,10,10,32,32,32,32,79,116,104, - 101,114,32,99,111,109,112,111,110,101,110,116,115,32,97,114, - 101,32,101,120,116,114,97,99,116,101,100,32,102,114,111,109, - 32,116,104,101,32,99,111,114,101,32,98,111,111,116,115,116, - 114,97,112,32,109,111,100,117,108,101,46,10,10,32,32,32, - 32,41,4,114,64,0,0,0,114,75,0,0,0,218,8,98, - 117,105,108,116,105,110,115,114,160,0,0,0,90,5,112,111, - 115,105,120,250,1,47,90,2,110,116,250,1,92,99,1,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, - 0,0,115,0,0,0,115,26,0,0,0,124,0,93,18,125, - 1,116,0,124,1,131,1,100,0,107,2,86,0,1,0,113, - 2,100,1,83,0,41,2,114,39,0,0,0,78,41,1,114, - 22,0,0,0,41,2,114,32,0,0,0,114,95,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 19,1,0,0,35,6,0,0,115,4,0,0,0,4,0,2, - 0,122,25,95,115,101,116,117,112,46,60,108,111,99,97,108, - 115,62,46,60,103,101,110,101,120,112,114,62,114,73,0,0, - 0,122,30,105,109,112,111,114,116,108,105,98,32,114,101,113, - 117,105,114,101,115,32,112,111,115,105,120,32,111,114,32,110, - 116,114,2,0,0,0,114,35,0,0,0,114,31,0,0,0, - 114,40,0,0,0,114,58,0,0,0,99,1,0,0,0,0, + 127,0,0,0,114,207,0,0,0,114,46,1,0,0,114,52, + 1,0,0,114,54,1,0,0,114,55,1,0,0,114,58,1, + 0,0,114,203,0,0,0,114,206,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,45,1,0,0,209,4,0,0,115,30,0,0,0,8,2, + 4,2,2,1,10,9,2,1,10,12,2,1,10,21,2,1, + 10,14,2,1,12,31,2,1,12,23,2,1,114,45,1,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,64,0,0,0,115,90,0,0,0,101, + 0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,132, + 0,90,4,100,4,100,5,132,0,90,5,101,6,90,7,100, + 6,100,7,132,0,90,8,100,8,100,9,132,0,90,9,100, + 19,100,11,100,12,132,1,90,10,100,13,100,14,132,0,90, + 11,101,12,100,15,100,16,132,0,131,1,90,13,100,17,100, + 18,132,0,90,14,100,10,83,0,41,20,218,10,70,105,108, + 101,70,105,110,100,101,114,122,172,70,105,108,101,45,98,97, + 115,101,100,32,102,105,110,100,101,114,46,10,10,32,32,32, + 32,73,110,116,101,114,97,99,116,105,111,110,115,32,119,105, + 116,104,32,116,104,101,32,102,105,108,101,32,115,121,115,116, + 101,109,32,97,114,101,32,99,97,99,104,101,100,32,102,111, + 114,32,112,101,114,102,111,114,109,97,110,99,101,44,32,98, + 101,105,110,103,10,32,32,32,32,114,101,102,114,101,115,104, + 101,100,32,119,104,101,110,32,116,104,101,32,100,105,114,101, + 99,116,111,114,121,32,116,104,101,32,102,105,110,100,101,114, + 32,105,115,32,104,97,110,100,108,105,110,103,32,104,97,115, + 32,98,101,101,110,32,109,111,100,105,102,105,101,100,46,10, + 10,32,32,32,32,99,2,0,0,0,0,0,0,0,0,0, + 0,0,5,0,0,0,6,0,0,0,7,0,0,0,115,84, + 0,0,0,103,0,125,3,124,2,68,0,93,32,92,2,137, + 0,125,4,124,3,160,0,135,0,102,1,100,1,100,2,132, + 8,124,4,68,0,131,1,161,1,1,0,113,8,124,3,124, + 0,95,1,124,1,112,54,100,3,124,0,95,2,100,4,124, + 0,95,3,116,4,131,0,124,0,95,5,116,4,131,0,124, + 0,95,6,100,5,83,0,41,6,122,154,73,110,105,116,105, + 97,108,105,122,101,32,119,105,116,104,32,116,104,101,32,112, + 97,116,104,32,116,111,32,115,101,97,114,99,104,32,111,110, + 32,97,110,100,32,97,32,118,97,114,105,97,98,108,101,32, + 110,117,109,98,101,114,32,111,102,10,32,32,32,32,32,32, + 32,32,50,45,116,117,112,108,101,115,32,99,111,110,116,97, + 105,110,105,110,103,32,116,104,101,32,108,111,97,100,101,114, + 32,97,110,100,32,116,104,101,32,102,105,108,101,32,115,117, + 102,102,105,120,101,115,32,116,104,101,32,108,111,97,100,101, + 114,10,32,32,32,32,32,32,32,32,114,101,99,111,103,110, + 105,122,101,115,46,99,1,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,51,0,0,0,115,22, + 0,0,0,124,0,93,14,125,1,124,1,136,0,102,2,86, + 0,1,0,113,2,100,0,83,0,114,110,0,0,0,114,3, + 0,0,0,114,16,1,0,0,169,1,114,140,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,19,1,0,0,102,5, + 0,0,115,4,0,0,0,4,0,2,0,122,38,70,105,108, + 101,70,105,110,100,101,114,46,95,95,105,110,105,116,95,95, + 46,60,108,111,99,97,108,115,62,46,60,103,101,110,101,120, + 112,114,62,114,71,0,0,0,114,105,0,0,0,78,41,7, + 114,167,0,0,0,218,8,95,108,111,97,100,101,114,115,114, + 44,0,0,0,218,11,95,112,97,116,104,95,109,116,105,109, + 101,218,3,115,101,116,218,11,95,112,97,116,104,95,99,97, + 99,104,101,218,19,95,114,101,108,97,120,101,100,95,112,97, + 116,104,95,99,97,99,104,101,41,5,114,119,0,0,0,114, + 44,0,0,0,218,14,108,111,97,100,101,114,95,100,101,116, + 97,105,108,115,90,7,108,111,97,100,101,114,115,114,189,0, + 0,0,114,3,0,0,0,114,60,1,0,0,114,6,0,0, + 0,114,209,0,0,0,96,5,0,0,115,16,0,0,0,0, + 4,4,1,12,1,26,1,6,2,10,1,6,1,8,1,122, + 19,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110, + 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,2,0,0,0,67,0,0,0,115,10,0, + 0,0,100,1,124,0,95,0,100,2,83,0,41,3,122,31, + 73,110,118,97,108,105,100,97,116,101,32,116,104,101,32,100, + 105,114,101,99,116,111,114,121,32,109,116,105,109,101,46,114, + 105,0,0,0,78,41,1,114,62,1,0,0,114,246,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,46,1,0,0,110,5,0,0,115,2,0,0,0,0,2, + 122,28,70,105,108,101,70,105,110,100,101,114,46,105,110,118, + 97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,2, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3, + 0,0,0,67,0,0,0,115,42,0,0,0,124,0,160,0, + 124,1,161,1,125,2,124,2,100,1,107,8,114,26,100,1, + 103,0,102,2,83,0,124,2,106,1,124,2,106,2,112,38, + 103,0,102,2,83,0,41,2,122,197,84,114,121,32,116,111, + 32,102,105,110,100,32,97,32,108,111,97,100,101,114,32,102, + 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, + 32,109,111,100,117,108,101,44,32,111,114,32,116,104,101,32, + 110,97,109,101,115,112,97,99,101,10,32,32,32,32,32,32, + 32,32,112,97,99,107,97,103,101,32,112,111,114,116,105,111, + 110,115,46,32,82,101,116,117,114,110,115,32,40,108,111,97, + 100,101,114,44,32,108,105,115,116,45,111,102,45,112,111,114, + 116,105,111,110,115,41,46,10,10,32,32,32,32,32,32,32, + 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, + 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, + 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, + 41,3,114,203,0,0,0,114,140,0,0,0,114,178,0,0, + 0,41,3,114,119,0,0,0,114,139,0,0,0,114,187,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,137,0,0,0,116,5,0,0,115,8,0,0,0,0, + 7,10,1,8,1,8,1,122,22,70,105,108,101,70,105,110, + 100,101,114,46,102,105,110,100,95,108,111,97,100,101,114,99, + 6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, + 6,0,0,0,67,0,0,0,115,26,0,0,0,124,1,124, + 2,124,3,131,2,125,6,116,0,124,2,124,3,124,6,124, + 4,100,1,141,4,83,0,41,2,78,114,177,0,0,0,41, + 1,114,190,0,0,0,41,7,114,119,0,0,0,114,188,0, + 0,0,114,139,0,0,0,114,44,0,0,0,90,4,115,109, + 115,108,114,202,0,0,0,114,140,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,58,1,0,0, + 128,5,0,0,115,8,0,0,0,0,1,10,1,8,1,2, + 255,122,20,70,105,108,101,70,105,110,100,101,114,46,95,103, + 101,116,95,115,112,101,99,78,99,3,0,0,0,0,0,0, + 0,0,0,0,0,14,0,0,0,8,0,0,0,67,0,0, + 0,115,102,1,0,0,100,1,125,3,124,1,160,0,100,2, + 161,1,100,3,25,0,125,4,122,24,116,1,124,0,106,2, + 112,34,116,3,160,4,161,0,131,1,106,5,125,5,87,0, + 110,24,4,0,116,6,107,10,114,66,1,0,1,0,1,0, + 100,4,125,5,89,0,110,2,88,0,124,5,124,0,106,7, + 107,3,114,92,124,0,160,8,161,0,1,0,124,5,124,0, + 95,7,116,9,131,0,114,114,124,0,106,10,125,6,124,4, + 160,11,161,0,125,7,110,10,124,0,106,12,125,6,124,4, + 125,7,124,7,124,6,107,6,114,218,116,13,124,0,106,2, + 124,4,131,2,125,8,124,0,106,14,68,0,93,58,92,2, + 125,9,125,10,100,5,124,9,23,0,125,11,116,13,124,8, + 124,11,131,2,125,12,116,15,124,12,131,1,114,208,124,0, + 160,16,124,10,124,1,124,12,124,8,103,1,124,2,161,5, + 2,0,1,0,83,0,113,150,116,17,124,8,131,1,125,3, + 124,0,106,14,68,0,93,86,92,2,125,9,125,10,116,13, + 124,0,106,2,124,4,124,9,23,0,131,2,125,12,116,18, + 106,19,100,6,124,12,100,3,100,7,141,3,1,0,124,7, + 124,9,23,0,124,6,107,6,144,1,114,54,116,15,124,12, + 131,1,144,1,114,54,124,0,160,16,124,10,124,1,124,12, + 100,8,124,2,161,5,2,0,1,0,83,0,113,224,124,3, + 144,1,114,98,116,18,160,19,100,9,124,8,161,2,1,0, + 116,18,160,20,124,1,100,8,161,2,125,13,124,8,103,1, + 124,13,95,21,124,13,83,0,100,8,83,0,41,10,122,111, + 84,114,121,32,116,111,32,102,105,110,100,32,97,32,115,112, + 101,99,32,102,111,114,32,116,104,101,32,115,112,101,99,105, + 102,105,101,100,32,109,111,100,117,108,101,46,10,10,32,32, + 32,32,32,32,32,32,82,101,116,117,114,110,115,32,116,104, + 101,32,109,97,116,99,104,105,110,103,32,115,112,101,99,44, + 32,111,114,32,78,111,110,101,32,105,102,32,110,111,116,32, + 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,70, + 114,71,0,0,0,114,28,0,0,0,114,105,0,0,0,114, + 209,0,0,0,122,9,116,114,121,105,110,103,32,123,125,41, + 1,90,9,118,101,114,98,111,115,105,116,121,78,122,25,112, + 111,115,115,105,98,108,101,32,110,97,109,101,115,112,97,99, + 101,32,102,111,114,32,123,125,41,22,114,41,0,0,0,114, + 49,0,0,0,114,44,0,0,0,114,2,0,0,0,114,55, + 0,0,0,114,10,1,0,0,114,50,0,0,0,114,62,1, + 0,0,218,11,95,102,105,108,108,95,99,97,99,104,101,114, + 7,0,0,0,114,65,1,0,0,114,106,0,0,0,114,64, + 1,0,0,114,38,0,0,0,114,61,1,0,0,114,54,0, + 0,0,114,58,1,0,0,114,56,0,0,0,114,134,0,0, + 0,114,149,0,0,0,114,183,0,0,0,114,178,0,0,0, + 41,14,114,119,0,0,0,114,139,0,0,0,114,202,0,0, + 0,90,12,105,115,95,110,97,109,101,115,112,97,99,101,90, + 11,116,97,105,108,95,109,111,100,117,108,101,114,169,0,0, + 0,90,5,99,97,99,104,101,90,12,99,97,99,104,101,95, + 109,111,100,117,108,101,90,9,98,97,115,101,95,112,97,116, + 104,114,17,1,0,0,114,188,0,0,0,90,13,105,110,105, + 116,95,102,105,108,101,110,97,109,101,90,9,102,117,108,108, + 95,112,97,116,104,114,187,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,203,0,0,0,133,5, + 0,0,115,74,0,0,0,0,5,4,1,14,1,2,1,24, + 1,14,1,10,1,10,1,8,1,6,2,6,1,6,1,10, + 2,6,1,4,2,8,1,12,1,14,1,8,1,10,1,8, + 1,26,4,8,2,14,1,16,1,16,1,14,1,10,1,10, + 1,2,0,2,255,10,2,6,1,12,1,12,1,8,1,4, + 1,122,20,70,105,108,101,70,105,110,100,101,114,46,102,105, + 110,100,95,115,112,101,99,99,1,0,0,0,0,0,0,0, + 0,0,0,0,9,0,0,0,10,0,0,0,67,0,0,0, + 115,190,0,0,0,124,0,106,0,125,1,122,22,116,1,160, + 2,124,1,112,22,116,1,160,3,161,0,161,1,125,2,87, + 0,110,30,4,0,116,4,116,5,116,6,102,3,107,10,114, + 58,1,0,1,0,1,0,103,0,125,2,89,0,110,2,88, + 0,116,7,106,8,160,9,100,1,161,1,115,84,116,10,124, + 2,131,1,124,0,95,11,110,74,116,10,131,0,125,3,124, + 2,68,0,93,56,125,4,124,4,160,12,100,2,161,1,92, + 3,125,5,125,6,125,7,124,6,114,136,100,3,160,13,124, + 5,124,7,160,14,161,0,161,2,125,8,110,4,124,5,125, + 8,124,3,160,15,124,8,161,1,1,0,113,94,124,3,124, + 0,95,11,116,7,106,8,160,9,116,16,161,1,114,186,100, + 4,100,5,132,0,124,2,68,0,131,1,124,0,95,17,100, + 6,83,0,41,7,122,68,70,105,108,108,32,116,104,101,32, + 99,97,99,104,101,32,111,102,32,112,111,116,101,110,116,105, + 97,108,32,109,111,100,117,108,101,115,32,97,110,100,32,112, + 97,99,107,97,103,101,115,32,102,111,114,32,116,104,105,115, + 32,100,105,114,101,99,116,111,114,121,46,114,0,0,0,0, + 114,71,0,0,0,114,61,0,0,0,99,1,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,83, - 0,0,0,115,22,0,0,0,104,0,124,0,93,14,125,1, - 100,0,124,1,155,0,157,2,146,2,113,4,83,0,41,1, - 114,74,0,0,0,114,3,0,0,0,41,2,114,32,0,0, - 0,218,1,115,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,68,1,0,0,51,6,0,0,115,4,0,0, - 0,6,0,2,0,122,25,95,115,101,116,117,112,46,60,108, - 111,99,97,108,115,62,46,60,115,101,116,99,111,109,112,62, - 90,7,95,116,104,114,101,97,100,90,8,95,119,101,97,107, - 114,101,102,90,6,119,105,110,114,101,103,114,192,0,0,0, - 114,7,0,0,0,122,4,46,112,121,119,122,6,95,100,46, - 112,121,100,84,78,41,19,114,134,0,0,0,114,8,0,0, - 0,114,163,0,0,0,114,31,1,0,0,114,125,0,0,0, - 90,18,95,98,117,105,108,116,105,110,95,102,114,111,109,95, - 110,97,109,101,114,129,0,0,0,218,3,97,108,108,114,23, - 0,0,0,114,118,0,0,0,114,36,0,0,0,114,13,0, - 0,0,114,21,1,0,0,114,167,0,0,0,114,80,1,0, - 0,114,102,0,0,0,114,186,0,0,0,114,191,0,0,0, - 114,195,0,0,0,41,12,218,17,95,98,111,111,116,115,116, - 114,97,112,95,109,111,100,117,108,101,90,11,115,101,108,102, - 95,109,111,100,117,108,101,90,12,98,117,105,108,116,105,110, - 95,110,97,109,101,90,14,98,117,105,108,116,105,110,95,109, - 111,100,117,108,101,90,10,111,115,95,100,101,116,97,105,108, - 115,90,10,98,117,105,108,116,105,110,95,111,115,114,31,0, - 0,0,114,35,0,0,0,90,9,111,115,95,109,111,100,117, - 108,101,90,13,116,104,114,101,97,100,95,109,111,100,117,108, - 101,90,14,119,101,97,107,114,101,102,95,109,111,100,117,108, - 101,90,13,119,105,110,114,101,103,95,109,111,100,117,108,101, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 6,95,115,101,116,117,112,10,6,0,0,115,78,0,0,0, - 0,8,4,1,6,1,6,3,10,1,8,1,10,1,12,2, - 10,1,14,3,22,1,12,2,22,1,8,1,10,1,10,1, - 6,2,2,1,10,1,10,1,14,1,12,2,8,1,12,1, - 12,1,18,1,22,3,10,1,12,3,10,1,12,3,10,1, - 10,1,12,3,14,1,14,1,10,1,10,1,10,1,114,87, - 1,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,67,0,0,0,115,50,0,0, - 0,116,0,124,0,131,1,1,0,116,1,131,0,125,1,116, - 2,106,3,160,4,116,5,106,6,124,1,142,0,103,1,161, - 1,1,0,116,2,106,7,160,8,116,9,161,1,1,0,100, - 1,83,0,41,2,122,41,73,110,115,116,97,108,108,32,116, - 104,101,32,112,97,116,104,45,98,97,115,101,100,32,105,109, - 112,111,114,116,32,99,111,109,112,111,110,101,110,116,115,46, - 78,41,10,114,87,1,0,0,114,184,0,0,0,114,8,0, - 0,0,114,51,1,0,0,114,167,0,0,0,114,59,1,0, - 0,114,74,1,0,0,218,9,109,101,116,97,95,112,97,116, - 104,114,186,0,0,0,114,45,1,0,0,41,2,114,86,1, - 0,0,90,17,115,117,112,112,111,114,116,101,100,95,108,111, - 97,100,101,114,115,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,8,95,105,110,115,116,97,108,108,75,6, - 0,0,115,8,0,0,0,0,2,8,1,6,1,20,1,114, - 89,1,0,0,41,63,114,127,0,0,0,114,12,0,0,0, - 90,37,95,67,65,83,69,95,73,78,83,69,78,83,73,84, - 73,86,69,95,80,76,65,84,70,79,82,77,83,95,66,89, - 84,69,83,95,75,69,89,114,11,0,0,0,114,13,0,0, - 0,114,20,0,0,0,114,27,0,0,0,114,29,0,0,0, - 114,38,0,0,0,114,47,0,0,0,114,49,0,0,0,114, - 53,0,0,0,114,54,0,0,0,114,56,0,0,0,114,59, - 0,0,0,114,69,0,0,0,218,4,116,121,112,101,218,8, - 95,95,99,111,100,101,95,95,114,162,0,0,0,114,18,0, - 0,0,114,148,0,0,0,114,17,0,0,0,114,24,0,0, - 0,114,236,0,0,0,114,92,0,0,0,114,88,0,0,0, - 114,102,0,0,0,114,89,0,0,0,90,23,68,69,66,85, - 71,95,66,89,84,69,67,79,68,69,95,83,85,70,70,73, - 88,69,83,90,27,79,80,84,73,77,73,90,69,68,95,66, - 89,84,69,67,79,68,69,95,83,85,70,70,73,88,69,83, - 114,98,0,0,0,114,103,0,0,0,114,109,0,0,0,114, - 113,0,0,0,114,115,0,0,0,114,136,0,0,0,114,143, - 0,0,0,114,152,0,0,0,114,156,0,0,0,114,158,0, - 0,0,114,165,0,0,0,114,170,0,0,0,114,171,0,0, - 0,114,176,0,0,0,218,6,111,98,106,101,99,116,114,185, - 0,0,0,114,190,0,0,0,114,191,0,0,0,114,208,0, - 0,0,114,221,0,0,0,114,239,0,0,0,114,8,1,0, - 0,114,14,1,0,0,114,21,1,0,0,114,15,1,0,0, - 114,22,1,0,0,114,43,1,0,0,114,45,1,0,0,114, - 59,1,0,0,114,79,1,0,0,114,184,0,0,0,114,87, - 1,0,0,114,89,1,0,0,114,3,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,8,60,109, - 111,100,117,108,101,62,1,0,0,0,115,126,0,0,0,4, - 22,4,1,4,1,2,1,2,255,4,4,8,17,8,5,8, - 5,8,6,8,6,8,12,8,10,8,9,8,5,8,7,8, - 9,12,22,10,127,0,8,16,1,12,2,4,1,4,2,6, - 2,6,2,8,2,18,71,8,40,8,19,8,12,8,12,8, - 28,8,17,8,33,8,28,8,24,16,13,14,10,12,11,8, - 14,6,3,6,1,2,255,12,68,14,64,14,29,16,127,0, - 17,14,68,18,45,18,26,4,3,18,53,14,63,14,42,14, - 127,0,7,14,127,0,22,12,23,8,11,8,65, + 0,0,0,115,20,0,0,0,104,0,124,0,93,12,125,1, + 124,1,160,0,161,0,146,2,113,4,83,0,114,3,0,0, + 0,41,1,114,106,0,0,0,41,2,114,32,0,0,0,90, + 2,102,110,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,9,60,115,101,116,99,111,109,112,62,210,5,0, + 0,115,4,0,0,0,6,0,2,0,122,41,70,105,108,101, + 70,105,110,100,101,114,46,95,102,105,108,108,95,99,97,99, + 104,101,46,60,108,111,99,97,108,115,62,46,60,115,101,116, + 99,111,109,112,62,78,41,18,114,44,0,0,0,114,2,0, + 0,0,114,7,1,0,0,114,55,0,0,0,114,3,1,0, + 0,218,15,80,101,114,109,105,115,115,105,111,110,69,114,114, + 111,114,218,18,78,111,116,65,68,105,114,101,99,116,111,114, + 121,69,114,114,111,114,114,8,0,0,0,114,9,0,0,0, + 114,10,0,0,0,114,63,1,0,0,114,64,1,0,0,114, + 101,0,0,0,114,62,0,0,0,114,106,0,0,0,218,3, + 97,100,100,114,11,0,0,0,114,65,1,0,0,41,9,114, + 119,0,0,0,114,44,0,0,0,114,8,1,0,0,90,21, + 108,111,119,101,114,95,115,117,102,102,105,120,95,99,111,110, + 116,101,110,116,115,114,41,1,0,0,114,117,0,0,0,114, + 29,1,0,0,114,17,1,0,0,90,8,110,101,119,95,110, + 97,109,101,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,67,1,0,0,181,5,0,0,115,34,0,0,0, + 0,2,6,1,2,1,22,1,20,3,10,3,12,1,12,7, + 6,1,8,1,16,1,4,1,18,2,4,1,12,1,6,1, + 12,1,122,22,70,105,108,101,70,105,110,100,101,114,46,95, + 102,105,108,108,95,99,97,99,104,101,99,1,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,7, + 0,0,0,115,18,0,0,0,135,0,135,1,102,2,100,1, + 100,2,132,8,125,2,124,2,83,0,41,3,97,20,1,0, + 0,65,32,99,108,97,115,115,32,109,101,116,104,111,100,32, + 119,104,105,99,104,32,114,101,116,117,114,110,115,32,97,32, + 99,108,111,115,117,114,101,32,116,111,32,117,115,101,32,111, + 110,32,115,121,115,46,112,97,116,104,95,104,111,111,107,10, + 32,32,32,32,32,32,32,32,119,104,105,99,104,32,119,105, + 108,108,32,114,101,116,117,114,110,32,97,110,32,105,110,115, + 116,97,110,99,101,32,117,115,105,110,103,32,116,104,101,32, + 115,112,101,99,105,102,105,101,100,32,108,111,97,100,101,114, + 115,32,97,110,100,32,116,104,101,32,112,97,116,104,10,32, + 32,32,32,32,32,32,32,99,97,108,108,101,100,32,111,110, + 32,116,104,101,32,99,108,111,115,117,114,101,46,10,10,32, + 32,32,32,32,32,32,32,73,102,32,116,104,101,32,112,97, + 116,104,32,99,97,108,108,101,100,32,111,110,32,116,104,101, + 32,99,108,111,115,117,114,101,32,105,115,32,110,111,116,32, + 97,32,100,105,114,101,99,116,111,114,121,44,32,73,109,112, + 111,114,116,69,114,114,111,114,32,105,115,10,32,32,32,32, + 32,32,32,32,114,97,105,115,101,100,46,10,10,32,32,32, + 32,32,32,32,32,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,4,0,0,0,19,0,0,0,115,34, + 0,0,0,116,0,124,0,131,1,115,20,116,1,100,1,124, + 0,100,2,141,2,130,1,136,0,124,0,102,1,136,1,158, + 2,142,0,83,0,41,3,122,45,80,97,116,104,32,104,111, + 111,107,32,102,111,114,32,105,109,112,111,114,116,108,105,98, + 46,109,97,99,104,105,110,101,114,121,46,70,105,108,101,70, + 105,110,100,101,114,46,122,30,111,110,108,121,32,100,105,114, + 101,99,116,111,114,105,101,115,32,97,114,101,32,115,117,112, + 112,111,114,116,101,100,114,48,0,0,0,41,2,114,56,0, + 0,0,114,118,0,0,0,114,48,0,0,0,169,2,114,193, + 0,0,0,114,66,1,0,0,114,3,0,0,0,114,6,0, + 0,0,218,24,112,97,116,104,95,104,111,111,107,95,102,111, + 114,95,70,105,108,101,70,105,110,100,101,114,222,5,0,0, + 115,6,0,0,0,0,2,8,1,12,1,122,54,70,105,108, + 101,70,105,110,100,101,114,46,112,97,116,104,95,104,111,111, + 107,46,60,108,111,99,97,108,115,62,46,112,97,116,104,95, + 104,111,111,107,95,102,111,114,95,70,105,108,101,70,105,110, + 100,101,114,114,3,0,0,0,41,3,114,193,0,0,0,114, + 66,1,0,0,114,73,1,0,0,114,3,0,0,0,114,72, + 1,0,0,114,6,0,0,0,218,9,112,97,116,104,95,104, + 111,111,107,212,5,0,0,115,4,0,0,0,0,10,14,6, + 122,20,70,105,108,101,70,105,110,100,101,114,46,112,97,116, + 104,95,104,111,111,107,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 12,0,0,0,100,1,160,0,124,0,106,1,161,1,83,0, + 41,2,78,122,16,70,105,108,101,70,105,110,100,101,114,40, + 123,33,114,125,41,41,2,114,62,0,0,0,114,44,0,0, + 0,114,246,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,39,1,0,0,230,5,0,0,115,2, + 0,0,0,0,1,122,19,70,105,108,101,70,105,110,100,101, + 114,46,95,95,114,101,112,114,95,95,41,1,78,41,15,114, + 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, + 0,0,0,114,209,0,0,0,114,46,1,0,0,114,143,0, + 0,0,114,206,0,0,0,114,137,0,0,0,114,58,1,0, + 0,114,203,0,0,0,114,67,1,0,0,114,207,0,0,0, + 114,74,1,0,0,114,39,1,0,0,114,3,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,59, + 1,0,0,87,5,0,0,115,22,0,0,0,8,2,4,7, + 8,14,8,4,4,2,8,12,8,5,10,48,8,31,2,1, + 10,17,114,59,1,0,0,99,4,0,0,0,0,0,0,0, + 0,0,0,0,6,0,0,0,8,0,0,0,67,0,0,0, + 115,146,0,0,0,124,0,160,0,100,1,161,1,125,4,124, + 0,160,0,100,2,161,1,125,5,124,4,115,66,124,5,114, + 36,124,5,106,1,125,4,110,30,124,2,124,3,107,2,114, + 56,116,2,124,1,124,2,131,2,125,4,110,10,116,3,124, + 1,124,2,131,2,125,4,124,5,115,84,116,4,124,1,124, + 2,124,4,100,3,141,3,125,5,122,36,124,5,124,0,100, + 2,60,0,124,4,124,0,100,1,60,0,124,2,124,0,100, + 4,60,0,124,3,124,0,100,5,60,0,87,0,110,20,4, + 0,116,5,107,10,114,140,1,0,1,0,1,0,89,0,110, + 2,88,0,100,0,83,0,41,6,78,218,10,95,95,108,111, + 97,100,101,114,95,95,218,8,95,95,115,112,101,99,95,95, + 114,60,1,0,0,90,8,95,95,102,105,108,101,95,95,90, + 10,95,95,99,97,99,104,101,100,95,95,41,6,218,3,103, + 101,116,114,140,0,0,0,114,15,1,0,0,114,9,1,0, + 0,114,190,0,0,0,218,9,69,120,99,101,112,116,105,111, + 110,41,6,90,2,110,115,114,117,0,0,0,90,8,112,97, + 116,104,110,97,109,101,90,9,99,112,97,116,104,110,97,109, + 101,114,140,0,0,0,114,187,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,14,95,102,105,120, + 95,117,112,95,109,111,100,117,108,101,236,5,0,0,115,34, + 0,0,0,0,2,10,1,10,1,4,1,4,1,8,1,8, + 1,12,2,10,1,4,1,14,1,2,1,8,1,8,1,8, + 1,12,1,14,2,114,79,1,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, + 0,0,0,115,38,0,0,0,116,0,116,1,160,2,161,0, + 102,2,125,0,116,3,116,4,102,2,125,1,116,5,116,6, + 102,2,125,2,124,0,124,1,124,2,103,3,83,0,41,1, + 122,95,82,101,116,117,114,110,115,32,97,32,108,105,115,116, + 32,111,102,32,102,105,108,101,45,98,97,115,101,100,32,109, + 111,100,117,108,101,32,108,111,97,100,101,114,115,46,10,10, + 32,32,32,32,69,97,99,104,32,105,116,101,109,32,105,115, + 32,97,32,116,117,112,108,101,32,40,108,111,97,100,101,114, + 44,32,115,117,102,102,105,120,101,115,41,46,10,32,32,32, + 32,41,7,114,252,0,0,0,114,163,0,0,0,218,18,101, + 120,116,101,110,115,105,111,110,95,115,117,102,102,105,120,101, + 115,114,9,1,0,0,114,102,0,0,0,114,15,1,0,0, + 114,89,0,0,0,41,3,90,10,101,120,116,101,110,115,105, + 111,110,115,90,6,115,111,117,114,99,101,90,8,98,121,116, + 101,99,111,100,101,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,184,0,0,0,3,6,0,0,115,8,0, + 0,0,0,5,12,1,8,1,8,1,114,184,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0, + 9,0,0,0,67,0,0,0,115,178,1,0,0,124,0,97, + 0,116,0,106,1,97,1,116,0,106,2,97,2,116,1,106, + 3,116,4,25,0,125,1,100,1,68,0,93,48,125,2,124, + 2,116,1,106,3,107,7,114,56,116,0,160,5,124,2,161, + 1,125,3,110,10,116,1,106,3,124,2,25,0,125,3,116, + 6,124,1,124,2,124,3,131,3,1,0,113,30,100,2,100, + 3,103,1,102,2,100,4,100,5,100,3,103,2,102,2,102, + 2,125,4,124,4,68,0,93,110,92,2,125,5,125,6,116, + 7,100,6,100,7,132,0,124,6,68,0,131,1,131,1,115, + 136,116,8,130,1,124,6,100,8,25,0,125,7,124,5,116, + 1,106,3,107,6,114,170,116,1,106,3,124,5,25,0,125, + 8,1,0,113,226,113,106,122,20,116,0,160,5,124,5,161, + 1,125,8,87,0,1,0,113,226,87,0,113,106,4,0,116, + 9,107,10,114,214,1,0,1,0,1,0,89,0,113,106,89, + 0,113,106,88,0,113,106,116,9,100,9,131,1,130,1,116, + 6,124,1,100,10,124,8,131,3,1,0,116,6,124,1,100, + 11,124,7,131,3,1,0,116,6,124,1,100,12,100,13,160, + 10,124,6,161,1,131,3,1,0,116,6,124,1,100,14,100, + 15,100,16,132,0,124,6,68,0,131,1,131,3,1,0,116, + 0,160,5,100,17,161,1,125,9,116,6,124,1,100,17,124, + 9,131,3,1,0,116,0,160,5,100,18,161,1,125,10,116, + 6,124,1,100,18,124,10,131,3,1,0,124,5,100,4,107, + 2,144,1,114,110,116,0,160,5,100,19,161,1,125,11,116, + 6,124,1,100,20,124,11,131,3,1,0,116,6,124,1,100, + 21,116,11,131,0,131,3,1,0,116,12,160,13,116,2,160, + 14,161,0,161,1,1,0,124,5,100,4,107,2,144,1,114, + 174,116,15,160,16,100,22,161,1,1,0,100,23,116,12,107, + 6,144,1,114,174,100,24,116,17,95,18,100,25,83,0,41, + 26,122,205,83,101,116,117,112,32,116,104,101,32,112,97,116, + 104,45,98,97,115,101,100,32,105,109,112,111,114,116,101,114, + 115,32,102,111,114,32,105,109,112,111,114,116,108,105,98,32, + 98,121,32,105,109,112,111,114,116,105,110,103,32,110,101,101, + 100,101,100,10,32,32,32,32,98,117,105,108,116,45,105,110, + 32,109,111,100,117,108,101,115,32,97,110,100,32,105,110,106, + 101,99,116,105,110,103,32,116,104,101,109,32,105,110,116,111, + 32,116,104,101,32,103,108,111,98,97,108,32,110,97,109,101, + 115,112,97,99,101,46,10,10,32,32,32,32,79,116,104,101, + 114,32,99,111,109,112,111,110,101,110,116,115,32,97,114,101, + 32,101,120,116,114,97,99,116,101,100,32,102,114,111,109,32, + 116,104,101,32,99,111,114,101,32,98,111,111,116,115,116,114, + 97,112,32,109,111,100,117,108,101,46,10,10,32,32,32,32, + 41,4,114,64,0,0,0,114,75,0,0,0,218,8,98,117, + 105,108,116,105,110,115,114,160,0,0,0,90,5,112,111,115, + 105,120,250,1,47,90,2,110,116,250,1,92,99,1,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, + 0,115,0,0,0,115,26,0,0,0,124,0,93,18,125,1, + 116,0,124,1,131,1,100,0,107,2,86,0,1,0,113,2, + 100,1,83,0,41,2,114,39,0,0,0,78,41,1,114,22, + 0,0,0,41,2,114,32,0,0,0,114,95,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,19, + 1,0,0,39,6,0,0,115,4,0,0,0,4,0,2,0, + 122,25,95,115,101,116,117,112,46,60,108,111,99,97,108,115, + 62,46,60,103,101,110,101,120,112,114,62,114,73,0,0,0, + 122,30,105,109,112,111,114,116,108,105,98,32,114,101,113,117, + 105,114,101,115,32,112,111,115,105,120,32,111,114,32,110,116, + 114,2,0,0,0,114,35,0,0,0,114,31,0,0,0,114, + 40,0,0,0,114,58,0,0,0,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,4,0,0,0,83,0, + 0,0,115,22,0,0,0,104,0,124,0,93,14,125,1,100, + 0,124,1,155,0,157,2,146,2,113,4,83,0,41,1,114, + 74,0,0,0,114,3,0,0,0,41,2,114,32,0,0,0, + 218,1,115,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,68,1,0,0,55,6,0,0,115,4,0,0,0, + 6,0,2,0,122,25,95,115,101,116,117,112,46,60,108,111, + 99,97,108,115,62,46,60,115,101,116,99,111,109,112,62,90, + 7,95,116,104,114,101,97,100,90,8,95,119,101,97,107,114, + 101,102,90,6,119,105,110,114,101,103,114,192,0,0,0,114, + 7,0,0,0,122,4,46,112,121,119,122,6,95,100,46,112, + 121,100,84,78,41,19,114,134,0,0,0,114,8,0,0,0, + 114,163,0,0,0,114,31,1,0,0,114,125,0,0,0,90, + 18,95,98,117,105,108,116,105,110,95,102,114,111,109,95,110, + 97,109,101,114,129,0,0,0,218,3,97,108,108,114,23,0, + 0,0,114,118,0,0,0,114,36,0,0,0,114,13,0,0, + 0,114,21,1,0,0,114,167,0,0,0,114,80,1,0,0, + 114,102,0,0,0,114,186,0,0,0,114,191,0,0,0,114, + 195,0,0,0,41,12,218,17,95,98,111,111,116,115,116,114, + 97,112,95,109,111,100,117,108,101,90,11,115,101,108,102,95, + 109,111,100,117,108,101,90,12,98,117,105,108,116,105,110,95, + 110,97,109,101,90,14,98,117,105,108,116,105,110,95,109,111, + 100,117,108,101,90,10,111,115,95,100,101,116,97,105,108,115, + 90,10,98,117,105,108,116,105,110,95,111,115,114,31,0,0, + 0,114,35,0,0,0,90,9,111,115,95,109,111,100,117,108, + 101,90,13,116,104,114,101,97,100,95,109,111,100,117,108,101, + 90,14,119,101,97,107,114,101,102,95,109,111,100,117,108,101, + 90,13,119,105,110,114,101,103,95,109,111,100,117,108,101,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,6, + 95,115,101,116,117,112,14,6,0,0,115,78,0,0,0,0, + 8,4,1,6,1,6,3,10,1,8,1,10,1,12,2,10, + 1,14,3,22,1,12,2,22,1,8,1,10,1,10,1,6, + 2,2,1,10,1,10,1,14,1,12,2,8,1,12,1,12, + 1,18,1,22,3,10,1,12,3,10,1,12,3,10,1,10, + 1,12,3,14,1,14,1,10,1,10,1,10,1,114,87,1, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,67,0,0,0,115,50,0,0,0, + 116,0,124,0,131,1,1,0,116,1,131,0,125,1,116,2, + 106,3,160,4,116,5,106,6,124,1,142,0,103,1,161,1, + 1,0,116,2,106,7,160,8,116,9,161,1,1,0,100,1, + 83,0,41,2,122,41,73,110,115,116,97,108,108,32,116,104, + 101,32,112,97,116,104,45,98,97,115,101,100,32,105,109,112, + 111,114,116,32,99,111,109,112,111,110,101,110,116,115,46,78, + 41,10,114,87,1,0,0,114,184,0,0,0,114,8,0,0, + 0,114,51,1,0,0,114,167,0,0,0,114,59,1,0,0, + 114,74,1,0,0,218,9,109,101,116,97,95,112,97,116,104, + 114,186,0,0,0,114,45,1,0,0,41,2,114,86,1,0, + 0,90,17,115,117,112,112,111,114,116,101,100,95,108,111,97, + 100,101,114,115,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,8,95,105,110,115,116,97,108,108,79,6,0, + 0,115,8,0,0,0,0,2,8,1,6,1,20,1,114,89, + 1,0,0,41,63,114,127,0,0,0,114,12,0,0,0,90, + 37,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, + 86,69,95,80,76,65,84,70,79,82,77,83,95,66,89,84, + 69,83,95,75,69,89,114,11,0,0,0,114,13,0,0,0, + 114,20,0,0,0,114,27,0,0,0,114,29,0,0,0,114, + 38,0,0,0,114,47,0,0,0,114,49,0,0,0,114,53, + 0,0,0,114,54,0,0,0,114,56,0,0,0,114,59,0, + 0,0,114,69,0,0,0,218,4,116,121,112,101,218,8,95, + 95,99,111,100,101,95,95,114,162,0,0,0,114,18,0,0, + 0,114,148,0,0,0,114,17,0,0,0,114,24,0,0,0, + 114,236,0,0,0,114,92,0,0,0,114,88,0,0,0,114, + 102,0,0,0,114,89,0,0,0,90,23,68,69,66,85,71, + 95,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88, + 69,83,90,27,79,80,84,73,77,73,90,69,68,95,66,89, + 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,114, + 98,0,0,0,114,103,0,0,0,114,109,0,0,0,114,113, + 0,0,0,114,115,0,0,0,114,136,0,0,0,114,143,0, + 0,0,114,152,0,0,0,114,156,0,0,0,114,158,0,0, + 0,114,165,0,0,0,114,170,0,0,0,114,171,0,0,0, + 114,176,0,0,0,218,6,111,98,106,101,99,116,114,185,0, + 0,0,114,190,0,0,0,114,191,0,0,0,114,208,0,0, + 0,114,221,0,0,0,114,239,0,0,0,114,9,1,0,0, + 114,15,1,0,0,114,21,1,0,0,114,252,0,0,0,114, + 22,1,0,0,114,43,1,0,0,114,45,1,0,0,114,59, + 1,0,0,114,79,1,0,0,114,184,0,0,0,114,87,1, + 0,0,114,89,1,0,0,114,3,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,8,60,109,111, + 100,117,108,101,62,1,0,0,0,115,126,0,0,0,4,22, + 4,1,4,1,2,1,2,255,4,4,8,17,8,5,8,5, + 8,6,8,6,8,12,8,10,8,9,8,5,8,7,8,9, + 12,22,10,127,0,8,16,1,12,2,4,1,4,2,6,2, + 6,2,8,2,18,71,8,40,8,19,8,12,8,12,8,28, + 8,17,8,33,8,28,8,24,16,13,14,10,12,11,8,14, + 6,3,6,1,2,255,12,68,14,64,14,29,16,127,0,17, + 14,72,18,45,18,26,4,3,18,53,14,63,14,42,14,127, + 0,7,14,127,0,22,12,23,8,11,8,65, }; diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index b7968944993556..cbb3d909a10b7b 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -522,563 +522,562 @@ const unsigned char _Py_M__zipimport[] = { 0,0,0,114,35,0,0,0,65,1,0,0,115,12,0,0, 0,0,1,10,1,14,1,8,1,10,1,10,1,114,35,0, 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,26, - 0,0,0,9,0,0,0,67,0,0,0,115,254,4,0,0, - 122,16,116,0,160,1,124,0,100,1,161,2,125,1,87,0, - 110,38,4,0,116,2,107,10,114,54,1,0,1,0,1,0, - 116,3,100,2,124,0,155,2,157,2,124,0,100,3,141,2, - 130,1,89,0,110,2,88,0,124,1,144,4,143,168,1,0, - 122,36,124,1,160,4,116,5,11,0,100,4,161,2,1,0, - 124,1,160,6,161,0,125,2,124,1,160,7,116,5,161,1, - 125,3,87,0,110,38,4,0,116,2,107,10,114,138,1,0, - 1,0,1,0,116,3,100,5,124,0,155,2,157,2,124,0, - 100,3,141,2,130,1,89,0,110,2,88,0,116,8,124,3, - 131,1,116,5,107,3,114,170,116,3,100,5,124,0,155,2, - 157,2,124,0,100,3,141,2,130,1,124,3,100,0,100,6, - 133,2,25,0,116,9,107,3,144,1,114,180,122,24,124,1, - 160,4,100,7,100,4,161,2,1,0,124,1,160,6,161,0, - 125,4,87,0,110,38,4,0,116,2,107,10,114,250,1,0, - 1,0,1,0,116,3,100,5,124,0,155,2,157,2,124,0, - 100,3,141,2,130,1,89,0,110,2,88,0,116,10,124,4, - 116,11,24,0,116,5,24,0,100,7,131,2,125,5,122,22, - 124,1,160,4,124,5,161,1,1,0,124,1,160,7,161,0, - 125,6,87,0,110,40,4,0,116,2,107,10,144,1,114,76, - 1,0,1,0,1,0,116,3,100,5,124,0,155,2,157,2, - 124,0,100,3,141,2,130,1,89,0,110,2,88,0,124,6, - 160,12,116,9,161,1,125,7,124,7,100,7,107,0,144,1, - 114,116,116,3,100,8,124,0,155,2,157,2,124,0,100,3, - 141,2,130,1,124,6,124,7,124,7,116,5,23,0,133,2, - 25,0,125,3,116,8,124,3,131,1,116,5,107,3,144,1, - 114,164,116,3,100,9,124,0,155,2,157,2,124,0,100,3, - 141,2,130,1,124,4,116,8,124,6,131,1,24,0,124,7, - 23,0,125,2,116,13,124,3,100,10,100,11,133,2,25,0, - 131,1,125,8,116,13,124,3,100,11,100,12,133,2,25,0, - 131,1,125,9,124,2,124,8,107,0,144,1,114,240,116,3, - 100,13,124,0,155,2,157,2,124,0,100,3,141,2,130,1, - 124,2,124,9,107,0,144,2,114,12,116,3,100,14,124,0, - 155,2,157,2,124,0,100,3,141,2,130,1,124,2,124,8, - 56,0,125,2,124,2,124,9,24,0,125,10,124,10,100,7, - 107,0,144,2,114,56,116,3,100,15,124,0,155,2,157,2, - 124,0,100,3,141,2,130,1,105,0,125,11,100,7,125,12, - 122,14,124,1,160,4,124,2,161,1,1,0,87,0,110,40, - 4,0,116,2,107,10,144,2,114,118,1,0,1,0,1,0, - 116,3,100,5,124,0,155,2,157,2,124,0,100,3,141,2, - 130,1,89,0,110,2,88,0,124,1,160,7,100,16,161,1, - 125,3,116,8,124,3,131,1,100,6,107,0,144,2,114,152, - 116,14,100,17,131,1,130,1,124,3,100,0,100,6,133,2, - 25,0,100,18,107,3,144,2,114,174,144,4,113,226,116,8, - 124,3,131,1,100,16,107,3,144,2,114,196,116,14,100,17, - 131,1,130,1,116,15,124,3,100,19,100,20,133,2,25,0, - 131,1,125,13,116,15,124,3,100,20,100,10,133,2,25,0, - 131,1,125,14,116,15,124,3,100,10,100,21,133,2,25,0, - 131,1,125,15,116,15,124,3,100,21,100,11,133,2,25,0, - 131,1,125,16,116,13,124,3,100,11,100,12,133,2,25,0, - 131,1,125,17,116,13,124,3,100,12,100,22,133,2,25,0, - 131,1,125,18,116,13,124,3,100,22,100,23,133,2,25,0, - 131,1,125,4,116,15,124,3,100,23,100,24,133,2,25,0, - 131,1,125,19,116,15,124,3,100,24,100,25,133,2,25,0, - 131,1,125,20,116,15,124,3,100,25,100,26,133,2,25,0, - 131,1,125,21,116,13,124,3,100,27,100,16,133,2,25,0, - 131,1,125,22,124,19,124,20,23,0,124,21,23,0,125,8, - 124,22,124,9,107,4,144,3,114,156,116,3,100,28,124,0, - 155,2,157,2,124,0,100,3,141,2,130,1,124,22,124,10, - 55,0,125,22,122,14,124,1,160,7,124,19,161,1,125,23, - 87,0,110,40,4,0,116,2,107,10,144,3,114,218,1,0, - 1,0,1,0,116,3,100,5,124,0,155,2,157,2,124,0, - 100,3,141,2,130,1,89,0,110,2,88,0,116,8,124,23, - 131,1,124,19,107,3,144,3,114,252,116,3,100,5,124,0, - 155,2,157,2,124,0,100,3,141,2,130,1,122,50,116,8, - 124,1,160,7,124,8,124,19,24,0,161,1,131,1,124,8, - 124,19,24,0,107,3,144,4,114,44,116,3,100,5,124,0, - 155,2,157,2,124,0,100,3,141,2,130,1,87,0,110,40, - 4,0,116,2,107,10,144,4,114,86,1,0,1,0,1,0, - 116,3,100,5,124,0,155,2,157,2,124,0,100,3,141,2, - 130,1,89,0,110,2,88,0,124,13,100,29,64,0,144,4, - 114,108,124,23,160,16,161,0,125,23,110,54,122,14,124,23, - 160,16,100,30,161,1,125,23,87,0,110,38,4,0,116,17, - 107,10,144,4,114,160,1,0,1,0,1,0,124,23,160,16, - 100,31,161,1,160,18,116,19,161,1,125,23,89,0,110,2, - 88,0,124,23,160,20,100,32,116,21,161,2,125,23,116,22, - 160,23,124,0,124,23,161,2,125,24,124,24,124,14,124,18, - 124,4,124,22,124,15,124,16,124,17,102,8,125,25,124,25, - 124,11,124,23,60,0,124,12,100,33,55,0,125,12,144,2, - 113,120,87,0,53,0,81,0,82,0,88,0,116,24,160,25, - 100,34,124,12,124,0,161,3,1,0,124,11,83,0,41,35, - 78,218,2,114,98,122,21,99,97,110,39,116,32,111,112,101, - 110,32,90,105,112,32,102,105,108,101,58,32,114,12,0,0, - 0,114,86,0,0,0,250,21,99,97,110,39,116,32,114,101, - 97,100,32,90,105,112,32,102,105,108,101,58,32,233,4,0, - 0,0,114,0,0,0,0,122,16,110,111,116,32,97,32,90, - 105,112,32,102,105,108,101,58,32,122,18,99,111,114,114,117, - 112,116,32,90,105,112,32,102,105,108,101,58,32,233,12,0, - 0,0,233,16,0,0,0,233,20,0,0,0,122,28,98,97, - 100,32,99,101,110,116,114,97,108,32,100,105,114,101,99,116, - 111,114,121,32,115,105,122,101,58,32,122,30,98,97,100,32, - 99,101,110,116,114,97,108,32,100,105,114,101,99,116,111,114, - 121,32,111,102,102,115,101,116,58,32,122,38,98,97,100,32, - 99,101,110,116,114,97,108,32,100,105,114,101,99,116,111,114, - 121,32,115,105,122,101,32,111,114,32,111,102,102,115,101,116, - 58,32,233,46,0,0,0,250,27,69,79,70,32,114,101,97, - 100,32,119,104,101,114,101,32,110,111,116,32,101,120,112,101, - 99,116,101,100,115,4,0,0,0,80,75,1,2,233,8,0, - 0,0,233,10,0,0,0,233,14,0,0,0,233,24,0,0, - 0,233,28,0,0,0,233,30,0,0,0,233,32,0,0,0, - 233,34,0,0,0,233,42,0,0,0,122,25,98,97,100,32, - 108,111,99,97,108,32,104,101,97,100,101,114,32,111,102,102, - 115,101,116,58,32,105,0,8,0,0,218,5,97,115,99,105, - 105,90,6,108,97,116,105,110,49,250,1,47,114,5,0,0, - 0,122,33,122,105,112,105,109,112,111,114,116,58,32,102,111, - 117,110,100,32,123,125,32,110,97,109,101,115,32,105,110,32, - 123,33,114,125,41,26,218,3,95,105,111,218,4,111,112,101, - 110,114,22,0,0,0,114,3,0,0,0,218,4,115,101,101, - 107,218,20,69,78,68,95,67,69,78,84,82,65,76,95,68, - 73,82,95,83,73,90,69,90,4,116,101,108,108,218,4,114, - 101,97,100,114,51,0,0,0,218,18,83,84,82,73,78,71, - 95,69,78,68,95,65,82,67,72,73,86,69,218,3,109,97, - 120,218,15,77,65,88,95,67,79,77,77,69,78,84,95,76, - 69,78,218,5,114,102,105,110,100,114,2,0,0,0,218,8, - 69,79,70,69,114,114,111,114,114,1,0,0,0,114,62,0, - 0,0,218,18,85,110,105,99,111,100,101,68,101,99,111,100, - 101,69,114,114,111,114,218,9,116,114,97,110,115,108,97,116, - 101,218,11,99,112,52,51,55,95,116,97,98,108,101,114,19, - 0,0,0,114,20,0,0,0,114,21,0,0,0,114,30,0, - 0,0,114,76,0,0,0,114,77,0,0,0,41,26,114,29, - 0,0,0,218,2,102,112,90,15,104,101,97,100,101,114,95, - 112,111,115,105,116,105,111,110,218,6,98,117,102,102,101,114, - 218,9,102,105,108,101,95,115,105,122,101,90,17,109,97,120, - 95,99,111,109,109,101,110,116,95,115,116,97,114,116,218,4, - 100,97,116,97,90,3,112,111,115,218,11,104,101,97,100,101, - 114,95,115,105,122,101,90,13,104,101,97,100,101,114,95,111, - 102,102,115,101,116,90,10,97,114,99,95,111,102,102,115,101, - 116,114,33,0,0,0,218,5,99,111,117,110,116,218,5,102, - 108,97,103,115,218,8,99,111,109,112,114,101,115,115,218,4, - 116,105,109,101,218,4,100,97,116,101,218,3,99,114,99,218, - 9,100,97,116,97,95,115,105,122,101,218,9,110,97,109,101, - 95,115,105,122,101,218,10,101,120,116,114,97,95,115,105,122, - 101,90,12,99,111,109,109,101,110,116,95,115,105,122,101,218, - 11,102,105,108,101,95,111,102,102,115,101,116,114,59,0,0, - 0,114,13,0,0,0,218,1,116,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,114,27,0,0,0,96,1,0, - 0,115,212,0,0,0,0,1,2,1,16,1,14,1,24,2, - 8,1,2,1,14,1,8,1,14,1,14,1,24,1,12,1, - 18,1,18,3,2,1,12,1,12,1,14,1,10,1,2,255, - 12,2,8,1,2,255,2,1,2,255,4,2,2,1,10,1, - 12,1,16,1,10,1,2,255,12,2,10,1,10,1,10,1, - 2,255,6,2,16,1,14,1,10,1,2,255,6,2,16,2, - 16,1,16,1,10,1,18,1,10,1,18,1,8,1,8,1, - 10,1,18,2,4,2,4,1,2,1,14,1,16,1,24,2, - 10,1,14,1,8,2,18,1,4,1,14,1,8,1,16,1, - 16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1, - 16,1,16,1,12,1,10,1,18,1,8,2,2,1,14,1, - 16,1,24,1,14,1,18,4,2,1,28,1,22,1,16,1, - 24,2,10,2,10,3,2,1,14,1,16,1,22,2,12,1, - 12,1,20,1,8,1,22,1,14,1,114,27,0,0,0,117, - 190,1,0,0,0,1,2,3,4,5,6,7,8,9,10,11, - 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, - 28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43, - 44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59, - 60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75, - 76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91, - 92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107, - 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123, - 124,125,126,127,195,135,195,188,195,169,195,162,195,164,195,160, - 195,165,195,167,195,170,195,171,195,168,195,175,195,174,195,172, - 195,132,195,133,195,137,195,166,195,134,195,180,195,182,195,178, - 195,187,195,185,195,191,195,150,195,156,194,162,194,163,194,165, - 226,130,167,198,146,195,161,195,173,195,179,195,186,195,177,195, - 145,194,170,194,186,194,191,226,140,144,194,172,194,189,194,188, - 194,161,194,171,194,187,226,150,145,226,150,146,226,150,147,226, - 148,130,226,148,164,226,149,161,226,149,162,226,149,150,226,149, - 149,226,149,163,226,149,145,226,149,151,226,149,157,226,149,156, - 226,149,155,226,148,144,226,148,148,226,148,180,226,148,172,226, - 148,156,226,148,128,226,148,188,226,149,158,226,149,159,226,149, - 154,226,149,148,226,149,169,226,149,166,226,149,160,226,149,144, - 226,149,172,226,149,167,226,149,168,226,149,164,226,149,165,226, - 149,153,226,149,152,226,149,146,226,149,147,226,149,171,226,149, - 170,226,148,152,226,148,140,226,150,136,226,150,132,226,150,140, - 226,150,144,226,150,128,206,177,195,159,206,147,207,128,206,163, - 207,131,194,181,207,132,206,166,206,152,206,169,206,180,226,136, - 158,207,134,206,181,226,136,169,226,137,161,194,177,226,137,165, - 226,137,164,226,140,160,226,140,161,195,183,226,137,136,194,176, - 226,136,153,194,183,226,136,154,226,129,191,194,178,226,150,160, - 194,160,99,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,8,0,0,0,67,0,0,0,115,108,0,0,0, - 116,0,114,22,116,1,160,2,100,1,161,1,1,0,116,3, - 100,2,131,1,130,1,100,3,97,0,122,60,122,16,100,4, - 100,5,108,4,109,5,125,0,1,0,87,0,110,38,4,0, - 116,6,107,10,114,82,1,0,1,0,1,0,116,1,160,2, - 100,1,161,1,1,0,116,3,100,2,131,1,130,1,89,0, - 110,2,88,0,87,0,53,0,100,6,97,0,88,0,116,1, - 160,2,100,7,161,1,1,0,124,0,83,0,41,8,78,122, - 27,122,105,112,105,109,112,111,114,116,58,32,122,108,105,98, - 32,85,78,65,86,65,73,76,65,66,76,69,250,41,99,97, - 110,39,116,32,100,101,99,111,109,112,114,101,115,115,32,100, - 97,116,97,59,32,122,108,105,98,32,110,111,116,32,97,118, - 97,105,108,97,98,108,101,84,114,0,0,0,0,169,1,218, - 10,100,101,99,111,109,112,114,101,115,115,70,122,25,122,105, - 112,105,109,112,111,114,116,58,32,122,108,105,98,32,97,118, - 97,105,108,97,98,108,101,41,7,218,15,95,105,109,112,111, - 114,116,105,110,103,95,122,108,105,98,114,76,0,0,0,114, - 77,0,0,0,114,3,0,0,0,90,4,122,108,105,98,114, - 142,0,0,0,218,9,69,120,99,101,112,116,105,111,110,114, - 141,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, - 0,0,0,218,20,95,103,101,116,95,100,101,99,111,109,112, - 114,101,115,115,95,102,117,110,99,254,1,0,0,115,24,0, - 0,0,0,2,4,3,10,1,8,2,4,1,4,1,16,1, - 14,1,10,1,18,2,6,2,10,1,114,145,0,0,0,99, - 2,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0, - 9,0,0,0,67,0,0,0,115,130,1,0,0,124,1,92, - 8,125,2,125,3,125,4,125,5,125,6,125,7,125,8,125, - 9,124,4,100,1,107,0,114,36,116,0,100,2,131,1,130, - 1,116,1,160,2,124,0,100,3,161,2,144,1,143,8,125, - 10,122,14,124,10,160,3,124,6,161,1,1,0,87,0,110, - 38,4,0,116,4,107,10,114,104,1,0,1,0,1,0,116, - 0,100,4,124,0,155,2,157,2,124,0,100,5,141,2,130, - 1,89,0,110,2,88,0,124,10,160,5,100,6,161,1,125, - 11,116,6,124,11,131,1,100,6,107,3,114,136,116,7,100, - 7,131,1,130,1,124,11,100,0,100,8,133,2,25,0,100, - 9,107,3,114,170,116,0,100,10,124,0,155,2,157,2,124, - 0,100,5,141,2,130,1,116,8,124,11,100,11,100,12,133, - 2,25,0,131,1,125,12,116,8,124,11,100,12,100,6,133, - 2,25,0,131,1,125,13,100,6,124,12,23,0,124,13,23, - 0,125,14,124,6,124,14,55,0,125,6,122,14,124,10,160, - 3,124,6,161,1,1,0,87,0,110,40,4,0,116,4,107, - 10,144,1,114,20,1,0,1,0,1,0,116,0,100,4,124, - 0,155,2,157,2,124,0,100,5,141,2,130,1,89,0,110, - 2,88,0,124,10,160,5,124,4,161,1,125,15,116,6,124, - 15,131,1,124,4,107,3,144,1,114,54,116,4,100,13,131, - 1,130,1,87,0,53,0,81,0,82,0,88,0,124,3,100, - 1,107,2,144,1,114,78,124,15,83,0,122,10,116,9,131, - 0,125,16,87,0,110,30,4,0,116,10,107,10,144,1,114, - 118,1,0,1,0,1,0,116,0,100,14,131,1,130,1,89, - 0,110,2,88,0,124,16,124,15,100,15,131,2,83,0,41, - 16,78,114,0,0,0,0,122,18,110,101,103,97,116,105,118, - 101,32,100,97,116,97,32,115,105,122,101,114,92,0,0,0, - 114,93,0,0,0,114,12,0,0,0,114,105,0,0,0,114, - 99,0,0,0,114,94,0,0,0,115,4,0,0,0,80,75, - 3,4,122,23,98,97,100,32,108,111,99,97,108,32,102,105, - 108,101,32,104,101,97,100,101,114,58,32,233,26,0,0,0, - 114,104,0,0,0,122,26,122,105,112,105,109,112,111,114,116, - 58,32,99,97,110,39,116,32,114,101,97,100,32,100,97,116, - 97,114,140,0,0,0,105,241,255,255,255,41,11,114,3,0, - 0,0,114,111,0,0,0,114,112,0,0,0,114,113,0,0, - 0,114,22,0,0,0,114,115,0,0,0,114,51,0,0,0, - 114,120,0,0,0,114,1,0,0,0,114,145,0,0,0,114, - 144,0,0,0,41,17,114,29,0,0,0,114,54,0,0,0, - 90,8,100,97,116,97,112,97,116,104,114,131,0,0,0,114, - 135,0,0,0,114,126,0,0,0,114,138,0,0,0,114,132, - 0,0,0,114,133,0,0,0,114,134,0,0,0,114,124,0, - 0,0,114,125,0,0,0,114,136,0,0,0,114,137,0,0, - 0,114,128,0,0,0,90,8,114,97,119,95,100,97,116,97, - 114,142,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,114,52,0,0,0,19,2,0,0,115,62,0, - 0,0,0,1,20,1,8,1,8,2,16,2,2,1,14,1, - 14,1,24,1,10,1,12,1,8,2,16,2,18,2,16,1, - 16,1,12,1,8,1,2,1,14,1,16,1,24,1,10,1, - 14,1,18,2,10,2,4,3,2,1,10,1,16,1,14,1, - 114,52,0,0,0,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,16, - 0,0,0,116,0,124,0,124,1,24,0,131,1,100,1,107, - 1,83,0,41,2,78,114,5,0,0,0,41,1,218,3,97, - 98,115,41,2,90,2,116,49,90,2,116,50,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,9,95,101,113, - 95,109,116,105,109,101,65,2,0,0,115,2,0,0,0,0, - 2,114,148,0,0,0,99,5,0,0,0,0,0,0,0,0, - 0,0,0,14,0,0,0,8,0,0,0,67,0,0,0,115, - 68,1,0,0,124,3,124,2,100,1,156,2,125,5,122,18, - 116,0,160,1,124,4,124,3,124,5,161,3,125,6,87,0, - 110,26,4,0,116,2,107,10,114,54,1,0,1,0,1,0, - 89,0,100,0,83,0,89,0,110,2,88,0,124,6,100,2, - 64,0,100,3,107,3,125,7,124,7,114,190,124,6,100,4, - 64,0,100,3,107,3,125,8,116,3,106,4,100,5,107,3, - 114,188,124,8,115,108,116,3,106,4,100,6,107,2,114,188, - 116,5,124,0,124,2,131,2,125,9,124,9,100,0,107,9, - 114,188,116,3,160,6,116,0,106,7,124,9,161,2,125,10, - 122,20,116,8,160,9,124,4,124,10,124,3,124,5,161,4, - 1,0,87,0,110,26,4,0,116,2,107,10,114,186,1,0, - 1,0,1,0,89,0,100,0,83,0,89,0,110,2,88,0, - 110,84,116,10,124,0,124,2,131,2,92,2,125,11,125,12, - 124,11,144,1,114,18,116,11,116,12,124,4,100,7,100,8, - 133,2,25,0,131,1,124,11,131,2,114,254,116,12,124,4, - 100,8,100,9,133,2,25,0,131,1,124,12,107,3,144,1, - 114,18,116,13,160,14,100,10,124,3,155,2,157,2,161,1, - 1,0,100,0,83,0,116,15,160,16,124,4,100,9,100,0, - 133,2,25,0,161,1,125,13,116,17,124,13,116,18,131,2, - 144,1,115,64,116,19,100,11,124,1,155,2,100,12,157,3, - 131,1,130,1,124,13,83,0,41,13,78,41,2,114,59,0, - 0,0,114,13,0,0,0,114,5,0,0,0,114,0,0,0, - 0,114,86,0,0,0,90,5,110,101,118,101,114,90,6,97, - 108,119,97,121,115,114,100,0,0,0,114,95,0,0,0,114, - 96,0,0,0,122,22,98,121,116,101,99,111,100,101,32,105, - 115,32,115,116,97,108,101,32,102,111,114,32,122,16,99,111, - 109,112,105,108,101,100,32,109,111,100,117,108,101,32,122,21, - 32,105,115,32,110,111,116,32,97,32,99,111,100,101,32,111, - 98,106,101,99,116,41,20,114,21,0,0,0,90,13,95,99, - 108,97,115,115,105,102,121,95,112,121,99,114,75,0,0,0, - 218,4,95,105,109,112,90,21,99,104,101,99,107,95,104,97, - 115,104,95,98,97,115,101,100,95,112,121,99,115,218,15,95, - 103,101,116,95,112,121,99,95,115,111,117,114,99,101,218,11, - 115,111,117,114,99,101,95,104,97,115,104,90,17,95,82,65, - 87,95,77,65,71,73,67,95,78,85,77,66,69,82,90,18, - 95,98,111,111,115,116,114,97,112,95,101,120,116,101,114,110, - 97,108,90,18,95,118,97,108,105,100,97,116,101,95,104,97, - 115,104,95,112,121,99,218,29,95,103,101,116,95,109,116,105, - 109,101,95,97,110,100,95,115,105,122,101,95,111,102,95,115, - 111,117,114,99,101,114,148,0,0,0,114,2,0,0,0,114, - 76,0,0,0,114,77,0,0,0,218,7,109,97,114,115,104, - 97,108,90,5,108,111,97,100,115,114,15,0,0,0,218,10, - 95,99,111,100,101,95,116,121,112,101,218,9,84,121,112,101, - 69,114,114,111,114,41,14,114,32,0,0,0,114,53,0,0, - 0,114,63,0,0,0,114,38,0,0,0,114,127,0,0,0, - 90,11,101,120,99,95,100,101,116,97,105,108,115,114,130,0, - 0,0,90,10,104,97,115,104,95,98,97,115,101,100,90,12, - 99,104,101,99,107,95,115,111,117,114,99,101,90,12,115,111, - 117,114,99,101,95,98,121,116,101,115,114,151,0,0,0,90, - 12,115,111,117,114,99,101,95,109,116,105,109,101,90,11,115, - 111,117,114,99,101,95,115,105,122,101,114,46,0,0,0,114, - 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,15, - 95,117,110,109,97,114,115,104,97,108,95,99,111,100,101,75, - 2,0,0,115,88,0,0,0,0,2,2,1,2,254,6,5, - 2,1,18,1,14,1,12,2,12,1,4,1,12,1,10,1, - 2,255,2,1,8,255,2,2,10,1,8,1,4,1,4,1, - 2,254,4,5,2,1,4,1,2,0,2,0,2,0,2,255, - 8,2,14,1,14,3,8,255,6,3,6,3,22,1,18,255, - 4,2,4,1,8,255,4,2,4,2,18,1,12,1,16,1, - 114,156,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,28, - 0,0,0,124,0,160,0,100,1,100,2,161,2,125,0,124, - 0,160,0,100,3,100,2,161,2,125,0,124,0,83,0,41, - 4,78,115,2,0,0,0,13,10,243,1,0,0,0,10,243, - 1,0,0,0,13,41,1,114,19,0,0,0,41,1,218,6, - 115,111,117,114,99,101,114,9,0,0,0,114,9,0,0,0, - 114,10,0,0,0,218,23,95,110,111,114,109,97,108,105,122, - 101,95,108,105,110,101,95,101,110,100,105,110,103,115,126,2, - 0,0,115,6,0,0,0,0,1,12,1,12,1,114,160,0, - 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,6,0,0,0,67,0,0,0,115,24,0,0,0, - 116,0,124,1,131,1,125,1,116,1,124,1,124,0,100,1, - 100,2,100,3,141,4,83,0,41,4,78,114,74,0,0,0, - 84,41,1,90,12,100,111,110,116,95,105,110,104,101,114,105, - 116,41,2,114,160,0,0,0,218,7,99,111,109,112,105,108, - 101,41,2,114,53,0,0,0,114,159,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,218,15,95,99, - 111,109,112,105,108,101,95,115,111,117,114,99,101,133,2,0, - 0,115,4,0,0,0,0,1,8,1,114,162,0,0,0,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 11,0,0,0,67,0,0,0,115,68,0,0,0,116,0,160, - 1,124,0,100,1,63,0,100,2,23,0,124,0,100,3,63, - 0,100,4,64,0,124,0,100,5,64,0,124,1,100,6,63, - 0,124,1,100,3,63,0,100,7,64,0,124,1,100,5,64, - 0,100,8,20,0,100,9,100,9,100,9,102,9,161,1,83, - 0,41,10,78,233,9,0,0,0,105,188,7,0,0,233,5, - 0,0,0,233,15,0,0,0,233,31,0,0,0,233,11,0, - 0,0,233,63,0,0,0,114,86,0,0,0,114,14,0,0, - 0,41,2,114,132,0,0,0,90,6,109,107,116,105,109,101, - 41,2,218,1,100,114,139,0,0,0,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,218,14,95,112,97,114,115, - 101,95,100,111,115,116,105,109,101,139,2,0,0,115,22,0, - 0,0,0,1,4,1,10,1,10,1,6,1,6,1,10,1, - 10,1,2,0,2,0,2,249,114,170,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,6,0,0,0,10,0, - 0,0,67,0,0,0,115,116,0,0,0,122,82,124,1,100, - 1,100,0,133,2,25,0,100,2,107,6,115,22,116,0,130, - 1,124,1,100,0,100,1,133,2,25,0,125,1,124,0,106, - 1,124,1,25,0,125,2,124,2,100,3,25,0,125,3,124, - 2,100,4,25,0,125,4,124,2,100,5,25,0,125,5,116, - 2,124,4,124,3,131,2,124,5,102,2,87,0,83,0,4, - 0,116,3,116,4,116,5,102,3,107,10,114,110,1,0,1, - 0,1,0,89,0,100,6,83,0,88,0,100,0,83,0,41, - 7,78,114,14,0,0,0,169,2,218,1,99,218,1,111,114, - 164,0,0,0,233,6,0,0,0,233,3,0,0,0,41,2, - 114,0,0,0,0,114,0,0,0,0,41,6,218,14,65,115, - 115,101,114,116,105,111,110,69,114,114,111,114,114,28,0,0, - 0,114,170,0,0,0,114,26,0,0,0,218,10,73,110,100, - 101,120,69,114,114,111,114,114,155,0,0,0,41,6,114,32, - 0,0,0,114,13,0,0,0,114,54,0,0,0,114,132,0, - 0,0,114,133,0,0,0,90,17,117,110,99,111,109,112,114, - 101,115,115,101,100,95,115,105,122,101,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,114,152,0,0,0,152,2, - 0,0,115,20,0,0,0,0,1,2,2,20,1,12,1,10, - 3,8,1,8,1,8,1,16,1,20,1,114,152,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,8,0,0,0,67,0,0,0,115,86,0,0,0,124,1, - 100,1,100,0,133,2,25,0,100,2,107,6,115,20,116,0, - 130,1,124,1,100,0,100,1,133,2,25,0,125,1,122,14, - 124,0,106,1,124,1,25,0,125,2,87,0,110,22,4,0, - 116,2,107,10,114,68,1,0,1,0,1,0,89,0,100,0, - 83,0,88,0,116,3,124,0,106,4,124,2,131,2,83,0, - 100,0,83,0,41,3,78,114,14,0,0,0,114,171,0,0, - 0,41,5,114,176,0,0,0,114,28,0,0,0,114,26,0, - 0,0,114,52,0,0,0,114,29,0,0,0,41,3,114,32, - 0,0,0,114,13,0,0,0,114,54,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,114,150,0,0, - 0,171,2,0,0,115,14,0,0,0,0,2,20,1,12,2, - 2,1,14,1,14,1,8,2,114,150,0,0,0,99,2,0, - 0,0,0,0,0,0,0,0,0,0,11,0,0,0,9,0, - 0,0,67,0,0,0,115,198,0,0,0,116,0,124,0,124, - 1,131,2,125,2,116,1,68,0,93,160,92,3,125,3,125, - 4,125,5,124,2,124,3,23,0,125,6,116,2,106,3,100, - 1,124,0,106,4,116,5,124,6,100,2,100,3,141,5,1, - 0,122,14,124,0,106,6,124,6,25,0,125,7,87,0,110, - 20,4,0,116,7,107,10,114,88,1,0,1,0,1,0,89, - 0,113,14,88,0,124,7,100,4,25,0,125,8,116,8,124, - 0,106,4,124,7,131,2,125,9,124,4,114,132,116,9,124, - 0,124,8,124,6,124,1,124,9,131,5,125,10,110,10,116, - 10,124,8,124,9,131,2,125,10,124,10,100,0,107,8,114, - 152,113,14,124,7,100,4,25,0,125,8,124,10,124,5,124, - 8,102,3,2,0,1,0,83,0,113,14,116,11,100,5,124, - 1,155,2,157,2,124,1,100,6,141,2,130,1,100,0,83, - 0,41,7,78,122,13,116,114,121,105,110,103,32,123,125,123, - 125,123,125,114,86,0,0,0,41,1,90,9,118,101,114,98, - 111,115,105,116,121,114,0,0,0,0,114,57,0,0,0,114, - 58,0,0,0,41,12,114,36,0,0,0,114,89,0,0,0, - 114,76,0,0,0,114,77,0,0,0,114,29,0,0,0,114, - 20,0,0,0,114,28,0,0,0,114,26,0,0,0,114,52, - 0,0,0,114,156,0,0,0,114,162,0,0,0,114,3,0, - 0,0,41,11,114,32,0,0,0,114,38,0,0,0,114,13, - 0,0,0,114,90,0,0,0,114,91,0,0,0,114,47,0, - 0,0,114,63,0,0,0,114,54,0,0,0,114,40,0,0, - 0,114,127,0,0,0,114,46,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,114,44,0,0,0,186, - 2,0,0,115,36,0,0,0,0,1,10,1,14,1,8,1, - 22,1,2,1,14,1,14,1,6,2,8,1,12,1,4,1, - 18,2,10,1,8,3,2,1,8,1,16,2,114,44,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,64,0,0,0,115,60,0,0,0,101, - 0,90,1,100,0,90,2,100,1,90,3,100,2,90,4,100, - 3,100,4,132,0,90,5,100,5,100,6,132,0,90,6,100, - 7,100,8,132,0,90,7,100,9,100,10,132,0,90,8,100, - 11,100,12,132,0,90,9,100,13,83,0,41,14,114,80,0, - 0,0,122,165,80,114,105,118,97,116,101,32,99,108,97,115, - 115,32,117,115,101,100,32,116,111,32,115,117,112,112,111,114, - 116,32,90,105,112,73,109,112,111,114,116,46,103,101,116,95, - 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,40, - 41,46,10,10,32,32,32,32,84,104,105,115,32,99,108,97, - 115,115,32,105,115,32,97,108,108,111,119,101,100,32,116,111, - 32,114,101,102,101,114,101,110,99,101,32,97,108,108,32,116, - 104,101,32,105,110,110,97,114,100,115,32,97,110,100,32,112, - 114,105,118,97,116,101,32,112,97,114,116,115,32,111,102,10, - 32,32,32,32,116,104,101,32,122,105,112,105,109,112,111,114, - 116,101,114,46,10,32,32,32,32,70,99,3,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,67, - 0,0,0,115,16,0,0,0,124,1,124,0,95,0,124,2, - 124,0,95,1,100,0,83,0,114,88,0,0,0,41,2,114, - 4,0,0,0,114,38,0,0,0,41,3,114,32,0,0,0, - 114,4,0,0,0,114,38,0,0,0,114,9,0,0,0,114, - 9,0,0,0,114,10,0,0,0,114,34,0,0,0,220,2, - 0,0,115,4,0,0,0,0,1,6,1,122,33,95,90,105, - 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, - 101,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, - 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,8, - 0,0,0,67,0,0,0,115,92,0,0,0,124,0,106,0, - 160,1,100,1,100,2,161,2,125,2,124,2,155,0,100,2, - 124,1,155,0,157,3,125,3,100,3,100,4,108,2,109,3, - 125,4,1,0,122,18,124,4,124,0,106,4,160,5,124,3, - 161,1,131,1,87,0,83,0,4,0,116,6,107,10,114,86, - 1,0,1,0,1,0,116,7,124,3,131,1,130,1,89,0, - 110,2,88,0,100,0,83,0,41,5,78,114,85,0,0,0, - 114,110,0,0,0,114,0,0,0,0,41,1,218,7,66,121, - 116,101,115,73,79,41,8,114,38,0,0,0,114,19,0,0, - 0,90,2,105,111,114,178,0,0,0,114,4,0,0,0,114, - 55,0,0,0,114,22,0,0,0,218,17,70,105,108,101,78, - 111,116,70,111,117,110,100,69,114,114,111,114,41,5,114,32, - 0,0,0,218,8,114,101,115,111,117,114,99,101,218,16,102, - 117,108,108,110,97,109,101,95,97,115,95,112,97,116,104,114, - 13,0,0,0,114,178,0,0,0,114,9,0,0,0,114,9, - 0,0,0,114,10,0,0,0,218,13,111,112,101,110,95,114, - 101,115,111,117,114,99,101,224,2,0,0,115,14,0,0,0, - 0,1,14,1,14,1,12,1,2,1,18,1,14,1,122,38, - 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, - 99,101,82,101,97,100,101,114,46,111,112,101,110,95,114,101, - 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 8,0,0,0,116,0,130,1,100,0,83,0,114,88,0,0, - 0,41,1,114,179,0,0,0,41,2,114,32,0,0,0,114, - 180,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, - 0,0,0,218,13,114,101,115,111,117,114,99,101,95,112,97, - 116,104,233,2,0,0,115,2,0,0,0,0,4,122,38,95, - 90,105,112,73,109,112,111,114,116,82,101,115,111,117,114,99, - 101,82,101,97,100,101,114,46,114,101,115,111,117,114,99,101, - 95,112,97,116,104,99,2,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,72, - 0,0,0,124,0,106,0,160,1,100,1,100,2,161,2,125, - 2,124,2,155,0,100,2,124,1,155,0,157,3,125,3,122, - 16,124,0,106,2,160,3,124,3,161,1,1,0,87,0,110, - 22,4,0,116,4,107,10,114,66,1,0,1,0,1,0,89, - 0,100,3,83,0,88,0,100,4,83,0,41,5,78,114,85, - 0,0,0,114,110,0,0,0,70,84,41,5,114,38,0,0, - 0,114,19,0,0,0,114,4,0,0,0,114,55,0,0,0, - 114,22,0,0,0,41,4,114,32,0,0,0,114,59,0,0, - 0,114,181,0,0,0,114,13,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,10,0,0,0,218,11,105,115,95,114, - 101,115,111,117,114,99,101,239,2,0,0,115,14,0,0,0, - 0,3,14,1,14,1,2,1,16,1,14,1,8,1,122,36, - 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, - 99,101,82,101,97,100,101,114,46,105,115,95,114,101,115,111, - 117,114,99,101,99,1,0,0,0,0,0,0,0,0,0,0, - 0,9,0,0,0,9,0,0,0,99,0,0,0,115,186,0, - 0,0,100,1,100,2,108,0,109,1,125,1,1,0,124,1, - 124,0,106,2,160,3,124,0,106,4,161,1,131,1,125,2, - 124,2,160,5,124,0,106,2,106,6,161,1,125,3,124,3, - 106,7,100,3,107,2,115,58,116,8,130,1,124,3,106,9, - 125,4,116,10,131,0,125,5,124,0,106,2,106,11,68,0, - 93,102,125,6,122,18,124,1,124,6,131,1,160,5,124,4, - 161,1,125,7,87,0,110,24,4,0,116,12,107,10,114,124, - 1,0,1,0,1,0,89,0,113,78,89,0,110,2,88,0, - 124,7,106,9,106,7,125,8,116,13,124,8,131,1,100,1, - 107,2,114,156,124,7,106,7,86,0,1,0,113,78,124,8, - 124,5,107,7,114,78,124,5,160,14,124,8,161,1,1,0, - 124,8,86,0,1,0,113,78,100,0,83,0,41,4,78,114, - 0,0,0,0,41,1,218,4,80,97,116,104,114,60,0,0, - 0,41,15,90,7,112,97,116,104,108,105,98,114,185,0,0, - 0,114,4,0,0,0,114,56,0,0,0,114,38,0,0,0, - 90,11,114,101,108,97,116,105,118,101,95,116,111,114,29,0, - 0,0,114,59,0,0,0,114,176,0,0,0,90,6,112,97, - 114,101,110,116,218,3,115,101,116,114,28,0,0,0,114,23, - 0,0,0,114,51,0,0,0,218,3,97,100,100,41,9,114, - 32,0,0,0,114,185,0,0,0,90,13,102,117,108,108,110, - 97,109,101,95,112,97,116,104,90,13,114,101,108,97,116,105, - 118,101,95,112,97,116,104,90,12,112,97,99,107,97,103,101, - 95,112,97,116,104,90,12,115,117,98,100,105,114,115,95,115, - 101,101,110,218,8,102,105,108,101,110,97,109,101,90,8,114, - 101,108,97,116,105,118,101,90,11,112,97,114,101,110,116,95, - 110,97,109,101,114,9,0,0,0,114,9,0,0,0,114,10, - 0,0,0,218,8,99,111,110,116,101,110,116,115,250,2,0, - 0,115,34,0,0,0,0,8,12,1,18,1,14,3,14,1, - 6,1,6,1,12,1,2,1,18,1,14,1,10,5,8,1, - 12,1,10,1,8,1,10,1,122,33,95,90,105,112,73,109, - 112,111,114,116,82,101,115,111,117,114,99,101,82,101,97,100, - 101,114,46,99,111,110,116,101,110,116,115,78,41,10,114,6, - 0,0,0,114,7,0,0,0,114,8,0,0,0,114,84,0, - 0,0,114,81,0,0,0,114,34,0,0,0,114,182,0,0, - 0,114,183,0,0,0,114,184,0,0,0,114,189,0,0,0, - 114,9,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,114,80,0,0,0,212,2,0,0,115,14,0, - 0,0,8,1,4,5,4,2,8,4,8,9,8,6,8,11, - 114,80,0,0,0,41,45,114,84,0,0,0,90,26,95,102, - 114,111,122,101,110,95,105,109,112,111,114,116,108,105,98,95, - 101,120,116,101,114,110,97,108,114,21,0,0,0,114,1,0, - 0,0,114,2,0,0,0,90,17,95,102,114,111,122,101,110, - 95,105,109,112,111,114,116,108,105,98,114,76,0,0,0,114, - 149,0,0,0,114,111,0,0,0,114,153,0,0,0,114,67, - 0,0,0,114,132,0,0,0,90,7,95,95,97,108,108,95, - 95,114,20,0,0,0,90,15,112,97,116,104,95,115,101,112, - 97,114,97,116,111,114,115,114,18,0,0,0,114,75,0,0, - 0,114,3,0,0,0,114,25,0,0,0,218,4,116,121,112, - 101,114,70,0,0,0,114,114,0,0,0,114,116,0,0,0, - 114,118,0,0,0,114,4,0,0,0,114,89,0,0,0,114, - 36,0,0,0,114,37,0,0,0,114,35,0,0,0,114,27, - 0,0,0,114,123,0,0,0,114,143,0,0,0,114,145,0, - 0,0,114,52,0,0,0,114,148,0,0,0,114,156,0,0, - 0,218,8,95,95,99,111,100,101,95,95,114,154,0,0,0, - 114,160,0,0,0,114,162,0,0,0,114,170,0,0,0,114, - 152,0,0,0,114,150,0,0,0,114,44,0,0,0,114,80, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,10,0,0,0,218,8,60,109,111,100,117,108,101, - 62,1,0,0,0,115,88,0,0,0,4,16,8,1,16,1, - 8,1,8,1,8,1,8,1,8,1,8,2,8,3,6,1, - 14,3,16,4,4,2,8,2,4,1,4,1,4,2,14,127, - 0,127,0,1,12,1,12,1,2,1,2,252,4,9,8,4, - 8,9,8,31,8,126,2,254,2,29,4,5,8,21,8,46, - 8,10,8,46,10,5,8,7,8,6,8,13,8,19,8,15, - 8,26, + 0,0,0,9,0,0,0,67,0,0,0,115,252,4,0,0, + 122,14,116,0,160,1,124,0,161,1,125,1,87,0,110,38, + 4,0,116,2,107,10,114,52,1,0,1,0,1,0,116,3, + 100,1,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 89,0,110,2,88,0,124,1,144,4,143,168,1,0,122,36, + 124,1,160,4,116,5,11,0,100,3,161,2,1,0,124,1, + 160,6,161,0,125,2,124,1,160,7,116,5,161,1,125,3, + 87,0,110,38,4,0,116,2,107,10,114,136,1,0,1,0, + 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, + 141,2,130,1,89,0,110,2,88,0,116,8,124,3,131,1, + 116,5,107,3,114,168,116,3,100,4,124,0,155,2,157,2, + 124,0,100,2,141,2,130,1,124,3,100,0,100,5,133,2, + 25,0,116,9,107,3,144,1,114,178,122,24,124,1,160,4, + 100,6,100,3,161,2,1,0,124,1,160,6,161,0,125,4, + 87,0,110,38,4,0,116,2,107,10,114,248,1,0,1,0, + 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, + 141,2,130,1,89,0,110,2,88,0,116,10,124,4,116,11, + 24,0,116,5,24,0,100,6,131,2,125,5,122,22,124,1, + 160,4,124,5,161,1,1,0,124,1,160,7,161,0,125,6, + 87,0,110,40,4,0,116,2,107,10,144,1,114,74,1,0, + 1,0,1,0,116,3,100,4,124,0,155,2,157,2,124,0, + 100,2,141,2,130,1,89,0,110,2,88,0,124,6,160,12, + 116,9,161,1,125,7,124,7,100,6,107,0,144,1,114,114, + 116,3,100,7,124,0,155,2,157,2,124,0,100,2,141,2, + 130,1,124,6,124,7,124,7,116,5,23,0,133,2,25,0, + 125,3,116,8,124,3,131,1,116,5,107,3,144,1,114,162, + 116,3,100,8,124,0,155,2,157,2,124,0,100,2,141,2, + 130,1,124,4,116,8,124,6,131,1,24,0,124,7,23,0, + 125,2,116,13,124,3,100,9,100,10,133,2,25,0,131,1, + 125,8,116,13,124,3,100,10,100,11,133,2,25,0,131,1, + 125,9,124,2,124,8,107,0,144,1,114,238,116,3,100,12, + 124,0,155,2,157,2,124,0,100,2,141,2,130,1,124,2, + 124,9,107,0,144,2,114,10,116,3,100,13,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,124,2,124,8,56,0, + 125,2,124,2,124,9,24,0,125,10,124,10,100,6,107,0, + 144,2,114,54,116,3,100,14,124,0,155,2,157,2,124,0, + 100,2,141,2,130,1,105,0,125,11,100,6,125,12,122,14, + 124,1,160,4,124,2,161,1,1,0,87,0,110,40,4,0, + 116,2,107,10,144,2,114,116,1,0,1,0,1,0,116,3, + 100,4,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 89,0,110,2,88,0,124,1,160,7,100,15,161,1,125,3, + 116,8,124,3,131,1,100,5,107,0,144,2,114,150,116,14, + 100,16,131,1,130,1,124,3,100,0,100,5,133,2,25,0, + 100,17,107,3,144,2,114,172,144,4,113,224,116,8,124,3, + 131,1,100,15,107,3,144,2,114,194,116,14,100,16,131,1, + 130,1,116,15,124,3,100,18,100,19,133,2,25,0,131,1, + 125,13,116,15,124,3,100,19,100,9,133,2,25,0,131,1, + 125,14,116,15,124,3,100,9,100,20,133,2,25,0,131,1, + 125,15,116,15,124,3,100,20,100,10,133,2,25,0,131,1, + 125,16,116,13,124,3,100,10,100,11,133,2,25,0,131,1, + 125,17,116,13,124,3,100,11,100,21,133,2,25,0,131,1, + 125,18,116,13,124,3,100,21,100,22,133,2,25,0,131,1, + 125,4,116,15,124,3,100,22,100,23,133,2,25,0,131,1, + 125,19,116,15,124,3,100,23,100,24,133,2,25,0,131,1, + 125,20,116,15,124,3,100,24,100,25,133,2,25,0,131,1, + 125,21,116,13,124,3,100,26,100,15,133,2,25,0,131,1, + 125,22,124,19,124,20,23,0,124,21,23,0,125,8,124,22, + 124,9,107,4,144,3,114,154,116,3,100,27,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,124,22,124,10,55,0, + 125,22,122,14,124,1,160,7,124,19,161,1,125,23,87,0, + 110,40,4,0,116,2,107,10,144,3,114,216,1,0,1,0, + 1,0,116,3,100,4,124,0,155,2,157,2,124,0,100,2, + 141,2,130,1,89,0,110,2,88,0,116,8,124,23,131,1, + 124,19,107,3,144,3,114,250,116,3,100,4,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,122,50,116,8,124,1, + 160,7,124,8,124,19,24,0,161,1,131,1,124,8,124,19, + 24,0,107,3,144,4,114,42,116,3,100,4,124,0,155,2, + 157,2,124,0,100,2,141,2,130,1,87,0,110,40,4,0, + 116,2,107,10,144,4,114,84,1,0,1,0,1,0,116,3, + 100,4,124,0,155,2,157,2,124,0,100,2,141,2,130,1, + 89,0,110,2,88,0,124,13,100,28,64,0,144,4,114,106, + 124,23,160,16,161,0,125,23,110,54,122,14,124,23,160,16, + 100,29,161,1,125,23,87,0,110,38,4,0,116,17,107,10, + 144,4,114,158,1,0,1,0,1,0,124,23,160,16,100,30, + 161,1,160,18,116,19,161,1,125,23,89,0,110,2,88,0, + 124,23,160,20,100,31,116,21,161,2,125,23,116,22,160,23, + 124,0,124,23,161,2,125,24,124,24,124,14,124,18,124,4, + 124,22,124,15,124,16,124,17,102,8,125,25,124,25,124,11, + 124,23,60,0,124,12,100,32,55,0,125,12,144,2,113,118, + 87,0,53,0,81,0,82,0,88,0,116,24,160,25,100,33, + 124,12,124,0,161,3,1,0,124,11,83,0,41,34,78,122, + 21,99,97,110,39,116,32,111,112,101,110,32,90,105,112,32, + 102,105,108,101,58,32,114,12,0,0,0,114,86,0,0,0, + 250,21,99,97,110,39,116,32,114,101,97,100,32,90,105,112, + 32,102,105,108,101,58,32,233,4,0,0,0,114,0,0,0, + 0,122,16,110,111,116,32,97,32,90,105,112,32,102,105,108, + 101,58,32,122,18,99,111,114,114,117,112,116,32,90,105,112, + 32,102,105,108,101,58,32,233,12,0,0,0,233,16,0,0, + 0,233,20,0,0,0,122,28,98,97,100,32,99,101,110,116, + 114,97,108,32,100,105,114,101,99,116,111,114,121,32,115,105, + 122,101,58,32,122,30,98,97,100,32,99,101,110,116,114,97, + 108,32,100,105,114,101,99,116,111,114,121,32,111,102,102,115, + 101,116,58,32,122,38,98,97,100,32,99,101,110,116,114,97, + 108,32,100,105,114,101,99,116,111,114,121,32,115,105,122,101, + 32,111,114,32,111,102,102,115,101,116,58,32,233,46,0,0, + 0,250,27,69,79,70,32,114,101,97,100,32,119,104,101,114, + 101,32,110,111,116,32,101,120,112,101,99,116,101,100,115,4, + 0,0,0,80,75,1,2,233,8,0,0,0,233,10,0,0, + 0,233,14,0,0,0,233,24,0,0,0,233,28,0,0,0, + 233,30,0,0,0,233,32,0,0,0,233,34,0,0,0,233, + 42,0,0,0,122,25,98,97,100,32,108,111,99,97,108,32, + 104,101,97,100,101,114,32,111,102,102,115,101,116,58,32,105, + 0,8,0,0,218,5,97,115,99,105,105,90,6,108,97,116, + 105,110,49,250,1,47,114,5,0,0,0,122,33,122,105,112, + 105,109,112,111,114,116,58,32,102,111,117,110,100,32,123,125, + 32,110,97,109,101,115,32,105,110,32,123,33,114,125,41,26, + 218,3,95,105,111,218,9,111,112,101,110,95,99,111,100,101, + 114,22,0,0,0,114,3,0,0,0,218,4,115,101,101,107, + 218,20,69,78,68,95,67,69,78,84,82,65,76,95,68,73, + 82,95,83,73,90,69,90,4,116,101,108,108,218,4,114,101, + 97,100,114,51,0,0,0,218,18,83,84,82,73,78,71,95, + 69,78,68,95,65,82,67,72,73,86,69,218,3,109,97,120, + 218,15,77,65,88,95,67,79,77,77,69,78,84,95,76,69, + 78,218,5,114,102,105,110,100,114,2,0,0,0,218,8,69, + 79,70,69,114,114,111,114,114,1,0,0,0,114,62,0,0, + 0,218,18,85,110,105,99,111,100,101,68,101,99,111,100,101, + 69,114,114,111,114,218,9,116,114,97,110,115,108,97,116,101, + 218,11,99,112,52,51,55,95,116,97,98,108,101,114,19,0, + 0,0,114,20,0,0,0,114,21,0,0,0,114,30,0,0, + 0,114,76,0,0,0,114,77,0,0,0,41,26,114,29,0, + 0,0,218,2,102,112,90,15,104,101,97,100,101,114,95,112, + 111,115,105,116,105,111,110,218,6,98,117,102,102,101,114,218, + 9,102,105,108,101,95,115,105,122,101,90,17,109,97,120,95, + 99,111,109,109,101,110,116,95,115,116,97,114,116,218,4,100, + 97,116,97,90,3,112,111,115,218,11,104,101,97,100,101,114, + 95,115,105,122,101,90,13,104,101,97,100,101,114,95,111,102, + 102,115,101,116,90,10,97,114,99,95,111,102,102,115,101,116, + 114,33,0,0,0,218,5,99,111,117,110,116,218,5,102,108, + 97,103,115,218,8,99,111,109,112,114,101,115,115,218,4,116, + 105,109,101,218,4,100,97,116,101,218,3,99,114,99,218,9, + 100,97,116,97,95,115,105,122,101,218,9,110,97,109,101,95, + 115,105,122,101,218,10,101,120,116,114,97,95,115,105,122,101, + 90,12,99,111,109,109,101,110,116,95,115,105,122,101,218,11, + 102,105,108,101,95,111,102,102,115,101,116,114,59,0,0,0, + 114,13,0,0,0,218,1,116,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,114,27,0,0,0,96,1,0,0, + 115,212,0,0,0,0,1,2,1,14,1,14,1,24,2,8, + 1,2,1,14,1,8,1,14,1,14,1,24,1,12,1,18, + 1,18,3,2,1,12,1,12,1,14,1,10,1,2,255,12, + 2,8,1,2,255,2,1,2,255,4,2,2,1,10,1,12, + 1,16,1,10,1,2,255,12,2,10,1,10,1,10,1,2, + 255,6,2,16,1,14,1,10,1,2,255,6,2,16,2,16, + 1,16,1,10,1,18,1,10,1,18,1,8,1,8,1,10, + 1,18,2,4,2,4,1,2,1,14,1,16,1,24,2,10, + 1,14,1,8,2,18,1,4,1,14,1,8,1,16,1,16, + 1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16, + 1,16,1,12,1,10,1,18,1,8,2,2,1,14,1,16, + 1,24,1,14,1,18,4,2,1,28,1,22,1,16,1,24, + 2,10,2,10,3,2,1,14,1,16,1,22,2,12,1,12, + 1,20,1,8,1,22,1,14,1,114,27,0,0,0,117,190, + 1,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12, + 13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, + 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44, + 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60, + 61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76, + 77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92, + 93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108, + 109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124, + 125,126,127,195,135,195,188,195,169,195,162,195,164,195,160,195, + 165,195,167,195,170,195,171,195,168,195,175,195,174,195,172,195, + 132,195,133,195,137,195,166,195,134,195,180,195,182,195,178,195, + 187,195,185,195,191,195,150,195,156,194,162,194,163,194,165,226, + 130,167,198,146,195,161,195,173,195,179,195,186,195,177,195,145, + 194,170,194,186,194,191,226,140,144,194,172,194,189,194,188,194, + 161,194,171,194,187,226,150,145,226,150,146,226,150,147,226,148, + 130,226,148,164,226,149,161,226,149,162,226,149,150,226,149,149, + 226,149,163,226,149,145,226,149,151,226,149,157,226,149,156,226, + 149,155,226,148,144,226,148,148,226,148,180,226,148,172,226,148, + 156,226,148,128,226,148,188,226,149,158,226,149,159,226,149,154, + 226,149,148,226,149,169,226,149,166,226,149,160,226,149,144,226, + 149,172,226,149,167,226,149,168,226,149,164,226,149,165,226,149, + 153,226,149,152,226,149,146,226,149,147,226,149,171,226,149,170, + 226,148,152,226,148,140,226,150,136,226,150,132,226,150,140,226, + 150,144,226,150,128,206,177,195,159,206,147,207,128,206,163,207, + 131,194,181,207,132,206,166,206,152,206,169,206,180,226,136,158, + 207,134,206,181,226,136,169,226,137,161,194,177,226,137,165,226, + 137,164,226,140,160,226,140,161,195,183,226,137,136,194,176,226, + 136,153,194,183,226,136,154,226,129,191,194,178,226,150,160,194, + 160,99,0,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,8,0,0,0,67,0,0,0,115,108,0,0,0,116, + 0,114,22,116,1,160,2,100,1,161,1,1,0,116,3,100, + 2,131,1,130,1,100,3,97,0,122,60,122,16,100,4,100, + 5,108,4,109,5,125,0,1,0,87,0,110,38,4,0,116, + 6,107,10,114,82,1,0,1,0,1,0,116,1,160,2,100, + 1,161,1,1,0,116,3,100,2,131,1,130,1,89,0,110, + 2,88,0,87,0,53,0,100,6,97,0,88,0,116,1,160, + 2,100,7,161,1,1,0,124,0,83,0,41,8,78,122,27, + 122,105,112,105,109,112,111,114,116,58,32,122,108,105,98,32, + 85,78,65,86,65,73,76,65,66,76,69,250,41,99,97,110, + 39,116,32,100,101,99,111,109,112,114,101,115,115,32,100,97, + 116,97,59,32,122,108,105,98,32,110,111,116,32,97,118,97, + 105,108,97,98,108,101,84,114,0,0,0,0,169,1,218,10, + 100,101,99,111,109,112,114,101,115,115,70,122,25,122,105,112, + 105,109,112,111,114,116,58,32,122,108,105,98,32,97,118,97, + 105,108,97,98,108,101,41,7,218,15,95,105,109,112,111,114, + 116,105,110,103,95,122,108,105,98,114,76,0,0,0,114,77, + 0,0,0,114,3,0,0,0,90,4,122,108,105,98,114,141, + 0,0,0,218,9,69,120,99,101,112,116,105,111,110,114,140, + 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, + 0,0,218,20,95,103,101,116,95,100,101,99,111,109,112,114, + 101,115,115,95,102,117,110,99,254,1,0,0,115,24,0,0, + 0,0,2,4,3,10,1,8,2,4,1,4,1,16,1,14, + 1,10,1,18,2,6,2,10,1,114,144,0,0,0,99,2, + 0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,9, + 0,0,0,67,0,0,0,115,128,1,0,0,124,1,92,8, + 125,2,125,3,125,4,125,5,125,6,125,7,125,8,125,9, + 124,4,100,1,107,0,114,36,116,0,100,2,131,1,130,1, + 116,1,160,2,124,0,161,1,144,1,143,8,125,10,122,14, + 124,10,160,3,124,6,161,1,1,0,87,0,110,38,4,0, + 116,4,107,10,114,102,1,0,1,0,1,0,116,0,100,3, + 124,0,155,2,157,2,124,0,100,4,141,2,130,1,89,0, + 110,2,88,0,124,10,160,5,100,5,161,1,125,11,116,6, + 124,11,131,1,100,5,107,3,114,134,116,7,100,6,131,1, + 130,1,124,11,100,0,100,7,133,2,25,0,100,8,107,3, + 114,168,116,0,100,9,124,0,155,2,157,2,124,0,100,4, + 141,2,130,1,116,8,124,11,100,10,100,11,133,2,25,0, + 131,1,125,12,116,8,124,11,100,11,100,5,133,2,25,0, + 131,1,125,13,100,5,124,12,23,0,124,13,23,0,125,14, + 124,6,124,14,55,0,125,6,122,14,124,10,160,3,124,6, + 161,1,1,0,87,0,110,40,4,0,116,4,107,10,144,1, + 114,18,1,0,1,0,1,0,116,0,100,3,124,0,155,2, + 157,2,124,0,100,4,141,2,130,1,89,0,110,2,88,0, + 124,10,160,5,124,4,161,1,125,15,116,6,124,15,131,1, + 124,4,107,3,144,1,114,52,116,4,100,12,131,1,130,1, + 87,0,53,0,81,0,82,0,88,0,124,3,100,1,107,2, + 144,1,114,76,124,15,83,0,122,10,116,9,131,0,125,16, + 87,0,110,30,4,0,116,10,107,10,144,1,114,116,1,0, + 1,0,1,0,116,0,100,13,131,1,130,1,89,0,110,2, + 88,0,124,16,124,15,100,14,131,2,83,0,41,15,78,114, + 0,0,0,0,122,18,110,101,103,97,116,105,118,101,32,100, + 97,116,97,32,115,105,122,101,114,92,0,0,0,114,12,0, + 0,0,114,104,0,0,0,114,98,0,0,0,114,93,0,0, + 0,115,4,0,0,0,80,75,3,4,122,23,98,97,100,32, + 108,111,99,97,108,32,102,105,108,101,32,104,101,97,100,101, + 114,58,32,233,26,0,0,0,114,103,0,0,0,122,26,122, + 105,112,105,109,112,111,114,116,58,32,99,97,110,39,116,32, + 114,101,97,100,32,100,97,116,97,114,139,0,0,0,105,241, + 255,255,255,41,11,114,3,0,0,0,114,110,0,0,0,114, + 111,0,0,0,114,112,0,0,0,114,22,0,0,0,114,114, + 0,0,0,114,51,0,0,0,114,119,0,0,0,114,1,0, + 0,0,114,144,0,0,0,114,143,0,0,0,41,17,114,29, + 0,0,0,114,54,0,0,0,90,8,100,97,116,97,112,97, + 116,104,114,130,0,0,0,114,134,0,0,0,114,125,0,0, + 0,114,137,0,0,0,114,131,0,0,0,114,132,0,0,0, + 114,133,0,0,0,114,123,0,0,0,114,124,0,0,0,114, + 135,0,0,0,114,136,0,0,0,114,127,0,0,0,90,8, + 114,97,119,95,100,97,116,97,114,141,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,52,0,0, + 0,19,2,0,0,115,62,0,0,0,0,1,20,1,8,1, + 8,2,14,2,2,1,14,1,14,1,24,1,10,1,12,1, + 8,2,16,2,18,2,16,1,16,1,12,1,8,1,2,1, + 14,1,16,1,24,1,10,1,14,1,18,2,10,2,4,3, + 2,1,10,1,16,1,14,1,114,52,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,67,0,0,0,115,16,0,0,0,116,0,124,0,124, + 1,24,0,131,1,100,1,107,1,83,0,41,2,78,114,5, + 0,0,0,41,1,218,3,97,98,115,41,2,90,2,116,49, + 90,2,116,50,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,9,95,101,113,95,109,116,105,109,101,65,2, + 0,0,115,2,0,0,0,0,2,114,147,0,0,0,99,5, + 0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,8, + 0,0,0,67,0,0,0,115,68,1,0,0,124,3,124,2, + 100,1,156,2,125,5,122,18,116,0,160,1,124,4,124,3, + 124,5,161,3,125,6,87,0,110,26,4,0,116,2,107,10, + 114,54,1,0,1,0,1,0,89,0,100,0,83,0,89,0, + 110,2,88,0,124,6,100,2,64,0,100,3,107,3,125,7, + 124,7,114,190,124,6,100,4,64,0,100,3,107,3,125,8, + 116,3,106,4,100,5,107,3,114,188,124,8,115,108,116,3, + 106,4,100,6,107,2,114,188,116,5,124,0,124,2,131,2, + 125,9,124,9,100,0,107,9,114,188,116,3,160,6,116,0, + 106,7,124,9,161,2,125,10,122,20,116,8,160,9,124,4, + 124,10,124,3,124,5,161,4,1,0,87,0,110,26,4,0, + 116,2,107,10,114,186,1,0,1,0,1,0,89,0,100,0, + 83,0,89,0,110,2,88,0,110,84,116,10,124,0,124,2, + 131,2,92,2,125,11,125,12,124,11,144,1,114,18,116,11, + 116,12,124,4,100,7,100,8,133,2,25,0,131,1,124,11, + 131,2,114,254,116,12,124,4,100,8,100,9,133,2,25,0, + 131,1,124,12,107,3,144,1,114,18,116,13,160,14,100,10, + 124,3,155,2,157,2,161,1,1,0,100,0,83,0,116,15, + 160,16,124,4,100,9,100,0,133,2,25,0,161,1,125,13, + 116,17,124,13,116,18,131,2,144,1,115,64,116,19,100,11, + 124,1,155,2,100,12,157,3,131,1,130,1,124,13,83,0, + 41,13,78,41,2,114,59,0,0,0,114,13,0,0,0,114, + 5,0,0,0,114,0,0,0,0,114,86,0,0,0,90,5, + 110,101,118,101,114,90,6,97,108,119,97,121,115,114,99,0, + 0,0,114,94,0,0,0,114,95,0,0,0,122,22,98,121, + 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, + 102,111,114,32,122,16,99,111,109,112,105,108,101,100,32,109, + 111,100,117,108,101,32,122,21,32,105,115,32,110,111,116,32, + 97,32,99,111,100,101,32,111,98,106,101,99,116,41,20,114, + 21,0,0,0,90,13,95,99,108,97,115,115,105,102,121,95, + 112,121,99,114,75,0,0,0,218,4,95,105,109,112,90,21, + 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, + 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95, + 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104, + 97,115,104,90,17,95,82,65,87,95,77,65,71,73,67,95, + 78,85,77,66,69,82,90,18,95,98,111,111,115,116,114,97, + 112,95,101,120,116,101,114,110,97,108,90,18,95,118,97,108, + 105,100,97,116,101,95,104,97,115,104,95,112,121,99,218,29, + 95,103,101,116,95,109,116,105,109,101,95,97,110,100,95,115, + 105,122,101,95,111,102,95,115,111,117,114,99,101,114,147,0, + 0,0,114,2,0,0,0,114,76,0,0,0,114,77,0,0, + 0,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, + 115,114,15,0,0,0,218,10,95,99,111,100,101,95,116,121, + 112,101,218,9,84,121,112,101,69,114,114,111,114,41,14,114, + 32,0,0,0,114,53,0,0,0,114,63,0,0,0,114,38, + 0,0,0,114,126,0,0,0,90,11,101,120,99,95,100,101, + 116,97,105,108,115,114,129,0,0,0,90,10,104,97,115,104, + 95,98,97,115,101,100,90,12,99,104,101,99,107,95,115,111, + 117,114,99,101,90,12,115,111,117,114,99,101,95,98,121,116, + 101,115,114,150,0,0,0,90,12,115,111,117,114,99,101,95, + 109,116,105,109,101,90,11,115,111,117,114,99,101,95,115,105, + 122,101,114,46,0,0,0,114,9,0,0,0,114,9,0,0, + 0,114,10,0,0,0,218,15,95,117,110,109,97,114,115,104, + 97,108,95,99,111,100,101,75,2,0,0,115,88,0,0,0, + 0,2,2,1,2,254,6,5,2,1,18,1,14,1,12,2, + 12,1,4,1,12,1,10,1,2,255,2,1,8,255,2,2, + 10,1,8,1,4,1,4,1,2,254,4,5,2,1,4,1, + 2,0,2,0,2,0,2,255,8,2,14,1,14,3,8,255, + 6,3,6,3,22,1,18,255,4,2,4,1,8,255,4,2, + 4,2,18,1,12,1,16,1,114,155,0,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, + 0,0,67,0,0,0,115,28,0,0,0,124,0,160,0,100, + 1,100,2,161,2,125,0,124,0,160,0,100,3,100,2,161, + 2,125,0,124,0,83,0,41,4,78,115,2,0,0,0,13, + 10,243,1,0,0,0,10,243,1,0,0,0,13,41,1,114, + 19,0,0,0,41,1,218,6,115,111,117,114,99,101,114,9, + 0,0,0,114,9,0,0,0,114,10,0,0,0,218,23,95, + 110,111,114,109,97,108,105,122,101,95,108,105,110,101,95,101, + 110,100,105,110,103,115,126,2,0,0,115,6,0,0,0,0, + 1,12,1,12,1,114,159,0,0,0,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,67, + 0,0,0,115,24,0,0,0,116,0,124,1,131,1,125,1, + 116,1,124,1,124,0,100,1,100,2,100,3,141,4,83,0, + 41,4,78,114,74,0,0,0,84,41,1,90,12,100,111,110, + 116,95,105,110,104,101,114,105,116,41,2,114,159,0,0,0, + 218,7,99,111,109,112,105,108,101,41,2,114,53,0,0,0, + 114,158,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,218,15,95,99,111,109,112,105,108,101,95,115, + 111,117,114,99,101,133,2,0,0,115,4,0,0,0,0,1, + 8,1,114,161,0,0,0,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,11,0,0,0,67,0,0,0, + 115,68,0,0,0,116,0,160,1,124,0,100,1,63,0,100, + 2,23,0,124,0,100,3,63,0,100,4,64,0,124,0,100, + 5,64,0,124,1,100,6,63,0,124,1,100,3,63,0,100, + 7,64,0,124,1,100,5,64,0,100,8,20,0,100,9,100, + 9,100,9,102,9,161,1,83,0,41,10,78,233,9,0,0, + 0,105,188,7,0,0,233,5,0,0,0,233,15,0,0,0, + 233,31,0,0,0,233,11,0,0,0,233,63,0,0,0,114, + 86,0,0,0,114,14,0,0,0,41,2,114,131,0,0,0, + 90,6,109,107,116,105,109,101,41,2,218,1,100,114,138,0, + 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, + 0,218,14,95,112,97,114,115,101,95,100,111,115,116,105,109, + 101,139,2,0,0,115,22,0,0,0,0,1,4,1,10,1, + 10,1,6,1,6,1,10,1,10,1,2,0,2,0,2,249, + 114,169,0,0,0,99,2,0,0,0,0,0,0,0,0,0, + 0,0,6,0,0,0,10,0,0,0,67,0,0,0,115,116, + 0,0,0,122,82,124,1,100,1,100,0,133,2,25,0,100, + 2,107,6,115,22,116,0,130,1,124,1,100,0,100,1,133, + 2,25,0,125,1,124,0,106,1,124,1,25,0,125,2,124, + 2,100,3,25,0,125,3,124,2,100,4,25,0,125,4,124, + 2,100,5,25,0,125,5,116,2,124,4,124,3,131,2,124, + 5,102,2,87,0,83,0,4,0,116,3,116,4,116,5,102, + 3,107,10,114,110,1,0,1,0,1,0,89,0,100,6,83, + 0,88,0,100,0,83,0,41,7,78,114,14,0,0,0,169, + 2,218,1,99,218,1,111,114,163,0,0,0,233,6,0,0, + 0,233,3,0,0,0,41,2,114,0,0,0,0,114,0,0, + 0,0,41,6,218,14,65,115,115,101,114,116,105,111,110,69, + 114,114,111,114,114,28,0,0,0,114,169,0,0,0,114,26, + 0,0,0,218,10,73,110,100,101,120,69,114,114,111,114,114, + 154,0,0,0,41,6,114,32,0,0,0,114,13,0,0,0, + 114,54,0,0,0,114,131,0,0,0,114,132,0,0,0,90, + 17,117,110,99,111,109,112,114,101,115,115,101,100,95,115,105, + 122,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0, + 0,114,151,0,0,0,152,2,0,0,115,20,0,0,0,0, + 1,2,2,20,1,12,1,10,3,8,1,8,1,8,1,16, + 1,20,1,114,151,0,0,0,99,2,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, + 0,115,86,0,0,0,124,1,100,1,100,0,133,2,25,0, + 100,2,107,6,115,20,116,0,130,1,124,1,100,0,100,1, + 133,2,25,0,125,1,122,14,124,0,106,1,124,1,25,0, + 125,2,87,0,110,22,4,0,116,2,107,10,114,68,1,0, + 1,0,1,0,89,0,100,0,83,0,88,0,116,3,124,0, + 106,4,124,2,131,2,83,0,100,0,83,0,41,3,78,114, + 14,0,0,0,114,170,0,0,0,41,5,114,175,0,0,0, + 114,28,0,0,0,114,26,0,0,0,114,52,0,0,0,114, + 29,0,0,0,41,3,114,32,0,0,0,114,13,0,0,0, + 114,54,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,149,0,0,0,171,2,0,0,115,14,0, + 0,0,0,2,20,1,12,2,2,1,14,1,14,1,8,2, + 114,149,0,0,0,99,2,0,0,0,0,0,0,0,0,0, + 0,0,11,0,0,0,9,0,0,0,67,0,0,0,115,198, + 0,0,0,116,0,124,0,124,1,131,2,125,2,116,1,68, + 0,93,160,92,3,125,3,125,4,125,5,124,2,124,3,23, + 0,125,6,116,2,106,3,100,1,124,0,106,4,116,5,124, + 6,100,2,100,3,141,5,1,0,122,14,124,0,106,6,124, + 6,25,0,125,7,87,0,110,20,4,0,116,7,107,10,114, + 88,1,0,1,0,1,0,89,0,113,14,88,0,124,7,100, + 4,25,0,125,8,116,8,124,0,106,4,124,7,131,2,125, + 9,124,4,114,132,116,9,124,0,124,8,124,6,124,1,124, + 9,131,5,125,10,110,10,116,10,124,8,124,9,131,2,125, + 10,124,10,100,0,107,8,114,152,113,14,124,7,100,4,25, + 0,125,8,124,10,124,5,124,8,102,3,2,0,1,0,83, + 0,113,14,116,11,100,5,124,1,155,2,157,2,124,1,100, + 6,141,2,130,1,100,0,83,0,41,7,78,122,13,116,114, + 121,105,110,103,32,123,125,123,125,123,125,114,86,0,0,0, + 41,1,90,9,118,101,114,98,111,115,105,116,121,114,0,0, + 0,0,114,57,0,0,0,114,58,0,0,0,41,12,114,36, + 0,0,0,114,89,0,0,0,114,76,0,0,0,114,77,0, + 0,0,114,29,0,0,0,114,20,0,0,0,114,28,0,0, + 0,114,26,0,0,0,114,52,0,0,0,114,155,0,0,0, + 114,161,0,0,0,114,3,0,0,0,41,11,114,32,0,0, + 0,114,38,0,0,0,114,13,0,0,0,114,90,0,0,0, + 114,91,0,0,0,114,47,0,0,0,114,63,0,0,0,114, + 54,0,0,0,114,40,0,0,0,114,126,0,0,0,114,46, + 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, + 0,0,114,44,0,0,0,186,2,0,0,115,36,0,0,0, + 0,1,10,1,14,1,8,1,22,1,2,1,14,1,14,1, + 6,2,8,1,12,1,4,1,18,2,10,1,8,3,2,1, + 8,1,16,2,114,44,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, + 0,0,115,60,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,100,2,90,4,100,3,100,4,132,0,90,5,100, + 5,100,6,132,0,90,6,100,7,100,8,132,0,90,7,100, + 9,100,10,132,0,90,8,100,11,100,12,132,0,90,9,100, + 13,83,0,41,14,114,80,0,0,0,122,165,80,114,105,118, + 97,116,101,32,99,108,97,115,115,32,117,115,101,100,32,116, + 111,32,115,117,112,112,111,114,116,32,90,105,112,73,109,112, + 111,114,116,46,103,101,116,95,114,101,115,111,117,114,99,101, + 95,114,101,97,100,101,114,40,41,46,10,10,32,32,32,32, + 84,104,105,115,32,99,108,97,115,115,32,105,115,32,97,108, + 108,111,119,101,100,32,116,111,32,114,101,102,101,114,101,110, + 99,101,32,97,108,108,32,116,104,101,32,105,110,110,97,114, + 100,115,32,97,110,100,32,112,114,105,118,97,116,101,32,112, + 97,114,116,115,32,111,102,10,32,32,32,32,116,104,101,32, + 122,105,112,105,109,112,111,114,116,101,114,46,10,32,32,32, + 32,70,99,3,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, + 124,1,124,0,95,0,124,2,124,0,95,1,100,0,83,0, + 114,88,0,0,0,41,2,114,4,0,0,0,114,38,0,0, + 0,41,3,114,32,0,0,0,114,4,0,0,0,114,38,0, + 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, + 0,114,34,0,0,0,220,2,0,0,115,4,0,0,0,0, + 1,6,1,122,33,95,90,105,112,73,109,112,111,114,116,82, + 101,115,111,117,114,99,101,82,101,97,100,101,114,46,95,95, + 105,110,105,116,95,95,99,2,0,0,0,0,0,0,0,0, + 0,0,0,5,0,0,0,8,0,0,0,67,0,0,0,115, + 92,0,0,0,124,0,106,0,160,1,100,1,100,2,161,2, + 125,2,124,2,155,0,100,2,124,1,155,0,157,3,125,3, + 100,3,100,4,108,2,109,3,125,4,1,0,122,18,124,4, + 124,0,106,4,160,5,124,3,161,1,131,1,87,0,83,0, + 4,0,116,6,107,10,114,86,1,0,1,0,1,0,116,7, + 124,3,131,1,130,1,89,0,110,2,88,0,100,0,83,0, + 41,5,78,114,85,0,0,0,114,109,0,0,0,114,0,0, + 0,0,41,1,218,7,66,121,116,101,115,73,79,41,8,114, + 38,0,0,0,114,19,0,0,0,90,2,105,111,114,177,0, + 0,0,114,4,0,0,0,114,55,0,0,0,114,22,0,0, + 0,218,17,70,105,108,101,78,111,116,70,111,117,110,100,69, + 114,114,111,114,41,5,114,32,0,0,0,218,8,114,101,115, + 111,117,114,99,101,218,16,102,117,108,108,110,97,109,101,95, + 97,115,95,112,97,116,104,114,13,0,0,0,114,177,0,0, + 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, + 218,13,111,112,101,110,95,114,101,115,111,117,114,99,101,224, + 2,0,0,115,14,0,0,0,0,1,14,1,14,1,12,1, + 2,1,18,1,14,1,122,38,95,90,105,112,73,109,112,111, + 114,116,82,101,115,111,117,114,99,101,82,101,97,100,101,114, + 46,111,112,101,110,95,114,101,115,111,117,114,99,101,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, + 0,0,0,67,0,0,0,115,8,0,0,0,116,0,130,1, + 100,0,83,0,114,88,0,0,0,41,1,114,178,0,0,0, + 41,2,114,32,0,0,0,114,179,0,0,0,114,9,0,0, + 0,114,9,0,0,0,114,10,0,0,0,218,13,114,101,115, + 111,117,114,99,101,95,112,97,116,104,233,2,0,0,115,2, + 0,0,0,0,4,122,38,95,90,105,112,73,109,112,111,114, + 116,82,101,115,111,117,114,99,101,82,101,97,100,101,114,46, + 114,101,115,111,117,114,99,101,95,112,97,116,104,99,2,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0, + 0,0,67,0,0,0,115,72,0,0,0,124,0,106,0,160, + 1,100,1,100,2,161,2,125,2,124,2,155,0,100,2,124, + 1,155,0,157,3,125,3,122,16,124,0,106,2,160,3,124, + 3,161,1,1,0,87,0,110,22,4,0,116,4,107,10,114, + 66,1,0,1,0,1,0,89,0,100,3,83,0,88,0,100, + 4,83,0,41,5,78,114,85,0,0,0,114,109,0,0,0, + 70,84,41,5,114,38,0,0,0,114,19,0,0,0,114,4, + 0,0,0,114,55,0,0,0,114,22,0,0,0,41,4,114, + 32,0,0,0,114,59,0,0,0,114,180,0,0,0,114,13, + 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, + 0,0,218,11,105,115,95,114,101,115,111,117,114,99,101,239, + 2,0,0,115,14,0,0,0,0,3,14,1,14,1,2,1, + 16,1,14,1,8,1,122,36,95,90,105,112,73,109,112,111, + 114,116,82,101,115,111,117,114,99,101,82,101,97,100,101,114, + 46,105,115,95,114,101,115,111,117,114,99,101,99,1,0,0, + 0,0,0,0,0,0,0,0,0,9,0,0,0,9,0,0, + 0,99,0,0,0,115,186,0,0,0,100,1,100,2,108,0, + 109,1,125,1,1,0,124,1,124,0,106,2,160,3,124,0, + 106,4,161,1,131,1,125,2,124,2,160,5,124,0,106,2, + 106,6,161,1,125,3,124,3,106,7,100,3,107,2,115,58, + 116,8,130,1,124,3,106,9,125,4,116,10,131,0,125,5, + 124,0,106,2,106,11,68,0,93,102,125,6,122,18,124,1, + 124,6,131,1,160,5,124,4,161,1,125,7,87,0,110,24, + 4,0,116,12,107,10,114,124,1,0,1,0,1,0,89,0, + 113,78,89,0,110,2,88,0,124,7,106,9,106,7,125,8, + 116,13,124,8,131,1,100,1,107,2,114,156,124,7,106,7, + 86,0,1,0,113,78,124,8,124,5,107,7,114,78,124,5, + 160,14,124,8,161,1,1,0,124,8,86,0,1,0,113,78, + 100,0,83,0,41,4,78,114,0,0,0,0,41,1,218,4, + 80,97,116,104,114,60,0,0,0,41,15,90,7,112,97,116, + 104,108,105,98,114,184,0,0,0,114,4,0,0,0,114,56, + 0,0,0,114,38,0,0,0,90,11,114,101,108,97,116,105, + 118,101,95,116,111,114,29,0,0,0,114,59,0,0,0,114, + 175,0,0,0,90,6,112,97,114,101,110,116,218,3,115,101, + 116,114,28,0,0,0,114,23,0,0,0,114,51,0,0,0, + 218,3,97,100,100,41,9,114,32,0,0,0,114,184,0,0, + 0,90,13,102,117,108,108,110,97,109,101,95,112,97,116,104, + 90,13,114,101,108,97,116,105,118,101,95,112,97,116,104,90, + 12,112,97,99,107,97,103,101,95,112,97,116,104,90,12,115, + 117,98,100,105,114,115,95,115,101,101,110,218,8,102,105,108, + 101,110,97,109,101,90,8,114,101,108,97,116,105,118,101,90, + 11,112,97,114,101,110,116,95,110,97,109,101,114,9,0,0, + 0,114,9,0,0,0,114,10,0,0,0,218,8,99,111,110, + 116,101,110,116,115,250,2,0,0,115,34,0,0,0,0,8, + 12,1,18,1,14,3,14,1,6,1,6,1,12,1,2,1, + 18,1,14,1,10,5,8,1,12,1,10,1,8,1,10,1, + 122,33,95,90,105,112,73,109,112,111,114,116,82,101,115,111, + 117,114,99,101,82,101,97,100,101,114,46,99,111,110,116,101, + 110,116,115,78,41,10,114,6,0,0,0,114,7,0,0,0, + 114,8,0,0,0,114,84,0,0,0,114,81,0,0,0,114, + 34,0,0,0,114,181,0,0,0,114,182,0,0,0,114,183, + 0,0,0,114,188,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,80,0,0, + 0,212,2,0,0,115,14,0,0,0,8,1,4,5,4,2, + 8,4,8,9,8,6,8,11,114,80,0,0,0,41,45,114, + 84,0,0,0,90,26,95,102,114,111,122,101,110,95,105,109, + 112,111,114,116,108,105,98,95,101,120,116,101,114,110,97,108, + 114,21,0,0,0,114,1,0,0,0,114,2,0,0,0,90, + 17,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, + 105,98,114,76,0,0,0,114,148,0,0,0,114,110,0,0, + 0,114,152,0,0,0,114,67,0,0,0,114,131,0,0,0, + 90,7,95,95,97,108,108,95,95,114,20,0,0,0,90,15, + 112,97,116,104,95,115,101,112,97,114,97,116,111,114,115,114, + 18,0,0,0,114,75,0,0,0,114,3,0,0,0,114,25, + 0,0,0,218,4,116,121,112,101,114,70,0,0,0,114,113, + 0,0,0,114,115,0,0,0,114,117,0,0,0,114,4,0, + 0,0,114,89,0,0,0,114,36,0,0,0,114,37,0,0, + 0,114,35,0,0,0,114,27,0,0,0,114,122,0,0,0, + 114,142,0,0,0,114,144,0,0,0,114,52,0,0,0,114, + 147,0,0,0,114,155,0,0,0,218,8,95,95,99,111,100, + 101,95,95,114,153,0,0,0,114,159,0,0,0,114,161,0, + 0,0,114,169,0,0,0,114,151,0,0,0,114,149,0,0, + 0,114,44,0,0,0,114,80,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, + 8,60,109,111,100,117,108,101,62,1,0,0,0,115,88,0, + 0,0,4,16,8,1,16,1,8,1,8,1,8,1,8,1, + 8,1,8,2,8,3,6,1,14,3,16,4,4,2,8,2, + 4,1,4,1,4,2,14,127,0,127,0,1,12,1,12,1, + 2,1,2,252,4,9,8,4,8,9,8,31,8,126,2,254, + 2,29,4,5,8,21,8,46,8,10,8,46,10,5,8,7, + 8,6,8,13,8,19,8,15,8,26, }; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 1084def9ce03fc..9880c0d624d523 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1250,6 +1250,13 @@ Py_FinalizeEx(void) /* nothing */; #endif + /* Clear all loghooks */ + /* We want minimal exposure of this function, so define the extern + * here. The linker should discover the correct function without + * exporting a symbol. */ + extern void _PySys_ClearAuditHooks(void); + _PySys_ClearAuditHooks(); + /* Destroy all modules */ PyImport_Cleanup(); diff --git a/Python/pystate.c b/Python/pystate.c index 879a5a91f8a3b0..41c66223390d05 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -45,8 +45,19 @@ static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstat static _PyInitError _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) { + /* We preserve the hook across init, because there is + currently no public API to set it between runtime + initialization and interpreter initialization. */ + void *open_code_hook = runtime->open_code_hook; + void *open_code_userdata = runtime->open_code_userdata; + _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head; + memset(runtime, 0, sizeof(*runtime)); + runtime->open_code_hook = open_code_hook; + runtime->open_code_userdata = open_code_userdata; + runtime->audit_hook_head = audit_hook_head; + _PyGC_Initialize(&runtime->gc); _PyEval_Initialize(&runtime->ceval); _PyPreConfig_InitPythonConfig(&runtime->preconfig); @@ -181,6 +192,10 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) PyInterpreterState * PyInterpreterState_New(void) { + if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) { + return NULL; + } + PyInterpreterState *interp = PyMem_RawMalloc(sizeof(PyInterpreterState)); if (interp == NULL) { return NULL; @@ -233,6 +248,8 @@ PyInterpreterState_New(void) interp->tstate_next_unique_id = 0; + interp->audit_hooks = NULL; + return interp; } @@ -240,11 +257,18 @@ PyInterpreterState_New(void) static void _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) { + if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) { + PyErr_Clear(); + } + HEAD_LOCK(runtime); for (PyThreadState *p = interp->tstate_head; p != NULL; p = p->next) { PyThreadState_Clear(p); } HEAD_UNLOCK(runtime); + + Py_CLEAR(interp->audit_hooks); + _PyCoreConfig_Clear(&interp->core_config); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); @@ -1057,6 +1081,10 @@ _PyThread_CurrentFrames(void) PyObject *result; PyInterpreterState *i; + if (PySys_Audit("sys._current_frames", NULL) < 0) { + return NULL; + } + result = PyDict_New(); if (result == NULL) return NULL; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index d2b27615903fee..7219f548fd251e 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1091,6 +1091,12 @@ run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals, co = PyAST_CompileObject(mod, filename, flags, -1, arena); if (co == NULL) return NULL; + + if (PySys_Audit("exec", "O", co) < 0) { + Py_DECREF(co); + return NULL; + } + v = run_eval_code_obj(co, globals, locals); Py_DECREF(co); return v; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 1735b90b33b955..5ebeacf0b7f399 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -22,7 +22,9 @@ Data members: #include "pycore_pymem.h" #include "pycore_pathconfig.h" #include "pycore_pystate.h" +#include "pycore_tupleobject.h" #include "pythread.h" +#include "pydtrace.h" #include "osdefs.h" #include @@ -111,6 +113,308 @@ PySys_SetObject(const char *name, PyObject *v) } } +static int +should_audit(void) +{ + PyThreadState *ts = _PyThreadState_GET(); + if (!ts) { + return 0; + } + PyInterpreterState *is = ts ? ts->interp : NULL; + return _PyRuntime.audit_hook_head + || (is && is->audit_hooks) + || PyDTrace_AUDIT_ENABLED(); +} + +int +PySys_Audit(const char *event, const char *argFormat, ...) +{ + PyObject *eventName = NULL; + PyObject *eventArgs = NULL; + PyObject *hooks = NULL; + PyObject *hook = NULL; + int res = -1; + + /* N format is inappropriate, because you do not know + whether the reference is consumed by the call. + Assert rather than exception for perf reasons */ + assert(!argFormat || !strchr(argFormat, 'N')); + + /* Early exit when no hooks are registered */ + if (!should_audit()) { + return 0; + } + + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; + PyThreadState *ts = _PyThreadState_GET(); + PyInterpreterState *is = ts ? ts->interp : NULL; + int dtrace = PyDTrace_AUDIT_ENABLED(); + + PyObject *exc_type, *exc_value, *exc_tb; + if (ts) { + PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + } + + /* Initialize event args now */ + if (argFormat && argFormat[0]) { + va_list args; + va_start(args, argFormat); + eventArgs = Py_VaBuildValue(argFormat, args); + if (eventArgs && !PyTuple_Check(eventArgs)) { + PyObject *argTuple = PyTuple_Pack(1, eventArgs); + Py_DECREF(eventArgs); + eventArgs = argTuple; + } + } else { + eventArgs = PyTuple_New(0); + } + if (!eventArgs) { + goto exit; + } + + /* Call global hooks */ + for (; e; e = e->next) { + if (e->hookCFunction(event, eventArgs, e->userData) < 0) { + goto exit; + } + } + + /* Dtrace USDT point */ + if (dtrace) { + PyDTrace_AUDIT(event, (void *)eventArgs); + } + + /* Call interpreter hooks */ + if (is && is->audit_hooks) { + eventName = PyUnicode_FromString(event); + if (!eventName) { + goto exit; + } + + hooks = PyObject_GetIter(is->audit_hooks); + if (!hooks) { + goto exit; + } + + /* Disallow tracing in hooks unless explicitly enabled */ + ts->tracing++; + ts->use_tracing = 0; + while ((hook = PyIter_Next(hooks)) != NULL) { + PyObject *o; + int canTrace = -1; + o = PyObject_GetAttrString(hook, "__cantrace__"); + if (o) { + canTrace = PyObject_IsTrue(o); + Py_DECREF(o); + } else if (PyErr_Occurred() && + PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + canTrace = 0; + } + if (canTrace < 0) { + break; + } + if (canTrace) { + ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); + ts->tracing--; + } + o = PyObject_CallFunctionObjArgs(hook, eventName, + eventArgs, NULL); + if (canTrace) { + ts->tracing++; + ts->use_tracing = 0; + } + if (!o) { + break; + } + Py_DECREF(o); + Py_CLEAR(hook); + } + ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); + ts->tracing--; + if (PyErr_Occurred()) { + goto exit; + } + } + + res = 0; + +exit: + Py_XDECREF(hook); + Py_XDECREF(hooks); + Py_XDECREF(eventName); + Py_XDECREF(eventArgs); + + if (ts) { + if (!res) { + PyErr_Restore(exc_type, exc_value, exc_tb); + } else { + assert(PyErr_Occurred()); + Py_XDECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + } + } + + return res; +} + +/* We expose this function primarily for our own cleanup during + * finalization. In general, it should not need to be called, + * and as such it is not defined in any header files. + */ +void _PySys_ClearAuditHooks(void) { + /* Must be finalizing to clear hooks */ + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *ts = _PyRuntimeState_GetThreadState(runtime); + assert(!ts || _Py_CURRENTLY_FINALIZING(runtime, ts)); + if (!ts || !_Py_CURRENTLY_FINALIZING(runtime, ts)) + return; + + if (Py_VerboseFlag) { + PySys_WriteStderr("# clear sys.audit hooks\n"); + } + + /* Hooks can abort later hooks for this event, but cannot + abort the clear operation itself. */ + PySys_Audit("cpython._PySys_ClearAuditHooks", NULL); + PyErr_Clear(); + + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n; + _PyRuntime.audit_hook_head = NULL; + while (e) { + n = e->next; + PyMem_RawFree(e); + e = n; + } +} + +int +PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) +{ + /* Invoke existing audit hooks to allow them an opportunity to abort. */ + /* Cannot invoke hooks until we are initialized */ + if (Py_IsInitialized()) { + if (PySys_Audit("sys.addaudithook", NULL) < 0) { + if (PyErr_ExceptionMatches(PyExc_Exception)) { + /* We do not report errors derived from Exception */ + PyErr_Clear(); + return 0; + } + return -1; + } + } + + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; + if (!e) { + e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); + _PyRuntime.audit_hook_head = e; + } else { + while (e->next) + e = e->next; + e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc( + sizeof(_Py_AuditHookEntry)); + } + + if (!e) { + if (Py_IsInitialized()) + PyErr_NoMemory(); + return -1; + } + + e->next = NULL; + e->hookCFunction = (Py_AuditHookFunction)hook; + e->userData = userData; + + return 0; +} + +/*[clinic input] +sys.addaudithook + + hook: object + +Adds a new audit hook callback. +[clinic start generated code]*/ + +static PyObject * +sys_addaudithook_impl(PyObject *module, PyObject *hook) +/*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/ +{ + /* Invoke existing audit hooks to allow them an opportunity to abort. */ + if (PySys_Audit("sys.addaudithook", NULL) < 0) { + if (PyErr_ExceptionMatches(PyExc_Exception)) { + /* We do not report errors derived from Exception */ + PyErr_Clear(); + Py_RETURN_NONE; + } + return NULL; + } + + PyInterpreterState *is = _PyInterpreterState_Get(); + + if (is->audit_hooks == NULL) { + is->audit_hooks = PyList_New(0); + if (is->audit_hooks == NULL) { + return NULL; + } + } + + if (PyList_Append(is->audit_hooks, hook) < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(audit_doc, +"audit(event, *args)\n\ +\n\ +Passes the event to any audit hooks that are attached."); + +static PyObject * +sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc) +{ + if (argc == 0) { + PyErr_SetString(PyExc_TypeError, "audit() missing 1 required positional argument: 'event'"); + return NULL; + } + + if (!should_audit()) { + Py_RETURN_NONE; + } + + PyObject *auditEvent = args[0]; + if (!auditEvent) { + PyErr_SetString(PyExc_TypeError, "expected str for argument 'event'"); + return NULL; + } + if (!PyUnicode_Check(auditEvent)) { + PyErr_Format(PyExc_TypeError, "expected str for argument 'event', not %.200s", + Py_TYPE(auditEvent)->tp_name); + return NULL; + } + const char *event = PyUnicode_AsUTF8(auditEvent); + if (!event) { + return NULL; + } + + PyObject *auditArgs = _PyTuple_FromArray(args + 1, argc - 1); + if (!auditArgs) { + return NULL; + } + + int res = PySys_Audit(event, "O", auditArgs); + Py_DECREF(auditArgs); + + if (res < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + + static PyObject * sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) { @@ -1469,6 +1773,10 @@ sys__getframe_impl(PyObject *module, int depth) { PyFrameObject *f = _PyThreadState_GET()->frame; + if (PySys_Audit("sys._getframe", "O", f) < 0) { + return NULL; + } + while (depth > 0 && f != NULL) { f = f->f_back; --depth; @@ -1642,8 +1950,11 @@ sys_getandroidapilevel_impl(PyObject *module) #endif /* ANDROID_API_LEVEL */ + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ + SYS_ADDAUDITHOOK_METHODDEF + {"audit", (PyCFunction)(void(*)(void))sys_audit, METH_FASTCALL, audit_doc }, {"breakpointhook", (PyCFunction)(void(*)(void))sys_breakpointhook, METH_FASTCALL | METH_KEYWORDS, breakpointhook_doc}, SYS_CALLSTATS_METHODDEF From 608876b6b1eb59538e6c29671a733033fb8b5be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Thu, 23 May 2019 22:30:00 +0200 Subject: [PATCH 080/441] bpo-23395: Fix PyErr_SetInterrupt if the SIGINT signal is ignored or not handled (GH-7778) ``_thread.interrupt_main()`` now avoids setting the Python error status if the ``SIGINT`` signal is ignored or not handled by Python. --- Doc/c-api/exceptions.rst | 12 +++---- Doc/library/_thread.rst | 8 +++-- Lib/test/test_threading.py | 35 +++++++++++++++++++ Misc/ACKS | 2 +- .../2016-07-27-11-06-43.bpo-23395.MuCEX9.rst | 2 ++ Modules/signalmodule.c | 13 ++++--- 6 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 18ff697a2325eb..d3f6daa8347e41 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -519,13 +519,13 @@ Signal Handling single: SIGINT single: KeyboardInterrupt (built-in exception) - This function simulates the effect of a :const:`SIGINT` signal arriving --- the - next time :c:func:`PyErr_CheckSignals` is called, :exc:`KeyboardInterrupt` will - be raised. It may be called without holding the interpreter lock. - - .. % XXX This was described as obsolete, but is used in - .. % _thread.interrupt_main() (used from IDLE), so it's still needed. + Simulate the effect of a :const:`SIGINT` signal arriving. The next time + :c:func:`PyErr_CheckSignals` is called, the Python signal handler for + :const:`SIGINT` will be called. + If :const:`SIGINT` isn't handled by Python (it was set to + :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does + nothing. .. c:function:: int PySignal_SetWakeupFd(int fd) diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index d7814f218b502f..a6ce945c72057c 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -53,8 +53,12 @@ This module defines the following constants and functions: .. function:: interrupt_main() - Raise a :exc:`KeyboardInterrupt` exception in the main thread. A subthread can - use this function to interrupt the main thread. + Simulate the effect of a :data:`signal.SIGINT` signal arriving in the main + thread. A thread can use this function to interrupt the main thread. + + If :data:`signal.SIGINT` isn't handled by Python (it was set to + :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does + nothing. .. function:: exit() diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 33a25f3b9d235d..3bfd6fa474ed04 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -16,6 +16,7 @@ import weakref import os import subprocess +import signal from test import lock_tests from test import support @@ -1168,6 +1169,7 @@ class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests): class BarrierTests(lock_tests.BarrierTests): barriertype = staticmethod(threading.Barrier) + class MiscTestCase(unittest.TestCase): def test__all__(self): extra = {"ThreadError"} @@ -1175,5 +1177,38 @@ def test__all__(self): support.check__all__(self, threading, ('threading', '_thread'), extra=extra, blacklist=blacklist) + +class InterruptMainTests(unittest.TestCase): + def test_interrupt_main_subthread(self): + # Calling start_new_thread with a function that executes interrupt_main + # should raise KeyboardInterrupt upon completion. + def call_interrupt(): + _thread.interrupt_main() + t = threading.Thread(target=call_interrupt) + with self.assertRaises(KeyboardInterrupt): + t.start() + t.join() + t.join() + + def test_interrupt_main_mainthread(self): + # Make sure that if interrupt_main is called in main thread that + # KeyboardInterrupt is raised instantly. + with self.assertRaises(KeyboardInterrupt): + _thread.interrupt_main() + + def test_interrupt_main_noerror(self): + handler = signal.getsignal(signal.SIGINT) + try: + # No exception should arise. + signal.signal(signal.SIGINT, signal.SIG_IGN) + _thread.interrupt_main() + + signal.signal(signal.SIGINT, signal.SIG_DFL) + _thread.interrupt_main() + finally: + # Restore original handler + signal.signal(signal.SIGINT, handler) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/ACKS b/Misc/ACKS index fbed14684b3134..5c23df8c589922 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -261,7 +261,7 @@ Donn Cave Charles Cazabon Jesús Cea Avión Per Cederqvist -Matej Cepl +Matěj Cepl Carl Cerecke Octavian Cerna Michael Cetrulo diff --git a/Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst b/Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst new file mode 100644 index 00000000000000..ec95320ab411fd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst @@ -0,0 +1,2 @@ +``_thread.interrupt_main()`` now avoids setting the Python error status +if the ``SIGINT`` signal is ignored or not handled by Python. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index b5e6250b1b4059..221b74fac65e7b 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1683,13 +1683,18 @@ _PyErr_CheckSignals(void) } -/* Replacements for intrcheck.c functionality - * Declared in pyerrors.h - */ +/* Simulate the effect of a signal.SIGINT signal arriving. The next time + PyErr_CheckSignals is called, the Python SIGINT signal handler will be + raised. + + Missing signal handler for the SIGINT signal is silently ignored. */ void PyErr_SetInterrupt(void) { - trip_signal(SIGINT); + if ((Handlers[SIGINT].func != IgnoreHandler) && + (Handlers[SIGINT].func != DefaultHandler)) { + trip_signal(SIGINT); + } } void From cccc11b38e5409861f4db345a4dd45dcc9ba470c Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 24 May 2019 00:53:21 +0100 Subject: [PATCH 081/441] Fix warning in _testembed.c (GH-13533) --- Programs/_testembed.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 21d3b445d7752c..de1c5877f0f5ab 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1231,15 +1231,13 @@ static int _audit_subinterpreter_hook(const char *event, PyObject *args, void *u static int test_audit_subinterpreter(void) { - PyThreadState *ts; - Py_IgnoreEnvironmentFlag = 0; PySys_AddAuditHook(_audit_subinterpreter_hook, NULL); _testembed_Py_Initialize(); - ts = Py_NewInterpreter(); - ts = Py_NewInterpreter(); - ts = Py_NewInterpreter(); + Py_NewInterpreter(); + Py_NewInterpreter(); + Py_NewInterpreter(); Py_Finalize(); From f1e17e9f97d9a4e97a5d99574775ee343a3a74fb Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 24 May 2019 11:19:42 +0200 Subject: [PATCH 082/441] bpo-34626: Document creating heap types from the C-API (GH-9154) bpo-34626: Document creating heap types from the C-API Add missing descriptions of PEP384's PyType_Spec and PyType_Slot, along with some introductory prose. --- Doc/c-api/type.rst | 115 +++++++++++++++++++++++++++++++++++++----- Doc/c-api/typeobj.rst | 29 +++++++++-- 2 files changed, 127 insertions(+), 17 deletions(-) diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 2474df2c90baad..8f8367ab77c8c4 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -95,18 +95,6 @@ Type Objects from a type's base class. Return ``0`` on success, or return ``-1`` and sets an exception on error. -.. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec) - - Creates and returns a heap type object from the *spec* passed to the function. - -.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) - - Creates and returns a heap type object from the *spec*. In addition to that, - the created heap type contains all types contained by the *bases* tuple as base - types. This allows the caller to reference other heap types as base types. - - .. versionadded:: 3.3 - .. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot) Return the function pointer stored in the given slot. If the @@ -115,4 +103,107 @@ Type Objects Callers will typically cast the result pointer into the appropriate function type. + See :c:member:`PyType_Slot.slot` for possible values of the *slot* argument. + + An exception is raised if *type* is not a heap type. + .. versionadded:: 3.4 + + +Creating Heap-Allocated Types +............................. + +The following functions and structs are used to create +:ref:`heap types `. + +.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) + + Creates and returns a heap type object from the *spec*. + + If *bases* is a tuple, the created heap type contains all types contained + in it as base types. + + If *bases* is *NULL*, the *Py_tp_base* slot is used instead. + If that also is *NULL*, the new type derives from :class:`object`. + + This function calls :c:func:`PyType_Ready` on the new type. + + .. versionadded:: 3.3 + +.. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec) + + Equivalent to ``PyType_FromSpecWithBases(spec, NULL)``. + +.. c:type:: PyType_Spec + + Structure defining a type's behavior. + + .. c:member:: const char* PyType_Spec.name + + Name of the type, used to set :c:member:`PyTypeObject.tp_name`. + + .. c:member:: const char* PyType_Spec.doc + + Type docstring, used to set :c:member:`PyTypeObject.tp_doc`. + + .. c:member:: int PyType_Spec.basicsize + .. c:member:: int PyType_Spec.itemsize + + Size of the instance in bytes, used to set + :c:member:`PyTypeObject.tp_basicsize` and + :c:member:`PyTypeObject.tp_itemsize`. + + .. c:member:: int PyType_Spec.flags + + Type flags, used to set :c:member:`PyTypeObject.tp_flags`. + + If the ``Py_TPFLAGS_HEAPTYPE`` flag is not set, + :c:func:`PyType_FromSpecWithBases` sets it automatically. + + .. c:member:: PyType_Slot *PyType_Spec.slots + + Array of :c:type:`PyType_Slot` structures. + Terminated by the special slot value ``{0, NULL}``. + +.. c:type:: PyType_Slot + + Structure defining optional functionality of a type, containing a slot ID + and a value pointer. + + .. c:member:: int PyType_Slot.slot + + A slot ID. + + Slot IDs are named like the field names of the structures + :c:type:`PyTypeObject`, :c:type:`PyNumberMethods`, + :c:type:`PySequenceMethods`, :c:type:`PyMappingMethods` and + :c:type:`PyAsyncMethods` with an added ``Py_`` prefix. + For example, use: + + * ``Py_tp_dealloc`` to set :c:member:`PyTypeObject.tp_dealloc` + * ``Py_nb_add`` to set :c:member:`PyNumberMethods.nb_add` + * ``Py_sq_length`` to set :c:member:`PySequenceMethods.sq_length` + + The following fields cannot be set using *PyType_Spec* and *PyType_Slot*: + + * :c:member:`~PyTypeObject.tp_dict` + * :c:member:`~PyTypeObject.tp_mro` + * :c:member:`~PyTypeObject.tp_cache` + * :c:member:`~PyTypeObject.tp_subclasses` + * :c:member:`~PyTypeObject.tp_weaklist` + * :c:member:`~PyTypeObject.tp_print` + * :c:member:`~PyTypeObject.tp_weaklistoffset` + * :c:member:`~PyTypeObject.tp_dictoffset` + * :c:member:`~PyBufferProcs.bf_getbuffer` + * :c:member:`~PyBufferProcs.bf_releasebuffer` + + Setting :c:data:`Py_tp_bases` may be problematic on some platforms. + To avoid issues, use the *bases* argument of + :py:func:`PyType_FromSpecWithBases` instead. + + .. c:member:: void *PyType_Slot.pfunc + + The desired value of the slot. In most cases, this is a pointer + to a function. + + May not be *NULL*. diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index b1d96db7f53df0..e0ea9b9b5f9663 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1822,16 +1822,35 @@ objects on the thread which called tp_dealloc will not violate any assumptions of the library. +.. _heap-types: + Heap Types ---------- -In addition to defining Python types statically, you can define them -dynamically (i.e. to the heap) using :c:func:`PyType_FromSpec` and -:c:func:`PyType_FromSpecWithBases`. +Traditionally, types defined in C code are *static*, that is, +a static :c:type:`PyTypeObject` structure is defined directly in code +and initialized using :c:func:`PyType_Ready`. + +This results in types that are limited relative to types defined in Python: -.. XXX Explain how to use PyType_FromSpec(). +* Static types are limited to one base, i.e. they cannot use multiple + inheritance. +* Static type objects (but not necessarily their instances) are immutable. + It is not possible to add or modify the type object's attributes from Python. +* Static type objects are shared across + :ref:`sub-interpreters `, so they should not + include any subinterpreter-specific state. -.. XXX Document PyType_Spec. +Also, since *PyTypeObject* is not part of the :ref:`stable ABI `, +any extension modules using static types must be compiled for a specific +Python minor version. + +An alternative to static types is *heap-allocated types*, or *heap types* +for short, which correspond closely to classes created by Python's +``class`` statement. + +This is done by filling a :c:type:`PyType_Spec` structure and calling +:c:func:`PyType_FromSpecWithBases`. .. _number-structs: From c95c93d4eb0519beaa06e6b6e0ecca7c2a58f69c Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Fri, 24 May 2019 06:43:29 -0400 Subject: [PATCH 083/441] bpo-20285: Improve help docs for object (GH-4759) --- Lib/pydoc.py | 4 ++-- .../Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst | 3 +++ Objects/typeobject.c | 7 ++++++- 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 86ccfe041f6675..679a596821f478 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -867,7 +867,7 @@ def spilldata(msg, attrs, predicate): thisclass = attrs[0][2] attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) - if thisclass is builtins.object: + if object is not builtins.object and thisclass is builtins.object: attrs = inherited continue elif thisclass is object: @@ -1327,7 +1327,7 @@ def spilldata(msg, attrs, predicate): thisclass = attrs[0][2] attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) - if thisclass is builtins.object: + if object is not builtins.object and thisclass is builtins.object: attrs = inherited continue elif thisclass is object: diff --git a/Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst b/Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst new file mode 100644 index 00000000000000..ebe0c3f95e45ab --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst @@ -0,0 +1,3 @@ +Expand object.__doc__ (docstring) to make it clearer. +Modify pydoc.py so that help(object) lists object methods +(for other classes, help omits methods of the object base class.) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 49b45b8518cc45..339f7285292c53 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4750,6 +4750,11 @@ static PyMethodDef object_methods[] = { {0} }; +PyDoc_STRVAR(object_doc, +"object()\n--\n\n" +"The base class of the class hierarchy.\n\n" +"When called, it accepts no arguments and returns a new featureless\n" +"instance that has no instance attributes and cannot be given any.\n"); PyTypeObject PyBaseObject_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) @@ -4772,7 +4777,7 @@ PyTypeObject PyBaseObject_Type = { PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("object()\n--\n\nThe most base type"), /* tp_doc */ + object_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ object_richcompare, /* tp_richcompare */ From cf7d5ef49b1d28f35af137d23ec1a94f3eae090d Mon Sep 17 00:00:00 2001 From: Xtreak Date: Fri, 24 May 2019 16:47:48 +0530 Subject: [PATCH 084/441] Fix typo: decription -> description (GH-13543) --- Doc/c-api/sys.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 2091da6af0be53..7d870a8d4e4a71 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -332,7 +332,7 @@ accessible to C code. They all work with the current interpreter thread's functions may be called from different runtimes, this pointer should not refer directly to Python state. - See :pep:`578` for a detailed decription of auditing. Functions in the + See :pep:`578` for a detailed description of auditing. Functions in the runtime and standard library that raise events include the details in each function's documentation. From 2a37f8f55b543589cc77a67b5cd17cbd9d0311c9 Mon Sep 17 00:00:00 2001 From: Dan Rose Date: Fri, 24 May 2019 06:38:01 -0500 Subject: [PATCH 085/441] bpo-36045: builtins.help() now prefixes `async` for async functions (GH-12010) Previously, it was hard to tell whether a function should be awaited. It was also incorrect (per PEP 484) to put this in the type hint for coroutine functions. Added this info to the output of builtins.help and pydoc. https://bugs.python.org/issue36045 --- Lib/pydoc.py | 18 ++++++++++++--- Lib/test/test_pydoc.py | 23 +++++++++++++++++++ .../2019-02-24-12-44-46.bpo-36045.RO20OV.rst | 1 + 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 679a596821f478..9a22e56686f618 100644 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -951,6 +951,12 @@ def docroutine(self, object, name=None, mod=None, else: note = ' unbound %s method' % self.classlink(imclass,mod) + if (inspect.iscoroutinefunction(object) or + inspect.isasyncgenfunction(object)): + asyncqualifier = 'async ' + else: + asyncqualifier = '' + if name == realname: title = '%s' % (anchor, realname) else: @@ -979,8 +985,8 @@ def docroutine(self, object, name=None, mod=None, if not argspec: argspec = '(...)' - decl = title + self.escape(argspec) + (note and self.grey( - '%s' % note)) + decl = asyncqualifier + title + self.escape(argspec) + (note and + self.grey('%s' % note)) if skipdocs: return '
%s
\n' % decl @@ -1382,6 +1388,12 @@ def docroutine(self, object, name=None, mod=None, cl=None): else: note = ' unbound %s method' % classname(imclass,mod) + if (inspect.iscoroutinefunction(object) or + inspect.isasyncgenfunction(object)): + asyncqualifier = 'async ' + else: + asyncqualifier = '' + if name == realname: title = self.bold(realname) else: @@ -1405,7 +1417,7 @@ def docroutine(self, object, name=None, mod=None, cl=None): argspec = argspec[1:-1] # remove parentheses if not argspec: argspec = '(...)' - decl = title + argspec + note + decl = asyncqualifier + title + argspec + note if skipdocs: return decl + '\n' diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 67c6c5d42d48b4..6efdeb047c217d 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -1288,6 +1288,29 @@ class X: Custom descriptor """) + def test_async_annotation(self): + async def coro_function(ign) -> int: + return 1 + + text = pydoc.plain(pydoc.plaintext.document(coro_function)) + self.assertIn('async coro_function', text) + + html = pydoc.HTMLDoc().document(coro_function) + self.assertIn( + 'async coro_function', + html) + + def test_async_generator_annotation(self): + async def an_async_generator(): + yield 1 + + text = pydoc.plain(pydoc.plaintext.document(an_async_generator)) + self.assertIn('async an_async_generator', text) + + html = pydoc.HTMLDoc().document(an_async_generator) + self.assertIn( + 'async an_async_generator', + html) class PydocServerTest(unittest.TestCase): """Tests for pydoc._start_server""" diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst new file mode 100644 index 00000000000000..7cab3ea8409d1b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst @@ -0,0 +1 @@ +builtins.help() now prefixes `async` for async functions From d8613dc86f4c7acd3e2598095c466fe9dc0ad27c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 13:43:55 +0200 Subject: [PATCH 086/441] bpo-37031: Reuse _PyRuntime.main_thread in signalmodule.c (GH-13538) Remove main_thread and main_interp variables from signalmodule.c: reuse _PyRuntime which already track the main thread and the main interpreter. * Remove #include which became useless: getpid() call has been removed. * Add runtime argument to is_main() * is_main() now gets the interpreter from runtime. --- Modules/signalmodule.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 221b74fac65e7b..ed3852d444e80a 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -99,10 +99,7 @@ class sigset_t_converter(CConverter): may not be the thread that received the signal. */ -#include /* For pid_t */ #include "pythread.h" -static unsigned long main_thread; -static PyInterpreterState *main_interp; static volatile struct { _Py_atomic_int tripped; @@ -190,10 +187,12 @@ itimer_retval(struct itimerval *iv) #endif static int -is_main(void) +is_main(_PyRuntimeState *runtime) { - return PyThread_get_thread_ident() == main_thread && - _PyInterpreterState_Get() == main_interp; + unsigned long thread = PyThread_get_thread_ident(); + PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + return (thread == runtime->main_thread + && interp == runtime->interpreters.main); } static PyObject * @@ -474,7 +473,9 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler) return NULL; } #endif - if (!is_main()) { + + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main(runtime)) { PyErr_SetString(PyExc_ValueError, "signal only works in main thread"); return NULL; @@ -691,7 +692,8 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) return NULL; #endif - if (!is_main()) { + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main(runtime)) { PyErr_SetString(PyExc_ValueError, "set_wakeup_fd only works in main thread"); return NULL; @@ -1329,9 +1331,6 @@ PyInit__signal(void) PyObject *m, *d, *x; int i; - main_thread = PyThread_get_thread_ident(); - main_interp = _PyInterpreterState_Get(); - /* Create the module and add the functions */ m = PyModule_Create(&signalmodule); if (m == NULL) @@ -1622,7 +1621,8 @@ finisignal(void) int PyErr_CheckSignals(void) { - if (!is_main()) { + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main(runtime)) { return 0; } @@ -1716,7 +1716,8 @@ int PyOS_InterruptOccurred(void) { if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) { - if (!is_main()) { + _PyRuntimeState *runtime = &_PyRuntime; + if (!is_main(runtime)) { return 0; } _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0); @@ -1744,14 +1745,13 @@ _PySignal_AfterFork(void) * in both processes if they came in just before the fork() but before * the interpreter had an opportunity to call the handlers. issue9535. */ _clear_pending_signals(); - main_thread = PyThread_get_thread_ident(); - main_interp = _PyInterpreterState_Get(); } int _PyOS_IsMainThread(void) { - return is_main(); + _PyRuntimeState *runtime = &_PyRuntime; + return is_main(runtime); } #ifdef MS_WINDOWS From b4bdecd0fc9112b60a81fec171bc78bc13f2f59c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 13:44:24 +0200 Subject: [PATCH 087/441] bpo-36710: Add tstate parameter in errors.c (GH-13540) Add 'PyThreadState *tstate' parameter to errors.c functions to avoid relying on global variables (indirectly on _PyRuntime). --- Python/errors.c | 346 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 230 insertions(+), 116 deletions(-) diff --git a/Python/errors.c b/Python/errors.c index 1b8b7eeb0e743f..d9b69d9dc6ca52 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -27,10 +27,16 @@ _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(stderr); -void -PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) +/* Forward declaration */ +static void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, + PyObject **p_value, PyObject **p_traceback); +static void _PyErr_Clear(PyThreadState *tstate); + + +static void +_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, + PyObject *traceback) { - PyThreadState *tstate = _PyThreadState_GET(); PyObject *oldtype, *oldvalue, *oldtraceback; if (traceback != NULL && !PyTraceBack_Check(traceback)) { @@ -55,6 +61,14 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) Py_XDECREF(oldtraceback); } +void +PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Restore(tstate, type, value, traceback); +} + + _PyErr_StackItem * _PyErr_GetTopmostException(PyThreadState *tstate) { @@ -81,10 +95,9 @@ _PyErr_CreateException(PyObject *exception, PyObject *value) } } -void -PyErr_SetObject(PyObject *exception, PyObject *value) +static void +_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) { - PyThreadState *tstate = _PyThreadState_GET(); PyObject *exc_value; PyObject *tb = NULL; @@ -107,7 +120,7 @@ PyErr_SetObject(PyObject *exception, PyObject *value) /* Issue #23571: functions must not be called with an exception set */ - PyErr_Clear(); + _PyErr_Clear(tstate); fixed_value = _PyErr_CreateException(exception, value); Py_XDECREF(value); @@ -142,7 +155,14 @@ PyErr_SetObject(PyObject *exception, PyObject *value) if (value != NULL && PyExceptionInstance_Check(value)) tb = PyException_GetTraceback(value); Py_XINCREF(exception); - PyErr_Restore(exception, value, tb); + _PyErr_Restore(tstate, exception, value, tb); +} + +void +PyErr_SetObject(PyObject *exception, PyObject *value) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetObject(tstate, exception, value); } /* Set a key error with the specified argument, wrapping it in a @@ -151,34 +171,60 @@ PyErr_SetObject(PyObject *exception, PyObject *value) void _PyErr_SetKeyError(PyObject *arg) { - PyObject *tup; - tup = PyTuple_Pack(1, arg); - if (!tup) - return; /* caller will expect error to be set anyway */ - PyErr_SetObject(PyExc_KeyError, tup); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *tup = PyTuple_Pack(1, arg); + if (!tup) { + /* caller will expect error to be set anyway */ + return; + } + _PyErr_SetObject(tstate, PyExc_KeyError, tup); Py_DECREF(tup); } +static void +_PyErr_SetNone(PyThreadState *tstate, PyObject *exception) +{ + _PyErr_SetObject(tstate, exception, (PyObject *)NULL); +} + + void PyErr_SetNone(PyObject *exception) { - PyErr_SetObject(exception, (PyObject *)NULL); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetNone(tstate, exception); } -void -PyErr_SetString(PyObject *exception, const char *string) + +static void +_PyErr_SetString(PyThreadState *tstate, PyObject *exception, + const char *string) { PyObject *value = PyUnicode_FromString(string); - PyErr_SetObject(exception, value); + _PyErr_SetObject(tstate, exception, value); Py_XDECREF(value); } +void +PyErr_SetString(PyObject *exception, const char *string) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, exception, string); +} + + +static PyObject* +_PyErr_Occurred(PyThreadState *tstate) +{ + return tstate == NULL ? NULL : tstate->curexc_type; +} + PyObject* _Py_HOT_FUNCTION PyErr_Occurred(void) { PyThreadState *tstate = _PyThreadState_GET(); - return tstate == NULL ? NULL : tstate->curexc_type; + return _PyErr_Occurred(tstate); } @@ -217,7 +263,8 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) int PyErr_ExceptionMatches(PyObject *exc) { - return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc); + PyThreadState *tstate = _PyThreadState_GET(); + return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); } @@ -231,8 +278,9 @@ PyErr_ExceptionMatches(PyObject *exc) XXX: should PyErr_NormalizeException() also call PyException_SetTraceback() with the resulting value and tb? */ -void -PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) +static void +_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, + PyObject **val, PyObject **tb) { int recursion_depth = 0; PyObject *type, *value, *initial_tb; @@ -299,15 +347,16 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) Py_DECREF(value); recursion_depth++; if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) { - PyErr_SetString(PyExc_RecursionError, "maximum recursion depth " - "exceeded while normalizing an exception"); + _PyErr_SetString(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded " + "while normalizing an exception"); } /* If the new exception doesn't set a traceback and the old exception had a traceback, use the old traceback for the new exception. It's better than nothing. */ initial_tb = *tb; - PyErr_Fetch(exc, val, tb); + _PyErr_Fetch(tstate, exc, val, tb); assert(*exc != NULL); if (initial_tb != NULL) { if (*tb == NULL) @@ -334,10 +383,17 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) void -PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) { PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_NormalizeException(tstate, exc, val, tb); +} + +static void +_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, + PyObject **p_traceback) +{ *p_type = tstate->curexc_type; *p_value = tstate->curexc_value; *p_traceback = tstate->curexc_traceback; @@ -347,12 +403,30 @@ PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) tstate->curexc_traceback = NULL; } + +void +PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Fetch(tstate, p_type, p_value, p_traceback); +} + + +static void +_PyErr_Clear(PyThreadState *tstate) +{ + _PyErr_Restore(tstate, NULL, NULL, NULL); +} + + void PyErr_Clear(void) { - PyErr_Restore(NULL, NULL, NULL); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Clear(tstate); } + void PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) { @@ -397,47 +471,49 @@ _PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) if (exc == NULL) return; - if (PyErr_Occurred()) { + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyErr_Occurred(tstate)) { PyObject *exc2, *val2, *tb2; - PyErr_Fetch(&exc2, &val2, &tb2); - PyErr_NormalizeException(&exc, &val, &tb); + _PyErr_Fetch(tstate, &exc2, &val2, &tb2); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } Py_DECREF(exc); - PyErr_NormalizeException(&exc2, &val2, &tb2); + _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2); PyException_SetContext(val2, val); - PyErr_Restore(exc2, val2, tb2); + _PyErr_Restore(tstate, exc2, val2, tb2); } else { - PyErr_Restore(exc, val, tb); + _PyErr_Restore(tstate, exc, val, tb); } } static PyObject * -_PyErr_FormatVFromCause(PyObject *exception, const char *format, va_list vargs) +_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs) { PyObject *exc, *val, *val2, *tb; - assert(PyErr_Occurred()); - PyErr_Fetch(&exc, &val, &tb); - PyErr_NormalizeException(&exc, &val, &tb); + assert(_PyErr_Occurred(tstate)); + _PyErr_Fetch(tstate, &exc, &val, &tb); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } Py_DECREF(exc); - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); PyErr_FormatV(exception, format, vargs); - PyErr_Fetch(&exc, &val2, &tb); - PyErr_NormalizeException(&exc, &val2, &tb); + _PyErr_Fetch(tstate, &exc, &val2, &tb); + _PyErr_NormalizeException(tstate, &exc, &val2, &tb); Py_INCREF(val); PyException_SetCause(val2, val); PyException_SetContext(val2, val); - PyErr_Restore(exc, val2, tb); + _PyErr_Restore(tstate, exc, val2, tb); return NULL; } @@ -445,13 +521,14 @@ _PyErr_FormatVFromCause(PyObject *exception, const char *format, va_list vargs) PyObject * _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) { + PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - _PyErr_FormatVFromCause(exception, format, vargs); + _PyErr_FormatVFromCause(tstate, exception, format, vargs); va_end(vargs); return NULL; } @@ -461,21 +538,23 @@ _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) int PyErr_BadArgument(void) { - PyErr_SetString(PyExc_TypeError, - "bad argument type for built-in operation"); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, PyExc_TypeError, + "bad argument type for built-in operation"); return 0; } PyObject * PyErr_NoMemory(void) { + PyThreadState *tstate = _PyThreadState_GET(); if (Py_TYPE(PyExc_MemoryError) == NULL) { /* PyErr_NoMemory() has been called before PyExc_MemoryError has been initialized by _PyExc_Init() */ Py_FatalError("Out of memory and PyExc_MemoryError is not " "initialized yet"); } - PyErr_SetNone(PyExc_MemoryError); + _PyErr_SetNone(tstate, PyExc_MemoryError); return NULL; } @@ -488,6 +567,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) PyObject * PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *message; PyObject *v, *args; int i = errno; @@ -573,7 +653,7 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P v = PyObject_Call(exc, args, NULL); Py_DECREF(args); if (v != NULL) { - PyErr_SetObject((PyObject *) Py_TYPE(v), v); + _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); Py_DECREF(v); } } @@ -626,12 +706,17 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( PyObject *filenameObject, PyObject *filenameObject2) { + PyThreadState *tstate = _PyThreadState_GET(); int len; WCHAR *s_buf = NULL; /* Free via LocalFree */ PyObject *message; PyObject *args, *v; + DWORD err = (DWORD)ierr; - if (err==0) err = GetLastError(); + if (err==0) { + err = GetLastError(); + } + len = FormatMessageW( /* Error API error */ FORMAT_MESSAGE_ALLOCATE_BUFFER | @@ -676,7 +761,7 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( v = PyObject_Call(exc, args, NULL); Py_DECREF(args); if (v != NULL) { - PyErr_SetObject((PyObject *) Py_TYPE(v), v); + _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v); Py_DECREF(v); } } @@ -752,6 +837,7 @@ PyObject * PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path) { + PyThreadState *tstate = _PyThreadState_GET(); int issubclass; PyObject *kwargs, *error; @@ -760,12 +846,14 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, return NULL; } else if (!issubclass) { - PyErr_SetString(PyExc_TypeError, "expected a subclass of ImportError"); + _PyErr_SetString(tstate, PyExc_TypeError, + "expected a subclass of ImportError"); return NULL; } if (msg == NULL) { - PyErr_SetString(PyExc_TypeError, "expected a message argument"); + _PyErr_SetString(tstate, PyExc_TypeError, + "expected a message argument"); return NULL; } @@ -789,7 +877,7 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, error = _PyObject_FastCallDict(exception, &msg, 1, kwargs); if (error != NULL) { - PyErr_SetObject((PyObject *)Py_TYPE(error), error); + _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error); Py_DECREF(error); } @@ -828,15 +916,16 @@ PyErr_BadInternalCall(void) PyObject * PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject* string; /* Issue #23571: PyUnicode_FromFormatV() must not be called with an exception set, it calls arbitrary Python code like PyObject_Repr() */ - PyErr_Clear(); + _PyErr_Clear(tstate); string = PyUnicode_FromFormatV(format, vargs); - PyErr_SetObject(exception, string); + _PyErr_SetObject(tstate, exception, string); Py_XDECREF(string); return NULL; } @@ -860,28 +949,31 @@ PyErr_Format(PyObject *exception, const char *format, ...) PyObject * PyErr_NewException(const char *name, PyObject *base, PyObject *dict) { + PyThreadState *tstate = _PyThreadState_GET(); _Py_IDENTIFIER(__module__); - const char *dot; PyObject *modulename = NULL; PyObject *classname = NULL; PyObject *mydict = NULL; PyObject *bases = NULL; PyObject *result = NULL; - dot = strrchr(name, '.'); + + const char *dot = strrchr(name, '.'); if (dot == NULL) { - PyErr_SetString(PyExc_SystemError, - "PyErr_NewException: name must be module.class"); + _PyErr_SetString(tstate, PyExc_SystemError, + "PyErr_NewException: name must be module.class"); return NULL; } - if (base == NULL) + if (base == NULL) { base = PyExc_Exception; + } if (dict == NULL) { dict = mydict = PyDict_New(); if (dict == NULL) goto failure; } + if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) { - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { goto failure; } modulename = PyUnicode_FromStringAndSize(name, @@ -983,8 +1075,8 @@ _PyErr_Init(void) static PyObject * -make_unraisable_hook_args(PyObject *exc_type, PyObject *exc_value, - PyObject *exc_tb, PyObject *obj) +make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, PyObject *obj) { PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); if (args == NULL) { @@ -1008,7 +1100,7 @@ make_unraisable_hook_args(PyObject *exc_type, PyObject *exc_value, ADD_ITEM(obj); #undef ADD_ITEM - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { Py_DECREF(args); return NULL; } @@ -1023,8 +1115,9 @@ make_unraisable_hook_args(PyObject *exc_type, PyObject *exc_value, Do nothing if sys.stderr attribute doesn't exist or is set to None. */ static int -write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, - PyObject *exc_tb, PyObject *obj, PyObject *file) +write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, + PyObject *obj, PyObject *file) { if (obj != NULL && obj != Py_None) { if (PyFile_WriteString("Exception ignored in: ", file) < 0) { @@ -1032,7 +1125,7 @@ write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, } if (PyFile_WriteObject(obj, file, 0) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); if (PyFile_WriteString("", file) < 0) { return -1; } @@ -1045,7 +1138,7 @@ write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, if (exc_tb != NULL && exc_tb != Py_None) { if (PyTraceBack_Print(exc_tb, file) < 0) { /* continue even if writing the traceback failed */ - PyErr_Clear(); + _PyErr_Clear(tstate); } } @@ -1065,7 +1158,7 @@ write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, PyObject *moduleName = _PyObject_GetAttrId(exc_type, &PyId___module__); if (moduleName == NULL || !PyUnicode_Check(moduleName)) { Py_XDECREF(moduleName); - PyErr_Clear(); + _PyErr_Clear(tstate); if (PyFile_WriteString("", file) < 0) { return -1; } @@ -1101,7 +1194,7 @@ write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, return -1; } if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); if (PyFile_WriteString("", file) < 0) { return -1; } @@ -1116,8 +1209,8 @@ write_unraisable_exc_file(PyObject *exc_type, PyObject *exc_value, static int -write_unraisable_exc(PyObject *exc_type, PyObject *exc_value, - PyObject *exc_tb, PyObject *obj) +write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, + PyObject *exc_value, PyObject *exc_tb, PyObject *obj) { PyObject *file = _PySys_GetObjectId(&PyId_stderr); if (file == NULL || file == Py_None) { @@ -1127,7 +1220,7 @@ write_unraisable_exc(PyObject *exc_type, PyObject *exc_value, /* Hold a strong reference to ensure that sys.stderr doesn't go away while we use it */ Py_INCREF(file); - int res = write_unraisable_exc_file(exc_type, exc_value, exc_tb, + int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, obj, file); Py_DECREF(file); @@ -1138,10 +1231,12 @@ write_unraisable_exc(PyObject *exc_type, PyObject *exc_value, PyObject* _PyErr_WriteUnraisableDefaultHook(PyObject *args) { + PyThreadState *tstate = _PyThreadState_GET(); + if (Py_TYPE(args) != &UnraisableHookArgsType) { - PyErr_SetString(PyExc_TypeError, - "sys.unraisablehook argument type " - "must be UnraisableHookArgs"); + _PyErr_SetString(tstate, PyExc_TypeError, + "sys.unraisablehook argument type " + "must be UnraisableHookArgs"); return NULL; } @@ -1151,7 +1246,7 @@ _PyErr_WriteUnraisableDefaultHook(PyObject *args) PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); PyObject *obj = PyStructSequence_GET_ITEM(args, 3); - if (write_unraisable_exc(exc_type, exc_value, exc_tb, obj) < 0) { + if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, obj) < 0) { return NULL; } Py_RETURN_NONE; @@ -1168,9 +1263,11 @@ _PyErr_WriteUnraisableDefaultHook(PyObject *args) void PyErr_WriteUnraisable(PyObject *obj) { - PyObject *exc_type, *exc_value, *exc_tb; + PyThreadState *tstate = _PyThreadState_GET(); + assert(tstate != NULL); - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + PyObject *exc_type, *exc_value, *exc_tb; + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); assert(exc_type != NULL); @@ -1180,20 +1277,20 @@ PyErr_WriteUnraisable(PyObject *obj) } if (exc_tb == NULL) { - struct _frame *frame = _PyThreadState_GET()->frame; + struct _frame *frame = tstate->frame; if (frame != NULL) { exc_tb = _PyTraceBack_FromFrame(NULL, frame); if (exc_tb == NULL) { - PyErr_Clear(); + _PyErr_Clear(tstate); } } } - PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); + _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb); if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) { if (PyException_SetTraceback(exc_value, exc_tb) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } } @@ -1202,7 +1299,8 @@ PyErr_WriteUnraisable(PyObject *obj) if (hook != NULL && hook != Py_None) { PyObject *hook_args; - hook_args = make_unraisable_hook_args(exc_type, exc_value, exc_tb, obj); + hook_args = make_unraisable_hook_args(tstate, exc_type, exc_value, + exc_tb, obj); if (hook_args != NULL) { PyObject *args[1] = {hook_args}; PyObject *res = _PyObject_FastCall(hook, args, 1); @@ -1217,20 +1315,20 @@ PyErr_WriteUnraisable(PyObject *obj) Py_XDECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); obj = hook; } default_hook: /* Call the default unraisable hook (ignore failure) */ - (void)write_unraisable_exc(exc_type, exc_value, exc_tb, obj); + (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, obj); done: Py_XDECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); - PyErr_Clear(); /* Just in case */ + _PyErr_Clear(tstate); /* Just in case */ } extern PyObject *PyModule_GetWarningsModule(void); @@ -1257,37 +1355,43 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) _Py_IDENTIFIER(offset); _Py_IDENTIFIER(print_file_and_line); _Py_IDENTIFIER(text); + PyThreadState *tstate = _PyThreadState_GET(); /* add attributes for the line number and filename for the error */ - PyErr_Fetch(&exc, &v, &tb); - PyErr_NormalizeException(&exc, &v, &tb); + _PyErr_Fetch(tstate, &exc, &v, &tb); + _PyErr_NormalizeException(tstate, &exc, &v, &tb); /* XXX check that it is, indeed, a syntax error. It might not * be, though. */ tmp = PyLong_FromLong(lineno); if (tmp == NULL) - PyErr_Clear(); + _PyErr_Clear(tstate); else { - if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) - PyErr_Clear(); + if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) { + _PyErr_Clear(tstate); + } Py_DECREF(tmp); } tmp = NULL; if (col_offset >= 0) { tmp = PyLong_FromLong(col_offset); - if (tmp == NULL) - PyErr_Clear(); + if (tmp == NULL) { + _PyErr_Clear(tstate); + } + } + if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) { + _PyErr_Clear(tstate); } - if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) - PyErr_Clear(); Py_XDECREF(tmp); if (filename != NULL) { - if (_PyObject_SetAttrId(v, &PyId_filename, filename)) - PyErr_Clear(); + if (_PyObject_SetAttrId(v, &PyId_filename, filename)) { + _PyErr_Clear(tstate); + } tmp = PyErr_ProgramTextObject(filename, lineno); if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_text, tmp)) - PyErr_Clear(); + if (_PyObject_SetAttrId(v, &PyId_text, tmp)) { + _PyErr_Clear(tstate); + } Py_DECREF(tmp); } } @@ -1295,33 +1399,39 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset) if (!_PyObject_HasAttrId(v, &PyId_msg)) { tmp = PyObject_Str(v); if (tmp) { - if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) - PyErr_Clear(); + if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) { + _PyErr_Clear(tstate); + } Py_DECREF(tmp); - } else { - PyErr_Clear(); + } + else { + _PyErr_Clear(tstate); } } if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) { if (_PyObject_SetAttrId(v, &PyId_print_file_and_line, - Py_None)) - PyErr_Clear(); + Py_None)) { + _PyErr_Clear(tstate); + } } } - PyErr_Restore(exc, v, tb); + _PyErr_Restore(tstate, exc, v, tb); } void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *fileobj; if (filename != NULL) { fileobj = PyUnicode_DecodeFSDefault(filename); - if (fileobj == NULL) - PyErr_Clear(); + if (fileobj == NULL) { + _PyErr_Clear(tstate); + } } - else + else { fileobj = NULL; + } PyErr_SyntaxLocationObject(fileobj, lineno, col_offset); Py_XDECREF(fileobj); } @@ -1333,7 +1443,7 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) functionality in tb_displayline() in traceback.c. */ static PyObject * -err_programtext(FILE *fp, int lineno) +err_programtext(PyThreadState *tstate, FILE *fp, int lineno) { int i; char linebuf[1000]; @@ -1359,7 +1469,7 @@ err_programtext(FILE *fp, int lineno) PyObject *res; res = PyUnicode_FromString(linebuf); if (res == NULL) - PyErr_Clear(); + _PyErr_Clear(tstate); return res; } return NULL; @@ -1369,24 +1479,28 @@ PyObject * PyErr_ProgramText(const char *filename, int lineno) { FILE *fp; - if (filename == NULL || *filename == '\0' || lineno <= 0) + if (filename == NULL || *filename == '\0' || lineno <= 0) { return NULL; + } + PyThreadState *tstate = _PyThreadState_GET(); fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE); - return err_programtext(fp, lineno); + return err_programtext(tstate, fp, lineno); } PyObject * PyErr_ProgramTextObject(PyObject *filename, int lineno) { - FILE *fp; - if (filename == NULL || lineno <= 0) + if (filename == NULL || lineno <= 0) { return NULL; - fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); + } + + PyThreadState *tstate = _PyThreadState_GET(); + FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); if (fp == NULL) { - PyErr_Clear(); + _PyErr_Clear(tstate); return NULL; } - return err_programtext(fp, lineno); + return err_programtext(tstate, fp, lineno); } #ifdef __cplusplus From b3a9843cd19039808a812ca11206881c94c64e3b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 15:16:08 +0200 Subject: [PATCH 088/441] Support Py_UNUSED() on clang (GH-13544) --- Doc/c-api/intro.rst | 2 +- Include/pymacro.h | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index b003bbaeff2f5b..672936a458f463 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -156,7 +156,7 @@ complete listing. .. c:macro:: Py_UNUSED(arg) Use this for unused arguments in a function definition to silence compiler - warnings, e.g. ``PyObject* func(PyObject *Py_UNUSED(ignored))``. + warnings. Example: ``int func(int a, int Py_UNUSED(b)) { return a; }``. .. versionadded:: 3.4 diff --git a/Include/pymacro.h b/Include/pymacro.h index 546f9c6e702025..1890619099a35b 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -89,10 +89,15 @@ /* Check if pointer "p" is aligned to "a"-bytes boundary. */ #define _Py_IS_ALIGNED(p, a) (!((uintptr_t)(p) & (uintptr_t)((a) - 1))) -#ifdef __GNUC__ -#define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) +/* Use this for unused arguments in a function definition to silence compiler + * warnings. Example: + * + * int func(int a, int Py_UNUSED(b)) { return a; } + */ +#if defined(__GNUC__) || defined(__clang__) +# define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) #else -#define Py_UNUSED(name) _unused_ ## name +# define Py_UNUSED(name) _unused_ ## name #endif #define Py_UNREACHABLE() abort() From b49858b4b7b4c9d85ef6946ad020f83e4fa1caa7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 15:20:23 +0200 Subject: [PATCH 089/441] bpo-37031: Fix PyOS_AfterFork_Child() (GH-13537) PyOS_AfterFork_Child(): _PyInterpreterState_DeleteExceptMain() must be called after _PyRuntimeState_ReInitThreads(). _PyRuntimeState_ReInitThreads() resets interpreters mutex after fork, mutex used by _PyInterpreterState_DeleteExceptMain(). --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8ebe3a0be05350..cd5b5ce082ece4 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -448,11 +448,11 @@ PyOS_AfterFork_Child(void) { _PyRuntimeState *runtime = &_PyRuntime; _PyGILState_Reinit(runtime); - _PyInterpreterState_DeleteExceptMain(runtime); _PyEval_ReInitThreads(runtime); _PyImport_ReInitLock(); _PySignal_AfterFork(); _PyRuntimeState_ReInitThreads(runtime); + _PyInterpreterState_DeleteExceptMain(runtime); run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0); } From 13d4e6a4a090031f8214e058ed3c8fd47767e05f Mon Sep 17 00:00:00 2001 From: Nick Sung Date: Fri, 24 May 2019 21:50:35 +0800 Subject: [PATCH 090/441] Fix typos in Doc/library/email.generator.rst documentation (GH-13539) --- Doc/library/email.generator.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index c09ae8cbc60410..2d9bae6a7ee57b 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -36,7 +36,7 @@ something that contains only ASCII characters, using the standard email RFC Content Transfer Encoding techniques for encoding email messages for transport over channels that are not "8 bit clean". -To accomodate reproducible processing of SMIME-signed messages +To accommodate reproducible processing of SMIME-signed messages :class:`Generator` disables header folding for message parts of type ``multipart/signed`` and all subparts. From 438a12dd9d85f463c0bb7bf1505cd87b98b98170 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 17:01:38 +0200 Subject: [PATCH 091/441] bpo-36710: Add tstate parameter in ceval.c (GH-13547) * Fix a possible reference leak in _PyErr_Print() if exception is NULL. * PyErr_BadInternalCall(): replace PyErr_Format() with _PyErr_SetString(). * Add pycore_pyerrors.h header file. * New functions: * _PyErr_Clear() * _PyErr_Fetch() * _PyErr_Print() * _PyErr_Restore() * _PyErr_SetObject() * _PyErr_SetString() * Add 'tstate' parameter to _PyEval_AddPendingCall(). --- Include/internal/pycore_ceval.h | 1 + Include/internal/pycore_pyerrors.h | 62 +++ Include/internal/pycore_pylifecycle.h | 2 + Include/internal/pycore_pymem.h | 6 +- Makefile.pre.in | 1 + Modules/signalmodule.c | 5 +- PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 + Python/ceval.c | 732 ++++++++++++++------------ Python/errors.c | 92 ++-- Python/pythonrun.c | 61 ++- 11 files changed, 563 insertions(+), 403 deletions(-) create mode 100644 Include/internal/pycore_pyerrors.h diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 7a3166e86dab7f..37170ed438f8bb 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -19,6 +19,7 @@ PyAPI_FUNC(void) _PyEval_FiniThreads( PyAPI_FUNC(void) _PyEval_SignalReceived( struct _ceval_runtime_state *ceval); PyAPI_FUNC(int) _PyEval_AddPendingCall( + PyThreadState *tstate, struct _ceval_runtime_state *ceval, int (*func)(void *), void *arg); diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h new file mode 100644 index 00000000000000..23327ef7839743 --- /dev/null +++ b/Include/internal/pycore_pyerrors.h @@ -0,0 +1,62 @@ +#ifndef Py_INTERNAL_PYERRORS_H +#define Py_INTERNAL_PYERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) +{ + return tstate == NULL ? NULL : tstate->curexc_type; +} + + +PyAPI_FUNC(void) _PyErr_Fetch( + PyThreadState *tstate, + PyObject **type, + PyObject **value, + PyObject **traceback); + +PyAPI_FUNC(int) _PyErr_ExceptionMatches( + PyThreadState *tstate, + PyObject *exc); + +PyAPI_FUNC(void) _PyErr_Restore( + PyThreadState *tstate, + PyObject *type, + PyObject *value, + PyObject *traceback); + +PyAPI_FUNC(void) _PyErr_SetObject( + PyThreadState *tstate, + PyObject *type, + PyObject *value); + +PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate); + +PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); + +PyAPI_FUNC(void) _PyErr_SetString( + PyThreadState *tstate, + PyObject *exception, + const char *string); + +PyAPI_FUNC(PyObject *) _PyErr_Format( + PyThreadState *tstate, + PyObject *exception, + const char *format, + ...); + +PyAPI_FUNC(void) _PyErr_NormalizeException( + PyThreadState *tstate, + PyObject **exc, + PyObject **val, + PyObject **tb); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYERRORS_H */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 07cf815363b779..13a31c262da8c4 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -106,6 +106,8 @@ PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p); PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); +PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index dcc492af01702c..22677d373855ca 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -1,5 +1,5 @@ -#ifndef Py_INTERNAL_MEM_H -#define Py_INTERNAL_MEM_H +#ifndef Py_INTERNAL_PYMEM_H +#define Py_INTERNAL_PYMEM_H #ifdef __cplusplus extern "C" { #endif @@ -191,4 +191,4 @@ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); #ifdef __cplusplus } #endif -#endif /* !Py_INTERNAL_MEM_H */ +#endif /* !Py_INTERNAL_PYMEM_H */ diff --git a/Makefile.pre.in b/Makefile.pre.in index 12891e938236a4..a149fdec4dcf40 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1077,6 +1077,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_hamt.h \ $(srcdir)/Include/internal/pycore_object.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \ + $(srcdir)/Include/internal/pycore_pyerrors.h \ $(srcdir)/Include/internal/pycore_pyhash.h \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ $(srcdir)/Include/internal/pycore_pymem.h \ diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index ed3852d444e80a..7698984ff3afe1 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -258,6 +258,7 @@ trip_signal(int sig_num) /* Notify ceval.c */ _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); _PyEval_SignalReceived(&runtime->ceval); /* And then write to the wakeup fd *after* setting all the globals and @@ -298,7 +299,7 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(&runtime->ceval, + _PyEval_AddPendingCall(tstate, &runtime->ceval, report_wakeup_send_error, (void *)(intptr_t) last_error); } @@ -317,7 +318,7 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(&runtime->ceval, + _PyEval_AddPendingCall(tstate, &runtime->ceval, report_wakeup_write_error, (void *)(intptr_t)errno); } diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 681c4db65df0ac..10f51dd431b7c1 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -168,6 +168,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 32964c008aa257..396d146513d799 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -207,6 +207,9 @@ Include + + Include + Include diff --git a/Python/ceval.c b/Python/ceval.c index 781b10dfac9aef..cb5a4beb2a6633 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -12,6 +12,8 @@ #include "Python.h" #include "pycore_ceval.h" #include "pycore_object.h" +#include "pycore_pyerrors.h" +#include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" @@ -50,7 +52,7 @@ static PyObject * do_call_core( #ifdef LLTRACE static int lltrace; -static int prtrace(PyObject *, const char *); +static int prtrace(PyThreadState *, PyObject *, const char *); #endif static int call_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, @@ -67,19 +69,19 @@ static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *); static void dtrace_function_entry(PyFrameObject *); static void dtrace_function_return(PyFrameObject *); -static PyObject * cmp_outcome(int, PyObject *, PyObject *); -static PyObject * import_name(PyFrameObject *, PyObject *, PyObject *, - PyObject *); -static PyObject * import_from(PyObject *, PyObject *); -static int import_all_from(PyObject *, PyObject *); -static void format_exc_check_arg(PyObject *, const char *, PyObject *); -static void format_exc_unbound(PyCodeObject *co, int oparg); -static PyObject * unicode_concatenate(PyObject *, PyObject *, +static PyObject * cmp_outcome(PyThreadState *, int, PyObject *, PyObject *); +static PyObject * import_name(PyThreadState *, PyFrameObject *, + PyObject *, PyObject *, PyObject *); +static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); +static int import_all_from(PyThreadState *, PyObject *, PyObject *); +static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); +static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); +static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *, PyFrameObject *, const _Py_CODEUNIT *); -static PyObject * special_lookup(PyObject *, _Py_Identifier *); -static int check_args_iterable(PyObject *func, PyObject *vararg); -static void format_kwargs_error(PyObject *func, PyObject *kwargs); -static void format_awaitable_error(PyTypeObject *, int); +static PyObject * special_lookup(PyThreadState *, PyObject *, _Py_Identifier *); +static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); +static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); +static void format_awaitable_error(PyThreadState *, PyTypeObject *, int); #define NAME_ERROR_MSG \ "name '%.200s' is not defined" @@ -420,7 +422,8 @@ _pop_pending_call(struct _pending_calls *pending, */ int -_PyEval_AddPendingCall(struct _ceval_runtime_state *ceval, +_PyEval_AddPendingCall(PyThreadState *tstate, + struct _ceval_runtime_state *ceval, int (*func)(void *), void *arg) { struct _pending_calls *pending = &ceval->pending; @@ -430,12 +433,12 @@ _PyEval_AddPendingCall(struct _ceval_runtime_state *ceval, PyThread_release_lock(pending->lock); PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); - PyErr_SetString(PyExc_SystemError, + _PyErr_Fetch(tstate, &exc, &val, &tb); + _PyErr_SetString(tstate, PyExc_SystemError, "Py_AddPendingCall: cannot add pending calls " "(Python shutting down)"); - PyErr_Print(); - PyErr_Restore(exc, val, tb); + _PyErr_Print(tstate); + _PyErr_Restore(tstate, exc, val, tb); return -1; } int result = _push_pending_call(pending, func, arg); @@ -449,7 +452,9 @@ _PyEval_AddPendingCall(struct _ceval_runtime_state *ceval, int Py_AddPendingCall(int (*func)(void *), void *arg) { - return _PyEval_AddPendingCall(&_PyRuntime.ceval, func, arg); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + return _PyEval_AddPendingCall(tstate, &runtime->ceval, func, arg); } static int @@ -535,6 +540,7 @@ _Py_FinishPendingCalls(_PyRuntimeState *runtime) { assert(PyGILState_Check()); + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); struct _pending_calls *pending = &runtime->ceval.pending; PyThread_acquire_lock(pending->lock, WAIT_LOCK); @@ -547,10 +553,10 @@ _Py_FinishPendingCalls(_PyRuntimeState *runtime) if (make_pending_calls(runtime) < 0) { PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + _PyErr_Fetch(tstate, &exc, &val, &tb); PyErr_BadInternalCall(); _PyErr_ChainExceptions(exc, val, tb); - PyErr_Print(); + _PyErr_Print(tstate); } } @@ -623,7 +629,7 @@ _Py_CheckRecursiveCall(const char *where) tstate->stackcheck_counter = 0; if (PyOS_CheckStack()) { --tstate->recursion_depth; - PyErr_SetString(PyExc_MemoryError, "Stack overflow"); + _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); return -1; } /* Needed for ABI backwards-compatibility (see bpo-31857) */ @@ -642,16 +648,16 @@ _Py_CheckRecursiveCall(const char *where) if (tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; tstate->overflowed = 1; - PyErr_Format(PyExc_RecursionError, - "maximum recursion depth exceeded%s", - where); + _PyErr_Format(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded%s", + where); return -1; } return 0; } static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); -static int unpack_iterable(PyObject *, int, int, PyObject **); +static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); #define _Py_TracingPossible(ceval) ((ceval)->tracing_possible) @@ -908,24 +914,24 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) #ifdef LLTRACE #define PUSH(v) { (void)(BASIC_PUSH(v), \ - lltrace && prtrace(TOP(), "push")); \ + lltrace && prtrace(tstate, TOP(), "push")); \ assert(STACK_LEVEL() <= co->co_stacksize); } -#define POP() ((void)(lltrace && prtrace(TOP(), "pop")), \ +#define POP() ((void)(lltrace && prtrace(tstate, TOP(), "pop")), \ BASIC_POP()) #define STACK_GROW(n) do { \ assert(n >= 0); \ (void)(BASIC_STACKADJ(n), \ - lltrace && prtrace(TOP(), "stackadj")); \ + lltrace && prtrace(tstate, TOP(), "stackadj")); \ assert(STACK_LEVEL() <= co->co_stacksize); \ } while (0) #define STACK_SHRINK(n) do { \ assert(n >= 0); \ - (void)(lltrace && prtrace(TOP(), "stackadj")); \ + (void)(lltrace && prtrace(tstate, TOP(), "stackadj")); \ (void)(BASIC_STACKADJ(-n)); \ assert(STACK_LEVEL() <= co->co_stacksize); \ } while (0) #define EXT_POP(STACK_POINTER) ((void)(lltrace && \ - prtrace((STACK_POINTER)[-1], "ext_pop")), \ + prtrace(tstate, (STACK_POINTER)[-1], "ext_pop")), \ *--(STACK_POINTER)) #else #define PUSH(v) BASIC_PUSH(v) @@ -1070,14 +1076,14 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* PyEval_EvalFrameEx() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); #endif main_loop: for (;;) { assert(stack_pointer >= f->f_valuestack); /* else underflow */ assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); /* Do periodic things. Doing this every time through the loop would add too much overhead, so we do it @@ -1146,7 +1152,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *exc = tstate->async_exc; tstate->async_exc = NULL; UNSIGNAL_ASYNC_EXC(ceval); - PyErr_SetNone(exc); + _PyErr_SetNone(tstate, exc); Py_DECREF(exc); goto error; } @@ -1222,7 +1228,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) case TARGET(LOAD_FAST): { PyObject *value = GETLOCAL(oparg); if (value == NULL) { - format_exc_check_arg(PyExc_UnboundLocalError, + format_exc_check_arg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(co->co_varnames, oparg)); goto error; @@ -1441,7 +1447,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) speedup on microbenchmarks. */ if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(left, right, f, next_instr); + sum = unicode_concatenate(tstate, left, right, f, next_instr); /* unicode_concatenate consumed the ref to left */ } else { @@ -1640,7 +1646,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *left = TOP(); PyObject *sum; if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(left, right, f, next_instr); + sum = unicode_concatenate(tstate, left, right, f, next_instr); /* unicode_concatenate consumed the ref to left */ } else { @@ -1762,8 +1768,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *hook = _PySys_GetObjectId(&PyId_displayhook); PyObject *res; if (hook == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "lost sys.displayhook"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "lost sys.displayhook"); Py_DECREF(value); goto error; } @@ -1790,8 +1796,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } break; default: - PyErr_SetString(PyExc_SystemError, - "bad RAISE_VARARGS oparg"); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); break; } goto error; @@ -1823,11 +1829,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } else { SET_TOP(NULL); - PyErr_Format( - PyExc_TypeError, - "'async for' requires an object with " - "__aiter__ method, got %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); Py_DECREF(obj); goto error; } @@ -1836,11 +1841,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) Py_TYPE(iter)->tp_as_async->am_anext == NULL) { SET_TOP(NULL); - PyErr_Format( - PyExc_TypeError, - "'async for' received an object from __aiter__ " - "that does not implement __anext__: %.100s", - Py_TYPE(iter)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); Py_DECREF(iter); goto error; } @@ -1873,11 +1877,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } } else { - PyErr_Format( - PyExc_TypeError, - "'async for' requires an iterator with " - "__anext__ method, got %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); goto error; } @@ -1907,7 +1910,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *iter = _PyCoro_GetAwaitableIter(iterable); if (iter == NULL) { - format_awaitable_error(Py_TYPE(iterable), + format_awaitable_error(tstate, Py_TYPE(iterable), _Py_OPCODE(next_instr[-2])); } @@ -1921,9 +1924,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) being awaited on. */ Py_DECREF(yf); Py_CLEAR(iter); - PyErr_SetString( - PyExc_RuntimeError, - "coroutine is being awaited already"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); /* The code below jumps to `error` if `iter` is NULL. */ } } @@ -1955,7 +1957,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (retval == NULL) { PyObject *val; if (tstate->c_tracefunc != NULL - && PyErr_ExceptionMatches(PyExc_StopIteration)) + && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); err = _PyGen_FetchStopIterationValue(&val); if (err < 0) @@ -1994,8 +1996,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) _PyErr_StackItem *exc_info; PyTryBlock *b = PyFrame_BlockPop(f); if (b->b_type != EXCEPT_HANDLER) { - PyErr_SetString(PyExc_SystemError, - "popped block is not an except handler"); + _PyErr_SetString(tstate, PyExc_SystemError, + "popped block is not an except handler"); goto error; } assert(STACK_LEVEL() >= (b)->b_level + 3 && @@ -2047,8 +2049,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) _PyErr_StackItem *exc_info; PyTryBlock *b = PyFrame_BlockPop(f); if (b->b_type != EXCEPT_HANDLER) { - PyErr_SetString(PyExc_SystemError, - "popped block is not an except handler"); + _PyErr_SetString(tstate, PyExc_SystemError, + "popped block is not an except handler"); Py_XDECREF(res); goto error; } @@ -2104,7 +2106,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) else if (PyLong_CheckExact(exc)) { int ret = _PyLong_AsInt(exc); Py_DECREF(exc); - if (ret == -1 && PyErr_Occurred()) { + if (ret == -1 && _PyErr_Occurred(tstate)) { goto error; } JUMPTO(ret); @@ -2114,7 +2116,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) assert(PyExceptionClass_Check(exc)); PyObject *val = POP(); PyObject *tb = POP(); - PyErr_Restore(exc, val, tb); + _PyErr_Restore(tstate, exc, val, tb); goto exception_unwind; } } @@ -2134,7 +2136,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) else { PyObject *val = POP(); PyObject *tb = POP(); - PyErr_Restore(exc, val, tb); + _PyErr_Restore(tstate, exc, val, tb); goto exception_unwind; } } @@ -2146,9 +2148,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (PyDict_CheckExact(f->f_builtins)) { bc = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___build_class__); if (bc == NULL) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError, - "__build_class__ not found"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); } goto error; } @@ -2160,9 +2162,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) goto error; bc = PyObject_GetItem(f->f_builtins, build_class_str); if (bc == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_SetString(PyExc_NameError, - "__build_class__ not found"); + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); goto error; } } @@ -2176,8 +2178,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *ns = f->f_locals; int err; if (ns == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals found when storing %R", name); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); Py_DECREF(v); goto error; } @@ -2196,13 +2198,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *ns = f->f_locals; int err; if (ns == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals when deleting %R", name); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); goto error; } err = PyObject_DelItem(ns, name); if (err != 0) { - format_exc_check_arg(PyExc_NameError, + format_exc_check_arg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); goto error; @@ -2229,7 +2231,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) Py_INCREF(item); PUSH(item); } - } else if (unpack_iterable(seq, oparg, -1, + } else if (unpack_iterable(tstate, seq, oparg, -1, stack_pointer + oparg)) { STACK_GROW(oparg); } else { @@ -2245,7 +2247,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject *seq = POP(); - if (unpack_iterable(seq, oparg & 0xFF, oparg >> 8, + if (unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, stack_pointer + totalargs)) { stack_pointer += totalargs; } else { @@ -2297,9 +2299,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) int err; err = PyDict_DelItem(f->f_globals, name); if (err != 0) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) { - format_exc_check_arg( - PyExc_NameError, NAME_ERROR_MSG, name); + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); } goto error; } @@ -2311,8 +2313,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *locals = f->f_locals; PyObject *v; if (locals == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals when loading %R", name); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when loading %R", name); goto error; } if (PyDict_CheckExact(locals)) { @@ -2320,16 +2322,16 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (v != NULL) { Py_INCREF(v); } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto error; } } else { v = PyObject_GetItem(locals, name); if (v == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) goto error; - PyErr_Clear(); + _PyErr_Clear(tstate); } } if (v == NULL) { @@ -2337,16 +2339,16 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (v != NULL) { Py_INCREF(v); } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto error; } else { if (PyDict_CheckExact(f->f_builtins)) { v = PyDict_GetItemWithError(f->f_builtins, name); if (v == NULL) { - if (!PyErr_Occurred()) { + if (!_PyErr_Occurred(tstate)) { format_exc_check_arg( - PyExc_NameError, + tstate, PyExc_NameError, NAME_ERROR_MSG, name); } goto error; @@ -2356,10 +2358,11 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) else { v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { format_exc_check_arg( - PyExc_NameError, + tstate, PyExc_NameError, NAME_ERROR_MSG, name); + } goto error; } } @@ -2382,7 +2385,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (!_PyErr_OCCURRED()) { /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ - format_exc_check_arg(PyExc_NameError, + format_exc_check_arg(tstate, PyExc_NameError, NAME_ERROR_MSG, name); } goto error; @@ -2395,17 +2398,19 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* namespace 1: globals */ v = PyObject_GetItem(f->f_globals, name); if (v == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; - PyErr_Clear(); + } + _PyErr_Clear(tstate); /* namespace 2: builtins */ v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { - if (PyErr_ExceptionMatches(PyExc_KeyError)) + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { format_exc_check_arg( - PyExc_NameError, + tstate, PyExc_NameError, NAME_ERROR_MSG, name); + } goto error; } } @@ -2421,7 +2426,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) DISPATCH(); } format_exc_check_arg( - PyExc_UnboundLocalError, + tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(co->co_varnames, oparg) ); @@ -2436,7 +2441,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) Py_DECREF(oldobj); DISPATCH(); } - format_exc_unbound(co, oparg); + format_exc_unbound(tstate, co, oparg); goto error; } @@ -2460,23 +2465,24 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (value != NULL) { Py_INCREF(value); } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto error; } } else { value = PyObject_GetItem(locals, name); if (value == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; - PyErr_Clear(); + } + _PyErr_Clear(tstate); } } if (!value) { PyObject *cell = freevars[oparg]; value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(co, oparg); + format_exc_unbound(tstate, co, oparg); goto error; } Py_INCREF(value); @@ -2489,7 +2495,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *cell = freevars[oparg]; PyObject *value = PyCell_GET(cell); if (value == NULL) { - format_exc_unbound(co, oparg); + format_exc_unbound(tstate, co, oparg); goto error; } Py_INCREF(value); @@ -2565,9 +2571,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) none_val = _PyList_Extend((PyListObject *)sum, PEEK(i)); if (none_val == NULL) { if (opcode == BUILD_TUPLE_UNPACK_WITH_CALL && - PyErr_ExceptionMatches(PyExc_TypeError)) + _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { - check_args_iterable(PEEK(1 + oparg), PEEK(i)); + check_args_iterable(tstate, PEEK(1 + oparg), PEEK(i)); } Py_DECREF(sum); goto error; @@ -2660,8 +2666,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) int err; PyObject *ann_dict; if (f->f_locals == NULL) { - PyErr_Format(PyExc_SystemError, - "no locals found when setting up annotations"); + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); goto error; } /* check if __annotations__ in locals()... */ @@ -2669,7 +2675,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) ann_dict = _PyDict_GetItemIdWithError(f->f_locals, &PyId___annotations__); if (ann_dict == NULL) { - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { goto error; } /* ...if not, create a new one */ @@ -2693,10 +2699,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } ann_dict = PyObject_GetItem(f->f_locals, ann_str); if (ann_dict == NULL) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { goto error; } - PyErr_Clear(); + _PyErr_Clear(tstate); ann_dict = PyDict_New(); if (ann_dict == NULL) { goto error; @@ -2720,8 +2726,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *keys = TOP(); if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { - PyErr_SetString(PyExc_SystemError, - "bad BUILD_CONST_KEY_MAP keys argument"); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); goto error; } map = _PyDict_NewPresized((Py_ssize_t)oparg); @@ -2756,10 +2762,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) for (i = oparg; i > 0; i--) { PyObject *arg = PEEK(i); if (PyDict_Update(sum, arg) < 0) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_TypeError, - "'%.200s' object is not a mapping", - arg->ob_type->tp_name); + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + arg->ob_type->tp_name); } Py_DECREF(sum); goto error; @@ -2782,7 +2788,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *arg = PEEK(i); if (_PyDict_MergeEx(sum, arg, 2) < 0) { Py_DECREF(sum); - format_kwargs_error(PEEK(2 + oparg), arg); + format_kwargs_error(tstate, PEEK(2 + oparg), arg); goto error; } } @@ -2824,7 +2830,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) case TARGET(COMPARE_OP): { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *res = cmp_outcome(oparg, left, right); + PyObject *res = cmp_outcome(tstate, oparg, left, right); Py_DECREF(left); Py_DECREF(right); SET_TOP(res); @@ -2840,7 +2846,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *fromlist = POP(); PyObject *level = TOP(); PyObject *res; - res = import_name(f, name, fromlist, level); + res = import_name(tstate, f, name, fromlist, level); Py_DECREF(level); Py_DECREF(fromlist); SET_TOP(res); @@ -2859,12 +2865,12 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) locals = f->f_locals; if (locals == NULL) { - PyErr_SetString(PyExc_SystemError, - "no locals found during 'import *'"); + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found during 'import *'"); Py_DECREF(from); goto error; } - err = import_all_from(locals, from); + err = import_all_from(tstate, locals, from); PyFrame_LocalsToFast(f, 0); Py_DECREF(from); if (err != 0) @@ -2876,7 +2882,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *name = GETITEM(names, oparg); PyObject *from = TOP(); PyObject *res; - res = import_from(from, name); + res = import_from(tstate, from, name); PUSH(res); if (res == NULL) goto error; @@ -3027,9 +3033,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) regular generator. */ Py_DECREF(iterable); SET_TOP(NULL); - PyErr_SetString(PyExc_TypeError, - "cannot 'yield from' a coroutine object " - "in a non-coroutine generator"); + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); goto error; } } @@ -3056,12 +3062,14 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PREDICT(UNPACK_SEQUENCE); DISPATCH(); } - if (PyErr_Occurred()) { - if (!PyErr_ExceptionMatches(PyExc_StopIteration)) + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { goto error; - else if (tstate->c_tracefunc != NULL) + } + else if (tstate->c_tracefunc != NULL) { call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); - PyErr_Clear(); + } + _PyErr_Clear(tstate); } /* iterator ended normally */ STACK_SHRINK(1); @@ -3087,13 +3095,13 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) _Py_IDENTIFIER(__aenter__); PyObject *mgr = TOP(); - PyObject *exit = special_lookup(mgr, &PyId___aexit__), + PyObject *exit = special_lookup(tstate, mgr, &PyId___aexit__), *enter; PyObject *res; if (exit == NULL) goto error; SET_TOP(exit); - enter = special_lookup(mgr, &PyId___aenter__); + enter = special_lookup(tstate, mgr, &PyId___aenter__); Py_DECREF(mgr); if (enter == NULL) goto error; @@ -3120,11 +3128,12 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) _Py_IDENTIFIER(__exit__); _Py_IDENTIFIER(__enter__); PyObject *mgr = TOP(); - PyObject *enter = special_lookup(mgr, &PyId___enter__), *exit; + PyObject *enter = special_lookup(tstate, mgr, &PyId___enter__); PyObject *res; - if (enter == NULL) + if (enter == NULL) { goto error; - exit = special_lookup(mgr, &PyId___exit__); + } + PyObject *exit = special_lookup(tstate, mgr, &PyId___exit__); if (exit == NULL) { Py_DECREF(enter); goto error; @@ -3380,7 +3389,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) goto error; if (_PyDict_MergeEx(d, kwargs, 2) < 0) { Py_DECREF(d); - format_kwargs_error(SECOND(), kwargs); + format_kwargs_error(tstate, SECOND(), kwargs); Py_DECREF(kwargs); goto error; } @@ -3392,7 +3401,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) callargs = POP(); func = TOP(); if (!PyTuple_CheckExact(callargs)) { - if (check_args_iterable(func, callargs) < 0) { + if (check_args_iterable(tstate, func, callargs) < 0) { Py_DECREF(callargs); goto error; } @@ -3485,9 +3494,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) case FVC_REPR: conv_fn = PyObject_Repr; break; case FVC_ASCII: conv_fn = PyObject_ASCII; break; default: - PyErr_Format(PyExc_SystemError, - "unexpected conversion flag %d", - which_conversion); + _PyErr_Format(tstate, PyExc_SystemError, + "unexpected conversion flag %d", + which_conversion); goto error; } @@ -3542,7 +3551,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) "XXX lineno: %d, opcode: %d\n", PyFrame_GetLineNumber(f), opcode); - PyErr_SetString(PyExc_SystemError, "unknown opcode"); + _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode"); goto error; } /* switch */ @@ -3554,11 +3563,12 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) error: /* Double-check exception status. */ #ifdef NDEBUG - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_SystemError, - "error return without exception set"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_SystemError, + "error return without exception set"); + } #else - assert(PyErr_Occurred()); + assert(_PyErr_Occurred(tstate)); #endif /* Log traceback info. */ @@ -3594,13 +3604,12 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) Py_INCREF(Py_None); PUSH(Py_None); } - PyErr_Fetch(&exc, &val, &tb); + _PyErr_Fetch(tstate, &exc, &val, &tb); /* Make the raw exception data available to the handler, so a program can emulate the Python main loop. */ - PyErr_NormalizeException( - &exc, &val, &tb); + _PyErr_NormalizeException(tstate, &exc, &val, &tb); if (tb != NULL) PyException_SetTraceback(val, tb); else @@ -3627,7 +3636,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } /* main loop */ assert(retval == NULL); - assert(PyErr_Occurred()); + assert(_PyErr_Occurred(tstate)); exit_returning: @@ -3665,7 +3674,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } static void -format_missing(const char *kind, PyCodeObject *co, PyObject *names) +format_missing(PyThreadState *tstate, const char *kind, + PyCodeObject *co, PyObject *names) { int err; Py_ssize_t len = PyList_GET_SIZE(names); @@ -3716,18 +3726,19 @@ format_missing(const char *kind, PyCodeObject *co, PyObject *names) } if (name_str == NULL) return; - PyErr_Format(PyExc_TypeError, - "%U() missing %i required %s argument%s: %U", - co->co_name, - len, - kind, - len == 1 ? "" : "s", - name_str); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() missing %i required %s argument%s: %U", + co->co_name, + len, + kind, + len == 1 ? "" : "s", + name_str); Py_DECREF(name_str); } static void -missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount, +missing_arguments(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t missing, Py_ssize_t defcount, PyObject **fastlocals) { Py_ssize_t i, j = 0; @@ -3760,12 +3771,13 @@ missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount, } } assert(j == missing); - format_missing(kind, co, missing_names); + format_missing(tstate, kind, co, missing_names); Py_DECREF(missing_names); } static void -too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount, +too_many_positional(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t given, Py_ssize_t defcount, PyObject **fastlocals) { int plural; @@ -3810,21 +3822,21 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount, kwonly_sig = PyUnicode_FromString(""); assert(kwonly_sig != NULL); } - PyErr_Format(PyExc_TypeError, - "%U() takes %U positional argument%s but %zd%U %s given", - co->co_name, - sig, - plural ? "s" : "", - given, - kwonly_sig, - given == 1 && !kwonly_given ? "was" : "were"); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() takes %U positional argument%s but %zd%U %s given", + co->co_name, + sig, + plural ? "s" : "", + given, + kwonly_sig, + given == 1 && !kwonly_given ? "was" : "were"); Py_DECREF(sig); Py_DECREF(kwonly_sig); } static int -positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount, - PyObject* const* kwnames) +positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, + Py_ssize_t kwcount, PyObject* const* kwnames) { int posonly_conflicts = 0; PyObject* posonly_names = PyList_New(0); @@ -3866,10 +3878,10 @@ positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount, if (error_names == NULL) { goto fail; } - PyErr_Format(PyExc_TypeError, - "%U() got some positional-only arguments passed" - " as keyword arguments: '%U'", - co->co_name, error_names); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got some positional-only arguments passed" + " as keyword arguments: '%U'", + co->co_name, error_names); Py_DECREF(error_names); goto fail; } @@ -3905,15 +3917,16 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, Py_ssize_t i, j, n; PyObject *kwdict; + PyThreadState *tstate = _PyThreadState_GET(); + assert(tstate != NULL); + if (globals == NULL) { - PyErr_SetString(PyExc_SystemError, - "PyEval_EvalCodeEx: NULL globals"); + _PyErr_SetString(tstate, PyExc_SystemError, + "PyEval_EvalCodeEx: NULL globals"); return NULL; } /* Create the frame */ - PyThreadState *tstate = _PyThreadState_GET(); - assert(tstate != NULL); f = _PyFrame_New_NoTrack(tstate, co, globals, locals); if (f == NULL) { return NULL; @@ -3981,9 +3994,9 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, Py_ssize_t j; if (keyword == NULL || !PyUnicode_Check(keyword)) { - PyErr_Format(PyExc_TypeError, - "%U() keywords must be strings", - co->co_name); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() keywords must be strings", + co->co_name); goto fail; } @@ -4012,13 +4025,16 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, assert(j >= total_args); if (kwdict == NULL) { - if (co->co_posonlyargcount && positional_only_passed_as_keyword(co, kwcount, kwnames)) { + if (co->co_posonlyargcount + && positional_only_passed_as_keyword(tstate, co, + kwcount, kwnames)) + { goto fail; } - PyErr_Format(PyExc_TypeError, - "%U() got an unexpected keyword argument '%S'", - co->co_name, keyword); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got an unexpected keyword argument '%S'", + co->co_name, keyword); goto fail; } @@ -4029,9 +4045,9 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, kw_found: if (GETLOCAL(j) != NULL) { - PyErr_Format(PyExc_TypeError, - "%U() got multiple values for argument '%S'", - co->co_name, keyword); + _PyErr_Format(tstate, PyExc_TypeError, + "%U() got multiple values for argument '%S'", + co->co_name, keyword); goto fail; } Py_INCREF(value); @@ -4040,7 +4056,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, /* Check the number of positional arguments */ if ((argcount > co->co_argcount + co->co_posonlyargcount) && !(co->co_flags & CO_VARARGS)) { - too_many_positional(co, argcount, defcount, fastlocals); + too_many_positional(tstate, co, argcount, defcount, fastlocals); goto fail; } @@ -4054,7 +4070,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, } } if (missing) { - missing_arguments(co, missing, defcount, fastlocals); + missing_arguments(tstate, co, missing, defcount, fastlocals); goto fail; } if (n > m) @@ -4085,14 +4101,14 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, SETLOCAL(i, def); continue; } - else if (PyErr_Occurred()) { + else if (_PyErr_Occurred(tstate)) { goto fail; } } missing++; } if (missing) { - missing_arguments(co, missing, -1, fastlocals); + missing_arguments(tstate, co, missing, -1, fastlocals); goto fail; } } @@ -4132,11 +4148,11 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, if (is_coro && tstate->in_coroutine_wrapper) { assert(coro_wrapper != NULL); - PyErr_Format(PyExc_RuntimeError, - "coroutine wrapper %.200R attempted " - "to recursively wrap %.200R", - coro_wrapper, - co); + _PyErr_Format(tstate, PyExc_RuntimeError, + "coroutine wrapper %.200R attempted " + "to recursively wrap %.200R", + coro_wrapper, + co); goto fail; } @@ -4209,12 +4225,12 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, } static PyObject * -special_lookup(PyObject *o, _Py_Identifier *id) +special_lookup(PyThreadState *tstate, PyObject *o, _Py_Identifier *id) { PyObject *res; res = _PyObject_LookupSpecial(o, id); - if (res == NULL && !PyErr_Occurred()) { - PyErr_SetObject(PyExc_AttributeError, id->object); + if (res == NULL && !_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_AttributeError, id->object); return NULL; } return res; @@ -4236,14 +4252,14 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) value = exc_info->exc_value; tb = exc_info->exc_traceback; if (type == Py_None || type == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "No active exception to reraise"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "No active exception to reraise"); return 0; } Py_XINCREF(type); Py_XINCREF(value); Py_XINCREF(tb); - PyErr_Restore(type, value, tb); + _PyErr_Restore(tstate, type, value, tb); return 1; } @@ -4258,11 +4274,11 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) if (value == NULL) goto raise_error; if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto raise_error; + _PyErr_Format(tstate, PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto raise_error; } } else if (PyExceptionInstance_Check(exc)) { @@ -4274,8 +4290,8 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) /* Not something you can raise. You get an exception anyway, just not what you specified :-) */ Py_DECREF(exc); - PyErr_SetString(PyExc_TypeError, - "exceptions must derive from BaseException"); + _PyErr_SetString(tstate, PyExc_TypeError, + "exceptions must derive from BaseException"); goto raise_error; } @@ -4298,15 +4314,15 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) fixed_cause = NULL; } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); + _PyErr_SetString(tstate, PyExc_TypeError, + "exception causes must derive from " + "BaseException"); goto raise_error; } PyException_SetCause(value, fixed_cause); } - PyErr_SetObject(type, value); + _PyErr_SetObject(tstate, type, value); /* PyErr_SetObject incref's its arguments */ Py_DECREF(value); Py_DECREF(type); @@ -4327,7 +4343,8 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) */ static int -unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) +unpack_iterable(PyThreadState *tstate, PyObject *v, + int argcnt, int argcntafter, PyObject **sp) { int i = 0, j = 0; Py_ssize_t ll = 0; @@ -4339,12 +4356,12 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) it = PyObject_GetIter(v); if (it == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError) && + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && v->ob_type->tp_iter == NULL && !PySequence_Check(v)) { - PyErr_Format(PyExc_TypeError, - "cannot unpack non-iterable %.200s object", - v->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "cannot unpack non-iterable %.200s object", + v->ob_type->tp_name); } return 0; } @@ -4353,17 +4370,18 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) w = PyIter_Next(it); if (w == NULL) { /* Iterator done, via error or exhaustion. */ - if (!PyErr_Occurred()) { + if (!_PyErr_Occurred(tstate)) { if (argcntafter == -1) { - PyErr_Format(PyExc_ValueError, - "not enough values to unpack (expected %d, got %d)", - argcnt, i); + _PyErr_Format(tstate, PyExc_ValueError, + "not enough values to unpack " + "(expected %d, got %d)", + argcnt, i); } else { - PyErr_Format(PyExc_ValueError, - "not enough values to unpack " - "(expected at least %d, got %d)", - argcnt + argcntafter, i); + _PyErr_Format(tstate, PyExc_ValueError, + "not enough values to unpack " + "(expected at least %d, got %d)", + argcnt + argcntafter, i); } } goto Error; @@ -4375,15 +4393,15 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) /* We better have exhausted the iterator now. */ w = PyIter_Next(it); if (w == NULL) { - if (PyErr_Occurred()) + if (_PyErr_Occurred(tstate)) goto Error; Py_DECREF(it); return 1; } Py_DECREF(w); - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %d)", - argcnt); + _PyErr_Format(tstate, PyExc_ValueError, + "too many values to unpack (expected %d)", + argcnt); goto Error; } @@ -4395,7 +4413,7 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) ll = PyList_GET_SIZE(l); if (ll < argcntafter) { - PyErr_Format(PyExc_ValueError, + _PyErr_Format(tstate, PyExc_ValueError, "not enough values to unpack (expected at least %d, got %zd)", argcnt + argcntafter, argcnt + ll); goto Error; @@ -4420,11 +4438,13 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) #ifdef LLTRACE static int -prtrace(PyObject *v, const char *str) +prtrace(PyThreadState *tstate, PyObject *v, const char *str) { printf("%s ", str); - if (PyObject_Print(v, stdout, 0) != 0) - PyErr_Clear(); /* Don't know what else to do */ + if (PyObject_Print(v, stdout, 0) != 0) { + /* Don't know what else to do */ + _PyErr_Clear(tstate); + } printf("\n"); return 1; } @@ -4436,22 +4456,23 @@ call_exc_trace(Py_tracefunc func, PyObject *self, { PyObject *type, *value, *traceback, *orig_traceback, *arg; int err; - PyErr_Fetch(&type, &value, &orig_traceback); + _PyErr_Fetch(tstate, &type, &value, &orig_traceback); if (value == NULL) { value = Py_None; Py_INCREF(value); } - PyErr_NormalizeException(&type, &value, &orig_traceback); + _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback); traceback = (orig_traceback != NULL) ? orig_traceback : Py_None; arg = PyTuple_Pack(3, type, value, traceback); if (arg == NULL) { - PyErr_Restore(type, value, orig_traceback); + _PyErr_Restore(tstate, type, value, orig_traceback); return; } err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); Py_DECREF(arg); - if (err == 0) - PyErr_Restore(type, value, orig_traceback); + if (err == 0) { + _PyErr_Restore(tstate, type, value, orig_traceback); + } else { Py_XDECREF(type); Py_XDECREF(value); @@ -4466,11 +4487,11 @@ call_trace_protected(Py_tracefunc func, PyObject *obj, { PyObject *type, *value, *traceback; int err; - PyErr_Fetch(&type, &value, &traceback); + _PyErr_Fetch(tstate, &type, &value, &traceback); err = call_trace(func, obj, tstate, frame, what, arg); if (err == 0) { - PyErr_Restore(type, value, traceback); + _PyErr_Restore(tstate, type, value, traceback); return 0; } else { @@ -4672,12 +4693,26 @@ _PyEval_GetAsyncGenFinalizer(void) return tstate->async_gen_finalizer; } +static PyFrameObject * +_PyEval_GetFrame(PyThreadState *tstate) +{ + return _PyRuntime.gilstate.getframe(tstate); +} + +PyFrameObject * +PyEval_GetFrame(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_GetFrame(tstate); +} + PyObject * PyEval_GetBuiltins(void) { - PyFrameObject *current_frame = PyEval_GetFrame(); + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); if (current_frame == NULL) - return _PyInterpreterState_GET_UNSAFE()->builtins; + return tstate->interp->builtins; else return current_frame->f_builtins; } @@ -4686,12 +4721,13 @@ PyEval_GetBuiltins(void) PyObject * _PyEval_GetBuiltinId(_Py_Identifier *name) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name); if (attr) { Py_INCREF(attr); } - else if (!PyErr_Occurred()) { - PyErr_SetObject(PyExc_AttributeError, _PyUnicode_FromId(name)); + else if (!_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_AttributeError, _PyUnicode_FromId(name)); } return attr; } @@ -4699,14 +4735,16 @@ _PyEval_GetBuiltinId(_Py_Identifier *name) PyObject * PyEval_GetLocals(void) { - PyFrameObject *current_frame = PyEval_GetFrame(); + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); if (current_frame == NULL) { - PyErr_SetString(PyExc_SystemError, "frame does not exist"); + _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); return NULL; } - if (PyFrame_FastToLocalsWithError(current_frame) < 0) + if (PyFrame_FastToLocalsWithError(current_frame) < 0) { return NULL; + } assert(current_frame->f_locals != NULL); return current_frame->f_locals; @@ -4715,26 +4753,21 @@ PyEval_GetLocals(void) PyObject * PyEval_GetGlobals(void) { - PyFrameObject *current_frame = PyEval_GetFrame(); - if (current_frame == NULL) + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); + if (current_frame == NULL) { return NULL; + } assert(current_frame->f_globals != NULL); return current_frame->f_globals; } -PyFrameObject * -PyEval_GetFrame(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - return runtime->gilstate.getframe(tstate); -} - int PyEval_MergeCompilerFlags(PyCompilerFlags *cf) { - PyFrameObject *current_frame = PyEval_GetFrame(); + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *current_frame = _PyEval_GetFrame(tstate); int result = cf->cf_flags != 0; if (current_frame != NULL) { @@ -4883,7 +4916,7 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO Py_DECREF(func); } - assert((x != NULL) ^ (PyErr_Occurred() != NULL)); + assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); /* Clear the stack of the function object. */ while ((*pp_stack) > pfunc) { @@ -4939,17 +4972,18 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject int _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) { + PyThreadState *tstate = _PyThreadState_GET(); if (v != Py_None) { Py_ssize_t x; if (PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); - if (x == -1 && PyErr_Occurred()) + if (x == -1 && _PyErr_Occurred(tstate)) return 0; } else { - PyErr_SetString(PyExc_TypeError, - "slice indices must be integers or " - "None or have an __index__ method"); + _PyErr_SetString(tstate, PyExc_TypeError, + "slice indices must be integers or " + "None or have an __index__ method"); return 0; } *pi = x; @@ -4960,16 +4994,17 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) int _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) { + PyThreadState *tstate = _PyThreadState_GET(); Py_ssize_t x; if (PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); - if (x == -1 && PyErr_Occurred()) + if (x == -1 && _PyErr_Occurred(tstate)) return 0; } else { - PyErr_SetString(PyExc_TypeError, - "slice indices must be integers or " - "have an __index__ method"); + _PyErr_SetString(tstate, PyExc_TypeError, + "slice indices must be integers or " + "have an __index__ method"); return 0; } *pi = x; @@ -4981,7 +5016,7 @@ _PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) "BaseException is not allowed" static PyObject * -cmp_outcome(int op, PyObject *v, PyObject *w) +cmp_outcome(PyThreadState *tstate, int op, PyObject *v, PyObject *w) { int res = 0; switch (op) { @@ -5009,16 +5044,16 @@ cmp_outcome(int op, PyObject *v, PyObject *w) for (i = 0; i < length; i += 1) { PyObject *exc = PyTuple_GET_ITEM(w, i); if (!PyExceptionClass_Check(exc)) { - PyErr_SetString(PyExc_TypeError, - CANNOT_CATCH_MSG); + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); return NULL; } } } else { if (!PyExceptionClass_Check(w)) { - PyErr_SetString(PyExc_TypeError, - CANNOT_CATCH_MSG); + _PyErr_SetString(tstate, PyExc_TypeError, + CANNOT_CATCH_MSG); return NULL; } } @@ -5033,7 +5068,8 @@ cmp_outcome(int op, PyObject *v, PyObject *w) } static PyObject * -import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *level) +import_name(PyThreadState *tstate, PyFrameObject *f, + PyObject *name, PyObject *fromlist, PyObject *level) { _Py_IDENTIFIER(__import__); PyObject *import_func, *res; @@ -5041,16 +5077,16 @@ import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *leve import_func = _PyDict_GetItemIdWithError(f->f_builtins, &PyId___import__); if (import_func == NULL) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "__import__ not found"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_ImportError, "__import__ not found"); } return NULL; } /* Fast path for not overloaded __import__. */ - if (import_func == _PyInterpreterState_GET_UNSAFE()->import_func) { + if (import_func == tstate->interp->import_func) { int ilevel = _PyLong_AsInt(level); - if (ilevel == -1 && PyErr_Occurred()) { + if (ilevel == -1 && _PyErr_Occurred(tstate)) { return NULL; } res = PyImport_ImportModuleLevelObject( @@ -5075,7 +5111,7 @@ import_name(PyFrameObject *f, PyObject *name, PyObject *fromlist, PyObject *leve } static PyObject * -import_from(PyObject *v, PyObject *name) +import_from(PyThreadState *tstate, PyObject *v, PyObject *name) { PyObject *x; _Py_IDENTIFIER(__name__); @@ -5102,7 +5138,7 @@ import_from(PyObject *v, PyObject *name) } x = PyImport_GetModule(fullmodname); Py_DECREF(fullmodname); - if (x == NULL && !PyErr_Occurred()) { + if (x == NULL && !_PyErr_Occurred(tstate)) { goto error; } Py_DECREF(pkgname); @@ -5120,7 +5156,7 @@ import_from(PyObject *v, PyObject *name) } if (pkgpath == NULL || !PyUnicode_Check(pkgpath)) { - PyErr_Clear(); + _PyErr_Clear(tstate); errmsg = PyUnicode_FromFormat( "cannot import name %R from %R (unknown location)", name, pkgname_or_unknown @@ -5144,7 +5180,7 @@ import_from(PyObject *v, PyObject *name) } static int -import_all_from(PyObject *locals, PyObject *v) +import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) { _Py_IDENTIFIER(__all__); _Py_IDENTIFIER(__dict__); @@ -5161,7 +5197,7 @@ import_all_from(PyObject *locals, PyObject *v) return -1; } if (dict == NULL) { - PyErr_SetString(PyExc_ImportError, + _PyErr_SetString(tstate, PyExc_ImportError, "from-import-* object has no __dict__ and no __all__"); return -1; } @@ -5175,10 +5211,12 @@ import_all_from(PyObject *locals, PyObject *v) for (pos = 0, err = 0; ; pos++) { name = PySequence_GetItem(all, pos); if (name == NULL) { - if (!PyErr_ExceptionMatches(PyExc_IndexError)) + if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { err = -1; - else - PyErr_Clear(); + } + else { + _PyErr_Clear(tstate); + } break; } if (!PyUnicode_Check(name)) { @@ -5189,17 +5227,17 @@ import_all_from(PyObject *locals, PyObject *v) break; } if (!PyUnicode_Check(modname)) { - PyErr_Format(PyExc_TypeError, - "module __name__ must be a string, not %.100s", - Py_TYPE(modname)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "module __name__ must be a string, not %.100s", + Py_TYPE(modname)->tp_name); } else { - PyErr_Format(PyExc_TypeError, - "%s in %U.%s must be str, not %.100s", - skip_leading_underscores ? "Key" : "Item", - modname, - skip_leading_underscores ? "__dict__" : "__all__", - Py_TYPE(name)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "%s in %U.%s must be str, not %.100s", + skip_leading_underscores ? "Key" : "Item", + modname, + skip_leading_underscores ? "__dict__" : "__all__", + Py_TYPE(name)->tp_name); } Py_DECREF(modname); Py_DECREF(name); @@ -5234,22 +5272,22 @@ import_all_from(PyObject *locals, PyObject *v) } static int -check_args_iterable(PyObject *func, PyObject *args) +check_args_iterable(PyThreadState *tstate, PyObject *func, PyObject *args) { if (args->ob_type->tp_iter == NULL && !PySequence_Check(args)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after * " - "must be an iterable, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - args->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s argument after * " + "must be an iterable, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + args->ob_type->tp_name); return -1; } return 0; } static void -format_kwargs_error(PyObject *func, PyObject *kwargs) +format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) { /* _PyDict_MergeEx raises attribute * error (percolated from an attempt @@ -5257,44 +5295,46 @@ format_kwargs_error(PyObject *func, PyObject *kwargs) * a type error if its second argument * is not a mapping. */ - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - kwargs->ob_type->tp_name); - } - else if (PyErr_ExceptionMatches(PyExc_KeyError)) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + kwargs->ob_type->tp_name); + } + else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + _PyErr_Fetch(tstate, &exc, &val, &tb); if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { PyObject *key = PyTuple_GET_ITEM(val, 0); if (!PyUnicode_Check(key)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s keywords must be strings", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func)); - } else { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s got multiple " - "values for keyword argument '%U'", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - key); + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s keywords must be strings", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func)); + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "%.200s%.200s got multiple " + "values for keyword argument '%U'", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + key); } Py_XDECREF(exc); Py_XDECREF(val); Py_XDECREF(tb); } else { - PyErr_Restore(exc, val, tb); + _PyErr_Restore(tstate, exc, val, tb); } } } static void -format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj) +format_exc_check_arg(PyThreadState *tstate, PyObject *exc, + const char *format_str, PyObject *obj) { const char *obj_str; @@ -5305,52 +5345,52 @@ format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj) if (!obj_str) return; - PyErr_Format(exc, format_str, obj_str); + _PyErr_Format(tstate, exc, format_str, obj_str); } static void -format_exc_unbound(PyCodeObject *co, int oparg) +format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) { PyObject *name; /* Don't stomp existing exception */ - if (PyErr_Occurred()) + if (_PyErr_Occurred(tstate)) return; if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) { name = PyTuple_GET_ITEM(co->co_cellvars, oparg); - format_exc_check_arg( + format_exc_check_arg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, name); } else { name = PyTuple_GET_ITEM(co->co_freevars, oparg - PyTuple_GET_SIZE(co->co_cellvars)); - format_exc_check_arg(PyExc_NameError, + format_exc_check_arg(tstate, PyExc_NameError, UNBOUNDFREE_ERROR_MSG, name); } } static void -format_awaitable_error(PyTypeObject *type, int prevopcode) +format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevopcode) { if (type->tp_as_async == NULL || type->tp_as_async->am_await == NULL) { if (prevopcode == BEFORE_ASYNC_WITH) { - PyErr_Format(PyExc_TypeError, - "'async with' received an object from __aenter__ " - "that does not implement __await__: %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async with' received an object from __aenter__ " + "that does not implement __await__: %.100s", + type->tp_name); } else if (prevopcode == WITH_CLEANUP_START) { - PyErr_Format(PyExc_TypeError, - "'async with' received an object from __aexit__ " - "that does not implement __await__: %.100s", - type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "'async with' received an object from __aexit__ " + "that does not implement __await__: %.100s", + type->tp_name); } } } static PyObject * -unicode_concatenate(PyObject *v, PyObject *w, +unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w, PyFrameObject *f, const _Py_CODEUNIT *next_instr) { PyObject *res; @@ -5390,7 +5430,7 @@ unicode_concatenate(PyObject *v, PyObject *w, if (locals && PyDict_CheckExact(locals)) { PyObject *w = PyDict_GetItemWithError(locals, name); if ((w == v && PyDict_DelItem(locals, name) != 0) || - (w == NULL && PyErr_Occurred())) + (w == NULL && _PyErr_Occurred(tstate))) { Py_DECREF(v); return NULL; diff --git a/Python/errors.c b/Python/errors.c index d9b69d9dc6ca52..e721f1915da407 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_coreconfig.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "pycore_traceback.h" @@ -27,13 +28,13 @@ _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(stderr); -/* Forward declaration */ -static void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, - PyObject **p_value, PyObject **p_traceback); -static void _PyErr_Clear(PyThreadState *tstate); +/* Forward declarations */ +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs); -static void +void _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *traceback) { @@ -95,7 +96,7 @@ _PyErr_CreateException(PyObject *exception, PyObject *value) } } -static void +void _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) { PyObject *exc_value; @@ -103,9 +104,9 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) if (exception != NULL && !PyExceptionClass_Check(exception)) { - PyErr_Format(PyExc_SystemError, - "exception %R not a BaseException subclass", - exception); + _PyErr_Format(tstate, PyExc_SystemError, + "exception %R not a BaseException subclass", + exception); return; } @@ -181,7 +182,7 @@ _PyErr_SetKeyError(PyObject *arg) Py_DECREF(tup); } -static void +void _PyErr_SetNone(PyThreadState *tstate, PyObject *exception) { _PyErr_SetObject(tstate, exception, (PyObject *)NULL); @@ -196,7 +197,7 @@ PyErr_SetNone(PyObject *exception) } -static void +void _PyErr_SetString(PyThreadState *tstate, PyObject *exception, const char *string) { @@ -213,13 +214,6 @@ PyErr_SetString(PyObject *exception, const char *string) } -static PyObject* -_PyErr_Occurred(PyThreadState *tstate) -{ - return tstate == NULL ? NULL : tstate->curexc_type; -} - - PyObject* _Py_HOT_FUNCTION PyErr_Occurred(void) { @@ -260,11 +254,18 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc) } +int +_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc) +{ + return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); +} + + int PyErr_ExceptionMatches(PyObject *exc) { PyThreadState *tstate = _PyThreadState_GET(); - return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc); + return _PyErr_ExceptionMatches(tstate, exc); } @@ -278,7 +279,7 @@ PyErr_ExceptionMatches(PyObject *exc) XXX: should PyErr_NormalizeException() also call PyException_SetTraceback() with the resulting value and tb? */ -static void +void _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, PyObject **val, PyObject **tb) { @@ -390,7 +391,7 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) } -static void +void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, PyObject **p_traceback) { @@ -412,7 +413,7 @@ PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback) } -static void +void _PyErr_Clear(PyThreadState *tstate) { _PyErr_Restore(tstate, NULL, NULL, NULL); @@ -506,7 +507,7 @@ _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, Py_DECREF(exc); assert(!_PyErr_Occurred(tstate)); - PyErr_FormatV(exception, format, vargs); + _PyErr_FormatV(tstate, exception, format, vargs); _PyErr_Fetch(tstate, &exc, &val2, &tb); _PyErr_NormalizeException(tstate, &exc, &val2, &tb); @@ -895,9 +896,10 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) void _PyErr_BadInternalCall(const char *filename, int lineno) { - PyErr_Format(PyExc_SystemError, - "%s:%d: bad argument to internal function", - filename, lineno); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_Format(tstate, PyExc_SystemError, + "%s:%d: bad argument to internal function", + filename, lineno); } /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can @@ -907,16 +909,17 @@ void PyErr_BadInternalCall(void) { assert(0 && "bad argument to internal function"); - PyErr_Format(PyExc_SystemError, - "bad argument to internal function"); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetString(tstate, PyExc_SystemError, + "bad argument to internal function"); } #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) -PyObject * -PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) +static PyObject * +_PyErr_FormatV(PyThreadState *tstate, PyObject *exception, + const char *format, va_list vargs) { - PyThreadState *tstate = _PyThreadState_GET(); PyObject* string; /* Issue #23571: PyUnicode_FromFormatV() must not be called with an @@ -931,16 +934,41 @@ PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) } +PyObject * +PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_FormatV(tstate, exception, format, vargs); +} + + +PyObject * +_PyErr_Format(PyThreadState *tstate, PyObject *exception, + const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + _PyErr_FormatV(tstate, exception, format, vargs); + va_end(vargs); + return NULL; +} + + PyObject * PyErr_Format(PyObject *exception, const char *format, ...) { + PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - PyErr_FormatV(exception, format, vargs); + _PyErr_FormatV(tstate, exception, format, vargs); va_end(vargs); return NULL; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 7219f548fd251e..26cb02aad5f1fb 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -12,6 +12,7 @@ #include "Python-ast.h" #undef Yield /* undefine macro conflicting with */ +#include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "grammar.h" @@ -542,12 +543,6 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, return 0; } -void -PyErr_Print(void) -{ - PyErr_PrintEx(1); -} - static void print_error_text(PyObject *f, int offset, PyObject *text_obj) { @@ -667,34 +662,38 @@ handle_system_exit(void) } -void -PyErr_PrintEx(int set_sys_last_vars) +static void +_PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) { PyObject *exception, *v, *tb, *hook; handle_system_exit(); - PyErr_Fetch(&exception, &v, &tb); - if (exception == NULL) - return; - PyErr_NormalizeException(&exception, &v, &tb); + _PyErr_Fetch(tstate, &exception, &v, &tb); + if (exception == NULL) { + goto done; + } + + _PyErr_NormalizeException(tstate, &exception, &v, &tb); if (tb == NULL) { tb = Py_None; Py_INCREF(tb); } PyException_SetTraceback(v, tb); - if (exception == NULL) - return; + if (exception == NULL) { + goto done; + } + /* Now we know v != NULL too */ if (set_sys_last_vars) { if (_PySys_SetObjectId(&PyId_last_type, exception) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } if (_PySys_SetObjectId(&PyId_last_value, v) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } if (_PySys_SetObjectId(&PyId_last_traceback, tb) < 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); } } hook = _PySys_GetObjectId(&PyId_excepthook); @@ -710,8 +709,8 @@ PyErr_PrintEx(int set_sys_last_vars) handle_system_exit(); PyObject *exception2, *v2, *tb2; - PyErr_Fetch(&exception2, &v2, &tb2); - PyErr_NormalizeException(&exception2, &v2, &tb2); + _PyErr_Fetch(tstate, &exception2, &v2, &tb2); + _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2); /* It should not be possible for exception2 or v2 to be NULL. However PyErr_Display() can't tolerate NULLs, so just be safe. */ @@ -733,15 +732,37 @@ PyErr_PrintEx(int set_sys_last_vars) Py_XDECREF(tb2); } Py_XDECREF(result); - } else { + } + else { PySys_WriteStderr("sys.excepthook is missing\n"); PyErr_Display(exception, v, tb); } + +done: Py_XDECREF(exception); Py_XDECREF(v); Py_XDECREF(tb); } +void +_PyErr_Print(PyThreadState *tstate) +{ + _PyErr_PrintEx(tstate, 1); +} + +void +PyErr_PrintEx(int set_sys_last_vars) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_PrintEx(tstate, set_sys_last_vars); +} + +void +PyErr_Print(void) +{ + PyErr_PrintEx(1); +} + static void print_exception(PyObject *f, PyObject *value) { From c994c8fc196a167c57c8850e8abdee170d366eec Mon Sep 17 00:00:00 2001 From: "E. M. Bray" Date: Fri, 24 May 2019 17:33:47 +0200 Subject: [PATCH 092/441] bpo-21536: On Cygwin, C extensions must be linked with libpython (GH-13549) It is also possible to link against a library or executable with a statically linked libpython, but not both with the same DLL. In fact building a statically linked python is currently broken on Cygwin for other (related) reasons. The same problem applies to other POSIX-like layers over Windows (MinGW, MSYS) but Python's build system does not seem to attempt to support those platforms at the moment. --- Doc/distutils/apiref.rst | 2 +- Doc/whatsnew/3.8.rst | 17 +++++++------- Lib/distutils/command/build_ext.py | 36 ++++++++++++++++++++---------- Misc/NEWS.d/3.8.0a4.rst | 3 ++- configure | 4 ++-- configure.ac | 4 ++-- 6 files changed, 40 insertions(+), 26 deletions(-) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index cbeedab5bb1225..2601d30f63eb4c 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -290,7 +290,7 @@ the full reference. .. versionchanged:: 3.8 On Unix, C extensions are no longer linked to libpython except on - Android. + Android and Cygwin. .. class:: Distribution diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index b91f7bca63c9f2..b5d70b5a2ec437 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -138,7 +138,8 @@ environment variable, can be set using the new ``./configure --with-trace-refs`` build option. (Contributed by Victor Stinner in :issue:`36465`.) -On Unix, C extensions are no longer linked to libpython except on Android. +On Unix, C extensions are no longer linked to libpython except on Android +and Cygwin. It is now possible for a statically linked Python to load a C extension built using a shared library Python. @@ -163,8 +164,8 @@ previous command fails (replace ``X.Y`` with the Python version). On the other hand, ``pkg-config python3.8 --libs`` no longer contains ``-lpython3.8``. C extensions must not be linked to libpython (except on -Android, case handled by the script); this change is backward incompatible on -purpose. +Android and Cygwin, whose cases are handled by the script); +this change is backward incompatible on purpose. (Contributed by Victor Stinner in :issue:`36721`.) f-strings now support = for quick and easy debugging @@ -1061,12 +1062,12 @@ Changes in the C API instead. (Contributed by Victor Stinner in :issue:`36728`.) -* On Unix, C extensions are no longer linked to libpython except on - Android. When Python is embedded, ``libpython`` must not be loaded with +* On Unix, C extensions are no longer linked to libpython except on Android + and Cygwin. When Python is embedded, ``libpython`` must not be loaded with ``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using - ``RTLD_LOCAL``, it was already not possible to load C extensions which were - not linked to ``libpython``, like C extensions of the standard library built - by the ``*shared*`` section of ``Modules/Setup``. + ``RTLD_LOCAL``, it was already not possible to load C extensions which + were not linked to ``libpython``, like C extensions of the standard + library built by the ``*shared*`` section of ``Modules/Setup``. * Use of ``#`` variants of formats in parsing or building value (e.g. :c:func:`PyArg_ParseTuple`, :c:func:`Py_BuildValue`, :c:func:`PyObject_CallFunction`, diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index c3b9602461f93a..2d7cdf063f01db 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -714,20 +714,32 @@ def get_libraries(self, ext): # don't extend ext.libraries, it may be shared with other # extensions, it is a reference to the original list return ext.libraries + [pythonlib] - # On Android only the main executable and LD_PRELOADs are considered - # to be RTLD_GLOBAL, all the dependencies of the main executable - # remain RTLD_LOCAL and so the shared libraries must be linked with - # libpython when python is built with a shared python library (issue - # bpo-21536). else: + # On Android only the main executable and LD_PRELOADs are considered + # to be RTLD_GLOBAL, all the dependencies of the main executable + # remain RTLD_LOCAL and so the shared libraries must be linked with + # libpython when python is built with a shared python library (issue + # bpo-21536). + # On Cygwin (and if required, other POSIX-like platforms based on + # Windows like MinGW) it is simply necessary that all symbols in + # shared libraries are resolved at link time. from distutils.sysconfig import get_config_var + link_libpython = False if get_config_var('Py_ENABLE_SHARED'): - # Either a native build on an Android device or the - # cross-compilation of Python. - if (hasattr(sys, 'getandroidapilevel') or - ('_PYTHON_HOST_PLATFORM' in os.environ and - get_config_var('ANDROID_API_LEVEL') != 0)): - ldversion = get_config_var('LDVERSION') - return ext.libraries + ['python' + ldversion] + # A native build on an Android device or on Cygwin + if hasattr(sys, 'getandroidapilevel'): + link_libpython = True + elif sys.platform == 'cygwin': + link_libpython = True + elif '_PYTHON_HOST_PLATFORM' in os.environ: + # We are cross-compiling for one of the relevant platforms + if get_config_var('ANDROID_API_LEVEL') != 0: + link_libpython = True + elif get_config_var('MACHDEP') == 'cygwin': + link_libpython = True + + if link_libpython: + ldversion = get_config_var('LDVERSION') + return ext.libraries + ['python' + ldversion] return ext.libraries diff --git a/Misc/NEWS.d/3.8.0a4.rst b/Misc/NEWS.d/3.8.0a4.rst index b92e60a9269132..80e01d97a04337 100644 --- a/Misc/NEWS.d/3.8.0a4.rst +++ b/Misc/NEWS.d/3.8.0a4.rst @@ -1052,7 +1052,8 @@ Remove the stale scriptsinstall Makefile target. .. nonce: ACQkiC .. section: Build -On Unix, C extensions are no longer linked to libpython except on Android. +On Unix, C extensions are no longer linked to libpython except on Android +and Cygwin. It is now possible for a statically linked Python to load a C extension built using a shared library Python. diff --git a/configure b/configure index 9f2007fed32560..c76eb7affe54be 100755 --- a/configure +++ b/configure @@ -15129,9 +15129,9 @@ LDVERSION='$(VERSION)$(ABIFLAGS)' { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5 $as_echo "$LDVERSION" >&6; } -# On Android the shared libraries must be linked with libpython. +# On Android and Cygwin the shared libraries must be linked with libpython. -if test -z "$ANDROID_API_LEVEL"; then +if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then LIBPYTHON='' else LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" diff --git a/configure.ac b/configure.ac index 0baf0d6660aafe..99d99ae55c17f3 100644 --- a/configure.ac +++ b/configure.ac @@ -4620,9 +4620,9 @@ AC_MSG_CHECKING(LDVERSION) LDVERSION='$(VERSION)$(ABIFLAGS)' AC_MSG_RESULT($LDVERSION) -# On Android the shared libraries must be linked with libpython. +# On Android and Cygwin the shared libraries must be linked with libpython. AC_SUBST(LIBPYTHON) -if test -z "$ANDROID_API_LEVEL"; then +if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then LIBPYTHON='' else LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" From 51394b8c3d42e6e6d368251ff6f0612495724fc0 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Fri, 24 May 2019 09:15:39 -0700 Subject: [PATCH 093/441] bpo-36511: Ensure error code propagates out of batch files (GH-13529) --- Tools/buildbot/test.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index b84e8e25567215..f430680f3d80cf 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -21,7 +21,7 @@ echo on if "%arm32_ssh%"=="true" goto :Arm32Ssh call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% -exit /b 0 +exit /b %ERRORLEVEL% :Arm32Ssh set dashU=-unetwork,decimal,subprocess,urlfetch,tzdata @@ -42,7 +42,7 @@ scp -r "%PYTHON_SOURCE%Lib" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Lib" set rt_args=%rt_opts% %dashU% -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% %TEMP_ARGS% ssh %SSH_SERVER% "set TEMP=%REMOTE_PYTHON_DIR%temp& %REMOTE_PYTHON_DIR%PCbuild\rt.bat" %rt_args% -exit /b 0 +exit /b %ERRORLEVEL% :Arm32SshHelp echo SSH_SERVER environment variable must be set to administrator@[ip address] From bc66faccb8a6140e7e07b5e67843b7f21152c144 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 18:27:13 +0200 Subject: [PATCH 094/441] bpo-36721: Fix pkg-config symbolic links on "make install" (GH-13551) --- Makefile.pre.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index a149fdec4dcf40..466cd763c98dee 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1261,8 +1261,8 @@ bininstall: altbininstall (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(LDVERSION)-config python$(VERSION)-config); \ rm -f $(DESTDIR)$(LIBPC)/python-$(LDVERSION).pc; \ (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python-$(LDVERSION).pc); \ - rm -f $(DESTDIR)$(LIBPC)/python-embed-$(LDVERSION).pc; \ - (cd $(DESTDIR)$(LIBPC); $(LN) -s python-embed-$(VERSION).pc python-embed-$(LDVERSION).pc); \ + rm -f $(DESTDIR)$(LIBPC)/python-$(LDVERSION)-embed.pc; \ + (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION)-embed.pc python-$(LDVERSION)-embed.pc); \ fi -rm -f $(DESTDIR)$(BINDIR)/python3-config (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python3-config) From b1fc41784136a2eb9737a7f0c821db52ab8d4dee Mon Sep 17 00:00:00 2001 From: "E. M. Bray" Date: Fri, 24 May 2019 18:39:39 +0200 Subject: [PATCH 095/441] bpo-21536: Fix configure.ac for LIBPYTHON on Android/Cygwin (GH-13552) Add also missing AC_MSG_RESULT for AC_MSG_CHECKING(MACHDEP). --- configure | 8 +++++--- configure.ac | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/configure b/configure index c76eb7affe54be..bc276ac58362bf 100755 --- a/configure +++ b/configure @@ -3292,6 +3292,8 @@ then '') MACHDEP="unknown";; esac fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$MACHDEP\"" >&5 +$as_echo "\"$MACHDEP\"" >&6; } if test "$cross_compiling" = yes; then @@ -15131,10 +15133,10 @@ $as_echo "$LDVERSION" >&6; } # On Android and Cygwin the shared libraries must be linked with libpython. -if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then - LIBPYTHON='' -else +if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin"; then LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" +else + LIBPYTHON='' fi diff --git a/configure.ac b/configure.ac index 99d99ae55c17f3..5e565191f27de1 100644 --- a/configure.ac +++ b/configure.ac @@ -411,6 +411,7 @@ then '') MACHDEP="unknown";; esac fi +AC_MSG_RESULT("$MACHDEP") AC_SUBST(_PYTHON_HOST_PLATFORM) if test "$cross_compiling" = yes; then @@ -4622,10 +4623,10 @@ AC_MSG_RESULT($LDVERSION) # On Android and Cygwin the shared libraries must be linked with libpython. AC_SUBST(LIBPYTHON) -if test -z "$ANDROID_API_LEVEL" -o "$MACHDEP" != "cygwin"; then - LIBPYTHON='' -else +if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin"; then LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" +else + LIBPYTHON='' fi dnl define LIBPL after ABIFLAGS and LDVERSION is defined. From 14738ff83d852c95a0cf33e5c90a85860a9c5620 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Fri, 24 May 2019 20:24:42 +0300 Subject: [PATCH 096/441] bpo-8138: Initialize wsgiref's SimpleServer as single-threaded (GH-12977) --- Lib/wsgiref/simple_server.py | 3 ++- .../next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst diff --git a/Lib/wsgiref/simple_server.py b/Lib/wsgiref/simple_server.py index f71563a5ae0890..93d01a863adf59 100644 --- a/Lib/wsgiref/simple_server.py +++ b/Lib/wsgiref/simple_server.py @@ -127,7 +127,8 @@ def handle(self): return handler = ServerHandler( - self.rfile, self.wfile, self.get_stderr(), self.get_environ() + self.rfile, self.wfile, self.get_stderr(), self.get_environ(), + multithread=False, ) handler.request_handler = self # backpointer for logging handler.run(self.server.get_app()) diff --git a/Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst b/Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst new file mode 100644 index 00000000000000..e94d0a68d465ed --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst @@ -0,0 +1,2 @@ +Don't mark ``wsgiref.simple_server.SimpleServer`` as multi-threaded since +``wsgiref.simple_server.WSGIServer`` is single-threaded. From 6de4574c6393b9cf8d7dfb0dc6ce53ee5b9ea841 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 24 May 2019 13:00:04 -0700 Subject: [PATCH 097/441] bpo-37023: Skip test_gdb under PGO (GH-13555) --- Lib/test/test_gdb.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 4d1ce4ed96c06d..dbcb5983e9ba1d 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -52,6 +52,10 @@ def get_gdb_version(): raise unittest.SkipTest("test_gdb doesn't work correctly when python is" " built with LLVM clang") +if ((sysconfig.get_config_var('PGO_PROF_USE_FLAG') or 'xxx') in + (sysconfig.get_config_var('PY_CORE_CFLAGS') or '')): + raise unittest.SkipTest("test_gdb is not reliable on PGO builds") + # Location of custom hooks file in a repository checkout. checkout_hook_path = os.path.join(os.path.dirname(sys.executable), 'python-gdb.py') @@ -272,7 +276,7 @@ def get_gdb_repr(self, source, # gdb can insert additional '\n' and space characters in various places # in its output, depending on the width of the terminal it's connected # to (using its "wrap_here" function) - m = re.match(r'.*#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)\)\s+at\s+\S*Python/bltinmodule.c.*', + m = re.match(r'.*#0\s+builtin_id\s+\(self\=.*,\s+v=\s*(.*?)?\)\s+at\s+\S*Python/bltinmodule.c.*', gdb_output, re.DOTALL) if not m: self.fail('Unexpected gdb output: %r\n%s' % (gdb_output, gdb_output)) From deffee57749cf29ba17f50f11fb2a8cbc3e3752d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 22:06:32 +0200 Subject: [PATCH 098/441] bpo-35907: Clarify the NEWS entry (GH-13523) --- .../next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst b/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst index 42aca0bbd1b7f1..9628c8797572eb 100644 --- a/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst +++ b/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst @@ -1,2 +1,3 @@ -CVE-2019-9948: Avoid file reading as disallowing the unnecessary URL scheme in -``URLopener().open()`` ``URLopener().retrieve()`` of :mod:`urllib.request`. +CVE-2019-9948: Avoid file reading by disallowing ``local-file://`` and +``local_file://`` URL schemes in ``URLopener().open()`` +``URLopener().retrieve()`` of :mod:`urllib.request`. From 458560347f5c28e162bb288adfa0cfe5aad79557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Fri, 24 May 2019 22:44:31 +0200 Subject: [PATCH 099/441] bpo-36969: Make PDB args command display positional only arguments (GH-13459) --- Lib/pdb.py | 2 +- Lib/test/test_pdb.py | 33 ++++++++++++++++--- .../2019-05-21-12-31-21.bpo-36969.u7cxu7.rst | 2 ++ 3 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index 0e7609e43d4eea..13068ce27bd166 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1132,7 +1132,7 @@ def do_args(self, arg): """ co = self.curframe.f_code dict = self.curframe_locals - n = co.co_argcount + co.co_kwonlyargcount + n = co.co_argcount + co.co_posonlyargcount + co.co_kwonlyargcount if co.co_flags & inspect.CO_VARARGS: n = n+1 if co.co_flags & inspect.CO_VARKEYWORDS: n = n+1 for i in range(n): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index a33494d6d878dd..d03f1b284300cf 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -80,10 +80,14 @@ def test_pdb_basic_commands(): >>> def test_function3(arg=None, *, kwonly=None): ... pass + >>> def test_function4(a, b, c, /): + ... pass + >>> def test_function(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... ret = test_function_2('baz') ... test_function3(kwonly=True) + ... test_function4(1, 2, 3) ... print(ret) >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE @@ -104,10 +108,14 @@ def test_pdb_basic_commands(): ... 'next', # step to test_function3() ... 'step', # stepping into test_function3() ... 'args', # display function args + ... 'return', # return out of function + ... 'next', # step to test_function4() + ... 'step', # stepping to test_function4() + ... 'args', # display function args ... 'continue', ... ]): ... test_function() - > (3)test_function() + > (3)test_function() -> ret = test_function_2('baz') (Pdb) step --Call-- @@ -130,14 +138,14 @@ def test_pdb_basic_commands(): [EOF] (Pdb) bt ... - (21)() + (25)() -> test_function() - (3)test_function() + (3)test_function() -> ret = test_function_2('baz') > (1)test_function_2() -> def test_function_2(foo, bar='default'): (Pdb) up - > (3)test_function() + > (3)test_function() -> ret = test_function_2('baz') (Pdb) down > (1)test_function_2() @@ -176,7 +184,7 @@ def test_pdb_basic_commands(): (Pdb) retval 'BAZ' (Pdb) next - > (4)test_function() + > (4)test_function() -> test_function3(kwonly=True) (Pdb) step --Call-- @@ -185,6 +193,21 @@ def test_pdb_basic_commands(): (Pdb) args arg = None kwonly = True + (Pdb) return + --Return-- + > (2)test_function3()->None + -> pass + (Pdb) next + > (5)test_function() + -> test_function4(1, 2, 3) + (Pdb) step + --Call-- + > (1)test_function4() + -> def test_function4(a, b, c, /): + (Pdb) args + a = 1 + b = 2 + c = 3 (Pdb) continue BAZ """ diff --git a/Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst b/Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst new file mode 100644 index 00000000000000..1823a4dcc2492b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst @@ -0,0 +1,2 @@ +PDB command `args` now display positional only arguments. Patch contributed +by Rémi Lapeyre. From 1c9debd2366a21525769aaa99ce334092033a963 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 23:06:25 +0200 Subject: [PATCH 100/441] bpo-35907: Fix typo in the NEWS entry (GH-13559) --- .../next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst b/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst index 9628c8797572eb..37b567a5b6f93b 100644 --- a/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst +++ b/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst @@ -1,3 +1,3 @@ CVE-2019-9948: Avoid file reading by disallowing ``local-file://`` and -``local_file://`` URL schemes in ``URLopener().open()`` +``local_file://`` URL schemes in ``URLopener().open()`` and ``URLopener().retrieve()`` of :mod:`urllib.request`. From 561612d8456cfab5672c9b445521113b847bd6b3 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 24 May 2019 22:09:23 +0100 Subject: [PATCH 101/441] bpo-37021: Port _randommodule to the argument clinic (GH-13532) --- Modules/_randommodule.c | 109 +++++++++++++++++++++------- Modules/clinic/_randommodule.c.h | 117 +++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+), 26 deletions(-) create mode 100644 Modules/clinic/_randommodule.c.h diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 6a48689204c5a5..85f6e402929975 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -89,6 +89,13 @@ static PyTypeObject Random_Type; #define RandomObject_Check(v) (Py_TYPE(v) == &Random_Type) +#include "clinic/_randommodule.c.h" + +/*[clinic input] +module _random +class _random.Random "RandomObject *" "&Random_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f79898ae7847c321]*/ /* Random methods */ @@ -137,8 +144,18 @@ genrand_int32(RandomObject *self) * lower 26 bits of the 53-bit numerator. * The original code credited Isaku Wada for this algorithm, 2002/01/09. */ + +/*[clinic input] +_random.Random.random + + self: self(type="RandomObject *") + +random() -> x in the interval [0, 1). +[clinic start generated code]*/ + static PyObject * -random_random(RandomObject *self, PyObject *Py_UNUSED(ignored)) +_random_Random_random_impl(RandomObject *self) +/*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/ { uint32_t a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); @@ -232,20 +249,16 @@ random_seed_time_pid(RandomObject *self) } static PyObject * -random_seed(RandomObject *self, PyObject *args) +random_seed(RandomObject *self, PyObject *arg) { PyObject *result = NULL; /* guilty until proved innocent */ PyObject *n = NULL; uint32_t *key = NULL; size_t bits, keyused; int res; - PyObject *arg = NULL; - - if (!PyArg_UnpackTuple(args, "seed", 0, 1, &arg)) - return NULL; - if (arg == NULL || arg == Py_None) { - if (random_seed_urandom(self) < 0) { + if (arg == NULL || arg == Py_None) { + if (random_seed_urandom(self) < 0) { PyErr_Clear(); /* Reading system entropy failed, fall back on the worst entropy: @@ -317,8 +330,37 @@ random_seed(RandomObject *self, PyObject *args) return result; } +/*[clinic input] +_random.Random.seed + + self: self(type="RandomObject *") + n: object = None + / + +seed([n]) -> None. + +Defaults to use urandom and falls back to a combination +of the current time and the process identifier. +[clinic start generated code]*/ + +static PyObject * +_random_Random_seed_impl(RandomObject *self, PyObject *n) +/*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/ +{ + return random_seed(self, n); +} + +/*[clinic input] +_random.Random.getstate + + self: self(type="RandomObject *") + +getstate() -> tuple containing the current state. +[clinic start generated code]*/ + static PyObject * -random_getstate(RandomObject *self, PyObject *Py_UNUSED(ignored)) +_random_Random_getstate_impl(RandomObject *self) +/*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/ { PyObject *state; PyObject *element; @@ -344,8 +386,20 @@ random_getstate(RandomObject *self, PyObject *Py_UNUSED(ignored)) return NULL; } + +/*[clinic input] +_random.Random.setstate + + self: self(type="RandomObject *") + state: object + / + +setstate(state) -> None. Restores generator state. +[clinic start generated code]*/ + static PyObject * -random_setstate(RandomObject *self, PyObject *state) +_random_Random_setstate(RandomObject *self, PyObject *state) +/*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/ { int i; unsigned long element; @@ -384,17 +438,26 @@ random_setstate(RandomObject *self, PyObject *state) Py_RETURN_NONE; } +/*[clinic input] + +_random.Random.getrandbits + + self: self(type="RandomObject *") + k: int + / + +getrandbits(k) -> x. Generates an int with k random bits. +[clinic start generated code]*/ + static PyObject * -random_getrandbits(RandomObject *self, PyObject *args) +_random_Random_getrandbits_impl(RandomObject *self, int k) +/*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/ { - int k, i, words; + int i, words; uint32_t r; uint32_t *wordarray; PyObject *result; - if (!PyArg_ParseTuple(args, "i:getrandbits", &k)) - return NULL; - if (k <= 0) { PyErr_SetString(PyExc_ValueError, "number of bits must be greater than zero"); @@ -453,17 +516,11 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static PyMethodDef random_methods[] = { - {"random", (PyCFunction)random_random, METH_NOARGS, - PyDoc_STR("random() -> x in the interval [0, 1).")}, - {"seed", (PyCFunction)random_seed, METH_VARARGS, - PyDoc_STR("seed([n]) -> None. Defaults to current time.")}, - {"getstate", (PyCFunction)random_getstate, METH_NOARGS, - PyDoc_STR("getstate() -> tuple containing the current state.")}, - {"setstate", (PyCFunction)random_setstate, METH_O, - PyDoc_STR("setstate(state) -> None. Restores generator state.")}, - {"getrandbits", (PyCFunction)random_getrandbits, METH_VARARGS, - PyDoc_STR("getrandbits(k) -> x. Generates an int with " - "k random bits.")}, + _RANDOM_RANDOM_RANDOM_METHODDEF + _RANDOM_RANDOM_SEED_METHODDEF + _RANDOM_RANDOM_GETSTATE_METHODDEF + _RANDOM_RANDOM_SETSTATE_METHODDEF + _RANDOM_RANDOM_GETRANDBITS_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/clinic/_randommodule.c.h b/Modules/clinic/_randommodule.c.h new file mode 100644 index 00000000000000..a467811d93b272 --- /dev/null +++ b/Modules/clinic/_randommodule.c.h @@ -0,0 +1,117 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_random_Random_random__doc__, +"random($self, /)\n" +"--\n" +"\n" +"random() -> x in the interval [0, 1)."); + +#define _RANDOM_RANDOM_RANDOM_METHODDEF \ + {"random", (PyCFunction)_random_Random_random, METH_NOARGS, _random_Random_random__doc__}, + +static PyObject * +_random_Random_random_impl(RandomObject *self); + +static PyObject * +_random_Random_random(RandomObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _random_Random_random_impl(self); +} + +PyDoc_STRVAR(_random_Random_seed__doc__, +"seed($self, n=None, /)\n" +"--\n" +"\n" +"seed([n]) -> None.\n" +"\n" +"Defaults to use urandom and falls back to a combination\n" +"of the current time and the process identifier."); + +#define _RANDOM_RANDOM_SEED_METHODDEF \ + {"seed", (PyCFunction)(void(*)(void))_random_Random_seed, METH_FASTCALL, _random_Random_seed__doc__}, + +static PyObject * +_random_Random_seed_impl(RandomObject *self, PyObject *n); + +static PyObject * +_random_Random_seed(RandomObject *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *n = Py_None; + + if (!_PyArg_CheckPositional("seed", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + n = args[0]; +skip_optional: + return_value = _random_Random_seed_impl(self, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_random_Random_getstate__doc__, +"getstate($self, /)\n" +"--\n" +"\n" +"getstate() -> tuple containing the current state."); + +#define _RANDOM_RANDOM_GETSTATE_METHODDEF \ + {"getstate", (PyCFunction)_random_Random_getstate, METH_NOARGS, _random_Random_getstate__doc__}, + +static PyObject * +_random_Random_getstate_impl(RandomObject *self); + +static PyObject * +_random_Random_getstate(RandomObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _random_Random_getstate_impl(self); +} + +PyDoc_STRVAR(_random_Random_setstate__doc__, +"setstate($self, state, /)\n" +"--\n" +"\n" +"setstate(state) -> None. Restores generator state."); + +#define _RANDOM_RANDOM_SETSTATE_METHODDEF \ + {"setstate", (PyCFunction)_random_Random_setstate, METH_O, _random_Random_setstate__doc__}, + +PyDoc_STRVAR(_random_Random_getrandbits__doc__, +"getrandbits($self, k, /)\n" +"--\n" +"\n" +"getrandbits(k) -> x. Generates an int with k random bits."); + +#define _RANDOM_RANDOM_GETRANDBITS_METHODDEF \ + {"getrandbits", (PyCFunction)_random_Random_getrandbits, METH_O, _random_Random_getrandbits__doc__}, + +static PyObject * +_random_Random_getrandbits_impl(RandomObject *self, int k); + +static PyObject * +_random_Random_getrandbits(RandomObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int k; + + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + k = _PyLong_AsInt(arg); + if (k == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _random_Random_getrandbits_impl(self, k); + +exit: + return return_value; +} +/*[clinic end generated code: output=a7feb0c9c8d1b627 input=a9049054013a1b77]*/ From a9f05d69ccbf3c75cdd604c25094282697789a62 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 24 May 2019 23:57:23 +0200 Subject: [PATCH 102/441] bpo-37032: Add CodeType.replace() method (GH-13542) --- Doc/whatsnew/3.8.rst | 6 +- Lib/modulefinder.py | 8 +- Lib/test/test_code.py | 66 ++++- Lib/test/test_import/__init__.py | 8 +- Lib/types.py | 10 +- .../2019-05-24-12-38-40.bpo-37032.T8rSH8.rst | 1 + Objects/clinic/codeobject.c.h | 256 ++++++++++++++++++ Objects/codeobject.c | 79 +++++- 8 files changed, 401 insertions(+), 33 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst create mode 100644 Objects/clinic/codeobject.c.h diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index b5d70b5a2ec437..a94aba6b2c987f 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -240,6 +240,9 @@ Other Language Changes and Windows use this to properly terminate scripts in interactive sessions. (Contributed by Google via Gregory P. Smith in :issue:`1054041`.) +* Added new ``replace()`` method to the code type (:class:`types.CodeType`). + (Contributed by Victor Stinner in :issue:`37032`.) + New Modules =========== @@ -1051,7 +1054,8 @@ Changes in the Python API * :class:`types.CodeType` has a new parameter in the second position of the constructor (*posonlyargcount*) to support positional-only arguments defined - in :pep:`570`. + in :pep:`570`. A new ``replace()`` method of :class:`types.CodeType` can be + used to make the code future-proof. Changes in the C API diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py index a36f1b6d58c446..e0d29984f862cf 100644 --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -619,13 +619,7 @@ def replace_paths_in_code(self, co): if isinstance(consts[i], type(co)): consts[i] = self.replace_paths_in_code(consts[i]) - return types.CodeType(co.co_argcount, co.co_posonlyargcount, - co.co_kwonlyargcount, co.co_nlocals, - co.co_stacksize, co.co_flags, - co.co_code, tuple(consts), co.co_names, - co.co_varnames, new_filename, co.co_name, - co.co_firstlineno, co.co_lnotab, co.co_freevars, - co.co_cellvars) + return co.replace(co_consts=tuple(consts), co_filename=new_filename) def test(): diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 9bf290d8d5a1f7..91008c04f7fd2e 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -174,18 +174,14 @@ def test_newempty(self): @cpython_only def test_closure_injection(self): # From https://bugs.python.org/issue32176 - from types import FunctionType, CodeType + from types import FunctionType def create_closure(__class__): return (lambda: __class__).__closure__ def new_code(c): '''A new code object with a __class__ cell added to freevars''' - return CodeType( - c.co_argcount, c.co_posonlyargcount, c.co_kwonlyargcount, c.co_nlocals, - c.co_stacksize, c.co_flags, c.co_code, c.co_consts, c.co_names, - c.co_varnames, c.co_filename, c.co_name, c.co_firstlineno, - c.co_lnotab, c.co_freevars + ('__class__',), c.co_cellvars) + return c.replace(co_freevars=c.co_freevars + ('__class__',)) def add_foreign_method(cls, name, f): code = new_code(f.__code__) @@ -212,6 +208,64 @@ class List(list): obj = List([1, 2, 3]) self.assertEqual(obj[0], "Foreign getitem: 1") + def test_constructor(self): + def func(): pass + co = func.__code__ + CodeType = type(co) + + # test code constructor + return CodeType(co.co_argcount, + co.co_posonlyargcount, + co.co_kwonlyargcount, + co.co_nlocals, + co.co_stacksize, + co.co_flags, + co.co_code, + co.co_consts, + co.co_names, + co.co_varnames, + co.co_filename, + co.co_name, + co.co_firstlineno, + co.co_lnotab, + co.co_freevars, + co.co_cellvars) + + def test_replace(self): + def func(): + x = 1 + return x + code = func.__code__ + + # different co_name, co_varnames, co_consts + def func2(): + y = 2 + return y + code2 = func.__code__ + + for attr, value in ( + ("co_argcount", 0), + ("co_posonlyargcount", 0), + ("co_kwonlyargcount", 0), + ("co_nlocals", 0), + ("co_stacksize", 0), + ("co_flags", code.co_flags | inspect.CO_COROUTINE), + ("co_firstlineno", 100), + ("co_code", code2.co_code), + ("co_consts", code2.co_consts), + ("co_names", ("myname",)), + ("co_varnames", code2.co_varnames), + ("co_freevars", ("freevar",)), + ("co_cellvars", ("cellvar",)), + ("co_filename", "newfilename"), + ("co_name", "newname"), + ("co_lnotab", code2.co_lnotab), + ): + with self.subTest(attr=attr, value=value): + new_code = code.replace(**{attr: value}) + self.assertEqual(getattr(new_code, attr), value) + + def isinterned(s): return s is sys.intern(('_' + s + '_')[1:-1]) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 109b01413b2d84..84cd0da94b36bf 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -674,13 +674,7 @@ def test_foreign_code(self): foreign_code = importlib.import_module.__code__ pos = constants.index(1) constants[pos] = foreign_code - code = type(code)(code.co_argcount, code.co_posonlyargcount, - code.co_kwonlyargcount, - code.co_nlocals, code.co_stacksize, - code.co_flags, code.co_code, tuple(constants), - code.co_names, code.co_varnames, code.co_filename, - code.co_name, code.co_firstlineno, code.co_lnotab, - code.co_freevars, code.co_cellvars) + code = code.replace(co_consts=tuple(constants)) with open(self.compiled_name, "wb") as f: f.write(header) marshal.dump(code, f) diff --git a/Lib/types.py b/Lib/types.py index 37ba4bb1f42e5d..ea3c0b29d5d4dd 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -262,14 +262,8 @@ def coroutine(func): if co_flags & 0x20: # TODO: Implement this in C. co = func.__code__ - func.__code__ = CodeType( - co.co_argcount, co.co_posonlyargcount, co.co_kwonlyargcount, co.co_nlocals, - co.co_stacksize, - co.co_flags | 0x100, # 0x100 == CO_ITERABLE_COROUTINE - co.co_code, - co.co_consts, co.co_names, co.co_varnames, co.co_filename, - co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars, - co.co_cellvars) + # 0x100 == CO_ITERABLE_COROUTINE + func.__code__ = co.replace(co_flags=co.co_flags | 0x100) return func # The following code is primarily to support functions that diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst new file mode 100644 index 00000000000000..7e31a84eb4688b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst @@ -0,0 +1 @@ +Added new ``replace()`` method to the code type (:class:`types.CodeType`). diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h new file mode 100644 index 00000000000000..ec127ce1718980 --- /dev/null +++ b/Objects/clinic/codeobject.c.h @@ -0,0 +1,256 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(code_replace__doc__, +"replace($self, /, *, co_argcount=-1, co_posonlyargcount=-1,\n" +" co_kwonlyargcount=-1, co_nlocals=-1, co_stacksize=-1,\n" +" co_flags=-1, co_firstlineno=-1, co_code=None, co_consts=None,\n" +" co_names=None, co_varnames=None, co_freevars=None,\n" +" co_cellvars=None, co_filename=None, co_name=None,\n" +" co_lnotab=None)\n" +"--\n" +"\n" +"Return a new code object with new specified fields."); + +#define CODE_REPLACE_METHODDEF \ + {"replace", (PyCFunction)(void(*)(void))code_replace, METH_FASTCALL|METH_KEYWORDS, code_replace__doc__}, + +static PyObject * +code_replace_impl(PyCodeObject *self, int co_argcount, + int co_posonlyargcount, int co_kwonlyargcount, + int co_nlocals, int co_stacksize, int co_flags, + int co_firstlineno, PyBytesObject *co_code, + PyObject *co_consts, PyObject *co_names, + PyObject *co_varnames, PyObject *co_freevars, + PyObject *co_cellvars, PyObject *co_filename, + PyObject *co_name, PyBytesObject *co_lnotab); + +static PyObject * +code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_lnotab", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + PyObject *argsbuf[16]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int co_argcount = self->co_argcount; + int co_posonlyargcount = self->co_posonlyargcount; + int co_kwonlyargcount = self->co_kwonlyargcount; + int co_nlocals = self->co_nlocals; + int co_stacksize = self->co_stacksize; + int co_flags = self->co_flags; + int co_firstlineno = self->co_firstlineno; + PyBytesObject *co_code = (PyBytesObject *)self->co_code; + PyObject *co_consts = self->co_consts; + PyObject *co_names = self->co_names; + PyObject *co_varnames = self->co_varnames; + PyObject *co_freevars = self->co_freevars; + PyObject *co_cellvars = self->co_cellvars; + PyObject *co_filename = self->co_filename; + PyObject *co_name = self->co_name; + PyBytesObject *co_lnotab = (PyBytesObject *)self->co_lnotab; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[0]) { + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_argcount = _PyLong_AsInt(args[0]); + if (co_argcount == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[1]) { + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_posonlyargcount = _PyLong_AsInt(args[1]); + if (co_posonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_kwonlyargcount = _PyLong_AsInt(args[2]); + if (co_kwonlyargcount == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + if (PyFloat_Check(args[3])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_nlocals = _PyLong_AsInt(args[3]); + if (co_nlocals == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[4]) { + if (PyFloat_Check(args[4])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_stacksize = _PyLong_AsInt(args[4]); + if (co_stacksize == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[5]) { + if (PyFloat_Check(args[5])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_flags = _PyLong_AsInt(args[5]); + if (co_flags == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[6]) { + if (PyFloat_Check(args[6])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + co_firstlineno = _PyLong_AsInt(args[6]); + if (co_firstlineno == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[7]) { + if (!PyBytes_Check(args[7])) { + _PyArg_BadArgument("replace", 8, "bytes", args[7]); + goto exit; + } + co_code = (PyBytesObject *)args[7]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[8]) { + if (!PyTuple_Check(args[8])) { + _PyArg_BadArgument("replace", 9, "tuple", args[8]); + goto exit; + } + co_consts = args[8]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[9]) { + if (!PyTuple_Check(args[9])) { + _PyArg_BadArgument("replace", 10, "tuple", args[9]); + goto exit; + } + co_names = args[9]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[10]) { + if (!PyTuple_Check(args[10])) { + _PyArg_BadArgument("replace", 11, "tuple", args[10]); + goto exit; + } + co_varnames = args[10]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[11]) { + if (!PyTuple_Check(args[11])) { + _PyArg_BadArgument("replace", 12, "tuple", args[11]); + goto exit; + } + co_freevars = args[11]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[12]) { + if (!PyTuple_Check(args[12])) { + _PyArg_BadArgument("replace", 13, "tuple", args[12]); + goto exit; + } + co_cellvars = args[12]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[13]) { + if (!PyUnicode_Check(args[13])) { + _PyArg_BadArgument("replace", 14, "str", args[13]); + goto exit; + } + if (PyUnicode_READY(args[13]) == -1) { + goto exit; + } + co_filename = args[13]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[14]) { + if (!PyUnicode_Check(args[14])) { + _PyArg_BadArgument("replace", 15, "str", args[14]); + goto exit; + } + if (PyUnicode_READY(args[14]) == -1) { + goto exit; + } + co_name = args[14]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (!PyBytes_Check(args[15])) { + _PyArg_BadArgument("replace", 16, "bytes", args[15]); + goto exit; + } + co_lnotab = (PyBytesObject *)args[15]; +skip_optional_kwonly: + return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_lnotab); + +exit: + return return_value; +} +/*[clinic end generated code: output=624ab6f2ea8f0ea4 input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index f4e48a9757e587..1e76f26d98fe67 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -5,6 +5,7 @@ #include "structmember.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" +#include "clinic/codeobject.c.h" /* Holder for co_extra information */ typedef struct { @@ -12,6 +13,11 @@ typedef struct { void *ce_extras[1]; } _PyCodeObjectExtra; +/*[clinic input] +class code "PyCodeObject *" "&PyCode_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78aa5d576683bb4b]*/ + /* all_name_chars(s): true iff s matches [a-zA-Z0-9_]* */ static int all_name_chars(PyObject *o) @@ -109,7 +115,8 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, /* Check argument types */ if (argcount < 0 || posonlyargcount < 0 || kwonlyargcount < 0 || - nlocals < 0 || code == NULL || !PyBytes_Check(code) || + nlocals < 0 || stacksize < 0 || flags < 0 || + code == NULL || !PyBytes_Check(code) || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || varnames == NULL || !PyTuple_Check(varnames) || @@ -122,9 +129,13 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, return NULL; } - /* Ensure that the filename is a ready Unicode string */ - if (PyUnicode_READY(filename) < 0) + /* Ensure that strings are ready Unicode string */ + if (PyUnicode_READY(name) < 0) { + return NULL; + } + if (PyUnicode_READY(filename) < 0) { return NULL; + } intern_strings(names); intern_strings(varnames); @@ -482,7 +493,7 @@ code_dealloc(PyCodeObject *co) } static PyObject * -code_sizeof(PyCodeObject *co, void *unused) +code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) { Py_ssize_t res = _PyObject_SIZE(Py_TYPE(co)); _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra; @@ -497,6 +508,65 @@ code_sizeof(PyCodeObject *co, void *unused) return PyLong_FromSsize_t(res); } +/*[clinic input] +code.replace + + * + co_argcount: int(c_default="self->co_argcount") = -1 + co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1 + co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1 + co_nlocals: int(c_default="self->co_nlocals") = -1 + co_stacksize: int(c_default="self->co_stacksize") = -1 + co_flags: int(c_default="self->co_flags") = -1 + co_firstlineno: int(c_default="self->co_firstlineno") = -1 + co_code: PyBytesObject(c_default="(PyBytesObject *)self->co_code") = None + co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None + co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None + co_varnames: object(subclass_of="&PyTuple_Type", c_default="self->co_varnames") = None + co_freevars: object(subclass_of="&PyTuple_Type", c_default="self->co_freevars") = None + co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None + co_filename: unicode(c_default="self->co_filename") = None + co_name: unicode(c_default="self->co_name") = None + co_lnotab: PyBytesObject(c_default="(PyBytesObject *)self->co_lnotab") = None + +Return a new code object with new specified fields. +[clinic start generated code]*/ + +static PyObject * +code_replace_impl(PyCodeObject *self, int co_argcount, + int co_posonlyargcount, int co_kwonlyargcount, + int co_nlocals, int co_stacksize, int co_flags, + int co_firstlineno, PyBytesObject *co_code, + PyObject *co_consts, PyObject *co_names, + PyObject *co_varnames, PyObject *co_freevars, + PyObject *co_cellvars, PyObject *co_filename, + PyObject *co_name, PyBytesObject *co_lnotab) +/*[clinic end generated code: output=25c8e303913bcace input=77189e46579ec426]*/ +{ +#define CHECK_INT_ARG(ARG) \ + if (ARG < 0) { \ + PyErr_SetString(PyExc_ValueError, \ + #ARG " must be a positive integer"); \ + return NULL; \ + } + + CHECK_INT_ARG(co_argcount); + CHECK_INT_ARG(co_posonlyargcount); + CHECK_INT_ARG(co_kwonlyargcount); + CHECK_INT_ARG(co_nlocals); + CHECK_INT_ARG(co_stacksize); + CHECK_INT_ARG(co_flags); + CHECK_INT_ARG(co_firstlineno); + +#undef CHECK_INT_ARG + + return (PyObject *)PyCode_New( + co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, + co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, + co_varnames, co_freevars, co_cellvars, co_filename, co_name, + co_firstlineno, (PyObject*)co_lnotab); +} + static PyObject * code_repr(PyCodeObject *co) { @@ -751,6 +821,7 @@ code_hash(PyCodeObject *co) static struct PyMethodDef code_methods[] = { {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS}, + CODE_REPLACE_METHODDEF {NULL, NULL} /* sentinel */ }; From 6dbbe748e101a173b4cff8aada41e9313e287e0f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 25 May 2019 00:09:38 +0200 Subject: [PATCH 103/441] bpo-36829: Document test.support.catch_unraisable_exception() (GH-13554) catch_unraisable_exception() now also removes its 'unraisable' attribute at the context manager exit. --- Doc/library/test.rst | 20 ++++++++++++++++++++ Lib/test/support/__init__.py | 8 +++++--- Lib/test/test_io.py | 20 ++++++-------------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 054521dcc5d3eb..b7a2595708d0ce 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1081,6 +1081,26 @@ The :mod:`test.support` module defines the following functions: :exc:`PermissionError` is raised. +.. function:: catch_unraisable_exception() + + Context manager catching unraisable exception using + :func:`sys.unraisablehook`. + + Usage:: + + with support.catch_unraisable_exception() as cm: + # code creating an "unraisable exception" + ... + + # check the unraisable exception: use cm.unraisable + ... + + # cm.unraisable attribute no longer exists at this point + # (to break a reference cycle) + + .. versionadded:: 3.8 + + .. function:: find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM) Returns an unused port that should be suitable for binding. This is diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 2fe9d9dc80998f..d6ed2215f38340 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3043,12 +3043,14 @@ class catch_unraisable_exception: Usage: with support.catch_unraisable_exception() as cm: + # code creating an "unraisable exception" ... - # check the expected unraisable exception: use cm.unraisable + # check the unraisable exception: use cm.unraisable ... - # cm.unraisable is None here (to break a reference cycle) + # cm.unraisable attribute no longer exists at this point + # (to break a reference cycle) """ def __init__(self): @@ -3065,5 +3067,5 @@ def __enter__(self): def __exit__(self, *exc_info): # Clear the unraisable exception to explicitly break a reference cycle - self.unraisable = None + del self.unraisable sys.unraisablehook = self._old_hook diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 6f22b35a9ab9f1..3a1f5ba5b6663d 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1098,18 +1098,14 @@ def test_error_through_destructor(self): # Test that the exception state is not modified by a destructor, # even if close() fails. rawio = self.CloseFailureIO() - try: - with support.catch_unraisable_exception() as cm: - with self.assertRaises(AttributeError): - self.tp(rawio).xyzzy + with support.catch_unraisable_exception() as cm: + with self.assertRaises(AttributeError): + self.tp(rawio).xyzzy if not IOBASE_EMITS_UNRAISABLE: self.assertIsNone(cm.unraisable) elif cm.unraisable is not None: self.assertEqual(cm.unraisable.exc_type, OSError) - finally: - # Explicitly break reference cycle - cm = None def test_repr(self): raw = self.MockRawIO() @@ -2854,18 +2850,14 @@ def test_error_through_destructor(self): # Test that the exception state is not modified by a destructor, # even if close() fails. rawio = self.CloseFailureIO() - try: - with support.catch_unraisable_exception() as cm: - with self.assertRaises(AttributeError): - self.TextIOWrapper(rawio).xyzzy + with support.catch_unraisable_exception() as cm: + with self.assertRaises(AttributeError): + self.TextIOWrapper(rawio).xyzzy if not IOBASE_EMITS_UNRAISABLE: self.assertIsNone(cm.unraisable) elif cm.unraisable is not None: self.assertEqual(cm.unraisable.exc_type, OSError) - finally: - # Explicitly break reference cycle - cm = None # Systematic tests of the text I/O API From 1bbf7b661f0ac8aac12d5531928d9a85c98ec1a9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 24 May 2019 19:59:01 -0400 Subject: [PATCH 104/441] bpo-34632: Add importlib.metadata (GH-12547) Add importlib.metadata module as forward port of the standalone importlib_metadata. --- Doc/library/importlib.metadata.rst | 257 +++ Doc/library/modules.rst | 1 + Doc/tools/susp-ignored.csv | 3 + Lib/importlib/_bootstrap_external.py | 52 + Lib/importlib/metadata/__init__.py | 394 +++++ Lib/test/test_importlib/data/__init__.py | 0 .../data/example-21.12-py3-none-any.whl | Bin 0 -> 1453 bytes .../data/example-21.12-py3.6.egg | Bin 0 -> 1492 bytes Lib/test/test_importlib/fixtures.py | 199 +++ Lib/test/test_importlib/test_main.py | 158 ++ Lib/test/test_importlib/test_metadata_api.py | 151 ++ Lib/test/test_importlib/test_zip.py | 56 + .../2019-05-11-02-30-45.bpo-34632.8MXa7T.rst | 1 + Python.framework/Resources | 1 + Python/importlib_external.h | 1413 +++++++++-------- 15 files changed, 2048 insertions(+), 638 deletions(-) create mode 100644 Doc/library/importlib.metadata.rst create mode 100644 Lib/importlib/metadata/__init__.py create mode 100644 Lib/test/test_importlib/data/__init__.py create mode 100644 Lib/test/test_importlib/data/example-21.12-py3-none-any.whl create mode 100644 Lib/test/test_importlib/data/example-21.12-py3.6.egg create mode 100644 Lib/test/test_importlib/fixtures.py create mode 100644 Lib/test/test_importlib/test_main.py create mode 100644 Lib/test/test_importlib/test_metadata_api.py create mode 100644 Lib/test/test_importlib/test_zip.py create mode 100644 Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst create mode 120000 Python.framework/Resources diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst new file mode 100644 index 00000000000000..3d10b5aeabfdc0 --- /dev/null +++ b/Doc/library/importlib.metadata.rst @@ -0,0 +1,257 @@ +.. _using: + +========================== + Using importlib.metadata +========================== + +.. note:: + This functionality is provisional and may deviate from the usual + version semantics of the standard library. + +``importlib.metadata`` is a library that provides for access to installed +package metadata. Built in part on Python's import system, this library +intends to replace similar functionality in the `entry point +API`_ and `metadata API`_ of ``pkg_resources``. Along with +``importlib.resources`` in `Python 3.7 +and newer`_ (backported as `importlib_resources`_ for older versions of +Python), this can eliminate the need to use the older and less efficient +``pkg_resources`` package. + +By "installed package" we generally mean a third-party package installed into +Python's ``site-packages`` directory via tools such as `pip +`_. Specifically, +it means a package with either a discoverable ``dist-info`` or ``egg-info`` +directory, and metadata defined by `PEP 566`_ or its older specifications. +By default, package metadata can live on the file system or in zip archives on +``sys.path``. Through an extension mechanism, the metadata can live almost +anywhere. + + +Overview +======== + +Let's say you wanted to get the version string for a package you've installed +using ``pip``. We start by creating a virtual environment and installing +something into it:: + +.. highlight:: none + + $ python3 -m venv example + $ source example/bin/activate + (example) $ pip install wheel + +You can get the version string for ``wheel`` by running the following:: + +.. highlight:: none + + (example) $ python + >>> from importlib.metadata import version # doctest: +SKIP + >>> version('wheel') # doctest: +SKIP + '0.32.3' + +You can also get the set of entry points keyed by group, such as +``console_scripts``, ``distutils.commands`` and others. Each group contains a +sequence of :ref:`EntryPoint ` objects. + +You can get the :ref:`metadata for a distribution `:: + + >>> list(metadata('wheel')) # doctest: +SKIP + ['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist'] + +You can also get a :ref:`distribution's version number `, list its +:ref:`constituent files `, and get a list of the distribution's +:ref:`requirements`. + + +Functional API +============== + +This package provides the following functionality via its public API. + + +.. _entry-points: + +Entry points +------------ + +The ``entry_points()`` function returns a dictionary of all entry points, +keyed by group. Entry points are represented by ``EntryPoint`` instances; +each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and +a ``.load()`` method to resolve the value. + + >>> eps = entry_points() # doctest: +SKIP + >>> list(eps) # doctest: +SKIP + ['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation'] + >>> scripts = eps['console_scripts'] # doctest: +SKIP + >>> wheel = [ep for ep in scripts if ep.name == 'wheel'][0] # doctest: +SKIP + >>> wheel # doctest: +SKIP + EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts') + >>> main = wheel.load() # doctest: +SKIP + >>> main # doctest: +SKIP + + +The ``group`` and ``name`` are arbitrary values defined by the package author +and usually a client will wish to resolve all entry points for a particular +group. Read `the setuptools docs +`_ +for more information on entrypoints, their definition, and usage. + + +.. _metadata: + +Distribution metadata +--------------------- + +Every distribution includes some metadata, which you can extract using the +``metadata()`` function:: + + >>> wheel_metadata = metadata('wheel') # doctest: +SKIP + +The keys of the returned data structure [#f1]_ name the metadata keywords, and +their values are returned unparsed from the distribution metadata:: + + >>> wheel_metadata['Requires-Python'] # doctest: +SKIP + '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' + + +.. _version: + +Distribution versions +--------------------- + +The ``version()`` function is the quickest way to get a distribution's version +number, as a string:: + + >>> version('wheel') # doctest: +SKIP + '0.32.3' + + +.. _files: + +Distribution files +------------------ + +You can also get the full set of files contained within a distribution. The +``files()`` function takes a distribution package name and returns all of the +files installed by this distribution. Each file object returned is a +``PackagePath``, a `pathlib.Path`_ derived object with additional ``dist``, +``size``, and ``hash`` properties as indicated by the metadata. For example:: + + >>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] # doctest: +SKIP + >>> util # doctest: +SKIP + PackagePath('wheel/util.py') + >>> util.size # doctest: +SKIP + 859 + >>> util.dist # doctest: +SKIP + + >>> util.hash # doctest: +SKIP + + +Once you have the file, you can also read its contents:: + + >>> print(util.read_text()) # doctest: +SKIP + import base64 + import sys + ... + def as_bytes(s): + if isinstance(s, text_type): + return s.encode('utf-8') + return s + + +.. _requirements: + +Distribution requirements +------------------------- + +To get the full set of requirements for a distribution, use the ``requires()`` +function. Note that this returns an iterator:: + + >>> list(requires('wheel')) # doctest: +SKIP + ["pytest (>=3.0.0) ; extra == 'test'"] + + +Distributions +============= + +While the above API is the most common and convenient usage, you can get all +of that information from the ``Distribution`` class. A ``Distribution`` is an +abstract object that represents the metadata for a Python package. You can +get the ``Distribution`` instance:: + + >>> from importlib.metadata import distribution # doctest: +SKIP + >>> dist = distribution('wheel') # doctest: +SKIP + +Thus, an alternative way to get the version number is through the +``Distribution`` instance:: + + >>> dist.version # doctest: +SKIP + '0.32.3' + +There are all kinds of additional metadata available on the ``Distribution`` +instance:: + + >>> d.metadata['Requires-Python'] # doctest: +SKIP + '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' + >>> d.metadata['License'] # doctest: +SKIP + 'MIT' + +The full set of available metadata is not described here. See `PEP 566 +`_ for additional details. + + +Extending the search algorithm +============================== + +Because package metadata is not available through ``sys.path`` searches, or +package loaders directly, the metadata for a package is found through import +system `finders`_. To find a distribution package's metadata, +``importlib.metadata`` queries the list of `meta path finders`_ on +`sys.meta_path`_. + +By default ``importlib.metadata`` installs a finder for distribution packages +found on the file system. This finder doesn't actually find any *packages*, +but it can find the packages' metadata. + +The abstract class :py:class:`importlib.abc.MetaPathFinder` defines the +interface expected of finders by Python's import system. +``importlib.metadata`` extends this protocol by looking for an optional +``find_distributions`` callable on the finders from +``sys.meta_path``. If the finder has this method, it must return +an iterator over instances of the ``Distribution`` abstract class. This +method must have the signature:: + + def find_distributions(name=None, path=None): + """Return an iterable of all Distribution instances capable of + loading the metadata for packages matching the name + (or all names if not supplied) along the paths in the list + of directories ``path`` (defaults to sys.path). + """ + +What this means in practice is that to support finding distribution package +metadata in locations other than the file system, you should derive from +``Distribution`` and implement the ``load_metadata()`` method. This takes a +single argument which is the name of the package whose metadata is being +found. This instance of the ``Distribution`` base abstract class is what your +finder's ``find_distributions()`` method should return. + + +.. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points +.. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api +.. _`Python 3.7 and newer`: https://docs.python.org/3/library/importlib.html#module-importlib.resources +.. _`importlib_resources`: https://importlib-resources.readthedocs.io/en/latest/index.html +.. _`PEP 566`: https://www.python.org/dev/peps/pep-0566/ +.. _`finders`: https://docs.python.org/3/reference/import.html#finders-and-loaders +.. _`meta path finders`: https://docs.python.org/3/glossary.html#term-meta-path-finder +.. _`sys.meta_path`: https://docs.python.org/3/library/sys.html#sys.meta_path +.. _`pathlib.Path`: https://docs.python.org/3/library/pathlib.html#pathlib.Path + + +.. rubric:: Footnotes + +.. [#f1] Technically, the returned distribution metadata object is an + `email.message.Message + `_ + instance, but this is an implementation detail, and not part of the + stable API. You should only use dictionary-like methods and syntax + to access the metadata contents. diff --git a/Doc/library/modules.rst b/Doc/library/modules.rst index 6b2a40a1b71476..565ce0525c2c99 100644 --- a/Doc/library/modules.rst +++ b/Doc/library/modules.rst @@ -17,3 +17,4 @@ The full list of modules described in this chapter is: modulefinder.rst runpy.rst importlib.rst + importlib.metadata.rst diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 31b22665eca475..85ff9d02aeb2db 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -350,3 +350,6 @@ whatsnew/3.7,,::,error::BytesWarning whatsnew/changelog,,::,error::BytesWarning whatsnew/changelog,,::,default::BytesWarning whatsnew/changelog,,::,default::DeprecationWarning +library/importlib.metadata,,.. highlight:,.. highlight:: none +library/importlib.metadata,,:main,"EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')" +library/importlib.metadata,,`,of directories ``path`` (defaults to sys.path). diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 7da0cd0f196554..9b5db81a3d7ba3 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1363,6 +1363,58 @@ def find_module(cls, fullname, path=None): return None return spec.loader + search_template = r'(?:{pattern}(-.*)?\.(dist|egg)-info|EGG-INFO)' + + @classmethod + def find_distributions(cls, name=None, path=None): + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching the ``name`` + (or all names if not supplied) along the paths in the list + of directories ``path`` (defaults to sys.path). + """ + import re + from importlib.metadata import PathDistribution + if path is None: + path = sys.path + pattern = '.*' if name is None else re.escape(name) + found = cls._search_paths(pattern, path) + return map(PathDistribution, found) + + @classmethod + def _search_paths(cls, pattern, paths): + """Find metadata directories in paths heuristically.""" + import itertools + return itertools.chain.from_iterable( + cls._search_path(path, pattern) + for path in map(cls._switch_path, paths) + ) + + @staticmethod + def _switch_path(path): + from contextlib import suppress + import zipfile + from pathlib import Path + with suppress(Exception): + return zipfile.Path(path) + return Path(path) + + @classmethod + def _predicate(cls, pattern, root, item): + import re + return re.match(pattern, str(item.name), flags=re.IGNORECASE) + + @classmethod + def _search_path(cls, root, pattern): + if not root.is_dir(): + return () + normalized = pattern.replace('-', '_') + matcher = cls.search_template.format(pattern=normalized) + return (item for item in root.iterdir() + if cls._predicate(matcher, root, item)) + class FileFinder: diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py new file mode 100644 index 00000000000000..24d45d2caad0ad --- /dev/null +++ b/Lib/importlib/metadata/__init__.py @@ -0,0 +1,394 @@ +import io +import re +import abc +import csv +import sys +import email +import pathlib +import operator +import functools +import itertools +import collections + +from configparser import ConfigParser +from contextlib import suppress +from importlib import import_module +from importlib.abc import MetaPathFinder +from itertools import starmap + + +__all__ = [ + 'Distribution', + 'PackageNotFoundError', + 'distribution', + 'distributions', + 'entry_points', + 'files', + 'metadata', + 'requires', + 'version', + ] + + +class PackageNotFoundError(ModuleNotFoundError): + """The package was not found.""" + + +class EntryPoint(collections.namedtuple('EntryPointBase', 'name value group')): + """An entry point as defined by Python packaging conventions. + + See `the packaging docs on entry points + `_ + for more information. + """ + + pattern = re.compile( + r'(?P[\w.]+)\s*' + r'(:\s*(?P[\w.]+))?\s*' + r'(?P\[.*\])?\s*$' + ) + """ + A regular expression describing the syntax for an entry point, + which might look like: + + - module + - package.module + - package.module:attribute + - package.module:object.attribute + - package.module:attr [extra1, extra2] + + Other combinations are possible as well. + + The expression is lenient about whitespace around the ':', + following the attr, and following any extras. + """ + + def load(self): + """Load the entry point from its definition. If only a module + is indicated by the value, return that module. Otherwise, + return the named object. + """ + match = self.pattern.match(self.value) + module = import_module(match.group('module')) + attrs = filter(None, (match.group('attr') or '').split('.')) + return functools.reduce(getattr, attrs, module) + + @property + def extras(self): + match = self.pattern.match(self.value) + return list(re.finditer(r'\w+', match.group('extras') or '')) + + @classmethod + def _from_config(cls, config): + return [ + cls(name, value, group) + for group in config.sections() + for name, value in config.items(group) + ] + + @classmethod + def _from_text(cls, text): + config = ConfigParser() + try: + config.read_string(text) + except AttributeError: # pragma: nocover + # Python 2 has no read_string + config.readfp(io.StringIO(text)) + return EntryPoint._from_config(config) + + def __iter__(self): + """ + Supply iter so one may construct dicts of EntryPoints easily. + """ + return iter((self.name, self)) + + +class PackagePath(pathlib.PurePosixPath): + """A reference to a path in a package""" + + def read_text(self, encoding='utf-8'): + with self.locate().open(encoding=encoding) as stream: + return stream.read() + + def read_binary(self): + with self.locate().open('rb') as stream: + return stream.read() + + def locate(self): + """Return a path-like object for this path""" + return self.dist.locate_file(self) + + +class FileHash: + def __init__(self, spec): + self.mode, _, self.value = spec.partition('=') + + def __repr__(self): + return ''.format(self.mode, self.value) + + +class Distribution: + """A Python distribution package.""" + + @abc.abstractmethod + def read_text(self, filename): + """Attempt to load metadata file given by the name. + + :param filename: The name of the file in the distribution info. + :return: The text if found, otherwise None. + """ + + @abc.abstractmethod + def locate_file(self, path): + """ + Given a path to a file in this distribution, return a path + to it. + """ + + @classmethod + def from_name(cls, name): + """Return the Distribution for the given package name. + + :param name: The name of the distribution package to search for. + :return: The Distribution instance (or subclass thereof) for the named + package, if found. + :raises PackageNotFoundError: When the named package's distribution + metadata cannot be found. + """ + for resolver in cls._discover_resolvers(): + dists = resolver(name) + dist = next(dists, None) + if dist is not None: + return dist + else: + raise PackageNotFoundError(name) + + @classmethod + def discover(cls): + """Return an iterable of Distribution objects for all packages. + + :return: Iterable of Distribution objects for all packages. + """ + return itertools.chain.from_iterable( + resolver() + for resolver in cls._discover_resolvers() + ) + + @staticmethod + def _discover_resolvers(): + """Search the meta_path for resolvers.""" + declared = ( + getattr(finder, 'find_distributions', None) + for finder in sys.meta_path + ) + return filter(None, declared) + + @property + def metadata(self): + """Return the parsed metadata for this Distribution. + + The returned object will have keys that name the various bits of + metadata. See PEP 566 for details. + """ + text = ( + self.read_text('METADATA') + or self.read_text('PKG-INFO') + # This last clause is here to support old egg-info files. Its + # effect is to just end up using the PathDistribution's self._path + # (which points to the egg-info file) attribute unchanged. + or self.read_text('') + ) + return email.message_from_string(text) + + @property + def version(self): + """Return the 'Version' metadata for the distribution package.""" + return self.metadata['Version'] + + @property + def entry_points(self): + return EntryPoint._from_text(self.read_text('entry_points.txt')) + + @property + def files(self): + file_lines = self._read_files_distinfo() or self._read_files_egginfo() + + def make_file(name, hash=None, size_str=None): + result = PackagePath(name) + result.hash = FileHash(hash) if hash else None + result.size = int(size_str) if size_str else None + result.dist = self + return result + + return file_lines and starmap(make_file, csv.reader(file_lines)) + + def _read_files_distinfo(self): + """ + Read the lines of RECORD + """ + text = self.read_text('RECORD') + return text and text.splitlines() + + def _read_files_egginfo(self): + """ + SOURCES.txt might contain literal commas, so wrap each line + in quotes. + """ + text = self.read_text('SOURCES.txt') + return text and map('"{}"'.format, text.splitlines()) + + @property + def requires(self): + """Generated requirements specified for this Distribution""" + return self._read_dist_info_reqs() or self._read_egg_info_reqs() + + def _read_dist_info_reqs(self): + spec = self.metadata['Requires-Dist'] + return spec and filter(None, spec.splitlines()) + + def _read_egg_info_reqs(self): + source = self.read_text('requires.txt') + return source and self._deps_from_requires_text(source) + + @classmethod + def _deps_from_requires_text(cls, source): + section_pairs = cls._read_sections(source.splitlines()) + sections = { + section: list(map(operator.itemgetter('line'), results)) + for section, results in + itertools.groupby(section_pairs, operator.itemgetter('section')) + } + return cls._convert_egg_info_reqs_to_simple_reqs(sections) + + @staticmethod + def _read_sections(lines): + section = None + for line in filter(None, lines): + section_match = re.match(r'\[(.*)\]$', line) + if section_match: + section = section_match.group(1) + continue + yield locals() + + @staticmethod + def _convert_egg_info_reqs_to_simple_reqs(sections): + """ + Historically, setuptools would solicit and store 'extra' + requirements, including those with environment markers, + in separate sections. More modern tools expect each + dependency to be defined separately, with any relevant + extras and environment markers attached directly to that + requirement. This method converts the former to the + latter. See _test_deps_from_requires_text for an example. + """ + def make_condition(name): + return name and 'extra == "{name}"'.format(name=name) + + def parse_condition(section): + section = section or '' + extra, sep, markers = section.partition(':') + if extra and markers: + markers = '({markers})'.format(markers=markers) + conditions = list(filter(None, [markers, make_condition(extra)])) + return '; ' + ' and '.join(conditions) if conditions else '' + + for section, deps in sections.items(): + for dep in deps: + yield dep + parse_condition(section) + + +class DistributionFinder(MetaPathFinder): + """ + A MetaPathFinder capable of discovering installed distributions. + """ + + @abc.abstractmethod + def find_distributions(self, name=None, path=None): + """ + Find distributions. + + Return an iterable of all Distribution instances capable of + loading the metadata for packages matching the ``name`` + (or all names if not supplied) along the paths in the list + of directories ``path`` (defaults to sys.path). + """ + + +class PathDistribution(Distribution): + def __init__(self, path): + """Construct a distribution from a path to the metadata directory.""" + self._path = path + + def read_text(self, filename): + with suppress(FileNotFoundError, NotADirectoryError, KeyError): + return self._path.joinpath(filename).read_text(encoding='utf-8') + read_text.__doc__ = Distribution.read_text.__doc__ + + def locate_file(self, path): + return self._path.parent / path + + +def distribution(package): + """Get the ``Distribution`` instance for the given package. + + :param package: The name of the package as a string. + :return: A ``Distribution`` instance (or subclass thereof). + """ + return Distribution.from_name(package) + + +def distributions(): + """Get all ``Distribution`` instances in the current environment. + + :return: An iterable of ``Distribution`` instances. + """ + return Distribution.discover() + + +def metadata(package): + """Get the metadata for the package. + + :param package: The name of the distribution package to query. + :return: An email.Message containing the parsed metadata. + """ + return Distribution.from_name(package).metadata + + +def version(package): + """Get the version string for the named package. + + :param package: The name of the distribution package to query. + :return: The version string for the package as defined in the package's + "Version" metadata key. + """ + return distribution(package).version + + +def entry_points(): + """Return EntryPoint objects for all installed packages. + + :return: EntryPoint objects for all installed packages. + """ + eps = itertools.chain.from_iterable( + dist.entry_points for dist in distributions()) + by_group = operator.attrgetter('group') + ordered = sorted(eps, key=by_group) + grouped = itertools.groupby(ordered, by_group) + return { + group: tuple(eps) + for group, eps in grouped + } + + +def files(package): + return distribution(package).files + + +def requires(package): + """ + Return a list of requirements for the indicated distribution. + + :return: An iterator of requirements, suitable for + packaging.requirement.Requirement. + """ + return distribution(package).requires diff --git a/Lib/test/test_importlib/data/__init__.py b/Lib/test/test_importlib/data/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/Lib/test/test_importlib/data/example-21.12-py3-none-any.whl b/Lib/test/test_importlib/data/example-21.12-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..f92f7716e3e613a2a9703be785135fd8b35cfb1c GIT binary patch literal 1453 zcmWIWW@Zs#U|`^2$X%l2E2Vj`LJ`OVVPPOntw_u*$Vt_YkI&4@EQycTE2#AL^bJ1Y zd*;mL3tJuqF*Gf@GU?JH8`iH^x{lmwniEp0#}EKF@#|6@-~Vw}E~^1e(gI=)go(OF zhI)oZdMTO3CAyh;Y5Dr8c_l@a@df#rc_qbqB^4#ze&^0>pF8i_tM8|GN=HMp@2S^X zk2AU_JVQ5xHf&l`By9Y7#||{R?xt`CaRKe%0Af`#eJG?#%hkK?YZh9~AkY_15*$IjO%X$iwTT zj$Wre`^vxz1{aLYt{7i=!gcDr{>864*LXE_z0RKW*%YLqspb2W%hP9jkj4s=YiCcN z_rB_TX7!Ut=+0vKml077bk1%dR>0#dU)K;v7sn9C*zS#7hYUnqzke6~*(h?!FxuR) z*JA$j=D}6nJuk63>$g|^aHQ)0StmYywxSwA=est9~!zT(kqV|fK2BE1^mxK0q zD(qh)b?4sPb$w-l5$bn#F3Qs`KJ!0*^MQ6R{<p(1r$KgS)&i+9zwP$x1H90UiT)ZdwKjq+uV@j;~jI4*9 zFSbRdFl*>>tZs;(uk_eQ>hgU{@!k)&u4PPICc4gJ)}^;Bzl1h5{m``K-uhy9=9lTe z-NnTxRmGRCybveUZnWu;{lQCXJ}s6};eD{ z#=6?Q%UABG&=n2Q`J~J@GtS}8)q{&~{}TM{1aZ}u05ukm*h zl5ERPr=_}oV=S9Bfwe1=@2=aOxF-kSE;PEja34gdfE literal 0 HcmV?d00001 diff --git a/Lib/test/test_importlib/data/example-21.12-py3.6.egg b/Lib/test/test_importlib/data/example-21.12-py3.6.egg new file mode 100644 index 0000000000000000000000000000000000000000..1d3f998f41b89700512b9bd20681e55e81963028 GIT binary patch literal 1492 zcmWIWW@Zs#U|`^2xR$fp@3nF0krp8DC=d$*v8%hguBV@yzkYx>gb~~8$aTm-!1cSO ztKNj9U1!!ka0&=sxZ<^c4f@#kCS*N+n7GL42YfZ! zEk5xYo$43J*3tWYGog!X+Wp$0%DLy;7$(q4-Im54c05E zC@DSV$kpt?s$Pc9T!_{7cXah`>i&=P4|_F+Kpf9t5RHa za$M}sCdvd)D?c%>-)L{RYwfgc?`B2cv%3AJhgrnPA#S40>GXa36wF*N9Z0I@t{X7}-NOjPvdHdANi9gtOG(X3u8hyg%*!qYIq)$P1FG)-aaS&@0d;8s zu_UtY)Vz|S%J_o(%)An?&ThYR=e5tB_w3d8(>tZ3q1pG;Ypur_-4mXn8$ug4ttk>V z{=8!cn&Ed-ID@!=hH?P07_#9d`33Pgsb#4-AUAnK%z29LG-QvVq>-x30^Q=ov{V$& z{LEhMC#89?LJ?>W2nz#oYDHphK~AcEe0*kJW=VX!UO}a|r*H5H-!o?}U)b^}h@olG zl}VQt*|2`S(skrc)0~h}Jv1NOWa-&67iiKmAl61Pv7jt+c^o&BMdrcl^@ zSk2sisfqekzBSxSIDx)oWD;SVM6j1EI}h{$CjQE+QWd_v7~Nf13<+rdh$gWumZ&Zf{8i6o0ScunF9z7fLi-N HB@P1s(BI54 literal 0 HcmV?d00001 diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py new file mode 100644 index 00000000000000..3b926ba26df779 --- /dev/null +++ b/Lib/test/test_importlib/fixtures.py @@ -0,0 +1,199 @@ +from __future__ import unicode_literals + +import os +import sys +import shutil +import tempfile +import textwrap +import contextlib + +try: + from contextlib import ExitStack +except ImportError: + from contextlib2 import ExitStack + +try: + import pathlib +except ImportError: + import pathlib2 as pathlib + + +__metaclass__ = type + + +@contextlib.contextmanager +def tempdir(): + tmpdir = tempfile.mkdtemp() + try: + yield pathlib.Path(tmpdir) + finally: + shutil.rmtree(tmpdir) + + +@contextlib.contextmanager +def save_cwd(): + orig = os.getcwd() + try: + yield + finally: + os.chdir(orig) + + +@contextlib.contextmanager +def tempdir_as_cwd(): + with tempdir() as tmp: + with save_cwd(): + os.chdir(str(tmp)) + yield tmp + + +class SiteDir: + def setUp(self): + self.fixtures = ExitStack() + self.addCleanup(self.fixtures.close) + self.site_dir = self.fixtures.enter_context(tempdir()) + + +class OnSysPath: + @staticmethod + @contextlib.contextmanager + def add_sys_path(dir): + sys.path[:0] = [str(dir)] + try: + yield + finally: + sys.path.remove(str(dir)) + + def setUp(self): + super(OnSysPath, self).setUp() + self.fixtures.enter_context(self.add_sys_path(self.site_dir)) + + +class DistInfoPkg(OnSysPath, SiteDir): + files = { + "distinfo_pkg-1.0.0.dist-info": { + "METADATA": """ + Name: distinfo-pkg + Author: Steven Ma + Version: 1.0.0 + Requires-Dist: wheel >= 1.0 + Requires-Dist: pytest; extra == 'test' + """, + "RECORD": "mod.py,sha256=abc,20\n", + "entry_points.txt": """ + [entries] + main = mod:main + """ + }, + "mod.py": """ + def main(): + print("hello world") + """, + } + + def setUp(self): + super(DistInfoPkg, self).setUp() + build_files(DistInfoPkg.files, self.site_dir) + + +class DistInfoPkgOffPath(SiteDir): + def setUp(self): + super(DistInfoPkgOffPath, self).setUp() + build_files(DistInfoPkg.files, self.site_dir) + + +class EggInfoPkg(OnSysPath, SiteDir): + files = { + "egginfo_pkg.egg-info": { + "PKG-INFO": """ + Name: egginfo-pkg + Author: Steven Ma + License: Unknown + Version: 1.0.0 + Classifier: Intended Audience :: Developers + Classifier: Topic :: Software Development :: Libraries + """, + "SOURCES.txt": """ + mod.py + egginfo_pkg.egg-info/top_level.txt + """, + "entry_points.txt": """ + [entries] + main = mod:main + """, + "requires.txt": """ + wheel >= 1.0; python_version >= "2.7" + [test] + pytest + """, + "top_level.txt": "mod\n" + }, + "mod.py": """ + def main(): + print("hello world") + """, + } + + def setUp(self): + super(EggInfoPkg, self).setUp() + build_files(EggInfoPkg.files, prefix=self.site_dir) + + +class EggInfoFile(OnSysPath, SiteDir): + files = { + "egginfo_file.egg-info": """ + Metadata-Version: 1.0 + Name: egginfo_file + Version: 0.1 + Summary: An example package + Home-page: www.example.com + Author: Eric Haffa-Vee + Author-email: eric@example.coms + License: UNKNOWN + Description: UNKNOWN + Platform: UNKNOWN + """, + } + + def setUp(self): + super(EggInfoFile, self).setUp() + build_files(EggInfoFile.files, prefix=self.site_dir) + + +def build_files(file_defs, prefix=pathlib.Path()): + """Build a set of files/directories, as described by the + + file_defs dictionary. Each key/value pair in the dictionary is + interpreted as a filename/contents pair. If the contents value is a + dictionary, a directory is created, and the dictionary interpreted + as the files within it, recursively. + + For example: + + {"README.txt": "A README file", + "foo": { + "__init__.py": "", + "bar": { + "__init__.py": "", + }, + "baz.py": "# Some code", + } + } + """ + for name, contents in file_defs.items(): + full_name = prefix / name + if isinstance(contents, dict): + full_name.mkdir() + build_files(contents, prefix=full_name) + else: + if isinstance(contents, bytes): + with full_name.open('wb') as f: + f.write(contents) + else: + with full_name.open('w') as f: + f.write(DALS(contents)) + + +def DALS(str): + "Dedent and left-strip" + return textwrap.dedent(str).lstrip() diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py new file mode 100644 index 00000000000000..b70f9440f6973a --- /dev/null +++ b/Lib/test/test_importlib/test_main.py @@ -0,0 +1,158 @@ +# coding: utf-8 + +import re +import textwrap +import unittest +import importlib.metadata + +from . import fixtures +from importlib.metadata import ( + Distribution, EntryPoint, + PackageNotFoundError, distributions, + entry_points, metadata, version, + ) + + +class BasicTests(fixtures.DistInfoPkg, unittest.TestCase): + version_pattern = r'\d+\.\d+(\.\d)?' + + def test_retrieves_version_of_self(self): + dist = Distribution.from_name('distinfo-pkg') + assert isinstance(dist.version, str) + assert re.match(self.version_pattern, dist.version) + + def test_for_name_does_not_exist(self): + with self.assertRaises(PackageNotFoundError): + Distribution.from_name('does-not-exist') + + def test_new_style_classes(self): + self.assertIsInstance(Distribution, type) + + +class ImportTests(fixtures.DistInfoPkg, unittest.TestCase): + def test_import_nonexistent_module(self): + # Ensure that the MetadataPathFinder does not crash an import of a + # non-existant module. + with self.assertRaises(ImportError): + importlib.import_module('does_not_exist') + + def test_resolve(self): + entries = dict(entry_points()['entries']) + ep = entries['main'] + self.assertEqual(ep.load().__name__, "main") + + def test_resolve_without_attr(self): + ep = EntryPoint( + name='ep', + value='importlib.metadata', + group='grp', + ) + assert ep.load() is importlib.metadata + + +class NameNormalizationTests( + fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): + @staticmethod + def pkg_with_dashes(site_dir): + """ + Create minimal metadata for a package with dashes + in the name (and thus underscores in the filename). + """ + metadata_dir = site_dir / 'my_pkg.dist-info' + metadata_dir.mkdir() + metadata = metadata_dir / 'METADATA' + with metadata.open('w') as strm: + strm.write('Version: 1.0\n') + return 'my-pkg' + + def test_dashes_in_dist_name_found_as_underscores(self): + """ + For a package with a dash in the name, the dist-info metadata + uses underscores in the name. Ensure the metadata loads. + """ + pkg_name = self.pkg_with_dashes(self.site_dir) + assert version(pkg_name) == '1.0' + + @staticmethod + def pkg_with_mixed_case(site_dir): + """ + Create minimal metadata for a package with mixed case + in the name. + """ + metadata_dir = site_dir / 'CherryPy.dist-info' + metadata_dir.mkdir() + metadata = metadata_dir / 'METADATA' + with metadata.open('w') as strm: + strm.write('Version: 1.0\n') + return 'CherryPy' + + def test_dist_name_found_as_any_case(self): + """ + Ensure the metadata loads when queried with any case. + """ + pkg_name = self.pkg_with_mixed_case(self.site_dir) + assert version(pkg_name) == '1.0' + assert version(pkg_name.lower()) == '1.0' + assert version(pkg_name.upper()) == '1.0' + + +class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): + @staticmethod + def pkg_with_non_ascii_description(site_dir): + """ + Create minimal metadata for a package with non-ASCII in + the description. + """ + metadata_dir = site_dir / 'portend.dist-info' + metadata_dir.mkdir() + metadata = metadata_dir / 'METADATA' + with metadata.open('w', encoding='utf-8') as fp: + fp.write('Description: pôrˈtend\n') + return 'portend' + + @staticmethod + def pkg_with_non_ascii_description_egg_info(site_dir): + """ + Create minimal metadata for an egg-info package with + non-ASCII in the description. + """ + metadata_dir = site_dir / 'portend.dist-info' + metadata_dir.mkdir() + metadata = metadata_dir / 'METADATA' + with metadata.open('w', encoding='utf-8') as fp: + fp.write(textwrap.dedent(""" + Name: portend + + pôrˈtend + """).lstrip()) + return 'portend' + + def test_metadata_loads(self): + pkg_name = self.pkg_with_non_ascii_description(self.site_dir) + meta = metadata(pkg_name) + assert meta['Description'] == 'pôrˈtend' + + def test_metadata_loads_egg_info(self): + pkg_name = self.pkg_with_non_ascii_description_egg_info(self.site_dir) + meta = metadata(pkg_name) + assert meta.get_payload() == 'pôrˈtend\n' + + +class DiscoveryTests(fixtures.EggInfoPkg, + fixtures.DistInfoPkg, + unittest.TestCase): + + def test_package_discovery(self): + dists = list(distributions()) + assert all( + isinstance(dist, Distribution) + for dist in dists + ) + assert any( + dist.metadata['Name'] == 'egginfo-pkg' + for dist in dists + ) + assert any( + dist.metadata['Name'] == 'distinfo-pkg' + for dist in dists + ) diff --git a/Lib/test/test_importlib/test_metadata_api.py b/Lib/test/test_importlib/test_metadata_api.py new file mode 100644 index 00000000000000..899777f4b1ad01 --- /dev/null +++ b/Lib/test/test_importlib/test_metadata_api.py @@ -0,0 +1,151 @@ +import re +import textwrap +import unittest +import itertools + +from collections.abc import Iterator + +from . import fixtures +from importlib.metadata import ( + Distribution, PackageNotFoundError, distribution, + entry_points, files, metadata, requires, version, + ) + + +class APITests( + fixtures.EggInfoPkg, + fixtures.DistInfoPkg, + fixtures.EggInfoFile, + unittest.TestCase): + + version_pattern = r'\d+\.\d+(\.\d)?' + + def test_retrieves_version_of_self(self): + pkg_version = version('egginfo-pkg') + assert isinstance(pkg_version, str) + assert re.match(self.version_pattern, pkg_version) + + def test_retrieves_version_of_distinfo_pkg(self): + pkg_version = version('distinfo-pkg') + assert isinstance(pkg_version, str) + assert re.match(self.version_pattern, pkg_version) + + def test_for_name_does_not_exist(self): + with self.assertRaises(PackageNotFoundError): + distribution('does-not-exist') + + def test_for_top_level(self): + self.assertEqual( + distribution('egginfo-pkg').read_text('top_level.txt').strip(), + 'mod') + + def test_read_text(self): + top_level = [ + path for path in files('egginfo-pkg') + if path.name == 'top_level.txt' + ][0] + self.assertEqual(top_level.read_text(), 'mod\n') + + def test_entry_points(self): + entries = dict(entry_points()['entries']) + ep = entries['main'] + self.assertEqual(ep.value, 'mod:main') + self.assertEqual(ep.extras, []) + + def test_metadata_for_this_package(self): + md = metadata('egginfo-pkg') + assert md['author'] == 'Steven Ma' + assert md['LICENSE'] == 'Unknown' + assert md['Name'] == 'egginfo-pkg' + classifiers = md.get_all('Classifier') + assert 'Topic :: Software Development :: Libraries' in classifiers + + @staticmethod + def _test_files(files_iter): + assert isinstance(files_iter, Iterator), files_iter + files = list(files_iter) + root = files[0].root + for file in files: + assert file.root == root + assert not file.hash or file.hash.value + assert not file.hash or file.hash.mode == 'sha256' + assert not file.size or file.size >= 0 + assert file.locate().exists() + assert isinstance(file.read_binary(), bytes) + if file.name.endswith('.py'): + file.read_text() + + def test_file_hash_repr(self): + assertRegex = self.assertRegex + + util = [ + p for p in files('distinfo-pkg') + if p.name == 'mod.py' + ][0] + assertRegex( + repr(util.hash), + '') + + def test_files_dist_info(self): + self._test_files(files('distinfo-pkg')) + + def test_files_egg_info(self): + self._test_files(files('egginfo-pkg')) + + def test_version_egg_info_file(self): + self.assertEqual(version('egginfo-file'), '0.1') + + def test_requires_egg_info_file(self): + requirements = requires('egginfo-file') + self.assertIsNone(requirements) + + def test_requires(self): + deps = requires('egginfo-pkg') + assert any( + dep == 'wheel >= 1.0; python_version >= "2.7"' + for dep in deps + ) + + def test_requires_dist_info(self): + deps = list(requires('distinfo-pkg')) + assert deps and all(deps) + + def test_more_complex_deps_requires_text(self): + requires = textwrap.dedent(""" + dep1 + dep2 + + [:python_version < "3"] + dep3 + + [extra1] + dep4 + + [extra2:python_version < "3"] + dep5 + """) + deps = sorted(Distribution._deps_from_requires_text(requires)) + expected = [ + 'dep1', + 'dep2', + 'dep3; python_version < "3"', + 'dep4; extra == "extra1"', + 'dep5; (python_version < "3") and extra == "extra2"', + ] + # It's important that the environment marker expression be + # wrapped in parentheses to avoid the following 'and' binding more + # tightly than some other part of the environment expression. + + assert deps == expected + + +class OffSysPathTests(fixtures.DistInfoPkgOffPath, unittest.TestCase): + def test_find_distributions_specified_path(self): + dists = itertools.chain.from_iterable( + resolver(path=[str(self.site_dir)]) + for resolver in Distribution._discover_resolvers() + ) + assert any( + dist.metadata['Name'] == 'distinfo-pkg' + for dist in dists + ) diff --git a/Lib/test/test_importlib/test_zip.py b/Lib/test/test_importlib/test_zip.py new file mode 100644 index 00000000000000..db39e190ea7ac9 --- /dev/null +++ b/Lib/test/test_importlib/test_zip.py @@ -0,0 +1,56 @@ +import sys +import unittest + +from contextlib import ExitStack +from importlib.metadata import distribution, entry_points, files, version +from importlib.resources import path + + +class TestZip(unittest.TestCase): + root = 'test.test_importlib.data' + + def setUp(self): + # Find the path to the example-*.whl so we can add it to the front of + # sys.path, where we'll then try to find the metadata thereof. + self.resources = ExitStack() + self.addCleanup(self.resources.close) + wheel = self.resources.enter_context( + path(self.root, 'example-21.12-py3-none-any.whl')) + sys.path.insert(0, str(wheel)) + self.resources.callback(sys.path.pop, 0) + + def test_zip_version(self): + self.assertEqual(version('example'), '21.12') + + def test_zip_entry_points(self): + scripts = dict(entry_points()['console_scripts']) + entry_point = scripts['example'] + self.assertEqual(entry_point.value, 'example:main') + + def test_missing_metadata(self): + self.assertIsNone(distribution('example').read_text('does not exist')) + + def test_case_insensitive(self): + self.assertEqual(version('Example'), '21.12') + + def test_files(self): + for file in files('example'): + path = str(file.dist.locate_file(file)) + assert '.whl/' in path, path + + +class TestEgg(TestZip): + def setUp(self): + # Find the path to the example-*.egg so we can add it to the front of + # sys.path, where we'll then try to find the metadata thereof. + self.resources = ExitStack() + self.addCleanup(self.resources.close) + egg = self.resources.enter_context( + path(self.root, 'example-21.12-py3.6.egg')) + sys.path.insert(0, str(egg)) + self.resources.callback(sys.path.pop, 0) + + def test_files(self): + for file in files('example'): + path = str(file.dist.locate_file(file)) + assert '.egg/' in path, path diff --git a/Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst b/Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst new file mode 100644 index 00000000000000..ab4433846d4f7f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst @@ -0,0 +1 @@ +Introduce the ``importlib.metadata`` module with (provisional) support for reading metadata from third-party packages. \ No newline at end of file diff --git a/Python.framework/Resources b/Python.framework/Resources new file mode 120000 index 00000000000000..953ee36f3bb709 --- /dev/null +++ b/Python.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Python/importlib_external.h b/Python/importlib_external.h index 36b95d99b23706..e724560d67a1c2 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -2051,650 +2051,787 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 1,8,3,2,1,10,8,8,3,8,3,8,3,8,3,8, 3,114,43,1,0,0,99,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, - 106,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, + 172,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, 101,4,100,2,100,3,132,0,131,1,90,5,101,4,100,4, 100,5,132,0,131,1,90,6,101,4,100,6,100,7,132,0, 131,1,90,7,101,4,100,8,100,9,132,0,131,1,90,8, - 101,4,100,17,100,11,100,12,132,1,131,1,90,9,101,4, - 100,18,100,13,100,14,132,1,131,1,90,10,101,4,100,19, - 100,15,100,16,132,1,131,1,90,11,100,10,83,0,41,20, - 218,10,80,97,116,104,70,105,110,100,101,114,122,62,77,101, - 116,97,32,112,97,116,104,32,102,105,110,100,101,114,32,102, - 111,114,32,115,121,115,46,112,97,116,104,32,97,110,100,32, - 112,97,99,107,97,103,101,32,95,95,112,97,116,104,95,95, - 32,97,116,116,114,105,98,117,116,101,115,46,99,1,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,4,0,0, - 0,67,0,0,0,115,64,0,0,0,116,0,116,1,106,2, - 160,3,161,0,131,1,68,0,93,44,92,2,125,1,125,2, - 124,2,100,1,107,8,114,40,116,1,106,2,124,1,61,0, - 113,14,116,4,124,2,100,2,131,2,114,14,124,2,160,5, - 161,0,1,0,113,14,100,1,83,0,41,3,122,125,67,97, - 108,108,32,116,104,101,32,105,110,118,97,108,105,100,97,116, - 101,95,99,97,99,104,101,115,40,41,32,109,101,116,104,111, - 100,32,111,110,32,97,108,108,32,112,97,116,104,32,101,110, - 116,114,121,32,102,105,110,100,101,114,115,10,32,32,32,32, - 32,32,32,32,115,116,111,114,101,100,32,105,110,32,115,121, - 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,101,115,32,40,119,104,101,114,101,32,105,109, - 112,108,101,109,101,110,116,101,100,41,46,78,218,17,105,110, - 118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,41, - 6,218,4,108,105,115,116,114,8,0,0,0,218,19,112,97, - 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, - 101,218,5,105,116,101,109,115,114,128,0,0,0,114,46,1, - 0,0,41,3,114,193,0,0,0,114,117,0,0,0,218,6, - 102,105,110,100,101,114,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,46,1,0,0,213,4,0,0,115,10, - 0,0,0,0,4,22,1,8,1,10,1,10,1,122,28,80, - 97,116,104,70,105,110,100,101,114,46,105,110,118,97,108,105, - 100,97,116,101,95,99,97,99,104,101,115,99,2,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,9,0,0,0, - 67,0,0,0,115,84,0,0,0,116,0,106,1,100,1,107, - 9,114,28,116,0,106,1,115,28,116,2,160,3,100,2,116, - 4,161,2,1,0,116,0,106,1,68,0,93,44,125,2,122, - 14,124,2,124,1,131,1,87,0,2,0,1,0,83,0,4, - 0,116,5,107,10,114,76,1,0,1,0,1,0,89,0,113, - 34,89,0,113,34,88,0,113,34,100,1,83,0,41,3,122, - 46,83,101,97,114,99,104,32,115,121,115,46,112,97,116,104, - 95,104,111,111,107,115,32,102,111,114,32,97,32,102,105,110, - 100,101,114,32,102,111,114,32,39,112,97,116,104,39,46,78, - 122,23,115,121,115,46,112,97,116,104,95,104,111,111,107,115, - 32,105,115,32,101,109,112,116,121,41,6,114,8,0,0,0, - 218,10,112,97,116,104,95,104,111,111,107,115,114,75,0,0, - 0,114,76,0,0,0,114,138,0,0,0,114,118,0,0,0, - 41,3,114,193,0,0,0,114,44,0,0,0,90,4,104,111, - 111,107,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,11,95,112,97,116,104,95,104,111,111,107,115,223,4, - 0,0,115,16,0,0,0,0,3,16,1,12,1,10,1,2, - 1,14,1,14,1,12,2,122,22,80,97,116,104,70,105,110, - 100,101,114,46,95,112,97,116,104,95,104,111,111,107,115,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 8,0,0,0,67,0,0,0,115,104,0,0,0,124,1,100, - 1,107,2,114,44,122,12,116,0,160,1,161,0,125,1,87, - 0,110,22,4,0,116,2,107,10,114,42,1,0,1,0,1, - 0,89,0,100,2,83,0,88,0,122,14,116,3,106,4,124, - 1,25,0,125,2,87,0,110,40,4,0,116,5,107,10,114, - 98,1,0,1,0,1,0,124,0,160,6,124,1,161,1,125, - 2,124,2,116,3,106,4,124,1,60,0,89,0,110,2,88, - 0,124,2,83,0,41,3,122,210,71,101,116,32,116,104,101, - 32,102,105,110,100,101,114,32,102,111,114,32,116,104,101,32, - 112,97,116,104,32,101,110,116,114,121,32,102,114,111,109,32, + 101,4,100,28,100,11,100,12,132,1,131,1,90,9,101,4, + 100,29,100,13,100,14,132,1,131,1,90,10,101,4,100,30, + 100,15,100,16,132,1,131,1,90,11,100,17,90,12,101,4, + 100,31,100,18,100,19,132,1,131,1,90,13,101,4,100,20, + 100,21,132,0,131,1,90,14,101,15,100,22,100,23,132,0, + 131,1,90,16,101,4,100,24,100,25,132,0,131,1,90,17, + 101,4,100,26,100,27,132,0,131,1,90,18,100,10,83,0, + 41,32,218,10,80,97,116,104,70,105,110,100,101,114,122,62, + 77,101,116,97,32,112,97,116,104,32,102,105,110,100,101,114, + 32,102,111,114,32,115,121,115,46,112,97,116,104,32,97,110, + 100,32,112,97,99,107,97,103,101,32,95,95,112,97,116,104, + 95,95,32,97,116,116,114,105,98,117,116,101,115,46,99,1, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, + 0,0,0,67,0,0,0,115,64,0,0,0,116,0,116,1, + 106,2,160,3,161,0,131,1,68,0,93,44,92,2,125,1, + 125,2,124,2,100,1,107,8,114,40,116,1,106,2,124,1, + 61,0,113,14,116,4,124,2,100,2,131,2,114,14,124,2, + 160,5,161,0,1,0,113,14,100,1,83,0,41,3,122,125, + 67,97,108,108,32,116,104,101,32,105,110,118,97,108,105,100, + 97,116,101,95,99,97,99,104,101,115,40,41,32,109,101,116, + 104,111,100,32,111,110,32,97,108,108,32,112,97,116,104,32, + 101,110,116,114,121,32,102,105,110,100,101,114,115,10,32,32, + 32,32,32,32,32,32,115,116,111,114,101,100,32,105,110,32, 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,46,10,10,32,32,32,32,32,32, - 32,32,73,102,32,116,104,101,32,112,97,116,104,32,101,110, - 116,114,121,32,105,115,32,110,111,116,32,105,110,32,116,104, - 101,32,99,97,99,104,101,44,32,102,105,110,100,32,116,104, - 101,32,97,112,112,114,111,112,114,105,97,116,101,32,102,105, - 110,100,101,114,10,32,32,32,32,32,32,32,32,97,110,100, - 32,99,97,99,104,101,32,105,116,46,32,73,102,32,110,111, - 32,102,105,110,100,101,114,32,105,115,32,97,118,97,105,108, - 97,98,108,101,44,32,115,116,111,114,101,32,78,111,110,101, - 46,10,10,32,32,32,32,32,32,32,32,114,40,0,0,0, - 78,41,7,114,2,0,0,0,114,55,0,0,0,114,3,1, - 0,0,114,8,0,0,0,114,48,1,0,0,218,8,75,101, - 121,69,114,114,111,114,114,52,1,0,0,41,3,114,193,0, - 0,0,114,44,0,0,0,114,50,1,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,20,95,112,97, - 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, - 101,236,4,0,0,115,22,0,0,0,0,8,8,1,2,1, - 12,1,14,3,8,1,2,1,14,1,14,1,10,1,16,1, - 122,31,80,97,116,104,70,105,110,100,101,114,46,95,112,97, - 116,104,95,105,109,112,111,114,116,101,114,95,99,97,99,104, - 101,99,3,0,0,0,0,0,0,0,0,0,0,0,6,0, - 0,0,4,0,0,0,67,0,0,0,115,82,0,0,0,116, - 0,124,2,100,1,131,2,114,26,124,2,160,1,124,1,161, - 1,92,2,125,3,125,4,110,14,124,2,160,2,124,1,161, - 1,125,3,103,0,125,4,124,3,100,0,107,9,114,60,116, - 3,160,4,124,1,124,3,161,2,83,0,116,3,160,5,124, - 1,100,0,161,2,125,5,124,4,124,5,95,6,124,5,83, - 0,41,2,78,114,137,0,0,0,41,7,114,128,0,0,0, - 114,137,0,0,0,114,206,0,0,0,114,134,0,0,0,114, - 201,0,0,0,114,183,0,0,0,114,178,0,0,0,41,6, - 114,193,0,0,0,114,139,0,0,0,114,50,1,0,0,114, - 140,0,0,0,114,141,0,0,0,114,187,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,16,95, - 108,101,103,97,99,121,95,103,101,116,95,115,112,101,99,2, - 5,0,0,115,18,0,0,0,0,4,10,1,16,2,10,1, - 4,1,8,1,12,1,12,1,6,1,122,27,80,97,116,104, - 70,105,110,100,101,114,46,95,108,101,103,97,99,121,95,103, - 101,116,95,115,112,101,99,78,99,4,0,0,0,0,0,0, - 0,0,0,0,0,9,0,0,0,5,0,0,0,67,0,0, - 0,115,166,0,0,0,103,0,125,4,124,2,68,0,93,134, - 125,5,116,0,124,5,116,1,116,2,102,2,131,2,115,28, - 113,8,124,0,160,3,124,5,161,1,125,6,124,6,100,1, - 107,9,114,8,116,4,124,6,100,2,131,2,114,70,124,6, - 160,5,124,1,124,3,161,2,125,7,110,12,124,0,160,6, - 124,1,124,6,161,2,125,7,124,7,100,1,107,8,114,92, - 113,8,124,7,106,7,100,1,107,9,114,110,124,7,2,0, - 1,0,83,0,124,7,106,8,125,8,124,8,100,1,107,8, - 114,132,116,9,100,3,131,1,130,1,124,4,160,10,124,8, - 161,1,1,0,113,8,116,11,160,12,124,1,100,1,161,2, - 125,7,124,4,124,7,95,8,124,7,83,0,41,4,122,63, - 70,105,110,100,32,116,104,101,32,108,111,97,100,101,114,32, - 111,114,32,110,97,109,101,115,112,97,99,101,95,112,97,116, - 104,32,102,111,114,32,116,104,105,115,32,109,111,100,117,108, - 101,47,112,97,99,107,97,103,101,32,110,97,109,101,46,78, - 114,203,0,0,0,122,19,115,112,101,99,32,109,105,115,115, - 105,110,103,32,108,111,97,100,101,114,41,13,114,161,0,0, - 0,114,85,0,0,0,218,5,98,121,116,101,115,114,54,1, - 0,0,114,128,0,0,0,114,203,0,0,0,114,55,1,0, - 0,114,140,0,0,0,114,178,0,0,0,114,118,0,0,0, - 114,167,0,0,0,114,134,0,0,0,114,183,0,0,0,41, - 9,114,193,0,0,0,114,139,0,0,0,114,44,0,0,0, - 114,202,0,0,0,218,14,110,97,109,101,115,112,97,99,101, - 95,112,97,116,104,90,5,101,110,116,114,121,114,50,1,0, - 0,114,187,0,0,0,114,141,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,9,95,103,101,116, - 95,115,112,101,99,17,5,0,0,115,40,0,0,0,0,5, - 4,1,8,1,14,1,2,1,10,1,8,1,10,1,14,2, - 12,1,8,1,2,1,10,1,8,1,6,1,8,1,8,5, - 12,2,12,1,6,1,122,20,80,97,116,104,70,105,110,100, - 101,114,46,95,103,101,116,95,115,112,101,99,99,4,0,0, - 0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0, - 0,67,0,0,0,115,100,0,0,0,124,2,100,1,107,8, - 114,14,116,0,106,1,125,2,124,0,160,2,124,1,124,2, - 124,3,161,3,125,4,124,4,100,1,107,8,114,40,100,1, - 83,0,124,4,106,3,100,1,107,8,114,92,124,4,106,4, - 125,5,124,5,114,86,100,1,124,4,95,5,116,6,124,1, - 124,5,124,0,106,2,131,3,124,4,95,4,124,4,83,0, - 100,1,83,0,110,4,124,4,83,0,100,1,83,0,41,2, - 122,141,84,114,121,32,116,111,32,102,105,110,100,32,97,32, - 115,112,101,99,32,102,111,114,32,39,102,117,108,108,110,97, - 109,101,39,32,111,110,32,115,121,115,46,112,97,116,104,32, - 111,114,32,39,112,97,116,104,39,46,10,10,32,32,32,32, - 32,32,32,32,84,104,101,32,115,101,97,114,99,104,32,105, - 115,32,98,97,115,101,100,32,111,110,32,115,121,115,46,112, - 97,116,104,95,104,111,111,107,115,32,97,110,100,32,115,121, - 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,101,46,10,32,32,32,32,32,32,32,32,78, - 41,7,114,8,0,0,0,114,44,0,0,0,114,58,1,0, - 0,114,140,0,0,0,114,178,0,0,0,114,181,0,0,0, - 114,22,1,0,0,41,6,114,193,0,0,0,114,139,0,0, - 0,114,44,0,0,0,114,202,0,0,0,114,187,0,0,0, - 114,57,1,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,203,0,0,0,49,5,0,0,115,26,0, - 0,0,0,6,8,1,6,1,14,1,8,1,4,1,10,1, - 6,1,4,3,6,1,16,1,4,2,6,2,122,20,80,97, - 116,104,70,105,110,100,101,114,46,102,105,110,100,95,115,112, - 101,99,99,3,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,4,0,0,0,67,0,0,0,115,30,0,0,0, - 124,0,160,0,124,1,124,2,161,2,125,3,124,3,100,1, - 107,8,114,24,100,1,83,0,124,3,106,1,83,0,41,2, - 122,170,102,105,110,100,32,116,104,101,32,109,111,100,117,108, - 101,32,111,110,32,115,121,115,46,112,97,116,104,32,111,114, - 32,39,112,97,116,104,39,32,98,97,115,101,100,32,111,110, - 32,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32, - 97,110,100,10,32,32,32,32,32,32,32,32,115,121,115,46, + 114,95,99,97,99,104,101,115,32,40,119,104,101,114,101,32, + 105,109,112,108,101,109,101,110,116,101,100,41,46,78,218,17, + 105,110,118,97,108,105,100,97,116,101,95,99,97,99,104,101, + 115,41,6,218,4,108,105,115,116,114,8,0,0,0,218,19, 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,46,10,10,32,32,32,32,32,32,32,32,84,104, - 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,46,32,32,85,115,101,32,102,105, - 110,100,95,115,112,101,99,40,41,32,105,110,115,116,101,97, - 100,46,10,10,32,32,32,32,32,32,32,32,78,114,204,0, - 0,0,114,205,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,206,0,0,0,73,5,0,0,115, - 8,0,0,0,0,8,12,1,8,1,4,1,122,22,80,97, - 116,104,70,105,110,100,101,114,46,102,105,110,100,95,109,111, - 100,117,108,101,41,1,78,41,2,78,78,41,1,78,41,12, - 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, - 127,0,0,0,114,207,0,0,0,114,46,1,0,0,114,52, - 1,0,0,114,54,1,0,0,114,55,1,0,0,114,58,1, - 0,0,114,203,0,0,0,114,206,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,45,1,0,0,209,4,0,0,115,30,0,0,0,8,2, - 4,2,2,1,10,9,2,1,10,12,2,1,10,21,2,1, - 10,14,2,1,12,31,2,1,12,23,2,1,114,45,1,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,64,0,0,0,115,90,0,0,0,101, - 0,90,1,100,0,90,2,100,1,90,3,100,2,100,3,132, - 0,90,4,100,4,100,5,132,0,90,5,101,6,90,7,100, - 6,100,7,132,0,90,8,100,8,100,9,132,0,90,9,100, - 19,100,11,100,12,132,1,90,10,100,13,100,14,132,0,90, - 11,101,12,100,15,100,16,132,0,131,1,90,13,100,17,100, - 18,132,0,90,14,100,10,83,0,41,20,218,10,70,105,108, - 101,70,105,110,100,101,114,122,172,70,105,108,101,45,98,97, - 115,101,100,32,102,105,110,100,101,114,46,10,10,32,32,32, - 32,73,110,116,101,114,97,99,116,105,111,110,115,32,119,105, - 116,104,32,116,104,101,32,102,105,108,101,32,115,121,115,116, - 101,109,32,97,114,101,32,99,97,99,104,101,100,32,102,111, - 114,32,112,101,114,102,111,114,109,97,110,99,101,44,32,98, - 101,105,110,103,10,32,32,32,32,114,101,102,114,101,115,104, - 101,100,32,119,104,101,110,32,116,104,101,32,100,105,114,101, - 99,116,111,114,121,32,116,104,101,32,102,105,110,100,101,114, - 32,105,115,32,104,97,110,100,108,105,110,103,32,104,97,115, - 32,98,101,101,110,32,109,111,100,105,102,105,101,100,46,10, - 10,32,32,32,32,99,2,0,0,0,0,0,0,0,0,0, - 0,0,5,0,0,0,6,0,0,0,7,0,0,0,115,84, - 0,0,0,103,0,125,3,124,2,68,0,93,32,92,2,137, - 0,125,4,124,3,160,0,135,0,102,1,100,1,100,2,132, - 8,124,4,68,0,131,1,161,1,1,0,113,8,124,3,124, - 0,95,1,124,1,112,54,100,3,124,0,95,2,100,4,124, - 0,95,3,116,4,131,0,124,0,95,5,116,4,131,0,124, - 0,95,6,100,5,83,0,41,6,122,154,73,110,105,116,105, - 97,108,105,122,101,32,119,105,116,104,32,116,104,101,32,112, - 97,116,104,32,116,111,32,115,101,97,114,99,104,32,111,110, - 32,97,110,100,32,97,32,118,97,114,105,97,98,108,101,32, - 110,117,109,98,101,114,32,111,102,10,32,32,32,32,32,32, - 32,32,50,45,116,117,112,108,101,115,32,99,111,110,116,97, - 105,110,105,110,103,32,116,104,101,32,108,111,97,100,101,114, - 32,97,110,100,32,116,104,101,32,102,105,108,101,32,115,117, - 102,102,105,120,101,115,32,116,104,101,32,108,111,97,100,101, - 114,10,32,32,32,32,32,32,32,32,114,101,99,111,103,110, - 105,122,101,115,46,99,1,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,51,0,0,0,115,22, - 0,0,0,124,0,93,14,125,1,124,1,136,0,102,2,86, - 0,1,0,113,2,100,0,83,0,114,110,0,0,0,114,3, - 0,0,0,114,16,1,0,0,169,1,114,140,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,19,1,0,0,102,5, - 0,0,115,4,0,0,0,4,0,2,0,122,38,70,105,108, + 99,104,101,218,5,105,116,101,109,115,114,128,0,0,0,114, + 46,1,0,0,41,3,114,193,0,0,0,114,117,0,0,0, + 218,6,102,105,110,100,101,114,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,46,1,0,0,213,4,0,0, + 115,10,0,0,0,0,4,22,1,8,1,10,1,10,1,122, + 28,80,97,116,104,70,105,110,100,101,114,46,105,110,118,97, + 108,105,100,97,116,101,95,99,97,99,104,101,115,99,2,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,9,0, + 0,0,67,0,0,0,115,84,0,0,0,116,0,106,1,100, + 1,107,9,114,28,116,0,106,1,115,28,116,2,160,3,100, + 2,116,4,161,2,1,0,116,0,106,1,68,0,93,44,125, + 2,122,14,124,2,124,1,131,1,87,0,2,0,1,0,83, + 0,4,0,116,5,107,10,114,76,1,0,1,0,1,0,89, + 0,113,34,89,0,113,34,88,0,113,34,100,1,83,0,41, + 3,122,46,83,101,97,114,99,104,32,115,121,115,46,112,97, + 116,104,95,104,111,111,107,115,32,102,111,114,32,97,32,102, + 105,110,100,101,114,32,102,111,114,32,39,112,97,116,104,39, + 46,78,122,23,115,121,115,46,112,97,116,104,95,104,111,111, + 107,115,32,105,115,32,101,109,112,116,121,41,6,114,8,0, + 0,0,218,10,112,97,116,104,95,104,111,111,107,115,114,75, + 0,0,0,114,76,0,0,0,114,138,0,0,0,114,118,0, + 0,0,41,3,114,193,0,0,0,114,44,0,0,0,90,4, + 104,111,111,107,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,11,95,112,97,116,104,95,104,111,111,107,115, + 223,4,0,0,115,16,0,0,0,0,3,16,1,12,1,10, + 1,2,1,14,1,14,1,12,2,122,22,80,97,116,104,70, + 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, + 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,8,0,0,0,67,0,0,0,115,104,0,0,0,124, + 1,100,1,107,2,114,44,122,12,116,0,160,1,161,0,125, + 1,87,0,110,22,4,0,116,2,107,10,114,42,1,0,1, + 0,1,0,89,0,100,2,83,0,88,0,122,14,116,3,106, + 4,124,1,25,0,125,2,87,0,110,40,4,0,116,5,107, + 10,114,98,1,0,1,0,1,0,124,0,160,6,124,1,161, + 1,125,2,124,2,116,3,106,4,124,1,60,0,89,0,110, + 2,88,0,124,2,83,0,41,3,122,210,71,101,116,32,116, + 104,101,32,102,105,110,100,101,114,32,102,111,114,32,116,104, + 101,32,112,97,116,104,32,101,110,116,114,121,32,102,114,111, + 109,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,46,10,10,32,32,32,32, + 32,32,32,32,73,102,32,116,104,101,32,112,97,116,104,32, + 101,110,116,114,121,32,105,115,32,110,111,116,32,105,110,32, + 116,104,101,32,99,97,99,104,101,44,32,102,105,110,100,32, + 116,104,101,32,97,112,112,114,111,112,114,105,97,116,101,32, + 102,105,110,100,101,114,10,32,32,32,32,32,32,32,32,97, + 110,100,32,99,97,99,104,101,32,105,116,46,32,73,102,32, + 110,111,32,102,105,110,100,101,114,32,105,115,32,97,118,97, + 105,108,97,98,108,101,44,32,115,116,111,114,101,32,78,111, + 110,101,46,10,10,32,32,32,32,32,32,32,32,114,40,0, + 0,0,78,41,7,114,2,0,0,0,114,55,0,0,0,114, + 3,1,0,0,114,8,0,0,0,114,48,1,0,0,218,8, + 75,101,121,69,114,114,111,114,114,52,1,0,0,41,3,114, + 193,0,0,0,114,44,0,0,0,114,50,1,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,20,95, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,236,4,0,0,115,22,0,0,0,0,8,8,1, + 2,1,12,1,14,3,8,1,2,1,14,1,14,1,10,1, + 16,1,122,31,80,97,116,104,70,105,110,100,101,114,46,95, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,99,3,0,0,0,0,0,0,0,0,0,0,0, + 6,0,0,0,4,0,0,0,67,0,0,0,115,82,0,0, + 0,116,0,124,2,100,1,131,2,114,26,124,2,160,1,124, + 1,161,1,92,2,125,3,125,4,110,14,124,2,160,2,124, + 1,161,1,125,3,103,0,125,4,124,3,100,0,107,9,114, + 60,116,3,160,4,124,1,124,3,161,2,83,0,116,3,160, + 5,124,1,100,0,161,2,125,5,124,4,124,5,95,6,124, + 5,83,0,41,2,78,114,137,0,0,0,41,7,114,128,0, + 0,0,114,137,0,0,0,114,206,0,0,0,114,134,0,0, + 0,114,201,0,0,0,114,183,0,0,0,114,178,0,0,0, + 41,6,114,193,0,0,0,114,139,0,0,0,114,50,1,0, + 0,114,140,0,0,0,114,141,0,0,0,114,187,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 16,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, + 99,2,5,0,0,115,18,0,0,0,0,4,10,1,16,2, + 10,1,4,1,8,1,12,1,12,1,6,1,122,27,80,97, + 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, + 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, + 0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,67, + 0,0,0,115,166,0,0,0,103,0,125,4,124,2,68,0, + 93,134,125,5,116,0,124,5,116,1,116,2,102,2,131,2, + 115,28,113,8,124,0,160,3,124,5,161,1,125,6,124,6, + 100,1,107,9,114,8,116,4,124,6,100,2,131,2,114,70, + 124,6,160,5,124,1,124,3,161,2,125,7,110,12,124,0, + 160,6,124,1,124,6,161,2,125,7,124,7,100,1,107,8, + 114,92,113,8,124,7,106,7,100,1,107,9,114,110,124,7, + 2,0,1,0,83,0,124,7,106,8,125,8,124,8,100,1, + 107,8,114,132,116,9,100,3,131,1,130,1,124,4,160,10, + 124,8,161,1,1,0,113,8,116,11,160,12,124,1,100,1, + 161,2,125,7,124,4,124,7,95,8,124,7,83,0,41,4, + 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, + 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, + 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, + 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, + 46,78,114,203,0,0,0,122,19,115,112,101,99,32,109,105, + 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,161, + 0,0,0,114,85,0,0,0,218,5,98,121,116,101,115,114, + 54,1,0,0,114,128,0,0,0,114,203,0,0,0,114,55, + 1,0,0,114,140,0,0,0,114,178,0,0,0,114,118,0, + 0,0,114,167,0,0,0,114,134,0,0,0,114,183,0,0, + 0,41,9,114,193,0,0,0,114,139,0,0,0,114,44,0, + 0,0,114,202,0,0,0,218,14,110,97,109,101,115,112,97, + 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,50, + 1,0,0,114,187,0,0,0,114,141,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,9,95,103, + 101,116,95,115,112,101,99,17,5,0,0,115,40,0,0,0, + 0,5,4,1,8,1,14,1,2,1,10,1,8,1,10,1, + 14,2,12,1,8,1,2,1,10,1,8,1,6,1,8,1, + 8,5,12,2,12,1,6,1,122,20,80,97,116,104,70,105, + 110,100,101,114,46,95,103,101,116,95,115,112,101,99,99,4, + 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5, + 0,0,0,67,0,0,0,115,100,0,0,0,124,2,100,1, + 107,8,114,14,116,0,106,1,125,2,124,0,160,2,124,1, + 124,2,124,3,161,3,125,4,124,4,100,1,107,8,114,40, + 100,1,83,0,124,4,106,3,100,1,107,8,114,92,124,4, + 106,4,125,5,124,5,114,86,100,1,124,4,95,5,116,6, + 124,1,124,5,124,0,106,2,131,3,124,4,95,4,124,4, + 83,0,100,1,83,0,110,4,124,4,83,0,100,1,83,0, + 41,2,122,141,84,114,121,32,116,111,32,102,105,110,100,32, + 97,32,115,112,101,99,32,102,111,114,32,39,102,117,108,108, + 110,97,109,101,39,32,111,110,32,115,121,115,46,112,97,116, + 104,32,111,114,32,39,112,97,116,104,39,46,10,10,32,32, + 32,32,32,32,32,32,84,104,101,32,115,101,97,114,99,104, + 32,105,115,32,98,97,115,101,100,32,111,110,32,115,121,115, + 46,112,97,116,104,95,104,111,111,107,115,32,97,110,100,32, + 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, + 114,95,99,97,99,104,101,46,10,32,32,32,32,32,32,32, + 32,78,41,7,114,8,0,0,0,114,44,0,0,0,114,58, + 1,0,0,114,140,0,0,0,114,178,0,0,0,114,181,0, + 0,0,114,22,1,0,0,41,6,114,193,0,0,0,114,139, + 0,0,0,114,44,0,0,0,114,202,0,0,0,114,187,0, + 0,0,114,57,1,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,203,0,0,0,49,5,0,0,115, + 26,0,0,0,0,6,8,1,6,1,14,1,8,1,4,1, + 10,1,6,1,4,3,6,1,16,1,4,2,6,2,122,20, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 115,112,101,99,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,4,0,0,0,67,0,0,0,115,30,0, + 0,0,124,0,160,0,124,1,124,2,161,2,125,3,124,3, + 100,1,107,8,114,24,100,1,83,0,124,3,106,1,83,0, + 41,2,122,170,102,105,110,100,32,116,104,101,32,109,111,100, + 117,108,101,32,111,110,32,115,121,115,46,112,97,116,104,32, + 111,114,32,39,112,97,116,104,39,32,98,97,115,101,100,32, + 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, + 115,32,97,110,100,10,32,32,32,32,32,32,32,32,115,121, + 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,114, + 204,0,0,0,114,205,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,206,0,0,0,73,5,0, + 0,115,8,0,0,0,0,8,12,1,8,1,4,1,122,22, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 109,111,100,117,108,101,122,45,40,63,58,123,112,97,116,116, + 101,114,110,125,40,45,46,42,41,63,92,46,40,100,105,115, + 116,124,101,103,103,41,45,105,110,102,111,124,69,71,71,45, + 73,78,70,79,41,99,3,0,0,0,0,0,0,0,0,0, + 0,0,7,0,0,0,4,0,0,0,67,0,0,0,115,78, + 0,0,0,100,1,100,2,108,0,125,3,100,1,100,3,108, + 1,109,2,125,4,1,0,124,2,100,2,107,8,114,34,116, + 3,106,4,125,2,124,1,100,2,107,8,114,46,100,4,110, + 8,124,3,160,5,124,1,161,1,125,5,124,0,160,6,124, + 5,124,2,161,2,125,6,116,7,124,4,124,6,131,2,83, + 0,41,5,97,37,1,0,0,10,32,32,32,32,32,32,32, + 32,70,105,110,100,32,100,105,115,116,114,105,98,117,116,105, + 111,110,115,46,10,10,32,32,32,32,32,32,32,32,82,101, + 116,117,114,110,32,97,110,32,105,116,101,114,97,98,108,101, + 32,111,102,32,97,108,108,32,68,105,115,116,114,105,98,117, + 116,105,111,110,32,105,110,115,116,97,110,99,101,115,32,99, + 97,112,97,98,108,101,32,111,102,10,32,32,32,32,32,32, + 32,32,108,111,97,100,105,110,103,32,116,104,101,32,109,101, + 116,97,100,97,116,97,32,102,111,114,32,112,97,99,107,97, + 103,101,115,32,109,97,116,99,104,105,110,103,32,116,104,101, + 32,96,96,110,97,109,101,96,96,10,32,32,32,32,32,32, + 32,32,40,111,114,32,97,108,108,32,110,97,109,101,115,32, + 105,102,32,110,111,116,32,115,117,112,112,108,105,101,100,41, + 32,97,108,111,110,103,32,116,104,101,32,112,97,116,104,115, + 32,105,110,32,116,104,101,32,108,105,115,116,10,32,32,32, + 32,32,32,32,32,111,102,32,100,105,114,101,99,116,111,114, + 105,101,115,32,96,96,112,97,116,104,96,96,32,40,100,101, + 102,97,117,108,116,115,32,116,111,32,115,121,115,46,112,97, + 116,104,41,46,10,32,32,32,32,32,32,32,32,114,73,0, + 0,0,78,41,1,218,16,80,97,116,104,68,105,115,116,114, + 105,98,117,116,105,111,110,122,2,46,42,41,8,218,2,114, + 101,90,18,105,109,112,111,114,116,108,105,98,46,109,101,116, + 97,100,97,116,97,114,59,1,0,0,114,8,0,0,0,114, + 44,0,0,0,90,6,101,115,99,97,112,101,218,13,95,115, + 101,97,114,99,104,95,112,97,116,104,115,218,3,109,97,112, + 41,7,114,193,0,0,0,114,117,0,0,0,114,44,0,0, + 0,114,60,1,0,0,114,59,1,0,0,218,7,112,97,116, + 116,101,114,110,90,5,102,111,117,110,100,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,18,102,105,110,100, + 95,100,105,115,116,114,105,98,117,116,105,111,110,115,88,5, + 0,0,115,14,0,0,0,0,10,8,1,12,1,8,1,6, + 1,22,1,12,1,122,29,80,97,116,104,70,105,110,100,101, + 114,46,102,105,110,100,95,100,105,115,116,114,105,98,117,116, + 105,111,110,115,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,6,0,0,0,3,0,0,0,115,44,0, + 0,0,100,1,100,2,108,0,125,3,124,3,106,1,160,2, + 135,0,135,1,102,2,100,3,100,4,132,8,116,3,136,0, + 106,4,124,2,131,2,68,0,131,1,161,1,83,0,41,5, + 122,49,70,105,110,100,32,109,101,116,97,100,97,116,97,32, + 100,105,114,101,99,116,111,114,105,101,115,32,105,110,32,112, + 97,116,104,115,32,104,101,117,114,105,115,116,105,99,97,108, + 108,121,46,114,73,0,0,0,78,99,1,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,5,0,0,0,51,0, + 0,0,115,26,0,0,0,124,0,93,18,125,1,136,0,160, + 0,124,1,136,1,161,2,86,0,1,0,113,2,100,0,83, + 0,114,110,0,0,0,41,1,218,12,95,115,101,97,114,99, + 104,95,112,97,116,104,41,2,114,32,0,0,0,114,44,0, + 0,0,169,2,114,193,0,0,0,114,63,1,0,0,114,3, + 0,0,0,114,6,0,0,0,114,19,1,0,0,110,5,0, + 0,115,4,0,0,0,4,2,2,255,122,43,80,97,116,104, + 70,105,110,100,101,114,46,95,115,101,97,114,99,104,95,112, + 97,116,104,115,46,60,108,111,99,97,108,115,62,46,60,103, + 101,110,101,120,112,114,62,41,5,218,9,105,116,101,114,116, + 111,111,108,115,90,5,99,104,97,105,110,90,13,102,114,111, + 109,95,105,116,101,114,97,98,108,101,114,62,1,0,0,218, + 12,95,115,119,105,116,99,104,95,112,97,116,104,41,4,114, + 193,0,0,0,114,63,1,0,0,90,5,112,97,116,104,115, + 114,67,1,0,0,114,3,0,0,0,114,66,1,0,0,114, + 6,0,0,0,114,61,1,0,0,106,5,0,0,115,8,0, + 0,0,0,3,8,1,18,2,10,254,122,24,80,97,116,104, + 70,105,110,100,101,114,46,95,115,101,97,114,99,104,95,112, + 97,116,104,115,99,1,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,10,0,0,0,67,0,0,0,115,78,0, + 0,0,100,1,100,2,108,0,109,1,125,1,1,0,100,1, + 100,0,108,2,125,2,100,1,100,3,108,3,109,4,125,3, + 1,0,124,1,116,5,131,1,143,24,1,0,124,2,160,4, + 124,0,161,1,87,0,2,0,53,0,81,0,82,0,163,0, + 83,0,81,0,82,0,88,0,124,3,124,0,131,1,83,0, + 41,4,78,114,73,0,0,0,41,1,218,8,115,117,112,112, + 114,101,115,115,41,1,218,4,80,97,116,104,41,6,90,10, + 99,111,110,116,101,120,116,108,105,98,114,69,1,0,0,218, + 7,122,105,112,102,105,108,101,90,7,112,97,116,104,108,105, + 98,114,70,1,0,0,218,9,69,120,99,101,112,116,105,111, + 110,41,4,114,44,0,0,0,114,69,1,0,0,114,71,1, + 0,0,114,70,1,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,68,1,0,0,115,5,0,0,115, + 12,0,0,0,0,2,12,1,8,1,12,1,10,1,28,1, + 122,23,80,97,116,104,70,105,110,100,101,114,46,95,115,119, + 105,116,99,104,95,112,97,116,104,99,4,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, + 0,0,115,32,0,0,0,100,1,100,0,108,0,125,4,124, + 4,106,1,124,1,116,2,124,3,106,3,131,1,124,4,106, + 4,100,2,141,3,83,0,41,3,78,114,73,0,0,0,41, + 1,114,83,0,0,0,41,5,114,60,1,0,0,90,5,109, + 97,116,99,104,114,85,0,0,0,114,117,0,0,0,90,10, + 73,71,78,79,82,69,67,65,83,69,41,5,114,193,0,0, + 0,114,63,1,0,0,218,4,114,111,111,116,114,41,1,0, + 0,114,60,1,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,10,95,112,114,101,100,105,99,97,116, + 101,124,5,0,0,115,4,0,0,0,0,2,8,1,122,21, + 80,97,116,104,70,105,110,100,101,114,46,95,112,114,101,100, + 105,99,97,116,101,99,3,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,4,0,0,0,3,0,0,0,115,64, + 0,0,0,136,2,160,0,161,0,115,12,100,1,83,0,124, + 2,160,1,100,2,100,3,161,2,125,3,136,0,106,2,106, + 3,124,3,100,4,141,1,137,1,135,0,135,1,135,2,102, + 3,100,5,100,6,132,8,136,2,160,4,161,0,68,0,131, + 1,83,0,41,7,78,114,3,0,0,0,250,1,45,114,45, + 0,0,0,41,1,114,63,1,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,51, + 0,0,0,115,32,0,0,0,124,0,93,24,125,1,136,0, + 160,0,136,1,136,2,124,1,161,3,114,26,124,1,86,0, + 1,0,113,2,100,0,83,0,114,110,0,0,0,41,1,114, + 74,1,0,0,41,2,114,32,0,0,0,114,41,1,0,0, + 169,3,114,193,0,0,0,90,7,109,97,116,99,104,101,114, + 114,73,1,0,0,114,3,0,0,0,114,6,0,0,0,114, + 19,1,0,0,135,5,0,0,115,6,0,0,0,4,0,2, + 1,14,255,122,42,80,97,116,104,70,105,110,100,101,114,46, + 95,115,101,97,114,99,104,95,112,97,116,104,46,60,108,111, + 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,41, + 5,90,6,105,115,95,100,105,114,114,67,0,0,0,218,15, + 115,101,97,114,99,104,95,116,101,109,112,108,97,116,101,114, + 62,0,0,0,90,7,105,116,101,114,100,105,114,41,4,114, + 193,0,0,0,114,73,1,0,0,114,63,1,0,0,90,10, + 110,111,114,109,97,108,105,122,101,100,114,3,0,0,0,114, + 76,1,0,0,114,6,0,0,0,114,65,1,0,0,129,5, + 0,0,115,10,0,0,0,0,2,8,1,4,1,12,1,14, + 1,122,23,80,97,116,104,70,105,110,100,101,114,46,95,115, + 101,97,114,99,104,95,112,97,116,104,41,1,78,41,2,78, + 78,41,1,78,41,2,78,78,41,19,114,125,0,0,0,114, + 124,0,0,0,114,126,0,0,0,114,127,0,0,0,114,207, + 0,0,0,114,46,1,0,0,114,52,1,0,0,114,54,1, + 0,0,114,55,1,0,0,114,58,1,0,0,114,203,0,0, + 0,114,206,0,0,0,114,77,1,0,0,114,64,1,0,0, + 114,61,1,0,0,218,12,115,116,97,116,105,99,109,101,116, + 104,111,100,114,68,1,0,0,114,74,1,0,0,114,65,1, + 0,0,114,3,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,45,1,0,0,209,4,0,0,115, + 52,0,0,0,8,2,4,2,2,1,10,9,2,1,10,12, + 2,1,10,21,2,1,10,14,2,1,12,31,2,1,12,23, + 2,1,12,12,4,2,2,1,12,17,2,1,10,8,2,1, + 10,8,2,1,10,4,2,1,114,45,1,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,64,0,0,0,115,90,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, + 4,100,5,132,0,90,5,101,6,90,7,100,6,100,7,132, + 0,90,8,100,8,100,9,132,0,90,9,100,19,100,11,100, + 12,132,1,90,10,100,13,100,14,132,0,90,11,101,12,100, + 15,100,16,132,0,131,1,90,13,100,17,100,18,132,0,90, + 14,100,10,83,0,41,20,218,10,70,105,108,101,70,105,110, + 100,101,114,122,172,70,105,108,101,45,98,97,115,101,100,32, + 102,105,110,100,101,114,46,10,10,32,32,32,32,73,110,116, + 101,114,97,99,116,105,111,110,115,32,119,105,116,104,32,116, + 104,101,32,102,105,108,101,32,115,121,115,116,101,109,32,97, + 114,101,32,99,97,99,104,101,100,32,102,111,114,32,112,101, + 114,102,111,114,109,97,110,99,101,44,32,98,101,105,110,103, + 10,32,32,32,32,114,101,102,114,101,115,104,101,100,32,119, + 104,101,110,32,116,104,101,32,100,105,114,101,99,116,111,114, + 121,32,116,104,101,32,102,105,110,100,101,114,32,105,115,32, + 104,97,110,100,108,105,110,103,32,104,97,115,32,98,101,101, + 110,32,109,111,100,105,102,105,101,100,46,10,10,32,32,32, + 32,99,2,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,6,0,0,0,7,0,0,0,115,84,0,0,0,103, + 0,125,3,124,2,68,0,93,32,92,2,137,0,125,4,124, + 3,160,0,135,0,102,1,100,1,100,2,132,8,124,4,68, + 0,131,1,161,1,1,0,113,8,124,3,124,0,95,1,124, + 1,112,54,100,3,124,0,95,2,100,4,124,0,95,3,116, + 4,131,0,124,0,95,5,116,4,131,0,124,0,95,6,100, + 5,83,0,41,6,122,154,73,110,105,116,105,97,108,105,122, + 101,32,119,105,116,104,32,116,104,101,32,112,97,116,104,32, + 116,111,32,115,101,97,114,99,104,32,111,110,32,97,110,100, + 32,97,32,118,97,114,105,97,98,108,101,32,110,117,109,98, + 101,114,32,111,102,10,32,32,32,32,32,32,32,32,50,45, + 116,117,112,108,101,115,32,99,111,110,116,97,105,110,105,110, + 103,32,116,104,101,32,108,111,97,100,101,114,32,97,110,100, + 32,116,104,101,32,102,105,108,101,32,115,117,102,102,105,120, + 101,115,32,116,104,101,32,108,111,97,100,101,114,10,32,32, + 32,32,32,32,32,32,114,101,99,111,103,110,105,122,101,115, + 46,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,51,0,0,0,115,22,0,0,0,124, + 0,93,14,125,1,124,1,136,0,102,2,86,0,1,0,113, + 2,100,0,83,0,114,110,0,0,0,114,3,0,0,0,114, + 16,1,0,0,169,1,114,140,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,19,1,0,0,154,5,0,0,115,4, + 0,0,0,4,0,2,0,122,38,70,105,108,101,70,105,110, + 100,101,114,46,95,95,105,110,105,116,95,95,46,60,108,111, + 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,114, + 71,0,0,0,114,105,0,0,0,78,41,7,114,167,0,0, + 0,218,8,95,108,111,97,100,101,114,115,114,44,0,0,0, + 218,11,95,112,97,116,104,95,109,116,105,109,101,218,3,115, + 101,116,218,11,95,112,97,116,104,95,99,97,99,104,101,218, + 19,95,114,101,108,97,120,101,100,95,112,97,116,104,95,99, + 97,99,104,101,41,5,114,119,0,0,0,114,44,0,0,0, + 218,14,108,111,97,100,101,114,95,100,101,116,97,105,108,115, + 90,7,108,111,97,100,101,114,115,114,189,0,0,0,114,3, + 0,0,0,114,80,1,0,0,114,6,0,0,0,114,209,0, + 0,0,148,5,0,0,115,16,0,0,0,0,4,4,1,12, + 1,26,1,6,2,10,1,6,1,8,1,122,19,70,105,108, 101,70,105,110,100,101,114,46,95,95,105,110,105,116,95,95, - 46,60,108,111,99,97,108,115,62,46,60,103,101,110,101,120, - 112,114,62,114,71,0,0,0,114,105,0,0,0,78,41,7, - 114,167,0,0,0,218,8,95,108,111,97,100,101,114,115,114, - 44,0,0,0,218,11,95,112,97,116,104,95,109,116,105,109, - 101,218,3,115,101,116,218,11,95,112,97,116,104,95,99,97, - 99,104,101,218,19,95,114,101,108,97,120,101,100,95,112,97, - 116,104,95,99,97,99,104,101,41,5,114,119,0,0,0,114, - 44,0,0,0,218,14,108,111,97,100,101,114,95,100,101,116, - 97,105,108,115,90,7,108,111,97,100,101,114,115,114,189,0, - 0,0,114,3,0,0,0,114,60,1,0,0,114,6,0,0, - 0,114,209,0,0,0,96,5,0,0,115,16,0,0,0,0, - 4,4,1,12,1,26,1,6,2,10,1,6,1,8,1,122, - 19,70,105,108,101,70,105,110,100,101,114,46,95,95,105,110, - 105,116,95,95,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,2,0,0,0,67,0,0,0,115,10,0, - 0,0,100,1,124,0,95,0,100,2,83,0,41,3,122,31, - 73,110,118,97,108,105,100,97,116,101,32,116,104,101,32,100, - 105,114,101,99,116,111,114,121,32,109,116,105,109,101,46,114, - 105,0,0,0,78,41,1,114,62,1,0,0,114,246,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 114,46,1,0,0,110,5,0,0,115,2,0,0,0,0,2, - 122,28,70,105,108,101,70,105,110,100,101,114,46,105,110,118, - 97,108,105,100,97,116,101,95,99,97,99,104,101,115,99,2, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,3, - 0,0,0,67,0,0,0,115,42,0,0,0,124,0,160,0, - 124,1,161,1,125,2,124,2,100,1,107,8,114,26,100,1, - 103,0,102,2,83,0,124,2,106,1,124,2,106,2,112,38, - 103,0,102,2,83,0,41,2,122,197,84,114,121,32,116,111, - 32,102,105,110,100,32,97,32,108,111,97,100,101,114,32,102, + 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, + 0,2,0,0,0,67,0,0,0,115,10,0,0,0,100,1, + 124,0,95,0,100,2,83,0,41,3,122,31,73,110,118,97, + 108,105,100,97,116,101,32,116,104,101,32,100,105,114,101,99, + 116,111,114,121,32,109,116,105,109,101,46,114,105,0,0,0, + 78,41,1,114,82,1,0,0,114,246,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,46,1,0, + 0,162,5,0,0,115,2,0,0,0,0,2,122,28,70,105, + 108,101,70,105,110,100,101,114,46,105,110,118,97,108,105,100, + 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, + 0,0,0,115,42,0,0,0,124,0,160,0,124,1,161,1, + 125,2,124,2,100,1,107,8,114,26,100,1,103,0,102,2, + 83,0,124,2,106,1,124,2,106,2,112,38,103,0,102,2, + 83,0,41,2,122,197,84,114,121,32,116,111,32,102,105,110, + 100,32,97,32,108,111,97,100,101,114,32,102,111,114,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, + 117,108,101,44,32,111,114,32,116,104,101,32,110,97,109,101, + 115,112,97,99,101,10,32,32,32,32,32,32,32,32,112,97, + 99,107,97,103,101,32,112,111,114,116,105,111,110,115,46,32, + 82,101,116,117,114,110,115,32,40,108,111,97,100,101,114,44, + 32,108,105,115,116,45,111,102,45,112,111,114,116,105,111,110, + 115,41,46,10,10,32,32,32,32,32,32,32,32,84,104,105, + 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,46,32,32,85,115,101,32,102,105,110, + 100,95,115,112,101,99,40,41,32,105,110,115,116,101,97,100, + 46,10,10,32,32,32,32,32,32,32,32,78,41,3,114,203, + 0,0,0,114,140,0,0,0,114,178,0,0,0,41,3,114, + 119,0,0,0,114,139,0,0,0,114,187,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,137,0, + 0,0,168,5,0,0,115,8,0,0,0,0,7,10,1,8, + 1,8,1,122,22,70,105,108,101,70,105,110,100,101,114,46, + 102,105,110,100,95,108,111,97,100,101,114,99,6,0,0,0, + 0,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0, + 67,0,0,0,115,26,0,0,0,124,1,124,2,124,3,131, + 2,125,6,116,0,124,2,124,3,124,6,124,4,100,1,141, + 4,83,0,41,2,78,114,177,0,0,0,41,1,114,190,0, + 0,0,41,7,114,119,0,0,0,114,188,0,0,0,114,139, + 0,0,0,114,44,0,0,0,90,4,115,109,115,108,114,202, + 0,0,0,114,140,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,58,1,0,0,180,5,0,0, + 115,8,0,0,0,0,1,10,1,8,1,2,255,122,20,70, + 105,108,101,70,105,110,100,101,114,46,95,103,101,116,95,115, + 112,101,99,78,99,3,0,0,0,0,0,0,0,0,0,0, + 0,14,0,0,0,8,0,0,0,67,0,0,0,115,102,1, + 0,0,100,1,125,3,124,1,160,0,100,2,161,1,100,3, + 25,0,125,4,122,24,116,1,124,0,106,2,112,34,116,3, + 160,4,161,0,131,1,106,5,125,5,87,0,110,24,4,0, + 116,6,107,10,114,66,1,0,1,0,1,0,100,4,125,5, + 89,0,110,2,88,0,124,5,124,0,106,7,107,3,114,92, + 124,0,160,8,161,0,1,0,124,5,124,0,95,7,116,9, + 131,0,114,114,124,0,106,10,125,6,124,4,160,11,161,0, + 125,7,110,10,124,0,106,12,125,6,124,4,125,7,124,7, + 124,6,107,6,114,218,116,13,124,0,106,2,124,4,131,2, + 125,8,124,0,106,14,68,0,93,58,92,2,125,9,125,10, + 100,5,124,9,23,0,125,11,116,13,124,8,124,11,131,2, + 125,12,116,15,124,12,131,1,114,208,124,0,160,16,124,10, + 124,1,124,12,124,8,103,1,124,2,161,5,2,0,1,0, + 83,0,113,150,116,17,124,8,131,1,125,3,124,0,106,14, + 68,0,93,86,92,2,125,9,125,10,116,13,124,0,106,2, + 124,4,124,9,23,0,131,2,125,12,116,18,106,19,100,6, + 124,12,100,3,100,7,141,3,1,0,124,7,124,9,23,0, + 124,6,107,6,144,1,114,54,116,15,124,12,131,1,144,1, + 114,54,124,0,160,16,124,10,124,1,124,12,100,8,124,2, + 161,5,2,0,1,0,83,0,113,224,124,3,144,1,114,98, + 116,18,160,19,100,9,124,8,161,2,1,0,116,18,160,20, + 124,1,100,8,161,2,125,13,124,8,103,1,124,13,95,21, + 124,13,83,0,100,8,83,0,41,10,122,111,84,114,121,32, + 116,111,32,102,105,110,100,32,97,32,115,112,101,99,32,102, 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,44,32,111,114,32,116,104,101,32, - 110,97,109,101,115,112,97,99,101,10,32,32,32,32,32,32, - 32,32,112,97,99,107,97,103,101,32,112,111,114,116,105,111, - 110,115,46,32,82,101,116,117,114,110,115,32,40,108,111,97, - 100,101,114,44,32,108,105,115,116,45,111,102,45,112,111,114, - 116,105,111,110,115,41,46,10,10,32,32,32,32,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, - 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, - 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, - 41,3,114,203,0,0,0,114,140,0,0,0,114,178,0,0, - 0,41,3,114,119,0,0,0,114,139,0,0,0,114,187,0, + 32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32, + 32,32,82,101,116,117,114,110,115,32,116,104,101,32,109,97, + 116,99,104,105,110,103,32,115,112,101,99,44,32,111,114,32, + 78,111,110,101,32,105,102,32,110,111,116,32,102,111,117,110, + 100,46,10,32,32,32,32,32,32,32,32,70,114,71,0,0, + 0,114,28,0,0,0,114,105,0,0,0,114,209,0,0,0, + 122,9,116,114,121,105,110,103,32,123,125,41,1,90,9,118, + 101,114,98,111,115,105,116,121,78,122,25,112,111,115,115,105, + 98,108,101,32,110,97,109,101,115,112,97,99,101,32,102,111, + 114,32,123,125,41,22,114,41,0,0,0,114,49,0,0,0, + 114,44,0,0,0,114,2,0,0,0,114,55,0,0,0,114, + 10,1,0,0,114,50,0,0,0,114,82,1,0,0,218,11, + 95,102,105,108,108,95,99,97,99,104,101,114,7,0,0,0, + 114,85,1,0,0,114,106,0,0,0,114,84,1,0,0,114, + 38,0,0,0,114,81,1,0,0,114,54,0,0,0,114,58, + 1,0,0,114,56,0,0,0,114,134,0,0,0,114,149,0, + 0,0,114,183,0,0,0,114,178,0,0,0,41,14,114,119, + 0,0,0,114,139,0,0,0,114,202,0,0,0,90,12,105, + 115,95,110,97,109,101,115,112,97,99,101,90,11,116,97,105, + 108,95,109,111,100,117,108,101,114,169,0,0,0,90,5,99, + 97,99,104,101,90,12,99,97,99,104,101,95,109,111,100,117, + 108,101,90,9,98,97,115,101,95,112,97,116,104,114,17,1, + 0,0,114,188,0,0,0,90,13,105,110,105,116,95,102,105, + 108,101,110,97,109,101,90,9,102,117,108,108,95,112,97,116, + 104,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,114,203,0,0,0,185,5,0,0,115,74, + 0,0,0,0,5,4,1,14,1,2,1,24,1,14,1,10, + 1,10,1,8,1,6,2,6,1,6,1,10,2,6,1,4, + 2,8,1,12,1,14,1,8,1,10,1,8,1,26,4,8, + 2,14,1,16,1,16,1,14,1,10,1,10,1,2,0,2, + 255,10,2,6,1,12,1,12,1,8,1,4,1,122,20,70, + 105,108,101,70,105,110,100,101,114,46,102,105,110,100,95,115, + 112,101,99,99,1,0,0,0,0,0,0,0,0,0,0,0, + 9,0,0,0,10,0,0,0,67,0,0,0,115,190,0,0, + 0,124,0,106,0,125,1,122,22,116,1,160,2,124,1,112, + 22,116,1,160,3,161,0,161,1,125,2,87,0,110,30,4, + 0,116,4,116,5,116,6,102,3,107,10,114,58,1,0,1, + 0,1,0,103,0,125,2,89,0,110,2,88,0,116,7,106, + 8,160,9,100,1,161,1,115,84,116,10,124,2,131,1,124, + 0,95,11,110,74,116,10,131,0,125,3,124,2,68,0,93, + 56,125,4,124,4,160,12,100,2,161,1,92,3,125,5,125, + 6,125,7,124,6,114,136,100,3,160,13,124,5,124,7,160, + 14,161,0,161,2,125,8,110,4,124,5,125,8,124,3,160, + 15,124,8,161,1,1,0,113,94,124,3,124,0,95,11,116, + 7,106,8,160,9,116,16,161,1,114,186,100,4,100,5,132, + 0,124,2,68,0,131,1,124,0,95,17,100,6,83,0,41, + 7,122,68,70,105,108,108,32,116,104,101,32,99,97,99,104, + 101,32,111,102,32,112,111,116,101,110,116,105,97,108,32,109, + 111,100,117,108,101,115,32,97,110,100,32,112,97,99,107,97, + 103,101,115,32,102,111,114,32,116,104,105,115,32,100,105,114, + 101,99,116,111,114,121,46,114,0,0,0,0,114,71,0,0, + 0,114,61,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,83,0,0,0,115, + 20,0,0,0,104,0,124,0,93,12,125,1,124,1,160,0, + 161,0,146,2,113,4,83,0,114,3,0,0,0,41,1,114, + 106,0,0,0,41,2,114,32,0,0,0,90,2,102,110,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,9, + 60,115,101,116,99,111,109,112,62,6,6,0,0,115,4,0, + 0,0,6,0,2,0,122,41,70,105,108,101,70,105,110,100, + 101,114,46,95,102,105,108,108,95,99,97,99,104,101,46,60, + 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, + 62,78,41,18,114,44,0,0,0,114,2,0,0,0,114,7, + 1,0,0,114,55,0,0,0,114,3,1,0,0,218,15,80, + 101,114,109,105,115,115,105,111,110,69,114,114,111,114,218,18, + 78,111,116,65,68,105,114,101,99,116,111,114,121,69,114,114, + 111,114,114,8,0,0,0,114,9,0,0,0,114,10,0,0, + 0,114,83,1,0,0,114,84,1,0,0,114,101,0,0,0, + 114,62,0,0,0,114,106,0,0,0,218,3,97,100,100,114, + 11,0,0,0,114,85,1,0,0,41,9,114,119,0,0,0, + 114,44,0,0,0,114,8,1,0,0,90,21,108,111,119,101, + 114,95,115,117,102,102,105,120,95,99,111,110,116,101,110,116, + 115,114,41,1,0,0,114,117,0,0,0,114,29,1,0,0, + 114,17,1,0,0,90,8,110,101,119,95,110,97,109,101,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,87, + 1,0,0,233,5,0,0,115,34,0,0,0,0,2,6,1, + 2,1,22,1,20,3,10,3,12,1,12,7,6,1,8,1, + 16,1,4,1,18,2,4,1,12,1,6,1,12,1,122,22, + 70,105,108,101,70,105,110,100,101,114,46,95,102,105,108,108, + 95,99,97,99,104,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,3,0,0,0,7,0,0,0,115, + 18,0,0,0,135,0,135,1,102,2,100,1,100,2,132,8, + 125,2,124,2,83,0,41,3,97,20,1,0,0,65,32,99, + 108,97,115,115,32,109,101,116,104,111,100,32,119,104,105,99, + 104,32,114,101,116,117,114,110,115,32,97,32,99,108,111,115, + 117,114,101,32,116,111,32,117,115,101,32,111,110,32,115,121, + 115,46,112,97,116,104,95,104,111,111,107,10,32,32,32,32, + 32,32,32,32,119,104,105,99,104,32,119,105,108,108,32,114, + 101,116,117,114,110,32,97,110,32,105,110,115,116,97,110,99, + 101,32,117,115,105,110,103,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,108,111,97,100,101,114,115,32,97,110, + 100,32,116,104,101,32,112,97,116,104,10,32,32,32,32,32, + 32,32,32,99,97,108,108,101,100,32,111,110,32,116,104,101, + 32,99,108,111,115,117,114,101,46,10,10,32,32,32,32,32, + 32,32,32,73,102,32,116,104,101,32,112,97,116,104,32,99, + 97,108,108,101,100,32,111,110,32,116,104,101,32,99,108,111, + 115,117,114,101,32,105,115,32,110,111,116,32,97,32,100,105, + 114,101,99,116,111,114,121,44,32,73,109,112,111,114,116,69, + 114,114,111,114,32,105,115,10,32,32,32,32,32,32,32,32, + 114,97,105,115,101,100,46,10,10,32,32,32,32,32,32,32, + 32,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,4,0,0,0,19,0,0,0,115,34,0,0,0,116, + 0,124,0,131,1,115,20,116,1,100,1,124,0,100,2,141, + 2,130,1,136,0,124,0,102,1,136,1,158,2,142,0,83, + 0,41,3,122,45,80,97,116,104,32,104,111,111,107,32,102, + 111,114,32,105,109,112,111,114,116,108,105,98,46,109,97,99, + 104,105,110,101,114,121,46,70,105,108,101,70,105,110,100,101, + 114,46,122,30,111,110,108,121,32,100,105,114,101,99,116,111, + 114,105,101,115,32,97,114,101,32,115,117,112,112,111,114,116, + 101,100,114,48,0,0,0,41,2,114,56,0,0,0,114,118, + 0,0,0,114,48,0,0,0,169,2,114,193,0,0,0,114, + 86,1,0,0,114,3,0,0,0,114,6,0,0,0,218,24, + 112,97,116,104,95,104,111,111,107,95,102,111,114,95,70,105, + 108,101,70,105,110,100,101,114,18,6,0,0,115,6,0,0, + 0,0,2,8,1,12,1,122,54,70,105,108,101,70,105,110, + 100,101,114,46,112,97,116,104,95,104,111,111,107,46,60,108, + 111,99,97,108,115,62,46,112,97,116,104,95,104,111,111,107, + 95,102,111,114,95,70,105,108,101,70,105,110,100,101,114,114, + 3,0,0,0,41,3,114,193,0,0,0,114,86,1,0,0, + 114,93,1,0,0,114,3,0,0,0,114,92,1,0,0,114, + 6,0,0,0,218,9,112,97,116,104,95,104,111,111,107,8, + 6,0,0,115,4,0,0,0,0,10,14,6,122,20,70,105, + 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, + 111,107,99,1,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,12,0,0,0, + 100,1,160,0,124,0,106,1,161,1,83,0,41,2,78,122, + 16,70,105,108,101,70,105,110,100,101,114,40,123,33,114,125, + 41,41,2,114,62,0,0,0,114,44,0,0,0,114,246,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,137,0,0,0,116,5,0,0,115,8,0,0,0,0, - 7,10,1,8,1,8,1,122,22,70,105,108,101,70,105,110, - 100,101,114,46,102,105,110,100,95,108,111,97,100,101,114,99, - 6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0, - 6,0,0,0,67,0,0,0,115,26,0,0,0,124,1,124, - 2,124,3,131,2,125,6,116,0,124,2,124,3,124,6,124, - 4,100,1,141,4,83,0,41,2,78,114,177,0,0,0,41, - 1,114,190,0,0,0,41,7,114,119,0,0,0,114,188,0, - 0,0,114,139,0,0,0,114,44,0,0,0,90,4,115,109, - 115,108,114,202,0,0,0,114,140,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,58,1,0,0, - 128,5,0,0,115,8,0,0,0,0,1,10,1,8,1,2, - 255,122,20,70,105,108,101,70,105,110,100,101,114,46,95,103, - 101,116,95,115,112,101,99,78,99,3,0,0,0,0,0,0, - 0,0,0,0,0,14,0,0,0,8,0,0,0,67,0,0, - 0,115,102,1,0,0,100,1,125,3,124,1,160,0,100,2, - 161,1,100,3,25,0,125,4,122,24,116,1,124,0,106,2, - 112,34,116,3,160,4,161,0,131,1,106,5,125,5,87,0, - 110,24,4,0,116,6,107,10,114,66,1,0,1,0,1,0, - 100,4,125,5,89,0,110,2,88,0,124,5,124,0,106,7, - 107,3,114,92,124,0,160,8,161,0,1,0,124,5,124,0, - 95,7,116,9,131,0,114,114,124,0,106,10,125,6,124,4, - 160,11,161,0,125,7,110,10,124,0,106,12,125,6,124,4, - 125,7,124,7,124,6,107,6,114,218,116,13,124,0,106,2, - 124,4,131,2,125,8,124,0,106,14,68,0,93,58,92,2, - 125,9,125,10,100,5,124,9,23,0,125,11,116,13,124,8, - 124,11,131,2,125,12,116,15,124,12,131,1,114,208,124,0, - 160,16,124,10,124,1,124,12,124,8,103,1,124,2,161,5, - 2,0,1,0,83,0,113,150,116,17,124,8,131,1,125,3, - 124,0,106,14,68,0,93,86,92,2,125,9,125,10,116,13, - 124,0,106,2,124,4,124,9,23,0,131,2,125,12,116,18, - 106,19,100,6,124,12,100,3,100,7,141,3,1,0,124,7, - 124,9,23,0,124,6,107,6,144,1,114,54,116,15,124,12, - 131,1,144,1,114,54,124,0,160,16,124,10,124,1,124,12, - 100,8,124,2,161,5,2,0,1,0,83,0,113,224,124,3, - 144,1,114,98,116,18,160,19,100,9,124,8,161,2,1,0, - 116,18,160,20,124,1,100,8,161,2,125,13,124,8,103,1, - 124,13,95,21,124,13,83,0,100,8,83,0,41,10,122,111, - 84,114,121,32,116,111,32,102,105,110,100,32,97,32,115,112, - 101,99,32,102,111,114,32,116,104,101,32,115,112,101,99,105, - 102,105,101,100,32,109,111,100,117,108,101,46,10,10,32,32, - 32,32,32,32,32,32,82,101,116,117,114,110,115,32,116,104, - 101,32,109,97,116,99,104,105,110,103,32,115,112,101,99,44, - 32,111,114,32,78,111,110,101,32,105,102,32,110,111,116,32, - 102,111,117,110,100,46,10,32,32,32,32,32,32,32,32,70, - 114,71,0,0,0,114,28,0,0,0,114,105,0,0,0,114, - 209,0,0,0,122,9,116,114,121,105,110,103,32,123,125,41, - 1,90,9,118,101,114,98,111,115,105,116,121,78,122,25,112, - 111,115,115,105,98,108,101,32,110,97,109,101,115,112,97,99, - 101,32,102,111,114,32,123,125,41,22,114,41,0,0,0,114, - 49,0,0,0,114,44,0,0,0,114,2,0,0,0,114,55, - 0,0,0,114,10,1,0,0,114,50,0,0,0,114,62,1, - 0,0,218,11,95,102,105,108,108,95,99,97,99,104,101,114, - 7,0,0,0,114,65,1,0,0,114,106,0,0,0,114,64, - 1,0,0,114,38,0,0,0,114,61,1,0,0,114,54,0, - 0,0,114,58,1,0,0,114,56,0,0,0,114,134,0,0, - 0,114,149,0,0,0,114,183,0,0,0,114,178,0,0,0, - 41,14,114,119,0,0,0,114,139,0,0,0,114,202,0,0, - 0,90,12,105,115,95,110,97,109,101,115,112,97,99,101,90, - 11,116,97,105,108,95,109,111,100,117,108,101,114,169,0,0, - 0,90,5,99,97,99,104,101,90,12,99,97,99,104,101,95, - 109,111,100,117,108,101,90,9,98,97,115,101,95,112,97,116, - 104,114,17,1,0,0,114,188,0,0,0,90,13,105,110,105, - 116,95,102,105,108,101,110,97,109,101,90,9,102,117,108,108, - 95,112,97,116,104,114,187,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,203,0,0,0,133,5, - 0,0,115,74,0,0,0,0,5,4,1,14,1,2,1,24, - 1,14,1,10,1,10,1,8,1,6,2,6,1,6,1,10, - 2,6,1,4,2,8,1,12,1,14,1,8,1,10,1,8, - 1,26,4,8,2,14,1,16,1,16,1,14,1,10,1,10, - 1,2,0,2,255,10,2,6,1,12,1,12,1,8,1,4, - 1,122,20,70,105,108,101,70,105,110,100,101,114,46,102,105, - 110,100,95,115,112,101,99,99,1,0,0,0,0,0,0,0, - 0,0,0,0,9,0,0,0,10,0,0,0,67,0,0,0, - 115,190,0,0,0,124,0,106,0,125,1,122,22,116,1,160, - 2,124,1,112,22,116,1,160,3,161,0,161,1,125,2,87, - 0,110,30,4,0,116,4,116,5,116,6,102,3,107,10,114, - 58,1,0,1,0,1,0,103,0,125,2,89,0,110,2,88, - 0,116,7,106,8,160,9,100,1,161,1,115,84,116,10,124, - 2,131,1,124,0,95,11,110,74,116,10,131,0,125,3,124, - 2,68,0,93,56,125,4,124,4,160,12,100,2,161,1,92, - 3,125,5,125,6,125,7,124,6,114,136,100,3,160,13,124, - 5,124,7,160,14,161,0,161,2,125,8,110,4,124,5,125, - 8,124,3,160,15,124,8,161,1,1,0,113,94,124,3,124, - 0,95,11,116,7,106,8,160,9,116,16,161,1,114,186,100, - 4,100,5,132,0,124,2,68,0,131,1,124,0,95,17,100, - 6,83,0,41,7,122,68,70,105,108,108,32,116,104,101,32, - 99,97,99,104,101,32,111,102,32,112,111,116,101,110,116,105, - 97,108,32,109,111,100,117,108,101,115,32,97,110,100,32,112, - 97,99,107,97,103,101,115,32,102,111,114,32,116,104,105,115, - 32,100,105,114,101,99,116,111,114,121,46,114,0,0,0,0, - 114,71,0,0,0,114,61,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,83, - 0,0,0,115,20,0,0,0,104,0,124,0,93,12,125,1, - 124,1,160,0,161,0,146,2,113,4,83,0,114,3,0,0, - 0,41,1,114,106,0,0,0,41,2,114,32,0,0,0,90, - 2,102,110,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,9,60,115,101,116,99,111,109,112,62,210,5,0, - 0,115,4,0,0,0,6,0,2,0,122,41,70,105,108,101, - 70,105,110,100,101,114,46,95,102,105,108,108,95,99,97,99, - 104,101,46,60,108,111,99,97,108,115,62,46,60,115,101,116, - 99,111,109,112,62,78,41,18,114,44,0,0,0,114,2,0, - 0,0,114,7,1,0,0,114,55,0,0,0,114,3,1,0, - 0,218,15,80,101,114,109,105,115,115,105,111,110,69,114,114, - 111,114,218,18,78,111,116,65,68,105,114,101,99,116,111,114, - 121,69,114,114,111,114,114,8,0,0,0,114,9,0,0,0, - 114,10,0,0,0,114,63,1,0,0,114,64,1,0,0,114, - 101,0,0,0,114,62,0,0,0,114,106,0,0,0,218,3, - 97,100,100,114,11,0,0,0,114,65,1,0,0,41,9,114, - 119,0,0,0,114,44,0,0,0,114,8,1,0,0,90,21, - 108,111,119,101,114,95,115,117,102,102,105,120,95,99,111,110, - 116,101,110,116,115,114,41,1,0,0,114,117,0,0,0,114, - 29,1,0,0,114,17,1,0,0,90,8,110,101,119,95,110, - 97,109,101,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,67,1,0,0,181,5,0,0,115,34,0,0,0, - 0,2,6,1,2,1,22,1,20,3,10,3,12,1,12,7, - 6,1,8,1,16,1,4,1,18,2,4,1,12,1,6,1, - 12,1,122,22,70,105,108,101,70,105,110,100,101,114,46,95, - 102,105,108,108,95,99,97,99,104,101,99,1,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,7, - 0,0,0,115,18,0,0,0,135,0,135,1,102,2,100,1, - 100,2,132,8,125,2,124,2,83,0,41,3,97,20,1,0, - 0,65,32,99,108,97,115,115,32,109,101,116,104,111,100,32, - 119,104,105,99,104,32,114,101,116,117,114,110,115,32,97,32, - 99,108,111,115,117,114,101,32,116,111,32,117,115,101,32,111, - 110,32,115,121,115,46,112,97,116,104,95,104,111,111,107,10, - 32,32,32,32,32,32,32,32,119,104,105,99,104,32,119,105, - 108,108,32,114,101,116,117,114,110,32,97,110,32,105,110,115, - 116,97,110,99,101,32,117,115,105,110,103,32,116,104,101,32, - 115,112,101,99,105,102,105,101,100,32,108,111,97,100,101,114, - 115,32,97,110,100,32,116,104,101,32,112,97,116,104,10,32, - 32,32,32,32,32,32,32,99,97,108,108,101,100,32,111,110, - 32,116,104,101,32,99,108,111,115,117,114,101,46,10,10,32, - 32,32,32,32,32,32,32,73,102,32,116,104,101,32,112,97, - 116,104,32,99,97,108,108,101,100,32,111,110,32,116,104,101, - 32,99,108,111,115,117,114,101,32,105,115,32,110,111,116,32, - 97,32,100,105,114,101,99,116,111,114,121,44,32,73,109,112, - 111,114,116,69,114,114,111,114,32,105,115,10,32,32,32,32, - 32,32,32,32,114,97,105,115,101,100,46,10,10,32,32,32, - 32,32,32,32,32,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,4,0,0,0,19,0,0,0,115,34, - 0,0,0,116,0,124,0,131,1,115,20,116,1,100,1,124, - 0,100,2,141,2,130,1,136,0,124,0,102,1,136,1,158, - 2,142,0,83,0,41,3,122,45,80,97,116,104,32,104,111, - 111,107,32,102,111,114,32,105,109,112,111,114,116,108,105,98, - 46,109,97,99,104,105,110,101,114,121,46,70,105,108,101,70, - 105,110,100,101,114,46,122,30,111,110,108,121,32,100,105,114, - 101,99,116,111,114,105,101,115,32,97,114,101,32,115,117,112, - 112,111,114,116,101,100,114,48,0,0,0,41,2,114,56,0, - 0,0,114,118,0,0,0,114,48,0,0,0,169,2,114,193, - 0,0,0,114,66,1,0,0,114,3,0,0,0,114,6,0, - 0,0,218,24,112,97,116,104,95,104,111,111,107,95,102,111, - 114,95,70,105,108,101,70,105,110,100,101,114,222,5,0,0, - 115,6,0,0,0,0,2,8,1,12,1,122,54,70,105,108, - 101,70,105,110,100,101,114,46,112,97,116,104,95,104,111,111, - 107,46,60,108,111,99,97,108,115,62,46,112,97,116,104,95, - 104,111,111,107,95,102,111,114,95,70,105,108,101,70,105,110, - 100,101,114,114,3,0,0,0,41,3,114,193,0,0,0,114, - 66,1,0,0,114,73,1,0,0,114,3,0,0,0,114,72, - 1,0,0,114,6,0,0,0,218,9,112,97,116,104,95,104, - 111,111,107,212,5,0,0,115,4,0,0,0,0,10,14,6, - 122,20,70,105,108,101,70,105,110,100,101,114,46,112,97,116, - 104,95,104,111,111,107,99,1,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, - 12,0,0,0,100,1,160,0,124,0,106,1,161,1,83,0, - 41,2,78,122,16,70,105,108,101,70,105,110,100,101,114,40, - 123,33,114,125,41,41,2,114,62,0,0,0,114,44,0,0, - 0,114,246,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,39,1,0,0,230,5,0,0,115,2, - 0,0,0,0,1,122,19,70,105,108,101,70,105,110,100,101, - 114,46,95,95,114,101,112,114,95,95,41,1,78,41,15,114, - 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, - 0,0,0,114,209,0,0,0,114,46,1,0,0,114,143,0, - 0,0,114,206,0,0,0,114,137,0,0,0,114,58,1,0, - 0,114,203,0,0,0,114,67,1,0,0,114,207,0,0,0, - 114,74,1,0,0,114,39,1,0,0,114,3,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,59, - 1,0,0,87,5,0,0,115,22,0,0,0,8,2,4,7, - 8,14,8,4,4,2,8,12,8,5,10,48,8,31,2,1, - 10,17,114,59,1,0,0,99,4,0,0,0,0,0,0,0, - 0,0,0,0,6,0,0,0,8,0,0,0,67,0,0,0, - 115,146,0,0,0,124,0,160,0,100,1,161,1,125,4,124, - 0,160,0,100,2,161,1,125,5,124,4,115,66,124,5,114, - 36,124,5,106,1,125,4,110,30,124,2,124,3,107,2,114, - 56,116,2,124,1,124,2,131,2,125,4,110,10,116,3,124, - 1,124,2,131,2,125,4,124,5,115,84,116,4,124,1,124, - 2,124,4,100,3,141,3,125,5,122,36,124,5,124,0,100, - 2,60,0,124,4,124,0,100,1,60,0,124,2,124,0,100, - 4,60,0,124,3,124,0,100,5,60,0,87,0,110,20,4, - 0,116,5,107,10,114,140,1,0,1,0,1,0,89,0,110, - 2,88,0,100,0,83,0,41,6,78,218,10,95,95,108,111, - 97,100,101,114,95,95,218,8,95,95,115,112,101,99,95,95, - 114,60,1,0,0,90,8,95,95,102,105,108,101,95,95,90, - 10,95,95,99,97,99,104,101,100,95,95,41,6,218,3,103, - 101,116,114,140,0,0,0,114,15,1,0,0,114,9,1,0, - 0,114,190,0,0,0,218,9,69,120,99,101,112,116,105,111, - 110,41,6,90,2,110,115,114,117,0,0,0,90,8,112,97, - 116,104,110,97,109,101,90,9,99,112,97,116,104,110,97,109, - 101,114,140,0,0,0,114,187,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,14,95,102,105,120, - 95,117,112,95,109,111,100,117,108,101,236,5,0,0,115,34, - 0,0,0,0,2,10,1,10,1,4,1,4,1,8,1,8, - 1,12,2,10,1,4,1,14,1,2,1,8,1,8,1,8, - 1,12,1,14,2,114,79,1,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,116,0,116,1,160,2,161,0, - 102,2,125,0,116,3,116,4,102,2,125,1,116,5,116,6, - 102,2,125,2,124,0,124,1,124,2,103,3,83,0,41,1, - 122,95,82,101,116,117,114,110,115,32,97,32,108,105,115,116, - 32,111,102,32,102,105,108,101,45,98,97,115,101,100,32,109, - 111,100,117,108,101,32,108,111,97,100,101,114,115,46,10,10, - 32,32,32,32,69,97,99,104,32,105,116,101,109,32,105,115, - 32,97,32,116,117,112,108,101,32,40,108,111,97,100,101,114, - 44,32,115,117,102,102,105,120,101,115,41,46,10,32,32,32, - 32,41,7,114,252,0,0,0,114,163,0,0,0,218,18,101, - 120,116,101,110,115,105,111,110,95,115,117,102,102,105,120,101, - 115,114,9,1,0,0,114,102,0,0,0,114,15,1,0,0, - 114,89,0,0,0,41,3,90,10,101,120,116,101,110,115,105, - 111,110,115,90,6,115,111,117,114,99,101,90,8,98,121,116, - 101,99,111,100,101,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,184,0,0,0,3,6,0,0,115,8,0, - 0,0,0,5,12,1,8,1,8,1,114,184,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0, - 9,0,0,0,67,0,0,0,115,178,1,0,0,124,0,97, - 0,116,0,106,1,97,1,116,0,106,2,97,2,116,1,106, - 3,116,4,25,0,125,1,100,1,68,0,93,48,125,2,124, - 2,116,1,106,3,107,7,114,56,116,0,160,5,124,2,161, - 1,125,3,110,10,116,1,106,3,124,2,25,0,125,3,116, - 6,124,1,124,2,124,3,131,3,1,0,113,30,100,2,100, - 3,103,1,102,2,100,4,100,5,100,3,103,2,102,2,102, - 2,125,4,124,4,68,0,93,110,92,2,125,5,125,6,116, - 7,100,6,100,7,132,0,124,6,68,0,131,1,131,1,115, - 136,116,8,130,1,124,6,100,8,25,0,125,7,124,5,116, - 1,106,3,107,6,114,170,116,1,106,3,124,5,25,0,125, - 8,1,0,113,226,113,106,122,20,116,0,160,5,124,5,161, - 1,125,8,87,0,1,0,113,226,87,0,113,106,4,0,116, - 9,107,10,114,214,1,0,1,0,1,0,89,0,113,106,89, - 0,113,106,88,0,113,106,116,9,100,9,131,1,130,1,116, - 6,124,1,100,10,124,8,131,3,1,0,116,6,124,1,100, - 11,124,7,131,3,1,0,116,6,124,1,100,12,100,13,160, - 10,124,6,161,1,131,3,1,0,116,6,124,1,100,14,100, - 15,100,16,132,0,124,6,68,0,131,1,131,3,1,0,116, - 0,160,5,100,17,161,1,125,9,116,6,124,1,100,17,124, - 9,131,3,1,0,116,0,160,5,100,18,161,1,125,10,116, - 6,124,1,100,18,124,10,131,3,1,0,124,5,100,4,107, - 2,144,1,114,110,116,0,160,5,100,19,161,1,125,11,116, - 6,124,1,100,20,124,11,131,3,1,0,116,6,124,1,100, - 21,116,11,131,0,131,3,1,0,116,12,160,13,116,2,160, - 14,161,0,161,1,1,0,124,5,100,4,107,2,144,1,114, - 174,116,15,160,16,100,22,161,1,1,0,100,23,116,12,107, - 6,144,1,114,174,100,24,116,17,95,18,100,25,83,0,41, - 26,122,205,83,101,116,117,112,32,116,104,101,32,112,97,116, - 104,45,98,97,115,101,100,32,105,109,112,111,114,116,101,114, - 115,32,102,111,114,32,105,109,112,111,114,116,108,105,98,32, - 98,121,32,105,109,112,111,114,116,105,110,103,32,110,101,101, - 100,101,100,10,32,32,32,32,98,117,105,108,116,45,105,110, - 32,109,111,100,117,108,101,115,32,97,110,100,32,105,110,106, - 101,99,116,105,110,103,32,116,104,101,109,32,105,110,116,111, - 32,116,104,101,32,103,108,111,98,97,108,32,110,97,109,101, - 115,112,97,99,101,46,10,10,32,32,32,32,79,116,104,101, - 114,32,99,111,109,112,111,110,101,110,116,115,32,97,114,101, - 32,101,120,116,114,97,99,116,101,100,32,102,114,111,109,32, - 116,104,101,32,99,111,114,101,32,98,111,111,116,115,116,114, - 97,112,32,109,111,100,117,108,101,46,10,10,32,32,32,32, - 41,4,114,64,0,0,0,114,75,0,0,0,218,8,98,117, - 105,108,116,105,110,115,114,160,0,0,0,90,5,112,111,115, - 105,120,250,1,47,90,2,110,116,250,1,92,99,1,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0, - 0,115,0,0,0,115,26,0,0,0,124,0,93,18,125,1, - 116,0,124,1,131,1,100,0,107,2,86,0,1,0,113,2, - 100,1,83,0,41,2,114,39,0,0,0,78,41,1,114,22, - 0,0,0,41,2,114,32,0,0,0,114,95,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,19, - 1,0,0,39,6,0,0,115,4,0,0,0,4,0,2,0, - 122,25,95,115,101,116,117,112,46,60,108,111,99,97,108,115, - 62,46,60,103,101,110,101,120,112,114,62,114,73,0,0,0, - 122,30,105,109,112,111,114,116,108,105,98,32,114,101,113,117, - 105,114,101,115,32,112,111,115,105,120,32,111,114,32,110,116, - 114,2,0,0,0,114,35,0,0,0,114,31,0,0,0,114, - 40,0,0,0,114,58,0,0,0,99,1,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,4,0,0,0,83,0, - 0,0,115,22,0,0,0,104,0,124,0,93,14,125,1,100, - 0,124,1,155,0,157,2,146,2,113,4,83,0,41,1,114, - 74,0,0,0,114,3,0,0,0,41,2,114,32,0,0,0, - 218,1,115,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,114,68,1,0,0,55,6,0,0,115,4,0,0,0, - 6,0,2,0,122,25,95,115,101,116,117,112,46,60,108,111, - 99,97,108,115,62,46,60,115,101,116,99,111,109,112,62,90, - 7,95,116,104,114,101,97,100,90,8,95,119,101,97,107,114, - 101,102,90,6,119,105,110,114,101,103,114,192,0,0,0,114, - 7,0,0,0,122,4,46,112,121,119,122,6,95,100,46,112, - 121,100,84,78,41,19,114,134,0,0,0,114,8,0,0,0, - 114,163,0,0,0,114,31,1,0,0,114,125,0,0,0,90, - 18,95,98,117,105,108,116,105,110,95,102,114,111,109,95,110, - 97,109,101,114,129,0,0,0,218,3,97,108,108,114,23,0, - 0,0,114,118,0,0,0,114,36,0,0,0,114,13,0,0, - 0,114,21,1,0,0,114,167,0,0,0,114,80,1,0,0, - 114,102,0,0,0,114,186,0,0,0,114,191,0,0,0,114, - 195,0,0,0,41,12,218,17,95,98,111,111,116,115,116,114, - 97,112,95,109,111,100,117,108,101,90,11,115,101,108,102,95, - 109,111,100,117,108,101,90,12,98,117,105,108,116,105,110,95, - 110,97,109,101,90,14,98,117,105,108,116,105,110,95,109,111, - 100,117,108,101,90,10,111,115,95,100,101,116,97,105,108,115, - 90,10,98,117,105,108,116,105,110,95,111,115,114,31,0,0, - 0,114,35,0,0,0,90,9,111,115,95,109,111,100,117,108, - 101,90,13,116,104,114,101,97,100,95,109,111,100,117,108,101, - 90,14,119,101,97,107,114,101,102,95,109,111,100,117,108,101, - 90,13,119,105,110,114,101,103,95,109,111,100,117,108,101,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,6, - 95,115,101,116,117,112,14,6,0,0,115,78,0,0,0,0, - 8,4,1,6,1,6,3,10,1,8,1,10,1,12,2,10, - 1,14,3,22,1,12,2,22,1,8,1,10,1,10,1,6, - 2,2,1,10,1,10,1,14,1,12,2,8,1,12,1,12, - 1,18,1,22,3,10,1,12,3,10,1,12,3,10,1,10, - 1,12,3,14,1,14,1,10,1,10,1,10,1,114,87,1, - 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,4,0,0,0,67,0,0,0,115,50,0,0,0, - 116,0,124,0,131,1,1,0,116,1,131,0,125,1,116,2, - 106,3,160,4,116,5,106,6,124,1,142,0,103,1,161,1, - 1,0,116,2,106,7,160,8,116,9,161,1,1,0,100,1, - 83,0,41,2,122,41,73,110,115,116,97,108,108,32,116,104, - 101,32,112,97,116,104,45,98,97,115,101,100,32,105,109,112, - 111,114,116,32,99,111,109,112,111,110,101,110,116,115,46,78, - 41,10,114,87,1,0,0,114,184,0,0,0,114,8,0,0, - 0,114,51,1,0,0,114,167,0,0,0,114,59,1,0,0, - 114,74,1,0,0,218,9,109,101,116,97,95,112,97,116,104, - 114,186,0,0,0,114,45,1,0,0,41,2,114,86,1,0, - 0,90,17,115,117,112,112,111,114,116,101,100,95,108,111,97, - 100,101,114,115,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,8,95,105,110,115,116,97,108,108,79,6,0, - 0,115,8,0,0,0,0,2,8,1,6,1,20,1,114,89, - 1,0,0,41,63,114,127,0,0,0,114,12,0,0,0,90, - 37,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, - 86,69,95,80,76,65,84,70,79,82,77,83,95,66,89,84, - 69,83,95,75,69,89,114,11,0,0,0,114,13,0,0,0, - 114,20,0,0,0,114,27,0,0,0,114,29,0,0,0,114, - 38,0,0,0,114,47,0,0,0,114,49,0,0,0,114,53, - 0,0,0,114,54,0,0,0,114,56,0,0,0,114,59,0, - 0,0,114,69,0,0,0,218,4,116,121,112,101,218,8,95, - 95,99,111,100,101,95,95,114,162,0,0,0,114,18,0,0, - 0,114,148,0,0,0,114,17,0,0,0,114,24,0,0,0, - 114,236,0,0,0,114,92,0,0,0,114,88,0,0,0,114, - 102,0,0,0,114,89,0,0,0,90,23,68,69,66,85,71, - 95,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88, - 69,83,90,27,79,80,84,73,77,73,90,69,68,95,66,89, - 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,114, - 98,0,0,0,114,103,0,0,0,114,109,0,0,0,114,113, - 0,0,0,114,115,0,0,0,114,136,0,0,0,114,143,0, - 0,0,114,152,0,0,0,114,156,0,0,0,114,158,0,0, - 0,114,165,0,0,0,114,170,0,0,0,114,171,0,0,0, - 114,176,0,0,0,218,6,111,98,106,101,99,116,114,185,0, - 0,0,114,190,0,0,0,114,191,0,0,0,114,208,0,0, - 0,114,221,0,0,0,114,239,0,0,0,114,9,1,0,0, - 114,15,1,0,0,114,21,1,0,0,114,252,0,0,0,114, - 22,1,0,0,114,43,1,0,0,114,45,1,0,0,114,59, - 1,0,0,114,79,1,0,0,114,184,0,0,0,114,87,1, - 0,0,114,89,1,0,0,114,3,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,8,60,109,111, - 100,117,108,101,62,1,0,0,0,115,126,0,0,0,4,22, - 4,1,4,1,2,1,2,255,4,4,8,17,8,5,8,5, - 8,6,8,6,8,12,8,10,8,9,8,5,8,7,8,9, - 12,22,10,127,0,8,16,1,12,2,4,1,4,2,6,2, - 6,2,8,2,18,71,8,40,8,19,8,12,8,12,8,28, - 8,17,8,33,8,28,8,24,16,13,14,10,12,11,8,14, - 6,3,6,1,2,255,12,68,14,64,14,29,16,127,0,17, - 14,72,18,45,18,26,4,3,18,53,14,63,14,42,14,127, - 0,7,14,127,0,22,12,23,8,11,8,65, + 0,114,39,1,0,0,26,6,0,0,115,2,0,0,0,0, + 1,122,19,70,105,108,101,70,105,110,100,101,114,46,95,95, + 114,101,112,114,95,95,41,1,78,41,15,114,125,0,0,0, + 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, + 209,0,0,0,114,46,1,0,0,114,143,0,0,0,114,206, + 0,0,0,114,137,0,0,0,114,58,1,0,0,114,203,0, + 0,0,114,87,1,0,0,114,207,0,0,0,114,94,1,0, + 0,114,39,1,0,0,114,3,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,79,1,0,0,139, + 5,0,0,115,22,0,0,0,8,2,4,7,8,14,8,4, + 4,2,8,12,8,5,10,48,8,31,2,1,10,17,114,79, + 1,0,0,99,4,0,0,0,0,0,0,0,0,0,0,0, + 6,0,0,0,8,0,0,0,67,0,0,0,115,146,0,0, + 0,124,0,160,0,100,1,161,1,125,4,124,0,160,0,100, + 2,161,1,125,5,124,4,115,66,124,5,114,36,124,5,106, + 1,125,4,110,30,124,2,124,3,107,2,114,56,116,2,124, + 1,124,2,131,2,125,4,110,10,116,3,124,1,124,2,131, + 2,125,4,124,5,115,84,116,4,124,1,124,2,124,4,100, + 3,141,3,125,5,122,36,124,5,124,0,100,2,60,0,124, + 4,124,0,100,1,60,0,124,2,124,0,100,4,60,0,124, + 3,124,0,100,5,60,0,87,0,110,20,4,0,116,5,107, + 10,114,140,1,0,1,0,1,0,89,0,110,2,88,0,100, + 0,83,0,41,6,78,218,10,95,95,108,111,97,100,101,114, + 95,95,218,8,95,95,115,112,101,99,95,95,114,80,1,0, + 0,90,8,95,95,102,105,108,101,95,95,90,10,95,95,99, + 97,99,104,101,100,95,95,41,6,218,3,103,101,116,114,140, + 0,0,0,114,15,1,0,0,114,9,1,0,0,114,190,0, + 0,0,114,72,1,0,0,41,6,90,2,110,115,114,117,0, + 0,0,90,8,112,97,116,104,110,97,109,101,90,9,99,112, + 97,116,104,110,97,109,101,114,140,0,0,0,114,187,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,14,95,102,105,120,95,117,112,95,109,111,100,117,108,101, + 32,6,0,0,115,34,0,0,0,0,2,10,1,10,1,4, + 1,4,1,8,1,8,1,12,2,10,1,4,1,14,1,2, + 1,8,1,8,1,8,1,12,1,14,2,114,98,1,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,3,0,0,0,67,0,0,0,115,38,0,0,0,116,0, + 116,1,160,2,161,0,102,2,125,0,116,3,116,4,102,2, + 125,1,116,5,116,6,102,2,125,2,124,0,124,1,124,2, + 103,3,83,0,41,1,122,95,82,101,116,117,114,110,115,32, + 97,32,108,105,115,116,32,111,102,32,102,105,108,101,45,98, + 97,115,101,100,32,109,111,100,117,108,101,32,108,111,97,100, + 101,114,115,46,10,10,32,32,32,32,69,97,99,104,32,105, + 116,101,109,32,105,115,32,97,32,116,117,112,108,101,32,40, + 108,111,97,100,101,114,44,32,115,117,102,102,105,120,101,115, + 41,46,10,32,32,32,32,41,7,114,252,0,0,0,114,163, + 0,0,0,218,18,101,120,116,101,110,115,105,111,110,95,115, + 117,102,102,105,120,101,115,114,9,1,0,0,114,102,0,0, + 0,114,15,1,0,0,114,89,0,0,0,41,3,90,10,101, + 120,116,101,110,115,105,111,110,115,90,6,115,111,117,114,99, + 101,90,8,98,121,116,101,99,111,100,101,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,184,0,0,0,55, + 6,0,0,115,8,0,0,0,0,5,12,1,8,1,8,1, + 114,184,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,12,0,0,0,9,0,0,0,67,0,0,0,115,178, + 1,0,0,124,0,97,0,116,0,106,1,97,1,116,0,106, + 2,97,2,116,1,106,3,116,4,25,0,125,1,100,1,68, + 0,93,48,125,2,124,2,116,1,106,3,107,7,114,56,116, + 0,160,5,124,2,161,1,125,3,110,10,116,1,106,3,124, + 2,25,0,125,3,116,6,124,1,124,2,124,3,131,3,1, + 0,113,30,100,2,100,3,103,1,102,2,100,4,100,5,100, + 3,103,2,102,2,102,2,125,4,124,4,68,0,93,110,92, + 2,125,5,125,6,116,7,100,6,100,7,132,0,124,6,68, + 0,131,1,131,1,115,136,116,8,130,1,124,6,100,8,25, + 0,125,7,124,5,116,1,106,3,107,6,114,170,116,1,106, + 3,124,5,25,0,125,8,1,0,113,226,113,106,122,20,116, + 0,160,5,124,5,161,1,125,8,87,0,1,0,113,226,87, + 0,113,106,4,0,116,9,107,10,114,214,1,0,1,0,1, + 0,89,0,113,106,89,0,113,106,88,0,113,106,116,9,100, + 9,131,1,130,1,116,6,124,1,100,10,124,8,131,3,1, + 0,116,6,124,1,100,11,124,7,131,3,1,0,116,6,124, + 1,100,12,100,13,160,10,124,6,161,1,131,3,1,0,116, + 6,124,1,100,14,100,15,100,16,132,0,124,6,68,0,131, + 1,131,3,1,0,116,0,160,5,100,17,161,1,125,9,116, + 6,124,1,100,17,124,9,131,3,1,0,116,0,160,5,100, + 18,161,1,125,10,116,6,124,1,100,18,124,10,131,3,1, + 0,124,5,100,4,107,2,144,1,114,110,116,0,160,5,100, + 19,161,1,125,11,116,6,124,1,100,20,124,11,131,3,1, + 0,116,6,124,1,100,21,116,11,131,0,131,3,1,0,116, + 12,160,13,116,2,160,14,161,0,161,1,1,0,124,5,100, + 4,107,2,144,1,114,174,116,15,160,16,100,22,161,1,1, + 0,100,23,116,12,107,6,144,1,114,174,100,24,116,17,95, + 18,100,25,83,0,41,26,122,205,83,101,116,117,112,32,116, + 104,101,32,112,97,116,104,45,98,97,115,101,100,32,105,109, + 112,111,114,116,101,114,115,32,102,111,114,32,105,109,112,111, + 114,116,108,105,98,32,98,121,32,105,109,112,111,114,116,105, + 110,103,32,110,101,101,100,101,100,10,32,32,32,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,97, + 110,100,32,105,110,106,101,99,116,105,110,103,32,116,104,101, + 109,32,105,110,116,111,32,116,104,101,32,103,108,111,98,97, + 108,32,110,97,109,101,115,112,97,99,101,46,10,10,32,32, + 32,32,79,116,104,101,114,32,99,111,109,112,111,110,101,110, + 116,115,32,97,114,101,32,101,120,116,114,97,99,116,101,100, + 32,102,114,111,109,32,116,104,101,32,99,111,114,101,32,98, + 111,111,116,115,116,114,97,112,32,109,111,100,117,108,101,46, + 10,10,32,32,32,32,41,4,114,64,0,0,0,114,75,0, + 0,0,218,8,98,117,105,108,116,105,110,115,114,160,0,0, + 0,90,5,112,111,115,105,120,250,1,47,90,2,110,116,250, + 1,92,99,1,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,115,0,0,0,115,26,0,0,0, + 124,0,93,18,125,1,116,0,124,1,131,1,100,0,107,2, + 86,0,1,0,113,2,100,1,83,0,41,2,114,39,0,0, + 0,78,41,1,114,22,0,0,0,41,2,114,32,0,0,0, + 114,95,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,19,1,0,0,91,6,0,0,115,4,0, + 0,0,4,0,2,0,122,25,95,115,101,116,117,112,46,60, + 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, + 62,114,73,0,0,0,122,30,105,109,112,111,114,116,108,105, + 98,32,114,101,113,117,105,114,101,115,32,112,111,115,105,120, + 32,111,114,32,110,116,114,2,0,0,0,114,35,0,0,0, + 114,31,0,0,0,114,40,0,0,0,114,58,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 4,0,0,0,83,0,0,0,115,22,0,0,0,104,0,124, + 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113, + 4,83,0,41,1,114,74,0,0,0,114,3,0,0,0,41, + 2,114,32,0,0,0,218,1,115,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,88,1,0,0,107,6,0, + 0,115,4,0,0,0,6,0,2,0,122,25,95,115,101,116, + 117,112,46,60,108,111,99,97,108,115,62,46,60,115,101,116, + 99,111,109,112,62,90,7,95,116,104,114,101,97,100,90,8, + 95,119,101,97,107,114,101,102,90,6,119,105,110,114,101,103, + 114,192,0,0,0,114,7,0,0,0,122,4,46,112,121,119, + 122,6,95,100,46,112,121,100,84,78,41,19,114,134,0,0, + 0,114,8,0,0,0,114,163,0,0,0,114,31,1,0,0, + 114,125,0,0,0,90,18,95,98,117,105,108,116,105,110,95, + 102,114,111,109,95,110,97,109,101,114,129,0,0,0,218,3, + 97,108,108,114,23,0,0,0,114,118,0,0,0,114,36,0, + 0,0,114,13,0,0,0,114,21,1,0,0,114,167,0,0, + 0,114,99,1,0,0,114,102,0,0,0,114,186,0,0,0, + 114,191,0,0,0,114,195,0,0,0,41,12,218,17,95,98, + 111,111,116,115,116,114,97,112,95,109,111,100,117,108,101,90, + 11,115,101,108,102,95,109,111,100,117,108,101,90,12,98,117, + 105,108,116,105,110,95,110,97,109,101,90,14,98,117,105,108, + 116,105,110,95,109,111,100,117,108,101,90,10,111,115,95,100, + 101,116,97,105,108,115,90,10,98,117,105,108,116,105,110,95, + 111,115,114,31,0,0,0,114,35,0,0,0,90,9,111,115, + 95,109,111,100,117,108,101,90,13,116,104,114,101,97,100,95, + 109,111,100,117,108,101,90,14,119,101,97,107,114,101,102,95, + 109,111,100,117,108,101,90,13,119,105,110,114,101,103,95,109, + 111,100,117,108,101,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,6,95,115,101,116,117,112,66,6,0,0, + 115,78,0,0,0,0,8,4,1,6,1,6,3,10,1,8, + 1,10,1,12,2,10,1,14,3,22,1,12,2,22,1,8, + 1,10,1,10,1,6,2,2,1,10,1,10,1,14,1,12, + 2,8,1,12,1,12,1,18,1,22,3,10,1,12,3,10, + 1,12,3,10,1,10,1,12,3,14,1,14,1,10,1,10, + 1,10,1,114,106,1,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, + 0,115,50,0,0,0,116,0,124,0,131,1,1,0,116,1, + 131,0,125,1,116,2,106,3,160,4,116,5,106,6,124,1, + 142,0,103,1,161,1,1,0,116,2,106,7,160,8,116,9, + 161,1,1,0,100,1,83,0,41,2,122,41,73,110,115,116, + 97,108,108,32,116,104,101,32,112,97,116,104,45,98,97,115, + 101,100,32,105,109,112,111,114,116,32,99,111,109,112,111,110, + 101,110,116,115,46,78,41,10,114,106,1,0,0,114,184,0, + 0,0,114,8,0,0,0,114,51,1,0,0,114,167,0,0, + 0,114,79,1,0,0,114,94,1,0,0,218,9,109,101,116, + 97,95,112,97,116,104,114,186,0,0,0,114,45,1,0,0, + 41,2,114,105,1,0,0,90,17,115,117,112,112,111,114,116, + 101,100,95,108,111,97,100,101,114,115,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,8,95,105,110,115,116, + 97,108,108,131,6,0,0,115,8,0,0,0,0,2,8,1, + 6,1,20,1,114,108,1,0,0,41,63,114,127,0,0,0, + 114,12,0,0,0,90,37,95,67,65,83,69,95,73,78,83, + 69,78,83,73,84,73,86,69,95,80,76,65,84,70,79,82, + 77,83,95,66,89,84,69,83,95,75,69,89,114,11,0,0, + 0,114,13,0,0,0,114,20,0,0,0,114,27,0,0,0, + 114,29,0,0,0,114,38,0,0,0,114,47,0,0,0,114, + 49,0,0,0,114,53,0,0,0,114,54,0,0,0,114,56, + 0,0,0,114,59,0,0,0,114,69,0,0,0,218,4,116, + 121,112,101,218,8,95,95,99,111,100,101,95,95,114,162,0, + 0,0,114,18,0,0,0,114,148,0,0,0,114,17,0,0, + 0,114,24,0,0,0,114,236,0,0,0,114,92,0,0,0, + 114,88,0,0,0,114,102,0,0,0,114,89,0,0,0,90, + 23,68,69,66,85,71,95,66,89,84,69,67,79,68,69,95, + 83,85,70,70,73,88,69,83,90,27,79,80,84,73,77,73, + 90,69,68,95,66,89,84,69,67,79,68,69,95,83,85,70, + 70,73,88,69,83,114,98,0,0,0,114,103,0,0,0,114, + 109,0,0,0,114,113,0,0,0,114,115,0,0,0,114,136, + 0,0,0,114,143,0,0,0,114,152,0,0,0,114,156,0, + 0,0,114,158,0,0,0,114,165,0,0,0,114,170,0,0, + 0,114,171,0,0,0,114,176,0,0,0,218,6,111,98,106, + 101,99,116,114,185,0,0,0,114,190,0,0,0,114,191,0, + 0,0,114,208,0,0,0,114,221,0,0,0,114,239,0,0, + 0,114,9,1,0,0,114,15,1,0,0,114,21,1,0,0, + 114,252,0,0,0,114,22,1,0,0,114,43,1,0,0,114, + 45,1,0,0,114,79,1,0,0,114,98,1,0,0,114,184, + 0,0,0,114,106,1,0,0,114,108,1,0,0,114,3,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,8,60,109,111,100,117,108,101,62,1,0,0,0,115, + 126,0,0,0,4,22,4,1,4,1,2,1,2,255,4,4, + 8,17,8,5,8,5,8,6,8,6,8,12,8,10,8,9, + 8,5,8,7,8,9,12,22,10,127,0,8,16,1,12,2, + 4,1,4,2,6,2,6,2,8,2,18,71,8,40,8,19, + 8,12,8,12,8,28,8,17,8,33,8,28,8,24,16,13, + 14,10,12,11,8,14,6,3,6,1,2,255,12,68,14,64, + 14,29,16,127,0,17,14,72,18,45,18,26,4,3,18,53, + 14,63,14,42,14,127,0,59,14,127,0,22,12,23,8,11, + 8,65, }; From 81bb97df6138c755e229dcdac9bed747e31b61b3 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 24 May 2019 21:59:53 -0400 Subject: [PATCH 105/441] bpo-37038: Make idlelib.run runnable; add test clause (GH-13560) --- Lib/idlelib/NEWS.txt | 2 ++ Lib/idlelib/run.py | 30 ++++++++++++++----- .../2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst | 1 + 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 3f19ce73739630..e1bc009ae93332 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-10-20? ====================================== +bpo-37038: Make idlelib.run runnable; add test clause. + bpo-36958: Print any argument other than None or int passed to SystemExit or sys.exit(). diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index b4a2b54a33c850..4075deec51d8ed 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -1,3 +1,9 @@ +""" idlelib.run + +Simplified, pyshell.ModifiedInterpreter spawns a subprocess with +f'''{sys.executable} -c "__import__('idlelib.run').run.main()"''' +'.run' is needed because __import__ returns idlelib, not idlelib.run. +""" import io import linecache import queue @@ -8,8 +14,6 @@ import threading import warnings -import tkinter # Tcl, deletions, messagebox if startup fails - from idlelib import autocomplete # AutoComplete, fetch_encodings from idlelib import calltip # Calltip from idlelib import debugger_r # start_debugger @@ -19,11 +23,16 @@ from idlelib import stackviewer # StackTreeItem import __main__ -for mod in ('simpledialog', 'messagebox', 'font', - 'dialog', 'filedialog', 'commondialog', - 'ttk'): - delattr(tkinter, mod) - del sys.modules['tkinter.' + mod] +import tkinter # Use tcl and, if startup fails, messagebox. +if not hasattr(sys.modules['idlelib.run'], 'firstrun'): + # Undo modifications of tkinter by idlelib imports; see bpo-25507. + for mod in ('simpledialog', 'messagebox', 'font', + 'dialog', 'filedialog', 'commondialog', + 'ttk'): + delattr(tkinter, mod) + del sys.modules['tkinter.' + mod] + # Avoid AttributeError if run again; see bpo-37038. + sys.modules['idlelib.run'].firstrun = False LOCALHOST = '127.0.0.1' @@ -523,4 +532,9 @@ def stackviewer(self, flist_oid=None): item = stackviewer.StackTreeItem(flist, tb) return debugobj_r.remote_object_tree_item(item) -capture_warnings(False) # Make sure turned off; see issue 18081 + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_run', verbosity=2) + +capture_warnings(False) # Make sure turned off; see bpo-18081. diff --git a/Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst b/Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst new file mode 100644 index 00000000000000..762e9f1e43749d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst @@ -0,0 +1 @@ +Make idlelib.run runnable; add test clause. From c3738cfe63b1f2c1dc4a28d0ff9adb4e9e3aae1f Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sat, 25 May 2019 16:09:35 +0800 Subject: [PATCH 106/441] bpo-34632: fix installation of importlib.metadata (#13563) --- Makefile.pre.in | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.pre.in b/Makefile.pre.in index 466cd763c98dee..925d52f7894e11 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1320,6 +1320,7 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ test/test_import/data/package \ test/test_import/data/package2 \ importlib \ + importlib/metadata \ test/test_importlib \ test/test_importlib/builtin \ test/test_importlib/data01 \ From af570745fe3852a9ded0e723a7232e4cc0451e95 Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Sat, 25 May 2019 12:03:45 +0200 Subject: [PATCH 107/441] =?UTF-8?q?=F0=9F=93=9D=20Add=20a=20GitHub-specifi?= =?UTF-8?q?c=20security=20page=20(GH-13526)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 📝 Add a GitHub-specific security page It will show up @ https://github.com/python/cpython/security/policy allowing to navigate users who get there from "Security" tab in the GitHub repo to the full article explaining the security vulnerability reporting practices. Co-Authored-By: Hugo --- .github/SECURITY.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000000000..23976fda4a7eb5 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +## Supported Versions + +The Python team applies security fixes according to the table in +in [the devguide]( +https://devguide.python.org/#status-of-python-branches +). + +## Reporting a Vulnerability + +Please read the guidelines on reporting security issues [on the +official website]( +https://www.python.org/news/security/#reporting-security-issues-in-python +) for instructions on how to report a security-related problem to +the Python team responsibly. + +To reach the response team, email `security at python dot org`. From f7fba6cfb62edfc22e9b2e12a00ebaf5f348398e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 25 May 2019 10:00:21 -0400 Subject: [PATCH 108/441] bpo-34632 fix buildbots and remove artifact (GH-13566) * bpo-34632: Also include the test data directory. * bpo-34632: remove the framework resources artifacts, accidentally added in 1bbf7b661f (ccbccce) --- Makefile.pre.in | 1 + Python.framework/Resources | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 120000 Python.framework/Resources diff --git a/Makefile.pre.in b/Makefile.pre.in index 925d52f7894e11..ee94ad54a272e5 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1323,6 +1323,7 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ importlib/metadata \ test/test_importlib \ test/test_importlib/builtin \ + test/test_importlib/data \ test/test_importlib/data01 \ test/test_importlib/data01/subdirectory \ test/test_importlib/data02 \ diff --git a/Python.framework/Resources b/Python.framework/Resources deleted file mode 120000 index 953ee36f3bb709..00000000000000 --- a/Python.framework/Resources +++ /dev/null @@ -1 +0,0 @@ -Versions/Current/Resources \ No newline at end of file From 7114c6504a60365b8b0cd718da0ec8a737599fb9 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Sat, 25 May 2019 20:02:24 +0200 Subject: [PATCH 109/441] Docs: FIX broken links. (GH-13491) --- Doc/faq/gui.rst | 2 +- Doc/library/readline.rst | 2 +- Doc/library/tkinter.rst | 2 +- Doc/using/mac.rst | 2 +- Doc/using/windows.rst | 7 ++++--- Doc/whatsnew/2.6.rst | 2 +- Doc/whatsnew/3.2.rst | 16 +++++++++------- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 4f9979bf55ed3a..781da467d18013 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -104,7 +104,7 @@ What platform-specific GUI toolkits exist for Python? ======================================================== By installing the `PyObjc Objective-C bridge -`_, Python programs can use Mac OS X's +`_, Python programs can use Mac OS X's Cocoa libraries. :ref:`Pythonwin ` by Mark Hammond includes an interface to the diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 16c28cf7d02fb9..eae0a6df45f30e 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -19,7 +19,7 @@ function. Readline keybindings may be configured via an initialization file, typically ``.inputrc`` in your home directory. See `Readline Init File -`_ +`_ in the GNU Readline manual for information about the format and allowable constructs of that file, and the capabilities of the Readline library in general. diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 60cf892e0888b7..640fb2ec61d359 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -55,7 +55,7 @@ installed, so you can read the Tcl/Tk documentation specific to that version. `Tcl/Tk recent man pages `_ Recent Tcl/Tk manuals on www.tcl.tk. - `ActiveState Tcl Home Page `_ + `ActiveState Tcl Home Page `_ The Tk/Tcl development is largely taking place at ActiveState. `Tcl and the Tk Toolkit `_ diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index a386728eaee306..bc022fa58c0401 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -141,7 +141,7 @@ There are several options for building GUI applications on the Mac with Python. *PyObjC* is a Python binding to Apple's Objective-C/Cocoa framework, which is the foundation of most modern Mac development. Information on PyObjC is -available from https://pythonhosted.org/pyobjc/. +available from https://pypi.org/project/pyobjc/. The standard Python GUI toolkit is :mod:`tkinter`, based on the cross-platform Tk toolkit (https://www.tcl.tk). An Aqua-native version of Tk is bundled with OS diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 44b646fddfc4ba..a1b25ffd25f08a 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -1043,7 +1043,9 @@ The `PyWin32 `_ module by Mark Hammond is a collection of modules for advanced Windows-specific support. This includes utilities for: -* `Component Object Model `_ (COM) +* `Component Object Model + `_ + (COM) * Win32 API calls * Registry * Event log @@ -1109,8 +1111,7 @@ For extension modules, consult :ref:`building-on-windows`. MinGW gcc under Windows" or "Installing Python extension with distutils and without Microsoft Visual C++" by Sébastien Sauvage, 2003 - `MingW -- Python extensions `_ - by Trent Apted et al, 2007 + `MingW -- Python extensions `_ Other Platforms diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index 512b8edb357ae9..b6174a19a178b6 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -227,7 +227,7 @@ the Python community. Sphinx is a standalone package that can be used for writing, and almost two dozen other projects -(`listed on the Sphinx web site `__) +(`listed on the Sphinx web site `__) have adopted Sphinx as their documentation tool. .. seealso:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 2d740006a3706a..ca3eda05c515af 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -50,7 +50,9 @@ This article explains the new features in Python 3.2 as compared to 3.1. It focuses on a few highlights and gives a few examples. For full details, see the -`Misc/NEWS `_ file. +`Misc/NEWS +`_ +file. .. seealso:: @@ -969,10 +971,10 @@ sites do not finish before midnight, the barrier times-out and the ballots are sealed and deposited in a queue for later handling. See `Barrier Synchronization Patterns -`_ for -more examples of how barriers can be used in parallel computing. Also, there is +`_ +for more examples of how barriers can be used in parallel computing. Also, there is a simple but thorough explanation of barriers in `The Little Book of Semaphores -`_, *section 3.6*. +`_, *section 3.6*. (Contributed by Kristján Valur Jónsson with an API review by Jeffrey Yasskin in :issue:`8777`.) @@ -2512,9 +2514,9 @@ repository. This distributed version control system should make it easier for members of the community to create and share external changesets. See :pep:`385` for details. -To learn to use the new version control system, see the `tutorial by Joel -Spolsky `_ or the `Guide to Mercurial Workflows -`_. +To learn to use the new version control system, see the `Quick Start +`_ or the `Guide to +Mercurial Workflows `_. Build and C API Changes From 47dd2f9fd86c32a79e77fef1fbb1ce25dc929de6 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Sun, 26 May 2019 00:23:34 -0700 Subject: [PATCH 110/441] bpo-37017: PyObject_CallMethodObjArgs uses LOAD_METHOD optimization (GH-13516) Update PyObject_CallMethodObjArgs and _PyObject_CallMethodIdObjArgs to use _PyObject_GetMethod to avoid creating a bound method object in many cases. On a microbenchmark of PyObject_CallMethodObjArgs calling a method on an interpreted Python class, this optimization resulted in a 1.7x speedup. --- .../2019-05-22-17-33-52.bpo-37107.8BVPR-.rst | 4 ++ Objects/call.c | 45 ++++++++++++------- 2 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst diff --git a/Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst b/Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst new file mode 100644 index 00000000000000..4a9e58f7155483 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst @@ -0,0 +1,4 @@ +Update :c:func:`PyObject_CallMethodObjArgs` and ``_PyObject_CallMethodIdObjArgs`` +to use ``_PyObject_GetMethod`` to avoid creating a bound method object in many +cases. +Patch by Michael J. Sullivan. diff --git a/Objects/call.c b/Objects/call.c index cb9ccd9c2caef4..b608492dd6bef5 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1159,7 +1159,7 @@ _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, /* --- Call with "..." arguments ---------------------------------- */ static PyObject * -object_vacall(PyObject *callable, va_list vargs) +object_vacall(PyObject *base, PyObject *callable, va_list vargs) { PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; @@ -1174,7 +1174,7 @@ object_vacall(PyObject *callable, va_list vargs) /* Count the number of arguments */ va_copy(countva, vargs); - nargs = 0; + nargs = base ? 1 : 0; while (1) { PyObject *arg = va_arg(countva, PyObject *); if (arg == NULL) { @@ -1196,7 +1196,12 @@ object_vacall(PyObject *callable, va_list vargs) } } - for (i = 0; i < nargs; ++i) { + i = 0; + if (base) { + stack[i++] = base; + } + + for (; i < nargs; ++i) { stack[i] = va_arg(vargs, PyObject *); } @@ -1210,23 +1215,26 @@ object_vacall(PyObject *callable, va_list vargs) } +/* Private API for the LOAD_METHOD opcode. */ +extern int _PyObject_GetMethod(PyObject *, PyObject *, PyObject **); + PyObject * -PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) +PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) { - va_list vargs; - PyObject *result; - - if (callable == NULL || name == NULL) { + if (obj == NULL || name == NULL) { return null_error(); } - callable = PyObject_GetAttr(callable, name); + PyObject *callable = NULL; + int is_method = _PyObject_GetMethod(obj, name, &callable); if (callable == NULL) { return NULL; } + obj = is_method ? obj : NULL; + va_list vargs; va_start(vargs, name); - result = object_vacall(callable, vargs); + PyObject *result = object_vacall(obj, callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -1238,20 +1246,25 @@ PyObject * _PyObject_CallMethodIdObjArgs(PyObject *obj, struct _Py_Identifier *name, ...) { - va_list vargs; - PyObject *callable, *result; - if (obj == NULL || name == NULL) { return null_error(); } - callable = _PyObject_GetAttrId(obj, name); + PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ + if (!oname) { + return NULL; + } + + PyObject *callable = NULL; + int is_method = _PyObject_GetMethod(obj, oname, &callable); if (callable == NULL) { return NULL; } + obj = is_method ? obj : NULL; + va_list vargs; va_start(vargs, name); - result = object_vacall(callable, vargs); + PyObject *result = object_vacall(obj, callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -1266,7 +1279,7 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...) PyObject *result; va_start(vargs, callable); - result = object_vacall(callable, vargs); + result = object_vacall(NULL, callable, vargs); va_end(vargs); return result; From f367242d10ef36db38133a39ab7627f63099cba4 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sun, 26 May 2019 09:37:07 +0100 Subject: [PATCH 111/441] bpo-37045: PEP 591: Add final qualifiers to typing module (GH-13571) The implementation is straightforward, it just mimics `ClassVar` (since the latter is also a name/access qualifier, not really a type). Also it is essentially copied from `typing_extensions`. --- Doc/library/typing.rst | 44 ++++++++++++++++ Lib/test/test_typing.py | 49 ++++++++++++++++- Lib/typing.py | 52 +++++++++++++++++-- .../2019-05-25-18-36-50.bpo-37045.suHdVJ.rst | 1 + 4 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 86a3db8467ec74..8362f1d8e6b793 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -940,6 +940,31 @@ The module defines the following classes, functions and decorators: See :pep:`484` for details and comparison with other typing semantics. +.. decorator:: final + + A decorator to indicate to type checkers that the decorated method + cannot be overridden, and the decorated class cannot be subclassed. + For example:: + + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker + ... + + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... + + There is no runtime checking of these properties. See :pep:`591` for + more details. + + .. versionadded:: 3.8 + .. decorator:: no_type_check Decorator to indicate that annotations are not type hints. @@ -1104,6 +1129,25 @@ The module defines the following classes, functions and decorators: .. versionadded:: 3.5.3 +.. data:: Final + + A special typing construct to indicate to type checkers that a name + cannot be re-assigned or overridden in a subclass. For example:: + + MAX_SIZE: Final = 9000 + MAX_SIZE += 1 # Error reported by type checker + + class Connection: + TIMEOUT: Final[int] = 10 + + class FastConnector(Connection): + TIMEOUT = 1 # Error reported by type checker + + There is no runtime checking of these properties. See :pep:`591` for + more details. + + .. versionadded:: 3.8 + .. data:: AnyStr ``AnyStr`` is a type variable defined as diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index c9bfd0c7ed720d..3d93eb396ce7ad 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -12,7 +12,7 @@ from typing import Union, Optional from typing import Tuple, List, MutableMapping from typing import Callable -from typing import Generic, ClassVar +from typing import Generic, ClassVar, Final, final from typing import cast from typing import get_type_hints from typing import no_type_check, no_type_check_decorator @@ -1438,6 +1438,53 @@ def test_no_isinstance(self): issubclass(int, ClassVar) +class FinalTests(BaseTestCase): + + def test_basics(self): + Final[int] # OK + with self.assertRaises(TypeError): + Final[1] + with self.assertRaises(TypeError): + Final[int, str] + with self.assertRaises(TypeError): + Final[int][str] + with self.assertRaises(TypeError): + Optional[Final[int]] + + def test_repr(self): + self.assertEqual(repr(Final), 'typing.Final') + cv = Final[int] + self.assertEqual(repr(cv), 'typing.Final[int]') + cv = Final[Employee] + self.assertEqual(repr(cv), 'typing.Final[%s.Employee]' % __name__) + + def test_cannot_subclass(self): + with self.assertRaises(TypeError): + class C(type(Final)): + pass + with self.assertRaises(TypeError): + class C(type(Final[int])): + pass + + def test_cannot_init(self): + with self.assertRaises(TypeError): + Final() + with self.assertRaises(TypeError): + type(Final)() + with self.assertRaises(TypeError): + type(Final[Optional[int]])() + + def test_no_isinstance(self): + with self.assertRaises(TypeError): + isinstance(1, Final[int]) + with self.assertRaises(TypeError): + issubclass(int, Final) + + def test_final_unmodified(self): + def func(x): ... + self.assertIs(func, final(func)) + + class CastTests(BaseTestCase): def test_basics(self): diff --git a/Lib/typing.py b/Lib/typing.py index 7aab1628a3192b..06a7eb0dff8437 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -35,6 +35,7 @@ 'Any', 'Callable', 'ClassVar', + 'Final', 'Generic', 'Optional', 'Tuple', @@ -92,6 +93,7 @@ # One-off things. 'AnyStr', 'cast', + 'final', 'get_type_hints', 'NewType', 'no_type_check', @@ -121,7 +123,7 @@ def _type_check(arg, msg, is_argument=True): """ invalid_generic_forms = (Generic, _Protocol) if is_argument: - invalid_generic_forms = invalid_generic_forms + (ClassVar, ) + invalid_generic_forms = invalid_generic_forms + (ClassVar, Final) if arg is None: return type(None) @@ -336,8 +338,8 @@ def __subclasscheck__(self, cls): @_tp_cache def __getitem__(self, parameters): - if self._name == 'ClassVar': - item = _type_check(parameters, 'ClassVar accepts only single type.') + if self._name in ('ClassVar', 'Final'): + item = _type_check(parameters, f'{self._name} accepts only single type.') return _GenericAlias(self, (item,)) if self._name == 'Union': if parameters == (): @@ -398,6 +400,24 @@ class Starship: be used with isinstance() or issubclass(). """) +Final = _SpecialForm('Final', doc= + """Special typing construct to indicate final names to type checkers. + + A final name cannot be re-assigned or overridden in a subclass. + For example: + + MAX_SIZE: Final = 9000 + MAX_SIZE += 1 # Error reported by type checker + + class Connection: + TIMEOUT: Final[int] = 10 + + class FastConnector(Connection): + TIMEOUT = 1 # Error reported by type checker + + There is no runtime checking of these properties. + """) + Union = _SpecialForm('Union', doc= """Union type; Union[X, Y] means either X or Y. @@ -1085,6 +1105,32 @@ def utf8(value): return _overload_dummy +def final(f): + """A decorator to indicate final methods and final classes. + + Use this decorator to indicate to type checkers that the decorated + method cannot be overridden, and decorated class cannot be subclassed. + For example: + + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker + ... + + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... + + There is no runtime checking of these properties. + """ + return f + + class _ProtocolMeta(type): """Internal metaclass for _Protocol. diff --git a/Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst b/Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst new file mode 100644 index 00000000000000..001529ed6db43c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst @@ -0,0 +1 @@ +PEP 591: Add ``Final`` qualifier and ``@final`` decorator to the ``typing`` module. \ No newline at end of file From b891c465bb7d38a597c5c2ad547d7b19194f4dad Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sun, 26 May 2019 09:37:48 +0100 Subject: [PATCH 112/441] bpo-37046: PEP 586: Add Literal to typing module (#13572) The implementation is straightforward and essentially is just copied from `typing_extensions`. --- Doc/library/typing.rst | 22 +++++++ Lib/test/test_typing.py | 64 ++++++++++++++++++- Lib/typing.py | 27 ++++++++ .../2019-05-25-19-12-53.bpo-37046.iuhQQj.rst | 1 + 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 8362f1d8e6b793..e64fecb8544b27 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1103,6 +1103,28 @@ The module defines the following classes, functions and decorators: ``Callable[..., Any]``, and in turn to :class:`collections.abc.Callable`. +.. data:: Literal + + A type that can be used to indicate to type checkers that the + corresponding variable or function parameter has a value equivalent to + the provided literal (or one of several literals). For example:: + + def validate_simple(data: Any) -> Literal[True]: # always returns True + ... + + MODE = Literal['r', 'rb', 'w', 'wb'] + def open_helper(file: str, mode: MODE) -> str: + ... + + open_helper('/some/path', 'r') # Passes type check + open_helper('/other/path', 'typo') # Error in type checker + + ``Literal[...]`` cannot be subclassed. At runtime, an arbitrary value + is allowed as type argument to ``Literal[...]``, but type checkers may + impose restrictions. See :pep:`586` for more details about literal types. + + .. versionadded:: 3.8 + .. data:: ClassVar Special type construct to mark class variables. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 3d93eb396ce7ad..eb618936d97b91 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -9,7 +9,7 @@ from typing import Any, NoReturn from typing import TypeVar, AnyStr from typing import T, KT, VT # Not in __all__. -from typing import Union, Optional +from typing import Union, Optional, Literal from typing import Tuple, List, MutableMapping from typing import Callable from typing import Generic, ClassVar, Final, final @@ -489,6 +489,68 @@ def test_ellipsis_in_generic(self): typing.List[Callable[..., str]] +class LiteralTests(BaseTestCase): + def test_basics(self): + # All of these are allowed. + Literal[1] + Literal[1, 2, 3] + Literal["x", "y", "z"] + Literal[None] + Literal[True] + Literal[1, "2", False] + Literal[Literal[1, 2], Literal[4, 5]] + Literal[b"foo", u"bar"] + + def test_illegal_parameters_do_not_raise_runtime_errors(self): + # Type checkers should reject these types, but we do not + # raise errors at runtime to maintain maximium flexibility. + Literal[int] + Literal[3j + 2, ..., ()] + Literal[{"foo": 3, "bar": 4}] + Literal[T] + + def test_literals_inside_other_types(self): + List[Literal[1, 2, 3]] + List[Literal[("foo", "bar", "baz")]] + + def test_repr(self): + self.assertEqual(repr(Literal[1]), "typing.Literal[1]") + self.assertEqual(repr(Literal[1, True, "foo"]), "typing.Literal[1, True, 'foo']") + self.assertEqual(repr(Literal[int]), "typing.Literal[int]") + self.assertEqual(repr(Literal), "typing.Literal") + self.assertEqual(repr(Literal[None]), "typing.Literal[None]") + + def test_cannot_init(self): + with self.assertRaises(TypeError): + Literal() + with self.assertRaises(TypeError): + Literal[1]() + with self.assertRaises(TypeError): + type(Literal)() + with self.assertRaises(TypeError): + type(Literal[1])() + + def test_no_isinstance_or_issubclass(self): + with self.assertRaises(TypeError): + isinstance(1, Literal[1]) + with self.assertRaises(TypeError): + isinstance(int, Literal[1]) + with self.assertRaises(TypeError): + issubclass(1, Literal[1]) + with self.assertRaises(TypeError): + issubclass(int, Literal[1]) + + def test_no_subclassing(self): + with self.assertRaises(TypeError): + class Foo(Literal[1]): pass + with self.assertRaises(TypeError): + class Bar(Literal): pass + + def test_no_multiple_subscripts(self): + with self.assertRaises(TypeError): + Literal[1][1] + + XK = TypeVar('XK', str, bytes) XV = TypeVar('XV') diff --git a/Lib/typing.py b/Lib/typing.py index 06a7eb0dff8437..1044cc409f410a 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -37,6 +37,7 @@ 'ClassVar', 'Final', 'Generic', + 'Literal', 'Optional', 'Tuple', 'Type', @@ -355,6 +356,10 @@ def __getitem__(self, parameters): if self._name == 'Optional': arg = _type_check(parameters, "Optional[t] requires a single type.") return Union[arg, type(None)] + if self._name == 'Literal': + # There is no '_type_check' call because arguments to Literal[...] are + # values, not types. + return _GenericAlias(self, parameters) raise TypeError(f"{self} is not subscriptable") @@ -451,6 +456,28 @@ class FastConnector(Connection): Optional[X] is equivalent to Union[X, None]. """) +Literal = _SpecialForm('Literal', doc= + """Special typing form to define literal types (a.k.a. value types). + + This form can be used to indicate to type checkers that the corresponding + variable or function parameter has a value equivalent to the provided + literal (or one of several literals): + + def validate_simple(data: Any) -> Literal[True]: # always returns True + ... + + MODE = Literal['r', 'rb', 'w', 'wb'] + def open_helper(file: str, mode: MODE) -> str: + ... + + open_helper('/some/path', 'r') # Passes type check + open_helper('/other/path', 'typo') # Error in type checker + + Literal[...] cannot be subclassed. At runtime, an arbitrary value + is allowed as type argument to Literal[...], but type checkers may + impose restrictions. + """) + class ForwardRef(_Final, _root=True): """Internal wrapper to hold a forward reference.""" diff --git a/Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst b/Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst new file mode 100644 index 00000000000000..9ec333b2d980f9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst @@ -0,0 +1 @@ +PEP 586: Add ``Literal`` to the ``typing`` module. \ No newline at end of file From 135c6a56e55d2f4f8718b3b9f03ce3c692b15f0f Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sun, 26 May 2019 09:39:24 +0100 Subject: [PATCH 113/441] bpo-37049: PEP 589: Add TypedDict to typing module (GH-13573) The implementation is straightforward and essentially is just copied from `typing_extensions`. --- Doc/library/typing.rst | 33 ++++++ Lib/test/test_typing.py | 105 +++++++++++++++++- Lib/typing.py | 84 ++++++++++++++ .../2019-05-25-19-48-42.bpo-37049.an2LXJ.rst | 1 + 4 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index e64fecb8544b27..27787fc2cb86b3 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -878,6 +878,39 @@ The module defines the following classes, functions and decorators: The ``_field_types`` and ``__annotations__`` attributes are now regular dictionaries instead of instances of ``OrderedDict``. +.. class:: TypedDict(dict) + + A simple typed namespace. At runtime it is equivalent to + a plain :class:`dict`. + + ``TypedDict`` creates a dictionary type that expects all of its + instances to have a certain set of keys, where each key is + associated with a value of a consistent type. This expectation + is not checked at runtime but is only enforced by type checkers. + Usage:: + + class Point2D(TypedDict): + x: int + y: int + label: str + + a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK + b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check + + assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') + + The type info for introspection can be accessed via ``Point2D.__annotations__`` + and ``Point2D.__total__``. To allow using this feature with older versions + of Python that do not support :pep:`526`, ``TypedDict`` supports two additional + equivalent syntactic forms:: + + Point2D = TypedDict('Point2D', x=int, y=int, label=str) + Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + + See :pep:`589` for more examples and detailed rules of using ``TypedDict`` + with type checkers. + + .. versionadded:: 3.8 .. function:: NewType(typ) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index eb618936d97b91..088db9c012066d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -18,7 +18,7 @@ from typing import no_type_check, no_type_check_decorator from typing import Type from typing import NewType -from typing import NamedTuple +from typing import NamedTuple, TypedDict from typing import IO, TextIO, BinaryIO from typing import Pattern, Match import abc @@ -1883,6 +1883,18 @@ def __str__(self): def __add__(self, other): return 0 +Label = TypedDict('Label', [('label', str)]) + +class Point2D(TypedDict): + x: int + y: int + +class LabelPoint2D(Point2D, Label): ... + +class Options(TypedDict, total=False): + log_level: int + log_path: str + class HasForeignBaseClass(mod_generics_cache.A): some_xrepr: 'XRepr' other_a: 'mod_generics_cache.A' @@ -2658,6 +2670,97 @@ def test_pickle(self): self.assertEqual(jane2, jane) +class TypedDictTests(BaseTestCase): + def test_basics_functional_syntax(self): + Emp = TypedDict('Emp', {'name': str, 'id': int}) + self.assertIsSubclass(Emp, dict) + self.assertIsSubclass(Emp, typing.MutableMapping) + self.assertNotIsSubclass(Emp, collections.abc.Sequence) + jim = Emp(name='Jim', id=1) + self.assertIs(type(jim), dict) + self.assertEqual(jim['name'], 'Jim') + self.assertEqual(jim['id'], 1) + self.assertEqual(Emp.__name__, 'Emp') + self.assertEqual(Emp.__module__, __name__) + self.assertEqual(Emp.__bases__, (dict,)) + self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) + self.assertEqual(Emp.__total__, True) + + def test_basics_keywords_syntax(self): + Emp = TypedDict('Emp', name=str, id=int) + self.assertIsSubclass(Emp, dict) + self.assertIsSubclass(Emp, typing.MutableMapping) + self.assertNotIsSubclass(Emp, collections.abc.Sequence) + jim = Emp(name='Jim', id=1) + self.assertIs(type(jim), dict) + self.assertEqual(jim['name'], 'Jim') + self.assertEqual(jim['id'], 1) + self.assertEqual(Emp.__name__, 'Emp') + self.assertEqual(Emp.__module__, __name__) + self.assertEqual(Emp.__bases__, (dict,)) + self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) + self.assertEqual(Emp.__total__, True) + + def test_typeddict_errors(self): + Emp = TypedDict('Emp', {'name': str, 'id': int}) + self.assertEqual(TypedDict.__module__, 'typing') + jim = Emp(name='Jim', id=1) + with self.assertRaises(TypeError): + isinstance({}, Emp) + with self.assertRaises(TypeError): + isinstance(jim, Emp) + with self.assertRaises(TypeError): + issubclass(dict, Emp) + with self.assertRaises(TypeError): + TypedDict('Hi', x=1) + with self.assertRaises(TypeError): + TypedDict('Hi', [('x', int), ('y', 1)]) + with self.assertRaises(TypeError): + TypedDict('Hi', [('x', int)], y=int) + + def test_py36_class_syntax_usage(self): + self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D') + self.assertEqual(LabelPoint2D.__module__, __name__) + self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str}) + self.assertEqual(LabelPoint2D.__bases__, (dict,)) + self.assertEqual(LabelPoint2D.__total__, True) + self.assertNotIsSubclass(LabelPoint2D, typing.Sequence) + not_origin = Point2D(x=0, y=1) + self.assertEqual(not_origin['x'], 0) + self.assertEqual(not_origin['y'], 1) + other = LabelPoint2D(x=0, y=1, label='hi') + self.assertEqual(other['label'], 'hi') + + def test_pickle(self): + global EmpD # pickle wants to reference the class by name + EmpD = TypedDict('EmpD', name=str, id=int) + jane = EmpD({'name': 'jane', 'id': 37}) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(jane, proto) + jane2 = pickle.loads(z) + self.assertEqual(jane2, jane) + self.assertEqual(jane2, {'name': 'jane', 'id': 37}) + ZZ = pickle.dumps(EmpD, proto) + EmpDnew = pickle.loads(ZZ) + self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane) + + def test_optional(self): + EmpD = TypedDict('EmpD', name=str, id=int) + + self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD]) + self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD]) + + def test_total(self): + D = TypedDict('D', {'x': int}, total=False) + self.assertEqual(D(), {}) + self.assertEqual(D(x=1), {'x': 1}) + self.assertEqual(D.__total__, False) + + self.assertEqual(Options(), {}) + self.assertEqual(Options(log_level=2), {'log_level': 2}) + self.assertEqual(Options.__total__, False) + + class IOTests(BaseTestCase): def test_io(self): diff --git a/Lib/typing.py b/Lib/typing.py index 1044cc409f410a..d3e84cd64abe8c 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -89,6 +89,7 @@ 'Set', 'FrozenSet', 'NamedTuple', # Not really a type. + 'TypedDict', # Not really a type. 'Generator', # One-off things. @@ -1490,6 +1491,89 @@ def __new__(self, typename, fields=None, **kwargs): return _make_nmtuple(typename, fields) +def _dict_new(cls, *args, **kwargs): + return dict(*args, **kwargs) + + +def _typeddict_new(cls, _typename, _fields=None, **kwargs): + total = kwargs.pop('total', True) + if _fields is None: + _fields = kwargs + elif kwargs: + raise TypeError("TypedDict takes either a dict or keyword arguments," + " but not both") + + ns = {'__annotations__': dict(_fields), '__total__': total} + try: + # Setting correct module is necessary to make typed dict classes pickleable. + ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass + + return _TypedDictMeta(_typename, (), ns) + + +def _check_fails(cls, other): + # Typed dicts are only for static structural subtyping. + raise TypeError('TypedDict does not support instance and class checks') + + +class _TypedDictMeta(type): + def __new__(cls, name, bases, ns, total=True): + """Create new typed dict class object. + + This method is called directly when TypedDict is subclassed, + or via _typeddict_new when TypedDict is instantiated. This way + TypedDict supports all three syntax forms described in its docstring. + Subclasses and instances of TypedDict return actual dictionaries + via _dict_new. + """ + ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new + tp_dict = super(_TypedDictMeta, cls).__new__(cls, name, (dict,), ns) + + anns = ns.get('__annotations__', {}) + msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" + anns = {n: _type_check(tp, msg) for n, tp in anns.items()} + for base in bases: + anns.update(base.__dict__.get('__annotations__', {})) + tp_dict.__annotations__ = anns + if not hasattr(tp_dict, '__total__'): + tp_dict.__total__ = total + return tp_dict + + __instancecheck__ = __subclasscheck__ = _check_fails + + +class TypedDict(dict, metaclass=_TypedDictMeta): + """A simple typed namespace. At runtime it is equivalent to a plain dict. + + TypedDict creates a dictionary type that expects all of its + instances to have a certain set of keys, where each key is + associated with a value of a consistent type. This expectation + is not checked at runtime but is only enforced by type checkers. + Usage:: + + class Point2D(TypedDict): + x: int + y: int + label: str + + a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK + b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check + + assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') + + The type info can be accessed via Point2D.__annotations__. TypedDict + supports two additional equivalent forms:: + + Point2D = TypedDict('Point2D', x=int, y=int, label=str) + Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) + + The class syntax is only supported in Python 3.6+, while two other + syntax forms work for Python 2.7 and 3.2+ + """ + + def NewType(name, tp): """NewType creates simple unique types with almost zero runtime overhead. NewType(name, tp) is considered a subtype of tp diff --git a/Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst b/Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst new file mode 100644 index 00000000000000..e0ce4a708d9eb7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst @@ -0,0 +1 @@ +PEP 589: Add ``TypedDict`` to the ``typing`` module. \ No newline at end of file From 180dc1b0f4a57c3f66351568ae8488fa8576d7f0 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Sun, 26 May 2019 16:25:47 +0200 Subject: [PATCH 114/441] bpo-28866: No type cache for types with specialized mro, invalidation is hard. (#13157) * No type cache for types with specialized mro, invalidation is hard. * FIX: Don't disable method cache custom types that do not implement mro(). * fixing implem. * Avoid storing error flags, also decref. * news entry * Clear as soon as we're getting an error. * FIX: Reference leak. --- .../2019-05-08-16-36-51.bpo-28866.qCv_bj.rst | 2 + Objects/typeobject.c | 38 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst new file mode 100644 index 00000000000000..69017293649cd5 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst @@ -0,0 +1,2 @@ +Avoid caching attributes of classes which type defines mro() to avoid a hard +cache invalidation problem. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 339f7285292c53..fc809d36e10be0 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -78,6 +78,9 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static void clear_slotdefs(void); +static PyObject * +lookup_maybe_method(PyObject *self, _Py_Identifier *attrid, int *unbound); + /* * finds the beginning of the docstring's introspection signature. * if present, returns a pointer pointing to the first '('. @@ -287,17 +290,35 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type has a custom MRO that includes a type which is not officially - super type. + super type, or if the type implements its own mro() method. Called from mro_internal, which will subsequently be called on each subclass when their mro is recursively updated. */ Py_ssize_t i, n; - int clear = 0; + int custom = (Py_TYPE(type) != &PyType_Type); + int unbound; + PyObject *mro_meth = NULL; + PyObject *type_mro_meth = NULL; if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG)) return; + if (custom) { + _Py_IDENTIFIER(mro); + mro_meth = lookup_maybe_method( + (PyObject *)type, &PyId_mro, &unbound); + if (mro_meth == NULL) + goto clear; + type_mro_meth = lookup_maybe_method( + (PyObject *)&PyType_Type, &PyId_mro, &unbound); + if (type_mro_meth == NULL) + goto clear; + if (mro_meth != type_mro_meth) + goto clear; + Py_XDECREF(mro_meth); + Py_XDECREF(type_mro_meth); + } n = PyTuple_GET_SIZE(bases); for (i = 0; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); @@ -308,14 +329,15 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) || !PyType_IsSubtype(type, cls)) { - clear = 1; - break; + goto clear; } } - - if (clear) - type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG| - Py_TPFLAGS_VALID_VERSION_TAG); + return; + clear: + Py_XDECREF(mro_meth); + Py_XDECREF(type_mro_meth); + type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG| + Py_TPFLAGS_VALID_VERSION_TAG); } static int From 22ccb0b4902137275960c008ef77b88fa82729ce Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 26 May 2019 07:30:52 -0700 Subject: [PATCH 115/441] Fix highlighting in importlib.metadata docs (GH-13575) --- Doc/library/importlib.metadata.rst | 8 ++++---- Doc/tools/susp-ignored.csv | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 3d10b5aeabfdc0..2126498e728cfa 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -32,17 +32,17 @@ Overview Let's say you wanted to get the version string for a package you've installed using ``pip``. We start by creating a virtual environment and installing -something into it:: +something into it: -.. highlight:: none +.. code-block:: shell-session $ python3 -m venv example $ source example/bin/activate (example) $ pip install wheel -You can get the version string for ``wheel`` by running the following:: +You can get the version string for ``wheel`` by running the following: -.. highlight:: none +.. code-block:: pycon (example) $ python >>> from importlib.metadata import version # doctest: +SKIP diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 85ff9d02aeb2db..a34524bb673e89 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -350,6 +350,5 @@ whatsnew/3.7,,::,error::BytesWarning whatsnew/changelog,,::,error::BytesWarning whatsnew/changelog,,::,default::BytesWarning whatsnew/changelog,,::,default::DeprecationWarning -library/importlib.metadata,,.. highlight:,.. highlight:: none library/importlib.metadata,,:main,"EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')" library/importlib.metadata,,`,of directories ``path`` (defaults to sys.path). From 91f4380cedbae32b49adbea2518014a5624c6523 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 26 May 2019 17:10:09 +0200 Subject: [PATCH 116/441] bpo-36785: PEP 574 implementation (GH-7076) --- Doc/library/pickle.rst | 271 ++++++++-- Include/Python.h | 1 + Include/picklebufobject.h | 31 ++ Lib/pickle.py | 152 +++++- Lib/pickletools.py | 80 ++- Lib/test/pickletester.py | 423 ++++++++++++++- Lib/test/test_inspect.py | 11 +- Lib/test/test_pickle.py | 12 +- Lib/test/test_picklebuffer.py | 154 ++++++ Lib/test/test_pickletools.py | 17 +- Lib/test/test_pyclbr.py | 2 +- Makefile.pre.in | 4 +- .../2019-05-03-20-47-55.bpo-36785.PQLnPq.rst | 1 + Modules/_pickle.c | 511 ++++++++++++++++-- Modules/clinic/_pickle.c.h | 228 +++++--- Objects/object.c | 1 + Objects/picklebufobject.c | 219 ++++++++ PCbuild/pythoncore.vcxproj | 2 + PCbuild/pythoncore.vcxproj.filters | 6 + 19 files changed, 1886 insertions(+), 240 deletions(-) create mode 100644 Include/picklebufobject.h create mode 100644 Lib/test/test_picklebuffer.py create mode 100644 Misc/NEWS.d/next/Library/2019-05-03-20-47-55.bpo-36785.PQLnPq.rst create mode 100644 Objects/picklebufobject.c diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index f4c41ac68d2f79..6aa30492c7060c 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -195,34 +195,29 @@ The :mod:`pickle` module provides the following constants: The :mod:`pickle` module provides the following functions to make the pickling process more convenient: -.. function:: dump(obj, file, protocol=None, \*, fix_imports=True) +.. function:: dump(obj, file, protocol=None, \*, fix_imports=True, buffer_callback=None) Write a pickled representation of *obj* to the open :term:`file object` *file*. This is equivalent to ``Pickler(file, protocol).dump(obj)``. - The optional *protocol* argument, an integer, tells the pickler to use - the given protocol; supported protocols are 0 to :data:`HIGHEST_PROTOCOL`. - If not specified, the default is :data:`DEFAULT_PROTOCOL`. If a negative - number is specified, :data:`HIGHEST_PROTOCOL` is selected. + Arguments *file*, *protocol*, *fix_imports* and *buffer_callback* have + the same meaning as in the :class:`Pickler` constructor. - The *file* argument must have a write() method that accepts a single bytes - argument. It can thus be an on-disk file opened for binary writing, an - :class:`io.BytesIO` instance, or any other custom object that meets this - interface. - - If *fix_imports* is true and *protocol* is less than 3, pickle will try to - map the new Python 3 names to the old module names used in Python 2, so - that the pickle data stream is readable with Python 2. + .. versionchanged:: 3.8 + The *buffer_callback* argument was added. -.. function:: dumps(obj, protocol=None, \*, fix_imports=True) +.. function:: dumps(obj, protocol=None, \*, fix_imports=True, buffer_callback=None) Return the pickled representation of the object as a :class:`bytes` object, instead of writing it to a file. - Arguments *protocol* and *fix_imports* have the same meaning as in - :func:`dump`. + Arguments *protocol*, *fix_imports* and *buffer_callback* have the same + meaning as in the :class:`Pickler` constructor. + + .. versionchanged:: 3.8 + The *buffer_callback* argument was added. -.. function:: load(file, \*, fix_imports=True, encoding="ASCII", errors="strict") +.. function:: load(file, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None) Read a pickled object representation from the open :term:`file object` *file* and return the reconstituted object hierarchy specified therein. @@ -232,24 +227,13 @@ process more convenient: protocol argument is needed. Bytes past the pickled object's representation are ignored. - The argument *file* must have two methods, a read() method that takes an - integer argument, and a readline() method that requires no arguments. Both - methods should return bytes. Thus *file* can be an on-disk file opened for - binary reading, an :class:`io.BytesIO` object, or any other custom object - that meets this interface. - - Optional keyword arguments are *fix_imports*, *encoding* and *errors*, - which are used to control compatibility support for pickle stream generated - by Python 2. If *fix_imports* is true, pickle will try to map the old - Python 2 names to the new names used in Python 3. The *encoding* and - *errors* tell pickle how to decode 8-bit string instances pickled by Python - 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can - be 'bytes' to read these 8-bit string instances as bytes objects. - Using ``encoding='latin1'`` is required for unpickling NumPy arrays and - instances of :class:`~datetime.datetime`, :class:`~datetime.date` and - :class:`~datetime.time` pickled by Python 2. + Arguments *file*, *fix_imports*, *encoding*, *errors*, *strict* and *buffers* + have the same meaning as in the :class:`Unpickler` constructor. -.. function:: loads(bytes_object, \*, fix_imports=True, encoding="ASCII", errors="strict") + .. versionchanged:: 3.8 + The *buffers* argument was added. + +.. function:: loads(bytes_object, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None) Read a pickled object hierarchy from a :class:`bytes` object and return the reconstituted object hierarchy specified therein. @@ -258,16 +242,11 @@ process more convenient: protocol argument is needed. Bytes past the pickled object's representation are ignored. - Optional keyword arguments are *fix_imports*, *encoding* and *errors*, - which are used to control compatibility support for pickle stream generated - by Python 2. If *fix_imports* is true, pickle will try to map the old - Python 2 names to the new names used in Python 3. The *encoding* and - *errors* tell pickle how to decode 8-bit string instances pickled by Python - 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can - be 'bytes' to read these 8-bit string instances as bytes objects. - Using ``encoding='latin1'`` is required for unpickling NumPy arrays and - instances of :class:`~datetime.datetime`, :class:`~datetime.date` and - :class:`~datetime.time` pickled by Python 2. + Arguments *file*, *fix_imports*, *encoding*, *errors*, *strict* and *buffers* + have the same meaning as in the :class:`Unpickler` constructor. + + .. versionchanged:: 3.8 + The *buffers* argument was added. The :mod:`pickle` module defines three exceptions: @@ -295,10 +274,10 @@ The :mod:`pickle` module defines three exceptions: IndexError. -The :mod:`pickle` module exports two classes, :class:`Pickler` and -:class:`Unpickler`: +The :mod:`pickle` module exports three classes, :class:`Pickler`, +:class:`Unpickler` and :class:`PickleBuffer`: -.. class:: Pickler(file, protocol=None, \*, fix_imports=True) +.. class:: Pickler(file, protocol=None, \*, fix_imports=True, buffer_callback=None) This takes a binary file for writing a pickle data stream. @@ -316,6 +295,20 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. + If *buffer_callback* is None (the default), buffer views are + serialized into *file* as part of the pickle stream. + + If *buffer_callback* is not None, then it can be called any number + of times with a buffer view. If the callback returns a false value + (such as None), the given buffer is :ref:`out-of-band `; + otherwise the buffer is serialized in-band, i.e. inside the pickle stream. + + It is an error if *buffer_callback* is not None and *protocol* is + None or smaller than 5. + + .. versionchanged:: 3.8 + The *buffer_callback* argument was added. + .. method:: dump(obj) Write a pickled representation of *obj* to the open file object given in @@ -379,26 +372,43 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and Use :func:`pickletools.optimize` if you need more compact pickles. -.. class:: Unpickler(file, \*, fix_imports=True, encoding="ASCII", errors="strict") +.. class:: Unpickler(file, \*, fix_imports=True, encoding="ASCII", errors="strict", buffers=None) This takes a binary file for reading a pickle data stream. The protocol version of the pickle is detected automatically, so no protocol argument is needed. - The argument *file* must have two methods, a read() method that takes an - integer argument, and a readline() method that requires no arguments. Both - methods should return bytes. Thus *file* can be an on-disk file object + The argument *file* must have three methods, a read() method that takes an + integer argument, a readinto() method that takes a buffer argument + and a readline() method that requires no arguments, as in the + :class:`io.BufferedIOBase` interface. Thus *file* can be an on-disk file opened for binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. - Optional keyword arguments are *fix_imports*, *encoding* and *errors*, - which are used to control compatibility support for pickle stream generated - by Python 2. If *fix_imports* is true, pickle will try to map the old - Python 2 names to the new names used in Python 3. The *encoding* and - *errors* tell pickle how to decode 8-bit string instances pickled by Python - 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can + The optional arguments *fix_imports*, *encoding* and *errors* are used + to control compatibility support for pickle stream generated by Python 2. + If *fix_imports* is true, pickle will try to map the old Python 2 names + to the new names used in Python 3. The *encoding* and *errors* tell + pickle how to decode 8-bit string instances pickled by Python 2; + these default to 'ASCII' and 'strict', respectively. The *encoding* can be 'bytes' to read these 8-bit string instances as bytes objects. + Using ``encoding='latin1'`` is required for unpickling NumPy arrays and + instances of :class:`~datetime.datetime`, :class:`~datetime.date` and + :class:`~datetime.time` pickled by Python 2. + + If *buffers* is None (the default), then all data necessary for + deserialization must be contained in the pickle stream. This means + that the *buffer_callback* argument was None when a :class:`Pickler` + was instantiated (or when :func:`dump` or :func:`dumps` was called). + + If *buffers* is not None, it should be an iterable of buffer-enabled + objects that is consumed each time the pickle stream references + an :ref:`out-of-band ` buffer view. Such buffers have been + given in order to the *buffer_callback* of a Pickler object. + + .. versionchanged:: 3.8 + The *buffers* argument was added. .. method:: load() @@ -429,6 +439,34 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and .. audit-event:: pickle.find_class "module name" +.. class:: PickleBuffer(buffer) + + A wrapper for a buffer representing picklable data. *buffer* must be a + :ref:`buffer-providing ` object, such as a + :term:`bytes-like object` or a N-dimensional array. + + :class:`PickleBuffer` is itself a buffer provider, therefore it is + possible to pass it to other APIs expecting a buffer-providing object, + such as :class:`memoryview`. + + :class:`PickleBuffer` objects can only be serialized using pickle + protocol 5 or higher. They are eligible for + :ref:`out-of-band serialization `. + + .. versionadded:: 3.8 + + .. method:: raw() + + Return a :class:`memoryview` of the memory area underlying this buffer. + The returned object is a one-dimensional, C-contiguous memoryview + with format ``B`` (unsigned bytes). :exc:`BufferError` is raised if + the buffer is neither C- nor Fortran-contiguous. + + .. method:: release() + + Release the underlying buffer exposed by the PickleBuffer object. + + .. _pickle-picklable: What can be pickled and unpickled? @@ -864,6 +902,125 @@ a given class:: assert unpickled_class.my_attribute == 1 +.. _pickle-oob: + +Out-of-band Buffers +------------------- + +.. versionadded:: 3.8 + +In some contexts, the :mod:`pickle` module is used to transfer massive amounts +of data. Therefore, it can be important to minimize the number of memory +copies, to preserve performance and resource consumption. However, normal +operation of the :mod:`pickle` module, as it transforms a graph-like structure +of objects into a sequential stream of bytes, intrinsically involves copying +data to and from the pickle stream. + +This constraint can be eschewed if both the *provider* (the implementation +of the object types to be transferred) and the *consumer* (the implementation +of the communications system) support the out-of-band transfer facilities +provided by pickle protocol 5 and higher. + +Provider API +^^^^^^^^^^^^ + +The large data objects to be pickled must implement a :meth:`__reduce_ex__` +method specialized for protocol 5 and higher, which returns a +:class:`PickleBuffer` instance (instead of e.g. a :class:`bytes` object) +for any large data. + +A :class:`PickleBuffer` object *signals* that the underlying buffer is +eligible for out-of-band data transfer. Those objects remain compatible +with normal usage of the :mod:`pickle` module. However, consumers can also +opt-in to tell :mod:`pickle` that they will handle those buffers by +themselves. + +Consumer API +^^^^^^^^^^^^ + +A communications system can enable custom handling of the :class:`PickleBuffer` +objects generated when serializing an object graph. + +On the sending side, it needs to pass a *buffer_callback* argument to +:class:`Pickler` (or to the :func:`dump` or :func:`dumps` function), which +will be called with each :class:`PickleBuffer` generated while pickling +the object graph. Buffers accumulated by the *buffer_callback* will not +see their data copied into the pickle stream, only a cheap marker will be +inserted. + +On the receiving side, it needs to pass a *buffers* argument to +:class:`Unpickler` (or to the :func:`load` or :func:`loads` function), +which is an iterable of the buffers which were passed to *buffer_callback*. +That iterable should produce buffers in the same order as they were passed +to *buffer_callback*. Those buffers will provide the data expected by the +reconstructors of the objects whose pickling produced the original +:class:`PickleBuffer` objects. + +Between the sending side and the receiving side, the communications system +is free to implement its own transfer mechanism for out-of-band buffers. +Potential optimizations include the use of shared memory or datatype-dependent +compression. + +Example +^^^^^^^ + +Here is a trivial example where we implement a :class:`bytearray` subclass +able to participate in out-of-band buffer pickling:: + + class ZeroCopyByteArray(bytearray): + + def __reduce_ex__(self, protocol): + if protocol >= 5: + return type(self)._reconstruct, (PickleBuffer(self),), None + else: + # PickleBuffer is forbidden with pickle protocols <= 4. + return type(self)._reconstruct, (bytearray(self),) + + @classmethod + def _reconstruct(cls, obj): + with memoryview(obj) as m: + # Get a handle over the original buffer object + obj = m.obj + if type(obj) is cls: + # Original buffer object is a ZeroCopyByteArray, return it + # as-is. + return obj + else: + return cls(obj) + +The reconstructor (the ``_reconstruct`` class method) returns the buffer's +providing object if it has the right type. This is an easy way to simulate +zero-copy behaviour on this toy example. + +On the consumer side, we can pickle those objects the usual way, which +when unserialized will give us a copy of the original object:: + + b = ZeroCopyByteArray(b"abc") + data = pickle.dumps(b, protocol=5) + new_b = pickle.loads(data) + print(b == new_b) # True + print(b is new_b) # False: a copy was made + +But if we pass a *buffer_callback* and then give back the accumulated +buffers when unserializing, we are able to get back the original object:: + + b = ZeroCopyByteArray(b"abc") + buffers = [] + data = pickle.dumps(b, protocol=5, buffer_callback=buffers.append) + new_b = pickle.loads(data, buffers=buffers) + print(b == new_b) # True + print(b is new_b) # True: no copy was made + +This example is limited by the fact that :class:`bytearray` allocates its +own memory: you cannot create a :class:`bytearray` instance that is backed +by another object's memory. However, third-party datatypes such as NumPy +arrays do not have this limitation, and allow use of zero-copy pickling +(or making as few copies as possible) when transferring between distinct +processes or systems. + +.. seealso:: :pep:`574` -- Pickle protocol 5 with out-of-band data + + .. _pickle-restrict: Restricting Globals diff --git a/Include/Python.h b/Include/Python.h index 55b06aeea9846f..17ad5b3071d405 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -124,6 +124,7 @@ #include "weakrefobject.h" #include "structseq.h" #include "namespaceobject.h" +#include "picklebufobject.h" #include "codecs.h" #include "pyerrors.h" diff --git a/Include/picklebufobject.h b/Include/picklebufobject.h new file mode 100644 index 00000000000000..f07e900bf26dac --- /dev/null +++ b/Include/picklebufobject.h @@ -0,0 +1,31 @@ +/* PickleBuffer object. This is built-in for ease of use from third-party + * C extensions. + */ + +#ifndef Py_PICKLEBUFOBJECT_H +#define Py_PICKLEBUFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API + +PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type; + +#define PyPickleBuffer_Check(op) (Py_TYPE(op) == &PyPickleBuffer_Type) + +/* Create a PickleBuffer redirecting to the given buffer-enabled object */ +PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *); +/* Get the PickleBuffer's underlying view to the original object + * (NULL if released) + */ +PyAPI_FUNC(const Py_buffer *) PyPickleBuffer_GetBuffer(PyObject *); +/* Release the PickleBuffer. Returns 0 on success, -1 on error. */ +PyAPI_FUNC(int) PyPickleBuffer_Release(PyObject *); + +#endif /* !Py_LIMITED_API */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PICKLEBUFOBJECT_H */ diff --git a/Lib/pickle.py b/Lib/pickle.py index be8e3811947b74..cb768b28586a1d 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -36,8 +36,10 @@ import codecs import _compat_pickle +from _pickle import PickleBuffer + __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", - "Unpickler", "dump", "dumps", "load", "loads"] + "Unpickler", "dump", "dumps", "load", "loads", "PickleBuffer"] # Shortcut for use in isinstance testing bytes_types = (bytes, bytearray) @@ -51,10 +53,11 @@ "2.0", # Protocol 2 "3.0", # Protocol 3 "4.0", # Protocol 4 + "5.0", # Protocol 5 ] # Old format versions we can read # This is the highest protocol number we know how to read. -HIGHEST_PROTOCOL = 4 +HIGHEST_PROTOCOL = 5 # The protocol we write by default. May be less than HIGHEST_PROTOCOL. # Only bump this if the oldest still supported version of Python already @@ -167,6 +170,7 @@ def __init__(self, value): SHORT_BINBYTES = b'C' # " " ; " " " " < 256 bytes # Protocol 4 + SHORT_BINUNICODE = b'\x8c' # push short string; UTF-8 length < 256 bytes BINUNICODE8 = b'\x8d' # push very long string BINBYTES8 = b'\x8e' # push very long bytes string @@ -178,6 +182,12 @@ def __init__(self, value): MEMOIZE = b'\x94' # store top of the stack in memo FRAME = b'\x95' # indicate the beginning of a new frame +# Protocol 5 + +BYTEARRAY8 = b'\x96' # push bytearray +NEXT_BUFFER = b'\x97' # push next out-of-band buffer +READONLY_BUFFER = b'\x98' # make top of stack readonly + __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$", x)]) @@ -251,6 +261,23 @@ def __init__(self, file_read, file_readline, file_tell=None): self.file_readline = file_readline self.current_frame = None + def readinto(self, buf): + if self.current_frame: + n = self.current_frame.readinto(buf) + if n == 0 and len(buf) != 0: + self.current_frame = None + n = len(buf) + buf[:] = self.file_read(n) + return n + if n < len(buf): + raise UnpicklingError( + "pickle exhausted before end of frame") + return n + else: + n = len(buf) + buf[:] = self.file_read(n) + return n + def read(self, n): if self.current_frame: data = self.current_frame.read(n) @@ -371,7 +398,8 @@ def decode_long(data): class _Pickler: - def __init__(self, file, protocol=None, *, fix_imports=True): + def __init__(self, file, protocol=None, *, fix_imports=True, + buffer_callback=None): """This takes a binary file for writing a pickle data stream. The optional *protocol* argument tells the pickler to use the @@ -393,6 +421,17 @@ def __init__(self, file, protocol=None, *, fix_imports=True): will try to map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. + + If *buffer_callback* is None (the default), buffer views are + serialized into *file* as part of the pickle stream. + + If *buffer_callback* is not None, then it can be called any number + of times with a buffer view. If the callback returns a false value + (such as None), the given buffer is out-of-band; otherwise the + buffer is serialized in-band, i.e. inside the pickle stream. + + It is an error if *buffer_callback* is not None and *protocol* + is None or smaller than 5. """ if protocol is None: protocol = DEFAULT_PROTOCOL @@ -400,6 +439,9 @@ def __init__(self, file, protocol=None, *, fix_imports=True): protocol = HIGHEST_PROTOCOL elif not 0 <= protocol <= HIGHEST_PROTOCOL: raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL) + if buffer_callback is not None and protocol < 5: + raise ValueError("buffer_callback needs protocol >= 5") + self._buffer_callback = buffer_callback try: self._file_write = file.write except AttributeError: @@ -756,6 +798,46 @@ def save_bytes(self, obj): self.memoize(obj) dispatch[bytes] = save_bytes + def save_bytearray(self, obj): + if self.proto < 5: + if not obj: # bytearray is empty + self.save_reduce(bytearray, (), obj=obj) + else: + self.save_reduce(bytearray, (bytes(obj),), obj=obj) + return + n = len(obj) + if n >= self.framer._FRAME_SIZE_TARGET: + self._write_large_bytes(BYTEARRAY8 + pack("= 5") + with obj.raw() as m: + if not m.contiguous: + raise PicklingError("PickleBuffer can not be pickled when " + "pointing to a non-contiguous buffer") + in_band = True + if self._buffer_callback is not None: + in_band = bool(self._buffer_callback(obj)) + if in_band: + # Write data in-band + # XXX The C implementation avoids a copy here + if m.readonly: + self.save_bytes(m.tobytes()) + else: + self.save_bytearray(m.tobytes()) + else: + # Write data out-of-band + self.write(NEXT_BUFFER) + if m.readonly: + self.write(READONLY_BUFFER) + + dispatch[PickleBuffer] = save_picklebuffer + def save_str(self, obj): if self.bin: encoded = obj.encode('utf-8', 'surrogatepass') @@ -1042,7 +1124,7 @@ def save_type(self, obj): class _Unpickler: def __init__(self, file, *, fix_imports=True, - encoding="ASCII", errors="strict"): + encoding="ASCII", errors="strict", buffers=None): """This takes a binary file for reading a pickle data stream. The protocol version of the pickle is detected automatically, so @@ -1061,7 +1143,17 @@ def __init__(self, file, *, fix_imports=True, reading, a BytesIO object, or any other custom object that meets this interface. - Optional keyword arguments are *fix_imports*, *encoding* and + If *buffers* is not None, it should be an iterable of buffer-enabled + objects that is consumed each time the pickle stream references + an out-of-band buffer view. Such buffers have been given in order + to the *buffer_callback* of a Pickler object. + + If *buffers* is None (the default), then the buffers are taken + from the pickle stream, assuming they are serialized there. + It is an error for *buffers* to be None if the pickle stream + was produced with a non-None *buffer_callback*. + + Other optional arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatibility support for pickle stream generated by Python 2. If *fix_imports* is True, pickle will try to map the old Python 2 names to the new names @@ -1070,6 +1162,7 @@ def __init__(self, file, *, fix_imports=True, default to 'ASCII' and 'strict', respectively. *encoding* can be 'bytes' to read theses 8-bit string instances as bytes objects. """ + self._buffers = iter(buffers) if buffers is not None else None self._file_readline = file.readline self._file_read = file.read self.memo = {} @@ -1090,6 +1183,7 @@ def load(self): "%s.__init__()" % (self.__class__.__name__,)) self._unframer = _Unframer(self._file_read, self._file_readline) self.read = self._unframer.read + self.readinto = self._unframer.readinto self.readline = self._unframer.readline self.metastack = [] self.stack = [] @@ -1276,6 +1370,34 @@ def load_binbytes8(self): self.append(self.read(len)) dispatch[BINBYTES8[0]] = load_binbytes8 + def load_bytearray8(self): + len, = unpack(' maxsize: + raise UnpicklingError("BYTEARRAY8 exceeds system's maximum size " + "of %d bytes" % maxsize) + b = bytearray(len) + self.readinto(b) + self.append(b) + dispatch[BYTEARRAY8[0]] = load_bytearray8 + + def load_next_buffer(self): + if self._buffers is None: + raise UnpicklingError("pickle stream refers to out-of-band data " + "but no *buffers* argument was given") + try: + buf = next(self._buffers) + except StopIteration: + raise UnpicklingError("not enough out-of-band buffers") + self.append(buf) + dispatch[NEXT_BUFFER[0]] = load_next_buffer + + def load_readonly_buffer(self): + buf = self.stack[-1] + with memoryview(buf) as m: + if not m.readonly: + self.stack[-1] = m.toreadonly() + dispatch[READONLY_BUFFER[0]] = load_readonly_buffer + def load_short_binstring(self): len = self.read(1)[0] data = self.read(len) @@ -1600,25 +1722,29 @@ def load_stop(self): # Shorthands -def _dump(obj, file, protocol=None, *, fix_imports=True): - _Pickler(file, protocol, fix_imports=fix_imports).dump(obj) +def _dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None): + _Pickler(file, protocol, fix_imports=fix_imports, + buffer_callback=buffer_callback).dump(obj) -def _dumps(obj, protocol=None, *, fix_imports=True): +def _dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None): f = io.BytesIO() - _Pickler(f, protocol, fix_imports=fix_imports).dump(obj) + _Pickler(f, protocol, fix_imports=fix_imports, + buffer_callback=buffer_callback).dump(obj) res = f.getvalue() assert isinstance(res, bytes_types) return res -def _load(file, *, fix_imports=True, encoding="ASCII", errors="strict"): - return _Unpickler(file, fix_imports=fix_imports, +def _load(file, *, fix_imports=True, encoding="ASCII", errors="strict", + buffers=None): + return _Unpickler(file, fix_imports=fix_imports, buffers=buffers, encoding=encoding, errors=errors).load() -def _loads(s, *, fix_imports=True, encoding="ASCII", errors="strict"): +def _loads(s, *, fix_imports=True, encoding="ASCII", errors="strict", + buffers=None): if isinstance(s, str): raise TypeError("Can't load pickle from unicode string") file = io.BytesIO(s) - return _Unpickler(file, fix_imports=fix_imports, + return _Unpickler(file, fix_imports=fix_imports, buffers=buffers, encoding=encoding, errors=errors).load() # Use the faster _pickle if possible diff --git a/Lib/pickletools.py b/Lib/pickletools.py index ed8bee36e8c586..95706e746c9870 100644 --- a/Lib/pickletools.py +++ b/Lib/pickletools.py @@ -565,6 +565,41 @@ def read_bytes8(f): the number of bytes, and the second argument is that many bytes. """) + +def read_bytearray8(f): + r""" + >>> import io, struct, sys + >>> read_bytearray8(io.BytesIO(b"\x00\x00\x00\x00\x00\x00\x00\x00abc")) + bytearray(b'') + >>> read_bytearray8(io.BytesIO(b"\x03\x00\x00\x00\x00\x00\x00\x00abcdef")) + bytearray(b'abc') + >>> bigsize8 = struct.pack(">> read_bytearray8(io.BytesIO(bigsize8 + b"abcdef")) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + ValueError: expected ... bytes in a bytearray8, but only 6 remain + """ + + n = read_uint8(f) + assert n >= 0 + if n > sys.maxsize: + raise ValueError("bytearray8 byte count > sys.maxsize: %d" % n) + data = f.read(n) + if len(data) == n: + return bytearray(data) + raise ValueError("expected %d bytes in a bytearray8, but only %d remain" % + (n, len(data))) + +bytearray8 = ArgumentDescriptor( + name="bytearray8", + n=TAKEN_FROM_ARGUMENT8U, + reader=read_bytearray8, + doc="""A counted bytearray. + + The first argument is an 8-byte little-endian unsigned int giving + the number of bytes, and the second argument is that many bytes. + """) + def read_unicodestringnl(f): r""" >>> import io @@ -970,6 +1005,11 @@ def __repr__(self): obtype=bytes, doc="A Python bytes object.") +pybytearray = StackObject( + name='bytearray', + obtype=bytearray, + doc="A Python bytearray object.") + pyunicode = StackObject( name='str', obtype=str, @@ -1005,6 +1045,11 @@ def __repr__(self): obtype=set, doc="A Python frozenset object.") +pybuffer = StackObject( + name='buffer', + obtype=object, + doc="A Python buffer-like object.") + anyobject = StackObject( name='any', obtype=object, @@ -1265,7 +1310,7 @@ def __init__(self, name, code, arg, object instead. """), - # Bytes (protocol 3 only; older protocols don't support bytes at all) + # Bytes (protocol 3 and higher) I(name='BINBYTES', code='B', @@ -1306,6 +1351,39 @@ def __init__(self, name, code, arg, which are taken literally as the string content. """), + # Bytearray (protocol 5 and higher) + + I(name='BYTEARRAY8', + code='\x96', + arg=bytearray8, + stack_before=[], + stack_after=[pybytearray], + proto=5, + doc="""Push a Python bytearray object. + + There are two arguments: the first is an 8-byte unsigned int giving + the number of bytes in the bytearray, and the second is that many bytes, + which are taken literally as the bytearray content. + """), + + # Out-of-band buffer (protocol 5 and higher) + + I(name='NEXT_BUFFER', + code='\x97', + arg=None, + stack_before=[], + stack_after=[pybuffer], + proto=5, + doc="Push an out-of-band buffer object."), + + I(name='READONLY_BUFFER', + code='\x98', + arg=None, + stack_before=[pybuffer], + stack_after=[pybuffer], + proto=5, + doc="Make an out-of-band buffer object read-only."), + # Ways to spell None. I(name='NONE', diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 4f8c2942df93dd..f6fda9ee6d8363 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -16,6 +16,16 @@ from textwrap import dedent from http.cookies import SimpleCookie +try: + import _testbuffer +except ImportError: + _testbuffer = None + +try: + import numpy as np +except ImportError: + np = None + from test import support from test.support import ( TestFailed, TESTFN, run_with_locale, no_tracing, @@ -162,6 +172,139 @@ def create_dynamic_class(name, bases): result.reduce_args = (name, bases) return result + +class ZeroCopyBytes(bytes): + readonly = True + c_contiguous = True + f_contiguous = True + zero_copy_reconstruct = True + + def __reduce_ex__(self, protocol): + if protocol >= 5: + return type(self)._reconstruct, (pickle.PickleBuffer(self),), None + else: + return type(self)._reconstruct, (bytes(self),) + + def __repr__(self): + return "{}({!r})".format(self.__class__.__name__, bytes(self)) + + __str__ = __repr__ + + @classmethod + def _reconstruct(cls, obj): + with memoryview(obj) as m: + obj = m.obj + if type(obj) is cls: + # Zero-copy + return obj + else: + return cls(obj) + + +class ZeroCopyBytearray(bytearray): + readonly = False + c_contiguous = True + f_contiguous = True + zero_copy_reconstruct = True + + def __reduce_ex__(self, protocol): + if protocol >= 5: + return type(self)._reconstruct, (pickle.PickleBuffer(self),), None + else: + return type(self)._reconstruct, (bytes(self),) + + def __repr__(self): + return "{}({!r})".format(self.__class__.__name__, bytes(self)) + + __str__ = __repr__ + + @classmethod + def _reconstruct(cls, obj): + with memoryview(obj) as m: + obj = m.obj + if type(obj) is cls: + # Zero-copy + return obj + else: + return cls(obj) + + +if _testbuffer is not None: + + class PicklableNDArray: + # A not-really-zero-copy picklable ndarray, as the ndarray() + # constructor doesn't allow for it + + zero_copy_reconstruct = False + + def __init__(self, *args, **kwargs): + self.array = _testbuffer.ndarray(*args, **kwargs) + + def __getitem__(self, idx): + cls = type(self) + new = cls.__new__(cls) + new.array = self.array[idx] + return new + + @property + def readonly(self): + return self.array.readonly + + @property + def c_contiguous(self): + return self.array.c_contiguous + + @property + def f_contiguous(self): + return self.array.f_contiguous + + def __eq__(self, other): + if not isinstance(other, PicklableNDArray): + return NotImplemented + return (other.array.format == self.array.format and + other.array.shape == self.array.shape and + other.array.strides == self.array.strides and + other.array.readonly == self.array.readonly and + other.array.tobytes() == self.array.tobytes()) + + def __ne__(self, other): + if not isinstance(other, PicklableNDArray): + return NotImplemented + return not (self == other) + + def __repr__(self): + return (f"{type(self)}(shape={self.array.shape}," + f"strides={self.array.strides}, " + f"bytes={self.array.tobytes()})") + + def __reduce_ex__(self, protocol): + if not self.array.contiguous: + raise NotImplementedError("Reconstructing a non-contiguous " + "ndarray does not seem possible") + ndarray_kwargs = {"shape": self.array.shape, + "strides": self.array.strides, + "format": self.array.format, + "flags": (0 if self.readonly + else _testbuffer.ND_WRITABLE)} + pb = pickle.PickleBuffer(self.array) + if protocol >= 5: + return (type(self)._reconstruct, + (pb, ndarray_kwargs)) + else: + # Need to serialize the bytes in physical order + with pb.raw() as m: + return (type(self)._reconstruct, + (m.tobytes(), ndarray_kwargs)) + + @classmethod + def _reconstruct(cls, obj, kwargs): + with memoryview(obj) as m: + # For some reason, ndarray() wants a list of integers... + # XXX This only works if format == 'B' + items = list(m.tobytes()) + return cls(items, **kwargs) + + # DATA0 .. DATA4 are the pickles we expect under the various protocols, for # the object returned by create_data(). @@ -888,12 +1031,22 @@ def test_binunicode8(self): dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.' self.assertEqual(self.loads(dumped), '\u20ac\x00') + def test_bytearray8(self): + dumped = b'\x80\x05\x96\x03\x00\x00\x00\x00\x00\x00\x00xxx.' + self.assertEqual(self.loads(dumped), bytearray(b'xxx')) + @requires_32b def test_large_32b_binbytes8(self): dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' self.check_unpickling_error((pickle.UnpicklingError, OverflowError), dumped) + @requires_32b + def test_large_32b_bytearray8(self): + dumped = b'\x80\x05\x96\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) + @requires_32b def test_large_32b_binunicode8(self): dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' @@ -1171,6 +1324,10 @@ def test_truncated_data(self): b'\x8e\x03\x00\x00\x00\x00\x00\x00', b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00', b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab', + b'\x96', # BYTEARRAY8 + b'\x96\x03\x00\x00\x00\x00\x00\x00', + b'\x96\x03\x00\x00\x00\x00\x00\x00\x00', + b'\x96\x03\x00\x00\x00\x00\x00\x00\x00ab', b'\x95', # FRAME b'\x95\x02\x00\x00\x00\x00\x00\x00', b'\x95\x02\x00\x00\x00\x00\x00\x00\x00', @@ -1482,6 +1639,25 @@ def test_bytes(self): p = self.dumps(s, proto) self.assert_is_copy(s, self.loads(p)) + def test_bytearray(self): + for proto in protocols: + for s in b'', b'xyz', b'xyz'*100: + b = bytearray(s) + p = self.dumps(b, proto) + bb = self.loads(p) + self.assertIsNot(bb, b) + self.assert_is_copy(b, bb) + if proto <= 3: + # bytearray is serialized using a global reference + self.assertIn(b'bytearray', p) + self.assertTrue(opcode_in_pickle(pickle.GLOBAL, p)) + elif proto == 4: + self.assertIn(b'bytearray', p) + self.assertTrue(opcode_in_pickle(pickle.STACK_GLOBAL, p)) + elif proto == 5: + self.assertNotIn(b'bytearray', p) + self.assertTrue(opcode_in_pickle(pickle.BYTEARRAY8, p)) + def test_ints(self): for proto in protocols: n = sys.maxsize @@ -2114,7 +2290,8 @@ def check_frame_opcodes(self, pickled): the following consistency check. """ frame_end = frameless_start = None - frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8', 'BINUNICODE8'} + frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8', + 'BINUNICODE8', 'BYTEARRAY8'} for op, arg, pos in pickletools.genops(pickled): if frame_end is not None: self.assertLessEqual(pos, frame_end) @@ -2225,19 +2402,20 @@ def remove_frames(pickled, keep_frame=None): num_frames = 20 # Large byte objects (dict values) intermittent with small objects # (dict keys) - obj = {i: bytes([i]) * frame_size for i in range(num_frames)} + for bytes_type in (bytes, bytearray): + obj = {i: bytes_type([i]) * frame_size for i in range(num_frames)} - for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): - pickled = self.dumps(obj, proto) + for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): + pickled = self.dumps(obj, proto) - frameless_pickle = remove_frames(pickled) - self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0) - self.assertEqual(obj, self.loads(frameless_pickle)) + frameless_pickle = remove_frames(pickled) + self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0) + self.assertEqual(obj, self.loads(frameless_pickle)) - some_frames_pickle = remove_frames(pickled, lambda i: i % 2) - self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle), - count_opcode(pickle.FRAME, pickled)) - self.assertEqual(obj, self.loads(some_frames_pickle)) + some_frames_pickle = remove_frames(pickled, lambda i: i % 2) + self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle), + count_opcode(pickle.FRAME, pickled)) + self.assertEqual(obj, self.loads(some_frames_pickle)) def test_framed_write_sizes_with_delayed_writer(self): class ChunkAccumulator: @@ -2452,6 +2630,186 @@ def f(): with self.assertRaises((AttributeError, pickle.PicklingError)): pickletools.dis(self.dumps(f, proto)) + # + # PEP 574 tests below + # + + def buffer_like_objects(self): + # Yield buffer-like objects with the bytestring "abcdef" in them + bytestring = b"abcdefgh" + yield ZeroCopyBytes(bytestring) + yield ZeroCopyBytearray(bytestring) + if _testbuffer is not None: + items = list(bytestring) + value = int.from_bytes(bytestring, byteorder='little') + for flags in (0, _testbuffer.ND_WRITABLE): + # 1-D, contiguous + yield PicklableNDArray(items, format='B', shape=(8,), + flags=flags) + # 2-D, C-contiguous + yield PicklableNDArray(items, format='B', shape=(4, 2), + strides=(2, 1), flags=flags) + # 2-D, Fortran-contiguous + yield PicklableNDArray(items, format='B', + shape=(4, 2), strides=(1, 4), + flags=flags) + + def test_in_band_buffers(self): + # Test in-band buffers (PEP 574) + for obj in self.buffer_like_objects(): + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + data = self.dumps(obj, proto) + if obj.c_contiguous and proto >= 5: + # The raw memory bytes are serialized in physical order + self.assertIn(b"abcdefgh", data) + self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 0) + if proto >= 5: + self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data), + 1 if obj.readonly else 0) + self.assertEqual(count_opcode(pickle.BYTEARRAY8, data), + 0 if obj.readonly else 1) + # Return a true value from buffer_callback should have + # the same effect + def buffer_callback(obj): + return True + data2 = self.dumps(obj, proto, + buffer_callback=buffer_callback) + self.assertEqual(data2, data) + + new = self.loads(data) + # It's a copy + self.assertIsNot(new, obj) + self.assertIs(type(new), type(obj)) + self.assertEqual(new, obj) + + # XXX Unfortunately cannot test non-contiguous array + # (see comment in PicklableNDArray.__reduce_ex__) + + def test_oob_buffers(self): + # Test out-of-band buffers (PEP 574) + for obj in self.buffer_like_objects(): + for proto in range(0, 5): + # Need protocol >= 5 for buffer_callback + with self.assertRaises(ValueError): + self.dumps(obj, proto, + buffer_callback=[].append) + for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): + buffers = [] + buffer_callback = lambda pb: buffers.append(pb.raw()) + data = self.dumps(obj, proto, + buffer_callback=buffer_callback) + self.assertNotIn(b"abcdefgh", data) + self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data), 0) + self.assertEqual(count_opcode(pickle.BYTEARRAY8, data), 0) + self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 1) + self.assertEqual(count_opcode(pickle.READONLY_BUFFER, data), + 1 if obj.readonly else 0) + + if obj.c_contiguous: + self.assertEqual(bytes(buffers[0]), b"abcdefgh") + # Need buffers argument to unpickle properly + with self.assertRaises(pickle.UnpicklingError): + self.loads(data) + + new = self.loads(data, buffers=buffers) + if obj.zero_copy_reconstruct: + # Zero-copy achieved + self.assertIs(new, obj) + else: + self.assertIs(type(new), type(obj)) + self.assertEqual(new, obj) + # Non-sequence buffers accepted too + new = self.loads(data, buffers=iter(buffers)) + if obj.zero_copy_reconstruct: + # Zero-copy achieved + self.assertIs(new, obj) + else: + self.assertIs(type(new), type(obj)) + self.assertEqual(new, obj) + + def test_oob_buffers_writable_to_readonly(self): + # Test reconstructing readonly object from writable buffer + obj = ZeroCopyBytes(b"foobar") + for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): + buffers = [] + buffer_callback = buffers.append + data = self.dumps(obj, proto, buffer_callback=buffer_callback) + + buffers = map(bytearray, buffers) + new = self.loads(data, buffers=buffers) + self.assertIs(type(new), type(obj)) + self.assertEqual(new, obj) + + def test_picklebuffer_error(self): + # PickleBuffer forbidden with protocol < 5 + pb = pickle.PickleBuffer(b"foobar") + for proto in range(0, 5): + with self.assertRaises(pickle.PickleError): + self.dumps(pb, proto) + + def test_buffer_callback_error(self): + def buffer_callback(buffers): + 1/0 + pb = pickle.PickleBuffer(b"foobar") + with self.assertRaises(ZeroDivisionError): + self.dumps(pb, 5, buffer_callback=buffer_callback) + + def test_buffers_error(self): + pb = pickle.PickleBuffer(b"foobar") + for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): + data = self.dumps(pb, proto, buffer_callback=[].append) + # Non iterable buffers + with self.assertRaises(TypeError): + self.loads(data, buffers=object()) + # Buffer iterable exhausts too early + with self.assertRaises(pickle.UnpicklingError): + self.loads(data, buffers=[]) + + @unittest.skipIf(np is None, "Test needs Numpy") + def test_buffers_numpy(self): + def check_no_copy(x, y): + np.testing.assert_equal(x, y) + self.assertEqual(x.ctypes.data, y.ctypes.data) + + def check_copy(x, y): + np.testing.assert_equal(x, y) + self.assertNotEqual(x.ctypes.data, y.ctypes.data) + + def check_array(arr): + # In-band + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + data = self.dumps(arr, proto) + new = self.loads(data) + check_copy(arr, new) + for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): + buffer_callback = lambda _: True + data = self.dumps(arr, proto, buffer_callback=buffer_callback) + new = self.loads(data) + check_copy(arr, new) + # Out-of-band + for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): + buffers = [] + buffer_callback = buffers.append + data = self.dumps(arr, proto, buffer_callback=buffer_callback) + new = self.loads(data, buffers=buffers) + if arr.flags.c_contiguous or arr.flags.f_contiguous: + check_no_copy(arr, new) + else: + check_copy(arr, new) + + # 1-D + arr = np.arange(6) + check_array(arr) + # 1-D, non-contiguous + check_array(arr[::2]) + # 2-D, C-contiguous + arr = np.arange(12).reshape((3, 4)) + check_array(arr) + # 2-D, F-contiguous + check_array(arr.T) + # 2-D, non-contiguous + check_array(arr[::2]) + class BigmemPickleTests(unittest.TestCase): @@ -2736,7 +3094,7 @@ def test_load_from_and_dump_to_file(self): def test_highest_protocol(self): # Of course this needs to be changed when HIGHEST_PROTOCOL changes. - self.assertEqual(pickle.HIGHEST_PROTOCOL, 4) + self.assertEqual(pickle.HIGHEST_PROTOCOL, 5) def test_callapi(self): f = io.BytesIO() @@ -2760,6 +3118,47 @@ def __init__(self): pass self.assertRaises(pickle.PicklingError, BadPickler().dump, 0) self.assertRaises(pickle.UnpicklingError, BadUnpickler().load) + def check_dumps_loads_oob_buffers(self, dumps, loads): + # No need to do the full gamut of tests here, just enough to + # check that dumps() and loads() redirect their arguments + # to the underlying Pickler and Unpickler, respectively. + obj = ZeroCopyBytes(b"foo") + + for proto in range(0, 5): + # Need protocol >= 5 for buffer_callback + with self.assertRaises(ValueError): + dumps(obj, protocol=proto, + buffer_callback=[].append) + for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): + buffers = [] + buffer_callback = buffers.append + data = dumps(obj, protocol=proto, + buffer_callback=buffer_callback) + self.assertNotIn(b"foo", data) + self.assertEqual(bytes(buffers[0]), b"foo") + # Need buffers argument to unpickle properly + with self.assertRaises(pickle.UnpicklingError): + loads(data) + new = loads(data, buffers=buffers) + self.assertIs(new, obj) + + def test_dumps_loads_oob_buffers(self): + # Test out-of-band buffers (PEP 574) with top-level dumps() and loads() + self.check_dumps_loads_oob_buffers(self.dumps, self.loads) + + def test_dump_load_oob_buffers(self): + # Test out-of-band buffers (PEP 574) with top-level dump() and load() + def dumps(obj, **kwargs): + f = io.BytesIO() + self.dump(obj, f, **kwargs) + return f.getvalue() + + def loads(data, **kwargs): + f = io.BytesIO(data) + return self.load(f, **kwargs) + + self.check_dumps_loads_oob_buffers(dumps, loads) + class AbstractPersistentPicklerTests(unittest.TestCase): diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index be52b389e62dc1..b3aae3a18ecfae 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -2894,16 +2894,15 @@ class D(C): pass @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") def test_signature_on_builtin_class(self): - self.assertEqual(str(inspect.signature(_pickle.Pickler)), - '(file, protocol=None, fix_imports=True)') + expected = ('(file, protocol=None, fix_imports=True, ' + 'buffer_callback=None)') + self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected) class P(_pickle.Pickler): pass class EmptyTrait: pass class P2(EmptyTrait, P): pass - self.assertEqual(str(inspect.signature(P)), - '(file, protocol=None, fix_imports=True)') - self.assertEqual(str(inspect.signature(P2)), - '(file, protocol=None, fix_imports=True)') + self.assertEqual(str(inspect.signature(P)), expected) + self.assertEqual(str(inspect.signature(P2)), expected) class P3(P2): def __init__(self, spam): diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 435c248802d3d7..5f7a879b935d92 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -57,9 +57,9 @@ class PyPicklerTests(AbstractPickleTests): pickler = pickle._Pickler unpickler = pickle._Unpickler - def dumps(self, arg, proto=None): + def dumps(self, arg, proto=None, **kwargs): f = io.BytesIO() - p = self.pickler(f, proto) + p = self.pickler(f, proto, **kwargs) p.dump(arg) f.seek(0) return bytes(f.read()) @@ -78,8 +78,8 @@ class InMemoryPickleTests(AbstractPickleTests, AbstractUnpickleTests, AttributeError, ValueError, struct.error, IndexError, ImportError) - def dumps(self, arg, protocol=None): - return pickle.dumps(arg, protocol) + def dumps(self, arg, protocol=None, **kwargs): + return pickle.dumps(arg, protocol, **kwargs) def loads(self, buf, **kwds): return pickle.loads(buf, **kwds) @@ -271,7 +271,7 @@ class SizeofTests(unittest.TestCase): check_sizeof = support.check_sizeof def test_pickler(self): - basesize = support.calcobjsize('6P2n3i2n3i2P') + basesize = support.calcobjsize('7P2n3i2n3i2P') p = _pickle.Pickler(io.BytesIO()) self.assertEqual(object.__sizeof__(p), basesize) MT_size = struct.calcsize('3nP0n') @@ -288,7 +288,7 @@ def test_pickler(self): 0) # Write buffer is cleared after every dump(). def test_unpickler(self): - basesize = support.calcobjsize('2P2n2P 2P2n2i5P 2P3n6P2n2i') + basesize = support.calcobjsize('2P2n2P 2P2n2i5P 2P3n8P2n2i') unpickler = _pickle.Unpickler P = struct.calcsize('P') # Size of memo table entry. n = struct.calcsize('n') # Size of mark table entry. diff --git a/Lib/test/test_picklebuffer.py b/Lib/test/test_picklebuffer.py new file mode 100644 index 00000000000000..7e72157fd02216 --- /dev/null +++ b/Lib/test/test_picklebuffer.py @@ -0,0 +1,154 @@ +"""Unit tests for the PickleBuffer object. + +Pickling tests themselves are in pickletester.py. +""" + +import gc +from pickle import PickleBuffer +import sys +import weakref +import unittest + +from test import support + + +class B(bytes): + pass + + +class PickleBufferTest(unittest.TestCase): + + def check_memoryview(self, pb, equiv): + with memoryview(pb) as m: + with memoryview(equiv) as expected: + self.assertEqual(m.nbytes, expected.nbytes) + self.assertEqual(m.readonly, expected.readonly) + self.assertEqual(m.itemsize, expected.itemsize) + self.assertEqual(m.shape, expected.shape) + self.assertEqual(m.strides, expected.strides) + self.assertEqual(m.c_contiguous, expected.c_contiguous) + self.assertEqual(m.f_contiguous, expected.f_contiguous) + self.assertEqual(m.format, expected.format) + self.assertEqual(m.tobytes(), expected.tobytes()) + + def test_constructor_failure(self): + with self.assertRaises(TypeError): + PickleBuffer() + with self.assertRaises(TypeError): + PickleBuffer("foo") + # Released memoryview fails taking a buffer + m = memoryview(b"foo") + m.release() + with self.assertRaises(ValueError): + PickleBuffer(m) + + def test_basics(self): + pb = PickleBuffer(b"foo") + self.assertEqual(b"foo", bytes(pb)) + with memoryview(pb) as m: + self.assertTrue(m.readonly) + + pb = PickleBuffer(bytearray(b"foo")) + self.assertEqual(b"foo", bytes(pb)) + with memoryview(pb) as m: + self.assertFalse(m.readonly) + m[0] = 48 + self.assertEqual(b"0oo", bytes(pb)) + + def test_release(self): + pb = PickleBuffer(b"foo") + pb.release() + with self.assertRaises(ValueError) as raises: + memoryview(pb) + self.assertIn("operation forbidden on released PickleBuffer object", + str(raises.exception)) + # Idempotency + pb.release() + + def test_cycle(self): + b = B(b"foo") + pb = PickleBuffer(b) + b.cycle = pb + wpb = weakref.ref(pb) + del b, pb + gc.collect() + self.assertIsNone(wpb()) + + def test_ndarray_2d(self): + # C-contiguous + ndarray = support.import_module("_testbuffer").ndarray + arr = ndarray(list(range(12)), shape=(4, 3), format='pers_func = NULL; self->dispatch_table = NULL; + self->buffer_callback = NULL; self->write = NULL; self->proto = 0; self->bin = 0; @@ -1174,6 +1183,23 @@ _Pickler_SetOutputStream(PicklerObject *self, PyObject *file) return 0; } +static int +_Pickler_SetBufferCallback(PicklerObject *self, PyObject *buffer_callback) +{ + if (buffer_callback == Py_None) { + buffer_callback = NULL; + } + if (buffer_callback != NULL && self->proto < 5) { + PyErr_SetString(PyExc_ValueError, + "buffer_callback needs protocol >= 5"); + return -1; + } + + Py_XINCREF(buffer_callback); + self->buffer_callback = buffer_callback; + return 0; +} + /* Returns the size of the input on success, -1 on failure. This takes its own reference to `input`. */ static Py_ssize_t @@ -1198,6 +1224,7 @@ bad_readline(void) return -1; } +/* Skip any consumed data that was only prefetched using peek() */ static int _Unpickler_SkipConsumed(UnpicklerObject *self) { @@ -1305,6 +1332,7 @@ _Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) if (!self->read) return bad_readline(); + /* Extend the buffer to satisfy desired size */ num_read = _Unpickler_ReadFromFile(self, n); if (num_read < 0) return -1; @@ -1315,6 +1343,66 @@ _Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) return n; } +/* Read `n` bytes from the unpickler's data source, storing the result in `buf`. + * + * This should only be used for non-small data reads where potentially + * avoiding a copy is beneficial. This method does not try to prefetch + * more data into the input buffer. + * + * _Unpickler_Read() is recommended in most cases. + */ +static Py_ssize_t +_Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) +{ + assert(n != READ_WHOLE_LINE); + + /* Read from available buffer data, if any */ + Py_ssize_t in_buffer = self->input_len - self->next_read_idx; + if (in_buffer > 0) { + Py_ssize_t to_read = Py_MIN(in_buffer, n); + memcpy(buf, self->input_buffer + self->next_read_idx, to_read); + self->next_read_idx += to_read; + buf += to_read; + n -= to_read; + if (n == 0) { + /* Entire read was satisfied from buffer */ + return n; + } + } + + /* Read from file */ + if (!self->readinto) { + return bad_readline(); + } + if (_Unpickler_SkipConsumed(self) < 0) { + return -1; + } + + /* Call readinto() into user buffer */ + PyObject *buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE); + if (buf_obj == NULL) { + return -1; + } + PyObject *read_size_obj = _Pickle_FastCall(self->readinto, buf_obj); + if (read_size_obj == NULL) { + return -1; + } + Py_ssize_t read_size = PyLong_AsSsize_t(read_size_obj); + Py_DECREF(read_size_obj); + + if (read_size < 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "readinto() returned negative size"); + } + return -1; + } + if (read_size < n) { + return bad_readline(); + } + return n; +} + /* Read `n` bytes from the unpickler's data source, storing the result in `*s`. This should be used for all data reads, rather than accessing the unpickler's @@ -1482,8 +1570,10 @@ _Unpickler_New(void) self->next_read_idx = 0; self->prefetched_idx = 0; self->read = NULL; + self->readinto = NULL; self->readline = NULL; self->peek = NULL; + self->buffers = NULL; self->encoding = NULL; self->errors = NULL; self->marks = NULL; @@ -1507,25 +1597,29 @@ _Unpickler_New(void) } /* Returns -1 (with an exception set) on failure, 0 on success. This may - be called once on a freshly created Pickler. */ + be called once on a freshly created Unpickler. */ static int _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) { _Py_IDENTIFIER(peek); _Py_IDENTIFIER(read); + _Py_IDENTIFIER(readinto); _Py_IDENTIFIER(readline); if (_PyObject_LookupAttrId(file, &PyId_peek, &self->peek) < 0) { return -1; } (void)_PyObject_LookupAttrId(file, &PyId_read, &self->read); + (void)_PyObject_LookupAttrId(file, &PyId_readinto, &self->readinto); (void)_PyObject_LookupAttrId(file, &PyId_readline, &self->readline); - if (self->readline == NULL || self->read == NULL) { + if (!self->readline || !self->readinto || !self->read) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, - "file must have 'read' and 'readline' attributes"); + "file must have 'read', 'readinto' and " + "'readline' attributes"); } Py_CLEAR(self->read); + Py_CLEAR(self->readinto); Py_CLEAR(self->readline); Py_CLEAR(self->peek); return -1; @@ -1534,7 +1628,7 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) } /* Returns -1 (with an exception set) on failure, 0 on success. This may - be called once on a freshly created Pickler. */ + be called once on a freshly created Unpickler. */ static int _Unpickler_SetInputEncoding(UnpicklerObject *self, const char *encoding, @@ -1554,6 +1648,23 @@ _Unpickler_SetInputEncoding(UnpicklerObject *self, return 0; } +/* Returns -1 (with an exception set) on failure, 0 on success. This may + be called once on a freshly created Unpickler. */ +static int +_Unpickler_SetBuffers(UnpicklerObject *self, PyObject *buffers) +{ + if (buffers == NULL) { + self->buffers = NULL; + } + else { + self->buffers = PyObject_GetIter(buffers); + if (self->buffers == NULL) { + return -1; + } + } + return 0; +} + /* Generate a GET opcode for an object stored in the memo. */ static int memo_get(PicklerObject *self, PyObject *key) @@ -2209,6 +2320,54 @@ _Pickler_write_bytes(PicklerObject *self, return 0; } +static int +_save_bytes_data(PicklerObject *self, PyObject *obj, const char *data, + Py_ssize_t size) +{ + assert(self->proto >= 3); + + char header[9]; + Py_ssize_t len; + + if (size < 0) + return -1; + + if (size <= 0xff) { + header[0] = SHORT_BINBYTES; + header[1] = (unsigned char)size; + len = 2; + } + else if ((size_t)size <= 0xffffffffUL) { + header[0] = BINBYTES; + header[1] = (unsigned char)(size & 0xff); + header[2] = (unsigned char)((size >> 8) & 0xff); + header[3] = (unsigned char)((size >> 16) & 0xff); + header[4] = (unsigned char)((size >> 24) & 0xff); + len = 5; + } + else if (self->proto >= 4) { + header[0] = BINBYTES8; + _write_size64(header + 1, size); + len = 9; + } + else { + PyErr_SetString(PyExc_OverflowError, + "serializing a bytes object larger than 4 GiB " + "requires pickle protocol 4 or higher"); + return -1; + } + + if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) { + return -1; + } + + if (memo_put(self, obj) < 0) { + return -1; + } + + return 0; +} + static int save_bytes(PicklerObject *self, PyObject *obj) { @@ -2255,49 +2414,132 @@ save_bytes(PicklerObject *self, PyObject *obj) return status; } else { - Py_ssize_t size; - char header[9]; - Py_ssize_t len; + return _save_bytes_data(self, obj, PyBytes_AS_STRING(obj), + PyBytes_GET_SIZE(obj)); + } +} - size = PyBytes_GET_SIZE(obj); - if (size < 0) +static int +_save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data, + Py_ssize_t size) +{ + assert(self->proto >= 5); + + char header[9]; + Py_ssize_t len; + + if (size < 0) + return -1; + + header[0] = BYTEARRAY8; + _write_size64(header + 1, size); + len = 9; + + if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) { + return -1; + } + + if (memo_put(self, obj) < 0) { + return -1; + } + + return 0; +} + +static int +save_bytearray(PicklerObject *self, PyObject *obj) +{ + if (self->proto < 5) { + /* Older pickle protocols do not have an opcode for pickling + * bytearrays. */ + PyObject *reduce_value = NULL; + int status; + + if (PyByteArray_GET_SIZE(obj) == 0) { + reduce_value = Py_BuildValue("(O())", + (PyObject *) &PyByteArray_Type); + } + else { + PyObject *bytes_obj = PyBytes_FromObject(obj); + if (bytes_obj != NULL) { + reduce_value = Py_BuildValue("(O(O))", + (PyObject *) &PyByteArray_Type, + bytes_obj); + Py_DECREF(bytes_obj); + } + } + if (reduce_value == NULL) return -1; - if (size <= 0xff) { - header[0] = SHORT_BINBYTES; - header[1] = (unsigned char)size; - len = 2; + /* save_reduce() will memoize the object automatically. */ + status = save_reduce(self, reduce_value, obj); + Py_DECREF(reduce_value); + return status; + } + else { + return _save_bytearray_data(self, obj, PyByteArray_AS_STRING(obj), + PyByteArray_GET_SIZE(obj)); + } +} + +static int +save_picklebuffer(PicklerObject *self, PyObject *obj) +{ + if (self->proto < 5) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "PickleBuffer can only pickled with protocol >= 5"); + return -1; + } + const Py_buffer* view = PyPickleBuffer_GetBuffer(obj); + if (view == NULL) { + return -1; + } + if (view->suboffsets != NULL || !PyBuffer_IsContiguous(view, 'A')) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->PicklingError, + "PickleBuffer can not be pickled when " + "pointing to a non-contiguous buffer"); + return -1; + } + int in_band = 1; + if (self->buffer_callback != NULL) { + PyObject *ret = PyObject_CallFunctionObjArgs(self->buffer_callback, + obj, NULL); + if (ret == NULL) { + return -1; } - else if ((size_t)size <= 0xffffffffUL) { - header[0] = BINBYTES; - header[1] = (unsigned char)(size & 0xff); - header[2] = (unsigned char)((size >> 8) & 0xff); - header[3] = (unsigned char)((size >> 16) & 0xff); - header[4] = (unsigned char)((size >> 24) & 0xff); - len = 5; + in_band = PyObject_IsTrue(ret); + Py_DECREF(ret); + if (in_band == -1) { + return -1; } - else if (self->proto >= 4) { - header[0] = BINBYTES8; - _write_size64(header + 1, size); - len = 9; + } + if (in_band) { + /* Write data in-band */ + if (view->readonly) { + return _save_bytes_data(self, obj, (const char*) view->buf, + view->len); } else { - PyErr_SetString(PyExc_OverflowError, - "cannot serialize a bytes object larger than 4 GiB"); - return -1; /* string too large */ + return _save_bytearray_data(self, obj, (const char*) view->buf, + view->len); } - - if (_Pickler_write_bytes(self, header, len, - PyBytes_AS_STRING(obj), size, obj) < 0) - { + } + else { + /* Write data out-of-band */ + const char next_buffer_op = NEXT_BUFFER; + if (_Pickler_Write(self, &next_buffer_op, 1) < 0) { return -1; } - - if (memo_put(self, obj) < 0) - return -1; - - return 0; + if (view->readonly) { + const char readonly_buffer_op = READONLY_BUFFER; + if (_Pickler_Write(self, &readonly_buffer_op, 1) < 0) { + return -1; + } + } } + return 0; } /* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates @@ -2417,7 +2659,8 @@ write_unicode_binary(PicklerObject *self, PyObject *obj) } else { PyErr_SetString(PyExc_OverflowError, - "cannot serialize a string larger than 4GiB"); + "serializing a string larger than 4 GiB " + "requires pickle protocol 4 or higher"); Py_XDECREF(encoded); return -1; } @@ -4062,6 +4305,14 @@ save(PicklerObject *self, PyObject *obj, int pers_save) status = save_tuple(self, obj); goto done; } + else if (type == &PyByteArray_Type) { + status = save_bytearray(self, obj); + goto done; + } + else if (type == &PyPickleBuffer_Type) { + status = save_picklebuffer(self, obj); + goto done; + } /* Now, check reducer_override. If it returns NotImplemented, * fallback to save_type or save_global, and then perhaps to the @@ -4342,6 +4593,7 @@ Pickler_dealloc(PicklerObject *self) Py_XDECREF(self->dispatch_table); Py_XDECREF(self->fast_memo); Py_XDECREF(self->reducer_override); + Py_XDECREF(self->buffer_callback); PyMemoTable_Del(self->memo); @@ -4356,6 +4608,7 @@ Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) Py_VISIT(self->dispatch_table); Py_VISIT(self->fast_memo); Py_VISIT(self->reducer_override); + Py_VISIT(self->buffer_callback); return 0; } @@ -4368,6 +4621,7 @@ Pickler_clear(PicklerObject *self) Py_CLEAR(self->dispatch_table); Py_CLEAR(self->fast_memo); Py_CLEAR(self->reducer_override); + Py_CLEAR(self->buffer_callback); if (self->memo != NULL) { PyMemoTable *memo = self->memo; @@ -4385,6 +4639,7 @@ _pickle.Pickler.__init__ file: object protocol: object = NULL fix_imports: bool = True + buffer_callback: object = NULL This takes a binary file for writing a pickle data stream. @@ -4404,12 +4659,25 @@ this interface. If *fix_imports* is True and protocol is less than 3, pickle will try to map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. + +If *buffer_callback* is None (the default), buffer views are +serialized into *file* as part of the pickle stream. + +If *buffer_callback* is not None, then it can be called any number +of times with a buffer view. If the callback returns a false value +(such as None), the given buffer is out-of-band; otherwise the +buffer is serialized in-band, i.e. inside the pickle stream. + +It is an error if *buffer_callback* is not None and *protocol* +is None or smaller than 5. + [clinic start generated code]*/ static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, - PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=b5f31078dab17fb0 input=4faabdbc763c2389]*/ + PyObject *protocol, int fix_imports, + PyObject *buffer_callback) +/*[clinic end generated code: output=0abedc50590d259b input=9a43a1c50ab91652]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -4424,6 +4692,9 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, if (_Pickler_SetOutputStream(self, file) < 0) return -1; + if (_Pickler_SetBufferCallback(self, buffer_callback) < 0) + return -1; + /* memo and output_buffer may have already been created in _Pickler_New */ if (self->memo == NULL) { self->memo = PyMemoTable_New(); @@ -5212,17 +5483,100 @@ load_counted_binbytes(UnpicklerObject *self, int nbytes) return -1; } - if (_Unpickler_Read(self, &s, size) < 0) - return -1; - - bytes = PyBytes_FromStringAndSize(s, size); + bytes = PyBytes_FromStringAndSize(NULL, size); if (bytes == NULL) return -1; + if (_Unpickler_ReadInto(self, PyBytes_AS_STRING(bytes), size) < 0) { + Py_DECREF(bytes); + return -1; + } PDATA_PUSH(self->stack, bytes, -1); return 0; } +static int +load_counted_bytearray(UnpicklerObject *self) +{ + PyObject *bytearray; + Py_ssize_t size; + char *s; + + if (_Unpickler_Read(self, &s, 8) < 0) { + return -1; + } + + size = calc_binsize(s, 8); + if (size < 0) { + PyErr_Format(PyExc_OverflowError, + "BYTEARRAY8 exceeds system's maximum size of %zd bytes", + PY_SSIZE_T_MAX); + return -1; + } + + bytearray = PyByteArray_FromStringAndSize(NULL, size); + if (bytearray == NULL) { + return -1; + } + if (_Unpickler_ReadInto(self, PyByteArray_AS_STRING(bytearray), size) < 0) { + Py_DECREF(bytearray); + return -1; + } + + PDATA_PUSH(self->stack, bytearray, -1); + return 0; +} + +static int +load_next_buffer(UnpicklerObject *self) +{ + if (self->buffers == NULL) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "pickle stream refers to out-of-band data " + "but no *buffers* argument was given"); + return -1; + } + PyObject *buf = PyIter_Next(self->buffers); + if (buf == NULL) { + if (!PyErr_Occurred()) { + PickleState *st = _Pickle_GetGlobalState(); + PyErr_SetString(st->UnpicklingError, + "not enough out-of-band buffers"); + } + return -1; + } + + PDATA_PUSH(self->stack, buf, -1); + return 0; +} + +static int +load_readonly_buffer(UnpicklerObject *self) +{ + Py_ssize_t len = Py_SIZE(self->stack); + if (len <= self->stack->fence) { + return Pdata_stack_underflow(self->stack); + } + + PyObject *obj = self->stack->data[len - 1]; + PyObject *view = PyMemoryView_FromObject(obj); + if (view == NULL) { + return -1; + } + if (!PyMemoryView_GET_BUFFER(view)->readonly) { + /* Original object is writable */ + PyMemoryView_GET_BUFFER(view)->readonly = 1; + self->stack->data[len - 1] = view; + Py_DECREF(obj); + } + else { + /* Original object is read-only, no need to replace it */ + Py_DECREF(view); + } + return 0; +} + static int load_unicode(UnpicklerObject *self) { @@ -6511,6 +6865,9 @@ load(UnpicklerObject *self) OP_ARG(SHORT_BINBYTES, load_counted_binbytes, 1) OP_ARG(BINBYTES, load_counted_binbytes, 4) OP_ARG(BINBYTES8, load_counted_binbytes, 8) + OP(BYTEARRAY8, load_counted_bytearray) + OP(NEXT_BUFFER, load_next_buffer) + OP(READONLY_BUFFER, load_readonly_buffer) OP_ARG(SHORT_BINSTRING, load_counted_binstring, 1) OP_ARG(BINSTRING, load_counted_binstring, 4) OP(STRING, load_string) @@ -6771,10 +7128,12 @@ Unpickler_dealloc(UnpicklerObject *self) { PyObject_GC_UnTrack((PyObject *)self); Py_XDECREF(self->readline); + Py_XDECREF(self->readinto); Py_XDECREF(self->read); Py_XDECREF(self->peek); Py_XDECREF(self->stack); Py_XDECREF(self->pers_func); + Py_XDECREF(self->buffers); if (self->buffer.buf != NULL) { PyBuffer_Release(&self->buffer); self->buffer.buf = NULL; @@ -6793,10 +7152,12 @@ static int Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) { Py_VISIT(self->readline); + Py_VISIT(self->readinto); Py_VISIT(self->read); Py_VISIT(self->peek); Py_VISIT(self->stack); Py_VISIT(self->pers_func); + Py_VISIT(self->buffers); return 0; } @@ -6804,10 +7165,12 @@ static int Unpickler_clear(UnpicklerObject *self) { Py_CLEAR(self->readline); + Py_CLEAR(self->readinto); Py_CLEAR(self->read); Py_CLEAR(self->peek); Py_CLEAR(self->stack); Py_CLEAR(self->pers_func); + Py_CLEAR(self->buffers); if (self->buffer.buf != NULL) { PyBuffer_Release(&self->buffer); self->buffer.buf = NULL; @@ -6835,6 +7198,7 @@ _pickle.Unpickler.__init__ fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' + buffers: object = NULL This takes a binary file for reading a pickle data stream. @@ -6861,8 +7225,8 @@ string instances as bytes objects. static int _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, - const char *errors) -/*[clinic end generated code: output=e2c8ce748edc57b0 input=f9b7da04f5f4f335]*/ + const char *errors, PyObject *buffers) +/*[clinic end generated code: output=09f0192649ea3f85 input=da4b62d9edb68700]*/ { _Py_IDENTIFIER(persistent_load); @@ -6876,6 +7240,9 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0) return -1; + if (_Unpickler_SetBuffers(self, buffers) < 0) + return -1; + self->fix_imports = fix_imports; if (init_method_ref((PyObject *)self, &PyId_persistent_load, @@ -7254,6 +7621,7 @@ _pickle.dump protocol: object = NULL * fix_imports: bool = True + buffer_callback: object = NULL Write a pickled representation of obj to the open file object file. @@ -7277,12 +7645,18 @@ this interface. If *fix_imports* is True and protocol is less than 3, pickle will try to map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. + +If *buffer_callback* is None (the default), buffer views are serialized +into *file* as part of the pickle stream. It is an error if +*buffer_callback* is not None and *protocol* is None or smaller than 5. + [clinic start generated code]*/ static PyObject * _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, - PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=a4774d5fde7d34de input=93f1408489a87472]*/ + PyObject *protocol, int fix_imports, + PyObject *buffer_callback) +/*[clinic end generated code: output=706186dba996490c input=2f035f02cc0f9547]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7295,6 +7669,9 @@ _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, if (_Pickler_SetOutputStream(pickler, file) < 0) goto error; + if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0) + goto error; + if (dump(pickler, obj) < 0) goto error; @@ -7317,6 +7694,7 @@ _pickle.dumps protocol: object = NULL * fix_imports: bool = True + buffer_callback: object = NULL Return the pickled representation of the object as a bytes object. @@ -7332,12 +7710,17 @@ version of Python needed to read the pickle produced. If *fix_imports* is True and *protocol* is less than 3, pickle will try to map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. + +If *buffer_callback* is None (the default), buffer views are serialized +into *file* as part of the pickle stream. It is an error if +*buffer_callback* is not None and *protocol* is None or smaller than 5. + [clinic start generated code]*/ static PyObject * _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, - int fix_imports) -/*[clinic end generated code: output=d75d5cda456fd261 input=b6efb45a7d19b5ab]*/ + int fix_imports, PyObject *buffer_callback) +/*[clinic end generated code: output=fbab0093a5580fdf input=001f167df711b9f1]*/ { PyObject *result; PicklerObject *pickler = _Pickler_New(); @@ -7348,6 +7731,9 @@ _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, if (_Pickler_SetProtocol(pickler, protocol, fix_imports) < 0) goto error; + if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0) + goto error; + if (dump(pickler, obj) < 0) goto error; @@ -7369,6 +7755,7 @@ _pickle.load fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' + buffers: object = NULL Read and return an object from the pickle data stored in a file. @@ -7397,8 +7784,9 @@ string instances as bytes objects. static PyObject * _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, - const char *encoding, const char *errors) -/*[clinic end generated code: output=69e298160285199e input=01b44dd3fc07afa7]*/ + const char *encoding, const char *errors, + PyObject *buffers) +/*[clinic end generated code: output=250452d141c23e76 input=29fae982fe778156]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); @@ -7412,6 +7800,9 @@ _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0) goto error; + if (_Unpickler_SetBuffers(unpickler, buffers) < 0) + goto error; + unpickler->fix_imports = fix_imports; result = load(unpickler); @@ -7432,6 +7823,7 @@ _pickle.loads fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' + buffers: object = NULL Read and return an object from the given pickle data. @@ -7451,8 +7843,9 @@ string instances as bytes objects. static PyObject * _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, - const char *encoding, const char *errors) -/*[clinic end generated code: output=1e7cb2343f2c440f input=70605948a719feb9]*/ + const char *encoding, const char *errors, + PyObject *buffers) +/*[clinic end generated code: output=82ac1e6b588e6d02 input=c6004393f8276867]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); @@ -7466,6 +7859,9 @@ _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0) goto error; + if (_Unpickler_SetBuffers(unpickler, buffers) < 0) + goto error; + unpickler->fix_imports = fix_imports; result = load(unpickler); @@ -7558,12 +7954,17 @@ PyInit__pickle(void) if (m == NULL) return NULL; + /* Add types */ Py_INCREF(&Pickler_Type); if (PyModule_AddObject(m, "Pickler", (PyObject *)&Pickler_Type) < 0) return NULL; Py_INCREF(&Unpickler_Type); if (PyModule_AddObject(m, "Unpickler", (PyObject *)&Unpickler_Type) < 0) return NULL; + Py_INCREF(&PyPickleBuffer_Type); + if (PyModule_AddObject(m, "PickleBuffer", + (PyObject *)&PyPickleBuffer_Type) < 0) + return NULL; st = _Pickle_GetState(m); diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 1da2f936be4399..8ac723fd43a681 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -63,7 +63,7 @@ _pickle_Pickler___sizeof__(PicklerObject *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(_pickle_Pickler___init____doc__, -"Pickler(file, protocol=None, fix_imports=True)\n" +"Pickler(file, protocol=None, fix_imports=True, buffer_callback=None)\n" "--\n" "\n" "This takes a binary file for writing a pickle data stream.\n" @@ -83,27 +83,40 @@ PyDoc_STRVAR(_pickle_Pickler___init____doc__, "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" "to map the new Python 3 names to the old module names used in Python\n" -"2, so that the pickle data stream is readable with Python 2."); +"2, so that the pickle data stream is readable with Python 2.\n" +"\n" +"If *buffer_callback* is None (the default), buffer views are\n" +"serialized into *file* as part of the pickle stream.\n" +"\n" +"If *buffer_callback* is not None, then it can be called any number\n" +"of times with a buffer view. If the callback returns a false value\n" +"(such as None), the given buffer is out-of-band; otherwise the\n" +"buffer is serialized in-band, i.e. inside the pickle stream.\n" +"\n" +"It is an error if *buffer_callback* is not None and *protocol*\n" +"is None or smaller than 5."); static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, - PyObject *protocol, int fix_imports); + PyObject *protocol, int fix_imports, + PyObject *buffer_callback); static int _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"file", "protocol", "fix_imports", NULL}; + static const char * const _keywords[] = {"file", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Pickler", 0}; - PyObject *argsbuf[3]; + PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; PyObject *file; PyObject *protocol = NULL; int fix_imports = 1; + PyObject *buffer_callback = NULL; - fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 3, 0, argsbuf); + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 4, 0, argsbuf); if (!fastargs) { goto exit; } @@ -117,12 +130,18 @@ _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } } - fix_imports = PyObject_IsTrue(fastargs[2]); - if (fix_imports < 0) { - goto exit; + if (fastargs[2]) { + fix_imports = PyObject_IsTrue(fastargs[2]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } + buffer_callback = fastargs[3]; skip_optional_pos: - return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports); + return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports, buffer_callback); exit: return return_value; @@ -272,7 +291,8 @@ _pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored) } PyDoc_STRVAR(_pickle_Unpickler___init____doc__, -"Unpickler(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" +"Unpickler(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\',\n" +" buffers=None)\n" "--\n" "\n" "This takes a binary file for reading a pickle data stream.\n" @@ -299,15 +319,15 @@ PyDoc_STRVAR(_pickle_Unpickler___init____doc__, static int _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, - const char *errors); + const char *errors, PyObject *buffers); static int _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "Unpickler", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; @@ -315,6 +335,7 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) int fix_imports = 1; const char *encoding = "ASCII"; const char *errors = "strict"; + PyObject *buffers = NULL; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); if (!fastargs) { @@ -351,21 +372,27 @@ _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_kwonly; } } - if (!PyUnicode_Check(fastargs[3])) { - _PyArg_BadArgument("Unpickler", 4, "str", fastargs[3]); - goto exit; - } - Py_ssize_t errors_length; - errors = PyUnicode_AsUTF8AndSize(fastargs[3], &errors_length); - if (errors == NULL) { - goto exit; - } - if (strlen(errors) != (size_t)errors_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; + if (fastargs[3]) { + if (!PyUnicode_Check(fastargs[3])) { + _PyArg_BadArgument("Unpickler", 4, "str", fastargs[3]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(fastargs[3], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } } + buffers = fastargs[4]; skip_optional_kwonly: - return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors); + return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors, buffers); exit: return return_value; @@ -426,7 +453,8 @@ _pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject * } PyDoc_STRVAR(_pickle_dump__doc__, -"dump($module, /, obj, file, protocol=None, *, fix_imports=True)\n" +"dump($module, /, obj, file, protocol=None, *, fix_imports=True,\n" +" buffer_callback=None)\n" "--\n" "\n" "Write a pickled representation of obj to the open file object file.\n" @@ -450,27 +478,33 @@ PyDoc_STRVAR(_pickle_dump__doc__, "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" "to map the new Python 3 names to the old module names used in Python\n" -"2, so that the pickle data stream is readable with Python 2."); +"2, so that the pickle data stream is readable with Python 2.\n" +"\n" +"If *buffer_callback* is None (the default), buffer views are serialized\n" +"into *file* as part of the pickle stream. It is an error if\n" +"*buffer_callback* is not None and *protocol* is None or smaller than 5."); #define _PICKLE_DUMP_METHODDEF \ {"dump", (PyCFunction)(void(*)(void))_pickle_dump, METH_FASTCALL|METH_KEYWORDS, _pickle_dump__doc__}, static PyObject * _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, - PyObject *protocol, int fix_imports); + PyObject *protocol, int fix_imports, + PyObject *buffer_callback); static PyObject * _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", NULL}; + static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "dump", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *obj; PyObject *file; PyObject *protocol = NULL; int fix_imports = 1; + PyObject *buffer_callback = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf); if (!args) { @@ -491,19 +525,26 @@ _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject if (!noptargs) { goto skip_optional_kwonly; } - fix_imports = PyObject_IsTrue(args[3]); - if (fix_imports < 0) { - goto exit; + if (args[3]) { + fix_imports = PyObject_IsTrue(args[3]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } } + buffer_callback = args[4]; skip_optional_kwonly: - return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports); + return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports, buffer_callback); exit: return return_value; } PyDoc_STRVAR(_pickle_dumps__doc__, -"dumps($module, /, obj, protocol=None, *, fix_imports=True)\n" +"dumps($module, /, obj, protocol=None, *, fix_imports=True,\n" +" buffer_callback=None)\n" "--\n" "\n" "Return the pickled representation of the object as a bytes object.\n" @@ -519,26 +560,31 @@ PyDoc_STRVAR(_pickle_dumps__doc__, "\n" "If *fix_imports* is True and *protocol* is less than 3, pickle will\n" "try to map the new Python 3 names to the old module names used in\n" -"Python 2, so that the pickle data stream is readable with Python 2."); +"Python 2, so that the pickle data stream is readable with Python 2.\n" +"\n" +"If *buffer_callback* is None (the default), buffer views are serialized\n" +"into *file* as part of the pickle stream. It is an error if\n" +"*buffer_callback* is not None and *protocol* is None or smaller than 5."); #define _PICKLE_DUMPS_METHODDEF \ {"dumps", (PyCFunction)(void(*)(void))_pickle_dumps, METH_FASTCALL|METH_KEYWORDS, _pickle_dumps__doc__}, static PyObject * _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, - int fix_imports); + int fix_imports, PyObject *buffer_callback); static PyObject * _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"obj", "protocol", "fix_imports", NULL}; + static const char * const _keywords[] = {"obj", "protocol", "fix_imports", "buffer_callback", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "dumps", 0}; - PyObject *argsbuf[3]; + PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; PyObject *protocol = NULL; int fix_imports = 1; + PyObject *buffer_callback = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); if (!args) { @@ -558,12 +604,18 @@ _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec if (!noptargs) { goto skip_optional_kwonly; } - fix_imports = PyObject_IsTrue(args[2]); - if (fix_imports < 0) { - goto exit; + if (args[2]) { + fix_imports = PyObject_IsTrue(args[2]); + if (fix_imports < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } } + buffer_callback = args[3]; skip_optional_kwonly: - return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports); + return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports, buffer_callback); exit: return return_value; @@ -571,7 +623,7 @@ _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec PyDoc_STRVAR(_pickle_load__doc__, "load($module, /, file, *, fix_imports=True, encoding=\'ASCII\',\n" -" errors=\'strict\')\n" +" errors=\'strict\', buffers=None)\n" "--\n" "\n" "Read and return an object from the pickle data stored in a file.\n" @@ -603,20 +655,22 @@ PyDoc_STRVAR(_pickle_load__doc__, static PyObject * _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, - const char *encoding, const char *errors); + const char *encoding, const char *errors, + PyObject *buffers); static PyObject * _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "load", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *file; int fix_imports = 1; const char *encoding = "ASCII"; const char *errors = "strict"; + PyObject *buffers = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -653,21 +707,27 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_kwonly; } } - if (!PyUnicode_Check(args[3])) { - _PyArg_BadArgument("load", 4, "str", args[3]); - goto exit; - } - Py_ssize_t errors_length; - errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); - if (errors == NULL) { - goto exit; - } - if (strlen(errors) != (size_t)errors_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; + if (args[3]) { + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("load", 4, "str", args[3]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } } + buffers = args[4]; skip_optional_kwonly: - return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors); + return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors, buffers); exit: return return_value; @@ -675,7 +735,7 @@ _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject PyDoc_STRVAR(_pickle_loads__doc__, "loads($module, /, data, *, fix_imports=True, encoding=\'ASCII\',\n" -" errors=\'strict\')\n" +" errors=\'strict\', buffers=None)\n" "--\n" "\n" "Read and return an object from the given pickle data.\n" @@ -698,20 +758,22 @@ PyDoc_STRVAR(_pickle_loads__doc__, static PyObject * _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, - const char *encoding, const char *errors); + const char *encoding, const char *errors, + PyObject *buffers); static PyObject * _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"data", "fix_imports", "encoding", "errors", NULL}; + static const char * const _keywords[] = {"data", "fix_imports", "encoding", "errors", "buffers", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "loads", 0}; - PyObject *argsbuf[4]; + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *data; int fix_imports = 1; const char *encoding = "ASCII"; const char *errors = "strict"; + PyObject *buffers = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); if (!args) { @@ -748,23 +810,29 @@ _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto skip_optional_kwonly; } } - if (!PyUnicode_Check(args[3])) { - _PyArg_BadArgument("loads", 4, "str", args[3]); - goto exit; - } - Py_ssize_t errors_length; - errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); - if (errors == NULL) { - goto exit; - } - if (strlen(errors) != (size_t)errors_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; + if (args[3]) { + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("loads", 4, "str", args[3]); + goto exit; + } + Py_ssize_t errors_length; + errors = PyUnicode_AsUTF8AndSize(args[3], &errors_length); + if (errors == NULL) { + goto exit; + } + if (strlen(errors) != (size_t)errors_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } } + buffers = args[4]; skip_optional_kwonly: - return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors); + return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors, buffers); exit: return return_value; } -/*[clinic end generated code: output=8f972562c8f71e2b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8dc0e862f96c4afe input=a9049054013a1b77]*/ diff --git a/Objects/object.c b/Objects/object.c index f842ab3889675e..6d79165683e157 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1839,6 +1839,7 @@ _PyTypes_Init(void) INIT_TYPE(&PyMethodDescr_Type, "method descr"); INIT_TYPE(&PyCallIter_Type, "call iter"); INIT_TYPE(&PySeqIter_Type, "sequence iterator"); + INIT_TYPE(&PyPickleBuffer_Type, "pickle.PickleBuffer"); INIT_TYPE(&PyCoro_Type, "coroutine"); INIT_TYPE(&_PyCoroWrapper_Type, "coroutine wrapper"); INIT_TYPE(&_PyInterpreterID_Type, "interpreter ID"); diff --git a/Objects/picklebufobject.c b/Objects/picklebufobject.c new file mode 100644 index 00000000000000..a135e5575e28c5 --- /dev/null +++ b/Objects/picklebufobject.c @@ -0,0 +1,219 @@ +/* PickleBuffer object implementation */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#include + +typedef struct { + PyObject_HEAD + /* The view exported by the original object */ + Py_buffer view; + PyObject *weakreflist; +} PyPickleBufferObject; + +/* C API */ + +PyObject * +PyPickleBuffer_FromObject(PyObject *base) +{ + PyTypeObject *type = &PyPickleBuffer_Type; + PyPickleBufferObject *self; + + self = (PyPickleBufferObject *) type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + self->view.obj = NULL; + self->weakreflist = NULL; + if (PyObject_GetBuffer(base, &self->view, PyBUF_FULL_RO) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *) self; +} + +const Py_buffer * +PyPickleBuffer_GetBuffer(PyObject *obj) +{ + PyPickleBufferObject *self = (PyPickleBufferObject *) obj; + + if (!PyPickleBuffer_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "expected PickleBuffer, %.200s found", + Py_TYPE(obj)->tp_name); + return NULL; + } + if (self->view.obj == NULL) { + PyErr_SetString(PyExc_ValueError, + "operation forbidden on released PickleBuffer object"); + return NULL; + } + return &self->view; +} + +int +PyPickleBuffer_Release(PyObject *obj) +{ + PyPickleBufferObject *self = (PyPickleBufferObject *) obj; + + if (!PyPickleBuffer_Check(obj)) { + PyErr_Format(PyExc_TypeError, + "expected PickleBuffer, %.200s found", + Py_TYPE(obj)->tp_name); + return -1; + } + PyBuffer_Release(&self->view); + return 0; +} + +static PyObject * +picklebuf_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyPickleBufferObject *self; + PyObject *base; + char *keywords[] = {"", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:PickleBuffer", + keywords, &base)) { + return NULL; + } + + self = (PyPickleBufferObject *) type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } + self->view.obj = NULL; + self->weakreflist = NULL; + if (PyObject_GetBuffer(base, &self->view, PyBUF_FULL_RO) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *) self; +} + +static int +picklebuf_traverse(PyPickleBufferObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->view.obj); + return 0; +} + +static int +picklebuf_clear(PyPickleBufferObject *self) +{ + PyBuffer_Release(&self->view); + return 0; +} + +static void +picklebuf_dealloc(PyPickleBufferObject *self) +{ + PyObject_GC_UnTrack(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + PyBuffer_Release(&self->view); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +/* Buffer API */ + +static int +picklebuf_getbuf(PyPickleBufferObject *self, Py_buffer *view, int flags) +{ + if (self->view.obj == NULL) { + PyErr_SetString(PyExc_ValueError, + "operation forbidden on released PickleBuffer object"); + return -1; + } + return PyObject_GetBuffer(self->view.obj, view, flags); +} + +static void +picklebuf_releasebuf(PyPickleBufferObject *self, Py_buffer *view) +{ + /* Since our bf_getbuffer redirects to the original object, this + * implementation is never called. It only exists to signal that + * buffers exported by PickleBuffer have non-trivial releasing + * behaviour (see check in Python/getargs.c). + */ +} + +static PyBufferProcs picklebuf_as_buffer = { + .bf_getbuffer = (getbufferproc) picklebuf_getbuf, + .bf_releasebuffer = (releasebufferproc) picklebuf_releasebuf, +}; + +/* Methods */ + +static PyObject * +picklebuf_raw(PyPickleBufferObject *self, PyObject *Py_UNUSED(ignored)) +{ + if (self->view.obj == NULL) { + PyErr_SetString(PyExc_ValueError, + "operation forbidden on released PickleBuffer object"); + return NULL; + } + if (self->view.suboffsets != NULL + || !PyBuffer_IsContiguous(&self->view, 'A')) { + PyErr_SetString(PyExc_BufferError, + "cannot extract raw buffer from non-contiguous buffer"); + return NULL; + } + PyObject *m = PyMemoryView_FromObject((PyObject *) self); + if (m == NULL) { + return NULL; + } + PyMemoryViewObject *mv = (PyMemoryViewObject *) m; + assert(mv->view.suboffsets == NULL); + /* Mutate memoryview instance to make it a "raw" memoryview */ + mv->view.format = "B"; + mv->view.ndim = 1; + mv->view.itemsize = 1; + /* shape = (length,) */ + mv->view.shape = &mv->view.len; + /* strides = (1,) */ + mv->view.strides = &mv->view.itemsize; + /* Fix memoryview state flags */ + /* XXX Expose memoryobject.c's init_flags() instead? */ + mv->flags = _Py_MEMORYVIEW_C | _Py_MEMORYVIEW_FORTRAN; + return m; +} + +PyDoc_STRVAR(picklebuf_raw_doc, +"raw($self, /)\n--\n\ +\n\ +Return a memoryview of the raw memory underlying this buffer.\n\ +Will raise BufferError is the buffer isn't contiguous."); + +static PyObject * +picklebuf_release(PyPickleBufferObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyBuffer_Release(&self->view); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(picklebuf_release_doc, +"release($self, /)\n--\n\ +\n\ +Release the underlying buffer exposed by the PickleBuffer object."); + +static PyMethodDef picklebuf_methods[] = { + {"raw", (PyCFunction) picklebuf_raw, METH_NOARGS, picklebuf_raw_doc}, + {"release", (PyCFunction) picklebuf_release, METH_NOARGS, picklebuf_release_doc}, + {NULL, NULL} +}; + +PyTypeObject PyPickleBuffer_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "pickle.PickleBuffer", + .tp_doc = "Wrapper for potentially out-of-band buffers", + .tp_basicsize = sizeof(PyPickleBufferObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_new = picklebuf_new, + .tp_dealloc = (destructor) picklebuf_dealloc, + .tp_traverse = (traverseproc) picklebuf_traverse, + .tp_clear = (inquiry) picklebuf_clear, + .tp_weaklistoffset = offsetof(PyPickleBufferObject, weakreflist), + .tp_as_buffer = &picklebuf_as_buffer, + .tp_methods = picklebuf_methods, +}; diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 10f51dd431b7c1..db691cd39c8bb4 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -197,6 +197,7 @@ + @@ -383,6 +384,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 396d146513d799..dba47e9aa2d1fb 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -285,6 +285,9 @@ Include + + Include + Include @@ -818,6 +821,9 @@ Objects + + Objects + Objects From aaf47caf35984e614d93bd8bea5227df55e0e3e6 Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Mon, 27 May 2019 01:08:20 +0800 Subject: [PATCH 117/441] bpo-37053: handle strings like u"bar" correctly in Tools/parser/unparse.py (GH-13583) Constant.kind is added in https://bugs.python.org/issue36280. Current possible values for Constant.kind are "u" or None. For r'bar' and b'bar', Constant.kind value is None, so there's no need for special handling. https://bugs.python.org/issue37053 --- Lib/test/test_tools/test_unparse.py | 5 +++++ .../Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst | 1 + Tools/parser/unparse.py | 2 ++ 3 files changed, 8 insertions(+) create mode 100644 Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst diff --git a/Lib/test/test_tools/test_unparse.py b/Lib/test/test_tools/test_unparse.py index f3386f5e31a2df..a958ebb51cc3d2 100644 --- a/Lib/test/test_tools/test_unparse.py +++ b/Lib/test/test_tools/test_unparse.py @@ -139,6 +139,11 @@ def test_fstrings(self): self.check_roundtrip(r"""f'{f"{0}"*3}'""") self.check_roundtrip(r"""f'{f"{y}"*3}'""") + def test_strings(self): + self.check_roundtrip("u'foo'") + self.check_roundtrip("r'foo'") + self.check_roundtrip("b'foo'") + def test_del_statement(self): self.check_roundtrip("del x, y, z") diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst b/Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst new file mode 100644 index 00000000000000..5320dc51f75036 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst @@ -0,0 +1 @@ +Handle strings like u"bar" correctly in Tools/parser/unparse.py. Patch by Chih-Hsuan Yen. \ No newline at end of file diff --git a/Tools/parser/unparse.py b/Tools/parser/unparse.py index 385902ef4bc5e7..a5cc000676b022 100644 --- a/Tools/parser/unparse.py +++ b/Tools/parser/unparse.py @@ -399,6 +399,8 @@ def _Constant(self, t): elif value is ...: self.write("...") else: + if t.kind == "u": + self.write("u") self._write_constant(t.value) def _List(self, t): From b821868e6d909f4805499db519ebc2cdc01cf611 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 26 May 2019 11:27:35 -0700 Subject: [PATCH 118/441] bpo-36772 Allow lru_cache to be used as decorator without making a function call (GH-13048) --- Doc/library/functools.rst | 15 ++++++++++++++- Doc/whatsnew/3.8.rst | 17 +++++++++++++++++ Lib/functools.py | 12 ++++++++---- Lib/test/test_functools.py | 19 ++++++++++++------- .../2019-05-01-20-41-53.bpo-36772.fV2K0F.rst | 2 ++ 5 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 16a779fa836858..8b8b1f80a622e7 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -76,7 +76,8 @@ The :mod:`functools` module defines the following functions: .. versionadded:: 3.2 -.. decorator:: lru_cache(maxsize=128, typed=False) +.. decorator:: lru_cache(user_function) + lru_cache(maxsize=128, typed=False) Decorator to wrap a function with a memoizing callable that saves up to the *maxsize* most recent calls. It can save time when an expensive or I/O bound @@ -90,6 +91,15 @@ The :mod:`functools` module defines the following functions: differ in their keyword argument order and may have two separate cache entries. + If *user_function* is specified, it must be a callable. This allows the + *lru_cache* decorator to be applied directly to a user function, leaving + the *maxsize* at its default value of 128:: + + @lru_cache + def count_vowels(sentence): + sentence = sentence.casefold() + return sum(sentence.count(vowel) for vowel in 'aeiou') + If *maxsize* is set to ``None``, the LRU feature is disabled and the cache can grow without bound. The LRU feature performs best when *maxsize* is a power-of-two. @@ -165,6 +175,9 @@ The :mod:`functools` module defines the following functions: .. versionchanged:: 3.3 Added the *typed* option. + .. versionchanged:: 3.8 + Added the *user_function* option. + .. decorator:: total_ordering Given a class defining one or more rich comparison ordering methods, this diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index a94aba6b2c987f..1180469ff28f65 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -291,6 +291,23 @@ where the DLL is stored (if a full or partial path is used to load the initial DLL) and paths added by :func:`~os.add_dll_directory`. +functools +--------- + +:func:`functools.lru_cache` can now be used as a straight decorator rather +than as a function returning a decorator. So both of these are now supported:: + + @lru_cache + def f(x): + ... + + @lru_cache(maxsize=256) + def f(x): + ... + +(Contributed by Raymond Hettinger in :issue:`36772`.) + + datetime -------- diff --git a/Lib/functools.py b/Lib/functools.py index c863341eec5f21..30964a6fe3d83a 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -518,14 +518,18 @@ def lru_cache(maxsize=128, typed=False): # The internals of the lru_cache are encapsulated for thread safety and # to allow the implementation to change (including a possible C version). - # Early detection of an erroneous call to @lru_cache without any arguments - # resulting in the inner function being passed to maxsize instead of an - # integer or None. Negative maxsize is treated as 0. if isinstance(maxsize, int): + # Negative maxsize is treated as 0 if maxsize < 0: maxsize = 0 + elif callable(maxsize) and isinstance(typed, bool): + # The user_function was passed in directly via the maxsize argument + user_function, maxsize = maxsize, 128 + wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) + return update_wrapper(wrapper, user_function) elif maxsize is not None: - raise TypeError('Expected maxsize to be an integer or None') + raise TypeError( + 'Expected first argument to be an integer, a callable, or None') def decorating_function(user_function): wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index b89d77967a0df2..8fee1c6afdd450 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -1251,6 +1251,18 @@ def f(x): self.assertEqual(misses, 4) self.assertEqual(currsize, 2) + def test_lru_no_args(self): + @self.module.lru_cache + def square(x): + return x ** 2 + + self.assertEqual(list(map(square, [10, 20, 10])), + [100, 400, 100]) + self.assertEqual(square.cache_info().hits, 1) + self.assertEqual(square.cache_info().misses, 2) + self.assertEqual(square.cache_info().maxsize, 128) + self.assertEqual(square.cache_info().currsize, 2) + def test_lru_bug_35780(self): # C version of the lru_cache was not checking to see if # the user function call has already modified the cache @@ -1582,13 +1594,6 @@ def __eq__(self, other): self.assertEqual(test_func(DoubleEq(2)), # Trigger a re-entrant __eq__ call DoubleEq(2)) # Verify the correct return value - def test_early_detection_of_bad_call(self): - # Issue #22184 - with self.assertRaises(TypeError): - @functools.lru_cache - def f(): - pass - def test_lru_method(self): class X(int): f_cnt = 0 diff --git a/Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst b/Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst new file mode 100644 index 00000000000000..00b8a684f9a7ac --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst @@ -0,0 +1,2 @@ +functools.lru_cache() can now be used as a straight decorator in +addition to its existing usage as a function that returns a decorator. From 2f0bfd27a5e3a9a7cbeb2ddd45ce50c3d4bdb4e9 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Mon, 27 May 2019 00:54:13 +0100 Subject: [PATCH 119/441] Add one more test for typing.Final (GH-13588) --- Lib/test/test_typing.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 088db9c012066d..46b7621182d6fd 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1772,6 +1772,11 @@ def test_default_globals(self): hints = get_type_hints(ns['C'].foo) self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']}) + def test_final_forward_ref(self): + self.assertEqual(gth(Loop, globals())['attr'], Final[Loop]) + self.assertNotEqual(gth(Loop, globals())['attr'], Final[int]) + self.assertNotEqual(gth(Loop, globals())['attr'], Final) + class OverloadTests(BaseTestCase): @@ -1858,6 +1863,9 @@ class CSub(B): class G(Generic[T]): lst: ClassVar[List[T]] = [] +class Loop: + attr: Final['Loop'] + class NoneAndForward: parent: 'NoneAndForward' meaning: None From 71c52e3048dd07567f0c690eab4e5d57be66f534 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 27 May 2019 08:57:14 +0200 Subject: [PATCH 120/441] bpo-36829: Add _PyErr_WriteUnraisableMsg() (GH-13488) * sys.unraisablehook: add 'err_msg' field to UnraisableHookArgs. * Use _PyErr_WriteUnraisableMsg() in _ctypes _DictRemover_call() and gc delete_garbage(). --- Doc/library/sys.rst | 5 +++ Include/cpython/pyerrors.h | 3 ++ Lib/test/test_sys.py | 44 +++++++++++-------- Modules/_ctypes/_ctypes.c | 6 +-- Modules/_testcapimodule.c | 17 ++++++-- Modules/gcmodule.c | 5 +-- Python/clinic/sysmodule.c.h | 9 ++-- Python/errors.c | 84 +++++++++++++++++++++++++++++++------ Python/sysmodule.c | 9 ++-- 9 files changed, 135 insertions(+), 47 deletions(-) diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 0294f74368c0fa..51a208ee60405d 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1566,11 +1566,16 @@ always available. * *exc_type*: Exception type. * *exc_value*: Exception value, can be ``None``. * *exc_traceback*: Exception traceback, can be ``None``. + * *err_msg*: Error message, can be ``None``. * *object*: Object causing the exception, can be ``None``. :func:`sys.unraisablehook` can be overridden to control how unraisable exceptions are handled. + The default hook formats *err_msg* and *object* as: + ``f'{err_msg}: {object!r}'``; use "Exception ignored in" error message + if *err_msg* is ``None``. + See also :func:`excepthook` which handles uncaught exceptions. .. versionadded:: 3.8 diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index de6548dc9c0bb5..6b0ccedac52dab 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -171,6 +171,9 @@ PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( const char *reason /* UTF-8 encoded string */ ); +PyAPI_FUNC(void) _PyErr_WriteUnraisableMsg( + const char *err_msg, + PyObject *obj); #ifdef __cplusplus } diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 1e5f168f30bdf1..dfe63b1aade2eb 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -878,31 +878,38 @@ def test__enablelegacywindowsfsencoding(self): @test.support.cpython_only class UnraisableHookTest(unittest.TestCase): - def write_unraisable_exc(self, exc, obj): + def write_unraisable_exc(self, exc, err_msg, obj): import _testcapi import types + err_msg2 = f"Exception ignored {err_msg}" try: - _testcapi.write_unraisable_exc(exc, obj) + _testcapi.write_unraisable_exc(exc, err_msg, obj) return types.SimpleNamespace(exc_type=type(exc), exc_value=exc, exc_traceback=exc.__traceback__, + err_msg=err_msg2, object=obj) finally: # Explicitly break any reference cycle exc = None def test_original_unraisablehook(self): - obj = "an object" - - with test.support.captured_output("stderr") as stderr: - with test.support.swap_attr(sys, 'unraisablehook', - sys.__unraisablehook__): - self.write_unraisable_exc(ValueError(42), obj) - - err = stderr.getvalue() - self.assertIn(f'Exception ignored in: {obj!r}\n', err) - self.assertIn('Traceback (most recent call last):\n', err) - self.assertIn('ValueError: 42\n', err) + for err_msg in (None, "original hook"): + with self.subTest(err_msg=err_msg): + obj = "an object" + + with test.support.captured_output("stderr") as stderr: + with test.support.swap_attr(sys, 'unraisablehook', + sys.__unraisablehook__): + self.write_unraisable_exc(ValueError(42), err_msg, obj) + + err = stderr.getvalue() + if err_msg is not None: + self.assertIn(f'Exception ignored {err_msg}: {obj!r}\n', err) + else: + self.assertIn(f'Exception ignored in: {obj!r}\n', err) + self.assertIn('Traceback (most recent call last):\n', err) + self.assertIn('ValueError: 42\n', err) def test_original_unraisablehook_err(self): # bpo-22836: PyErr_WriteUnraisable() should give sensible reports @@ -962,8 +969,9 @@ def hook_func(args): obj = object() try: with test.support.swap_attr(sys, 'unraisablehook', hook_func): - expected = self.write_unraisable_exc(ValueError(42), obj) - for attr in "exc_type exc_value exc_traceback object".split(): + expected = self.write_unraisable_exc(ValueError(42), + "custom hook", obj) + for attr in "exc_type exc_value exc_traceback err_msg object".split(): self.assertEqual(getattr(hook_args, attr), getattr(expected, attr), (hook_args, expected)) @@ -978,10 +986,12 @@ def hook_func(*args): with test.support.captured_output("stderr") as stderr: with test.support.swap_attr(sys, 'unraisablehook', hook_func): - self.write_unraisable_exc(ValueError(42), None) + self.write_unraisable_exc(ValueError(42), + "custom hook fail", None) err = stderr.getvalue() - self.assertIn(f'Exception ignored in: {hook_func!r}\n', + self.assertIn(f'Exception ignored in sys.unraisablehook: ' + f'{hook_func!r}\n', err) self.assertIn('Traceback (most recent call last):\n', err) self.assertIn('Exception: hook_func failed\n', err) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index f4eb53657dd408..21b08f8e332d44 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -150,9 +150,9 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) { DictRemoverObject *self = (DictRemoverObject *)myself; if (self->key && self->dict) { - if (-1 == PyDict_DelItem(self->dict, self->key)) - /* XXX Error context */ - PyErr_WriteUnraisable(Py_None); + if (-1 == PyDict_DelItem(self->dict, self->key)) { + _PyErr_WriteUnraisableMsg("on calling _ctypes.DictRemover", NULL); + } Py_CLEAR(self->key); Py_CLEAR(self->dict); } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 7945f498f9e2e7..51e5d80d1f51b3 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4985,13 +4985,24 @@ negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) static PyObject* test_write_unraisable_exc(PyObject *self, PyObject *args) { - PyObject *exc, *obj; - if (!PyArg_ParseTuple(args, "OO", &exc, &obj)) { + PyObject *exc, *err_msg, *obj; + if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) { return NULL; } + const char *err_msg_utf8; + if (err_msg != Py_None) { + err_msg_utf8 = PyUnicode_AsUTF8(err_msg); + if (err_msg_utf8 == NULL) { + return NULL; + } + } + else { + err_msg_utf8 = NULL; + } + PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); - PyErr_WriteUnraisable(obj); + _PyErr_WriteUnraisableMsg(err_msg_utf8, obj); Py_RETURN_NONE; } diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index be9b73a8446073..3b15c7ba5b6284 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -929,9 +929,8 @@ delete_garbage(struct _gc_runtime_state *state, Py_INCREF(op); (void) clear(op); if (PyErr_Occurred()) { - PySys_WriteStderr("Exception ignored in tp_clear of " - "%.50s\n", Py_TYPE(op)->tp_name); - PyErr_WriteUnraisable(NULL); + _PyErr_WriteUnraisableMsg("in tp_clear of", + (PyObject*)Py_TYPE(op)); } Py_DECREF(op); } diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 2a4ec72b0dc34e..5df8af1a1172c6 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -106,9 +106,10 @@ PyDoc_STRVAR(sys_unraisablehook__doc__, "The unraisable argument has the following attributes:\n" "\n" "* exc_type: Exception type.\n" -"* exc_value: Exception value.\n" -"* exc_tb: Exception traceback, can be None.\n" -"* obj: Object causing the exception, can be None."); +"* exc_value: Exception value, can be None.\n" +"* exc_traceback: Exception traceback, can be None.\n" +"* err_msg: Error message, can be None.\n" +"* object: Object causing the exception, can be None."); #define SYS_UNRAISABLEHOOK_METHODDEF \ {"unraisablehook", (PyCFunction)sys_unraisablehook, METH_O, sys_unraisablehook__doc__}, @@ -1108,4 +1109,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=3c32bc91ec659509 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=03da2eb03135d9f2 input=a9049054013a1b77]*/ diff --git a/Python/errors.c b/Python/errors.c index e721f1915da407..831f111eead207 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1077,6 +1077,7 @@ static PyStructSequence_Field UnraisableHookArgs_fields[] = { {"exc_type", "Exception type"}, {"exc_value", "Exception value"}, {"exc_traceback", "Exception traceback"}, + {"err_msg", "Error message"}, {"object", "Object causing the exception"}, {0} }; @@ -1085,7 +1086,7 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = { .name = "UnraisableHookArgs", .doc = UnraisableHookArgs__doc__, .fields = UnraisableHookArgs_fields, - .n_in_sequence = 4 + .n_in_sequence = 5 }; @@ -1104,7 +1105,8 @@ _PyErr_Init(void) static PyObject * make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, PyObject *obj) + PyObject *exc_value, PyObject *exc_tb, + PyObject *err_msg, PyObject *obj) { PyObject *args = PyStructSequence_New(&UnraisableHookArgsType); if (args == NULL) { @@ -1125,6 +1127,7 @@ make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, ADD_ITEM(exc_type); ADD_ITEM(exc_value); ADD_ITEM(exc_tb); + ADD_ITEM(err_msg); ADD_ITEM(obj); #undef ADD_ITEM @@ -1145,11 +1148,21 @@ make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, static int write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb, - PyObject *obj, PyObject *file) + PyObject *err_msg, PyObject *obj, PyObject *file) { if (obj != NULL && obj != Py_None) { - if (PyFile_WriteString("Exception ignored in: ", file) < 0) { - return -1; + if (err_msg != NULL && err_msg != Py_None) { + if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { + return -1; + } + if (PyFile_WriteString(": ", file) < 0) { + return -1; + } + } + else { + if (PyFile_WriteString("Exception ignored in: ", file) < 0) { + return -1; + } } if (PyFile_WriteObject(obj, file, 0) < 0) { @@ -1162,6 +1175,14 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, return -1; } } + else if (err_msg != NULL && err_msg != Py_None) { + if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) { + return -1; + } + if (PyFile_WriteString(":\n", file) < 0) { + return -1; + } + } if (exc_tb != NULL && exc_tb != Py_None) { if (PyTraceBack_Print(exc_tb, file) < 0) { @@ -1178,8 +1199,9 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, const char *className = PyExceptionClass_Name(exc_type); if (className != NULL) { const char *dot = strrchr(className, '.'); - if (dot != NULL) + if (dot != NULL) { className = dot+1; + } } _Py_IDENTIFIER(__module__); @@ -1238,7 +1260,8 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, static int write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, - PyObject *exc_value, PyObject *exc_tb, PyObject *obj) + PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg, + PyObject *obj) { PyObject *file = _PySys_GetObjectId(&PyId_stderr); if (file == NULL || file == Py_None) { @@ -1249,7 +1272,7 @@ write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type, while we use it */ Py_INCREF(file); int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb, - obj, file); + err_msg, obj, file); Py_DECREF(file); return res; @@ -1272,9 +1295,10 @@ _PyErr_WriteUnraisableDefaultHook(PyObject *args) PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); - PyObject *obj = PyStructSequence_GET_ITEM(args, 3); + PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3); + PyObject *obj = PyStructSequence_GET_ITEM(args, 4); - if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, obj) < 0) { + if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) { return NULL; } Py_RETURN_NONE; @@ -1287,13 +1311,18 @@ _PyErr_WriteUnraisableDefaultHook(PyObject *args) for Python to handle it. For example, when a destructor raises an exception or during garbage collection (gc.collect()). + If err_msg_str is non-NULL, the error message is formatted as: + "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in" + error message. + An exception must be set when calling this function. */ void -PyErr_WriteUnraisable(PyObject *obj) +_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj) { PyThreadState *tstate = _PyThreadState_GET(); assert(tstate != NULL); + PyObject *err_msg = NULL; PyObject *exc_type, *exc_value, *exc_tb; _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); @@ -1322,13 +1351,20 @@ PyErr_WriteUnraisable(PyObject *obj) } } + if (err_msg_str != NULL) { + err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str); + if (err_msg == NULL) { + PyErr_Clear(); + } + } + _Py_IDENTIFIER(unraisablehook); PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook); if (hook != NULL && hook != Py_None) { PyObject *hook_args; hook_args = make_unraisable_hook_args(tstate, exc_type, exc_value, - exc_tb, obj); + exc_tb, err_msg, obj); if (hook_args != NULL) { PyObject *args[1] = {hook_args}; PyObject *res = _PyObject_FastCall(hook, args, 1); @@ -1337,6 +1373,18 @@ PyErr_WriteUnraisable(PyObject *obj) Py_DECREF(res); goto done; } + + err_msg_str = "Exception ignored in sys.unraisablehook"; + } + else { + err_msg_str = ("Exception ignored on building " + "sys.unraisablehook arguments"); + } + + Py_XDECREF(err_msg); + err_msg = PyUnicode_FromString(err_msg_str); + if (err_msg == NULL) { + PyErr_Clear(); } /* sys.unraisablehook failed: log its error using default hook */ @@ -1350,15 +1398,25 @@ PyErr_WriteUnraisable(PyObject *obj) default_hook: /* Call the default unraisable hook (ignore failure) */ - (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, obj); + (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, + err_msg, obj); done: Py_XDECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); + Py_XDECREF(err_msg); _PyErr_Clear(tstate); /* Just in case */ } + +void +PyErr_WriteUnraisable(PyObject *obj) +{ + _PyErr_WriteUnraisableMsg(NULL, obj); +} + + extern PyObject *PyModule_GetWarningsModule(void); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 5ebeacf0b7f399..08a1a2995e004e 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -689,14 +689,15 @@ Handle an unraisable exception. The unraisable argument has the following attributes: * exc_type: Exception type. -* exc_value: Exception value. -* exc_tb: Exception traceback, can be None. -* obj: Object causing the exception, can be None. +* exc_value: Exception value, can be None. +* exc_traceback: Exception traceback, can be None. +* err_msg: Error message, can be None. +* object: Object causing the exception, can be None. [clinic start generated code]*/ static PyObject * sys_unraisablehook(PyObject *module, PyObject *unraisable) -/*[clinic end generated code: output=bb92838b32abaa14 input=fdbdb47fdd0bee06]*/ +/*[clinic end generated code: output=bb92838b32abaa14 input=ec3af148294af8d3]*/ { return _PyErr_WriteUnraisableDefaultHook(unraisable); } From 16cefb0bc7b05c08caf08525398ff178c35dece4 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 27 May 2019 13:42:29 +0200 Subject: [PATCH 121/441] bpo-37028: asyncio REPL; activated via 'python -m asyncio'. (GH-13472) This makes it easy to play with asyncio APIs with simply using async/await in the REPL. --- Lib/asyncio/__main__.py | 125 ++++++++++++++++++ .../2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst | 1 + 2 files changed, 126 insertions(+) create mode 100644 Lib/asyncio/__main__.py create mode 100644 Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst diff --git a/Lib/asyncio/__main__.py b/Lib/asyncio/__main__.py new file mode 100644 index 00000000000000..18bb87a5bc4ffd --- /dev/null +++ b/Lib/asyncio/__main__.py @@ -0,0 +1,125 @@ +import ast +import asyncio +import code +import concurrent.futures +import inspect +import sys +import threading +import types +import warnings + +from . import futures + + +class AsyncIOInteractiveConsole(code.InteractiveConsole): + + def __init__(self, locals, loop): + super().__init__(locals) + self.compile.compiler.flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT + + self.loop = loop + + def runcode(self, code): + future = concurrent.futures.Future() + + def callback(): + global repl_future + global repl_future_interrupted + + repl_future = None + repl_future_interrupted = False + + func = types.FunctionType(code, self.locals) + try: + coro = func() + except SystemExit: + raise + except KeyboardInterrupt as ex: + repl_future_interrupted = True + future.set_exception(ex) + return + except BaseException as ex: + future.set_exception(ex) + return + + if not inspect.iscoroutine(coro): + future.set_result(coro) + return + + try: + repl_future = self.loop.create_task(coro) + futures._chain_future(repl_future, future) + except BaseException as exc: + future.set_exception(exc) + + loop.call_soon_threadsafe(callback) + + try: + return future.result() + except SystemExit: + raise + except BaseException: + if repl_future_interrupted: + self.write("\nKeyboardInterrupt\n") + else: + self.showtraceback() + + +class REPLThread(threading.Thread): + + def run(self): + try: + banner = ( + f'asyncio REPL {sys.version} on {sys.platform}\n' + f'Use "await" directly instead of "asyncio.run()".\n' + f'Type "help", "copyright", "credits" or "license" ' + f'for more information.\n' + f'{getattr(sys, "ps1", ">>> ")}import asyncio' + ) + + console.interact( + banner=banner, + exitmsg='exiting asyncio REPL...') + finally: + warnings.filterwarnings( + 'ignore', + message=r'^coroutine .* was never awaited$', + category=RuntimeWarning) + + loop.call_soon_threadsafe(loop.stop) + + +if __name__ == '__main__': + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + + repl_locals = {'asyncio': asyncio} + for key in {'__name__', '__package__', + '__loader__', '__spec__', + '__builtins__', '__file__'}: + repl_locals[key] = locals()[key] + + console = AsyncIOInteractiveConsole(repl_locals, loop) + + repl_future = None + repl_future_interrupted = False + + try: + import readline # NoQA + except ImportError: + pass + + repl_thread = REPLThread() + repl_thread.daemon = True + repl_thread.start() + + while True: + try: + loop.run_forever() + except KeyboardInterrupt: + if repl_future and not repl_future.done(): + repl_future.cancel() + repl_future_interrupted = True + continue + else: + break diff --git a/Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst b/Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst new file mode 100644 index 00000000000000..d9db21fb6f3c96 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst @@ -0,0 +1 @@ +Implement asyncio REPL From 431b540bf79f0982559b1b0e420b1b085f667bb7 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 27 May 2019 14:45:12 +0200 Subject: [PATCH 122/441] bpo-32528: Make asyncio.CancelledError a BaseException. (GH-13528) This will address the common mistake many asyncio users make: an "except Exception" clause breaking Tasks cancellation. In addition to this change, we stop inheriting asyncio.TimeoutError and asyncio.InvalidStateError from their concurrent.futures.* counterparts. There's no point for these exceptions to share the inheritance chain. In 3.9 we'll focus on implementing supervisors and cancel scopes, which should allow better handling of all exceptions, including SystemExit and KeyboardInterrupt --- Lib/asyncio/base_events.py | 16 ++-- Lib/asyncio/base_subprocess.py | 4 +- Lib/asyncio/events.py | 4 +- Lib/asyncio/exceptions.py | 9 +-- Lib/asyncio/proactor_events.py | 12 ++- Lib/asyncio/selector_events.py | 76 ++++++++++++++----- Lib/asyncio/sslproto.py | 16 +++- Lib/asyncio/staggered.py | 4 +- Lib/asyncio/tasks.py | 10 ++- Lib/asyncio/transports.py | 8 +- Lib/asyncio/unix_events.py | 20 +++-- Lib/asyncio/windows_events.py | 4 +- Lib/test/test_asyncio/test_base_events.py | 6 +- Lib/test/test_asyncio/test_tasks.py | 4 +- .../2019-05-23-17-37-22.bpo-32528.sGnkcl.rst | 8 ++ Modules/_asynciomodule.c | 11 +-- 16 files changed, 146 insertions(+), 66 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index de9fa4f4f7f3b6..63b072b851e3ea 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -186,7 +186,7 @@ def _interleave_addrinfos(addrinfos, first_address_family_count=1): def _run_until_complete_cb(fut): if not fut.cancelled(): exc = fut.exception() - if isinstance(exc, BaseException) and not isinstance(exc, Exception): + if isinstance(exc, (SystemExit, KeyboardInterrupt)): # Issue #22429: run_forever() already finished, no need to # stop it. return @@ -1196,7 +1196,7 @@ async def start_tls(self, transport, protocol, sslcontext, *, try: await waiter - except Exception: + except BaseException: transport.close() conmade_cb.cancel() resume_cb.cancel() @@ -1710,7 +1710,9 @@ def call_exception_handler(self, context): if self._exception_handler is None: try: self.default_exception_handler(context) - except Exception: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException: # Second protection layer for unexpected errors # in the default implementation, as well as for subclassed # event loops with overloaded "default_exception_handler". @@ -1719,7 +1721,9 @@ def call_exception_handler(self, context): else: try: self._exception_handler(self, context) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: # Exception in the user set custom exception handler. try: # Let's try default handler. @@ -1728,7 +1732,9 @@ def call_exception_handler(self, context): 'exception': exc, 'context': context, }) - except Exception: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException: # Guard 'default_exception_handler' in case it is # overloaded. logger.error('Exception in default exception handler ' diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index f503f78fdda349..14d50519228814 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -182,7 +182,9 @@ async def _connect_pipes(self, waiter): for callback, data in self._pending_calls: loop.call_soon(callback, *data) self._pending_calls = None - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: if waiter is not None and not waiter.cancelled(): waiter.set_exception(exc) else: diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 9a923514db0993..d381b1c596239c 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -79,7 +79,9 @@ def cancelled(self): def _run(self): try: self._context.run(self._callback, *self._args) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: cb = format_helpers._format_callback_source( self._callback, self._args) msg = f'Exception in callback {cb}' diff --git a/Lib/asyncio/exceptions.py b/Lib/asyncio/exceptions.py index cac31a54d2531a..e03602ef576234 100644 --- a/Lib/asyncio/exceptions.py +++ b/Lib/asyncio/exceptions.py @@ -5,19 +5,16 @@ 'IncompleteReadError', 'LimitOverrunError', 'SendfileNotAvailableError') -import concurrent.futures -from . import base_futures - -class CancelledError(concurrent.futures.CancelledError): +class CancelledError(BaseException): """The Future or Task was cancelled.""" -class TimeoutError(concurrent.futures.TimeoutError): +class TimeoutError(Exception): """The operation exceeded the given deadline.""" -class InvalidStateError(concurrent.futures.InvalidStateError): +class InvalidStateError(Exception): """The operation is not allowed in this state.""" diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index a849be1cc1479b..7dfe29579a0dee 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -212,7 +212,9 @@ def _eof_received(self): try: keep_open = self._protocol.eof_received() - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error( exc, 'Fatal error: protocol.eof_received() call failed.') return @@ -235,7 +237,9 @@ def _data_received(self, data): if isinstance(self._protocol, protocols.BufferedProtocol): try: protocols._feed_data_to_buffered_proto(self._protocol, data) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error(exc, 'Fatal error: protocol.buffer_updated() ' 'call failed.') @@ -625,7 +629,9 @@ def _loop_self_reading(self, f=None): except exceptions.CancelledError: # _close_self_pipe() has been called, stop waiting for data return - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self.call_exception_handler({ 'message': 'Error on reading from the event loop self pipe', 'exception': exc, diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 6461d3077633d0..f5f43a9bfef33a 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -208,12 +208,14 @@ async def _accept_connection2( try: await waiter - except: + except BaseException: transport.close() raise + # It's now up to the protocol to handle the connection. - # It's now up to the protocol to handle the connection. - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: if self._debug: context = { 'message': @@ -370,7 +372,9 @@ def _sock_recv(self, fut, sock, n): data = sock.recv(n) except (BlockingIOError, InterruptedError): return # try again next time - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: fut.set_exception(exc) else: fut.set_result(data) @@ -404,7 +408,9 @@ def _sock_recv_into(self, fut, sock, buf): nbytes = sock.recv_into(buf) except (BlockingIOError, InterruptedError): return # try again next time - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: fut.set_exception(exc) else: fut.set_result(nbytes) @@ -447,7 +453,9 @@ def _sock_sendall(self, fut, sock, view, pos): n = sock.send(view[start:]) except (BlockingIOError, InterruptedError): return - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: fut.set_exception(exc) return @@ -487,7 +495,9 @@ def _sock_connect(self, fut, sock, address): fut.add_done_callback( functools.partial(self._sock_write_done, fd)) self.add_writer(fd, self._sock_connect_cb, fut, sock, address) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: fut.set_exception(exc) else: fut.set_result(None) @@ -507,7 +517,9 @@ def _sock_connect_cb(self, fut, sock, address): except (BlockingIOError, InterruptedError): # socket is still registered, the callback will be retried later pass - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: fut.set_exception(exc) else: fut.set_result(None) @@ -537,7 +549,9 @@ def _sock_accept(self, fut, registered, sock): conn.setblocking(False) except (BlockingIOError, InterruptedError): self.add_reader(fd, self._sock_accept, fut, True, sock) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: fut.set_exception(exc) else: fut.set_result((conn, address)) @@ -785,7 +799,9 @@ def _read_ready__get_buffer(self): buf = self._protocol.get_buffer(-1) if not len(buf): raise RuntimeError('get_buffer() returned an empty buffer') - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error( exc, 'Fatal error: protocol.get_buffer() call failed.') return @@ -794,7 +810,9 @@ def _read_ready__get_buffer(self): nbytes = self._sock.recv_into(buf) except (BlockingIOError, InterruptedError): return - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error(exc, 'Fatal read error on socket transport') return @@ -804,7 +822,9 @@ def _read_ready__get_buffer(self): try: self._protocol.buffer_updated(nbytes) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error( exc, 'Fatal error: protocol.buffer_updated() call failed.') @@ -815,7 +835,9 @@ def _read_ready__data_received(self): data = self._sock.recv(self.max_size) except (BlockingIOError, InterruptedError): return - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error(exc, 'Fatal read error on socket transport') return @@ -825,7 +847,9 @@ def _read_ready__data_received(self): try: self._protocol.data_received(data) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error( exc, 'Fatal error: protocol.data_received() call failed.') @@ -835,7 +859,9 @@ def _read_ready__on_eof(self): try: keep_open = self._protocol.eof_received() - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error( exc, 'Fatal error: protocol.eof_received() call failed.') return @@ -871,7 +897,9 @@ def write(self, data): n = self._sock.send(data) except (BlockingIOError, InterruptedError): pass - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error(exc, 'Fatal write error on socket transport') return else: @@ -894,7 +922,9 @@ def _write_ready(self): n = self._sock.send(self._buffer) except (BlockingIOError, InterruptedError): pass - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._loop._remove_writer(self._sock_fd) self._buffer.clear() self._fatal_error(exc, 'Fatal write error on socket transport') @@ -970,7 +1000,9 @@ def _read_ready(self): pass except OSError as exc: self._protocol.error_received(exc) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error(exc, 'Fatal read error on datagram transport') else: self._protocol.datagram_received(data, addr) @@ -1007,7 +1039,9 @@ def sendto(self, data, addr=None): except OSError as exc: self._protocol.error_received(exc) return - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error( exc, 'Fatal write error on datagram transport') return @@ -1030,7 +1064,9 @@ def _sendto_ready(self): except OSError as exc: self._protocol.error_received(exc) return - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._fatal_error( exc, 'Fatal write error on datagram transport') return diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 97a6fc66a92735..8546985fe63fc6 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -527,7 +527,9 @@ def data_received(self, data): try: ssldata, appdata = self._sslpipe.feed_ssldata(data) - except Exception as e: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as e: self._fatal_error(e, 'SSL error in data received') return @@ -542,7 +544,9 @@ def data_received(self, data): self._app_protocol, chunk) else: self._app_protocol.data_received(chunk) - except Exception as ex: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as ex: self._fatal_error( ex, 'application protocol failed to receive SSL data') return @@ -628,7 +632,9 @@ def _on_handshake_complete(self, handshake_exc): raise handshake_exc peercert = sslobj.getpeercert() - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: if isinstance(exc, ssl.CertificateError): msg = 'SSL handshake failed on verifying the certificate' else: @@ -691,7 +697,9 @@ def _process_write_backlog(self): # delete it and reduce the outstanding buffer size. del self._write_backlog[0] self._write_buffer_size -= len(data) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: if self._in_handshake: # Exceptions will be re-raised in _on_handshake_complete. self._on_handshake_complete(exc) diff --git a/Lib/asyncio/staggered.py b/Lib/asyncio/staggered.py index feec681b4371bf..27c665a9910ab2 100644 --- a/Lib/asyncio/staggered.py +++ b/Lib/asyncio/staggered.py @@ -105,7 +105,9 @@ async def run_one_coro( try: result = await coro_fn() - except Exception as e: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as e: exceptions[this_index] = e this_failed.set() # Kickstart the next coroutine else: diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 1dc595298c556d..78e76003b3ac22 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -260,11 +260,11 @@ def __step(self, exc=None): super().set_result(exc.value) except exceptions.CancelledError: super().cancel() # I.e., Future.cancel(self). - except Exception as exc: + except (KeyboardInterrupt, SystemExit) as exc: super().set_exception(exc) + raise except BaseException as exc: super().set_exception(exc) - raise else: blocking = getattr(result, '_asyncio_future_blocking', None) if blocking is not None: @@ -318,7 +318,7 @@ def __step(self, exc=None): def __wakeup(self, future): try: future.result() - except Exception as exc: + except BaseException as exc: # This may also be a cancellation. self.__step(exc) else: @@ -858,7 +858,9 @@ def run_coroutine_threadsafe(coro, loop): def callback(): try: futures._chain_future(ensure_future(coro, loop=loop), future) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: if future.set_running_or_notify_cancel(): future.set_exception(exc) raise diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 233bbb53cb6a3f..47b37fa9b7f0f6 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -262,7 +262,9 @@ def _maybe_pause_protocol(self): self._protocol_paused = True try: self._protocol.pause_writing() - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._loop.call_exception_handler({ 'message': 'protocol.pause_writing() failed', 'exception': exc, @@ -276,7 +278,9 @@ def _maybe_resume_protocol(self): self._protocol_paused = False try: self._protocol.resume_writing() - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._loop.call_exception_handler({ 'message': 'protocol.resume_writing() failed', 'exception': exc, diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 1aa3b396086c59..81d10b190cc6de 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -194,7 +194,9 @@ async def _make_subprocess_transport(self, protocol, args, shell, self._child_watcher_callback, transp) try: await waiter - except Exception: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException: transp.close() await transp._wait() raise @@ -390,7 +392,9 @@ def _sock_sendfile_native_impl(self, fut, registered_fd, sock, fileno, else: self._sock_sendfile_update_filepos(fileno, offset, total_sent) fut.set_exception(exc) - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._sock_sendfile_update_filepos(fileno, offset, total_sent) fut.set_exception(exc) else: @@ -641,7 +645,9 @@ def write(self, data): n = os.write(self._fileno, data) except (BlockingIOError, InterruptedError): n = 0 - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._conn_lost += 1 self._fatal_error(exc, 'Fatal write error on pipe transport') return @@ -661,7 +667,9 @@ def _write_ready(self): n = os.write(self._fileno, self._buffer) except (BlockingIOError, InterruptedError): pass - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: self._buffer.clear() self._conn_lost += 1 # Remove writer here, _fatal_error() doesn't it @@ -879,7 +887,9 @@ def attach_loop(self, loop): def _sig_chld(self): try: self._do_waitpid_all() - except Exception as exc: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: # self._loop should always be available here # as '_sig_chld' is added as a signal handler # in 'attach_loop' diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index 29750f18d80c46..b5b2e24c5ba4f3 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -388,7 +388,9 @@ async def _make_subprocess_transport(self, protocol, args, shell, **kwargs) try: await waiter - except Exception: + except (SystemExit, KeyboardInterrupt): + raise + except BaseException: transp.close() await transp._wait() raise diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index f068fc781f5d7c..31018c5c563637 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -476,7 +476,7 @@ def test_run_until_complete_loop(self): other_loop.run_until_complete, task) def test_run_until_complete_loop_orphan_future_close_loop(self): - class ShowStopper(BaseException): + class ShowStopper(SystemExit): pass async def foo(delay): @@ -487,10 +487,8 @@ def throw(): self.loop._process_events = mock.Mock() self.loop.call_soon(throw) - try: + with self.assertRaises(ShowStopper): self.loop.run_until_complete(foo(0.1)) - except ShowStopper: - pass # This call fails if run_until_complete does not clean up # done-callback for the previous future. diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 1c1f912ff8af5c..114dd76687cd70 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1527,7 +1527,7 @@ def gen(): async def sleeper(): await asyncio.sleep(10) - base_exc = BaseException() + base_exc = SystemExit() async def notmutch(): try: @@ -1541,7 +1541,7 @@ async def notmutch(): task.cancel() self.assertFalse(task.done()) - self.assertRaises(BaseException, test_utils.run_briefly, loop) + self.assertRaises(SystemExit, test_utils.run_briefly, loop) self.assertTrue(task.done()) self.assertFalse(task.cancelled()) diff --git a/Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst b/Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst new file mode 100644 index 00000000000000..375f426025d325 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst @@ -0,0 +1,8 @@ +Make asyncio.CancelledError a BaseException. + +This will address the common mistake many asyncio users make: an "except +Exception" clause breaking Tasks cancellation. + +In addition to this change, we stop inheriting asyncio.TimeoutError and +asyncio.InvalidStateError from their concurrent.futures.* counterparts. +There's no point for these exceptions to share the inheritance chain. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index f9037c279ac9c3..ac15d0169b8158 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2672,8 +2672,10 @@ task_step_impl(TaskObj *task, PyObject *exc) assert(o == Py_None); Py_DECREF(o); - if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) { - /* We've got a BaseException; re-raise it */ + if (PyErr_GivenExceptionMatches(et, PyExc_KeyboardInterrupt) || + PyErr_GivenExceptionMatches(et, PyExc_SystemExit)) + { + /* We've got a KeyboardInterrupt or a SystemError; re-raise it */ PyErr_Restore(et, ev, tb); goto fail; } @@ -2950,11 +2952,6 @@ task_wakeup(TaskObj *task, PyObject *o) } PyErr_Fetch(&et, &ev, &tb); - if (!PyErr_GivenExceptionMatches(et, PyExc_Exception)) { - /* We've got a BaseException; re-raise it */ - PyErr_Restore(et, ev, tb); - return NULL; - } if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject *) et)) { PyErr_NormalizeException(&et, &ev, &tb); } From ff6b2e66b19a26b4c2ab57e62e1ab9f3d94dd76a Mon Sep 17 00:00:00 2001 From: Xtreak Date: Mon, 27 May 2019 18:26:23 +0530 Subject: [PATCH 123/441] bpo-37047: Refactor AsyncMock setup logic for autospeccing (GH-13574) Handle late binding and attribute access in unittest.mock.AsyncMock setup for autospeccing. --- Doc/library/unittest.mock.rst | 6 +- Lib/unittest/mock.py | 59 ++++++++++------- Lib/unittest/test/testmock/testasync.py | 63 ++++++++++++++++++- .../2019-05-26-01-20-06.bpo-37047.K9epi8.rst | 3 + 4 files changed, 107 insertions(+), 24 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 163da9aecdbbc5..36ac24afa2bc07 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1945,7 +1945,7 @@ The full list of supported magic methods is: * Container methods: ``__getitem__``, ``__setitem__``, ``__delitem__``, ``__contains__``, ``__len__``, ``__iter__``, ``__reversed__`` and ``__missing__`` -* Context manager: ``__enter__`` and ``__exit__`` +* Context manager: ``__enter__``, ``__exit__``, ``__aenter`` and ``__aexit__`` * Unary numeric methods: ``__neg__``, ``__pos__`` and ``__invert__`` * The numeric methods (including right hand and in-place variants): ``__add__``, ``__sub__``, ``__mul__``, ``__matmul__``, ``__div__``, ``__truediv__``, @@ -1957,10 +1957,14 @@ The full list of supported magic methods is: * Pickling: ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``, ``__getstate__`` and ``__setstate__`` * File system path representation: ``__fspath__`` +* Asynchronous iteration methods: ``__aiter__`` and ``__anext__`` .. versionchanged:: 3.8 Added support for :func:`os.PathLike.__fspath__`. +.. versionchanged:: 3.8 + Added support for ``__aenter__``, ``__aexit__``, ``__aiter__`` and ``__anext__``. + The following methods exist but are *not* supported as they are either in use by mock, can't be set dynamically, or can cause problems: diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index b14bf01b28fdbd..b91afd88dd132e 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -51,6 +51,13 @@ def _is_async_obj(obj): return False +def _is_async_func(func): + if getattr(func, '__code__', None): + return asyncio.iscoroutinefunction(func) + else: + return False + + def _is_instance_mock(obj): # can't use isinstance on Mock objects because they override __class__ # The base class for all mocks is NonCallableMock @@ -225,6 +232,34 @@ def reset_mock(): mock._mock_delegate = funcopy +def _setup_async_mock(mock): + mock._is_coroutine = asyncio.coroutines._is_coroutine + mock.await_count = 0 + mock.await_args = None + mock.await_args_list = _CallList() + mock.awaited = _AwaitEvent(mock) + + # Mock is not configured yet so the attributes are set + # to a function and then the corresponding mock helper function + # is called when the helper is accessed similar to _setup_func. + def wrapper(attr, *args, **kwargs): + return getattr(mock.mock, attr)(*args, **kwargs) + + for attribute in ('assert_awaited', + 'assert_awaited_once', + 'assert_awaited_with', + 'assert_awaited_once_with', + 'assert_any_await', + 'assert_has_awaits', + 'assert_not_awaited'): + + # setattr(mock, attribute, wrapper) causes late binding + # hence attribute will always be the last value in the loop + # Use partial(wrapper, attribute) to ensure the attribute is bound + # correctly. + setattr(mock, attribute, partial(wrapper, attribute)) + + def _is_magic(name): return '__%s__' % name[2:-2] == name @@ -2151,7 +2186,7 @@ def assert_not_awaited(_mock_self): """ self = _mock_self if self.await_count != 0: - msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once." + msg = (f"Expected {self._mock_name or 'mock'} to not have been awaited." f" Awaited {self.await_count} times.") raise AssertionError(msg) @@ -2457,10 +2492,7 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, spec = type(spec) is_type = isinstance(spec, type) - if getattr(spec, '__code__', None): - is_async_func = asyncio.iscoroutinefunction(spec) - else: - is_async_func = False + is_async_func = _is_async_func(spec) _kwargs = {'spec': spec} if spec_set: _kwargs = {'spec_set': spec} @@ -2498,26 +2530,11 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, name=_name, **_kwargs) if isinstance(spec, FunctionTypes): - wrapped_mock = mock # should only happen at the top level because we don't # recurse for functions mock = _set_signature(mock, spec) if is_async_func: - mock._is_coroutine = asyncio.coroutines._is_coroutine - mock.await_count = 0 - mock.await_args = None - mock.await_args_list = _CallList() - - for a in ('assert_awaited', - 'assert_awaited_once', - 'assert_awaited_with', - 'assert_awaited_once_with', - 'assert_any_await', - 'assert_has_awaits', - 'assert_not_awaited'): - def f(*args, **kwargs): - return getattr(wrapped_mock, a)(*args, **kwargs) - setattr(mock, a, f) + _setup_async_mock(mock) else: _check_signature(spec, mock, is_type, instance) diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index a9aa1434b963f1..0519d59696f6c6 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -2,7 +2,8 @@ import inspect import unittest -from unittest.mock import call, AsyncMock, patch, MagicMock, create_autospec +from unittest.mock import (call, AsyncMock, patch, MagicMock, create_autospec, + _AwaitEvent) def tearDownModule(): @@ -20,6 +21,9 @@ def normal_method(self): async def async_func(): pass +async def async_func_args(a, b, *, c): + pass + def normal_func(): pass @@ -141,8 +145,63 @@ def test_create_autospec_instance(self): create_autospec(async_func, instance=True) def test_create_autospec(self): - spec = create_autospec(async_func) + spec = create_autospec(async_func_args) + awaitable = spec(1, 2, c=3) + async def main(): + await awaitable + + self.assertEqual(spec.await_count, 0) + self.assertIsNone(spec.await_args) + self.assertEqual(spec.await_args_list, []) + self.assertIsInstance(spec.awaited, _AwaitEvent) + spec.assert_not_awaited() + + asyncio.run(main()) + self.assertTrue(asyncio.iscoroutinefunction(spec)) + self.assertTrue(asyncio.iscoroutine(awaitable)) + self.assertEqual(spec.await_count, 1) + self.assertEqual(spec.await_args, call(1, 2, c=3)) + self.assertEqual(spec.await_args_list, [call(1, 2, c=3)]) + spec.assert_awaited_once() + spec.assert_awaited_once_with(1, 2, c=3) + spec.assert_awaited_with(1, 2, c=3) + spec.assert_awaited() + + def test_patch_with_autospec(self): + + async def test_async(): + with patch(f"{__name__}.async_func_args", autospec=True) as mock_method: + awaitable = mock_method(1, 2, c=3) + self.assertIsInstance(mock_method.mock, AsyncMock) + + self.assertTrue(asyncio.iscoroutinefunction(mock_method)) + self.assertTrue(asyncio.iscoroutine(awaitable)) + self.assertTrue(inspect.isawaitable(awaitable)) + + # Verify the default values during mock setup + self.assertEqual(mock_method.await_count, 0) + self.assertEqual(mock_method.await_args_list, []) + self.assertIsNone(mock_method.await_args) + self.assertIsInstance(mock_method.awaited, _AwaitEvent) + mock_method.assert_not_awaited() + + await awaitable + + self.assertEqual(mock_method.await_count, 1) + self.assertEqual(mock_method.await_args, call(1, 2, c=3)) + self.assertEqual(mock_method.await_args_list, [call(1, 2, c=3)]) + mock_method.assert_awaited_once() + mock_method.assert_awaited_once_with(1, 2, c=3) + mock_method.assert_awaited_with(1, 2, c=3) + mock_method.assert_awaited() + + mock_method.reset_mock() + self.assertEqual(mock_method.await_count, 0) + self.assertIsNone(mock_method.await_args) + self.assertEqual(mock_method.await_args_list, []) + + asyncio.run(test_async()) class AsyncSpecTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst b/Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst new file mode 100644 index 00000000000000..ace5a3a4417895 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst @@ -0,0 +1,3 @@ +Handle late binding and attribute access in :class:`unittest.mock.AsyncMock` +setup for autospeccing. Document newly implemented async methods in +:class:`unittest.mock.MagicMock`. From 1f39c28e489cca0397fc4c3675d13569318122ac Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 27 May 2019 16:28:34 +0300 Subject: [PATCH 124/441] bpo-37035: Don't log OSError (GH-13548) https://bugs.python.org/issue37035 --- Lib/asyncio/base_events.py | 7 ----- Lib/asyncio/proactor_events.py | 2 +- Lib/asyncio/selector_events.py | 2 +- Lib/asyncio/sslproto.py | 2 +- Lib/asyncio/unix_events.py | 2 +- Lib/test/test_asyncio/test_selector_events.py | 27 +++++++++++++++++-- Lib/test/test_asyncio/test_unix_events.py | 6 +---- .../2019-05-24-18-16-07.bpo-37035.HFbJVT.rst | 5 ++++ 8 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 63b072b851e3ea..ce4f1904f95056 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -59,13 +59,6 @@ # before cleanup of cancelled handles is performed. _MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5 -# Exceptions which must not call the exception handler in fatal error -# methods (_fatal_error()) -_FATAL_ERROR_IGNORE = (BrokenPipeError, - ConnectionResetError, ConnectionAbortedError) - -if ssl is not None: - _FATAL_ERROR_IGNORE = _FATAL_ERROR_IGNORE + (ssl.SSLCertVerificationError,) _HAS_IPv6 = hasattr(socket, 'AF_INET6') diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 7dfe29579a0dee..710f768718b477 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -96,7 +96,7 @@ def __del__(self, _warn=warnings.warn): def _fatal_error(self, exc, message='Fatal error on pipe transport'): try: - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index f5f43a9bfef33a..44c380ae62db66 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -685,7 +685,7 @@ def __del__(self, _warn=warnings.warn): def _fatal_error(self, exc, message='Fatal error on transport'): # Should be called from exception handler only. - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 8546985fe63fc6..3eca6b4a39128b 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -707,7 +707,7 @@ def _process_write_backlog(self): self._fatal_error(exc, 'Fatal error on SSL transport') def _fatal_error(self, exc, message='Fatal error on transport'): - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 81d10b190cc6de..28128d2977df64 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -724,7 +724,7 @@ def abort(self): def _fatal_error(self, exc, message='Fatal error on pipe transport'): # should be called by exception handler only - if isinstance(exc, base_events._FATAL_ERROR_IGNORE): + if isinstance(exc, OSError): if self._loop.get_debug(): logger.debug("%r: %s", self, message, exc_info=True) else: diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index bf721b0005b000..2e52e9df5c3b6e 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -448,10 +448,23 @@ def test_fatal_error(self, m_exc): tr._force_close = mock.Mock() tr._fatal_error(exc) + m_exc.assert_not_called() + + tr._force_close.assert_called_with(exc) + + @mock.patch('asyncio.log.logger.error') + def test_fatal_error_custom_exception(self, m_exc): + class MyError(Exception): + pass + exc = MyError() + tr = self.create_transport() + tr._force_close = mock.Mock() + tr._fatal_error(exc) + m_exc.assert_called_with( test_utils.MockPattern( 'Fatal error on transport\nprotocol:.*\ntransport:.*'), - exc_info=(OSError, MOCK_ANY, MOCK_ANY)) + exc_info=(MyError, MOCK_ANY, MOCK_ANY)) tr._force_close.assert_called_with(exc) @@ -1338,10 +1351,20 @@ def test_fatal_error_connected(self, m_exc): err = ConnectionRefusedError() transport._fatal_error(err) self.assertFalse(self.protocol.error_received.called) + m_exc.assert_not_called() + + @mock.patch('asyncio.base_events.logger.error') + def test_fatal_error_connected_custom_error(self, m_exc): + class MyException(Exception): + pass + transport = self.datagram_transport(address=('0.0.0.0', 1)) + err = MyException() + transport._fatal_error(err) + self.assertFalse(self.protocol.error_received.called) m_exc.assert_called_with( test_utils.MockPattern( 'Fatal error on transport\nprotocol:.*\ntransport:.*'), - exc_info=(ConnectionRefusedError, MOCK_ANY, MOCK_ANY)) + exc_info=(MyException, MOCK_ANY, MOCK_ANY)) if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 31e710037f76a3..ac84304ec99da6 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -977,11 +977,7 @@ def test__write_ready_err(self, m_write, m_logexc): self.assertFalse(self.loop.readers) self.assertEqual(bytearray(), tr._buffer) self.assertTrue(tr.is_closing()) - m_logexc.assert_called_with( - test_utils.MockPattern( - 'Fatal write error on pipe transport' - '\nprotocol:.*\ntransport:.*'), - exc_info=(OSError, MOCK_ANY, MOCK_ANY)) + m_logexc.assert_not_called() self.assertEqual(1, tr._conn_lost) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) diff --git a/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst b/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst new file mode 100644 index 00000000000000..004ec2d1371401 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst @@ -0,0 +1,5 @@ +Don't log OSError based exceptions if a fatal error has occurred in asyncio +transport. Peer can generate almost any OSError, user cannot avoid these exceptions +by fixing own code. +Errors are still propagated to user code, it's just logging them +is pointless and pollute asyncio logs. From 674ee1260025ff36f27e5d70ff6b66e3aab880bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Mon, 27 May 2019 15:43:45 +0200 Subject: [PATCH 125/441] bpo-35397: Remove deprecation and document urllib.parse.unwrap (GH-11481) --- Doc/library/urllib.parse.rst | 7 +++++++ Doc/tools/susp-ignored.csv | 2 ++ Lib/test/test_urlparse.py | 12 ++++-------- Lib/urllib/parse.py | 12 +++++------- Lib/urllib/request.py | 8 ++++---- .../2019-01-09-17-56-35.bpo-35397.ZMreIz.rst | 2 ++ 6 files changed, 24 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index f9936288fd42cd..49276daa7ff43f 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -370,6 +370,13 @@ or on combining URL components into a URL string. .. versionchanged:: 3.2 Result is a structured object rather than a simple 2-tuple. +.. function:: unwrap(url) + + Extract the url from a wrapped URL (that is, a string formatted as + ````, ````, ``URL:scheme://host/path`` + or ``scheme://host/path``). If *url* is not a wrapped URL, it is returned + without changes. + .. _parsing-ascii-encoded-bytes: Parsing ASCII Encoded Bytes diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index a34524bb673e89..a0e7868a037ac0 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -236,6 +236,8 @@ library/urllib.request,,:close,Connection:close library/urllib.request,,:port,:port library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n\n" library/urllib.request,,:password,"""joe:password@python.org""" +library/urllib.parse,,:scheme, +library/urllib.parse,,:scheme,URL:scheme://host/path library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678 library/venv,,:param,":param nodist: If True, setuptools and pip are not installed into the" library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the" diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index d0365ecab72ccb..43447656376472 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1169,8 +1169,10 @@ def test_to_bytes(self): 'http://www.python.org/medi\u00e6val') def test_unwrap(self): - url = urllib.parse._unwrap('') - self.assertEqual(url, 'type://host/path') + for wrapped_url in ('', '', + 'URL:scheme://host/path', 'scheme://host/path'): + url = urllib.parse.unwrap(wrapped_url) + self.assertEqual(url, 'scheme://host/path') class DeprecationTest(unittest.TestCase): @@ -1251,12 +1253,6 @@ def test_to_bytes_deprecation(self): self.assertEqual(str(cm.warning), 'urllib.parse.to_bytes() is deprecated as of 3.8') - def test_unwrap(self): - with self.assertWarns(DeprecationWarning) as cm: - urllib.parse.unwrap('') - self.assertEqual(str(cm.warning), - 'urllib.parse.unwrap() is deprecated as of 3.8') - if __name__ == "__main__": unittest.main() diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index dfba704144e9b4..daefb2025b14ea 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -979,17 +979,15 @@ def _to_bytes(url): def unwrap(url): - warnings.warn("urllib.parse.unwrap() is deprecated as of 3.8", - DeprecationWarning, stacklevel=2) - return _unwrap(url) - + """Transform a string like '' into 'scheme://host/path'. -def _unwrap(url): - """unwrap('') --> 'type://host/path'.""" + The string is returned unchanged if it's not a wrapped URL. + """ url = str(url).strip() if url[:1] == '<' and url[-1:] == '>': url = url[1:-1].strip() - if url[:4] == 'URL:': url = url[4:].strip() + if url[:4] == 'URL:': + url = url[4:].strip() return url diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index afce8eb1a1b165..f6ce9cb6d5866e 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -101,7 +101,7 @@ from urllib.error import URLError, HTTPError, ContentTooShortError from urllib.parse import ( - urlparse, urlsplit, urljoin, _unwrap, quote, unquote, + urlparse, urlsplit, urljoin, unwrap, quote, unquote, _splittype, _splithost, _splitport, _splituser, _splitpasswd, _splitattr, _splitquery, _splitvalue, _splittag, _to_bytes, unquote_to_bytes, urlunparse) @@ -349,7 +349,7 @@ def full_url(self): @full_url.setter def full_url(self, url): # unwrap('') --> 'type://host/path' - self._full_url = _unwrap(url) + self._full_url = unwrap(url) self._full_url, self.fragment = _splittag(self._full_url) self._parse() @@ -1727,7 +1727,7 @@ def addheader(self, *args): # External interface def open(self, fullurl, data=None): """Use URLopener().open(file) instead of open(file, 'r').""" - fullurl = _unwrap(_to_bytes(fullurl)) + fullurl = unwrap(_to_bytes(fullurl)) fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]|") if self.tempcache and fullurl in self.tempcache: filename, headers = self.tempcache[fullurl] @@ -1775,7 +1775,7 @@ def open_unknown_proxy(self, proxy, fullurl, data=None): def retrieve(self, url, filename=None, reporthook=None, data=None): """retrieve(url) returns (filename, headers) for a local object or (tempfilename, headers) for a remote object.""" - url = _unwrap(_to_bytes(url)) + url = unwrap(_to_bytes(url)) if self.tempcache and url in self.tempcache: return self.tempcache[url] type, url1 = _splittype(url) diff --git a/Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst b/Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst new file mode 100644 index 00000000000000..6dc7d3aebb1a44 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst @@ -0,0 +1,2 @@ +Remove deprecation and document urllib.parse.unwrap(). Patch contributed by +Rémi Lapeyre. From 8cd5165ba05ff57cfdbbc71c393bddad1ce1ab87 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 27 May 2019 15:57:20 +0200 Subject: [PATCH 126/441] bpo-37027: Return a proxy socket object from transp.get_extra_info('socket') (GH-13530) Return a safe to use proxy socket object from `transport.get_extra_info('socket')` https://bugs.python.org/issue37027 --- Lib/asyncio/base_events.py | 5 +- Lib/asyncio/proactor_events.py | 5 +- Lib/asyncio/selector_events.py | 5 +- Lib/asyncio/trsock.py | 206 ++++++++++++++++++ Lib/test/test_asyncio/test_events.py | 2 +- Lib/test/test_asyncio/test_server.py | 4 +- .../2019-05-23-18-46-56.bpo-37027.iH4eut.rst | 2 + 7 files changed, 220 insertions(+), 9 deletions(-) create mode 100644 Lib/asyncio/trsock.py create mode 100644 Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index ce4f1904f95056..e5cd14b59af5d6 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -45,6 +45,7 @@ from . import staggered from . import tasks from . import transports +from . import trsock from .log import logger @@ -319,8 +320,8 @@ def is_serving(self): @property def sockets(self): if self._sockets is None: - return [] - return list(self._sockets) + return () + return tuple(trsock.TransportSocket(s) for s in self._sockets) def close(self): sockets = self._sockets diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 710f768718b477..6a53b2edaac125 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -19,6 +19,7 @@ from . import protocols from . import sslproto from . import transports +from . import trsock from .log import logger @@ -454,7 +455,7 @@ def __init__(self, loop, sock, protocol, waiter=None, base_events._set_nodelay(sock) def _set_extra(self, sock): - self._extra['socket'] = sock + self._extra['socket'] = trsock.TransportSocket(sock) try: self._extra['sockname'] = sock.getsockname() @@ -679,7 +680,7 @@ def loop(f=None): self.call_exception_handler({ 'message': 'Accept failed on a socket', 'exception': exc, - 'socket': sock, + 'socket': trsock.TransportSocket(sock), }) sock.close() elif self._debug: diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 44c380ae62db66..00e3244bfb294c 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -25,6 +25,7 @@ from . import protocols from . import sslproto from . import transports +from . import trsock from .log import logger @@ -171,7 +172,7 @@ def _accept_connection( self.call_exception_handler({ 'message': 'socket.accept() out of system resource', 'exception': exc, - 'socket': sock, + 'socket': trsock.TransportSocket(sock), }) self._remove_reader(sock.fileno()) self.call_later(constants.ACCEPT_RETRY_DELAY, @@ -603,7 +604,7 @@ class _SelectorTransport(transports._FlowControlMixin, def __init__(self, loop, sock, protocol, extra=None, server=None): super().__init__(extra, loop) - self._extra['socket'] = sock + self._extra['socket'] = trsock.TransportSocket(sock) try: self._extra['sockname'] = sock.getsockname() except OSError: diff --git a/Lib/asyncio/trsock.py b/Lib/asyncio/trsock.py new file mode 100644 index 00000000000000..e9ebcc32614259 --- /dev/null +++ b/Lib/asyncio/trsock.py @@ -0,0 +1,206 @@ +import socket +import warnings + + +class TransportSocket: + + """A socket-like wrapper for exposing real transport sockets. + + These objects can be safely returned by APIs like + `transport.get_extra_info('socket')`. All potentially disruptive + operations (like "socket.close()") are banned. + """ + + __slots__ = ('_sock',) + + def __init__(self, sock: socket.socket): + self._sock = sock + + def _na(self, what): + warnings.warn( + f"Using {what} on sockets returned from get_extra_info('socket') " + f"will be prohibited in asyncio 3.9. Please report your use case " + f"to bugs.python.org.", + DeprecationWarning, source=self) + + @property + def family(self): + return self._sock.family + + @property + def type(self): + return self._sock.type + + @property + def proto(self): + return self._sock.proto + + def __repr__(self): + s = ( + f"" + + def __getstate__(self): + raise TypeError("Cannot serialize asyncio.TransportSocket object") + + def fileno(self): + return self._sock.fileno() + + def dup(self): + return self._sock.dup() + + def get_inheritable(self): + return self._sock.get_inheritable() + + def shutdown(self, how): + # asyncio doesn't currently provide a high-level transport API + # to shutdown the connection. + self._sock.shutdown(how) + + def getsockopt(self, *args, **kwargs): + return self._sock.getsockopt(*args, **kwargs) + + def setsockopt(self, *args, **kwargs): + self._sock.setsockopt(*args, **kwargs) + + def getpeername(self): + return self._sock.getpeername() + + def getsockname(self): + return self._sock.getsockname() + + def getsockbyname(self): + return self._sock.getsockbyname() + + def accept(self): + self._na('accept() method') + return self._sock.accept() + + def connect(self, *args, **kwargs): + self._na('connect() method') + return self._sock.connect(*args, **kwargs) + + def connect_ex(self, *args, **kwargs): + self._na('connect_ex() method') + return self._sock.connect_ex(*args, **kwargs) + + def bind(self, *args, **kwargs): + self._na('bind() method') + return self._sock.bind(*args, **kwargs) + + def ioctl(self, *args, **kwargs): + self._na('ioctl() method') + return self._sock.ioctl(*args, **kwargs) + + def listen(self, *args, **kwargs): + self._na('listen() method') + return self._sock.listen(*args, **kwargs) + + def makefile(self): + self._na('makefile() method') + return self._sock.makefile() + + def sendfile(self, *args, **kwargs): + self._na('sendfile() method') + return self._sock.sendfile(*args, **kwargs) + + def close(self): + self._na('close() method') + return self._sock.close() + + def detach(self): + self._na('detach() method') + return self._sock.detach() + + def sendmsg_afalg(self, *args, **kwargs): + self._na('sendmsg_afalg() method') + return self._sock.sendmsg_afalg(*args, **kwargs) + + def sendmsg(self, *args, **kwargs): + self._na('sendmsg() method') + return self._sock.sendmsg(*args, **kwargs) + + def sendto(self, *args, **kwargs): + self._na('sendto() method') + return self._sock.sendto(*args, **kwargs) + + def send(self, *args, **kwargs): + self._na('send() method') + return self._sock.send(*args, **kwargs) + + def sendall(self, *args, **kwargs): + self._na('sendall() method') + return self._sock.sendall(*args, **kwargs) + + def set_inheritable(self, *args, **kwargs): + self._na('set_inheritable() method') + return self._sock.set_inheritable(*args, **kwargs) + + def share(self, process_id): + self._na('share() method') + return self._sock.share(process_id) + + def recv_into(self, *args, **kwargs): + self._na('recv_into() method') + return self._sock.recv_into(*args, **kwargs) + + def recvfrom_into(self, *args, **kwargs): + self._na('recvfrom_into() method') + return self._sock.recvfrom_into(*args, **kwargs) + + def recvmsg_into(self, *args, **kwargs): + self._na('recvmsg_into() method') + return self._sock.recvmsg_into(*args, **kwargs) + + def recvmsg(self, *args, **kwargs): + self._na('recvmsg() method') + return self._sock.recvmsg(*args, **kwargs) + + def recvfrom(self, *args, **kwargs): + self._na('recvfrom() method') + return self._sock.recvfrom(*args, **kwargs) + + def recv(self, *args, **kwargs): + self._na('recv() method') + return self._sock.recv(*args, **kwargs) + + def settimeout(self, value): + if value == 0: + return + raise ValueError( + 'settimeout(): only 0 timeout is allowed on transport sockets') + + def gettimeout(self): + return 0 + + def setblocking(self, flag): + if not flag: + return + raise ValueError( + 'setblocking(): transport sockets cannot be blocking') + + def __enter__(self): + self._na('context manager protocol') + return self._sock.__enter__() + + def __exit__(self, *err): + self._na('context manager protocol') + return self._sock.__exit__(*err) diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 0ae6eab1e1e426..e89db99df31214 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1118,7 +1118,7 @@ def connection_made(self, transport): f = self.loop.create_server(TestMyProto, sock=sock_ob) server = self.loop.run_until_complete(f) sock = server.sockets[0] - self.assertIs(sock, sock_ob) + self.assertEqual(sock.fileno(), sock_ob.fileno()) host, port = sock.getsockname() self.assertEqual(host, '0.0.0.0') diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py index ab7f3debbc152e..4e758ad12e600e 100644 --- a/Lib/test/test_asyncio/test_server.py +++ b/Lib/test/test_asyncio/test_server.py @@ -58,7 +58,7 @@ async def main(srv): with self.tcp_client(lambda sock: client(sock, addr)): self.loop.run_until_complete(main_task) - self.assertEqual(srv.sockets, []) + self.assertEqual(srv.sockets, ()) self.assertIsNone(srv._sockets) self.assertIsNone(srv._waiters) @@ -111,7 +111,7 @@ async def main(srv): with self.unix_client(lambda sock: client(sock, addr)): self.loop.run_until_complete(main_task) - self.assertEqual(srv.sockets, []) + self.assertEqual(srv.sockets, ()) self.assertIsNone(srv._sockets) self.assertIsNone(srv._waiters) diff --git a/Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst b/Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst new file mode 100644 index 00000000000000..60b513d6ea3aaf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst @@ -0,0 +1,2 @@ +Return safe to use proxy socket object from +transport.get_extra_info('socket') From 331a6a56e9a9c72f3e4605987fabdaec72677702 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 27 May 2019 16:39:22 +0200 Subject: [PATCH 127/441] bpo-36763: Implement the PEP 587 (GH-13592) * Add a whole new documentation page: "Python Initialization Configuration" * PyWideStringList_Append() return type is now PyStatus, instead of int * PyInterpreterState_New() now calls PyConfig_Clear() if PyConfig_InitPythonConfig() fails. * Rename files: * Python/coreconfig.c => Python/initconfig.c * Include/cpython/coreconfig.h => Include/cpython/initconfig.h * Include/internal/: pycore_coreconfig.h => pycore_initconfig.h * Rename structures * _PyCoreConfig => PyConfig * _PyPreConfig => PyPreConfig * _PyInitError => PyStatus * _PyWstrList => PyWideStringList * Rename PyConfig fields: * use_module_search_paths => module_search_paths_set * module_search_path_env => pythonpath_env * Rename PyStatus field: _func => func * PyInterpreterState: rename core_config field to config * Rename macros and functions: * _PyCoreConfig_SetArgv() => PyConfig_SetBytesArgv() * _PyCoreConfig_SetWideArgv() => PyConfig_SetArgv() * _PyCoreConfig_DecodeLocale() => PyConfig_SetBytesString() * _PyInitError_Failed() => PyStatus_Exception() * _Py_INIT_ERROR_TYPE_xxx enums => _PyStatus_TYPE_xxx * _Py_UnixMain() => Py_BytesMain() * _Py_ExitInitError() => Py_ExitStatusException() * _Py_PreInitializeFromArgs() => Py_PreInitializeFromBytesArgs() * _Py_PreInitializeFromWideArgs() => Py_PreInitializeFromArgs() * _Py_PreInitialize() => Py_PreInitialize() * _Py_RunMain() => Py_RunMain() * _Py_InitializeFromConfig() => Py_InitializeFromConfig() * _Py_INIT_XXX() => _PyStatus_XXX() * _Py_INIT_FAILED() => _PyStatus_EXCEPTION() * Rename 'err' PyStatus variables to 'status' * Convert RUN_CODE() macro to config_run_code() static inline function * Remove functions: * _Py_InitializeFromArgs() * _Py_InitializeFromWideArgs() * _PyInterpreterState_GetCoreConfig() --- Doc/c-api/index.rst | 1 + Doc/c-api/init_config.rst | 1018 +++++++++++++++++ Doc/c-api/veryhigh.rst | 7 + Doc/whatsnew/3.8.rst | 55 + Include/Python.h | 2 +- .../cpython/{coreconfig.h => initconfig.h} | 139 ++- Include/cpython/pylifecycle.h | 30 +- Include/cpython/pystate.h | 4 +- Include/internal/pycore_coreconfig.h | 163 --- Include/internal/pycore_initconfig.h | 168 +++ Include/internal/pycore_pathconfig.h | 20 +- Include/internal/pycore_pylifecycle.h | 38 +- Include/internal/pycore_pystate.h | 14 +- Lib/test/test_embed.py | 156 +-- Makefile.pre.in | 10 +- .../2019-05-27-12-25-25.bpo-36763.bHCA9j.rst | 1 + Modules/_io/_iomodule.c | 2 +- Modules/_io/iobase.c | 2 +- Modules/_testinternalcapi.c | 2 +- Modules/faulthandler.c | 10 +- Modules/getpath.c | 476 ++++---- Modules/main.c | 101 +- Objects/bytearrayobject.c | 4 +- Objects/bytesobject.c | 4 +- Objects/exceptions.c | 24 +- Objects/listobject.c | 2 +- Objects/moduleobject.c | 4 +- Objects/object.c | 10 +- Objects/tupleobject.c | 2 +- Objects/unicodeobject.c | 62 +- PC/getpathp.c | 146 +-- PCbuild/pythoncore.vcxproj | 6 +- PCbuild/pythoncore.vcxproj.filters | 18 +- Programs/_freeze_importlib.c | 34 +- Programs/_testembed.c | 420 +++---- Programs/python.c | 2 +- Python/bltinmodule.c | 2 +- Python/bootstrap_hash.c | 12 +- Python/compile.c | 4 +- Python/dynload_hpux.c | 2 +- Python/errors.c | 8 +- Python/frozenmain.c | 24 +- Python/import.c | 30 +- Python/{coreconfig.c => initconfig.c} | 916 +++++++-------- Python/pathconfig.c | 214 ++-- Python/preconfig.c | 235 ++-- Python/pylifecycle.c | 689 ++++++----- Python/pystate.c | 41 +- Python/pythonrun.c | 4 +- Python/sysmodule.c | 56 +- 50 files changed, 3229 insertions(+), 2165 deletions(-) create mode 100644 Doc/c-api/init_config.rst rename Include/cpython/{coreconfig.h => initconfig.h} (84%) delete mode 100644 Include/internal/pycore_coreconfig.h create mode 100644 Include/internal/pycore_initconfig.h create mode 100644 Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst rename Python/{coreconfig.c => initconfig.c} (71%) diff --git a/Doc/c-api/index.rst b/Doc/c-api/index.rst index 3bfbaf4eedde0e..9a8f1507b3f4cc 100644 --- a/Doc/c-api/index.rst +++ b/Doc/c-api/index.rst @@ -21,6 +21,7 @@ document the API functions in detail. abstract.rst concrete.rst init.rst + init_config.rst memory.rst objimpl.rst apiabiversion.rst diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst new file mode 100644 index 00000000000000..0d94e6b8f27b57 --- /dev/null +++ b/Doc/c-api/init_config.rst @@ -0,0 +1,1018 @@ +.. highlight:: c + +.. _init-config: + +*********************************** +Python Initialization Configuration +*********************************** + +.. versionadded:: 3.8 + +Structures: + +* :c:type:`PyConfig` +* :c:type:`PyPreConfig` +* :c:type:`PyStatus` +* :c:type:`PyWideStringList` + +Functions: + +* :c:func:`PyConfig_Clear` +* :c:func:`PyConfig_InitIsolatedConfig` +* :c:func:`PyConfig_InitPythonConfig` +* :c:func:`PyConfig_Read` +* :c:func:`PyConfig_SetArgv` +* :c:func:`PyConfig_SetBytesArgv` +* :c:func:`PyConfig_SetBytesString` +* :c:func:`PyConfig_SetString` +* :c:func:`PyPreConfig_InitIsolatedConfig` +* :c:func:`PyPreConfig_InitPythonConfig` +* :c:func:`PyStatus_Error` +* :c:func:`PyStatus_Exception` +* :c:func:`PyStatus_Exit` +* :c:func:`PyStatus_IsError` +* :c:func:`PyStatus_IsExit` +* :c:func:`PyStatus_NoMemory` +* :c:func:`PyStatus_Ok` +* :c:func:`PyWideStringList_Append` +* :c:func:`PyWideStringList_Insert` +* :c:func:`Py_ExitStatusException` +* :c:func:`Py_InitializeFromConfig` +* :c:func:`Py_PreInitialize` +* :c:func:`Py_PreInitializeFromArgs` +* :c:func:`Py_PreInitializeFromBytesArgs` +* :c:func:`Py_RunMain` + +The preconfiguration (``PyPreConfig`` type) is stored in +``_PyRuntime.preconfig`` and the configuration (``PyConfig`` type) is stored in +``PyInterpreterState.config``. + +.. seealso:: + :pep:`587` "Python Initialization Configuration". + + +PyWideStringList +---------------- + +.. c:type:: PyWideStringList + + List of ``wchar_t*`` strings. + + If *length* is non-zero, *items* must be non-NULL and all strings must be + non-NULL. + + Methods: + + .. c:function:: PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) + + Append *item* to *list*. + + Python must be preinitialized to call this function. + + .. c:function:: PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item) + + Insert *item* into *list* at *index*. If *index* is greater than *list* + length, just append *item* to *list*. + + Python must be preinitialized to call this function. + + Structure fields: + + .. c:member:: Py_ssize_t length + + List length. + + .. c:member:: wchar_t** items + + List items. + +PyStatus +-------- + +.. c:type:: PyStatus + + Structure to store an initialization function status: success, error + or exit. + + For an error, it can store the C function name which created the error. + + Structure fields: + + .. c:member:: int exitcode + + Exit code. Argument passed to ``exit()``. + + .. c:member:: const char *err_msg + + Error message. + + .. c:member:: const char *func + + Name of the function which created an error, can be ``NULL``. + + Functions to create a status: + + .. c:function:: PyStatus PyStatus_Ok(void) + + Success. + + .. c:function:: PyStatus PyStatus_Error(const char *err_msg) + + Initialization error with a message. + + .. c:function:: PyStatus PyStatus_NoMemory(void) + + Memory allocation failure (out of memory). + + .. c:function:: PyStatus PyStatus_Exit(int exitcode) + + Exit Python with the specified exit code. + + Functions to handle a status: + + .. c:function:: int PyStatus_Exception(PyStatus status) + + Is the status an error or an exit? If true, the exception must be + handled; by calling :c:func:`Py_ExitStatusException` for example. + + .. c:function:: int PyStatus_IsError(PyStatus status) + + Is the result an error? + + .. c:function:: int PyStatus_IsExit(PyStatus status) + + Is the result an exit? + + .. c:function:: void Py_ExitStatusException(PyStatus status) + + Call ``exit(exitcode)`` if *status* is an exit. Print the error + message and exit with a non-zero exit code if *status* is an error. Must + only be called if ``PyStatus_Exception(status)`` is non-zero. + +.. note:: + Internally, Python uses macros which set ``PyStatus.func``, + whereas functions to create a status set ``func`` to ``NULL``. + +Example:: + + PyStatus alloc(void **ptr, size_t size) + { + *ptr = PyMem_RawMalloc(size); + if (*ptr == NULL) { + return PyStatus_NoMemory(); + } + return PyStatus_Ok(); + } + + int main(int argc, char **argv) + { + void *ptr; + PyStatus status = alloc(&ptr, 16); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + PyMem_Free(ptr); + return 0; + } + + +PyPreConfig +----------- + +.. c:type:: PyPreConfig + + Structure used to preinitialize Python: + + * Set the Python memory allocator + * Configure the LC_CTYPE locale + * Set the UTF-8 mode + + Function to initialize a preconfiguration: + + .. c:function:: void PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig) + + Initialize the preconfiguration with :ref:`Python Configuration + `. + + .. c:function:: void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig) + + Initialize the preconfiguration with :ref:`Isolated Configuration + `. + + Structure fields: + + .. c:member:: int allocator + + Name of the memory allocator: + + * ``PYMEM_ALLOCATOR_NOT_SET`` (``0``): don't change memory allocators + (use defaults) + * ``PYMEM_ALLOCATOR_DEFAULT`` (``1``): default memory allocators + * ``PYMEM_ALLOCATOR_DEBUG`` (``2``): default memory allocators with + debug hooks + * ``PYMEM_ALLOCATOR_MALLOC`` (``3``): force usage of ``malloc()`` + * ``PYMEM_ALLOCATOR_MALLOC_DEBUG`` (``4``): force usage of + ``malloc()`` with debug hooks + * ``PYMEM_ALLOCATOR_PYMALLOC`` (``5``): :ref:`Python pymalloc memory + allocator ` + * ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG`` (``6``): :ref:`Python pymalloc + memory allocator ` with debug hooks + + ``PYMEM_ALLOCATOR_PYMALLOC`` and ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG`` + are not supported if Python is configured using ``--without-pymalloc`` + + See :ref:`Memory Management `. + + .. c:member:: int configure_locale + + Set the LC_CTYPE locale to the user preferred locale? If equals to 0, set + :c:member:`coerce_c_locale` and :c:member:`coerce_c_locale_warn` to 0. + + .. c:member:: int coerce_c_locale + + If equals to 2, coerce the C locale; if equals to 1, read the LC_CTYPE + locale to decide if it should be coerced. + + .. c:member:: int coerce_c_locale_warn + If non-zero, emit a warning if the C locale is coerced. + + .. c:member:: int dev_mode + + See :c:member:`PyConfig.dev_mode`. + + .. c:member:: int isolated + + See :c:member:`PyConfig.isolated`. + + .. c:member:: int legacy_windows_fs_encoding (Windows only) + + If non-zero, disable UTF-8 Mode, set the Python filesystem encoding to + ``mbcs``, set the filesystem error handler to ``replace``. + + Only available on Windows. ``#ifdef MS_WINDOWS`` macro can be used for + Windows specific code. + + .. c:member:: int parse_argv + + If non-zero, :c:func:`Py_PreInitializeFromArgs` and + :c:func:`Py_PreInitializeFromBytesArgs` parse their ``argv`` argument the + same way the regular Python parses command line arguments: see + :ref:`Command Line Arguments `. + + .. c:member:: int use_environment + + See :c:member:`PyConfig.use_environment`. + + .. c:member:: int utf8_mode + + If non-zero, enable the UTF-8 mode. + +Preinitialization with PyPreConfig +---------------------------------- + +Functions to preinitialize Python: + +.. c:function:: PyStatus Py_PreInitialize(const PyPreConfig *preconfig) + + Preinitialize Python from *preconfig* preconfiguration. + +.. c:function:: PyStatus Py_PreInitializeFromBytesArgs(const PyPreConfig *preconfig, int argc, char * const *argv) + + Preinitialize Python from *preconfig* preconfiguration and command line + arguments (bytes strings). + +.. c:function:: PyStatus Py_PreInitializeFromArgs(const PyPreConfig *preconfig, int argc, wchar_t * const * argv) + + Preinitialize Python from *preconfig* preconfiguration and command line + arguments (wide strings). + +The caller is responsible to handle exceptions (error or exit) using +:c:func:`PyStatus_Exception` and :c:func:`Py_ExitStatusException`. + +For :ref:`Python Configuration ` +(:c:func:`PyPreConfig_InitPythonConfig`), if Python is initialized with +command line arguments, the command line arguments must also be passed to +preinitialize Python, since they have an effect on the pre-configuration +like encodings. For example, the :option:`-X` ``utf8`` command line option +enables the UTF-8 Mode. + +``PyMem_SetAllocator()`` can be called after :c:func:`Py_PreInitialize` and +before :c:func:`Py_InitializeFromConfig` to install a custom memory allocator. +It can be called before :c:func:`Py_PreInitialize` if +:c:member:`PyPreConfig.allocator` is set to ``PYMEM_ALLOCATOR_NOT_SET``. + +Python memory allocation functions like :c:func:`PyMem_RawMalloc` must not be +used before Python preinitialization, whereas calling directly ``malloc()`` and +``free()`` is always safe. :c:func:`Py_DecodeLocale` must not be called before +the preinitialization. + +Example using the preinitialization to enable the UTF-8 Mode:: + + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); + + preconfig.utf8_mode = 1; + + PyStatus status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + /* at this point, Python will speak UTF-8 */ + + Py_Initialize(); + /* ... use Python API here ... */ + Py_Finalize(); + + +PyConfig +-------- + +.. c:type:: PyConfig + + Structure containing most parameters to configure Python. + + Structure methods: + + .. c:function:: PyStatus PyConfig_InitPythonConfig(PyConfig *config) + + Initialize configuration with :ref:`Python Configuration + `. + + .. c:function:: PyStatus PyConfig_InitIsolatedConfig(PyConfig *config) + + Initialize configuration with :ref:`Isolated Configuration + `. + + .. c:function:: PyStatus PyConfig_SetString(PyConfig *config, wchar_t * const *config_str, const wchar_t *str) + + Copy the wide character string *str* into ``*config_str``. + + Preinitialize Python if needed. + + .. c:function:: PyStatus PyConfig_SetBytesString(PyConfig *config, wchar_t * const *config_str, const char *str) + + Decode *str* using ``Py_DecodeLocale()`` and set the result into ``*config_str``. + + Preinitialize Python if needed. + + .. c:function:: PyStatus PyConfig_SetArgv(PyConfig *config, int argc, wchar_t * const *argv) + + Set command line arguments from wide character strings. + + Preinitialize Python if needed. + + .. c:function:: PyStatus PyConfig_SetBytesArgv(PyConfig *config, int argc, char * const *argv) + + Set command line arguments: decode bytes using :c:func:`Py_DecodeLocale`. + + Preinitialize Python if needed. + + .. c:function:: PyStatus PyConfig_Read(PyConfig *config) + + Read all Python configuration. + + Fields which are already initialized are left unchanged. + + Preinitialize Python if needed. + + .. c:function:: void PyConfig_Clear(PyConfig *config) + + Release configuration memory. + + Most ``PyConfig`` methods preinitialize Python if needed. In that case, the + Python preinitialization configuration in based on the :c:type:`PyConfig`. + If configuration fields which are in common with :c:type:`PyPreConfig` are + tuned, they must be set before calling a :c:type:`PyConfig` method: + + * :c:member:`~PyConfig.dev_mode` + * :c:member:`~PyConfig.isolated` + * :c:member:`~PyConfig.parse_argv` + * :c:member:`~PyConfig.use_environment` + + Moreover, if :c:func:`PyConfig_SetArgv` or :c:func:`PyConfig_SetBytesArgv` + is used, this method must be called first, before other methods, since the + preinitialization configuration depends on command line arguments (if + :c:member:`parse_argv` is non-zero). + + The caller of these methods is responsible to handle exceptions (error or + exit) using ``PyStatus_Exception()`` and ``Py_ExitStatusException()``. + + Structure fields: + + .. c:member:: PyWideStringList argv + + Command line arguments, :data:`sys.argv`. See + :c:member:`~PyConfig.parse_argv` to parse :c:member:`~PyConfig.argv` the + same way the regular Python parses Python command line arguments. If + :c:member:`~PyConfig.argv` is empty, an empty string is added to ensure + that :data:`sys.argv` always exists and is never empty. + + .. c:member:: wchar_t* base_exec_prefix + + :data:`sys.base_exec_prefix`. + + .. c:member:: wchar_t* base_prefix + + :data:`sys.base_prefix`. + + .. c:member:: int buffered_stdio + + If equals to 0, enable unbuffered mode, making the stdout and stderr + streams unbuffered. + + stdin is always opened in buffered mode. + + .. c:member:: int bytes_warning + + If equals to 1, issue a warning when comparing :class:`bytes` or + :class:`bytearray` with :class:`str`, or comparing :class:`bytes` with + :class:`int`. If equal or greater to 2, raise a :exc:`BytesWarning` + exception. + + .. c:member:: wchar_t* check_hash_pycs_mode + + Control the validation behavior of hash-based ``.pyc`` files (see + :pep:`552`): :option:`--check-hash-based-pycs` command line option value. + + Valid values: ``always``, ``never`` and ``default``. + + The default value is: ``default``. + + .. c:member:: int configure_c_stdio + + If non-zero, configure C standard streams (``stdio``, ``stdout``, + ``stdout``). For example, set their mode to ``O_BINARY`` on Windows. + + .. c:member:: int dev_mode + + Development mode: see :option:`-X` ``dev``. + + .. c:member:: int dump_refs + + If non-zero, dump all objects which are still alive at exit. + + Require a debug build of Python (``Py_REF_DEBUG`` macro must be defined). + + .. c:member:: wchar_t* exec_prefix + + :data:`sys.exec_prefix`. + + .. c:member:: wchar_t* executable + + :data:`sys.executable`. + + .. c:member:: int faulthandler + + If non-zero, call :func:`faulthandler.enable`. + + .. c:member:: wchar_t* filesystem_encoding + + Filesystem encoding, :func:`sys.getfilesystemencoding`. + + .. c:member:: wchar_t* filesystem_errors + + Filesystem encoding errors, :func:`sys.getfilesystemencodeerrors`. + + .. c:member:: unsigned long hash_seed + .. c:member:: int use_hash_seed + + Randomized hash function seed. + + If :c:member:`~PyConfig.use_hash_seed` is zero, a seed is chosen randomly + at Pythonstartup, and :c:member:`~PyConfig.hash_seed` is ignored. + + .. c:member:: wchar_t* home + + Python home directory. + + .. c:member:: int import_time + + If non-zero, profile import time. + + .. c:member:: int inspect + + Enter interactive mode after executing a script or a command. + + .. c:member:: int install_signal_handlers + + Install signal handlers? + + .. c:member:: int interactive + + Interactive mode. + + .. c:member:: int isolated + + If greater than 0, enable isolated mode: + + * :data:`sys.path` contains neither the script's directory (computed from + ``argv[0]`` or the current directory) nor the user's site-packages + directory. + * Python REPL doesn't import :mod:`readline` nor enable default readline + configuration on interactive prompts. + * Set :c:member:`~PyConfig.use_environment` and + :c:member:`~PyConfig.user_site_directory` to 0. + + .. c:member:: int legacy_windows_stdio + + If non-zero, use :class:`io.FileIO` instead of + :class:`io.WindowsConsoleIO` for :data:`sys.stdin`, :data:`sys.stdout` + and :data:`sys.stderr`. + + Only available on Windows. ``#ifdef MS_WINDOWS`` macro can be used for + Windows specific code. + + .. c:member:: int malloc_stats + + If non-zero, dump statistics on :ref:`Python pymalloc memory allocator + ` at exit. + + The option is ignored if Python is built using ``--without-pymalloc``. + + .. c:member:: wchar_t* pythonpath_env + + Module search paths as a string separated by ``DELIM`` + (:data:`os.path.pathsep`). + + Initialized from :envvar:`PYTHONPATH` environment variable value by + default. + + .. c:member:: PyWideStringList module_search_paths + .. c:member:: int module_search_paths_set + + :data:`sys.path`. If :c:member:`~PyConfig.module_search_paths_set` is + equal to 0, the :c:member:`~PyConfig.module_search_paths` is overridden + by the function computing the :ref:`Path Configuration + `. + + .. c:member:: int optimization_level + + Compilation optimization level: + + * 0: Peephole optimizer (and ``__debug__`` is set to ``True``) + * 1: Remove assertions, set ``__debug__`` to ``False`` + * 2: Strip docstrings + + .. c:member:: int parse_argv + + If non-zero, parse :c:member:`~PyConfig.argv` the same way the regular + Python command line arguments, and strip Python arguments from + :c:member:`~PyConfig.argv`: see :ref:`Command Line Arguments + `. + + .. c:member:: int parser_debug + + If non-zero, turn on parser debugging output (for expert only, depending + on compilation options). + + .. c:member:: int pathconfig_warnings + + If equal to 0, suppress warnings when computing the path configuration + (Unix only, Windows does not log any warning). Otherwise, warnings are + written into ``stderr``. + + .. c:member:: wchar_t* prefix + + :data:`sys.prefix`. + + .. c:member:: wchar_t* program_name + + Program name. + + .. c:member:: wchar_t* pycache_prefix + + ``.pyc`` cache prefix. + + .. c:member:: int quiet + + Quiet mode. For example, don't display the copyright and version messages + even in interactive mode. + + .. c:member:: wchar_t* run_command + + ``python3 -c COMMAND`` argument. + + .. c:member:: wchar_t* run_filename + + ``python3 FILENAME`` argument. + + .. c:member:: wchar_t* run_module + + ``python3 -m MODULE`` argument. + + .. c:member:: int show_alloc_count + + Show allocation counts at exit? + + Need a special Python build with ``COUNT_ALLOCS`` macro defined. + + .. c:member:: int show_ref_count + + Show total reference count at exit? + + Need a debug build of Python (``Py_REF_DEBUG`` macro must be defined). + + .. c:member:: int site_import + + Import the :mod:`site` module at startup? + + .. c:member:: int skip_source_first_line + + Skip the first line of the source? + + .. c:member:: wchar_t* stdio_encoding + .. c:member:: wchar_t* stdio_errors + + Encoding and encoding errors of :data:`sys.stdin`, :data:`sys.stdout` and + :data:`sys.stderr`. + + .. c:member:: int tracemalloc + + If non-zero, call :func:`tracemalloc.start`. + + .. c:member:: int use_environment + + If greater than 0, use :ref:`environment variables `. + + .. c:member:: int user_site_directory + + If non-zero, add user site directory to :data:`sys.path`. + + .. c:member:: int verbose + + If non-zero, enable verbose mode. + + .. c:member:: PyWideStringList warnoptions + + Options of the :mod:`warnings` module to build warnings filters. + + .. c:member:: int write_bytecode + + If non-zero, write ``.pyc`` files. + + .. c:member:: PyWideStringList xoptions + + :data:`sys._xoptions`. + +If ``parse_argv`` is non-zero, ``argv`` arguments are parsed the same +way the regular Python parses command line arguments, and Python +arguments are stripped from ``argv``: see :ref:`Command Line Arguments +`. + +The ``xoptions`` options are parsed to set other options: see :option:`-X` +option. + + +Initialization with PyConfig +---------------------------- + +Function to initialize Python: + +.. c:function:: PyStatus Py_InitializeFromConfig(const PyConfig *config) + + Initialize Python from *config* configuration. + +The caller is responsible to handle exceptions (error or exit) using +:c:func:`PyStatus_Exception` and :c:func:`Py_ExitStatusException`. + +``PyImport_FrozenModules``, ``PyImport_AppendInittab()`` or +``PyImport_ExtendInittab()`` is used: they must be set or called after Python +preinitialization and before the Python initialization. + +Example setting the program name:: + + void init_python(void) + { + PyStatus status; + PyConfig config; + + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + goto fail; + } + + /* Set the program name. Implicitly preinitialize Python. */ + status = PyConfig_SetString(&config, &config.program_name, + L"/path/to/my_program"); + if (PyStatus_Exception(status)) { + goto fail; + } + + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + goto fail; + } + PyConfig_Clear(&config); + return; + + fail: + PyConfig_Clear(&config); + Py_ExitStatusException(status); + } + +More complete example modifying the default configuration, read the +configuration, and then override some parameters:: + + PyStatus init_python(const char *program_name) + { + PyStatus status; + PyConfig config; + + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + goto done; + } + + /* Set the program name before reading the configuraton + (decode byte string from the locale encoding). + + Implicitly preinitialize Python. */ + status = PyConfig_SetBytesString(&config, &config.program_name, + program_name); + if (PyStatus_Exception(status)) { + goto done; + } + + /* Read all configuration at once */ + status = PyConfig_Read(&config); + if (PyStatus_Exception(status)) { + goto done; + } + + /* Append our custom search path to sys.path */ + status = PyWideStringList_Append(&config.module_search_paths, + L"/path/to/more/modules"); + if (PyStatus_Exception(status)) { + goto done; + } + + /* Override executable computed by PyConfig_Read() */ + status = PyConfig_SetString(&config, &config.executable, + L"/path/to/my_executable"); + if (PyStatus_Exception(status)) { + goto done; + } + + status = Py_InitializeFromConfig(&config); + + done: + PyConfig_Clear(&config); + return status; + } + + +.. _init-isolated-conf: + +Isolated Configuration +---------------------- + +:c:func:`PyPreConfig_InitIsolatedConfig` and +:c:func:`PyConfig_InitIsolatedConfig` functions create a configuration to +isolate Python from the system. For example, to embed Python into an +application. + +This configuration ignores global configuration variables, environments +variables and command line arguments (:c:member:`PyConfig.argv` is not parsed). +The C standard streams (ex: ``stdout``) and the LC_CTYPE locale are left +unchanged by default. + +Configuration files are still used with this configuration. Set the +:ref:`Path Configuration ` ("output fields") to ignore these +configuration files and avoid the function computing the default path +configuration. + + +.. _init-python-config: + +Python Configuration +-------------------- + +:c:func:`PyPreConfig_InitPythonConfig` and :c:func:`PyConfig_InitPythonConfig` +functions create a configuration to build a customized Python which behaves as +the regular Python. + +Environments variables and command line arguments are used to configure +Python, whereas global configuration variables are ignored. + +This function enables C locale coercion (:pep:`538`) and UTF-8 Mode +(:pep:`540`) depending on the LC_CTYPE locale, :envvar:`PYTHONUTF8` and +:envvar:`PYTHONCOERCECLOCALE` environment variables. + +Example of customized Python always running in isolated mode:: + + int main(int argc, char **argv) + { + PyConfig config; + PyStatus status; + + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + goto fail; + } + + config.isolated = 1; + + /* Decode command line arguments. + Implicitly preinitialize Python (in isolated mode). */ + status = PyConfig_SetBytesArgv(&config, argc, argv); + if (PyStatus_Exception(status)) { + goto fail; + } + + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + goto fail; + } + PyConfig_Clear(&config); + + return Py_RunMain(); + + fail: + PyConfig_Clear(&config); + if (PyStatus_IsExit(status)) { + return status.exitcode; + } + /* Display the error message and exit the process with + non-zero exit code */ + Py_ExitStatusException(status); + } + + +.. _init-path-config: + +Path Configuration +------------------ + +:c:type:`PyConfig` contains multiple fields for the path configuration: + +* Path configuration input fields: + + * :c:member:`PyConfig.home` + * :c:member:`PyConfig.pythonpath_env` + * :c:member:`PyConfig.pathconfig_warnings` + +* Path configuration output fields: + + * :c:member:`PyConfig.exec_prefix` + * :c:member:`PyConfig.executable` + * :c:member:`PyConfig.prefix` + * :c:member:`PyConfig.module_search_paths_set`, + :c:member:`PyConfig.module_search_paths` + +If at least one "output field" is not set, Python computes the path +configuration to fill unset fields. If +:c:member:`~PyConfig.module_search_paths_set` is equal to 0, +:c:member:`~PyConfig.module_search_paths` is overriden and +:c:member:`~PyConfig.module_search_paths_set` is set to 1. + +It is possible to completely ignore the function computing the default +path configuration by setting explicitly all path configuration output +fields listed above. A string is considered as set even if it is non-empty. +``module_search_paths`` is considered as set if +``module_search_paths_set`` is set to 1. In this case, path +configuration input fields are ignored as well. + +Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when +computing the path configuration (Unix only, Windows does not log any warning). + +If :c:member:`~PyConfig.base_prefix` or :c:member:`~PyConfig.base_exec_prefix` +fields are not set, they inherit their value from :c:member:`~PyConfig.prefix` +and :c:member:`~PyConfig.exec_prefix` respectively. + +:c:func:`Py_RunMain` and :c:func:`Py_Main` modify :data:`sys.path`: + +* If :c:member:`~PyConfig.run_filename` is set and is a directory which contains a + ``__main__.py`` script, prepend :c:member:`~PyConfig.run_filename` to + :data:`sys.path`. +* If :c:member:`~PyConfig.isolated` is zero: + + * If :c:member:`~PyConfig.run_module` is set, prepend the current directory + to :data:`sys.path`. Do nothing if the current directory cannot be read. + * If :c:member:`~PyConfig.run_filename` is set, prepend the directory of the + filename to :data:`sys.path`. + * Otherwise, prepend an empty string to :data:`sys.path`. + +If :c:member:`~PyConfig.site_import` is non-zero, :data:`sys.path` can be +modified by the :mod:`site` module. If +:c:member:`~PyConfig.user_site_directory` is non-zero and the user's +site-package directory exists, the :mod:`site` module appends the user's +site-package directory to :data:`sys.path`. + +The following configuration files are used by the path configuration: + +* ``pyvenv.cfg`` +* ``python._pth`` (Windows only) +* ``pybuilddir.txt`` (Unix only) + + +Py_RunMain() +------------ + +.. c:function:: int Py_RunMain(void) + + Execute the command (:c:member:`PyConfig.run_command`), the script + (:c:member:`PyConfig.run_filename`) or the module + (:c:member:`PyConfig.run_module`) specified on the command line or in the + configuration. + + By default and when if :option:`-i` option is used, run the REPL. + + Finally, finalizes Python and returns an exit status that can be passed to + the ``exit()`` function. + +See :ref:`Python Configuration ` for an example of +customized Python always running in isolated mode using +:c:func:`Py_RunMain`. + + +Multi-Phase Initialization Private Provisional API +-------------------------------------------------- + +This section is a private provisional API introducing multi-phase +initialization, the core feature of the :pep:`432`: + +* "Core" initialization phase, "bare minimum Python": + + * Builtin types; + * Builtin exceptions; + * Builtin and frozen modules; + * The :mod:`sys` module is only partially initialized + (ex: :data:`sys.path` doesn't exist yet); + +* "Main" initialization phase, Python is fully initialized: + + * Install and configure :mod:`importlib`; + * Apply the :ref:`Path Configuration `; + * Install signal handlers; + * Finish :mod:`sys` module initialization (ex: create :data:`sys.stdout` + and :data:`sys.path`); + * Enable optional features like :mod:`faulthandler` and :mod:`tracemalloc`; + * Import the :mod:`site` module; + * etc. + +Private provisional API: + +* :c:member:`PyConfig._init_main`: if set to 0, + :c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase. + +.. c:function:: PyStatus _Py_InitializeMain(void) + + Move to the "Main" initialization phase, finish the Python initialization. + +No module is imported during the "Core" phase and the ``importlib`` module is +not configured: the :ref:`Path Configuration ` is only +applied during the "Main" phase. It may allow to customize Python in Python to +override or tune the :ref:`Path Configuration `, maybe +install a custom sys.meta_path importer or an import hook, etc. + +It may become possible to compute the :ref:`Path Configuration +` in Python, after the Core phase and before the Main phase, +which is one of the :pep:`432` motivation. + +The "Core" phase is not properly defined: what should be and what should +not be available at this phase is not specified yet. The API is marked +as private and provisional: the API can be modified or even be removed +anytime until a proper public API is designed. + +Example running Python code between "Core" and "Main" initialization +phases:: + + void init_python(void) + { + PyStatus status; + PyConfig config; + + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); + } + + config._init_main = 0; + + /* ... customize 'config' configuration ... */ + + status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + + /* Use sys.stderr because sys.stdout is only created + by _Py_InitializeMain() */ + int res = PyRun_SimpleString( + "import sys; " + "print('Run Python code before _Py_InitializeMain', " + "file=sys.stderr)"); + if (res < 0) { + exit(1); + } + + /* ... put more configuration code here ... */ + + status = _Py_InitializeMain(); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); + } + } diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index a7ff08cfb6bdaa..3fe0ae47aac35a 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -42,6 +42,13 @@ the same library that the Python runtime is using. ``Py_InspectFlag`` is not set. +.. c:function:: int Py_BytesMain(int argc, char **argv) + + Similar to :c:func:`Py_Main` but *argv* is an array of bytes strings. + + .. versionadded:: 3.8 + + .. c:function:: int PyRun_AnyFile(FILE *fp, const char *filename) This is a simplified interface to :c:func:`PyRun_AnyFileExFlags` below, leaving diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 1180469ff28f65..6102d8c357cab0 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -182,6 +182,61 @@ Would print ``x*9 + 15=42``. (Contributed by Eric V. Smith and Larry Hastings in :issue:`36817`.) +PEP 587: Python Initialization Configuration +-------------------------------------------- + +The :pep:`587` adds a new C API to configure the Python Initialization +providing finer control on the whole configuration and better error reporting. + +New structures: + +* :c:type:`PyConfig` +* :c:type:`PyPreConfig` +* :c:type:`PyStatus` +* :c:type:`PyWideStringList` + +New functions: + +* :c:func:`PyConfig_Clear` +* :c:func:`PyConfig_InitIsolatedConfig` +* :c:func:`PyConfig_InitPythonConfig` +* :c:func:`PyConfig_Read` +* :c:func:`PyConfig_SetArgv` +* :c:func:`PyConfig_SetBytesArgv` +* :c:func:`PyConfig_SetBytesString` +* :c:func:`PyConfig_SetString` +* :c:func:`PyPreConfig_InitIsolatedConfig` +* :c:func:`PyPreConfig_InitPythonConfig` +* :c:func:`PyStatus_Error` +* :c:func:`PyStatus_Exception` +* :c:func:`PyStatus_Exit` +* :c:func:`PyStatus_IsError` +* :c:func:`PyStatus_IsExit` +* :c:func:`PyStatus_NoMemory` +* :c:func:`PyStatus_Ok` +* :c:func:`PyWideStringList_Append` +* :c:func:`PyWideStringList_Insert` +* :c:func:`Py_BytesMain` +* :c:func:`Py_ExitStatusException` +* :c:func:`Py_InitializeFromConfig` +* :c:func:`Py_PreInitialize` +* :c:func:`Py_PreInitializeFromArgs` +* :c:func:`Py_PreInitializeFromBytesArgs` +* :c:func:`Py_RunMain` + +This PEP also adds ``_PyRuntimeState.preconfig`` (:c:type:`PyPreConfig` type) +and ``PyInterpreterState.config`` (:c:type:`PyConfig` type) fields to these +internal structures. ``PyInterpreterState.config`` becomes the new +reference configuration, replacing global configuration variables and +other private variables. + +See :ref:`Python Initialization Configuration ` for the +documentation. + +See :pep:`587` for a full description. + +(Contributed by Victor Stinner in :issue:`36763`.) + Other Language Changes ====================== diff --git a/Include/Python.h b/Include/Python.h index 17ad5b3071d405..d6e5b139ac6796 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -129,7 +129,7 @@ #include "codecs.h" #include "pyerrors.h" -#include "cpython/coreconfig.h" +#include "cpython/initconfig.h" #include "pystate.h" #include "context.h" diff --git a/Include/cpython/coreconfig.h b/Include/cpython/initconfig.h similarity index 84% rename from Include/cpython/coreconfig.h rename to Include/cpython/initconfig.h index ef5fde20e88d67..a98b91a86943ba 100644 --- a/Include/cpython/coreconfig.h +++ b/Include/cpython/initconfig.h @@ -5,56 +5,49 @@ extern "C" { #endif -/* --- _PyInitError ----------------------------------------------- */ +/* --- PyStatus ----------------------------------------------- */ typedef struct { enum { - _Py_INIT_ERR_TYPE_OK=0, - _Py_INIT_ERR_TYPE_ERROR=1, - _Py_INIT_ERR_TYPE_EXIT=2 + _PyStatus_TYPE_OK=0, + _PyStatus_TYPE_ERROR=1, + _PyStatus_TYPE_EXIT=2 } _type; - const char *_func; + const char *func; const char *err_msg; int exitcode; -} _PyInitError; +} PyStatus; -PyAPI_FUNC(_PyInitError) _PyInitError_Ok(void); -PyAPI_FUNC(_PyInitError) _PyInitError_Error(const char *err_msg); -PyAPI_FUNC(_PyInitError) _PyInitError_NoMemory(void); -PyAPI_FUNC(_PyInitError) _PyInitError_Exit(int exitcode); -PyAPI_FUNC(int) _PyInitError_IsError(_PyInitError err); -PyAPI_FUNC(int) _PyInitError_IsExit(_PyInitError err); -PyAPI_FUNC(int) _PyInitError_Failed(_PyInitError err); +PyAPI_FUNC(PyStatus) PyStatus_Ok(void); +PyAPI_FUNC(PyStatus) PyStatus_Error(const char *err_msg); +PyAPI_FUNC(PyStatus) PyStatus_NoMemory(void); +PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode); +PyAPI_FUNC(int) PyStatus_IsError(PyStatus err); +PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err); +PyAPI_FUNC(int) PyStatus_Exception(PyStatus err); -/* --- _PyWstrList ------------------------------------------------ */ +/* --- PyWideStringList ------------------------------------------------ */ typedef struct { /* If length is greater than zero, items must be non-NULL and all items strings must be non-NULL */ Py_ssize_t length; wchar_t **items; -} _PyWstrList; +} PyWideStringList; +PyAPI_FUNC(PyStatus) PyWideStringList_Append(PyWideStringList *list, + const wchar_t *item); -/* --- _PyPreConfig ----------------------------------------------- */ - -#define _Py_CONFIG_VERSION 1 - -typedef enum { - /* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */ - _PyConfig_INIT_COMPAT = 1, - _PyConfig_INIT_PYTHON = 2, - _PyConfig_INIT_ISOLATED = 3 -} _PyConfigInitEnum; +/* --- PyPreConfig ----------------------------------------------- */ typedef struct { int _config_version; /* Internal configuration version, used for ABI compatibility */ int _config_init; /* _PyConfigInitEnum value */ - /* Parse _Py_PreInitializeFromArgs() arguments? - See _PyCoreConfig.parse_argv */ + /* Parse Py_PreInitializeFromBytesArgs() arguments? + See PyConfig.parse_argv */ int parse_argv; /* If greater than 0, enable isolated mode: sys.path contains @@ -124,22 +117,22 @@ typedef struct { /* Memory allocator: PYTHONMALLOC env var. See PyMemAllocatorName for valid values. */ int allocator; -} _PyPreConfig; +} PyPreConfig; -PyAPI_FUNC(void) _PyPreConfig_InitPythonConfig(_PyPreConfig *config); -PyAPI_FUNC(void) _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config); +PyAPI_FUNC(void) PyPreConfig_InitPythonConfig(PyPreConfig *config); +PyAPI_FUNC(void) PyPreConfig_InitIsolatedConfig(PyPreConfig *config); -/* --- _PyCoreConfig ---------------------------------------------- */ +/* --- PyConfig ---------------------------------------------- */ typedef struct { int _config_version; /* Internal configuration version, used for ABI compatibility */ int _config_init; /* _PyConfigInitEnum value */ - int isolated; /* Isolated mode? see _PyPreConfig.isolated */ - int use_environment; /* Use environment variables? see _PyPreConfig.use_environment */ - int dev_mode; /* Development mode? See _PyPreConfig.dev_mode */ + int isolated; /* Isolated mode? see PyPreConfig.isolated */ + int use_environment; /* Use environment variables? see PyPreConfig.use_environment */ + int dev_mode; /* Development mode? See PyPreConfig.dev_mode */ /* Install signal handlers? Yes by default. */ int install_signal_handlers; @@ -207,7 +200,7 @@ typedef struct { If argv is empty, an empty string is added to ensure that sys.argv always exists and is never empty. */ - _PyWstrList argv; + PyWideStringList argv; /* Program name: @@ -219,8 +212,8 @@ typedef struct { - Use "python" on Windows, or "python3 on other platforms. */ wchar_t *program_name; - _PyWstrList xoptions; /* Command line -X options */ - _PyWstrList warnoptions; /* Warnings options */ + PyWideStringList xoptions; /* Command line -X options */ + PyWideStringList warnoptions; /* Warnings options */ /* If equal to zero, disable the import of the module site and the site-dependent manipulations of sys.path that it entails. Also disable @@ -347,17 +340,37 @@ typedef struct { int legacy_windows_stdio; #endif + /* Value of the --check-hash-based-pycs command line option: + + - "default" means the 'check_source' flag in hash-based pycs + determines invalidation + - "always" causes the interpreter to hash the source file for + invalidation regardless of value of 'check_source' bit + - "never" causes the interpreter to always assume hash-based pycs are + valid + + The default value is "default". + + See PEP 552 "Deterministic pycs" for more details. */ + wchar_t *check_hash_pycs_mode; + /* --- Path configuration inputs ------------ */ - wchar_t *module_search_path_env; /* PYTHONPATH environment variable */ + /* If greater than 0, suppress _PyPathConfig_Calculate() warnings on Unix. + The parameter has no effect on Windows. + + If set to -1 (default), inherit !Py_FrozenFlag value. */ + int pathconfig_warnings; + + wchar_t *pythonpath_env; /* PYTHONPATH environment variable */ wchar_t *home; /* PYTHONHOME environment variable, see also Py_SetPythonHome(). */ /* --- Path configuration outputs ----------- */ - int use_module_search_paths; /* If non-zero, use module_search_paths */ - _PyWstrList module_search_paths; /* sys.path paths. Computed if - use_module_search_paths is equal + int module_search_paths_set; /* If non-zero, use module_search_paths */ + PyWideStringList module_search_paths; /* sys.path paths. Computed if + module_search_paths_set is equal to zero. */ wchar_t *executable; /* sys.executable */ @@ -384,48 +397,28 @@ typedef struct { Needed by freeze_importlib. */ int _install_importlib; - /* Value of the --check-hash-based-pycs command line option: - - - "default" means the 'check_source' flag in hash-based pycs - determines invalidation - - "always" causes the interpreter to hash the source file for - invalidation regardless of value of 'check_source' bit - - "never" causes the interpreter to always assume hash-based pycs are - valid - - The default value is "default". - - See PEP 552 "Deterministic pycs" for more details. */ - wchar_t *check_hash_pycs_mode; - - /* If greater than 0, suppress _PyPathConfig_Calculate() warnings on Unix. - The parameter has no effect on Windows. - - If set to -1 (default), inherit !Py_FrozenFlag value. */ - int pathconfig_warnings; - /* If equal to 0, stop Python initialization before the "main" phase */ int _init_main; -} _PyCoreConfig; +} PyConfig; -PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPythonConfig(_PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config); -PyAPI_FUNC(void) _PyCoreConfig_Clear(_PyCoreConfig *); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetString( - _PyCoreConfig *config, +PyAPI_FUNC(PyStatus) PyConfig_InitPythonConfig(PyConfig *config); +PyAPI_FUNC(PyStatus) PyConfig_InitIsolatedConfig(PyConfig *config); +PyAPI_FUNC(void) PyConfig_Clear(PyConfig *); +PyAPI_FUNC(PyStatus) PyConfig_SetString( + PyConfig *config, wchar_t **config_str, const wchar_t *str); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_DecodeLocale( - _PyCoreConfig *config, +PyAPI_FUNC(PyStatus) PyConfig_SetBytesString( + PyConfig *config, wchar_t **config_str, const char *str); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_Read(_PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetArgv( - _PyCoreConfig *config, +PyAPI_FUNC(PyStatus) PyConfig_Read(PyConfig *config); +PyAPI_FUNC(PyStatus) PyConfig_SetBytesArgv( + PyConfig *config, Py_ssize_t argc, char * const *argv); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetWideArgv(_PyCoreConfig *config, +PyAPI_FUNC(PyStatus) PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv); diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index ba5666465d7e75..2f3a0dbdfe64c5 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -14,14 +14,14 @@ PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, /* PEP 432 Multi-phase initialization API (Private while provisional!) */ -PyAPI_FUNC(_PyInitError) _Py_PreInitialize( - const _PyPreConfig *src_config); -PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromArgs( - const _PyPreConfig *src_config, +PyAPI_FUNC(PyStatus) Py_PreInitialize( + const PyPreConfig *src_config); +PyAPI_FUNC(PyStatus) Py_PreInitializeFromBytesArgs( + const PyPreConfig *src_config, Py_ssize_t argc, char **argv); -PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromWideArgs( - const _PyPreConfig *src_config, +PyAPI_FUNC(PyStatus) Py_PreInitializeFromArgs( + const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv); @@ -30,22 +30,22 @@ PyAPI_FUNC(int) _Py_IsCoreInitialized(void); /* Initialization and finalization */ -PyAPI_FUNC(_PyInitError) _Py_InitializeFromConfig( - const _PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _Py_InitializeFromArgs( - const _PyCoreConfig *config, +PyAPI_FUNC(PyStatus) Py_InitializeFromConfig( + const PyConfig *config); +PyAPI_FUNC(PyStatus) _Py_InitializeFromArgs( + const PyConfig *config, Py_ssize_t argc, char * const *argv); -PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs( - const _PyCoreConfig *config, +PyAPI_FUNC(PyStatus) _Py_InitializeFromWideArgs( + const PyConfig *config, Py_ssize_t argc, wchar_t * const *argv); -PyAPI_FUNC(_PyInitError) _Py_InitializeMain(void); +PyAPI_FUNC(PyStatus) _Py_InitializeMain(void); -PyAPI_FUNC(int) _Py_RunMain(void); +PyAPI_FUNC(int) Py_RunMain(void); -PyAPI_FUNC(void) _Py_NO_RETURN _Py_ExitInitError(_PyInitError err); +PyAPI_FUNC(void) _Py_NO_RETURN Py_ExitStatusException(PyStatus err); /* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level * exit functions. diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 94331f35e1bd43..6b7663fe33157a 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -6,13 +6,11 @@ extern "C" { #endif -#include "cpython/coreconfig.h" +#include "cpython/initconfig.h" PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); -PyAPI_FUNC(_PyCoreConfig *) _PyInterpreterState_GetCoreConfig(PyInterpreterState *); - PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); /* State unique per thread */ diff --git a/Include/internal/pycore_coreconfig.h b/Include/internal/pycore_coreconfig.h deleted file mode 100644 index b17737a90ba325..00000000000000 --- a/Include/internal/pycore_coreconfig.h +++ /dev/null @@ -1,163 +0,0 @@ -#ifndef Py_INTERNAL_CORECONFIG_H -#define Py_INTERNAL_CORECONFIG_H -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -#include "pycore_pystate.h" /* _PyRuntimeState */ - -/* --- _PyInitError ----------------------------------------------- */ - -/* Almost all errors causing Python initialization to fail */ -#ifdef _MSC_VER - /* Visual Studio 2015 doesn't implement C99 __func__ in C */ -# define _Py_INIT_GET_FUNC() __FUNCTION__ -#else -# define _Py_INIT_GET_FUNC() __func__ -#endif - -#define _Py_INIT_OK() \ - (_PyInitError){._type = _Py_INIT_ERR_TYPE_OK,} - /* other fields are set to 0 */ -#define _Py_INIT_ERR(ERR_MSG) \ - (_PyInitError){ \ - ._type = _Py_INIT_ERR_TYPE_ERROR, \ - ._func = _Py_INIT_GET_FUNC(), \ - .err_msg = (ERR_MSG)} - /* other fields are set to 0 */ -#define _Py_INIT_NO_MEMORY() _Py_INIT_ERR("memory allocation failed") -#define _Py_INIT_EXIT(EXITCODE) \ - (_PyInitError){ \ - ._type = _Py_INIT_ERR_TYPE_EXIT, \ - .exitcode = (EXITCODE)} -#define _Py_INIT_IS_ERROR(err) \ - (err._type == _Py_INIT_ERR_TYPE_ERROR) -#define _Py_INIT_IS_EXIT(err) \ - (err._type == _Py_INIT_ERR_TYPE_EXIT) -#define _Py_INIT_FAILED(err) \ - (err._type != _Py_INIT_ERR_TYPE_OK) - -/* --- _PyWstrList ------------------------------------------------ */ - -#define _PyWstrList_INIT (_PyWstrList){.length = 0, .items = NULL} - -#ifndef NDEBUG -PyAPI_FUNC(int) _PyWstrList_CheckConsistency(const _PyWstrList *list); -#endif -PyAPI_FUNC(void) _PyWstrList_Clear(_PyWstrList *list); -PyAPI_FUNC(int) _PyWstrList_Copy(_PyWstrList *list, - const _PyWstrList *list2); -PyAPI_FUNC(int) _PyWstrList_Append(_PyWstrList *list, - const wchar_t *item); -PyAPI_FUNC(PyObject*) _PyWstrList_AsList(const _PyWstrList *list); -PyAPI_FUNC(int) _PyWstrList_Extend(_PyWstrList *list, - const _PyWstrList *list2); - - -/* --- _PyArgv ---------------------------------------------------- */ - -typedef struct { - Py_ssize_t argc; - int use_bytes_argv; - char * const *bytes_argv; - wchar_t * const *wchar_argv; -} _PyArgv; - -PyAPI_FUNC(_PyInitError) _PyArgv_AsWstrList(const _PyArgv *args, - _PyWstrList *list); - - -/* --- Helper functions ------------------------------------------- */ - -PyAPI_FUNC(int) _Py_str_to_int( - const char *str, - int *result); -PyAPI_FUNC(const wchar_t*) _Py_get_xoption( - const _PyWstrList *xoptions, - const wchar_t *name); -PyAPI_FUNC(const char*) _Py_GetEnv( - int use_environment, - const char *name); -PyAPI_FUNC(void) _Py_get_env_flag( - int use_environment, - int *flag, - const char *name); - -/* Py_GetArgcArgv() helper */ -PyAPI_FUNC(void) _Py_ClearArgcArgv(void); - - -/* --- _PyPreCmdline ------------------------------------------------- */ - -typedef struct { - _PyWstrList argv; - _PyWstrList xoptions; /* "-X value" option */ - int isolated; /* -I option */ - int use_environment; /* -E option */ - int dev_mode; /* -X dev and PYTHONDEVMODE */ -} _PyPreCmdline; - -#define _PyPreCmdline_INIT \ - (_PyPreCmdline){ \ - .use_environment = -1, \ - .isolated = -1, \ - .dev_mode = -1} -/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */ - -PyAPI_FUNC(void) _PyPreCmdline_Clear(_PyPreCmdline *cmdline); -PyAPI_FUNC(_PyInitError) _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, - const _PyArgv *args); -PyAPI_FUNC(int) _PyPreCmdline_SetCoreConfig( - const _PyPreCmdline *cmdline, - _PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyPreCmdline_Read(_PyPreCmdline *cmdline, - const _PyPreConfig *preconfig); - - -/* --- _PyPreConfig ----------------------------------------------- */ - -PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(_PyPreConfig *config); -PyAPI_FUNC(void) _PyPreConfig_InitFromCoreConfig( - _PyPreConfig *config, - const _PyCoreConfig *coreconfig); -PyAPI_FUNC(void) _PyPreConfig_InitFromPreConfig( - _PyPreConfig *config, - const _PyPreConfig *config2); -PyAPI_FUNC(void) _PyPreConfig_Copy(_PyPreConfig *config, - const _PyPreConfig *config2); -PyAPI_FUNC(PyObject*) _PyPreConfig_AsDict(const _PyPreConfig *config); -PyAPI_FUNC(void) _PyPreConfig_GetCoreConfig(_PyPreConfig *config, - const _PyCoreConfig *core_config); -PyAPI_FUNC(_PyInitError) _PyPreConfig_Read(_PyPreConfig *config, - const _PyArgv *args); -PyAPI_FUNC(_PyInitError) _PyPreConfig_Write(const _PyPreConfig *config); - - -/* --- _PyCoreConfig ---------------------------------------------- */ - -PyAPI_FUNC(void) _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_Copy( - _PyCoreConfig *config, - const _PyCoreConfig *config2); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_InitPathConfig(_PyCoreConfig *config); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPathConfig( - const _PyCoreConfig *config); -PyAPI_FUNC(void) _PyCoreConfig_Write(const _PyCoreConfig *config, - _PyRuntimeState *runtime); -PyAPI_FUNC(_PyInitError) _PyCoreConfig_SetPyArgv( - _PyCoreConfig *config, - const _PyArgv *args); - - -/* --- Function used for testing ---------------------------------- */ - -PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_CORECONFIG_H */ diff --git a/Include/internal/pycore_initconfig.h b/Include/internal/pycore_initconfig.h new file mode 100644 index 00000000000000..c0b3d957827a55 --- /dev/null +++ b/Include/internal/pycore_initconfig.h @@ -0,0 +1,168 @@ +#ifndef Py_INTERNAL_CORECONFIG_H +#define Py_INTERNAL_CORECONFIG_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pystate.h" /* _PyRuntimeState */ + +/* --- PyStatus ----------------------------------------------- */ + +/* Almost all errors causing Python initialization to fail */ +#ifdef _MSC_VER + /* Visual Studio 2015 doesn't implement C99 __func__ in C */ +# define _PyStatus_GET_FUNC() __FUNCTION__ +#else +# define _PyStatus_GET_FUNC() __func__ +#endif + +#define _PyStatus_OK() \ + (PyStatus){._type = _PyStatus_TYPE_OK,} + /* other fields are set to 0 */ +#define _PyStatus_ERR(ERR_MSG) \ + (PyStatus){ \ + ._type = _PyStatus_TYPE_ERROR, \ + .func = _PyStatus_GET_FUNC(), \ + .err_msg = (ERR_MSG)} + /* other fields are set to 0 */ +#define _PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed") +#define _PyStatus_EXIT(EXITCODE) \ + (PyStatus){ \ + ._type = _PyStatus_TYPE_EXIT, \ + .exitcode = (EXITCODE)} +#define _PyStatus_IS_ERROR(err) \ + (err._type == _PyStatus_TYPE_ERROR) +#define _PyStatus_IS_EXIT(err) \ + (err._type == _PyStatus_TYPE_EXIT) +#define _PyStatus_EXCEPTION(err) \ + (err._type != _PyStatus_TYPE_OK) + +/* --- PyWideStringList ------------------------------------------------ */ + +#define PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL} + +#ifndef NDEBUG +PyAPI_FUNC(int) _PyWideStringList_CheckConsistency(const PyWideStringList *list); +#endif +PyAPI_FUNC(void) _PyWideStringList_Clear(PyWideStringList *list); +PyAPI_FUNC(int) _PyWideStringList_Copy(PyWideStringList *list, + const PyWideStringList *list2); +PyAPI_FUNC(PyStatus) _PyWideStringList_Extend(PyWideStringList *list, + const PyWideStringList *list2); +PyAPI_FUNC(PyObject*) _PyWideStringList_AsList(const PyWideStringList *list); + + +/* --- _PyArgv ---------------------------------------------------- */ + +typedef struct { + Py_ssize_t argc; + int use_bytes_argv; + char * const *bytes_argv; + wchar_t * const *wchar_argv; +} _PyArgv; + +PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args, + PyWideStringList *list); + + +/* --- Helper functions ------------------------------------------- */ + +PyAPI_FUNC(int) _Py_str_to_int( + const char *str, + int *result); +PyAPI_FUNC(const wchar_t*) _Py_get_xoption( + const PyWideStringList *xoptions, + const wchar_t *name); +PyAPI_FUNC(const char*) _Py_GetEnv( + int use_environment, + const char *name); +PyAPI_FUNC(void) _Py_get_env_flag( + int use_environment, + int *flag, + const char *name); + +/* Py_GetArgcArgv() helper */ +PyAPI_FUNC(void) _Py_ClearArgcArgv(void); + + +/* --- _PyPreCmdline ------------------------------------------------- */ + +typedef struct { + PyWideStringList argv; + PyWideStringList xoptions; /* "-X value" option */ + int isolated; /* -I option */ + int use_environment; /* -E option */ + int dev_mode; /* -X dev and PYTHONDEVMODE */ +} _PyPreCmdline; + +#define _PyPreCmdline_INIT \ + (_PyPreCmdline){ \ + .use_environment = -1, \ + .isolated = -1, \ + .dev_mode = -1} +/* Note: _PyPreCmdline_INIT sets other fields to 0/NULL */ + +extern void _PyPreCmdline_Clear(_PyPreCmdline *cmdline); +extern PyStatus _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, + const _PyArgv *args); +extern PyStatus _PyPreCmdline_SetConfig( + const _PyPreCmdline *cmdline, + PyConfig *config); +extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline, + const PyPreConfig *preconfig); + + +/* --- PyPreConfig ----------------------------------------------- */ + +PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig); +extern void _PyPreConfig_InitFromConfig( + PyPreConfig *preconfig, + const PyConfig *config); +extern void _PyPreConfig_InitFromPreConfig( + PyPreConfig *preconfig, + const PyPreConfig *config2); +extern PyObject* _PyPreConfig_AsDict(const PyPreConfig *preconfig); +extern void _PyPreConfig_GetConfig(PyPreConfig *preconfig, + const PyConfig *config); +extern PyStatus _PyPreConfig_Read(PyPreConfig *preconfig, + const _PyArgv *args); +extern PyStatus _PyPreConfig_Write(const PyPreConfig *preconfig); + + +/* --- PyConfig ---------------------------------------------- */ + +#define _Py_CONFIG_VERSION 1 + +typedef enum { + /* Py_Initialize() API: backward compatibility with Python 3.6 and 3.7 */ + _PyConfig_INIT_COMPAT = 1, + _PyConfig_INIT_PYTHON = 2, + _PyConfig_INIT_ISOLATED = 3 +} _PyConfigInitEnum; + +PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config); +extern PyStatus _PyConfig_Copy( + PyConfig *config, + const PyConfig *config2); +extern PyStatus _PyConfig_InitPathConfig(PyConfig *config); +extern PyStatus _PyConfig_SetPathConfig( + const PyConfig *config); +extern void _PyConfig_Write(const PyConfig *config, + _PyRuntimeState *runtime); +extern PyStatus _PyConfig_SetPyArgv( + PyConfig *config, + const _PyArgv *args); + + +/* --- Function used for testing ---------------------------------- */ + +PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CORECONFIG_H */ diff --git a/Include/internal/pycore_pathconfig.h b/Include/internal/pycore_pathconfig.h index bee391187cc97d..be12c6f5cf321a 100644 --- a/Include/internal/pycore_pathconfig.h +++ b/Include/internal/pycore_pathconfig.h @@ -37,17 +37,17 @@ typedef struct _PyPathConfig { PyAPI_DATA(_PyPathConfig) _Py_path_config; -PyAPI_FUNC(void) _PyPathConfig_ClearGlobal(void); -PyAPI_FUNC(_PyInitError) _PyPathConfig_SetGlobal( - const struct _PyPathConfig *config); - -PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate_impl( - _PyPathConfig *config, - const _PyCoreConfig *core_config); -PyAPI_FUNC(int) _PyPathConfig_ComputeSysPath0( - const _PyWstrList *argv, +extern void _PyPathConfig_ClearGlobal(void); +extern PyStatus _PyPathConfig_SetGlobal( + const struct _PyPathConfig *pathconfig); + +extern PyStatus _PyPathConfig_Calculate( + _PyPathConfig *pathconfig, + const PyConfig *config); +extern int _PyPathConfig_ComputeSysPath0( + const PyWideStringList *argv, PyObject **path0); -PyAPI_FUNC(int) _Py_FindEnvConfigValue( +extern int _Py_FindEnvConfigValue( FILE *env_file, const wchar_t *key, wchar_t *value, diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 13a31c262da8c4..69761cef982204 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -8,20 +8,20 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "pycore_coreconfig.h" /* _PyArgv */ +#include "pycore_initconfig.h" /* _PyArgv */ #include "pycore_pystate.h" /* _PyRuntimeState */ /* True if the main interpreter thread exited due to an unhandled * KeyboardInterrupt exception, suggesting the user pressed ^C. */ PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt; -PyAPI_FUNC(int) _Py_UnixMain(int argc, char **argv); +PyAPI_FUNC(int) Py_BytesMain(int argc, char **argv); extern int _Py_SetFileSystemEncoding( const char *encoding, const char *errors); extern void _Py_ClearFileSystemEncoding(void); -extern _PyInitError _PyUnicode_InitEncodings(PyInterpreterState *interp); +extern PyStatus _PyUnicode_InitEncodings(PyInterpreterState *interp); #ifdef MS_WINDOWS extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void); #endif @@ -32,30 +32,30 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); /* Various one-time initializers */ -extern _PyInitError _PyUnicode_Init(void); +extern PyStatus _PyUnicode_Init(void); extern int _PyStructSequence_Init(void); extern int _PyLong_Init(void); -extern _PyInitError _PyFaulthandler_Init(int enable); +extern PyStatus _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(void); -extern _PyInitError _PySys_Create( +extern PyStatus _PySys_Create( _PyRuntimeState *runtime, PyInterpreterState *interp, PyObject **sysmod_p); -extern _PyInitError _PySys_SetPreliminaryStderr(PyObject *sysdict); +extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); extern int _PySys_InitMain( _PyRuntimeState *runtime, PyInterpreterState *interp); -extern _PyInitError _PyImport_Init(PyInterpreterState *interp); -extern _PyInitError _PyExc_Init(void); -extern _PyInitError _PyErr_Init(void); -extern _PyInitError _PyBuiltins_AddExceptions(PyObject * bltinmod); -extern _PyInitError _PyImportHooks_Init(void); +extern PyStatus _PyImport_Init(PyInterpreterState *interp); +extern PyStatus _PyExc_Init(void); +extern PyStatus _PyErr_Init(void); +extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod); +extern PyStatus _PyImportHooks_Init(void); extern int _PyFloat_Init(void); -extern _PyInitError _Py_HashRandomization_Init(const _PyCoreConfig *); +extern PyStatus _Py_HashRandomization_Init(const PyConfig *); -extern _PyInitError _PyTypes_Init(void); -extern _PyInitError _PyImportZip_Init(PyInterpreterState *interp); +extern PyStatus _PyTypes_Init(void); +extern PyStatus _PyImportZip_Init(PyInterpreterState *interp); /* Various internal finalizers */ @@ -94,11 +94,11 @@ extern void _PyGILState_Fini(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime); -PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromPyArgv( - const _PyPreConfig *src_config, +PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv( + const PyPreConfig *src_config, const _PyArgv *args); -PyAPI_FUNC(_PyInitError) _Py_PreInitializeFromCoreConfig( - const _PyCoreConfig *coreconfig, +PyAPI_FUNC(PyStatus) _Py_PreInitializeFromConfig( + const PyConfig *config, const _PyArgv *args); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index ef1d8a061f17f5..3ab4009770c9a0 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -8,7 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -#include "cpython/coreconfig.h" +#include "cpython/initconfig.h" #include "fileobject.h" #include "pystate.h" #include "pythread.h" @@ -106,7 +106,7 @@ struct _is { _Py_error_handler error_handler; } fs_codec; - _PyCoreConfig core_config; + PyConfig config; #ifdef HAVE_DLOPEN int dlopenflags; #endif @@ -193,7 +193,7 @@ struct _gilstate_runtime_state { /* Full Python runtime state */ typedef struct pyruntimestate { - /* Is Python pre-initialized? Set to 1 by _Py_PreInitialize() */ + /* Is Python pre-initialized? Set to 1 by Py_PreInitialize() */ int pre_initialized; /* Is Python core initialized? Set to 1 by _Py_InitializeCore() */ @@ -234,7 +234,7 @@ typedef struct pyruntimestate { struct _ceval_runtime_state ceval; struct _gilstate_runtime_state gilstate; - _PyPreConfig preconfig; + PyPreConfig preconfig; Py_OpenCodeHookFunction open_code_hook; void *open_code_userdata; @@ -248,13 +248,13 @@ typedef struct pyruntimestate { /* Note: _PyRuntimeState_INIT sets other fields to 0/NULL */ PyAPI_DATA(_PyRuntimeState) _PyRuntime; -PyAPI_FUNC(_PyInitError) _PyRuntimeState_Init(_PyRuntimeState *runtime); +PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime); /* Initialize _PyRuntimeState. Return NULL on success, or return an error message on failure. */ -PyAPI_FUNC(_PyInitError) _PyRuntime_Initialize(void); +PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void); PyAPI_FUNC(void) _PyRuntime_Finalize(void); @@ -307,7 +307,7 @@ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( struct _gilstate_runtime_state *gilstate, PyThreadState *newts); -PyAPI_FUNC(_PyInitError) _PyInterpreterState_Enable(_PyRuntimeState *runtime); +PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyGILState_Reinit(_PyRuntimeState *runtime); diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 87e90f74bb13db..a39ef2babbdb0e 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -272,7 +272,7 @@ def test_initialize_pymain(self): def test_run_main(self): out, err = self.run_embedded_interpreter("test_run_main") - self.assertEqual(out.rstrip(), "_Py_RunMain(): sys.argv=['-c', 'arg2']") + self.assertEqual(out.rstrip(), "Py_RunMain(): sys.argv=['-c', 'arg2']") self.assertEqual(err, '') @@ -321,7 +321,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_environment', ] - CORE_CONFIG_COMPAT = { + CONFIG_COMPAT = { '_config_init': API_COMPAT, 'isolated': 0, 'use_environment': 1, @@ -349,7 +349,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'xoptions': [], 'warnoptions': [], - 'module_search_path_env': None, + 'pythonpath_env': None, 'home': None, 'executable': GET_DEFAULT_CONFIG, @@ -386,16 +386,16 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): '_init_main': 1, } if MS_WINDOWS: - CORE_CONFIG_COMPAT.update({ + CONFIG_COMPAT.update({ 'legacy_windows_stdio': 0, }) - CORE_CONFIG_PYTHON = dict(CORE_CONFIG_COMPAT, + CONFIG_PYTHON = dict(CONFIG_COMPAT, _config_init=API_PYTHON, configure_c_stdio=1, parse_argv=1, ) - CORE_CONFIG_ISOLATED = dict(CORE_CONFIG_COMPAT, + CONFIG_ISOLATED = dict(CONFIG_COMPAT, _config_init=API_ISOLATED, isolated=1, use_environment=0, @@ -408,7 +408,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): pathconfig_warnings=0, ) if MS_WINDOWS: - CORE_CONFIG_ISOLATED['legacy_windows_stdio'] = 0 + CONFIG_ISOLATED['legacy_windows_stdio'] = 0 # global config DEFAULT_GLOBAL_CONFIG = { @@ -535,12 +535,12 @@ def get_expected_config(self, expected_preconfig, expected, env, api, if expected['program_name'] is self.GET_DEFAULT_CONFIG: expected['program_name'] = './_testembed' - core_config = configs['core_config'] + config = configs['config'] for key, value in expected.items(): if value is self.GET_DEFAULT_CONFIG: - expected[key] = core_config[key] + expected[key] = config[key] - prepend_path = expected['module_search_path_env'] + prepend_path = expected['pythonpath_env'] if prepend_path is not None: expected['module_search_paths'] = [prepend_path, *expected['module_search_paths']] if add_path is not None: @@ -550,34 +550,34 @@ def get_expected_config(self, expected_preconfig, expected, env, api, if key not in expected_preconfig: expected_preconfig[key] = expected[key] - def check_pre_config(self, config, expected): - pre_config = dict(config['pre_config']) + def check_pre_config(self, configs, expected): + pre_config = dict(configs['pre_config']) for key, value in list(expected.items()): if value is self.IGNORE_CONFIG: del pre_config[key] del expected[key] self.assertEqual(pre_config, expected) - def check_core_config(self, config, expected): - core_config = dict(config['core_config']) + def check_config(self, configs, expected): + config = dict(configs['config']) for key, value in list(expected.items()): if value is self.IGNORE_CONFIG: - del core_config[key] + del config[key] del expected[key] - self.assertEqual(core_config, expected) + self.assertEqual(config, expected) - def check_global_config(self, config): - pre_config = config['pre_config'] - core_config = config['core_config'] + def check_global_config(self, configs): + pre_config = configs['pre_config'] + config = configs['config'] expected = dict(self.DEFAULT_GLOBAL_CONFIG) for item in self.COPY_GLOBAL_CONFIG: if len(item) == 3: global_key, core_key, opposite = item - expected[global_key] = 0 if core_config[core_key] else 1 + expected[global_key] = 0 if config[core_key] else 1 else: global_key, core_key = item - expected[global_key] = core_config[core_key] + expected[global_key] = config[core_key] for item in self.COPY_GLOBAL_PRE_CONFIG: if len(item) == 3: global_key, core_key, opposite = item @@ -586,9 +586,9 @@ def check_global_config(self, config): global_key, core_key = item expected[global_key] = pre_config[core_key] - self.assertEqual(config['global_config'], expected) + self.assertEqual(configs['global_config'], expected) - def check_config(self, testname, expected_config=None, + def check_all_configs(self, testname, expected_config=None, expected_preconfig=None, add_path=None, stderr=None, *, api): env = dict(os.environ) @@ -610,11 +610,11 @@ def check_config(self, testname, expected_config=None, expected_config = {} if api == API_PYTHON: - default_config = self.CORE_CONFIG_PYTHON + default_config = self.CONFIG_PYTHON elif api == API_ISOLATED: - default_config = self.CORE_CONFIG_ISOLATED + default_config = self.CONFIG_ISOLATED else: - default_config = self.CORE_CONFIG_COMPAT + default_config = self.CONFIG_COMPAT expected_config = dict(default_config, **expected_config) self.get_expected_config(expected_preconfig, @@ -627,22 +627,22 @@ def check_config(self, testname, expected_config=None, if stderr is not None: self.assertEqual(err.rstrip(), stderr) try: - config = json.loads(out) + configs = json.loads(out) except json.JSONDecodeError: self.fail(f"fail to decode stdout: {out!r}") - self.check_pre_config(config, expected_preconfig) - self.check_core_config(config, expected_config) - self.check_global_config(config) + self.check_pre_config(configs, expected_preconfig) + self.check_config(configs, expected_config) + self.check_global_config(configs) def test_init_default_config(self): - self.check_config("test_init_initialize_config", api=API_COMPAT) + self.check_all_configs("test_init_initialize_config", api=API_COMPAT) def test_preinit_compat_config(self): - self.check_config("test_preinit_compat_config", api=API_COMPAT) + self.check_all_configs("test_preinit_compat_config", api=API_COMPAT) def test_init_compat_config(self): - self.check_config("test_init_compat_config", api=API_COMPAT) + self.check_all_configs("test_init_compat_config", api=API_COMPAT) def test_init_global_config(self): preconfig = { @@ -664,8 +664,8 @@ def test_init_global_config(self): 'user_site_directory': 0, 'pathconfig_warnings': 0, } - self.check_config("test_init_global_config", config, preconfig, - api=API_COMPAT) + self.check_all_configs("test_init_global_config", config, preconfig, + api=API_COMPAT) def test_init_from_config(self): preconfig = { @@ -689,7 +689,7 @@ def test_init_from_config(self): 'program_name': './conf_program_name', 'argv': ['-c', 'arg2'], 'parse_argv': 1, - 'xoptions': ['core_xoption1=3', 'core_xoption2=', 'core_xoption3'], + 'xoptions': ['xoption1=3', 'xoption2=', 'xoption3'], 'warnoptions': ['error::ResourceWarning', 'default::BytesWarning'], 'run_command': 'pass\n', @@ -709,8 +709,8 @@ def test_init_from_config(self): 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, } - self.check_config("test_init_from_config", config, preconfig, - api=API_COMPAT) + self.check_all_configs("test_init_from_config", config, preconfig, + api=API_COMPAT) def test_init_compat_env(self): preconfig = { @@ -724,7 +724,7 @@ def test_init_compat_env(self): 'malloc_stats': 1, 'inspect': 1, 'optimization_level': 2, - 'module_search_path_env': '/my/path', + 'pythonpath_env': '/my/path', 'pycache_prefix': 'env_pycache_prefix', 'write_bytecode': 0, 'verbose': 1, @@ -735,8 +735,8 @@ def test_init_compat_env(self): 'faulthandler': 1, 'warnoptions': ['EnvVar'], } - self.check_config("test_init_compat_env", config, preconfig, - api=API_COMPAT) + self.check_all_configs("test_init_compat_env", config, preconfig, + api=API_COMPAT) def test_init_python_env(self): preconfig = { @@ -751,7 +751,7 @@ def test_init_python_env(self): 'malloc_stats': 1, 'inspect': 1, 'optimization_level': 2, - 'module_search_path_env': '/my/path', + 'pythonpath_env': '/my/path', 'pycache_prefix': 'env_pycache_prefix', 'write_bytecode': 0, 'verbose': 1, @@ -762,24 +762,24 @@ def test_init_python_env(self): 'faulthandler': 1, 'warnoptions': ['EnvVar'], } - self.check_config("test_init_python_env", config, preconfig, - api=API_PYTHON) + self.check_all_configs("test_init_python_env", config, preconfig, + api=API_PYTHON) def test_init_env_dev_mode(self): preconfig = dict(allocator=PYMEM_ALLOCATOR_DEBUG) config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("test_init_env_dev_mode", config, preconfig, - api=API_COMPAT) + self.check_all_configs("test_init_env_dev_mode", config, preconfig, + api=API_COMPAT) def test_init_env_dev_mode_alloc(self): preconfig = dict(allocator=PYMEM_ALLOCATOR_MALLOC) config = dict(dev_mode=1, faulthandler=1, warnoptions=['default']) - self.check_config("test_init_env_dev_mode_alloc", config, preconfig, - api=API_COMPAT) + self.check_all_configs("test_init_env_dev_mode_alloc", config, preconfig, + api=API_COMPAT) def test_init_dev_mode(self): preconfig = { @@ -790,8 +790,8 @@ def test_init_dev_mode(self): 'dev_mode': 1, 'warnoptions': ['default'], } - self.check_config("test_init_dev_mode", config, preconfig, - api=API_PYTHON) + self.check_all_configs("test_init_dev_mode", config, preconfig, + api=API_PYTHON) def test_preinit_parse_argv(self): # Pre-initialize implicitly using argv: make sure that -X dev @@ -807,8 +807,8 @@ def test_preinit_parse_argv(self): 'warnoptions': ['default'], 'xoptions': ['dev'], } - self.check_config("test_preinit_parse_argv", config, preconfig, - api=API_PYTHON) + self.check_all_configs("test_preinit_parse_argv", config, preconfig, + api=API_PYTHON) def test_preinit_dont_parse_argv(self): # -X dev must be ignored by isolated preconfiguration @@ -820,8 +820,8 @@ def test_preinit_dont_parse_argv(self): "-X", "dev", "-X", "utf8", "script.py"], 'isolated': 0, } - self.check_config("test_preinit_dont_parse_argv", config, preconfig, - api=API_ISOLATED) + self.check_all_configs("test_preinit_dont_parse_argv", config, preconfig, + api=API_ISOLATED) def test_init_isolated_flag(self): config = { @@ -829,7 +829,7 @@ def test_init_isolated_flag(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("test_init_isolated_flag", config, api=API_PYTHON) + self.check_all_configs("test_init_isolated_flag", config, api=API_PYTHON) def test_preinit_isolated1(self): # _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set @@ -838,7 +838,7 @@ def test_preinit_isolated1(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("test_preinit_isolated1", config, api=API_COMPAT) + self.check_all_configs("test_preinit_isolated1", config, api=API_COMPAT) def test_preinit_isolated2(self): # _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 @@ -847,19 +847,19 @@ def test_preinit_isolated2(self): 'use_environment': 0, 'user_site_directory': 0, } - self.check_config("test_preinit_isolated2", config, api=API_COMPAT) + self.check_all_configs("test_preinit_isolated2", config, api=API_COMPAT) def test_preinit_isolated_config(self): - self.check_config("test_preinit_isolated_config", api=API_ISOLATED) + self.check_all_configs("test_preinit_isolated_config", api=API_ISOLATED) def test_init_isolated_config(self): - self.check_config("test_init_isolated_config", api=API_ISOLATED) + self.check_all_configs("test_init_isolated_config", api=API_ISOLATED) def test_preinit_python_config(self): - self.check_config("test_preinit_python_config", api=API_PYTHON) + self.check_all_configs("test_preinit_python_config", api=API_PYTHON) def test_init_python_config(self): - self.check_config("test_init_python_config", api=API_PYTHON) + self.check_all_configs("test_init_python_config", api=API_PYTHON) def test_init_dont_configure_locale(self): # _PyPreConfig.configure_locale=0 @@ -867,64 +867,64 @@ def test_init_dont_configure_locale(self): 'configure_locale': 0, 'coerce_c_locale': 0, } - self.check_config("test_init_dont_configure_locale", {}, preconfig, - api=API_PYTHON) + self.check_all_configs("test_init_dont_configure_locale", {}, preconfig, + api=API_PYTHON) def test_init_read_set(self): - core_config = { + config = { 'program_name': './init_read_set', 'executable': 'my_executable', } - self.check_config("test_init_read_set", core_config, - api=API_PYTHON, - add_path="init_read_set_path") + self.check_all_configs("test_init_read_set", config, + api=API_PYTHON, + add_path="init_read_set_path") def test_init_run_main(self): code = ('import _testinternalcapi, json; ' 'print(json.dumps(_testinternalcapi.get_configs()))') - core_config = { + config = { 'argv': ['-c', 'arg2'], 'program_name': './python3', 'run_command': code + '\n', 'parse_argv': 1, } - self.check_config("test_init_run_main", core_config, api=API_PYTHON) + self.check_all_configs("test_init_run_main", config, api=API_PYTHON) def test_init_main(self): code = ('import _testinternalcapi, json; ' 'print(json.dumps(_testinternalcapi.get_configs()))') - core_config = { + config = { 'argv': ['-c', 'arg2'], 'program_name': './python3', 'run_command': code + '\n', 'parse_argv': 1, '_init_main': 0, } - self.check_config("test_init_main", core_config, - api=API_PYTHON, - stderr="Run Python code before _Py_InitializeMain") + self.check_all_configs("test_init_main", config, + api=API_PYTHON, + stderr="Run Python code before _Py_InitializeMain") def test_init_parse_argv(self): - core_config = { + config = { 'parse_argv': 1, 'argv': ['-c', 'arg1', '-v', 'arg3'], 'program_name': './argv0', 'run_command': 'pass\n', 'use_environment': 0, } - self.check_config("test_init_parse_argv", core_config, api=API_PYTHON) + self.check_all_configs("test_init_parse_argv", config, api=API_PYTHON) def test_init_dont_parse_argv(self): pre_config = { 'parse_argv': 0, } - core_config = { + config = { 'parse_argv': 0, 'argv': ['./argv0', '-E', '-c', 'pass', 'arg1', '-v', 'arg3'], 'program_name': './argv0', } - self.check_config("test_init_dont_parse_argv", core_config, pre_config, - api=API_PYTHON) + self.check_all_configs("test_init_dont_parse_argv", config, pre_config, + api=API_PYTHON) class AuditingTests(EmbeddingTestsMixin, unittest.TestCase): diff --git a/Makefile.pre.in b/Makefile.pre.in index 8071a94dd6ff16..0bf5df4b68e57b 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -322,7 +322,7 @@ PYTHON_OBJS= \ Python/ceval.o \ Python/codecs.o \ Python/compile.o \ - Python/coreconfig.o \ + Python/context.o \ Python/dynamic_annotations.o \ Python/errors.o \ Python/frozenmain.o \ @@ -333,8 +333,10 @@ PYTHON_OBJS= \ Python/getplatform.o \ Python/getversion.o \ Python/graminit.o \ + Python/hamt.o \ Python/import.o \ Python/importdl.o \ + Python/initconfig.o \ Python/marshal.o \ Python/modsupport.o \ Python/mysnprintf.o \ @@ -349,8 +351,6 @@ PYTHON_OBJS= \ Python/pylifecycle.o \ Python/pymath.o \ Python/pystate.o \ - Python/context.o \ - Python/hamt.o \ Python/pythonrun.o \ Python/pytime.o \ Python/bootstrap_hash.o \ @@ -1052,9 +1052,9 @@ PYTHON_HEADERS= \ $(srcdir)/Include/Python-ast.h \ \ $(srcdir)/Include/cpython/abstract.h \ - $(srcdir)/Include/cpython/coreconfig.h \ $(srcdir)/Include/cpython/dictobject.h \ $(srcdir)/Include/cpython/fileobject.h \ + $(srcdir)/Include/cpython/initconfig.h \ $(srcdir)/Include/cpython/interpreteridobject.h \ $(srcdir)/Include/cpython/object.h \ $(srcdir)/Include/cpython/objimpl.h \ @@ -1072,11 +1072,11 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_ceval.h \ $(srcdir)/Include/internal/pycore_condvar.h \ $(srcdir)/Include/internal/pycore_context.h \ - $(srcdir)/Include/internal/pycore_coreconfig.h \ $(srcdir)/Include/internal/pycore_fileutils.h \ $(srcdir)/Include/internal/pycore_getopt.h \ $(srcdir)/Include/internal/pycore_gil.h \ $(srcdir)/Include/internal/pycore_hamt.h \ + $(srcdir)/Include/internal/pycore_initconfig.h \ $(srcdir)/Include/internal/pycore_object.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \ $(srcdir)/Include/internal/pycore_pyerrors.h \ diff --git a/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst b/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst new file mode 100644 index 00000000000000..fc5a48107cfd30 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst @@ -0,0 +1 @@ +Implement the :pep:`587` "Python Initialization Configuration". diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index ba8f0018043f7d..5c2f019e840bdf 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -377,7 +377,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, { PyObject *RawIO_class = (PyObject *)&PyFileIO_Type; #ifdef MS_WINDOWS - _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') { RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type; encoding = "utf-8"; diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 6a0d9bec5af320..a5727b8deed35a 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -288,7 +288,7 @@ iobase_finalize(PyObject *self) shutdown issues). */ if (res == NULL) { #ifndef Py_DEBUG - const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (config->dev_mode) { PyErr_WriteUnraisable(self); } diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 3a43ec16850fcf..3ea77e6934db1b 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -9,7 +9,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" static PyObject * diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index aa466c46ccff12..f2b5a503f4ee1e 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1,5 +1,5 @@ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_traceback.h" #include "pythread.h" #include @@ -1315,7 +1315,7 @@ faulthandler_init_enable(void) return 0; } -_PyInitError +PyStatus _PyFaulthandler_Init(int enable) { #ifdef HAVE_SIGALTSTACK @@ -1340,17 +1340,17 @@ _PyFaulthandler_Init(int enable) thread.cancel_event = PyThread_allocate_lock(); thread.running = PyThread_allocate_lock(); if (!thread.cancel_event || !thread.running) { - return _Py_INIT_ERR("failed to allocate locks for faulthandler"); + return _PyStatus_ERR("failed to allocate locks for faulthandler"); } PyThread_acquire_lock(thread.cancel_event, 1); #endif if (enable) { if (faulthandler_init_enable() < 0) { - return _Py_INIT_ERR("failed to enable faulthandler"); + return _PyStatus_ERR("failed to enable faulthandler"); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } void _PyFaulthandler_Fini(void) diff --git a/Modules/getpath.c b/Modules/getpath.c index 3dcfcef7bd7856..5f807381880283 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -1,7 +1,7 @@ /* Return the initial module search path. */ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "osdefs.h" #include "pycore_fileutils.h" #include "pycore_pathconfig.h" @@ -115,10 +115,10 @@ extern "C" { #define DECODE_LOCALE_ERR(NAME, LEN) \ ((LEN) == (size_t)-2) \ - ? _Py_INIT_ERR("cannot decode " NAME) \ - : _Py_INIT_NO_MEMORY() + ? _PyStatus_ERR("cannot decode " NAME) \ + : _PyStatus_NO_MEMORY() -#define PATHLEN_ERR() _Py_INIT_ERR("path configuration: path too long") +#define PATHLEN_ERR() _PyStatus_ERR("path configuration: path too long") typedef struct { wchar_t *path_env; /* PATH environment variable */ @@ -236,7 +236,7 @@ isdir(wchar_t *filename) /* Add a path component, by appending stuff to buffer. buflen: 'buffer' length in characters including trailing NUL. */ -static _PyInitError +static PyStatus joinpath(wchar_t *buffer, const wchar_t *stuff, size_t buflen) { size_t n, k; @@ -261,7 +261,7 @@ joinpath(wchar_t *buffer, const wchar_t *stuff, size_t buflen) wcsncpy(buffer+n, stuff, k); buffer[n+k] = '\0'; - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -280,7 +280,7 @@ safe_wcscpy(wchar_t *dst, const wchar_t *src, size_t n) /* copy_absolute requires that path be allocated at least 'pathlen' characters (including trailing NUL). */ -static _PyInitError +static PyStatus copy_absolute(wchar_t *path, const wchar_t *p, size_t pathlen) { if (p[0] == SEP) { @@ -294,38 +294,38 @@ copy_absolute(wchar_t *path, const wchar_t *p, size_t pathlen) if (safe_wcscpy(path, p, pathlen) < 0) { return PATHLEN_ERR(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } if (p[0] == '.' && p[1] == SEP) { p += 2; } - _PyInitError err = joinpath(path, p, pathlen); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = joinpath(path, p, pathlen); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* path_len: path length in characters including trailing NUL */ -static _PyInitError +static PyStatus absolutize(wchar_t *path, size_t path_len) { if (path[0] == SEP) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } wchar_t abs_path[MAXPATHLEN+1]; - _PyInitError err = copy_absolute(abs_path, path, Py_ARRAY_LENGTH(abs_path)); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = copy_absolute(abs_path, path, Py_ARRAY_LENGTH(abs_path)); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (safe_wcscpy(path, abs_path, path_len) < 0) { return PATHLEN_ERR(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -335,14 +335,14 @@ absolutize(wchar_t *path, size_t path_len) #endif /* pathlen: 'path' length in characters including trailing NUL */ -static _PyInitError +static PyStatus add_exe_suffix(wchar_t *progpath, size_t progpathlen) { /* Check for already have an executable suffix */ size_t n = wcslen(progpath); size_t s = wcslen(EXE_SUFFIX); if (wcsncasecmp(EXE_SUFFIX, progpath + n - s, s) == 0) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } if (n + s >= progpathlen) { @@ -356,7 +356,7 @@ add_exe_suffix(wchar_t *progpath, size_t progpathlen) progpath[n] = '\0'; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } #endif @@ -364,43 +364,43 @@ add_exe_suffix(wchar_t *progpath, size_t progpathlen) /* search_for_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ -static _PyInitError -search_for_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate, +static PyStatus +search_for_prefix(const PyConfig *config, PyCalculatePath *calculate, wchar_t *prefix, size_t prefix_len, int *found) { - _PyInitError err; + PyStatus status; size_t n; wchar_t *vpath; /* If PYTHONHOME is set, we believe it unconditionally */ - if (core_config->home) { - if (safe_wcscpy(prefix, core_config->home, prefix_len) < 0) { + if (config->home) { + if (safe_wcscpy(prefix, config->home, prefix_len) < 0) { return PATHLEN_ERR(); } wchar_t *delim = wcschr(prefix, DELIM); if (delim) { *delim = L'\0'; } - err = joinpath(prefix, calculate->lib_python, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(prefix, LANDMARK, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, LANDMARK, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } *found = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Check to see if argv[0] is in the build directory */ if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(prefix, L"Modules/Setup.local", prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, L"Modules/Setup.local", prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (isfile(prefix)) { @@ -410,48 +410,48 @@ search_for_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate, if (safe_wcscpy(prefix, calculate->argv0_path, prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(prefix, vpath, prefix_len); + status = joinpath(prefix, vpath, prefix_len); PyMem_RawFree(vpath); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(prefix, L"Lib", prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, L"Lib", prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(prefix, LANDMARK, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, LANDMARK, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (ismodule(prefix, prefix_len)) { *found = -1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } } } /* Search from argv0_path, until root is found */ - err = copy_absolute(prefix, calculate->argv0_path, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = copy_absolute(prefix, calculate->argv0_path, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } do { n = wcslen(prefix); - err = joinpath(prefix, calculate->lib_python, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(prefix, LANDMARK, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, LANDMARK, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (ismodule(prefix, prefix_len)) { *found = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } prefix[n] = L'\0'; reduce(prefix); @@ -461,59 +461,59 @@ search_for_prefix(const _PyCoreConfig *core_config, PyCalculatePath *calculate, if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(prefix, calculate->lib_python, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(prefix, LANDMARK, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, LANDMARK, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (ismodule(prefix, prefix_len)) { *found = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Fail */ *found = 0; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -calculate_prefix(const _PyCoreConfig *core_config, +static PyStatus +calculate_prefix(const PyConfig *config, PyCalculatePath *calculate, wchar_t *prefix, size_t prefix_len) { - _PyInitError err; + PyStatus status; - err = search_for_prefix(core_config, calculate, prefix, prefix_len, + status = search_for_prefix(config, calculate, prefix, prefix_len, &calculate->prefix_found); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } if (!calculate->prefix_found) { - if (core_config->pathconfig_warnings) { + if (config->pathconfig_warnings) { fprintf(stderr, "Could not find platform independent libraries \n"); } if (safe_wcscpy(prefix, calculate->prefix, prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(prefix, calculate->lib_python, prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(prefix, calculate->lib_python, prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } } else { reduce(prefix); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus calculate_reduce_prefix(PyCalculatePath *calculate, wchar_t *prefix, size_t prefix_len) { @@ -536,45 +536,45 @@ calculate_reduce_prefix(PyCalculatePath *calculate, return PATHLEN_ERR(); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* search_for_exec_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ -static _PyInitError -search_for_exec_prefix(const _PyCoreConfig *core_config, +static PyStatus +search_for_exec_prefix(const PyConfig *config, PyCalculatePath *calculate, wchar_t *exec_prefix, size_t exec_prefix_len, int *found) { - _PyInitError err; + PyStatus status; size_t n; /* If PYTHONHOME is set, we believe it unconditionally */ - if (core_config->home) { - wchar_t *delim = wcschr(core_config->home, DELIM); + if (config->home) { + wchar_t *delim = wcschr(config->home, DELIM); if (delim) { if (safe_wcscpy(exec_prefix, delim+1, exec_prefix_len) < 0) { return PATHLEN_ERR(); } } else { - if (safe_wcscpy(exec_prefix, core_config->home, exec_prefix_len) < 0) { + if (safe_wcscpy(exec_prefix, config->home, exec_prefix_len) < 0) { return PATHLEN_ERR(); } } - err = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } *found = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Check to see if argv[0] is in the build directory. "pybuilddir.txt" @@ -583,9 +583,9 @@ search_for_exec_prefix(const _PyCoreConfig *core_config, if (safe_wcscpy(exec_prefix, calculate->argv0_path, exec_prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(exec_prefix, L"pybuilddir.txt", exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, L"pybuilddir.txt", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (isfile(exec_prefix)) { @@ -609,36 +609,36 @@ search_for_exec_prefix(const _PyCoreConfig *core_config, if (safe_wcscpy(exec_prefix, calculate->argv0_path, exec_prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(exec_prefix, pybuilddir, exec_prefix_len); + status = joinpath(exec_prefix, pybuilddir, exec_prefix_len); PyMem_RawFree(pybuilddir ); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } *found = -1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } } /* Search from argv0_path, until root is found */ - err = copy_absolute(exec_prefix, calculate->argv0_path, exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = copy_absolute(exec_prefix, calculate->argv0_path, exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } do { n = wcslen(exec_prefix); - err = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (isdir(exec_prefix)) { *found = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } exec_prefix[n] = L'\0'; reduce(exec_prefix); @@ -648,58 +648,58 @@ search_for_exec_prefix(const _PyCoreConfig *core_config, if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, calculate->lib_python, exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, L"lib-dynload", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (isdir(exec_prefix)) { *found = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Fail */ *found = 0; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -calculate_exec_prefix(const _PyCoreConfig *core_config, +static PyStatus +calculate_exec_prefix(const PyConfig *config, PyCalculatePath *calculate, wchar_t *exec_prefix, size_t exec_prefix_len) { - _PyInitError err; + PyStatus status; - err = search_for_exec_prefix(core_config, calculate, + status = search_for_exec_prefix(config, calculate, exec_prefix, exec_prefix_len, &calculate->exec_prefix_found); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } if (!calculate->exec_prefix_found) { - if (core_config->pathconfig_warnings) { + if (config->pathconfig_warnings) { fprintf(stderr, "Could not find platform dependent libraries \n"); } if (safe_wcscpy(exec_prefix, calculate->exec_prefix, exec_prefix_len) < 0) { return PATHLEN_ERR(); } - err = joinpath(exec_prefix, L"lib/lib-dynload", exec_prefix_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(exec_prefix, L"lib/lib-dynload", exec_prefix_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus calculate_reduce_exec_prefix(PyCalculatePath *calculate, wchar_t *exec_prefix, size_t exec_prefix_len) { @@ -716,15 +716,15 @@ calculate_reduce_exec_prefix(PyCalculatePath *calculate, return PATHLEN_ERR(); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -calculate_program_full_path(const _PyCoreConfig *core_config, - PyCalculatePath *calculate, _PyPathConfig *config) +static PyStatus +calculate_program_full_path(const PyConfig *config, + PyCalculatePath *calculate, _PyPathConfig *pathconfig) { - _PyInitError err; + PyStatus status; wchar_t program_full_path[MAXPATHLEN + 1]; const size_t program_full_path_len = Py_ARRAY_LENGTH(program_full_path); memset(program_full_path, 0, sizeof(program_full_path)); @@ -743,8 +743,8 @@ calculate_program_full_path(const _PyCoreConfig *core_config, * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ - if (wcschr(core_config->program_name, SEP)) { - if (safe_wcscpy(program_full_path, core_config->program_name, + if (wcschr(config->program_name, SEP)) { + if (safe_wcscpy(program_full_path, config->program_name, program_full_path_len) < 0) { return PATHLEN_ERR(); } @@ -795,10 +795,10 @@ calculate_program_full_path(const _PyCoreConfig *core_config, } } - err = joinpath(program_full_path, core_config->program_name, + status = joinpath(program_full_path, config->program_name, program_full_path_len); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } if (isxfile(program_full_path)) { @@ -816,9 +816,9 @@ calculate_program_full_path(const _PyCoreConfig *core_config, program_full_path[0] = '\0'; } if (program_full_path[0] != SEP && program_full_path[0] != '\0') { - err = absolutize(program_full_path, program_full_path_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = absolutize(program_full_path, program_full_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } } #if defined(__CYGWIN__) || defined(__MINGW32__) @@ -828,22 +828,22 @@ calculate_program_full_path(const _PyCoreConfig *core_config, * path (bpo-28441). */ if (program_full_path[0] != '\0') { - err = add_exe_suffix(program_full_path, program_full_path_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = add_exe_suffix(program_full_path, program_full_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } } #endif - config->program_full_path = _PyMem_RawWcsdup(program_full_path); - if (config->program_full_path == NULL) { - return _Py_INIT_NO_MEMORY(); + pathconfig->program_full_path = _PyMem_RawWcsdup(program_full_path); + if (pathconfig->program_full_path == NULL) { + return _PyStatus_NO_MEMORY(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_path) { const size_t argv0_path_len = Py_ARRAY_LENGTH(calculate->argv0_path); @@ -871,7 +871,7 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ - _PyInitError err; + PyStatus status; size_t len; wchar_t* wbuf = Py_DecodeLocale(modPath, &len); if (wbuf == NULL) { @@ -882,15 +882,15 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat return PATHLEN_ERR(); } reduce(calculate->argv0_path); - err = joinpath(calculate->argv0_path, calculate->lib_python, argv0_path_len); - if (_Py_INIT_FAILED(err)) { + status = joinpath(calculate->argv0_path, calculate->lib_python, argv0_path_len); + if (_PyStatus_EXCEPTION(status)) { PyMem_RawFree(wbuf); - return err; + return status; } - err = joinpath(calculate->argv0_path, LANDMARK, argv0_path_len); - if (_Py_INIT_FAILED(err)) { + status = joinpath(calculate->argv0_path, LANDMARK, argv0_path_len); + if (_PyStatus_EXCEPTION(status)) { PyMem_RawFree(wbuf); - return err; + return status; } if (!ismodule(calculate->argv0_path, Py_ARRAY_LENGTH(calculate->argv0_path))) { @@ -925,11 +925,11 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat } else { /* Interpret relative to program_full_path */ - _PyInitError err; + PyStatus status; reduce(calculate->argv0_path); - err = joinpath(calculate->argv0_path, tmpbuffer, argv0_path_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(calculate->argv0_path, tmpbuffer, argv0_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } } linklen = _Py_wreadlink(calculate->argv0_path, tmpbuffer, buflen); @@ -939,7 +939,7 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat reduce(calculate->argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -947,10 +947,10 @@ calculate_argv0_path(PyCalculatePath *calculate, const wchar_t *program_full_pat executable's directory and then in the parent directory. If found, open it for use when searching for prefixes. */ -static _PyInitError +static PyStatus calculate_read_pyenv(PyCalculatePath *calculate) { - _PyInitError err; + PyStatus status; wchar_t tmpbuffer[MAXPATHLEN+1]; const size_t buflen = Py_ARRAY_LENGTH(tmpbuffer); wchar_t *env_cfg = L"pyvenv.cfg"; @@ -960,9 +960,9 @@ calculate_read_pyenv(PyCalculatePath *calculate) return PATHLEN_ERR(); } - err = joinpath(tmpbuffer, env_cfg, buflen); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(tmpbuffer, env_cfg, buflen); + if (_PyStatus_EXCEPTION(status)) { + return status; } env_file = _Py_wfopen(tmpbuffer, L"r"); if (env_file == NULL) { @@ -970,9 +970,9 @@ calculate_read_pyenv(PyCalculatePath *calculate) reduce(tmpbuffer); reduce(tmpbuffer); - err = joinpath(tmpbuffer, env_cfg, buflen); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(tmpbuffer, env_cfg, buflen); + if (_PyStatus_EXCEPTION(status)) { + return status; } env_file = _Py_wfopen(tmpbuffer, L"r"); @@ -982,7 +982,7 @@ calculate_read_pyenv(PyCalculatePath *calculate) } if (env_file == NULL) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Look for a 'home' variable and set argv0_path to it, if found */ @@ -993,14 +993,14 @@ calculate_read_pyenv(PyCalculatePath *calculate) } } fclose(env_file); - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix) { - _PyInitError err; + PyStatus status; const size_t zip_path_len = Py_ARRAY_LENGTH(calculate->zip_path); if (safe_wcscpy(calculate->zip_path, prefix, zip_path_len) < 0) { return PATHLEN_ERR(); @@ -1016,29 +1016,29 @@ calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix) return PATHLEN_ERR(); } } - err = joinpath(calculate->zip_path, L"lib/python00.zip", zip_path_len); - if (_Py_INIT_FAILED(err)) { - return err; + status = joinpath(calculate->zip_path, L"lib/python00.zip", zip_path_len); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* Replace "00" with version */ size_t bufsz = wcslen(calculate->zip_path); calculate->zip_path[bufsz - 6] = VERSION[0]; calculate->zip_path[bufsz - 5] = VERSION[2]; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -calculate_module_search_path(const _PyCoreConfig *core_config, +static PyStatus +calculate_module_search_path(const PyConfig *config, PyCalculatePath *calculate, const wchar_t *prefix, const wchar_t *exec_prefix, - _PyPathConfig *config) + _PyPathConfig *pathconfig) { /* Calculate size of return buffer */ size_t bufsz = 0; - if (core_config->module_search_path_env != NULL) { - bufsz += wcslen(core_config->module_search_path_env) + 1; + if (config->pythonpath_env != NULL) { + bufsz += wcslen(config->pythonpath_env) + 1; } wchar_t *defpath = calculate->pythonpath; @@ -1067,13 +1067,13 @@ calculate_module_search_path(const _PyCoreConfig *core_config, /* Allocate the buffer */ wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); if (buf == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } buf[0] = '\0'; /* Run-time value of $PYTHONPATH goes first */ - if (core_config->module_search_path_env) { - wcscpy(buf, core_config->module_search_path_env); + if (config->pythonpath_env) { + wcscpy(buf, config->pythonpath_env); wcscat(buf, delimiter); } @@ -1115,14 +1115,14 @@ calculate_module_search_path(const _PyCoreConfig *core_config, /* Finally, on goes the directory for dynamic-load modules */ wcscat(buf, exec_prefix); - config->module_search_path = buf; - return _Py_INIT_OK(); + pathconfig->module_search_path = buf; + return _PyStatus_OK(); } -static _PyInitError +static PyStatus calculate_init(PyCalculatePath *calculate, - const _PyCoreConfig *core_config) + const PyConfig *config) { size_t len; const char *path = getenv("PATH"); @@ -1149,7 +1149,7 @@ calculate_init(PyCalculatePath *calculate, if (!calculate->lib_python) { return DECODE_LOCALE_ERR("EXEC_PREFIX define", len); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -1164,108 +1164,108 @@ calculate_free(PyCalculatePath *calculate) } -static _PyInitError -calculate_path_impl(const _PyCoreConfig *core_config, - PyCalculatePath *calculate, _PyPathConfig *config) +static PyStatus +calculate_path_impl(const PyConfig *config, + PyCalculatePath *calculate, _PyPathConfig *pathconfig) { - _PyInitError err; + PyStatus status; - err = calculate_program_full_path(core_config, calculate, config); - if (_Py_INIT_FAILED(err)) { - return err; + status = calculate_program_full_path(config, calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = calculate_argv0_path(calculate, config->program_full_path); - if (_Py_INIT_FAILED(err)) { - return err; + status = calculate_argv0_path(calculate, pathconfig->program_full_path); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = calculate_read_pyenv(calculate); - if (_Py_INIT_FAILED(err)) { - return err; + status = calculate_read_pyenv(calculate); + if (_PyStatus_EXCEPTION(status)) { + return status; } wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); - err = calculate_prefix(core_config, calculate, + status = calculate_prefix(config, calculate, prefix, Py_ARRAY_LENGTH(prefix)); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = calculate_zip_path(calculate, prefix); - if (_Py_INIT_FAILED(err)) { - return err; + status = calculate_zip_path(calculate, prefix); + if (_PyStatus_EXCEPTION(status)) { + return status; } wchar_t exec_prefix[MAXPATHLEN+1]; memset(exec_prefix, 0, sizeof(exec_prefix)); - err = calculate_exec_prefix(core_config, calculate, + status = calculate_exec_prefix(config, calculate, exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } if ((!calculate->prefix_found || !calculate->exec_prefix_found) && - core_config->pathconfig_warnings) + config->pathconfig_warnings) { fprintf(stderr, "Consider setting $PYTHONHOME to [:]\n"); } - err = calculate_module_search_path(core_config, calculate, - prefix, exec_prefix, config); - if (_Py_INIT_FAILED(err)) { - return err; + status = calculate_module_search_path(config, calculate, + prefix, exec_prefix, pathconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix)); - if (_Py_INIT_FAILED(err)) { - return err; + status = calculate_reduce_prefix(calculate, prefix, Py_ARRAY_LENGTH(prefix)); + if (_PyStatus_EXCEPTION(status)) { + return status; } - config->prefix = _PyMem_RawWcsdup(prefix); - if (config->prefix == NULL) { - return _Py_INIT_NO_MEMORY(); + pathconfig->prefix = _PyMem_RawWcsdup(prefix); + if (pathconfig->prefix == NULL) { + return _PyStatus_NO_MEMORY(); } - err = calculate_reduce_exec_prefix(calculate, + status = calculate_reduce_exec_prefix(calculate, exec_prefix, Py_ARRAY_LENGTH(exec_prefix)); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } - config->exec_prefix = _PyMem_RawWcsdup(exec_prefix); - if (config->exec_prefix == NULL) { - return _Py_INIT_NO_MEMORY(); + pathconfig->exec_prefix = _PyMem_RawWcsdup(exec_prefix); + if (pathconfig->exec_prefix == NULL) { + return _PyStatus_NO_MEMORY(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError -_PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config) +PyStatus +_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) { - _PyInitError err; + PyStatus status; PyCalculatePath calculate; memset(&calculate, 0, sizeof(calculate)); - err = calculate_init(&calculate, core_config); - if (_Py_INIT_FAILED(err)) { + status = calculate_init(&calculate, config); + if (_PyStatus_EXCEPTION(status)) { goto done; } - err = calculate_path_impl(core_config, &calculate, config); - if (_Py_INIT_FAILED(err)) { + status = calculate_path_impl(config, &calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { goto done; } - err = _Py_INIT_OK(); + status = _PyStatus_OK(); done: calculate_free(&calculate); - return err; + return status; } #ifdef __cplusplus diff --git a/Modules/main.c b/Modules/main.c index 08fb0e0417d038..6b9406f7866672 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -1,7 +1,7 @@ /* Python interpreter main program */ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" #include "pycore_pystate.h" @@ -33,14 +33,14 @@ extern "C" { /* --- pymain_init() ---------------------------------------------- */ -static _PyInitError +static PyStatus pymain_init(const _PyArgv *args) { - _PyInitError err; + PyStatus status; - err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* 754 requires that FP exceptions run in "no stop" mode by default, @@ -52,29 +52,36 @@ pymain_init(const _PyArgv *args) fedisableexcept(FE_OVERFLOW); #endif - _PyPreConfig preconfig; - _PyPreConfig_InitPythonConfig(&preconfig); - err = _Py_PreInitializeFromPyArgv(&preconfig, args); - if (_Py_INIT_FAILED(err)) { - return err; + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); + status = _Py_PreInitializeFromPyArgv(&preconfig, args); + if (_PyStatus_EXCEPTION(status)) { + return status; } - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_Py_INIT_FAILED(err)) { - return err; + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* pass NULL as the config: config is read from command line arguments, environment variables, configuration files */ if (args->use_bytes_argv) { - return _Py_InitializeFromArgs(&config, - args->argc, args->bytes_argv); + status = PyConfig_SetBytesArgv(&config, args->argc, args->bytes_argv); } else { - return _Py_InitializeFromWideArgs(&config, - args->argc, args->wchar_argv); + status = PyConfig_SetArgv(&config, args->argc, args->wchar_argv); } + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = Py_InitializeFromConfig(&config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + return _PyStatus_OK(); } @@ -82,13 +89,17 @@ pymain_init(const _PyArgv *args) /* Non-zero if filename, command (-c) or module (-m) is set on the command line */ -#define RUN_CODE(config) \ - (config->run_command != NULL || config->run_filename != NULL \ - || config->run_module != NULL) +static inline int config_run_code(const PyConfig *config) +{ + return (config->run_command != NULL + || config->run_filename != NULL + || config->run_module != NULL); +} + /* Return non-zero is stdin is a TTY or if -i command line option is used */ static int -stdin_is_interactive(const _PyCoreConfig *config) +stdin_is_interactive(const PyConfig *config) { return (isatty(fileno(stdin)) || config->interactive); } @@ -181,13 +192,13 @@ pymain_sys_path_add_path0(PyInterpreterState *interp, PyObject *path0) static void -pymain_header(const _PyCoreConfig *config) +pymain_header(const PyConfig *config) { if (config->quiet) { return; } - if (!config->verbose && (RUN_CODE(config) || !stdin_is_interactive(config))) { + if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) { return; } @@ -199,12 +210,12 @@ pymain_header(const _PyCoreConfig *config) static void -pymain_import_readline(const _PyCoreConfig *config) +pymain_import_readline(const PyConfig *config) { if (config->isolated) { return; } - if (!config->inspect && RUN_CODE(config)) { + if (!config->inspect && config_run_code(config)) { return; } if (!isatty(fileno(stdin))) { @@ -293,7 +304,7 @@ pymain_run_module(const wchar_t *modname, int set_argv0) static int -pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf) +pymain_run_file(PyConfig *config, PyCompilerFlags *cf) { const wchar_t *filename = config->run_filename; FILE *fp = _Py_wfopen(filename, L"rb"); @@ -362,7 +373,7 @@ pymain_run_file(_PyCoreConfig *config, PyCompilerFlags *cf) static int -pymain_run_startup(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode) +pymain_run_startup(PyConfig *config, PyCompilerFlags *cf, int *exitcode) { const char *startup = _Py_GetEnv(config->use_environment, "PYTHONSTARTUP"); if (startup == NULL) { @@ -421,7 +432,7 @@ pymain_run_interactive_hook(int *exitcode) static int -pymain_run_stdin(_PyCoreConfig *config, PyCompilerFlags *cf) +pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf) { if (stdin_is_interactive(config)) { config->inspect = 0; @@ -448,7 +459,7 @@ pymain_run_stdin(_PyCoreConfig *config, PyCompilerFlags *cf) static void -pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode) +pymain_repl(PyConfig *config, PyCompilerFlags *cf, int *exitcode) { /* Check this environment variable at the end, to give programs the opportunity to set it from Python. */ @@ -457,7 +468,7 @@ pymain_repl(_PyCoreConfig *config, PyCompilerFlags *cf, int *exitcode) Py_InspectFlag = 1; } - if (!(config->inspect && stdin_is_interactive(config) && RUN_CODE(config))) { + if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) { return; } @@ -477,7 +488,7 @@ pymain_run_python(int *exitcode) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); /* pymain_run_stdin() modify the config */ - _PyCoreConfig *config = &interp->core_config; + PyConfig *config = &interp->config; PyObject *main_importer_path = NULL; if (config->run_filename != NULL) { @@ -590,20 +601,20 @@ exit_sigint(void) static void _Py_NO_RETURN -pymain_exit_error(_PyInitError err) +pymain_exit_error(PyStatus status) { - if (_Py_INIT_IS_EXIT(err)) { + if (_PyStatus_IS_EXIT(status)) { /* If it's an error rather than a regular exit, leave Python runtime - alive: _Py_ExitInitError() uses the current exception and use + alive: Py_ExitStatusException() uses the current exception and use sys.stdout in this case. */ pymain_free(); } - _Py_ExitInitError(err); + Py_ExitStatusException(status); } int -_Py_RunMain(void) +Py_RunMain(void) { int exitcode = 0; @@ -628,16 +639,16 @@ _Py_RunMain(void) static int pymain_main(_PyArgv *args) { - _PyInitError err = pymain_init(args); - if (_Py_INIT_IS_EXIT(err)) { + PyStatus status = pymain_init(args); + if (_PyStatus_IS_EXIT(status)) { pymain_free(); - return err.exitcode; + return status.exitcode; } - if (_Py_INIT_FAILED(err)) { - pymain_exit_error(err); + if (_PyStatus_EXCEPTION(status)) { + pymain_exit_error(status); } - return _Py_RunMain(); + return Py_RunMain(); } @@ -654,7 +665,7 @@ Py_Main(int argc, wchar_t **argv) int -_Py_UnixMain(int argc, char **argv) +Py_BytesMain(int argc, char **argv) { _PyArgv args = { .argc = argc, diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 8d5ba540120f4b..c7c28312b0052b 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -999,7 +999,7 @@ bytearray_repr(PyByteArrayObject *self) static PyObject * bytearray_str(PyObject *op) { - _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (config->bytes_warning) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytearray instance", 1)) { @@ -1025,7 +1025,7 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) if (rc < 0) return NULL; if (rc) { - _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (config->bytes_warning && (op == Py_EQ || op == Py_NE)) { if (PyErr_WarnEx(PyExc_BytesWarning, "Comparison between bytearray and string", 1)) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 41453b2d14e9d9..0a3ed8691a222f 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1421,7 +1421,7 @@ bytes_repr(PyObject *op) static PyObject * bytes_str(PyObject *op) { - _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (config->bytes_warning) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytes instance", 1)) { @@ -1579,7 +1579,7 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) /* Make sure both arguments are strings. */ if (!(PyBytes_Check(a) && PyBytes_Check(b))) { - _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (config->bytes_warning && (op == Py_EQ || op == Py_NE)) { rc = PyObject_IsInstance((PyObject*)a, (PyObject*)&PyUnicode_Type); diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 4dad0b24cee841..8456a8f1828611 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -6,7 +6,7 @@ #define PY_SSIZE_T_CLEAN #include -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" @@ -2499,13 +2499,13 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, #endif #endif /* MS_WINDOWS */ -_PyInitError +PyStatus _PyExc_Init(void) { #define PRE_INIT(TYPE) \ if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \ - return _Py_INIT_ERR("exceptions bootstrapping error."); \ + return _PyStatus_ERR("exceptions bootstrapping error."); \ } \ Py_INCREF(PyExc_ ## TYPE); \ } @@ -2515,7 +2515,7 @@ _PyExc_Init(void) PyObject *_code = PyLong_FromLong(CODE); \ assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \ if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \ - return _Py_INIT_ERR("errmap insertion problem."); \ + return _PyStatus_ERR("errmap insertion problem."); \ Py_DECREF(_code); \ } while (0) @@ -2589,14 +2589,14 @@ _PyExc_Init(void) PRE_INIT(TimeoutError); if (preallocate_memerrors() < 0) { - return _Py_INIT_ERR("Could not preallocate MemoryError object"); + return _PyStatus_ERR("Could not preallocate MemoryError object"); } /* Add exceptions to errnomap */ if (!errnomap) { errnomap = PyDict_New(); if (!errnomap) { - return _Py_INIT_ERR("Cannot allocate map from errnos to OSError subclasses"); + return _PyStatus_ERR("Cannot allocate map from errnos to OSError subclasses"); } } @@ -2622,7 +2622,7 @@ _PyExc_Init(void) ADD_ERRNO(ProcessLookupError, ESRCH); ADD_ERRNO(TimeoutError, ETIMEDOUT); - return _Py_INIT_OK(); + return _PyStatus_OK(); #undef PRE_INIT #undef ADD_ERRNO @@ -2630,12 +2630,12 @@ _PyExc_Init(void) /* Add exception types to the builtins module */ -_PyInitError +PyStatus _PyBuiltins_AddExceptions(PyObject *bltinmod) { #define POST_INIT(TYPE) \ if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \ - return _Py_INIT_ERR("Module dictionary insertion problem."); \ + return _PyStatus_ERR("Module dictionary insertion problem."); \ } #define INIT_ALIAS(NAME, TYPE) \ @@ -2644,7 +2644,7 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) Py_XDECREF(PyExc_ ## NAME); \ PyExc_ ## NAME = PyExc_ ## TYPE; \ if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \ - return _Py_INIT_ERR("Module dictionary insertion problem."); \ + return _PyStatus_ERR("Module dictionary insertion problem."); \ } \ } while (0) @@ -2652,7 +2652,7 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) bdict = PyModule_GetDict(bltinmod); if (bdict == NULL) { - return _Py_INIT_ERR("exceptions bootstrapping error."); + return _PyStatus_ERR("exceptions bootstrapping error."); } POST_INIT(BaseException); @@ -2729,7 +2729,7 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod) POST_INIT(ProcessLookupError); POST_INIT(TimeoutError); - return _Py_INIT_OK(); + return _PyStatus_OK(); #undef POST_INIT #undef INIT_ALIAS diff --git a/Objects/listobject.c b/Objects/listobject.c index 3185957453d721..b210c005da13cf 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -104,7 +104,7 @@ static void show_alloc(void) { PyInterpreterState *interp = _PyInterpreterState_Get(); - if (!interp->core_config.show_alloc_count) { + if (!interp->config.show_alloc_count) { return; } diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index e570107cedfba5..20e7d44ab5e187 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -590,7 +590,7 @@ _PyModule_ClearDict(PyObject *d) Py_ssize_t pos; PyObject *key, *value; - int verbose = _PyInterpreterState_GET_UNSAFE()->core_config.verbose; + int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose; /* First, clear only names starting with a single underscore */ pos = 0; @@ -677,7 +677,7 @@ module___init___impl(PyModuleObject *self, PyObject *name, PyObject *doc) static void module_dealloc(PyModuleObject *m) { - int verbose = _PyInterpreterState_GET_UNSAFE()->core_config.verbose; + int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose; PyObject_GC_UnTrack(m); if (verbose && m->md_name) { diff --git a/Objects/object.c b/Objects/object.c index 6d79165683e157..270716f397c974 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2,7 +2,7 @@ /* Generic object operations; and implementation of None */ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_object.h" #include "pycore_pystate.h" #include "pycore_context.h" @@ -124,7 +124,7 @@ void _Py_dump_counts(FILE* f) { PyInterpreterState *interp = _PyInterpreterState_Get(); - if (!interp->core_config.show_alloc_count) { + if (!interp->config.show_alloc_count) { return; } @@ -1767,13 +1767,13 @@ PyObject _Py_NotImplementedStruct = { 1, &_PyNotImplemented_Type }; -_PyInitError +PyStatus _PyTypes_Init(void) { #define INIT_TYPE(TYPE, NAME) \ do { \ if (PyType_Ready(TYPE) < 0) { \ - return _Py_INIT_ERR("Can't initialize " NAME " type"); \ + return _PyStatus_ERR("Can't initialize " NAME " type"); \ } \ } while (0) @@ -1843,7 +1843,7 @@ _PyTypes_Init(void) INIT_TYPE(&PyCoro_Type, "coroutine"); INIT_TYPE(&_PyCoroWrapper_Type, "coroutine wrapper"); INIT_TYPE(&_PyInterpreterID_Type, "interpreter ID"); - return _Py_INIT_OK(); + return _PyStatus_OK(); #undef INIT_TYPE } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index dc1d0e5ad0d458..72556adb620746 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -46,7 +46,7 @@ static void show_track(void) { PyInterpreterState *interp = _PyInterpreterState_Get(); - if (!interp->core_config.show_alloc_count) { + if (!interp->config.show_alloc_count) { return; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 0aa5e4ad18dd21..0fe7b5658bef36 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -40,7 +40,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_fileutils.h" #include "pycore_object.h" #include "pycore_pylifecycle.h" @@ -3549,9 +3549,9 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) interp->fs_codec.errors); } else { - const _PyCoreConfig *config = &interp->core_config; + const wchar_t *filesystem_errors = interp->config.filesystem_errors; _Py_error_handler errors; - errors = get_error_handler_wide(config->filesystem_errors); + errors = get_error_handler_wide(filesystem_errors); assert(errors != _Py_ERROR_UNKNOWN); return unicode_encode_utf8(unicode, errors, NULL); } @@ -3567,9 +3567,9 @@ PyUnicode_EncodeFSDefault(PyObject *unicode) interp->fs_codec.errors); } else { - const _PyCoreConfig *config = &interp->core_config; + const wchar_t *filesystem_errors = interp->config.filesystem_errors; _Py_error_handler errors; - errors = get_error_handler_wide(config->filesystem_errors); + errors = get_error_handler_wide(filesystem_errors); assert(errors != _Py_ERROR_UNKNOWN); return unicode_encode_locale(unicode, errors, 0); } @@ -3787,9 +3787,9 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) NULL); } else { - const _PyCoreConfig *config = &interp->core_config; + const wchar_t *filesystem_errors = interp->config.filesystem_errors; _Py_error_handler errors; - errors = get_error_handler_wide(config->filesystem_errors); + errors = get_error_handler_wide(filesystem_errors); assert(errors != _Py_ERROR_UNKNOWN); return unicode_decode_utf8(s, size, errors, NULL, NULL); } @@ -3805,9 +3805,9 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) interp->fs_codec.errors); } else { - const _PyCoreConfig *config = &interp->core_config; + const wchar_t *filesystem_errors = interp->config.filesystem_errors; _Py_error_handler errors; - errors = get_error_handler_wide(config->filesystem_errors); + errors = get_error_handler_wide(filesystem_errors); return unicode_decode_locale(s, size, errors, 0); } #endif @@ -15200,7 +15200,7 @@ PyTypeObject PyUnicode_Type = { /* Initialize the Unicode implementation */ -_PyInitError +PyStatus _PyUnicode_Init(void) { /* XXX - move this array to unicodectype.c ? */ @@ -15218,12 +15218,12 @@ _PyUnicode_Init(void) /* Init the implementation */ _Py_INCREF_UNICODE_EMPTY(); if (!unicode_empty) { - return _Py_INIT_ERR("Can't create empty string"); + return _PyStatus_ERR("Can't create empty string"); } Py_DECREF(unicode_empty); if (PyType_Ready(&PyUnicode_Type) < 0) { - return _Py_INIT_ERR("Can't initialize unicode type"); + return _PyStatus_ERR("Can't initialize unicode type"); } /* initialize the linebreak bloom filter */ @@ -15232,15 +15232,15 @@ _PyUnicode_Init(void) Py_ARRAY_LENGTH(linebreak)); if (PyType_Ready(&EncodingMapType) < 0) { - return _Py_INIT_ERR("Can't initialize encoding map type"); + return _PyStatus_ERR("Can't initialize encoding map type"); } if (PyType_Ready(&PyFieldNameIter_Type) < 0) { - return _Py_INIT_ERR("Can't initialize field name iterator type"); + return _PyStatus_ERR("Can't initialize field name iterator type"); } if (PyType_Ready(&PyFormatterIter_Type) < 0) { - return _Py_INIT_ERR("Can't initialize formatter iter type"); + return _PyStatus_ERR("Can't initialize formatter iter type"); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Finalize the Unicode implementation */ @@ -15718,23 +15718,23 @@ config_get_codec_name(wchar_t **config_encoding) } -static _PyInitError +static PyStatus init_stdio_encoding(PyInterpreterState *interp) { /* Update the stdio encoding to the normalized Python codec name. */ - _PyCoreConfig *config = &interp->core_config; + PyConfig *config = &interp->config; if (config_get_codec_name(&config->stdio_encoding) < 0) { - return _Py_INIT_ERR("failed to get the Python codec name " + return _PyStatus_ERR("failed to get the Python codec name " "of the stdio encoding"); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } static int init_fs_codec(PyInterpreterState *interp) { - _PyCoreConfig *config = &interp->core_config; + PyConfig *config = &interp->config; _Py_error_handler error_handler; error_handler = get_error_handler_wide(config->filesystem_errors); @@ -15778,31 +15778,31 @@ init_fs_codec(PyInterpreterState *interp) } -static _PyInitError +static PyStatus init_fs_encoding(PyInterpreterState *interp) { /* Update the filesystem encoding to the normalized Python codec name. For example, replace "ANSI_X3.4-1968" (locale encoding) with "ascii" (Python codec name). */ - _PyCoreConfig *config = &interp->core_config; + PyConfig *config = &interp->config; if (config_get_codec_name(&config->filesystem_encoding) < 0) { - return _Py_INIT_ERR("failed to get the Python codec " + return _PyStatus_ERR("failed to get the Python codec " "of the filesystem encoding"); } if (init_fs_codec(interp) < 0) { - return _Py_INIT_ERR("cannot initialize filesystem codec"); + return _PyStatus_ERR("cannot initialize filesystem codec"); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError +PyStatus _PyUnicode_InitEncodings(PyInterpreterState *interp) { - _PyInitError err = init_fs_encoding(interp); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = init_fs_encoding(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } return init_stdio_encoding(interp); @@ -15814,7 +15814,7 @@ int _PyUnicode_EnableLegacyWindowsFSEncoding(void) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - _PyCoreConfig *config = &interp->core_config; + PyConfig *config = &interp->config; /* Set the filesystem encoding to mbcs/replace (PEP 529) */ wchar_t *encoding = _PyMem_RawWcsdup(L"mbcs"); diff --git a/PC/getpathp.c b/PC/getpathp.c index 62c42ecefe9e18..e86cf13a4910ac 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -80,7 +80,7 @@ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_pystate.h" #include "osdefs.h" #include @@ -272,10 +272,10 @@ typedef HRESULT(__stdcall *PPathCchCanonicalizeEx) (PWSTR pszPathOut, size_t cch PCWSTR pszPathIn, unsigned long dwFlags); static PPathCchCanonicalizeEx _PathCchCanonicalizeEx; -static _PyInitError canonicalize(wchar_t *buffer, const wchar_t *path) +static PyStatus canonicalize(wchar_t *buffer, const wchar_t *path) { if (buffer == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } if (_PathCchCanonicalizeEx_Initialized == 0) { @@ -291,15 +291,15 @@ static _PyInitError canonicalize(wchar_t *buffer, const wchar_t *path) if (_PathCchCanonicalizeEx) { if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) { - return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()"); + return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()"); } } else { if (!PathCanonicalizeW(buffer, path)) { - return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()"); + return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()"); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -529,9 +529,9 @@ _Py_GetDLLPath(void) } -static _PyInitError -get_program_full_path(const _PyCoreConfig *core_config, - PyCalculatePath *calculate, _PyPathConfig *config) +static PyStatus +get_program_full_path(const PyConfig *config, + PyCalculatePath *calculate, _PyPathConfig *pathconfig) { const wchar_t *pyvenv_launcher; wchar_t program_full_path[MAXPATHLEN+1]; @@ -544,19 +544,19 @@ get_program_full_path(const _PyCoreConfig *core_config, wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher); } else if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) { /* GetModuleFileName should never fail when passed NULL */ - return _Py_INIT_ERR("Cannot determine program path"); + return _PyStatus_ERR("Cannot determine program path"); } - config->program_full_path = PyMem_RawMalloc( + pathconfig->program_full_path = PyMem_RawMalloc( sizeof(wchar_t) * (MAXPATHLEN + 1)); - return canonicalize(config->program_full_path, + return canonicalize(pathconfig->program_full_path, program_full_path); } static int -read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path) +read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path) { FILE *sp_file = _Py_wfopen(path, L"r"); if (sp_file == NULL) { @@ -565,8 +565,8 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path) wcscpy_s(prefix, MAXPATHLEN+1, path); reduce(prefix); - config->isolated = 1; - config->site_import = 0; + pathconfig->isolated = 1; + pathconfig->site_import = 0; size_t bufsiz = MAXPATHLEN; size_t prefixlen = wcslen(prefix); @@ -594,7 +594,7 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path) } if (strcmp(line, "import site") == 0) { - config->site_import = 1; + pathconfig->site_import = 1; continue; } else if (strncmp(line, "import ", 7) == 0) { @@ -642,7 +642,7 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path) } fclose(sp_file); - config->module_search_path = buf; + pathconfig->module_search_path = buf; return 1; error: @@ -654,25 +654,25 @@ read_pth_file(_PyPathConfig *config, wchar_t *prefix, const wchar_t *path) static void calculate_init(PyCalculatePath *calculate, - const _PyCoreConfig *core_config) + const PyConfig *config) { - calculate->home = core_config->home; + calculate->home = config->home; calculate->path_env = _wgetenv(L"PATH"); } static int -get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config) +get_pth_filename(wchar_t *spbuffer, _PyPathConfig *pathconfig) { - if (config->dll_path[0]) { - if (!change_ext(spbuffer, config->dll_path, L"._pth") && + if (pathconfig->dll_path[0]) { + if (!change_ext(spbuffer, pathconfig->dll_path, L"._pth") && exists(spbuffer)) { return 1; } } - if (config->program_full_path[0]) { - if (!change_ext(spbuffer, config->program_full_path, L"._pth") && + if (pathconfig->program_full_path[0]) { + if (!change_ext(spbuffer, pathconfig->program_full_path, L"._pth") && exists(spbuffer)) { return 1; @@ -683,15 +683,15 @@ get_pth_filename(wchar_t *spbuffer, _PyPathConfig *config) static int -calculate_pth_file(_PyPathConfig *config, wchar_t *prefix) +calculate_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix) { wchar_t spbuffer[MAXPATHLEN+1]; - if (!get_pth_filename(spbuffer, config)) { + if (!get_pth_filename(spbuffer, pathconfig)) { return 0; } - return read_pth_file(config, prefix, spbuffer); + return read_pth_file(pathconfig, prefix, spbuffer); } @@ -735,7 +735,7 @@ calculate_pyvenv_file(PyCalculatePath *calculate) } -#define INIT_ERR_BUFFER_OVERFLOW() _Py_INIT_ERR("buffer overflow") +#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow") static void @@ -760,9 +760,9 @@ calculate_home_prefix(PyCalculatePath *calculate, wchar_t *prefix) } -static _PyInitError -calculate_module_search_path(const _PyCoreConfig *core_config, - PyCalculatePath *calculate, _PyPathConfig *config, +static PyStatus +calculate_module_search_path(const PyConfig *config, + PyCalculatePath *calculate, _PyPathConfig *pathconfig, wchar_t *prefix) { int skiphome = calculate->home==NULL ? 0 : 1; @@ -772,7 +772,7 @@ calculate_module_search_path(const _PyCoreConfig *core_config, #endif /* We only use the default relative PYTHONPATH if we haven't anything better to use! */ - int skipdefault = (core_config->module_search_path_env != NULL || + int skipdefault = (config->pythonpath_env != NULL || calculate->home != NULL || calculate->machine_path != NULL || calculate->user_path != NULL); @@ -811,8 +811,8 @@ calculate_module_search_path(const _PyCoreConfig *core_config, bufsz += wcslen(calculate->machine_path) + 1; } bufsz += wcslen(calculate->zip_path) + 1; - if (core_config->module_search_path_env != NULL) { - bufsz += wcslen(core_config->module_search_path_env) + 1; + if (config->pythonpath_env != NULL) { + bufsz += wcslen(config->pythonpath_env) + 1; } wchar_t *buf, *start_buf; @@ -820,21 +820,21 @@ calculate_module_search_path(const _PyCoreConfig *core_config, if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n"); - if (core_config->module_search_path_env) { + if (config->pythonpath_env) { fprintf(stderr, "Using environment $PYTHONPATH.\n"); - config->module_search_path = core_config->module_search_path_env; + pathconfig->module_search_path = config->pythonpath_env; } else { fprintf(stderr, "Using default static path.\n"); - config->module_search_path = PYTHONPATH; + pathconfig->module_search_path = PYTHONPATH; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } start_buf = buf; - if (core_config->module_search_path_env) { + if (config->pythonpath_env) { if (wcscpy_s(buf, bufsz - (buf - start_buf), - core_config->module_search_path_env)) { + config->pythonpath_env)) { return INIT_ERR_BUFFER_OVERFLOW(); } buf = wcschr(buf, L'\0'); @@ -941,38 +941,38 @@ calculate_module_search_path(const _PyCoreConfig *core_config, } } - config->module_search_path = start_buf; - return _Py_INIT_OK(); + pathconfig->module_search_path = start_buf; + return _PyStatus_OK(); } -static _PyInitError -calculate_path_impl(const _PyCoreConfig *core_config, - PyCalculatePath *calculate, _PyPathConfig *config) +static PyStatus +calculate_path_impl(const PyConfig *config, + PyCalculatePath *calculate, _PyPathConfig *pathconfig) { - _PyInitError err; + PyStatus status; - assert(config->dll_path == NULL); + assert(pathconfig->dll_path == NULL); - config->dll_path = _Py_GetDLLPath(); - if (config->dll_path == NULL) { - return _Py_INIT_NO_MEMORY(); + pathconfig->dll_path = _Py_GetDLLPath(); + if (pathconfig->dll_path == NULL) { + return _PyStatus_NO_MEMORY(); } - err = get_program_full_path(core_config, calculate, config); - if (_Py_INIT_FAILED(err)) { - return err; + status = get_program_full_path(config, calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */ - wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->program_full_path); + wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, pathconfig->program_full_path); reduce(calculate->argv0_path); wchar_t prefix[MAXPATHLEN+1]; memset(prefix, 0, sizeof(prefix)); /* Search for a sys.path file */ - if (calculate_pth_file(config, prefix)) { + if (calculate_pth_file(pathconfig, prefix)) { goto done; } @@ -980,27 +980,27 @@ calculate_path_impl(const _PyCoreConfig *core_config, /* Calculate zip archive path from DLL or exe path */ change_ext(calculate->zip_path, - config->dll_path[0] ? config->dll_path : config->program_full_path, + pathconfig->dll_path[0] ? pathconfig->dll_path : pathconfig->program_full_path, L".zip"); calculate_home_prefix(calculate, prefix); - err = calculate_module_search_path(core_config, calculate, config, prefix); - if (_Py_INIT_FAILED(err)) { - return err; + status = calculate_module_search_path(config, calculate, pathconfig, prefix); + if (_PyStatus_EXCEPTION(status)) { + return status; } done: - config->prefix = _PyMem_RawWcsdup(prefix); - if (config->prefix == NULL) { - return _Py_INIT_NO_MEMORY(); + pathconfig->prefix = _PyMem_RawWcsdup(prefix); + if (pathconfig->prefix == NULL) { + return _PyStatus_NO_MEMORY(); } - config->exec_prefix = _PyMem_RawWcsdup(prefix); - if (config->exec_prefix == NULL) { - return _Py_INIT_NO_MEMORY(); + pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix); + if (pathconfig->exec_prefix == NULL) { + return _PyStatus_NO_MEMORY(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -1012,24 +1012,24 @@ calculate_free(PyCalculatePath *calculate) } -_PyInitError -_PyPathConfig_Calculate_impl(_PyPathConfig *config, const _PyCoreConfig *core_config) +PyStatus +_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config) { PyCalculatePath calculate; memset(&calculate, 0, sizeof(calculate)); - calculate_init(&calculate, core_config); + calculate_init(&calculate, config); - _PyInitError err = calculate_path_impl(core_config, &calculate, config); - if (_Py_INIT_FAILED(err)) { + PyStatus status = calculate_path_impl(config, &calculate, pathconfig); + if (_PyStatus_EXCEPTION(status)) { goto done; } - err = _Py_INIT_OK(); + status = _PyStatus_OK(); done: calculate_free(&calculate); - return err; + return status; } diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index db691cd39c8bb4..329f9feb2bdf02 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -127,9 +127,9 @@ - + @@ -161,11 +161,11 @@ - + @@ -420,7 +420,6 @@ - @@ -438,6 +437,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index dba47e9aa2d1fb..d80d05fb15a0cf 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -84,15 +84,15 @@ Include - - Include - Include Include + + Include + Include @@ -186,9 +186,6 @@ Include - - Include - Include @@ -201,6 +198,9 @@ Include + + Include + Include @@ -920,9 +920,6 @@ Python - - Python - Python @@ -977,6 +974,9 @@ Python + + Python + Python diff --git a/Programs/_freeze_importlib.c b/Programs/_freeze_importlib.c index 8cf44d33bc02d9..13375b0a381955 100644 --- a/Programs/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -36,7 +36,7 @@ main(int argc, char *argv[]) const char *name, *inpath, *outpath; char buf[100]; FILE *infile = NULL, *outfile = NULL; - struct _Py_stat_struct status; + struct _Py_stat_struct stat; size_t text_size, data_size, i, n; char *text = NULL; unsigned char *data; @@ -56,11 +56,11 @@ main(int argc, char *argv[]) fprintf(stderr, "cannot open '%s' for reading\n", inpath); goto error; } - if (_Py_fstat_noraise(fileno(infile), &status)) { + if (_Py_fstat_noraise(fileno(infile), &stat)) { fprintf(stderr, "cannot fstat '%s'\n", inpath); goto error; } - text_size = (size_t)status.st_size; + text_size = (size_t)stat.st_size; text = (char *) malloc(text_size + 1); if (text == NULL) { fprintf(stderr, "could not allocate %ld bytes\n", (long) text_size); @@ -76,32 +76,32 @@ main(int argc, char *argv[]) } text[text_size] = '\0'; - _PyInitError err; - _PyCoreConfig config; + PyStatus status; + PyConfig config; - err = _PyCoreConfig_InitIsolatedConfig(&config); - if (_PyInitError_Failed(err)) { - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + status = PyConfig_InitIsolatedConfig(&config); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); } config.site_import = 0; - err = _PyCoreConfig_SetString(&config, &config.program_name, + status = PyConfig_SetString(&config, &config.program_name, L"./_freeze_importlib"); - if (_PyInitError_Failed(err)) { - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); } /* Don't install importlib, since it could execute outdated bytecode. */ config._install_importlib = 0; config._init_main = 0; - err = _Py_InitializeFromConfig(&config); - _PyCoreConfig_Clear(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } sprintf(buf, "", name); diff --git a/Programs/_testembed.c b/Programs/_testembed.c index de1c5877f0f5ab..3e1210e04d8245 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -4,7 +4,7 @@ #endif #include -#include "pycore_coreconfig.h" /* FIXME: PEP 587 makes these functions public */ +#include "pycore_initconfig.h" /* FIXME: PEP 587 makes these functions public */ #include #include "pythread.h" #include @@ -328,25 +328,25 @@ static int test_init_initialize_config(void) static int check_init_compat_config(int preinit) { - _PyInitError err; + PyStatus status; if (preinit) { - _PyPreConfig preconfig; + PyPreConfig preconfig; _PyPreConfig_InitCompatConfig(&preconfig); - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } } - _PyCoreConfig config; - _PyCoreConfig_InitCompatConfig(&config); + PyConfig config; + _PyConfig_InitCompatConfig(&config); config.program_name = L"./_testembed"; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); @@ -418,9 +418,9 @@ static int test_init_global_config(void) static int test_init_from_config(void) { - _PyInitError err; + PyStatus status; - _PyPreConfig preconfig; + PyPreConfig preconfig; _PyPreConfig_InitCompatConfig(&preconfig); putenv("PYTHONMALLOC=malloc_debug"); @@ -430,14 +430,14 @@ static int test_init_from_config(void) Py_UTF8Mode = 0; preconfig.utf8_mode = 1; - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } - /* Test _Py_InitializeFromConfig() */ - _PyCoreConfig config; - _PyCoreConfig_InitCompatConfig(&config); + /* Test Py_InitializeFromConfig() */ + PyConfig config; + _PyConfig_InitCompatConfig(&config); config.install_signal_handlers = 0; /* FIXME: test use_environment */ @@ -481,9 +481,9 @@ static int test_init_from_config(void) config.parse_argv = 1; static wchar_t* xoptions[3] = { - L"core_xoption1=3", - L"core_xoption2=", - L"core_xoption3", + L"xoption1=3", + L"xoption2=", + L"xoption3", }; config.xoptions.length = Py_ARRAY_LENGTH(xoptions); config.xoptions.items = xoptions; @@ -494,7 +494,7 @@ static int test_init_from_config(void) config.warnoptions.length = Py_ARRAY_LENGTH(warnoptions); config.warnoptions.items = warnoptions; - /* FIXME: test module_search_path_env */ + /* FIXME: test pythonpath_env */ /* FIXME: test home */ /* FIXME: test path config: module_search_path .. dll_path */ @@ -553,9 +553,9 @@ static int test_init_from_config(void) Py_FrozenFlag = 0; config.pathconfig_warnings = 0; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -565,12 +565,12 @@ static int test_init_from_config(void) static int check_init_parse_argv(int parse_argv) { - _PyInitError err; + PyStatus status; - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } static wchar_t* argv[] = { @@ -587,9 +587,9 @@ static int check_init_parse_argv(int parse_argv) config.argv.items = argv; config.parse_argv = parse_argv; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -652,20 +652,20 @@ static int test_init_compat_env(void) static int test_init_python_env(void) { - _PyInitError err; + PyStatus status; set_all_env_vars(); - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } config.program_name = L"./_testembed"; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -708,13 +708,13 @@ static int test_init_env_dev_mode_alloc(void) static int test_init_isolated_flag(void) { - _PyInitError err; + PyStatus status; - /* Test _PyCoreConfig.isolated=1 */ - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + /* Test PyConfig.isolated=1 */ + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } Py_IsolatedFlag = 0; @@ -724,9 +724,9 @@ static int test_init_isolated_flag(void) config.program_name = L"./_testembed"; set_all_env_vars(); - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -734,28 +734,28 @@ static int test_init_isolated_flag(void) } -/* _PyPreConfig.isolated=1, _PyCoreConfig.isolated=0 */ +/* PyPreConfig.isolated=1, PyConfig.isolated=0 */ static int test_preinit_isolated1(void) { - _PyInitError err; + PyStatus status; - _PyPreConfig preconfig; + PyPreConfig preconfig; _PyPreConfig_InitCompatConfig(&preconfig); preconfig.isolated = 1; - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } - _PyCoreConfig config; - _PyCoreConfig_InitCompatConfig(&config); + PyConfig config; + _PyConfig_InitCompatConfig(&config); config.program_name = L"./_testembed"; set_all_env_vars(); - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -763,23 +763,23 @@ static int test_preinit_isolated1(void) } -/* _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1 */ +/* PyPreConfig.isolated=0, PyConfig.isolated=1 */ static int test_preinit_isolated2(void) { - _PyInitError err; + PyStatus status; - _PyPreConfig preconfig; + PyPreConfig preconfig; _PyPreConfig_InitCompatConfig(&preconfig); preconfig.isolated = 0; - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } - /* Test _PyCoreConfig.isolated=1 */ - _PyCoreConfig config; - _PyCoreConfig_InitCompatConfig(&config); + /* Test PyConfig.isolated=1 */ + PyConfig config; + _PyConfig_InitCompatConfig(&config); Py_IsolatedFlag = 0; config.isolated = 1; @@ -788,9 +788,9 @@ static int test_preinit_isolated2(void) config.program_name = L"./_testembed"; set_all_env_vars(); - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -800,10 +800,10 @@ static int test_preinit_isolated2(void) static int test_preinit_dont_parse_argv(void) { - _PyInitError err; + PyStatus status; - _PyPreConfig preconfig; - _PyPreConfig_InitIsolatedConfig(&preconfig); + PyPreConfig preconfig; + PyPreConfig_InitIsolatedConfig(&preconfig); preconfig.isolated = 0; @@ -814,15 +814,15 @@ static int test_preinit_dont_parse_argv(void) L"-X", L"dev", L"-X", L"utf8", L"script.py"}; - err = _Py_PreInitializeFromWideArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv); - if (_PyInitError_Failed(err)) { + status = Py_PreInitializeFromArgs(&preconfig, Py_ARRAY_LENGTH(argv), argv); + if (PyStatus_Exception(status)) { goto failed; } - _PyCoreConfig config; + PyConfig config; - err = _PyCoreConfig_InitIsolatedConfig(&config); - if (_PyInitError_Failed(err)) { + status = PyConfig_InitIsolatedConfig(&config); + if (PyStatus_Exception(status)) { goto failed; } @@ -830,70 +830,70 @@ static int test_preinit_dont_parse_argv(void) /* Pre-initialize implicitly using argv: make sure that -X dev is used to configure the allocation in preinitialization */ - err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv); - if (_PyInitError_Failed(err)) { + status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv); + if (PyStatus_Exception(status)) { goto failed; } - err = _PyCoreConfig_SetString(&config, &config.program_name, + status = PyConfig_SetString(&config, &config.program_name, L"./_testembed"); - if (_PyInitError_Failed(err)) { + if (PyStatus_Exception(status)) { goto failed; } - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { goto failed; } - _PyCoreConfig_Clear(&config); + PyConfig_Clear(&config); dump_config(); Py_Finalize(); return 0; failed: - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + PyConfig_Clear(&config); + Py_ExitStatusException(status); } static int test_preinit_parse_argv(void) { - _PyInitError err; - _PyCoreConfig config; + PyStatus status; + PyConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { goto failed; } /* Pre-initialize implicitly using argv: make sure that -X dev is used to configure the allocation in preinitialization */ wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"}; - err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv); - if (_PyInitError_Failed(err)) { + status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv); + if (PyStatus_Exception(status)) { goto failed; } - err = _PyCoreConfig_SetString(&config, &config.program_name, + status = PyConfig_SetString(&config, &config.program_name, L"./_testembed"); - if (_PyInitError_Failed(err)) { + if (PyStatus_Exception(status)) { goto failed; } - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { goto failed; } - _PyCoreConfig_Clear(&config); + PyConfig_Clear(&config); dump_config(); Py_Finalize(); return 0; failed: - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + PyConfig_Clear(&config); + Py_ExitStatusException(status); } @@ -923,8 +923,8 @@ static void set_all_global_config_variables(void) static int check_preinit_isolated_config(int preinit) { - _PyInitError err; - _PyPreConfig *rt_preconfig; + PyStatus status; + PyPreConfig *rt_preconfig; /* environment variables must be ignored */ set_all_env_vars(); @@ -933,12 +933,12 @@ static int check_preinit_isolated_config(int preinit) set_all_global_config_variables(); if (preinit) { - _PyPreConfig preconfig; - _PyPreConfig_InitIsolatedConfig(&preconfig); + PyPreConfig preconfig; + PyPreConfig_InitIsolatedConfig(&preconfig); - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } rt_preconfig = &_PyRuntime.preconfig; @@ -946,18 +946,18 @@ static int check_preinit_isolated_config(int preinit) assert(rt_preconfig->use_environment == 0); } - _PyCoreConfig config; - err = _PyCoreConfig_InitIsolatedConfig(&config); - if (_PyInitError_Failed(err)) { - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + PyConfig config; + status = PyConfig_InitIsolatedConfig(&config); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); } config.program_name = L"./_testembed"; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); } rt_preconfig = &_PyRuntime.preconfig; @@ -984,7 +984,7 @@ static int test_init_isolated_config(void) static int check_init_python_config(int preinit) { - _PyInitError err; + PyStatus status; /* global configuration variables must be ignored */ set_all_global_config_variables(); @@ -1000,25 +1000,25 @@ static int check_init_python_config(int preinit) #endif if (preinit) { - _PyPreConfig preconfig; - _PyPreConfig_InitPythonConfig(&preconfig); + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } } - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } config.program_name = L"./_testembed"; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -1040,28 +1040,28 @@ static int test_init_python_config(void) static int test_init_dont_configure_locale(void) { - _PyInitError err; + PyStatus status; - _PyPreConfig preconfig; - _PyPreConfig_InitPythonConfig(&preconfig); + PyPreConfig preconfig; + PyPreConfig_InitPythonConfig(&preconfig); preconfig.configure_locale = 0; preconfig.coerce_c_locale = 1; preconfig.coerce_c_locale_warn = 1; - err = _Py_PreInitialize(&preconfig); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } config.program_name = L"./_testembed"; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); @@ -1072,19 +1072,19 @@ static int test_init_dont_configure_locale(void) static int test_init_dev_mode(void) { - _PyInitError err; - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyStatus status; + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } putenv("PYTHONFAULTHANDLER="); putenv("PYTHONMALLOC="); config.dev_mode = 1; config.program_name = L"./_testembed"; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } dump_config(); Py_Finalize(); @@ -1250,39 +1250,39 @@ static int test_audit_subinterpreter(void) static int test_init_read_set(void) { - _PyInitError err; - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyStatus status; + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } - err = _PyCoreConfig_DecodeLocale(&config, &config.program_name, + status = PyConfig_SetBytesString(&config, &config.program_name, "./init_read_set"); - if (_PyInitError_Failed(err)) { + if (PyStatus_Exception(status)) { goto fail; } - err = _PyCoreConfig_Read(&config); - if (_PyInitError_Failed(err)) { + status = PyConfig_Read(&config); + if (PyStatus_Exception(status)) { goto fail; } - if (_PyWstrList_Append(&config.module_search_paths, - L"init_read_set_path") < 0) { - err = _PyInitError_NoMemory(); + status = PyWideStringList_Append(&config.module_search_paths, + L"init_read_set_path"); + if (PyStatus_Exception(status)) { goto fail; } - /* override executable computed by _PyCoreConfig_Read() */ - err = _PyCoreConfig_SetString(&config, &config.executable, L"my_executable"); - if (_PyInitError_Failed(err)) { + /* override executable computed by PyConfig_Read() */ + status = PyConfig_SetString(&config, &config.executable, L"my_executable"); + if (PyStatus_Exception(status)) { goto fail; } - err = _Py_InitializeFromConfig(&config); - _PyCoreConfig_Clear(&config); - if (_PyInitError_Failed(err)) { + status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + if (PyStatus_Exception(status)) { goto fail; } dump_config(); @@ -1290,7 +1290,7 @@ static int test_init_read_set(void) return 0; fail: - _Py_ExitInitError(err); + Py_ExitStatusException(status); } @@ -1301,7 +1301,7 @@ wchar_t *init_main_argv[] = { L"arg2"}; -static void configure_init_main(_PyCoreConfig *config) +static void configure_init_main(PyConfig *config) { config->argv.length = Py_ARRAY_LENGTH(init_main_argv); config->argv.items = init_main_argv; @@ -1312,38 +1312,38 @@ static void configure_init_main(_PyCoreConfig *config) static int test_init_run_main(void) { - _PyInitError err; - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyStatus status; + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } configure_init_main(&config); - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } - return _Py_RunMain(); + return Py_RunMain(); } static int test_init_main(void) { - _PyInitError err; - _PyCoreConfig config; + PyStatus status; + PyConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } configure_init_main(&config); config._init_main = 0; - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } /* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */ @@ -1355,51 +1355,51 @@ static int test_init_main(void) exit(1); } - err = _Py_InitializeMain(); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = _Py_InitializeMain(); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } - return _Py_RunMain(); + return Py_RunMain(); } static int test_run_main(void) { - _PyInitError err; - _PyCoreConfig config; + PyStatus status; + PyConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { goto failed; } wchar_t *argv[] = {L"python3", L"-c", (L"import sys; " - L"print(f'_Py_RunMain(): sys.argv={sys.argv}')"), + L"print(f'Py_RunMain(): sys.argv={sys.argv}')"), L"arg2"}; - err = _PyCoreConfig_SetWideArgv(&config, Py_ARRAY_LENGTH(argv), argv); - if (_PyInitError_Failed(err)) { + status = PyConfig_SetArgv(&config, Py_ARRAY_LENGTH(argv), argv); + if (PyStatus_Exception(status)) { goto failed; } - err = _PyCoreConfig_SetString(&config, &config.program_name, + status = PyConfig_SetString(&config, &config.program_name, L"./python3"); - if (_PyInitError_Failed(err)) { + if (PyStatus_Exception(status)) { goto failed; } - err = _Py_InitializeFromConfig(&config); - if (_PyInitError_Failed(err)) { + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { goto failed; } - _PyCoreConfig_Clear(&config); + PyConfig_Clear(&config); - return _Py_RunMain(); + return Py_RunMain(); failed: - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + PyConfig_Clear(&config); + Py_ExitStatusException(status); } diff --git a/Programs/python.c b/Programs/python.c index 4c12d38c53b996..1cc3c42cfcbf93 100644 --- a/Programs/python.c +++ b/Programs/python.c @@ -13,6 +13,6 @@ wmain(int argc, wchar_t **argv) int main(int argc, char **argv) { - return _Py_UnixMain(argc, argv); + return Py_BytesMain(argc, argv); } #endif diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index ff5a51216939e7..5d5808530e1197 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2824,7 +2824,7 @@ _PyBuiltin_Init(void) { PyObject *mod, *dict, *debug; - const _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + const PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (PyType_Ready(&PyFilter_Type) < 0 || PyType_Ready(&PyMap_Type) < 0 || diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index fe71cc388a079e..43f5264d86250c 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -1,5 +1,5 @@ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #ifdef MS_WINDOWS # include /* All sample MSDN wincrypt programs include the header below. It is at least @@ -547,14 +547,14 @@ _PyOS_URandomNonblock(void *buffer, Py_ssize_t size) } -_PyInitError -_Py_HashRandomization_Init(const _PyCoreConfig *config) +PyStatus +_Py_HashRandomization_Init(const PyConfig *config) { void *secret = &_Py_HashSecret; Py_ssize_t secret_size = sizeof(_Py_HashSecret_t); if (_Py_HashSecret_Initialized) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } _Py_HashSecret_Initialized = 1; @@ -579,11 +579,11 @@ _Py_HashRandomization_Init(const _PyCoreConfig *config) pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */ res = pyurandom(secret, secret_size, 0, 0); if (res < 0) { - return _Py_INIT_ERR("failed to get random numbers " + return _PyStatus_ERR("failed to get random numbers " "to initialize Python"); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } diff --git a/Python/compile.c b/Python/compile.c index 734e8401ff0247..425d0d68ac4adc 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -311,7 +311,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, PyCodeObject *co = NULL; PyCompilerFlags local_flags; int merged; - _PyCoreConfig *config = &_PyInterpreterState_GET_UNSAFE()->core_config; + PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; if (!__doc__) { __doc__ = PyUnicode_InternFromString("__doc__"); @@ -4782,7 +4782,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) return compiler_error(c, "'await' outside function"); } - if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && + if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){ return compiler_error(c, "'await' outside async function"); } diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c index f275e534588aa9..da9baa4b998920 100644 --- a/Python/dynload_hpux.c +++ b/Python/dynload_hpux.c @@ -20,7 +20,7 @@ dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, const char *pathname, FILE *fp) { int flags = BIND_FIRST | BIND_DEFERRED; - int verbose = _PyInterpreterState_GET_UNSAFE()->core_config.verbose; + int verbose = _PyInterpreterState_GET_UNSAFE()->config.verbose; if (verbose) { flags = BIND_FIRST | BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE; diff --git a/Python/errors.c b/Python/errors.c index 831f111eead207..bd33d4d340f668 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -2,7 +2,7 @@ /* Error handling */ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "pycore_traceback.h" @@ -1090,16 +1090,16 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = { }; -_PyInitError +PyStatus _PyErr_Init(void) { if (UnraisableHookArgsType.tp_name == NULL) { if (PyStructSequence_InitType2(&UnraisableHookArgsType, &UnraisableHookArgs_desc) < 0) { - return _Py_INIT_ERR("failed to initialize UnraisableHookArgs type"); + return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } diff --git a/Python/frozenmain.c b/Python/frozenmain.c index c3af080401e9b9..c56938ab489948 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -16,9 +16,9 @@ extern int PyInitFrozenExtensions(void); int Py_FrozenMain(int argc, char **argv) { - _PyInitError err = _PyRuntime_Initialize(); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + PyStatus status = _PyRuntime_Initialize(); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } const char *p; @@ -39,11 +39,11 @@ Py_FrozenMain(int argc, char **argv) } } - _PyCoreConfig config; - err = _PyCoreConfig_InitPythonConfig(&config); - if (_PyInitError_Failed(err)) { - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + PyConfig config; + status = PyConfig_InitPythonConfig(&config); + if (PyStatus_Exception(status)) { + PyConfig_Clear(&config); + Py_ExitStatusException(status); } config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */ @@ -85,10 +85,10 @@ Py_FrozenMain(int argc, char **argv) if (argc >= 1) Py_SetProgramName(argv_copy[0]); - err = _Py_InitializeFromConfig(&config); - _PyCoreConfig_Clear(&config); - if (_PyInitError_Failed(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + PyConfig_Clear(&config); + if (PyStatus_Exception(status)) { + Py_ExitStatusException(status); } #ifdef MS_WINDOWS diff --git a/Python/import.c b/Python/import.c index ec172b29f739fc..41a5c01cadf3ad 100644 --- a/Python/import.c +++ b/Python/import.c @@ -43,17 +43,17 @@ module _imp /* Initialize things */ -_PyInitError +PyStatus _PyImport_Init(PyInterpreterState *interp) { interp->builtins_copy = PyDict_Copy(interp->builtins); if (interp->builtins_copy == NULL) { - return _Py_INIT_ERR("Can't backup builtins dict"); + return _PyStatus_ERR("Can't backup builtins dict"); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError +PyStatus _PyImportHooks_Init(void) { PyObject *v, *path_hooks = NULL; @@ -82,15 +82,15 @@ _PyImportHooks_Init(void) goto error; } Py_DECREF(path_hooks); - return _Py_INIT_OK(); + return _PyStatus_OK(); error: PyErr_Print(); - return _Py_INIT_ERR("initializing sys.meta_path, sys.path_hooks, " + return _PyStatus_ERR("initializing sys.meta_path, sys.path_hooks, " "or path_importer_cache failed"); } -_PyInitError +PyStatus _PyImportZip_Init(PyInterpreterState *interp) { PyObject *path_hooks, *zipimport; @@ -102,7 +102,7 @@ _PyImportZip_Init(PyInterpreterState *interp) goto error; } - int verbose = interp->core_config.verbose; + int verbose = interp->config.verbose; if (verbose) { PySys_WriteStderr("# installing zipimport hook\n"); } @@ -138,11 +138,11 @@ _PyImportZip_Init(PyInterpreterState *interp) } } - return _Py_INIT_OK(); + return _PyStatus_OK(); error: PyErr_Print(); - return _Py_INIT_ERR("initializing zipimport failed"); + return _PyStatus_ERR("initializing zipimport failed"); } /* Locking primitives to prevent parallel imports of the same module @@ -418,7 +418,7 @@ PyImport_Cleanup(void) /* XXX Perhaps these precautions are obsolete. Who knows? */ - int verbose = interp->core_config.verbose; + int verbose = interp->config.verbose; if (verbose) { PySys_WriteStderr("# clear builtins._\n"); } @@ -766,7 +766,7 @@ _PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename, PyMapping_DelItem(modules, name); return NULL; } - int verbose = _PyInterpreterState_Get()->core_config.verbose; + int verbose = _PyInterpreterState_Get()->config.verbose; if (verbose) { PySys_FormatStderr("import %U # previously loaded (%R)\n", name, filename); @@ -1455,7 +1455,7 @@ remove_importlib_frames(PyInterpreterState *interp) which end with a call to "_call_with_frames_removed". */ PyErr_Fetch(&exception, &value, &base_tb); - if (!exception || interp->core_config.verbose) { + if (!exception || interp->config.verbose) { goto done; } @@ -1655,7 +1655,7 @@ import_find_and_load(PyObject *abs_name) _Py_IDENTIFIER(_find_and_load); PyObject *mod = NULL; PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - int import_time = interp->core_config.import_time; + int import_time = interp->config.import_time; static int import_level; static _PyTime_t accumulated; @@ -2338,7 +2338,7 @@ PyInit__imp(void) goto failure; } - const wchar_t *mode = _PyInterpreterState_Get()->core_config.check_hash_pycs_mode; + const wchar_t *mode = _PyInterpreterState_Get()->config.check_hash_pycs_mode; PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1); if (pyc_mode == NULL) { goto failure; diff --git a/Python/coreconfig.c b/Python/initconfig.c similarity index 71% rename from Python/coreconfig.c rename to Python/initconfig.c index 89ccff4c9b762e..66b1b305a56033 100644 --- a/Python/coreconfig.c +++ b/Python/initconfig.c @@ -1,6 +1,6 @@ #include "Python.h" #include "osdefs.h" /* DELIM */ -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_fileutils.h" #include "pycore_getopt.h" #include "pycore_pylifecycle.h" @@ -202,39 +202,39 @@ _Py_GetGlobalVariablesAsDict(void) } -/* --- _PyInitError ----------------------------------------------- */ +/* --- PyStatus ----------------------------------------------- */ -_PyInitError _PyInitError_Ok(void) -{ return _Py_INIT_OK(); } +PyStatus PyStatus_Ok(void) +{ return _PyStatus_OK(); } -_PyInitError _PyInitError_Error(const char *err_msg) +PyStatus PyStatus_Error(const char *err_msg) { - return (_PyInitError){._type = _Py_INIT_ERR_TYPE_ERROR, + return (PyStatus){._type = _PyStatus_TYPE_ERROR, .err_msg = err_msg}; } -_PyInitError _PyInitError_NoMemory(void) -{ return _PyInitError_Error("memory allocation failed"); } +PyStatus PyStatus_NoMemory(void) +{ return PyStatus_Error("memory allocation failed"); } -_PyInitError _PyInitError_Exit(int exitcode) -{ return _Py_INIT_EXIT(exitcode); } +PyStatus PyStatus_Exit(int exitcode) +{ return _PyStatus_EXIT(exitcode); } -int _PyInitError_IsError(_PyInitError err) -{ return _Py_INIT_IS_ERROR(err); } +int PyStatus_IsError(PyStatus status) +{ return _PyStatus_IS_ERROR(status); } -int _PyInitError_IsExit(_PyInitError err) -{ return _Py_INIT_IS_EXIT(err); } +int PyStatus_IsExit(PyStatus status) +{ return _PyStatus_IS_EXIT(status); } -int _PyInitError_Failed(_PyInitError err) -{ return _Py_INIT_FAILED(err); } +int PyStatus_Exception(PyStatus status) +{ return _PyStatus_EXCEPTION(status); } -/* --- _PyWstrList ------------------------------------------------ */ +/* --- PyWideStringList ------------------------------------------------ */ #ifndef NDEBUG int -_PyWstrList_CheckConsistency(const _PyWstrList *list) +_PyWideStringList_CheckConsistency(const PyWideStringList *list) { assert(list->length >= 0); if (list->length != 0) { @@ -249,9 +249,9 @@ _PyWstrList_CheckConsistency(const _PyWstrList *list) void -_PyWstrList_Clear(_PyWstrList *list) +_PyWideStringList_Clear(PyWideStringList *list) { - assert(_PyWstrList_CheckConsistency(list)); + assert(_PyWideStringList_CheckConsistency(list)); for (Py_ssize_t i=0; i < list->length; i++) { PyMem_RawFree(list->items[i]); } @@ -262,17 +262,17 @@ _PyWstrList_Clear(_PyWstrList *list) int -_PyWstrList_Copy(_PyWstrList *list, const _PyWstrList *list2) +_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2) { - assert(_PyWstrList_CheckConsistency(list)); - assert(_PyWstrList_CheckConsistency(list2)); + assert(_PyWideStringList_CheckConsistency(list)); + assert(_PyWideStringList_CheckConsistency(list2)); if (list2->length == 0) { - _PyWstrList_Clear(list); + _PyWideStringList_Clear(list); return 0; } - _PyWstrList copy = _PyWstrList_INIT; + PyWideStringList copy = PyWideStringList_INIT; size_t size = list2->length * sizeof(list2->items[0]); copy.items = PyMem_RawMalloc(size); @@ -283,60 +283,61 @@ _PyWstrList_Copy(_PyWstrList *list, const _PyWstrList *list2) for (Py_ssize_t i=0; i < list2->length; i++) { wchar_t *item = _PyMem_RawWcsdup(list2->items[i]); if (item == NULL) { - _PyWstrList_Clear(©); + _PyWideStringList_Clear(©); return -1; } copy.items[i] = item; copy.length = i + 1; } - _PyWstrList_Clear(list); + _PyWideStringList_Clear(list); *list = copy; return 0; } -int -_PyWstrList_Append(_PyWstrList *list, const wchar_t *item) +PyStatus +PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) { if (list->length == PY_SSIZE_T_MAX) { /* lenght+1 would overflow */ - return -1; + return _PyStatus_NO_MEMORY(); } wchar_t *item2 = _PyMem_RawWcsdup(item); if (item2 == NULL) { - return -1; + return _PyStatus_NO_MEMORY(); } size_t size = (list->length + 1) * sizeof(list->items[0]); wchar_t **items2 = (wchar_t **)PyMem_RawRealloc(list->items, size); if (items2 == NULL) { PyMem_RawFree(item2); - return -1; + return _PyStatus_NO_MEMORY(); } items2[list->length] = item2; list->items = items2; list->length++; - return 0; + return _PyStatus_OK(); } -int -_PyWstrList_Extend(_PyWstrList *list, const _PyWstrList *list2) +PyStatus +_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2) { for (Py_ssize_t i = 0; i < list2->length; i++) { - if (_PyWstrList_Append(list, list2->items[i])) { - return -1; + PyStatus status = PyWideStringList_Append(list, list2->items[i]); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return 0; + return _PyStatus_OK(); } static int -_PyWstrList_Find(_PyWstrList *list, const wchar_t *item) +_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item) { for (Py_ssize_t i = 0; i < list->length; i++) { if (wcscmp(list->items[i], item) == 0) { @@ -348,9 +349,9 @@ _PyWstrList_Find(_PyWstrList *list, const wchar_t *item) PyObject* -_PyWstrList_AsList(const _PyWstrList *list) +_PyWideStringList_AsList(const PyWideStringList *list) { - assert(_PyWstrList_CheckConsistency(list)); + assert(_PyWideStringList_CheckConsistency(list)); PyObject *pylist = PyList_New(list->length); if (pylist == NULL) { @@ -457,7 +458,7 @@ _Py_ClearStandardStreamEncoding(void) /* --- Py_GetArgcArgv() ------------------------------------------- */ /* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */ -static _PyWstrList orig_argv = {.length = 0, .items = NULL}; +static PyWideStringList orig_argv = {.length = 0, .items = NULL}; void @@ -466,7 +467,7 @@ _Py_ClearArgcArgv(void) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyWstrList_Clear(&orig_argv); + _PyWideStringList_Clear(&orig_argv); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } @@ -475,13 +476,13 @@ _Py_ClearArgcArgv(void) static int _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) { - const _PyWstrList argv_list = {.length = argc, .items = (wchar_t **)argv}; + const PyWideStringList argv_list = {.length = argc, .items = (wchar_t **)argv}; int res; PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - res = _PyWstrList_Copy(&orig_argv, &argv_list); + res = _PyWideStringList_Copy(&orig_argv, &argv_list); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return res; @@ -498,16 +499,16 @@ Py_GetArgcArgv(int *argc, wchar_t ***argv) } -/* --- _PyCoreConfig ---------------------------------------------- */ +/* --- PyConfig ---------------------------------------------- */ #define DECODE_LOCALE_ERR(NAME, LEN) \ (((LEN) == -2) \ - ? _Py_INIT_ERR("cannot decode " NAME) \ - : _Py_INIT_NO_MEMORY()) + ? _PyStatus_ERR("cannot decode " NAME) \ + : _PyStatus_NO_MEMORY()) /* Free memory allocated in config, but don't clear all attributes */ void -_PyCoreConfig_Clear(_PyCoreConfig *config) +PyConfig_Clear(PyConfig *config) { #define CLEAR(ATTR) \ do { \ @@ -516,15 +517,15 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) } while (0) CLEAR(config->pycache_prefix); - CLEAR(config->module_search_path_env); + CLEAR(config->pythonpath_env); CLEAR(config->home); CLEAR(config->program_name); - _PyWstrList_Clear(&config->argv); - _PyWstrList_Clear(&config->warnoptions); - _PyWstrList_Clear(&config->xoptions); - _PyWstrList_Clear(&config->module_search_paths); - config->use_module_search_paths = 0; + _PyWideStringList_Clear(&config->argv); + _PyWideStringList_Clear(&config->warnoptions); + _PyWideStringList_Clear(&config->xoptions); + _PyWideStringList_Clear(&config->module_search_paths); + config->module_search_paths_set = 0; CLEAR(config->executable); CLEAR(config->prefix); @@ -545,7 +546,7 @@ _PyCoreConfig_Clear(_PyCoreConfig *config) void -_PyCoreConfig_InitCompatConfig(_PyCoreConfig *config) +_PyConfig_InitCompatConfig(PyConfig *config) { memset(config, 0, sizeof(*config)); @@ -558,7 +559,7 @@ _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config) config->use_hash_seed = -1; config->faulthandler = -1; config->tracemalloc = -1; - config->use_module_search_paths = 0; + config->module_search_paths_set = 0; config->parse_argv = 0; config->site_import = -1; config->bytes_warning = -1; @@ -583,9 +584,9 @@ _PyCoreConfig_InitCompatConfig(_PyCoreConfig *config) static void -_PyCoreConfig_InitDefaults(_PyCoreConfig *config) +config_init_defaults(PyConfig *config) { - _PyCoreConfig_InitCompatConfig(config); + _PyConfig_InitCompatConfig(config); config->isolated = 0; config->use_environment = 1; @@ -607,23 +608,23 @@ _PyCoreConfig_InitDefaults(_PyCoreConfig *config) } -_PyInitError -_PyCoreConfig_InitPythonConfig(_PyCoreConfig *config) +PyStatus +PyConfig_InitPythonConfig(PyConfig *config) { - _PyCoreConfig_InitDefaults(config); + config_init_defaults(config); config->_config_init = (int)_PyConfig_INIT_PYTHON; config->configure_c_stdio = 1; config->parse_argv = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError -_PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config) +PyStatus +PyConfig_InitIsolatedConfig(PyConfig *config) { - _PyCoreConfig_InitDefaults(config); + config_init_defaults(config); config->_config_init = (int)_PyConfig_INIT_ISOLATED; config->isolated = 1; @@ -639,25 +640,24 @@ _PyCoreConfig_InitIsolatedConfig(_PyCoreConfig *config) config->legacy_windows_stdio = 0; #endif - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Copy str into *config_str (duplicate the string) */ -_PyInitError -_PyCoreConfig_SetString(_PyCoreConfig *config, wchar_t **config_str, - const wchar_t *str) +PyStatus +PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str) { - _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; } wchar_t *str2; if (str != NULL) { str2 = _PyMem_RawWcsdup(str); if (str2 == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } } else { @@ -665,17 +665,17 @@ _PyCoreConfig_SetString(_PyCoreConfig *config, wchar_t **config_str, } PyMem_RawFree(*config_str); *config_str = str2; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -_PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str, - const char *str, const char *decode_err_msg) +static PyStatus +config_set_bytes_string(PyConfig *config, wchar_t **config_str, + const char *str, const char *decode_err_msg) { - _PyInitError err = _Py_PreInitializeFromCoreConfig(config, NULL); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; } wchar_t *str2; @@ -684,10 +684,10 @@ _PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str, str2 = Py_DecodeLocale(str, &len); if (str2 == NULL) { if (len == (size_t)-2) { - return _Py_INIT_ERR(decode_err_msg); + return _PyStatus_ERR(decode_err_msg); } else { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } } } @@ -696,43 +696,43 @@ _PyCoreConfig_DecodeLocaleErr(_PyCoreConfig *config, wchar_t **config_str, } PyMem_RawFree(*config_str); *config_str = str2; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -#define CONFIG_DECODE_LOCALE(config, config_str, str, NAME) \ - _PyCoreConfig_DecodeLocaleErr(config, config_str, str, "cannot decode " NAME) +#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME) \ + config_set_bytes_string(config, config_str, str, "cannot decode " NAME) /* Decode str using Py_DecodeLocale() and set the result into *config_str. Pre-initialize Python if needed to ensure that encodings are properly configured. */ -_PyInitError -_PyCoreConfig_DecodeLocale(_PyCoreConfig *config, wchar_t **config_str, +PyStatus +PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str, const char *str) { - return CONFIG_DECODE_LOCALE(config, config_str, str, "string"); + return CONFIG_SET_BYTES_STR(config, config_str, str, "string"); } -_PyInitError -_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) +PyStatus +_PyConfig_Copy(PyConfig *config, const PyConfig *config2) { - _PyInitError err; - _PyCoreConfig_Clear(config); + PyStatus status; + PyConfig_Clear(config); #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR #define COPY_WSTR_ATTR(ATTR) \ do { \ - err = _PyCoreConfig_SetString(config, &config->ATTR, config2->ATTR); \ - if (_Py_INIT_FAILED(err)) { \ - return err; \ + status = PyConfig_SetString(config, &config->ATTR, config2->ATTR); \ + if (_PyStatus_EXCEPTION(status)) { \ + return status; \ } \ } while (0) #define COPY_WSTRLIST(LIST) \ do { \ - if (_PyWstrList_Copy(&config->LIST, &config2->LIST) < 0 ) { \ - return _Py_INIT_NO_MEMORY(); \ + if (_PyWideStringList_Copy(&config->LIST, &config2->LIST) < 0 ) { \ + return _PyStatus_NO_MEMORY(); \ } \ } while (0) @@ -753,7 +753,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_ATTR(malloc_stats); COPY_WSTR_ATTR(pycache_prefix); - COPY_WSTR_ATTR(module_search_path_env); + COPY_WSTR_ATTR(pythonpath_env); COPY_WSTR_ATTR(home); COPY_WSTR_ATTR(program_name); @@ -762,7 +762,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) COPY_WSTRLIST(warnoptions); COPY_WSTRLIST(xoptions); COPY_WSTRLIST(module_search_paths); - COPY_ATTR(use_module_search_paths); + COPY_ATTR(module_search_paths_set); COPY_WSTR_ATTR(executable); COPY_WSTR_ATTR(prefix); @@ -800,12 +800,12 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2) #undef COPY_ATTR #undef COPY_WSTR_ATTR #undef COPY_WSTRLIST - return _Py_INIT_OK(); + return _PyStatus_OK(); } static PyObject * -_PyCoreConfig_AsDict(const _PyCoreConfig *config) +config_as_dict(const PyConfig *config) { PyObject *dict; @@ -837,7 +837,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) #define SET_ITEM_WSTR(ATTR) \ SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) #define SET_ITEM_WSTRLIST(LIST) \ - SET_ITEM(#LIST, _PyWstrList_AsList(&config->LIST)) + SET_ITEM(#LIST, _PyWideStringList_AsList(&config->LIST)) SET_ITEM_INT(_config_init); SET_ITEM_INT(isolated); @@ -861,7 +861,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) SET_ITEM_WSTRLIST(argv); SET_ITEM_WSTRLIST(xoptions); SET_ITEM_WSTRLIST(warnoptions); - SET_ITEM_WSTR(module_search_path_env); + SET_ITEM_WSTR(pythonpath_env); SET_ITEM_WSTR(home); SET_ITEM_WSTRLIST(module_search_paths); SET_ITEM_WSTR(executable); @@ -911,7 +911,7 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config) static const char* -_PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) +config_get_env(const PyConfig *config, const char *name) { return _Py_GetEnv(config->use_environment, name); } @@ -920,46 +920,46 @@ _PyCoreConfig_GetEnv(const _PyCoreConfig *config, const char *name) /* Get a copy of the environment variable as wchar_t*. Return 0 on success, but *dest can be NULL. Return -1 on memory allocation failure. Return -2 on decoding error. */ -static _PyInitError -_PyCoreConfig_GetEnvDup(_PyCoreConfig *config, - wchar_t **dest, - wchar_t *wname, char *name, - const char *decode_err_msg) +static PyStatus +config_get_env_dup(PyConfig *config, + wchar_t **dest, + wchar_t *wname, char *name, + const char *decode_err_msg) { assert(*dest == NULL); assert(config->use_environment >= 0); if (!config->use_environment) { *dest = NULL; - return _Py_INIT_OK(); + return _PyStatus_OK(); } #ifdef MS_WINDOWS const wchar_t *var = _wgetenv(wname); if (!var || var[0] == '\0') { *dest = NULL; - return _Py_INIT_OK(); + return _PyStatus_OK(); } - return _PyCoreConfig_SetString(config, dest, var); + return PyConfig_SetString(config, dest, var); #else const char *var = getenv(name); if (!var || var[0] == '\0') { *dest = NULL; - return _Py_INIT_OK(); + return _PyStatus_OK(); } - return _PyCoreConfig_DecodeLocaleErr(config, dest, var, decode_err_msg); + return config_set_bytes_string(config, dest, var, decode_err_msg); #endif } #define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME) \ - _PyCoreConfig_GetEnvDup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME) + config_get_env_dup(CONFIG, DEST, WNAME, NAME, "cannot decode " NAME) static void -_PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) +config_get_global_vars(PyConfig *config) { if (config->_config_init != _PyConfig_INIT_COMPAT) { /* Python and Isolated configuration ignore global variables */ @@ -1001,7 +1001,7 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config) /* Set Py_xxx global configuration variables from 'config' configuration. */ static void -_PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) +config_set_global_vars(const PyConfig *config) { #define COPY_FLAG(ATTR, VAR) \ if (config->ATTR != -1) { \ @@ -1042,19 +1042,19 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config) /* Get the program name: use PYTHONEXECUTABLE and __PYVENV_LAUNCHER__ environment variables on macOS if available. */ -static _PyInitError -config_init_program_name(_PyCoreConfig *config) +static PyStatus +config_init_program_name(PyConfig *config) { - _PyInitError err; + PyStatus status; /* If Py_SetProgramName() was called, use its value */ const wchar_t *program_name = _Py_path_config.program_name; if (program_name != NULL) { config->program_name = _PyMem_RawWcsdup(program_name); if (config->program_name == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } #ifdef __APPLE__ @@ -1067,14 +1067,14 @@ config_init_program_name(_PyCoreConfig *config) so the actual executable path is passed in an environment variable. See Lib/plat-mac/bundlebuiler.py for details about the bootstrap script. */ - const char *p = _PyCoreConfig_GetEnv(config, "PYTHONEXECUTABLE"); + const char *p = config_get_env(config, "PYTHONEXECUTABLE"); if (p != NULL) { - err = CONFIG_DECODE_LOCALE(config, &config->program_name, p, - "PYTHONEXECUTABLE environment variable"); - if (_Py_INIT_FAILED(err)) { - return err; + status = CONFIG_SET_BYTES_STR(config, &config->program_name, p, + "PYTHONEXECUTABLE environment variable"); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } #ifdef WITH_NEXT_FRAMEWORK else { @@ -1083,26 +1083,27 @@ config_init_program_name(_PyCoreConfig *config) /* Used by Mac/Tools/pythonw.c to forward * the argv0 of the stub executable */ - err = CONFIG_DECODE_LOCALE(config, - &config->program_name, pyvenv_launcher, - "__PYVENV_LAUNCHER__ environment variable"); - if (_Py_INIT_FAILED(err)) { - return err; + status = CONFIG_SET_BYTES_STR(config, + &config->program_name, + pyvenv_launcher, + "__PYVENV_LAUNCHER__ environment variable"); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } } #endif /* WITH_NEXT_FRAMEWORK */ #endif /* __APPLE__ */ /* Use argv[0] if available and non-empty */ - const _PyWstrList *argv = &config->argv; + const PyWideStringList *argv = &config->argv; if (argv->length >= 1 && argv->items[0][0] != L'\0') { config->program_name = _PyMem_RawWcsdup(argv->items[0]); if (config->program_name == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Last fall back: hardcoded name */ @@ -1111,54 +1112,54 @@ config_init_program_name(_PyCoreConfig *config) #else const wchar_t *default_program_name = L"python3"; #endif - err = _PyCoreConfig_SetString(config, &config->program_name, - default_program_name); - if (_Py_INIT_FAILED(err)) { - return err; + status = PyConfig_SetString(config, &config->program_name, + default_program_name); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -config_init_executable(_PyCoreConfig *config) +static PyStatus +config_init_executable(PyConfig *config) { assert(config->executable == NULL); /* If Py_SetProgramFullPath() was called, use its value */ const wchar_t *program_full_path = _Py_path_config.program_full_path; if (program_full_path != NULL) { - _PyInitError err = _PyCoreConfig_SetString(config, - &config->executable, - program_full_path); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = PyConfig_SetString(config, + &config->executable, + program_full_path); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } static const wchar_t* -config_get_xoption(const _PyCoreConfig *config, wchar_t *name) +config_get_xoption(const PyConfig *config, wchar_t *name) { return _Py_get_xoption(&config->xoptions, name); } -static _PyInitError -config_init_home(_PyCoreConfig *config) +static PyStatus +config_init_home(PyConfig *config) { assert(config->home == NULL); /* If Py_SetPythonHome() was called, use its value */ wchar_t *home = _Py_path_config.home; if (home) { - _PyInitError err = _PyCoreConfig_SetString(config, &config->home, home); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = PyConfig_SetString(config, &config->home, home); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } return CONFIG_GET_ENV_DUP(config, &config->home, @@ -1166,10 +1167,10 @@ config_init_home(_PyCoreConfig *config) } -static _PyInitError -config_init_hash_seed(_PyCoreConfig *config) +static PyStatus +config_init_hash_seed(PyConfig *config) { - const char *seed_text = _PyCoreConfig_GetEnv(config, "PYTHONHASHSEED"); + const char *seed_text = config_get_env(config, "PYTHONHASHSEED"); Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); /* Convert a text seed to a numeric one */ @@ -1182,7 +1183,7 @@ config_init_hash_seed(_PyCoreConfig *config) || seed > 4294967295UL || (errno == ERANGE && seed == ULONG_MAX)) { - return _Py_INIT_ERR("PYTHONHASHSEED must be \"random\" " + return _PyStatus_ERR("PYTHONHASHSEED must be \"random\" " "or an integer in range [0; 4294967295]"); } /* Use a specific hash */ @@ -1194,7 +1195,7 @@ config_init_hash_seed(_PyCoreConfig *config) config->use_hash_seed = 0; config->hash_seed = 0; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -1216,10 +1217,10 @@ config_wstr_to_int(const wchar_t *wstr, int *result) } -static _PyInitError -config_read_env_vars(_PyCoreConfig *config) +static PyStatus +config_read_env_vars(PyConfig *config) { - _PyInitError err; + PyStatus status; int use_env = config->use_environment; /* Get environment variables */ @@ -1251,39 +1252,39 @@ config_read_env_vars(_PyCoreConfig *config) "PYTHONLEGACYWINDOWSSTDIO"); #endif - if (_PyCoreConfig_GetEnv(config, "PYTHONDUMPREFS")) { + if (config_get_env(config, "PYTHONDUMPREFS")) { config->dump_refs = 1; } - if (_PyCoreConfig_GetEnv(config, "PYTHONMALLOCSTATS")) { + if (config_get_env(config, "PYTHONMALLOCSTATS")) { config->malloc_stats = 1; } - if (config->module_search_path_env == NULL) { - err = CONFIG_GET_ENV_DUP(config, &config->module_search_path_env, - L"PYTHONPATH", "PYTHONPATH"); - if (_Py_INIT_FAILED(err)) { - return err; + if (config->pythonpath_env == NULL) { + status = CONFIG_GET_ENV_DUP(config, &config->pythonpath_env, + L"PYTHONPATH", "PYTHONPATH"); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->use_hash_seed < 0) { - err = config_init_hash_seed(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_hash_seed(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -config_init_tracemalloc(_PyCoreConfig *config) +static PyStatus +config_init_tracemalloc(PyConfig *config) { int nframe; int valid; - const char *env = _PyCoreConfig_GetEnv(config, "PYTHONTRACEMALLOC"); + const char *env = config_get_env(config, "PYTHONTRACEMALLOC"); if (env) { if (!_Py_str_to_int(env, &nframe)) { valid = (nframe >= 0); @@ -1292,7 +1293,7 @@ config_init_tracemalloc(_PyCoreConfig *config) valid = 0; } if (!valid) { - return _Py_INIT_ERR("PYTHONTRACEMALLOC: invalid number of frames"); + return _PyStatus_ERR("PYTHONTRACEMALLOC: invalid number of frames"); } config->tracemalloc = nframe; } @@ -1308,8 +1309,8 @@ config_init_tracemalloc(_PyCoreConfig *config) valid = 0; } if (!valid) { - return _Py_INIT_ERR("-X tracemalloc=NFRAME: " - "invalid number of frames"); + return _PyStatus_ERR("-X tracemalloc=NFRAME: " + "invalid number of frames"); } } else { @@ -1318,12 +1319,12 @@ config_init_tracemalloc(_PyCoreConfig *config) } config->tracemalloc = nframe; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -config_init_pycache_prefix(_PyCoreConfig *config) +static PyStatus +config_init_pycache_prefix(PyConfig *config) { assert(config->pycache_prefix == NULL); @@ -1333,7 +1334,7 @@ config_init_pycache_prefix(_PyCoreConfig *config) if (sep && wcslen(sep) > 1) { config->pycache_prefix = _PyMem_RawWcsdup(sep + 1); if (config->pycache_prefix == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } } else { @@ -1341,7 +1342,7 @@ config_init_pycache_prefix(_PyCoreConfig *config) // if "-X pycache_prefix=" option is used config->pycache_prefix = NULL; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } return CONFIG_GET_ENV_DUP(config, &config->pycache_prefix, @@ -1350,41 +1351,41 @@ config_init_pycache_prefix(_PyCoreConfig *config) } -static _PyInitError -config_read_complex_options(_PyCoreConfig *config) +static PyStatus +config_read_complex_options(PyConfig *config) { /* More complex options configured by env var and -X option */ if (config->faulthandler < 0) { - if (_PyCoreConfig_GetEnv(config, "PYTHONFAULTHANDLER") + if (config_get_env(config, "PYTHONFAULTHANDLER") || config_get_xoption(config, L"faulthandler")) { config->faulthandler = 1; } } - if (_PyCoreConfig_GetEnv(config, "PYTHONPROFILEIMPORTTIME") + if (config_get_env(config, "PYTHONPROFILEIMPORTTIME") || config_get_xoption(config, L"importtime")) { config->import_time = 1; } - _PyInitError err; + PyStatus status; if (config->tracemalloc < 0) { - err = config_init_tracemalloc(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_tracemalloc(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->pycache_prefix == NULL) { - err = config_init_pycache_prefix(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_pycache_prefix(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } static const wchar_t * -config_get_stdio_errors(const _PyCoreConfig *config) +config_get_stdio_errors(const PyConfig *config) { #ifndef MS_WINDOWS const char *loc = setlocale(LC_CTYPE, NULL); @@ -1410,65 +1411,65 @@ config_get_stdio_errors(const _PyCoreConfig *config) } -static _PyInitError -config_get_locale_encoding(_PyCoreConfig *config, wchar_t **locale_encoding) +static PyStatus +config_get_locale_encoding(PyConfig *config, wchar_t **locale_encoding) { #ifdef MS_WINDOWS char encoding[20]; PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); - return _PyCoreConfig_DecodeLocale(config, locale_encoding, encoding); + return PyConfig_SetBytesString(config, locale_encoding, encoding); #elif defined(_Py_FORCE_UTF8_LOCALE) - return _PyCoreConfig_SetString(config, locale_encoding, L"utf-8"); + return PyConfig_SetString(config, locale_encoding, L"utf-8"); #else const char *encoding = nl_langinfo(CODESET); if (!encoding || encoding[0] == '\0') { - return _Py_INIT_ERR("failed to get the locale encoding: " - "nl_langinfo(CODESET) failed"); + return _PyStatus_ERR("failed to get the locale encoding: " + "nl_langinfo(CODESET) failed"); } /* nl_langinfo(CODESET) is decoded by Py_DecodeLocale() */ - return CONFIG_DECODE_LOCALE(config, + return CONFIG_SET_BYTES_STR(config, locale_encoding, encoding, "nl_langinfo(CODESET)"); #endif } -static _PyInitError -config_init_stdio_encoding(_PyCoreConfig *config, - const _PyPreConfig *preconfig) +static PyStatus +config_init_stdio_encoding(PyConfig *config, + const PyPreConfig *preconfig) { - _PyInitError err; + PyStatus status; /* If Py_SetStandardStreamEncoding() have been called, use these parameters. */ if (config->stdio_encoding == NULL && _Py_StandardStreamEncoding != NULL) { - err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding, - _Py_StandardStreamEncoding, - "_Py_StandardStreamEncoding"); - if (_Py_INIT_FAILED(err)) { - return err; + status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding, + _Py_StandardStreamEncoding, + "_Py_StandardStreamEncoding"); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->stdio_errors == NULL && _Py_StandardStreamErrors != NULL) { - err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors, - _Py_StandardStreamErrors, - "_Py_StandardStreamErrors"); - if (_Py_INIT_FAILED(err)) { - return err; + status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors, + _Py_StandardStreamErrors, + "_Py_StandardStreamErrors"); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->stdio_encoding != NULL && config->stdio_errors != NULL) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* PYTHONIOENCODING environment variable */ - const char *opt = _PyCoreConfig_GetEnv(config, "PYTHONIOENCODING"); + const char *opt = config_get_env(config, "PYTHONIOENCODING"); if (opt) { char *pythonioencoding = _PyMem_RawStrdup(opt); if (pythonioencoding == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } char *errors = strchr(pythonioencoding, ':'); @@ -1483,12 +1484,12 @@ config_init_stdio_encoding(_PyCoreConfig *config, /* Does PYTHONIOENCODING contain an encoding? */ if (pythonioencoding[0]) { if (config->stdio_encoding == NULL) { - err = CONFIG_DECODE_LOCALE(config, &config->stdio_encoding, - pythonioencoding, - "PYTHONIOENCODING environment variable"); - if (_Py_INIT_FAILED(err)) { + status = CONFIG_SET_BYTES_STR(config, &config->stdio_encoding, + pythonioencoding, + "PYTHONIOENCODING environment variable"); + if (_PyStatus_EXCEPTION(status)) { PyMem_RawFree(pythonioencoding); - return err; + return status; } } @@ -1502,12 +1503,12 @@ config_init_stdio_encoding(_PyCoreConfig *config, } if (config->stdio_errors == NULL && errors != NULL) { - err = CONFIG_DECODE_LOCALE(config, &config->stdio_errors, - errors, - "PYTHONIOENCODING environment variable"); - if (_Py_INIT_FAILED(err)) { + status = CONFIG_SET_BYTES_STR(config, &config->stdio_errors, + errors, + "PYTHONIOENCODING environment variable"); + if (_PyStatus_EXCEPTION(status)) { PyMem_RawFree(pythonioencoding); - return err; + return status; } } @@ -1517,83 +1518,84 @@ config_init_stdio_encoding(_PyCoreConfig *config, /* UTF-8 Mode uses UTF-8/surrogateescape */ if (preconfig->utf8_mode) { if (config->stdio_encoding == NULL) { - err = _PyCoreConfig_SetString(config, &config->stdio_encoding, L"utf-8"); - if (_Py_INIT_FAILED(err)) { - return err; + status = PyConfig_SetString(config, &config->stdio_encoding, + L"utf-8"); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->stdio_errors == NULL) { - err = _PyCoreConfig_SetString(config, &config->stdio_errors, - L"surrogateescape"); - if (_Py_INIT_FAILED(err)) { - return err; + status = PyConfig_SetString(config, &config->stdio_errors, + L"surrogateescape"); + if (_PyStatus_EXCEPTION(status)) { + return status; } } } /* Choose the default error handler based on the current locale. */ if (config->stdio_encoding == NULL) { - err = config_get_locale_encoding(config, &config->stdio_encoding); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_get_locale_encoding(config, &config->stdio_encoding); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->stdio_errors == NULL) { const wchar_t *errors = config_get_stdio_errors(config); assert(errors != NULL); - err = _PyCoreConfig_SetString(config, &config->stdio_errors, errors); - if (_Py_INIT_FAILED(err)) { - return err; + status = PyConfig_SetString(config, &config->stdio_errors, errors); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) +static PyStatus +config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig) { - _PyInitError err; + PyStatus status; if (config->filesystem_encoding == NULL) { #ifdef _Py_FORCE_UTF8_FS_ENCODING - err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, L"utf-8"); + status = PyConfig_SetString(config, &config->filesystem_encoding, L"utf-8"); #else #ifdef MS_WINDOWS if (preconfig->legacy_windows_fs_encoding) { /* Legacy Windows filesystem encoding: mbcs/replace */ - err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, - L"mbcs"); + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"mbcs"); } else #endif if (preconfig->utf8_mode) { - err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, - L"utf-8"); + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"utf-8"); } #ifndef MS_WINDOWS else if (_Py_GetForceASCII()) { - err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, - L"ascii"); + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"ascii"); } #endif else { #ifdef MS_WINDOWS /* Windows defaults to utf-8/surrogatepass (PEP 529). */ - err = _PyCoreConfig_SetString(config, &config->filesystem_encoding, - L"utf-8"); + status = PyConfig_SetString(config, &config->filesystem_encoding, + L"utf-8"); #else - err = config_get_locale_encoding(config, - &config->filesystem_encoding); + status = config_get_locale_encoding(config, + &config->filesystem_encoding); #endif } #endif /* !_Py_FORCE_UTF8_FS_ENCODING */ - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } } @@ -1609,25 +1611,25 @@ config_init_fs_encoding(_PyCoreConfig *config, const _PyPreConfig *preconfig) #else errors = L"surrogateescape"; #endif - err = _PyCoreConfig_SetString(config, &config->filesystem_errors, errors); - if (_Py_INIT_FAILED(err)) { - return err; + status = PyConfig_SetString(config, &config->filesystem_errors, errors); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -config_read(_PyCoreConfig *config) +static PyStatus +config_read(PyConfig *config) { - _PyInitError err; - const _PyPreConfig *preconfig = &_PyRuntime.preconfig; + PyStatus status; + const PyPreConfig *preconfig = &_PyRuntime.preconfig; if (config->use_environment) { - err = config_read_env_vars(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_read_env_vars(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } @@ -1639,29 +1641,29 @@ config_read(_PyCoreConfig *config) config->show_alloc_count = 1; } - err = config_read_complex_options(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_read_complex_options(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (config->home == NULL) { - err = config_init_home(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_home(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->executable == NULL) { - err = config_init_executable(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_executable(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->_install_importlib) { - err = _PyCoreConfig_InitPathConfig(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyConfig_InitPathConfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } @@ -1683,29 +1685,30 @@ config_read(_PyCoreConfig *config) } if (config->filesystem_encoding == NULL || config->filesystem_errors == NULL) { - err = config_init_fs_encoding(config, preconfig); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_fs_encoding(config, preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - err = config_init_stdio_encoding(config, preconfig); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_stdio_encoding(config, preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (config->argv.length < 1) { /* Ensure at least one (empty) argument is seen */ - if (_PyWstrList_Append(&config->argv, L"") < 0) { - return _Py_INIT_NO_MEMORY(); + status = PyWideStringList_Append(&config->argv, L""); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->check_hash_pycs_mode == NULL) { - err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode, - L"default"); - if (_Py_INIT_FAILED(err)) { - return err; + status = PyConfig_SetString(config, &config->check_hash_pycs_mode, + L"default"); + if (_PyStatus_EXCEPTION(status)) { + return status; } } @@ -1713,12 +1716,12 @@ config_read(_PyCoreConfig *config) config->configure_c_stdio = 1; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } static void -config_init_stdio(const _PyCoreConfig *config) +config_init_stdio(const PyConfig *config) { #if defined(MS_WINDOWS) || defined(__CYGWIN__) /* don't translate newlines (\r\n <=> \n) */ @@ -1759,23 +1762,23 @@ config_init_stdio(const _PyCoreConfig *config) - set Py_xxx global configuration variables - initialize C standard streams (stdin, stdout, stderr) */ void -_PyCoreConfig_Write(const _PyCoreConfig *config, _PyRuntimeState *runtime) +_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime) { - _PyCoreConfig_SetGlobalConfig(config); + config_set_global_vars(config); if (config->configure_c_stdio) { config_init_stdio(config); } /* Write the new pre-configuration into _PyRuntime */ - _PyPreConfig *preconfig = &runtime->preconfig; + PyPreConfig *preconfig = &runtime->preconfig; preconfig->isolated = config->isolated; preconfig->use_environment = config->use_environment; preconfig->dev_mode = config->dev_mode; } -/* --- _PyCoreConfig command line parser -------------------------- */ +/* --- PyConfig command line parser -------------------------- */ static void config_usage(int error, const wchar_t* program) @@ -1797,12 +1800,12 @@ config_usage(int error, const wchar_t* program) /* Parse the command line arguments */ -static _PyInitError -config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, +static PyStatus +config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions, Py_ssize_t *opt_index) { - _PyInitError err; - const _PyWstrList *argv = &config->argv; + PyStatus status; + const PyWideStringList *argv = &config->argv; int print_version = 0; const wchar_t* program = config->program_name; @@ -1822,7 +1825,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, size_t len = wcslen(_PyOS_optarg) + 1 + 1; wchar_t *command = PyMem_RawMalloc(sizeof(wchar_t) * len); if (command == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } memcpy(command, _PyOS_optarg, (len - 2) * sizeof(wchar_t)); command[len - 2] = '\n'; @@ -1839,7 +1842,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, if (config->run_module == NULL) { config->run_module = _PyMem_RawWcsdup(_PyOS_optarg); if (config->run_module == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } } break; @@ -1853,16 +1856,16 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, || wcscmp(_PyOS_optarg, L"never") == 0 || wcscmp(_PyOS_optarg, L"default") == 0) { - err = _PyCoreConfig_SetString(config, &config->check_hash_pycs_mode, - _PyOS_optarg); - if (_Py_INIT_FAILED(err)) { - return err; + status = PyConfig_SetString(config, &config->check_hash_pycs_mode, + _PyOS_optarg); + if (_PyStatus_EXCEPTION(status)) { + return status; } } else { fprintf(stderr, "--check-hash-based-pycs must be one of " "'default', 'always', or 'never'\n"); config_usage(1, program); - return _Py_INIT_EXIT(2); + return _PyStatus_EXIT(2); } break; @@ -1922,15 +1925,16 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, case 'h': case '?': config_usage(0, program); - return _Py_INIT_EXIT(0); + return _PyStatus_EXIT(0); case 'V': print_version++; break; case 'W': - if (_PyWstrList_Append(warnoptions, _PyOS_optarg) < 0) { - return _Py_INIT_NO_MEMORY(); + status = PyWideStringList_Append(warnoptions, _PyOS_optarg); + if (_PyStatus_EXCEPTION(status)) { + return status; } break; @@ -1947,14 +1951,14 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, default: /* unknown argument: parsing failed */ config_usage(1, program); - return _Py_INIT_EXIT(2); + return _PyStatus_EXIT(2); } } while (1); if (print_version) { printf("Python %s\n", (print_version >= 2) ? Py_GetVersion() : PY_VERSION); - return _Py_INIT_EXIT(0); + return _PyStatus_EXIT(0); } if (config->run_command == NULL && config->run_module == NULL @@ -1964,7 +1968,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, { config->run_filename = _PyMem_RawWcsdup(argv->items[_PyOS_optind]); if (config->run_filename == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } } @@ -1975,7 +1979,7 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, *opt_index = _PyOS_optind; - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -1986,21 +1990,21 @@ config_parse_cmdline(_PyCoreConfig *config, _PyWstrList *warnoptions, #endif /* Get warning options from PYTHONWARNINGS environment variable. */ -static _PyInitError -config_init_env_warnoptions(_PyCoreConfig *config, _PyWstrList *warnoptions) +static PyStatus +config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions) { - _PyInitError err; + PyStatus status; /* CONFIG_GET_ENV_DUP requires dest to be initialized to NULL */ wchar_t *env = NULL; - err = CONFIG_GET_ENV_DUP(config, &env, + status = CONFIG_GET_ENV_DUP(config, &env, L"PYTHONWARNINGS", "PYTHONWARNINGS"); - if (_Py_INIT_FAILED(err)) { - return err; + if (_PyStatus_EXCEPTION(status)) { + return status; } /* env var is not set or is empty */ if (env == NULL) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -2009,35 +2013,35 @@ config_init_env_warnoptions(_PyCoreConfig *config, _PyWstrList *warnoptions) warning != NULL; warning = WCSTOK(NULL, L",", &context)) { - if (_PyWstrList_Append(warnoptions, warning) < 0) { + status = PyWideStringList_Append(warnoptions, warning); + if (_PyStatus_EXCEPTION(status)) { PyMem_RawFree(env); - return _Py_INIT_NO_MEMORY(); + return status; } } PyMem_RawFree(env); - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static int -config_add_warnoption(_PyCoreConfig *config, const wchar_t *option) +static PyStatus +config_add_warnoption(PyConfig *config, const wchar_t *option) { - if (_PyWstrList_Find(&config->warnoptions, option)) { + if (_PyWideStringList_Find(&config->warnoptions, option)) { /* Already present: do nothing */ - return 0; - } - if (_PyWstrList_Append(&config->warnoptions, option)) { - return -1; + return _PyStatus_OK(); } - return 0; + return PyWideStringList_Append(&config->warnoptions, option); } -static _PyInitError -config_init_warnoptions(_PyCoreConfig *config, - const _PyWstrList *cmdline_warnoptions, - const _PyWstrList *env_warnoptions) +static PyStatus +config_init_warnoptions(PyConfig *config, + const PyWideStringList *cmdline_warnoptions, + const PyWideStringList *env_warnoptions) { + PyStatus status; + /* The priority order for warnings configuration is (highest precedence * first): * @@ -2054,25 +2058,28 @@ config_init_warnoptions(_PyCoreConfig *config, */ if (config->dev_mode) { - if (config_add_warnoption(config, L"default") < 0) { - return _Py_INIT_NO_MEMORY(); + status = config_add_warnoption(config, L"default"); + if (_PyStatus_EXCEPTION(status)) { + return status; } } Py_ssize_t i; - const _PyWstrList *options; + const PyWideStringList *options; options = env_warnoptions; for (i = 0; i < options->length; i++) { - if (config_add_warnoption(config, options->items[i]) < 0) { - return _Py_INIT_NO_MEMORY(); + status = config_add_warnoption(config, options->items[i]); + if (_PyStatus_EXCEPTION(status)) { + return status; } } options = cmdline_warnoptions; for (i = 0; i < options->length; i++) { - if (config_add_warnoption(config, options->items[i]) < 0) { - return _Py_INIT_NO_MEMORY(); + status = config_add_warnoption(config, options->items[i]); + if (_PyStatus_EXCEPTION(status)) { + return status; } } @@ -2088,33 +2095,35 @@ config_init_warnoptions(_PyCoreConfig *config, else { filter = L"default::BytesWarning"; } - if (config_add_warnoption(config, filter) < 0) { - return _Py_INIT_NO_MEMORY(); + status = config_add_warnoption(config, filter); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -config_update_argv(_PyCoreConfig *config, Py_ssize_t opt_index) +static PyStatus +config_update_argv(PyConfig *config, Py_ssize_t opt_index) { - const _PyWstrList *cmdline_argv = &config->argv; - _PyWstrList config_argv = _PyWstrList_INIT; + const PyWideStringList *cmdline_argv = &config->argv; + PyWideStringList config_argv = PyWideStringList_INIT; /* Copy argv to be able to modify it (to force -c/-m) */ if (cmdline_argv->length <= opt_index) { /* Ensure at least one (empty) argument is seen */ - if (_PyWstrList_Append(&config_argv, L"") < 0) { - return _Py_INIT_NO_MEMORY(); + PyStatus status = PyWideStringList_Append(&config_argv, L""); + if (_PyStatus_EXCEPTION(status)) { + return status; } } else { - _PyWstrList slice; + PyWideStringList slice; slice.length = cmdline_argv->length - opt_index; slice.items = &cmdline_argv->items[opt_index]; - if (_PyWstrList_Copy(&config_argv, &slice) < 0) { - return _Py_INIT_NO_MEMORY(); + if (_PyWideStringList_Copy(&config_argv, &slice) < 0) { + return _PyStatus_NO_MEMORY(); } } assert(config_argv.length >= 1); @@ -2131,109 +2140,108 @@ config_update_argv(_PyCoreConfig *config, Py_ssize_t opt_index) if (arg0 != NULL) { arg0 = _PyMem_RawWcsdup(arg0); if (arg0 == NULL) { - _PyWstrList_Clear(&config_argv); - return _Py_INIT_NO_MEMORY(); + _PyWideStringList_Clear(&config_argv); + return _PyStatus_NO_MEMORY(); } PyMem_RawFree(config_argv.items[0]); config_argv.items[0] = arg0; } - _PyWstrList_Clear(&config->argv); + _PyWideStringList_Clear(&config->argv); config->argv = config_argv; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline) +static PyStatus +core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline) { - _PyInitError err; + PyStatus status; if (config->parse_argv) { - if (_PyWstrList_Copy(&precmdline->argv, &config->argv) < 0) { - return _Py_INIT_NO_MEMORY(); + if (_PyWideStringList_Copy(&precmdline->argv, &config->argv) < 0) { + return _PyStatus_NO_MEMORY(); } } - _PyPreConfig preconfig; + PyPreConfig preconfig; _PyPreConfig_InitFromPreConfig(&preconfig, &_PyRuntime.preconfig); - _PyPreConfig_GetCoreConfig(&preconfig, config); + _PyPreConfig_GetConfig(&preconfig, config); - err = _PyPreCmdline_Read(precmdline, &preconfig); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyPreCmdline_Read(precmdline, &preconfig); + if (_PyStatus_EXCEPTION(status)) { + return status; } - if (_PyPreCmdline_SetCoreConfig(precmdline, config) < 0) { - err = _Py_INIT_NO_MEMORY(); - return err; + status = _PyPreCmdline_SetConfig(precmdline, config); + if (_PyStatus_EXCEPTION(status)) { + return status; } - - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -config_read_cmdline(_PyCoreConfig *config) +static PyStatus +config_read_cmdline(PyConfig *config) { - _PyInitError err; - _PyWstrList cmdline_warnoptions = _PyWstrList_INIT; - _PyWstrList env_warnoptions = _PyWstrList_INIT; + PyStatus status; + PyWideStringList cmdline_warnoptions = PyWideStringList_INIT; + PyWideStringList env_warnoptions = PyWideStringList_INIT; if (config->parse_argv < 0) { config->parse_argv = 1; } if (config->program_name == NULL) { - err = config_init_program_name(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = config_init_program_name(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->parse_argv) { Py_ssize_t opt_index; - err = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index); - if (_Py_INIT_FAILED(err)) { + status = config_parse_cmdline(config, &cmdline_warnoptions, &opt_index); + if (_PyStatus_EXCEPTION(status)) { goto done; } - err = config_update_argv(config, opt_index); - if (_Py_INIT_FAILED(err)) { + status = config_update_argv(config, opt_index); + if (_PyStatus_EXCEPTION(status)) { goto done; } } if (config->use_environment) { - err = config_init_env_warnoptions(config, &env_warnoptions); - if (_Py_INIT_FAILED(err)) { + status = config_init_env_warnoptions(config, &env_warnoptions); + if (_PyStatus_EXCEPTION(status)) { goto done; } } - err = config_init_warnoptions(config, + status = config_init_warnoptions(config, &cmdline_warnoptions, &env_warnoptions); - if (_Py_INIT_FAILED(err)) { + if (_PyStatus_EXCEPTION(status)) { goto done; } - err = _Py_INIT_OK(); + status = _PyStatus_OK(); done: - _PyWstrList_Clear(&cmdline_warnoptions); - _PyWstrList_Clear(&env_warnoptions); - return err; + _PyWideStringList_Clear(&cmdline_warnoptions); + _PyWideStringList_Clear(&env_warnoptions); + return status; } -_PyInitError -_PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args) +PyStatus +_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args) { - _PyInitError err = _Py_PreInitializeFromCoreConfig(config, args); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _Py_PreInitializeFromConfig(config, args); + if (_PyStatus_EXCEPTION(status)) { + return status; } return _PyArgv_AsWstrList(args, &config->argv); @@ -2242,57 +2250,57 @@ _PyCoreConfig_SetPyArgv(_PyCoreConfig *config, const _PyArgv *args) /* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python if needed to ensure that encodings are properly configured. */ -_PyInitError -_PyCoreConfig_SetArgv(_PyCoreConfig *config, Py_ssize_t argc, char * const *argv) +PyStatus +PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv) { _PyArgv args = { .argc = argc, .use_bytes_argv = 1, .bytes_argv = argv, .wchar_argv = NULL}; - return _PyCoreConfig_SetPyArgv(config, &args); + return _PyConfig_SetPyArgv(config, &args); } -_PyInitError -_PyCoreConfig_SetWideArgv(_PyCoreConfig *config, Py_ssize_t argc, wchar_t * const *argv) +PyStatus +PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv) { _PyArgv args = { .argc = argc, .use_bytes_argv = 0, .bytes_argv = NULL, .wchar_argv = argv}; - return _PyCoreConfig_SetPyArgv(config, &args); + return _PyConfig_SetPyArgv(config, &args); } -/* Read the configuration into _PyCoreConfig from: +/* Read the configuration into PyConfig from: * Command line arguments * Environment variables * Py_xxx global configuration variables The only side effects are to modify config and to call _Py_SetArgcArgv(). */ -_PyInitError -_PyCoreConfig_Read(_PyCoreConfig *config) +PyStatus +PyConfig_Read(PyConfig *config) { - _PyInitError err; - _PyWstrList orig_argv = _PyWstrList_INIT; + PyStatus status; + PyWideStringList orig_argv = PyWideStringList_INIT; - err = _Py_PreInitializeFromCoreConfig(config, NULL); - if (_Py_INIT_FAILED(err)) { - return err; + status = _Py_PreInitializeFromConfig(config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; } - _PyCoreConfig_GetGlobalConfig(config); + config_get_global_vars(config); - if (_PyWstrList_Copy(&orig_argv, &config->argv) < 0) { - return _Py_INIT_NO_MEMORY(); + if (_PyWideStringList_Copy(&orig_argv, &config->argv) < 0) { + return _PyStatus_NO_MEMORY(); } _PyPreCmdline precmdline = _PyPreCmdline_INIT; - err = core_read_precmdline(config, &precmdline); - if (_Py_INIT_FAILED(err)) { + status = core_read_precmdline(config, &precmdline); + if (_PyStatus_EXCEPTION(status)) { goto done; } @@ -2302,18 +2310,18 @@ _PyCoreConfig_Read(_PyCoreConfig *config) config->user_site_directory = 0; } - err = config_read_cmdline(config); - if (_Py_INIT_FAILED(err)) { + status = config_read_cmdline(config); + if (_PyStatus_EXCEPTION(status)) { goto done; } - err = config_read(config); - if (_Py_INIT_FAILED(err)) { + status = config_read(config); + if (_PyStatus_EXCEPTION(status)) { goto done; } if (_Py_SetArgcArgv(orig_argv.length, orig_argv.items) < 0) { - err = _Py_INIT_NO_MEMORY(); + status = _PyStatus_NO_MEMORY(); goto done; } @@ -2339,14 +2347,14 @@ _PyCoreConfig_Read(_PyCoreConfig *config) assert(config->configure_c_stdio >= 0); assert(config->buffered_stdio >= 0); assert(config->program_name != NULL); - assert(_PyWstrList_CheckConsistency(&config->argv)); + assert(_PyWideStringList_CheckConsistency(&config->argv)); /* sys.argv must be non-empty: empty argv is replaced with [''] */ assert(config->argv.length >= 1); - assert(_PyWstrList_CheckConsistency(&config->xoptions)); - assert(_PyWstrList_CheckConsistency(&config->warnoptions)); - assert(_PyWstrList_CheckConsistency(&config->module_search_paths)); + assert(_PyWideStringList_CheckConsistency(&config->xoptions)); + assert(_PyWideStringList_CheckConsistency(&config->warnoptions)); + assert(_PyWideStringList_CheckConsistency(&config->module_search_paths)); if (config->_install_importlib) { - assert(config->use_module_search_paths != 0); + assert(config->module_search_paths_set != 0); /* don't check config->module_search_paths */ assert(config->executable != NULL); assert(config->prefix != NULL); @@ -2367,63 +2375,63 @@ _PyCoreConfig_Read(_PyCoreConfig *config) assert(config->_install_importlib >= 0); assert(config->pathconfig_warnings >= 0); - err = _Py_INIT_OK(); + status = _PyStatus_OK(); done: - _PyWstrList_Clear(&orig_argv); + _PyWideStringList_Clear(&orig_argv); _PyPreCmdline_Clear(&precmdline); - return err; + return status; } PyObject* _Py_GetConfigsAsDict(void) { - PyObject *config = NULL; + PyObject *result = NULL; PyObject *dict = NULL; - config = PyDict_New(); - if (config == NULL) { + result = PyDict_New(); + if (result == NULL) { goto error; } - /* global config */ + /* global result */ dict = _Py_GetGlobalVariablesAsDict(); if (dict == NULL) { goto error; } - if (PyDict_SetItemString(config, "global_config", dict) < 0) { + if (PyDict_SetItemString(result, "global_config", dict) < 0) { goto error; } Py_CLEAR(dict); /* pre config */ PyInterpreterState *interp = _PyInterpreterState_Get(); - const _PyPreConfig *pre_config = &_PyRuntime.preconfig; + const PyPreConfig *pre_config = &_PyRuntime.preconfig; dict = _PyPreConfig_AsDict(pre_config); if (dict == NULL) { goto error; } - if (PyDict_SetItemString(config, "pre_config", dict) < 0) { + if (PyDict_SetItemString(result, "pre_config", dict) < 0) { goto error; } Py_CLEAR(dict); /* core config */ - const _PyCoreConfig *core_config = _PyInterpreterState_GetCoreConfig(interp); - dict = _PyCoreConfig_AsDict(core_config); + const PyConfig *config = &interp->config; + dict = config_as_dict(config); if (dict == NULL) { goto error; } - if (PyDict_SetItemString(config, "core_config", dict) < 0) { + if (PyDict_SetItemString(result, "config", dict) < 0) { goto error; } Py_CLEAR(dict); - return config; + return result; error: - Py_XDECREF(config); + Py_XDECREF(result); Py_XDECREF(dict); return NULL; } diff --git a/Python/pathconfig.c b/Python/pathconfig.c index bbf29b2fa59819..ec67405a28d054 100644 --- a/Python/pathconfig.c +++ b/Python/pathconfig.c @@ -2,7 +2,7 @@ #include "Python.h" #include "osdefs.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_fileutils.h" #include "pycore_pathconfig.h" #include "pycore_pymem.h" @@ -34,7 +34,7 @@ copy_wstr(wchar_t **dst, const wchar_t *src) static void -_PyPathConfig_Clear(_PyPathConfig *config) +pathconfig_clear(_PyPathConfig *config) { /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator, since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be @@ -63,12 +63,11 @@ _PyPathConfig_Clear(_PyPathConfig *config) } -/* Calculate the path configuration: initialize path_config from core_config */ -static _PyInitError -_PyPathConfig_Calculate(_PyPathConfig *path_config, - const _PyCoreConfig *core_config) +/* Calculate the path configuration: initialize pathconfig from config */ +static PyStatus +pathconfig_calculate(_PyPathConfig *pathconfig, const PyConfig *config) { - _PyInitError err; + PyStatus status; _PyPathConfig new_config = _PyPathConfig_INIT; PyMemAllocatorEx old_alloc; @@ -76,40 +75,40 @@ _PyPathConfig_Calculate(_PyPathConfig *path_config, /* Calculate program_full_path, prefix, exec_prefix, dll_path (Windows), and module_search_path */ - err = _PyPathConfig_Calculate_impl(&new_config, core_config); - if (_Py_INIT_FAILED(err)) { - goto err; + status = _PyPathConfig_Calculate(&new_config, config); + if (_PyStatus_EXCEPTION(status)) { + goto error; } - /* Copy home and program_name from core_config */ - if (copy_wstr(&new_config.home, core_config->home) < 0) { - err = _Py_INIT_NO_MEMORY(); - goto err; + /* Copy home and program_name from config */ + if (copy_wstr(&new_config.home, config->home) < 0) { + status = _PyStatus_NO_MEMORY(); + goto error; } - if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) { - err = _Py_INIT_NO_MEMORY(); - goto err; + if (copy_wstr(&new_config.program_name, config->program_name) < 0) { + status = _PyStatus_NO_MEMORY(); + goto error; } - _PyPathConfig_Clear(path_config); - *path_config = new_config; + pathconfig_clear(pathconfig); + *pathconfig = new_config; - err = _Py_INIT_OK(); + status = _PyStatus_OK(); goto done; -err: - _PyPathConfig_Clear(&new_config); +error: + pathconfig_clear(&new_config); done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return err; + return status; } -_PyInitError +PyStatus _PyPathConfig_SetGlobal(const _PyPathConfig *config) { - _PyInitError err; + PyStatus status; _PyPathConfig new_config = _PyPathConfig_INIT; PyMemAllocatorEx old_alloc; @@ -118,8 +117,8 @@ _PyPathConfig_SetGlobal(const _PyPathConfig *config) #define COPY_ATTR(ATTR) \ do { \ if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \ - _PyPathConfig_Clear(&new_config); \ - err = _Py_INIT_NO_MEMORY(); \ + pathconfig_clear(&new_config); \ + status = _PyStatus_NO_MEMORY(); \ goto done; \ } \ } while (0) @@ -134,15 +133,15 @@ _PyPathConfig_SetGlobal(const _PyPathConfig *config) COPY_ATTR(program_name); COPY_ATTR(home); - _PyPathConfig_Clear(&_Py_path_config); + pathconfig_clear(&_Py_path_config); /* Steal new_config strings; don't clear new_config */ _Py_path_config = new_config; - err = _Py_INIT_OK(); + status = _PyStatus_OK(); done: PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return err; + return status; } @@ -152,14 +151,14 @@ _PyPathConfig_ClearGlobal(void) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyPathConfig_Clear(&_Py_path_config); + pathconfig_clear(&_Py_path_config); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } static wchar_t* -_PyWstrList_Join(const _PyWstrList *list, wchar_t sep) +_PyWideStringList_Join(const PyWideStringList *list, wchar_t sep) { size_t len = 1; /* NUL terminator */ for (Py_ssize_t i=0; i < list->length; i++) { @@ -189,70 +188,69 @@ _PyWstrList_Join(const _PyWstrList *list, wchar_t sep) } -/* Set the global path configuration from core_config. */ -_PyInitError -_PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config) +/* Set the global path configuration from config. */ +PyStatus +_PyConfig_SetPathConfig(const PyConfig *config) { PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyInitError err; - _PyPathConfig path_config = _PyPathConfig_INIT; + PyStatus status; + _PyPathConfig pathconfig = _PyPathConfig_INIT; - path_config.module_search_path = _PyWstrList_Join(&core_config->module_search_paths, DELIM); - if (path_config.module_search_path == NULL) { + pathconfig.module_search_path = _PyWideStringList_Join(&config->module_search_paths, DELIM); + if (pathconfig.module_search_path == NULL) { goto no_memory; } - if (copy_wstr(&path_config.program_full_path, core_config->executable) < 0) { + if (copy_wstr(&pathconfig.program_full_path, config->executable) < 0) { goto no_memory; } - if (copy_wstr(&path_config.prefix, core_config->prefix) < 0) { + if (copy_wstr(&pathconfig.prefix, config->prefix) < 0) { goto no_memory; } - if (copy_wstr(&path_config.exec_prefix, core_config->exec_prefix) < 0) { + if (copy_wstr(&pathconfig.exec_prefix, config->exec_prefix) < 0) { goto no_memory; } #ifdef MS_WINDOWS - path_config.dll_path = _Py_GetDLLPath(); - if (path_config.dll_path == NULL) { + pathconfig.dll_path = _Py_GetDLLPath(); + if (pathconfig.dll_path == NULL) { goto no_memory; } #endif - if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) { + if (copy_wstr(&pathconfig.program_name, config->program_name) < 0) { goto no_memory; } - if (copy_wstr(&path_config.home, core_config->home) < 0) { + if (copy_wstr(&pathconfig.home, config->home) < 0) { goto no_memory; } - err = _PyPathConfig_SetGlobal(&path_config); - if (_Py_INIT_FAILED(err)) { + status = _PyPathConfig_SetGlobal(&pathconfig); + if (_PyStatus_EXCEPTION(status)) { goto done; } - err = _Py_INIT_OK(); + status = _PyStatus_OK(); goto done; no_memory: - err = _Py_INIT_NO_MEMORY(); + status = _PyStatus_NO_MEMORY(); done: - _PyPathConfig_Clear(&path_config); + pathconfig_clear(&pathconfig); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return err; + return status; } -static _PyInitError -core_config_init_module_search_paths(_PyCoreConfig *config, - _PyPathConfig *path_config) +static PyStatus +config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig) { - assert(!config->use_module_search_paths); + assert(!config->module_search_paths_set); - _PyWstrList_Clear(&config->module_search_paths); + _PyWideStringList_Clear(&config->module_search_paths); - const wchar_t *sys_path = path_config->module_search_path; + const wchar_t *sys_path = pathconfig->module_search_path; const wchar_t delim = DELIM; const wchar_t *p = sys_path; while (1) { @@ -264,15 +262,15 @@ core_config_init_module_search_paths(_PyCoreConfig *config, size_t path_len = (p - sys_path); wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t)); if (path == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } memcpy(path, sys_path, path_len * sizeof(wchar_t)); path[path_len] = L'\0'; - int res = _PyWstrList_Append(&config->module_search_paths, path); + PyStatus status = PyWideStringList_Append(&config->module_search_paths, path); PyMem_RawFree(path); - if (res < 0) { - return _Py_INIT_NO_MEMORY(); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (*p == '\0') { @@ -280,96 +278,96 @@ core_config_init_module_search_paths(_PyCoreConfig *config, } sys_path = p + 1; } - config->use_module_search_paths = 1; - return _Py_INIT_OK(); + config->module_search_paths_set = 1; + return _PyStatus_OK(); } -static _PyInitError -_PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config) +static PyStatus +config_calculate_pathconfig(PyConfig *config) { - _PyPathConfig path_config = _PyPathConfig_INIT; - _PyInitError err; + _PyPathConfig pathconfig = _PyPathConfig_INIT; + PyStatus status; - err = _PyPathConfig_Calculate(&path_config, config); - if (_Py_INIT_FAILED(err)) { + status = pathconfig_calculate(&pathconfig, config); + if (_PyStatus_EXCEPTION(status)) { goto error; } - if (!config->use_module_search_paths) { - err = core_config_init_module_search_paths(config, &path_config); - if (_Py_INIT_FAILED(err)) { + if (!config->module_search_paths_set) { + status = config_init_module_search_paths(config, &pathconfig); + if (_PyStatus_EXCEPTION(status)) { goto error; } } if (config->executable == NULL) { if (copy_wstr(&config->executable, - path_config.program_full_path) < 0) { + pathconfig.program_full_path) < 0) { goto no_memory; } } if (config->prefix == NULL) { - if (copy_wstr(&config->prefix, path_config.prefix) < 0) { + if (copy_wstr(&config->prefix, pathconfig.prefix) < 0) { goto no_memory; } } if (config->exec_prefix == NULL) { if (copy_wstr(&config->exec_prefix, - path_config.exec_prefix) < 0) { + pathconfig.exec_prefix) < 0) { goto no_memory; } } - if (path_config.isolated != -1) { - config->isolated = path_config.isolated; + if (pathconfig.isolated != -1) { + config->isolated = pathconfig.isolated; } - if (path_config.site_import != -1) { - config->site_import = path_config.site_import; + if (pathconfig.site_import != -1) { + config->site_import = pathconfig.site_import; } - _PyPathConfig_Clear(&path_config); - return _Py_INIT_OK(); + pathconfig_clear(&pathconfig); + return _PyStatus_OK(); no_memory: - err = _Py_INIT_NO_MEMORY(); + status = _PyStatus_NO_MEMORY(); error: - _PyPathConfig_Clear(&path_config); - return err; + pathconfig_clear(&pathconfig); + return status; } -_PyInitError -_PyCoreConfig_InitPathConfig(_PyCoreConfig *config) +PyStatus +_PyConfig_InitPathConfig(PyConfig *config) { /* Do we need to calculate the path? */ - if (!config->use_module_search_paths + if (!config->module_search_paths_set || (config->executable == NULL) || (config->prefix == NULL) || (config->exec_prefix == NULL)) { - _PyInitError err = _PyCoreConfig_CalculatePathConfig(config); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = config_calculate_pathconfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } if (config->base_prefix == NULL) { if (copy_wstr(&config->base_prefix, config->prefix) < 0) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } } if (config->base_exec_prefix == NULL) { if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -381,26 +379,26 @@ pathconfig_global_init(void) return; } - _PyInitError err; - _PyCoreConfig config; - _PyCoreConfig_InitCompatConfig(&config); + PyStatus status; + PyConfig config; + _PyConfig_InitCompatConfig(&config); - err = _PyCoreConfig_Read(&config); - if (_Py_INIT_FAILED(err)) { + status = PyConfig_Read(&config); + if (_PyStatus_EXCEPTION(status)) { goto error; } - err = _PyCoreConfig_SetPathConfig(&config); - if (_Py_INIT_FAILED(err)) { + status = _PyConfig_SetPathConfig(&config); + if (_PyStatus_EXCEPTION(status)) { goto error; } - _PyCoreConfig_Clear(&config); + PyConfig_Clear(&config); return; error: - _PyCoreConfig_Clear(&config); - _Py_ExitInitError(err); + PyConfig_Clear(&config); + Py_ExitStatusException(status); } @@ -410,7 +408,7 @@ void Py_SetPath(const wchar_t *path) { if (path == NULL) { - _PyPathConfig_Clear(&_Py_path_config); + pathconfig_clear(&_Py_path_config); return; } @@ -437,7 +435,7 @@ Py_SetPath(const wchar_t *path) new_config.program_name = _Py_path_config.program_name; _Py_path_config.program_name = NULL; - _PyPathConfig_Clear(&_Py_path_config); + pathconfig_clear(&_Py_path_config); _Py_path_config = new_config; PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -569,9 +567,9 @@ Py_GetProgramName(void) Raise an exception and return -1 on error. */ int -_PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p) +_PyPathConfig_ComputeSysPath0(const PyWideStringList *argv, PyObject **path0_p) { - assert(_PyWstrList_CheckConsistency(argv)); + assert(_PyWideStringList_CheckConsistency(argv)); if (argv->length == 0) { /* Leave sys.path unchanged if sys.argv is empty */ diff --git a/Python/preconfig.c b/Python/preconfig.c index a6d1346eb4e1f7..8be6533eace073 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -1,5 +1,5 @@ #include "Python.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_getopt.h" #include "pycore_pystate.h" /* _PyRuntime_Initialize() */ #include /* setlocale() */ @@ -7,8 +7,13 @@ #define DECODE_LOCALE_ERR(NAME, LEN) \ (((LEN) == -2) \ - ? _Py_INIT_ERR("cannot decode " NAME) \ - : _Py_INIT_NO_MEMORY()) + ? _PyStatus_ERR("cannot decode " NAME) \ + : _PyStatus_NO_MEMORY()) + + +/* Forward declarations */ +static void +preconfig_copy(PyPreConfig *config, const PyPreConfig *config2); /* --- File system encoding/errors -------------------------------- */ @@ -67,22 +72,22 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors) /* --- _PyArgv ---------------------------------------------------- */ /* Decode bytes_argv using Py_DecodeLocale() */ -_PyInitError -_PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list) +PyStatus +_PyArgv_AsWstrList(const _PyArgv *args, PyWideStringList *list) { - _PyWstrList wargv = _PyWstrList_INIT; + PyWideStringList wargv = PyWideStringList_INIT; if (args->use_bytes_argv) { size_t size = sizeof(wchar_t*) * args->argc; wargv.items = (wchar_t **)PyMem_RawMalloc(size); if (wargv.items == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } for (Py_ssize_t i = 0; i < args->argc; i++) { size_t len; wchar_t *arg = Py_DecodeLocale(args->bytes_argv[i], &len); if (arg == NULL) { - _PyWstrList_Clear(&wargv); + _PyWideStringList_Clear(&wargv); return DECODE_LOCALE_ERR("command line arguments", (Py_ssize_t)len); } @@ -90,17 +95,17 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list) wargv.length++; } - _PyWstrList_Clear(list); + _PyWideStringList_Clear(list); *list = wargv; } else { wargv.length = args->argc; wargv.items = (wchar_t **)args->wchar_argv; - if (_PyWstrList_Copy(list, &wargv) < 0) { - return _Py_INIT_NO_MEMORY(); + if (_PyWideStringList_Copy(list, &wargv) < 0) { + return _PyStatus_NO_MEMORY(); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -109,12 +114,12 @@ _PyArgv_AsWstrList(const _PyArgv *args, _PyWstrList *list) void _PyPreCmdline_Clear(_PyPreCmdline *cmdline) { - _PyWstrList_Clear(&cmdline->argv); - _PyWstrList_Clear(&cmdline->xoptions); + _PyWideStringList_Clear(&cmdline->argv); + _PyWideStringList_Clear(&cmdline->xoptions); } -_PyInitError +PyStatus _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) { return _PyArgv_AsWstrList(args, &cmdline->argv); @@ -122,7 +127,7 @@ _PyPreCmdline_SetArgv(_PyPreCmdline *cmdline, const _PyArgv *args) static void -_PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config) +precmdline_get_preconfig(_PyPreCmdline *cmdline, const PyPreConfig *config) { #define COPY_ATTR(ATTR) \ if (config->ATTR != -1) { \ @@ -138,7 +143,7 @@ _PyPreCmdline_GetPreConfig(_PyPreCmdline *cmdline, const _PyPreConfig *config) static void -_PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config) +precmdline_set_preconfig(const _PyPreCmdline *cmdline, PyPreConfig *config) { #define COPY_ATTR(ATTR) \ config->ATTR = cmdline->ATTR @@ -151,33 +156,34 @@ _PyPreCmdline_SetPreConfig(const _PyPreCmdline *cmdline, _PyPreConfig *config) } -int -_PyPreCmdline_SetCoreConfig(const _PyPreCmdline *cmdline, _PyCoreConfig *config) +PyStatus +_PyPreCmdline_SetConfig(const _PyPreCmdline *cmdline, PyConfig *config) { #define COPY_ATTR(ATTR) \ config->ATTR = cmdline->ATTR - if (_PyWstrList_Extend(&config->xoptions, &cmdline->xoptions) < 0) { - return -1; + PyStatus status = _PyWideStringList_Extend(&config->xoptions, &cmdline->xoptions); + if (_PyStatus_EXCEPTION(status)) { + return status; } COPY_ATTR(isolated); COPY_ATTR(use_environment); COPY_ATTR(dev_mode); - return 0; + return _PyStatus_OK(); #undef COPY_ATTR } /* Parse the command line arguments */ -static _PyInitError +static PyStatus precmdline_parse_cmdline(_PyPreCmdline *cmdline) { - const _PyWstrList *argv = &cmdline->argv; + const PyWideStringList *argv = &cmdline->argv; _PyOS_ResetGetOpt(); - /* Don't log parsing errors into stderr here: _PyCoreConfig_Read() + /* Don't log parsing errors into stderr here: PyConfig_Read() is responsible for that */ _PyOS_opterr = 0; do { @@ -199,32 +205,34 @@ precmdline_parse_cmdline(_PyPreCmdline *cmdline) case 'X': { - if (_PyWstrList_Append(&cmdline->xoptions, _PyOS_optarg) < 0) { - return _Py_INIT_NO_MEMORY(); + PyStatus status = PyWideStringList_Append(&cmdline->xoptions, + _PyOS_optarg); + if (_PyStatus_EXCEPTION(status)) { + return status; } break; } default: /* ignore other argument: - handled by _PyCoreConfig_Read() */ + handled by PyConfig_Read() */ break; } } while (1); - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError -_PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig) +PyStatus +_PyPreCmdline_Read(_PyPreCmdline *cmdline, const PyPreConfig *preconfig) { - _PyPreCmdline_GetPreConfig(cmdline, preconfig); + precmdline_get_preconfig(cmdline, preconfig); if (preconfig->parse_argv) { - _PyInitError err = precmdline_parse_cmdline(cmdline); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = precmdline_parse_cmdline(cmdline); + if (_PyStatus_EXCEPTION(status)) { + return status; } } @@ -254,15 +262,15 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, const _PyPreConfig *preconfig) assert(cmdline->isolated >= 0); assert(cmdline->dev_mode >= 0); - return _Py_INIT_OK(); + return _PyStatus_OK(); } -/* --- _PyPreConfig ----------------------------------------------- */ +/* --- PyPreConfig ----------------------------------------------- */ void -_PyPreConfig_InitCompatConfig(_PyPreConfig *config) +_PyPreConfig_InitCompatConfig(PyPreConfig *config) { memset(config, 0, sizeof(*config)); @@ -291,7 +299,7 @@ _PyPreConfig_InitCompatConfig(_PyPreConfig *config) void -_PyPreConfig_InitPythonConfig(_PyPreConfig *config) +PyPreConfig_InitPythonConfig(PyPreConfig *config) { _PyPreConfig_InitCompatConfig(config); @@ -312,7 +320,7 @@ _PyPreConfig_InitPythonConfig(_PyPreConfig *config) void -_PyPreConfig_InitIsolatedConfig(_PyPreConfig *config) +PyPreConfig_InitIsolatedConfig(PyPreConfig *config) { _PyPreConfig_InitCompatConfig(config); @@ -329,37 +337,37 @@ _PyPreConfig_InitIsolatedConfig(_PyPreConfig *config) void -_PyPreConfig_InitFromPreConfig(_PyPreConfig *config, - const _PyPreConfig *config2) +_PyPreConfig_InitFromPreConfig(PyPreConfig *config, + const PyPreConfig *config2) { - _PyPreConfig_InitCompatConfig(config); - _PyPreConfig_Copy(config, config2); + PyPreConfig_InitPythonConfig(config); + preconfig_copy(config, config2); } void -_PyPreConfig_InitFromCoreConfig(_PyPreConfig *config, - const _PyCoreConfig *coreconfig) +_PyPreConfig_InitFromConfig(PyPreConfig *preconfig, const PyConfig *config) { - _PyConfigInitEnum config_init = (_PyConfigInitEnum)coreconfig->_config_init; + _PyConfigInitEnum config_init = (_PyConfigInitEnum)config->_config_init; switch (config_init) { case _PyConfig_INIT_PYTHON: - _PyPreConfig_InitPythonConfig(config); + PyPreConfig_InitPythonConfig(preconfig); break; case _PyConfig_INIT_ISOLATED: - _PyPreConfig_InitIsolatedConfig(config); + PyPreConfig_InitIsolatedConfig(preconfig); break; case _PyConfig_INIT_COMPAT: default: - _PyPreConfig_InitCompatConfig(config); + _PyPreConfig_InitCompatConfig(preconfig); } - _PyPreConfig_GetCoreConfig(config, coreconfig); + _PyPreConfig_GetConfig(preconfig, config); } -void -_PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) +static void +preconfig_copy(PyPreConfig *config, const PyPreConfig *config2) { + assert(config2->_config_version == _Py_CONFIG_VERSION); #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR COPY_ATTR(_config_init); @@ -381,7 +389,7 @@ _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) PyObject* -_PyPreConfig_AsDict(const _PyPreConfig *config) +_PyPreConfig_AsDict(const PyPreConfig *config) { PyObject *dict; @@ -427,12 +435,11 @@ _PyPreConfig_AsDict(const _PyPreConfig *config) void -_PyPreConfig_GetCoreConfig(_PyPreConfig *config, - const _PyCoreConfig *core_config) +_PyPreConfig_GetConfig(PyPreConfig *preconfig, const PyConfig *config) { #define COPY_ATTR(ATTR) \ - if (core_config->ATTR != -1) { \ - config->ATTR = core_config->ATTR; \ + if (config->ATTR != -1) { \ + preconfig->ATTR = config->ATTR; \ } COPY_ATTR(parse_argv); @@ -445,7 +452,7 @@ _PyPreConfig_GetCoreConfig(_PyPreConfig *config, static void -_PyPreConfig_GetGlobalConfig(_PyPreConfig *config) +preconfig_get_global_vars(PyPreConfig *config) { if (config->_config_init != _PyConfig_INIT_COMPAT) { /* Python and Isolated configuration ignore global variables */ @@ -476,7 +483,7 @@ _PyPreConfig_GetGlobalConfig(_PyPreConfig *config) static void -_PyPreConfig_SetGlobalConfig(const _PyPreConfig *config) +preconfig_set_global_vars(const PyPreConfig *config) { #define COPY_FLAG(ATTR, VAR) \ if (config->ATTR >= 0) { \ @@ -555,7 +562,7 @@ _Py_get_env_flag(int use_environment, int *flag, const char *name) const wchar_t* -_Py_get_xoption(const _PyWstrList *xoptions, const wchar_t *name) +_Py_get_xoption(const PyWideStringList *xoptions, const wchar_t *name) { for (Py_ssize_t i=0; i < xoptions->length; i++) { const wchar_t *option = xoptions->items[i]; @@ -575,8 +582,8 @@ _Py_get_xoption(const _PyWstrList *xoptions, const wchar_t *name) } -static _PyInitError -preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) +static PyStatus +preconfig_init_utf8_mode(PyPreConfig *config, const _PyPreCmdline *cmdline) { #ifdef MS_WINDOWS if (config->legacy_windows_fs_encoding) { @@ -585,7 +592,7 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) #endif if (config->utf8_mode >= 0) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } const wchar_t *xopt; @@ -601,13 +608,13 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) config->utf8_mode = 0; } else { - return _Py_INIT_ERR("invalid -X utf8 option value"); + return _PyStatus_ERR("invalid -X utf8 option value"); } } else { config->utf8_mode = 1; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } const char *opt = _Py_GetEnv(config->use_environment, "PYTHONUTF8"); @@ -619,10 +626,10 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) config->utf8_mode = 0; } else { - return _Py_INIT_ERR("invalid PYTHONUTF8 environment " + return _PyStatus_ERR("invalid PYTHONUTF8 environment " "variable value"); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -642,12 +649,12 @@ preconfig_init_utf8_mode(_PyPreConfig *config, const _PyPreCmdline *cmdline) if (config->utf8_mode < 0) { config->utf8_mode = 0; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } static void -preconfig_init_coerce_c_locale(_PyPreConfig *config) +preconfig_init_coerce_c_locale(PyPreConfig *config) { if (!config->configure_locale) { config->coerce_c_locale = 0; @@ -693,8 +700,8 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config) } -static _PyInitError -preconfig_init_allocator(_PyPreConfig *config) +static PyStatus +preconfig_init_allocator(PyPreConfig *config) { if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) { /* bpo-34247. The PYTHONMALLOC environment variable has the priority @@ -705,7 +712,7 @@ preconfig_init_allocator(_PyPreConfig *config) if (envvar) { PyMemAllocatorName name; if (_PyMem_GetAllocatorName(envvar, &name) < 0) { - return _Py_INIT_ERR("PYTHONMALLOC: unknown allocator"); + return _PyStatus_ERR("PYTHONMALLOC: unknown allocator"); } config->allocator = (int)name; } @@ -714,21 +721,21 @@ preconfig_init_allocator(_PyPreConfig *config) if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) { config->allocator = PYMEM_ALLOCATOR_DEBUG; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline) +static PyStatus +preconfig_read(PyPreConfig *config, _PyPreCmdline *cmdline) { - _PyInitError err; + PyStatus status; - err = _PyPreCmdline_Read(cmdline, config); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyPreCmdline_Read(cmdline, config); + if (_PyStatus_EXCEPTION(status)) { + return status; } - _PyPreCmdline_SetPreConfig(cmdline, config); + precmdline_set_preconfig(cmdline, config); /* legacy_windows_fs_encoding, coerce_c_locale, utf8_mode */ #ifdef MS_WINDOWS @@ -739,15 +746,15 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline) preconfig_init_coerce_c_locale(config); - err = preconfig_init_utf8_mode(config, cmdline); - if (_Py_INIT_FAILED(err)) { - return err; + status = preconfig_init_utf8_mode(config, cmdline); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* allocator */ - err = preconfig_init_allocator(config); - if (_Py_INIT_FAILED(err)) { - return err; + status = preconfig_init_allocator(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } assert(config->coerce_c_locale >= 0); @@ -760,7 +767,7 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline) assert(config->use_environment >= 0); assert(config->dev_mode >= 0); - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -770,30 +777,30 @@ preconfig_read(_PyPreConfig *config, _PyPreCmdline *cmdline) - environment variables - Py_xxx global configuration variables - the LC_CTYPE locale */ -_PyInitError -_PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) +PyStatus +_PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) { - _PyInitError err; + PyStatus status; - err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; } - _PyPreConfig_GetGlobalConfig(config); + preconfig_get_global_vars(config); /* Copy LC_CTYPE locale, since it's modified later */ const char *loc = setlocale(LC_CTYPE, NULL); if (loc == NULL) { - return _Py_INIT_ERR("failed to LC_CTYPE locale"); + return _PyStatus_ERR("failed to LC_CTYPE locale"); } char *init_ctype_locale = _PyMem_RawStrdup(loc); if (init_ctype_locale == NULL) { - return _Py_INIT_NO_MEMORY(); + return _PyStatus_NO_MEMORY(); } /* Save the config to be able to restore it if encodings change */ - _PyPreConfig save_config; + PyPreConfig save_config; _PyPreConfig_InitFromPreConfig(&save_config, config); /* Set LC_CTYPE to the user preferred locale */ @@ -808,8 +815,8 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) #endif if (args) { - err = _PyPreCmdline_SetArgv(&cmdline, args); - if (_Py_INIT_FAILED(err)) { + status = _PyPreCmdline_SetArgv(&cmdline, args); + if (_PyStatus_EXCEPTION(status)) { goto done; } } @@ -823,7 +830,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) /* Watchdog to prevent an infinite loop */ loops++; if (loops == 3) { - err = _Py_INIT_ERR("Encoding changed twice while " + status = _PyStatus_ERR("Encoding changed twice while " "reading the configuration"); goto done; } @@ -835,8 +842,8 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; #endif - err = preconfig_read(config, &cmdline); - if (_Py_INIT_FAILED(err)) { + status = preconfig_read(config, &cmdline); + if (_PyStatus_EXCEPTION(status)) { goto done; } @@ -877,14 +884,14 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) just keep UTF-8 Mode value. */ int new_utf8_mode = config->utf8_mode; int new_coerce_c_locale = config->coerce_c_locale; - _PyPreConfig_Copy(config, &save_config); + preconfig_copy(config, &save_config); config->utf8_mode = new_utf8_mode; config->coerce_c_locale = new_coerce_c_locale; /* The encoding changed: read again the configuration with the new encoding */ } - err = _Py_INIT_OK(); + status = _PyStatus_OK(); done: if (init_ctype_locale != NULL) { @@ -896,7 +903,7 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; #endif _PyPreCmdline_Clear(&cmdline); - return err; + return status; } @@ -912,26 +919,26 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) Do nothing if called after Py_Initialize(): ignore the new pre-configuration. */ -_PyInitError -_PyPreConfig_Write(const _PyPreConfig *src_config) +PyStatus +_PyPreConfig_Write(const PyPreConfig *src_config) { - _PyPreConfig config; + PyPreConfig config; _PyPreConfig_InitFromPreConfig(&config, src_config); if (_PyRuntime.core_initialized) { /* bpo-34008: Calling this functions after Py_Initialize() ignores the new configuration. */ - return _Py_INIT_OK(); + return _PyStatus_OK(); } PyMemAllocatorName name = (PyMemAllocatorName)config.allocator; if (name != PYMEM_ALLOCATOR_NOT_SET) { if (_PyMem_SetupAllocators(name) < 0) { - return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator"); + return _PyStatus_ERR("Unknown PYTHONMALLOC allocator"); } } - _PyPreConfig_SetGlobalConfig(&config); + preconfig_set_global_vars(&config); if (config.configure_locale) { if (config.coerce_c_locale) { @@ -946,7 +953,7 @@ _PyPreConfig_Write(const _PyPreConfig *src_config) } /* Write the new pre-configuration into _PyRuntime */ - _PyPreConfig_Copy(&_PyRuntime.preconfig, &config); + preconfig_copy(&_PyRuntime.preconfig, &config); - return _Py_INIT_OK(); + return _PyStatus_OK(); } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 9880c0d624d523..10a28813faa8db 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -6,7 +6,7 @@ #undef Yield /* undefine macro conflicting with */ #include "pycore_ceval.h" #include "pycore_context.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_fileutils.h" #include "pycore_hamt.h" #include "pycore_pathconfig.h" @@ -60,10 +60,10 @@ extern "C" { extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward */ -static _PyInitError add_main_module(PyInterpreterState *interp); -static _PyInitError init_import_size(void); -static _PyInitError init_sys_streams(PyInterpreterState *interp); -static _PyInitError init_signals(void); +static PyStatus add_main_module(PyInterpreterState *interp); +static PyStatus init_import_size(void); +static PyStatus init_sys_streams(PyInterpreterState *interp); +static PyStatus init_signals(void); static void call_py_exitfuncs(PyInterpreterState *); static void wait_for_thread_shutdown(void); static void call_ll_exitfuncs(_PyRuntimeState *runtime); @@ -72,7 +72,7 @@ int _Py_UnhandledKeyboardInterrupt = 0; _PyRuntimeState _PyRuntime = _PyRuntimeState_INIT; static int runtime_initialized = 0; -_PyInitError +PyStatus _PyRuntime_Initialize(void) { /* XXX We only initialize once in the process, which aligns with @@ -82,7 +82,7 @@ _PyRuntime_Initialize(void) This is because the runtime state is not properly finalized currently. */ if (runtime_initialized) { - return _Py_INIT_OK(); + return _PyStatus_OK(); } runtime_initialized = 1; @@ -145,58 +145,58 @@ Py_IsInitialized(void) */ -static _PyInitError +static PyStatus init_importlib(PyInterpreterState *interp, PyObject *sysmod) { PyObject *importlib; PyObject *impmod; PyObject *value; - int verbose = interp->core_config.verbose; + int verbose = interp->config.verbose; /* Import _importlib through its frozen version, _frozen_importlib. */ if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { - return _Py_INIT_ERR("can't import _frozen_importlib"); + return _PyStatus_ERR("can't import _frozen_importlib"); } else if (verbose) { PySys_FormatStderr("import _frozen_importlib # frozen\n"); } importlib = PyImport_AddModule("_frozen_importlib"); if (importlib == NULL) { - return _Py_INIT_ERR("couldn't get _frozen_importlib from sys.modules"); + return _PyStatus_ERR("couldn't get _frozen_importlib from sys.modules"); } interp->importlib = importlib; Py_INCREF(interp->importlib); interp->import_func = PyDict_GetItemString(interp->builtins, "__import__"); if (interp->import_func == NULL) - return _Py_INIT_ERR("__import__ not found"); + return _PyStatus_ERR("__import__ not found"); Py_INCREF(interp->import_func); /* Import the _imp module */ impmod = PyInit__imp(); if (impmod == NULL) { - return _Py_INIT_ERR("can't import _imp"); + return _PyStatus_ERR("can't import _imp"); } else if (verbose) { PySys_FormatStderr("import _imp # builtin\n"); } if (_PyImport_SetModuleString("_imp", impmod) < 0) { - return _Py_INIT_ERR("can't save _imp to sys.modules"); + return _PyStatus_ERR("can't save _imp to sys.modules"); } /* Install importlib as the implementation of import */ value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); if (value == NULL) { PyErr_Print(); - return _Py_INIT_ERR("importlib install failed"); + return _PyStatus_ERR("importlib install failed"); } Py_DECREF(value); Py_DECREF(impmod); - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus init_importlib_external(PyInterpreterState *interp) { PyObject *value; @@ -204,7 +204,7 @@ init_importlib_external(PyInterpreterState *interp) "_install_external_importers", ""); if (value == NULL) { PyErr_Print(); - return _Py_INIT_ERR("external importer setup failed"); + return _PyStatus_ERR("external importer setup failed"); } Py_DECREF(value); return _PyImportZip_Init(interp); @@ -265,7 +265,7 @@ static const char *_C_LOCALE_WARNING = static void emit_stderr_warning_for_legacy_locale(_PyRuntimeState *runtime) { - const _PyPreConfig *preconfig = &runtime->preconfig; + const PyPreConfig *preconfig = &runtime->preconfig; if (preconfig->coerce_c_locale_warn && _Py_LegacyLocaleDetected(1)) { PySys_FormatStderr("%s", _C_LOCALE_WARNING); } @@ -437,7 +437,7 @@ _Py_SetLocaleFromEnv(int category) /* Global initializations. Can be undone by Py_Finalize(). Don't call this twice without an intervening Py_Finalize() call. - Every call to _Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx + Every call to Py_InitializeFromConfig, Py_Initialize or Py_InitializeEx must have a corresponding call to Py_Finalize. Locking: you must hold the interpreter lock while calling these APIs. @@ -446,50 +446,50 @@ _Py_SetLocaleFromEnv(int category) */ -static _PyInitError +static PyStatus pyinit_core_reconfigure(_PyRuntimeState *runtime, PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) + const PyConfig *config) { - _PyInitError err; + PyStatus status; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { - return _Py_INIT_ERR("failed to read thread state"); + return _PyStatus_ERR("failed to read thread state"); } PyInterpreterState *interp = tstate->interp; if (interp == NULL) { - return _Py_INIT_ERR("can't make main interpreter"); + return _PyStatus_ERR("can't make main interpreter"); } *interp_p = interp; - _PyCoreConfig_Write(core_config, runtime); + _PyConfig_Write(config, runtime); - err = _PyCoreConfig_Copy(&interp->core_config, core_config); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyConfig_Copy(&interp->config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; } - core_config = &interp->core_config; + config = &interp->config; - if (core_config->_install_importlib) { - err = _PyCoreConfig_SetPathConfig(core_config); - if (_Py_INIT_FAILED(err)) { - return err; + if (config->_install_importlib) { + status = _PyConfig_SetPathConfig(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus pycore_init_runtime(_PyRuntimeState *runtime, - const _PyCoreConfig *core_config) + const PyConfig *config) { if (runtime->initialized) { - return _Py_INIT_ERR("main interpreter already initialized"); + return _PyStatus_ERR("main interpreter already initialized"); } - _PyCoreConfig_Write(core_config, runtime); + _PyConfig_Write(config, runtime); /* Py_Finalize leaves _Py_Finalizing set in order to help daemon * threads behave a little more gracefully at interpreter shutdown. @@ -502,39 +502,39 @@ pycore_init_runtime(_PyRuntimeState *runtime, */ runtime->finalizing = NULL; - _PyInitError err = _Py_HashRandomization_Init(core_config); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _Py_HashRandomization_Init(config); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyInterpreterState_Enable(runtime); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyInterpreterState_Enable(runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus pycore_create_interpreter(_PyRuntimeState *runtime, - const _PyCoreConfig *core_config, + const PyConfig *config, PyInterpreterState **interp_p) { PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { - return _Py_INIT_ERR("can't make main interpreter"); + return _PyStatus_ERR("can't make main interpreter"); } *interp_p = interp; - _PyInitError err = _PyCoreConfig_Copy(&interp->core_config, core_config); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _PyConfig_Copy(&interp->config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; } - core_config = &interp->core_config; + config = &interp->config; PyThreadState *tstate = PyThreadState_New(interp); if (tstate == NULL) - return _Py_INIT_ERR("can't make first thread"); + return _PyStatus_ERR("can't make first thread"); (void) PyThreadState_Swap(tstate); /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because @@ -550,249 +550,249 @@ pycore_create_interpreter(_PyRuntimeState *runtime, /* Create the GIL */ PyEval_InitThreads(); - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus pycore_init_types(void) { - _PyInitError err = _PyTypes_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _PyTypes_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyUnicode_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyUnicode_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (_PyStructSequence_Init() < 0) { - return _Py_INIT_ERR("can't initialize structseq"); + return _PyStatus_ERR("can't initialize structseq"); } if (!_PyLong_Init()) { - return _Py_INIT_ERR("can't init longs"); + return _PyStatus_ERR("can't init longs"); } - err = _PyExc_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyExc_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } if (!_PyFloat_Init()) { - return _Py_INIT_ERR("can't init float"); + return _PyStatus_ERR("can't init float"); } if (!_PyContext_Init()) { - return _Py_INIT_ERR("can't init context"); + return _PyStatus_ERR("can't init context"); } - err = _PyErr_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyErr_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus pycore_init_builtins(PyInterpreterState *interp) { PyObject *bimod = _PyBuiltin_Init(); if (bimod == NULL) { - return _Py_INIT_ERR("can't initialize builtins modules"); + return _PyStatus_ERR("can't initialize builtins modules"); } _PyImport_FixupBuiltin(bimod, "builtins", interp->modules); interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) { - return _Py_INIT_ERR("can't initialize builtins dict"); + return _PyStatus_ERR("can't initialize builtins dict"); } Py_INCREF(interp->builtins); - _PyInitError err = _PyBuiltins_AddExceptions(bimod); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _PyBuiltins_AddExceptions(bimod); + if (_PyStatus_EXCEPTION(status)) { + return status; } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError +static PyStatus pycore_init_import_warnings(PyInterpreterState *interp, PyObject *sysmod) { - _PyInitError err = _PyImport_Init(interp); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _PyImport_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyImportHooks_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyImportHooks_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* Initialize _warnings. */ if (_PyWarnings_Init() == NULL) { - return _Py_INIT_ERR("can't initialize warnings"); + return _PyStatus_ERR("can't initialize warnings"); } - if (interp->core_config._install_importlib) { - err = _PyCoreConfig_SetPathConfig(&interp->core_config); - if (_Py_INIT_FAILED(err)) { - return err; + if (interp->config._install_importlib) { + status = _PyConfig_SetPathConfig(&interp->config); + if (_PyStatus_EXCEPTION(status)) { + return status; } } /* This call sets up builtin and frozen import support */ - if (interp->core_config._install_importlib) { - err = init_importlib(interp, sysmod); - if (_Py_INIT_FAILED(err)) { - return err; + if (interp->config._install_importlib) { + status = init_importlib(interp, sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } -static _PyInitError -pyinit_core_config(_PyRuntimeState *runtime, - PyInterpreterState **interp_p, - const _PyCoreConfig *core_config) +static PyStatus +pyinit_config(_PyRuntimeState *runtime, + PyInterpreterState **interp_p, + const PyConfig *config) { PyInterpreterState *interp; - _PyCoreConfig_Write(core_config, runtime); + _PyConfig_Write(config, runtime); - _PyInitError err = pycore_init_runtime(runtime, core_config); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = pycore_init_runtime(runtime, config); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = pycore_create_interpreter(runtime, core_config, &interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = pycore_create_interpreter(runtime, config, &interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - core_config = &interp->core_config; + config = &interp->config; *interp_p = interp; - err = pycore_init_types(); - if (_Py_INIT_FAILED(err)) { - return err; + status = pycore_init_types(); + if (_PyStatus_EXCEPTION(status)) { + return status; } PyObject *sysmod; - err = _PySys_Create(runtime, interp, &sysmod); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PySys_Create(runtime, interp, &sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = pycore_init_builtins(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = pycore_init_builtins(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = pycore_init_import_warnings(interp, sysmod); - if (_Py_INIT_FAILED(err)) { - return err; + status = pycore_init_import_warnings(interp, sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* Only when we get here is the runtime core fully initialized */ runtime->core_initialized = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError -_Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args) +PyStatus +_Py_PreInitializeFromPyArgv(const PyPreConfig *src_config, const _PyArgv *args) { - _PyInitError err; + PyStatus status; if (src_config == NULL) { - return _Py_INIT_ERR("preinitialization config is NULL"); + return _PyStatus_ERR("preinitialization config is NULL"); } - err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; } _PyRuntimeState *runtime = &_PyRuntime; if (runtime->pre_initialized) { /* If it's already configured: ignored the new configuration */ - return _Py_INIT_OK(); + return _PyStatus_OK(); } - _PyPreConfig config; + PyPreConfig config; _PyPreConfig_InitFromPreConfig(&config, src_config); - err = _PyPreConfig_Read(&config, args); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyPreConfig_Read(&config, args); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyPreConfig_Write(&config); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyPreConfig_Write(&config); + if (_PyStatus_EXCEPTION(status)) { + return status; } runtime->pre_initialized = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError -_Py_PreInitializeFromArgs(const _PyPreConfig *src_config, Py_ssize_t argc, char **argv) +PyStatus +Py_PreInitializeFromBytesArgs(const PyPreConfig *src_config, Py_ssize_t argc, char **argv) { _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; return _Py_PreInitializeFromPyArgv(src_config, &args); } -_PyInitError -_Py_PreInitializeFromWideArgs(const _PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv) +PyStatus +Py_PreInitializeFromArgs(const PyPreConfig *src_config, Py_ssize_t argc, wchar_t **argv) { _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; return _Py_PreInitializeFromPyArgv(src_config, &args); } -_PyInitError -_Py_PreInitialize(const _PyPreConfig *src_config) +PyStatus +Py_PreInitialize(const PyPreConfig *src_config) { return _Py_PreInitializeFromPyArgv(src_config, NULL); } -_PyInitError -_Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig, - const _PyArgv *args) +PyStatus +_Py_PreInitializeFromConfig(const PyConfig *config, + const _PyArgv *args) { - assert(coreconfig != NULL); + assert(config != NULL); - _PyInitError err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; } _PyRuntimeState *runtime = &_PyRuntime; if (runtime->pre_initialized) { /* Already initialized: do nothing */ - return _Py_INIT_OK(); + return _PyStatus_OK(); } - _PyPreConfig preconfig; - _PyPreConfig_InitFromCoreConfig(&preconfig, coreconfig); + PyPreConfig preconfig; + _PyPreConfig_InitFromConfig(&preconfig, config); - if (!coreconfig->parse_argv) { - return _Py_PreInitialize(&preconfig); + if (!config->parse_argv) { + return Py_PreInitialize(&preconfig); } else if (args == NULL) { _PyArgv config_args = { .use_bytes_argv = 0, - .argc = coreconfig->argv.length, - .wchar_argv = coreconfig->argv.items}; + .argc = config->argv.length, + .wchar_argv = config->argv.items}; return _Py_PreInitializeFromPyArgv(&preconfig, &config_args); } else { @@ -818,74 +818,66 @@ _Py_PreInitializeFromCoreConfig(const _PyCoreConfig *coreconfig, * to the Python C API (unless the API is explicitly listed as being * safe to call without calling Py_Initialize first) */ -static _PyInitError +static PyStatus pyinit_core(_PyRuntimeState *runtime, - const _PyCoreConfig *src_config, - const _PyArgv *args, + const PyConfig *src_config, PyInterpreterState **interp_p) { - _PyInitError err; + PyStatus status; - err = _Py_PreInitializeFromCoreConfig(src_config, args); - if (_Py_INIT_FAILED(err)) { - return err; + status = _Py_PreInitializeFromConfig(src_config, NULL); + if (_PyStatus_EXCEPTION(status)) { + return status; } - _PyCoreConfig config; - _PyCoreConfig_InitCompatConfig(&config); + PyConfig config; + _PyConfig_InitCompatConfig(&config); - err = _PyCoreConfig_Copy(&config, src_config); - if (_Py_INIT_FAILED(err)) { + status = _PyConfig_Copy(&config, src_config); + if (_PyStatus_EXCEPTION(status)) { goto done; } - if (args) { - err = _PyCoreConfig_SetPyArgv(&config, args); - if (_Py_INIT_FAILED(err)) { - goto done; - } - } - - err = _PyCoreConfig_Read(&config); - if (_Py_INIT_FAILED(err)) { + status = PyConfig_Read(&config); + if (_PyStatus_EXCEPTION(status)) { goto done; } if (!runtime->core_initialized) { - err = pyinit_core_config(runtime, interp_p, &config); + status = pyinit_config(runtime, interp_p, &config); } else { - err = pyinit_core_reconfigure(runtime, interp_p, &config); + status = pyinit_core_reconfigure(runtime, interp_p, &config); } - if (_Py_INIT_FAILED(err)) { + if (_PyStatus_EXCEPTION(status)) { goto done; } done: - _PyCoreConfig_Clear(&config); - return err; + PyConfig_Clear(&config); + return status; } /* Py_Initialize() has already been called: update the main interpreter configuration. Example of bpo-34008: Py_Main() called after Py_Initialize(). */ -static _PyInitError +static PyStatus _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) { - _PyCoreConfig *core_config = &interp->core_config; + PyConfig *config = &interp->config; - PyObject *argv = _PyWstrList_AsList(&core_config->argv); + PyObject *argv = _PyWideStringList_AsList(&config->argv); if (argv == NULL) { - return _Py_INIT_NO_MEMORY(); \ + return _PyStatus_NO_MEMORY(); \ } int res = PyDict_SetItemString(interp->sysdict, "argv", argv); Py_DECREF(argv); if (res < 0) { - return _Py_INIT_ERR("fail to set sys.argv"); + return _PyStatus_ERR("fail to set sys.argv"); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Update interpreter state based on supplied configuration settings @@ -899,73 +891,73 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * Other errors should be reported as normal Python exceptions with a * non-zero return code. */ -static _PyInitError +static PyStatus pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) { if (!runtime->core_initialized) { - return _Py_INIT_ERR("runtime core not initialized"); + return _PyStatus_ERR("runtime core not initialized"); } /* Configure the main interpreter */ - _PyCoreConfig *core_config = &interp->core_config; + PyConfig *config = &interp->config; if (runtime->initialized) { return _Py_ReconfigureMainInterpreter(interp); } - if (!core_config->_install_importlib) { + if (!config->_install_importlib) { /* Special mode for freeze_importlib: run with no import system * * This means anything which needs support from extension modules * or pure Python code in the standard library won't work. */ runtime->initialized = 1; - return _Py_INIT_OK(); + return _PyStatus_OK(); } if (_PyTime_Init() < 0) { - return _Py_INIT_ERR("can't initialize time"); + return _PyStatus_ERR("can't initialize time"); } if (_PySys_InitMain(runtime, interp) < 0) { - return _Py_INIT_ERR("can't finish initializing sys"); + return _PyStatus_ERR("can't finish initializing sys"); } - _PyInitError err = init_importlib_external(interp); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = init_importlib_external(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* initialize the faulthandler module */ - err = _PyFaulthandler_Init(core_config->faulthandler); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyFaulthandler_Init(config->faulthandler); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyUnicode_InitEncodings(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyUnicode_InitEncodings(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - if (core_config->install_signal_handlers) { - err = init_signals(); - if (_Py_INIT_FAILED(err)) { - return err; + if (config->install_signal_handlers) { + status = init_signals(); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - if (_PyTraceMalloc_Init(core_config->tracemalloc) < 0) { - return _Py_INIT_ERR("can't initialize tracemalloc"); + if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { + return _PyStatus_ERR("can't initialize tracemalloc"); } - err = add_main_module(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = add_main_module(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = init_sys_streams(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = init_sys_streams(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* Initialize warnings. */ @@ -982,10 +974,10 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) runtime->initialized = 1; - if (core_config->site_import) { - err = init_import_size(); /* Module site */ - if (_Py_INIT_FAILED(err)) { - return err; + if (config->site_import) { + status = init_import_size(); /* Module site */ + if (_PyStatus_EXCEPTION(status)) { + return status; } } @@ -993,16 +985,16 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) emit_stderr_warning_for_legacy_locale(runtime); #endif - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError +PyStatus _Py_InitializeMain(void) { - _PyInitError err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; } _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; @@ -1011,74 +1003,47 @@ _Py_InitializeMain(void) } -#undef _INIT_DEBUG_PRINT - -static _PyInitError -pyinit_python(const _PyCoreConfig *config, const _PyArgv *args) +PyStatus +Py_InitializeFromConfig(const PyConfig *config) { if (config == NULL) { - return _Py_INIT_ERR("initialization config is NULL"); + return _PyStatus_ERR("initialization config is NULL"); } - _PyInitError err; + PyStatus status; - err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; } _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = NULL; - err = pyinit_core(runtime, config, args, &interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = pyinit_core(runtime, config, &interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - config = &interp->core_config; + config = &interp->config; if (config->_init_main) { - err = pyinit_main(runtime, interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = pyinit_main(runtime, interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } } - return _Py_INIT_OK(); -} - - -_PyInitError -_Py_InitializeFromArgs(const _PyCoreConfig *config, - Py_ssize_t argc, char * const *argv) -{ - _PyArgv args = {.use_bytes_argv = 1, .argc = argc, .bytes_argv = argv}; - return pyinit_python(config, &args); -} - - -_PyInitError -_Py_InitializeFromWideArgs(const _PyCoreConfig *config, - Py_ssize_t argc, wchar_t * const *argv) -{ - _PyArgv args = {.use_bytes_argv = 0, .argc = argc, .wchar_argv = argv}; - return pyinit_python(config, &args); -} - - -_PyInitError -_Py_InitializeFromConfig(const _PyCoreConfig *config) -{ - return pyinit_python(config, NULL); + return _PyStatus_OK(); } void Py_InitializeEx(int install_sigs) { - _PyInitError err; + PyStatus status; - err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - _Py_ExitInitError(err); + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); } _PyRuntimeState *runtime = &_PyRuntime; @@ -1087,13 +1052,13 @@ Py_InitializeEx(int install_sigs) return; } - _PyCoreConfig config; - _PyCoreConfig_InitCompatConfig(&config); + PyConfig config; + _PyConfig_InitCompatConfig(&config); config.install_signal_handlers = install_sigs; - err = _Py_InitializeFromConfig(&config); - if (_Py_INIT_FAILED(err)) { - _Py_ExitInitError(err); + status = Py_InitializeFromConfig(&config); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); } } @@ -1206,13 +1171,13 @@ Py_FinalizeEx(void) /* Copy the core config, PyInterpreterState_Delete() free the core config memory */ #ifdef Py_REF_DEBUG - int show_ref_count = interp->core_config.show_ref_count; + int show_ref_count = interp->config.show_ref_count; #endif #ifdef Py_TRACE_REFS - int dump_refs = interp->core_config.dump_refs; + int dump_refs = interp->config.dump_refs; #endif #ifdef WITH_PYMALLOC - int malloc_stats = interp->core_config.malloc_stats; + int malloc_stats = interp->config.malloc_stats; #endif /* Remaining threads (e.g. daemon threads) will automatically exit @@ -1412,19 +1377,19 @@ Py_Finalize(void) */ -static _PyInitError +static PyStatus new_interpreter(PyThreadState **tstate_p) { - _PyInitError err; + PyStatus status; - err = _PyRuntime_Initialize(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyRuntime_Initialize(); + if (_PyStatus_EXCEPTION(status)) { + return status; } _PyRuntimeState *runtime = &_PyRuntime; if (!runtime->initialized) { - return _Py_INIT_ERR("Py_Initialize must be called first"); + return _PyStatus_ERR("Py_Initialize must be called first"); } /* Issue #10915, #15751: The GIL API doesn't work with multiple @@ -1434,49 +1399,49 @@ new_interpreter(PyThreadState **tstate_p) PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { *tstate_p = NULL; - return _Py_INIT_OK(); + return _PyStatus_OK(); } PyThreadState *tstate = PyThreadState_New(interp); if (tstate == NULL) { PyInterpreterState_Delete(interp); *tstate_p = NULL; - return _Py_INIT_OK(); + return _PyStatus_OK(); } PyThreadState *save_tstate = PyThreadState_Swap(tstate); /* Copy the current interpreter config into the new interpreter */ - _PyCoreConfig *core_config; + PyConfig *config; if (save_tstate != NULL) { - core_config = &save_tstate->interp->core_config; + config = &save_tstate->interp->config; } else { /* No current thread state, copy from the main interpreter */ PyInterpreterState *main_interp = PyInterpreterState_Main(); - core_config = &main_interp->core_config; + config = &main_interp->config; } - err = _PyCoreConfig_Copy(&interp->core_config, core_config); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyConfig_Copy(&interp->config, config); + if (_PyStatus_EXCEPTION(status)) { + return status; } - core_config = &interp->core_config; + config = &interp->config; - err = _PyExc_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyExc_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyErr_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyErr_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } /* XXX The following is lax in error checking */ PyObject *modules = PyDict_New(); if (modules == NULL) { - return _Py_INIT_ERR("can't make modules dictionary"); + return _PyStatus_ERR("can't make modules dictionary"); } interp->modules = modules; @@ -1489,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p) Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); if (_PySys_InitMain(runtime, interp) < 0) { - return _Py_INIT_ERR("can't finish initializing sys"); + return _PyStatus_ERR("can't finish initializing sys"); } } else if (PyErr_Occurred()) { @@ -1508,50 +1473,50 @@ new_interpreter(PyThreadState **tstate_p) } if (bimod != NULL && sysmod != NULL) { - err = _PyBuiltins_AddExceptions(bimod); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyBuiltins_AddExceptions(bimod); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PySys_SetPreliminaryStderr(interp->sysdict); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PySys_SetPreliminaryStderr(interp->sysdict); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyImportHooks_Init(); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyImportHooks_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = init_importlib(interp, sysmod); - if (_Py_INIT_FAILED(err)) { - return err; + status = init_importlib(interp, sysmod); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = init_importlib_external(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = init_importlib_external(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PyUnicode_InitEncodings(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PyUnicode_InitEncodings(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = init_sys_streams(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = init_sys_streams(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = add_main_module(interp); - if (_Py_INIT_FAILED(err)) { - return err; + status = add_main_module(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; } - if (core_config->site_import) { - err = init_import_size(); - if (_Py_INIT_FAILED(err)) { - return err; + if (config->site_import) { + status = init_import_size(); + if (_PyStatus_EXCEPTION(status)) { + return status; } } } @@ -1561,7 +1526,7 @@ new_interpreter(PyThreadState **tstate_p) } *tstate_p = tstate; - return _Py_INIT_OK(); + return _PyStatus_OK(); handle_error: /* Oops, it didn't work. Undo it all. */ @@ -1573,16 +1538,16 @@ new_interpreter(PyThreadState **tstate_p) PyInterpreterState_Delete(interp); *tstate_p = NULL; - return _Py_INIT_OK(); + return _PyStatus_OK(); } PyThreadState * Py_NewInterpreter(void) { PyThreadState *tstate = NULL; - _PyInitError err = new_interpreter(&tstate); - if (_Py_INIT_FAILED(err)) { - _Py_ExitInitError(err); + PyStatus status = new_interpreter(&tstate); + if (_PyStatus_EXCEPTION(status)) { + Py_ExitStatusException(status); } return tstate; @@ -1627,29 +1592,29 @@ Py_EndInterpreter(PyThreadState *tstate) /* Add the __main__ module */ -static _PyInitError +static PyStatus add_main_module(PyInterpreterState *interp) { PyObject *m, *d, *loader, *ann_dict; m = PyImport_AddModule("__main__"); if (m == NULL) - return _Py_INIT_ERR("can't create __main__ module"); + return _PyStatus_ERR("can't create __main__ module"); d = PyModule_GetDict(m); ann_dict = PyDict_New(); if ((ann_dict == NULL) || (PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) { - return _Py_INIT_ERR("Failed to initialize __main__.__annotations__"); + return _PyStatus_ERR("Failed to initialize __main__.__annotations__"); } Py_DECREF(ann_dict); if (PyDict_GetItemString(d, "__builtins__") == NULL) { PyObject *bimod = PyImport_ImportModule("builtins"); if (bimod == NULL) { - return _Py_INIT_ERR("Failed to retrieve builtins module"); + return _PyStatus_ERR("Failed to retrieve builtins module"); } if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { - return _Py_INIT_ERR("Failed to initialize __main__.__builtins__"); + return _PyStatus_ERR("Failed to initialize __main__.__builtins__"); } Py_DECREF(bimod); } @@ -1665,28 +1630,28 @@ add_main_module(PyInterpreterState *interp) PyObject *loader = PyObject_GetAttrString(interp->importlib, "BuiltinImporter"); if (loader == NULL) { - return _Py_INIT_ERR("Failed to retrieve BuiltinImporter"); + return _PyStatus_ERR("Failed to retrieve BuiltinImporter"); } if (PyDict_SetItemString(d, "__loader__", loader) < 0) { - return _Py_INIT_ERR("Failed to initialize __main__.__loader__"); + return _PyStatus_ERR("Failed to initialize __main__.__loader__"); } Py_DECREF(loader); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Import the site module (not into __main__ though) */ -static _PyInitError +static PyStatus init_import_size(void) { PyObject *m; m = PyImport_ImportModule("site"); if (m == NULL) { - return _Py_INIT_ERR("Failed to import the site module"); + return _PyStatus_ERR("Failed to import the site module"); } Py_DECREF(m); - return _Py_INIT_OK(); + return _PyStatus_OK(); } /* Check if a file descriptor is valid or not. @@ -1727,7 +1692,7 @@ is_valid_fd(int fd) /* returns Py_None if the fd is not valid */ static PyObject* -create_stdio(const _PyCoreConfig *config, PyObject* io, +create_stdio(const PyConfig *config, PyObject* io, int fd, int write_mode, const char* name, const wchar_t* encoding, const wchar_t* errors) { @@ -1864,7 +1829,7 @@ create_stdio(const _PyCoreConfig *config, PyObject* io, } /* Initialize sys.stdin, stdout, stderr and builtins.open */ -static _PyInitError +static PyStatus init_sys_streams(PyInterpreterState *interp) { PyObject *iomod = NULL, *wrapper; @@ -1873,8 +1838,8 @@ init_sys_streams(PyInterpreterState *interp) PyObject *std = NULL; int fd; PyObject * encoding_attr; - _PyInitError res = _Py_INIT_OK(); - _PyCoreConfig *config = &interp->core_config; + PyStatus res = _PyStatus_OK(); + PyConfig *config = &interp->config; /* Check that stdin is not a directory Using shell redirection, you can redirect stdin to a directory, @@ -1885,7 +1850,7 @@ init_sys_streams(PyInterpreterState *interp) struct _Py_stat_struct sb; if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode)) { - return _Py_INIT_ERR(" is a directory, cannot continue"); + return _PyStatus_ERR(" is a directory, cannot continue"); } #endif @@ -1981,7 +1946,7 @@ init_sys_streams(PyInterpreterState *interp) goto done; error: - res = _Py_INIT_ERR("can't initialize sys standard streams"); + res = _PyStatus_ERR("can't initialize sys standard streams"); done: _Py_ClearStandardStreamEncoding(); @@ -2183,16 +2148,16 @@ Py_FatalError(const char *msg) } void _Py_NO_RETURN -_Py_ExitInitError(_PyInitError err) +Py_ExitStatusException(PyStatus status) { - if (_Py_INIT_IS_EXIT(err)) { - exit(err.exitcode); + if (_PyStatus_IS_EXIT(status)) { + exit(status.exitcode); } - else if (_Py_INIT_IS_ERROR(err)) { - fatal_error(err._func, err.err_msg, 1); + else if (_PyStatus_IS_ERROR(status)) { + fatal_error(status.func, status.err_msg, 1); } else { - Py_FatalError("_Py_ExitInitError() must not be called on success"); + Py_FatalError("Py_ExitStatusException() must not be called on success"); } } @@ -2284,7 +2249,7 @@ Py_Exit(int sts) exit(sts); } -static _PyInitError +static PyStatus init_signals(void) { #ifdef SIGPIPE @@ -2298,9 +2263,9 @@ init_signals(void) #endif PyOS_InitInterrupts(); /* May imply initsignal() */ if (PyErr_Occurred()) { - return _Py_INIT_ERR("can't import signal"); + return _PyStatus_ERR("can't import signal"); } - return _Py_INIT_OK(); + return _PyStatus_OK(); } diff --git a/Python/pystate.c b/Python/pystate.c index 41c66223390d05..d1a8d24724707e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,7 +3,7 @@ #include "Python.h" #include "pycore_ceval.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "pycore_pylifecycle.h" @@ -42,7 +42,7 @@ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_st static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate); -static _PyInitError +static PyStatus _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) { /* We preserve the hook across init, because there is @@ -60,7 +60,7 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) _PyGC_Initialize(&runtime->gc); _PyEval_Initialize(&runtime->ceval); - _PyPreConfig_InitPythonConfig(&runtime->preconfig); + PyPreConfig_InitPythonConfig(&runtime->preconfig); runtime->gilstate.check_enabled = 1; @@ -71,22 +71,22 @@ _PyRuntimeState_Init_impl(_PyRuntimeState *runtime) runtime->interpreters.mutex = PyThread_allocate_lock(); if (runtime->interpreters.mutex == NULL) { - return _Py_INIT_ERR("Can't initialize threads for interpreter"); + return _PyStatus_ERR("Can't initialize threads for interpreter"); } runtime->interpreters.next_id = -1; runtime->xidregistry.mutex = PyThread_allocate_lock(); if (runtime->xidregistry.mutex == NULL) { - return _Py_INIT_ERR("Can't initialize threads for cross-interpreter data registry"); + return _PyStatus_ERR("Can't initialize threads for cross-interpreter data registry"); } // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); - return _Py_INIT_OK(); + return _PyStatus_OK(); } -_PyInitError +PyStatus _PyRuntimeState_Init(_PyRuntimeState *runtime) { /* Force default allocator, since _PyRuntimeState_Fini() must @@ -94,10 +94,10 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyInitError err = _PyRuntimeState_Init_impl(runtime); + PyStatus status = _PyRuntimeState_Init_impl(runtime); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return err; + return status; } void @@ -163,7 +163,7 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) static void _PyGILState_NoteThreadState( struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); -_PyInitError +PyStatus _PyInterpreterState_Enable(_PyRuntimeState *runtime) { struct pyinterpreters *interpreters = &runtime->interpreters; @@ -182,11 +182,11 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); if (interpreters->mutex == NULL) { - return _Py_INIT_ERR("Can't initialize threads for interpreter"); + return _PyStatus_ERR("Can't initialize threads for interpreter"); } } - return _Py_INIT_OK(); + return _PyStatus_OK(); } PyInterpreterState * @@ -205,8 +205,11 @@ PyInterpreterState_New(void) interp->id_refcount = -1; interp->check_interval = 100; - _PyInitError err = _PyCoreConfig_InitPythonConfig(&interp->core_config); - if (_Py_INIT_FAILED(err)) { + PyStatus status = PyConfig_InitPythonConfig(&interp->config); + if (_PyStatus_EXCEPTION(status)) { + /* Don't report status to caller: PyConfig_InitPythonConfig() + can only fail with a memory allocation error. */ + PyConfig_Clear(&interp->config); PyMem_RawFree(interp); return NULL; } @@ -269,7 +272,7 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) Py_CLEAR(interp->audit_hooks); - _PyCoreConfig_Clear(&interp->core_config); + PyConfig_Clear(&interp->config); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); Py_CLEAR(interp->codec_error_registry); @@ -523,12 +526,6 @@ _PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required) interp->requires_idref = required ? 1 : 0; } -_PyCoreConfig * -_PyInterpreterState_GetCoreConfig(PyInterpreterState *interp) -{ - return &interp->core_config; -} - PyObject * _PyInterpreterState_GetMainModule(PyInterpreterState *interp) { @@ -775,7 +772,7 @@ _PyState_ClearModules(void) void PyThreadState_Clear(PyThreadState *tstate) { - int verbose = tstate->interp->core_config.verbose; + int verbose = tstate->interp->config.verbose; if (verbose && tstate->frame != NULL) fprintf(stderr, diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 26cb02aad5f1fb..665c9c9586e1e0 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -94,7 +94,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * PyCompilerFlags local_flags; int nomem_count = 0; #ifdef Py_REF_DEBUG - int show_ref_count = _PyInterpreterState_Get()->core_config.show_ref_count; + int show_ref_count = _PyInterpreterState_Get()->config.show_ref_count; #endif filename = PyUnicode_DecodeFSDefault(filename_str); @@ -584,7 +584,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj) int _Py_HandleSystemExit(int *exitcode_p) { - int inspect = _PyInterpreterState_GET_UNSAFE()->core_config.inspect; + int inspect = _PyInterpreterState_GET_UNSAFE()->config.inspect; if (inspect) { /* Don't exit if -i flag was given. This flag is set to 0 * when entering interactive mode for inspecting. */ diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 08a1a2995e004e..24018e25fa579d 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -17,7 +17,7 @@ Data members: #include "Python.h" #include "code.h" #include "frameobject.h" -#include "pycore_coreconfig.h" +#include "pycore_initconfig.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" #include "pycore_pathconfig.h" @@ -752,7 +752,7 @@ sys_getfilesystemencoding_impl(PyObject *module) /*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/ { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; + const PyConfig *config = &interp->config; return PyUnicode_FromWideChar(config->filesystem_encoding, -1); } @@ -767,7 +767,7 @@ sys_getfilesystemencodeerrors_impl(PyObject *module) /*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/ { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const _PyCoreConfig *config = &interp->core_config; + const PyConfig *config = &interp->config; return PyUnicode_FromWideChar(config->filesystem_errors, -1); } @@ -2475,8 +2475,8 @@ make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) { int pos = 0; PyObject *seq; - const _PyPreConfig *preconfig = &runtime->preconfig; - const _PyCoreConfig *config = &interp->core_config; + const PyPreConfig *preconfig = &runtime->preconfig; + const PyConfig *config = &interp->config; seq = PyStructSequence_New(&FlagsType); if (seq == NULL) @@ -2690,7 +2690,7 @@ static struct PyModuleDef sysmodule = { } \ } while (0) -static _PyInitError +static PyStatus _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, PyObject *sysdict) { @@ -2827,13 +2827,13 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, if (PyErr_Occurred()) { goto err_occurred; } - return _Py_INIT_OK(); + return _PyStatus_OK(); type_init_failed: - return _Py_INIT_ERR("failed to initialize a type"); + return _PyStatus_ERR("failed to initialize a type"); err_occurred: - return _Py_INIT_ERR("can't initialize sys module"); + return _PyStatus_ERR("can't initialize sys module"); } #undef SET_SYS_FROM_STRING @@ -2885,7 +2885,7 @@ sys_add_xoption(PyObject *opts, const wchar_t *s) static PyObject* -sys_create_xoptions_dict(const _PyCoreConfig *config) +sys_create_xoptions_dict(const PyConfig *config) { Py_ssize_t nxoption = config->xoptions.length; wchar_t * const * xoptions = config->xoptions.items; @@ -2910,12 +2910,12 @@ int _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) { PyObject *sysdict = interp->sysdict; - const _PyCoreConfig *config = &interp->core_config; + const PyConfig *config = &interp->config; int res; #define COPY_LIST(KEY, VALUE) \ do { \ - PyObject *list = _PyWstrList_AsList(&(VALUE)); \ + PyObject *list = _PyWideStringList_AsList(&(VALUE)); \ if (list == NULL) { \ return -1; \ } \ @@ -3003,7 +3003,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) infrastructure for the io module in place. Use UTF-8/surrogateescape and ignore EAGAIN errors. */ -_PyInitError +PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict) { PyObject *pstderr = PyFile_NewStdPrinter(fileno(stderr)); @@ -3017,56 +3017,56 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict) goto error; } Py_DECREF(pstderr); - return _Py_INIT_OK(); + return _PyStatus_OK(); error: Py_XDECREF(pstderr); - return _Py_INIT_ERR("can't set preliminary stderr"); + return _PyStatus_ERR("can't set preliminary stderr"); } /* Create sys module without all attributes: _PySys_InitMain() should be called later to add remaining attributes. */ -_PyInitError +PyStatus _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, PyObject **sysmod_p) { PyObject *modules = PyDict_New(); if (modules == NULL) { - return _Py_INIT_ERR("can't make modules dictionary"); + return _PyStatus_ERR("can't make modules dictionary"); } interp->modules = modules; PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION); if (sysmod == NULL) { - return _Py_INIT_ERR("failed to create a module object"); + return _PyStatus_ERR("failed to create a module object"); } PyObject *sysdict = PyModule_GetDict(sysmod); if (sysdict == NULL) { - return _Py_INIT_ERR("can't initialize sys dict"); + return _PyStatus_ERR("can't initialize sys dict"); } Py_INCREF(sysdict); interp->sysdict = sysdict; if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) { - return _Py_INIT_ERR("can't initialize sys module"); + return _PyStatus_ERR("can't initialize sys module"); } - _PyInitError err = _PySys_SetPreliminaryStderr(sysdict); - if (_Py_INIT_FAILED(err)) { - return err; + PyStatus status = _PySys_SetPreliminaryStderr(sysdict); + if (_PyStatus_EXCEPTION(status)) { + return status; } - err = _PySys_InitCore(runtime, interp, sysdict); - if (_Py_INIT_FAILED(err)) { - return err; + status = _PySys_InitCore(runtime, interp, sysdict); + if (_PyStatus_EXCEPTION(status)) { + return status; } _PyImport_FixupBuiltin(sysmod, "sys", interp->modules); *sysmod_p = sysmod; - return _Py_INIT_OK(); + return _PyStatus_OK(); } @@ -3156,7 +3156,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) if (updatepath) { /* If argv[0] is not '-c' nor '-m', prepend argv[0] to sys.path. If argv[0] is a symlink, use the real path. */ - const _PyWstrList argv_list = {.length = argc, .items = argv}; + const PyWideStringList argv_list = {.length = argc, .items = argv}; PyObject *path0 = NULL; if (_PyPathConfig_ComputeSysPath0(&argv_list, &path0)) { if (path0 == NULL) { From 02db696732c031d9a0265dc9bbf4f5b1fad042b3 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Mon, 27 May 2019 10:48:17 -0600 Subject: [PATCH 128/441] bpo-32941: Add madvise() for mmap objects (GH-6172) Allow mmap objects to access the madvise() system call. --- Doc/library/mmap.rst | 49 ++++++++ Doc/whatsnew/3.8.rst | 9 ++ Lib/test/test_mmap.py | 19 +++ .../2018-03-20-20-57-00.bpo-32941.9FU0gL.rst | 2 + Modules/mmapmodule.c | 118 ++++++++++++++++++ configure | 2 +- configure.ac | 2 +- pyconfig.h.in | 3 + 8 files changed, 202 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index a82caf86e8018a..c7a13abad888d9 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -203,6 +203,20 @@ To map anonymous memory, -1 should be passed as the fileno along with the length exception was raised on error under Unix. + .. method:: madvise(option[, start[, length]]) + + Send advice *option* to the kernel about the memory region beginning at + *start* and extending *length* bytes. *option* must be one of the + :ref:`MADV_* constants ` available on the system. If + *start* and *length* are omitted, the entire mapping is spanned. On + some systems (including Linux), *start* must be a multiple of the + :const:`PAGESIZE`. + + Availability: Systems with the ``madvise()`` system call. + + .. versionadded:: 3.8 + + .. method:: move(dest, src, count) Copy the *count* bytes starting at offset *src* to the destination index @@ -292,3 +306,38 @@ To map anonymous memory, -1 should be passed as the fileno along with the length position of the file pointer; the file position is advanced by ``1``. If the mmap was created with :const:`ACCESS_READ`, then writing to it will raise a :exc:`TypeError` exception. + +.. _madvise-constants: + +MADV_* Constants +++++++++++++++++ + +.. data:: MADV_NORMAL + MADV_RANDOM + MADV_SEQUENTIAL + MADV_WILLNEED + MADV_DONTNEED + MADV_REMOVE + MADV_DONTFORK + MADV_DOFORK + MADV_HWPOISON + MADV_MERGEABLE + MADV_UNMERGEABLE + MADV_SOFT_OFFLINE + MADV_HUGEPAGE + MADV_NOHUGEPAGE + MADV_DONTDUMP + MADV_DODUMP + MADV_FREE + MADV_NOSYNC + MADV_AUTOSYNC + MADV_NOCORE + MADV_CORE + MADV_PROTECT + + These options can be passed to :meth:`mmap.madvise`. Not every option will + be present on every system. + + Availability: Systems with the madvise() system call. + + .. versionadded:: 3.8 diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 6102d8c357cab0..fd5e6496ba2ed5 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -460,6 +460,15 @@ numbers. (Contributed by Pablo Galindo in :issue:`35606`) Added new function :func:`math.isqrt` for computing integer square roots. (Contributed by Mark Dickinson in :issue:`36887`.) + +mmap +---- + +The :class:`mmap.mmap` class now has an :meth:`~mmap.mmap.madvise` method to +access the ``madvise()`` system call. +(Contributed by Zackery Spytz in :issue:`32941`.) + + os -- diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 495d24ad807730..7b2b100dce0155 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -739,6 +739,25 @@ def test_flush_return_value(self): # See bpo-34754 for details. self.assertRaises(OSError, mm.flush, 1, len(b'python')) + @unittest.skipUnless(hasattr(mmap.mmap, 'madvise'), 'needs madvise') + def test_madvise(self): + size = 8192 + m = mmap.mmap(-1, size) + + with self.assertRaisesRegex(ValueError, "madvise start out of bounds"): + m.madvise(mmap.MADV_NORMAL, size) + with self.assertRaisesRegex(ValueError, "madvise start out of bounds"): + m.madvise(mmap.MADV_NORMAL, -1) + with self.assertRaisesRegex(ValueError, "madvise length invalid"): + m.madvise(mmap.MADV_NORMAL, 0, -1) + with self.assertRaisesRegex(OverflowError, "madvise length too large"): + m.madvise(mmap.MADV_NORMAL, PAGESIZE, sys.maxsize) + self.assertEqual(m.madvise(mmap.MADV_NORMAL), None) + self.assertEqual(m.madvise(mmap.MADV_NORMAL, PAGESIZE), None) + self.assertEqual(m.madvise(mmap.MADV_NORMAL, PAGESIZE, size), None) + self.assertEqual(m.madvise(mmap.MADV_NORMAL, 0, 2), None) + self.assertEqual(m.madvise(mmap.MADV_NORMAL, 0, size), None) + class LargeMmapTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst b/Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst new file mode 100644 index 00000000000000..f7668aecda6b50 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst @@ -0,0 +1,2 @@ +Allow :class:`mmap.mmap` objects to access the madvise() system call +(through :meth:`mmap.mmap.madvise`). diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index fdd60bbb6eefca..36cbaf9fb8b23d 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -708,11 +708,54 @@ mmap__sizeof__method(mmap_object *self, void *unused) } #endif +#ifdef HAVE_MADVISE +static PyObject * +mmap_madvise_method(mmap_object *self, PyObject *args) +{ + int option; + Py_ssize_t start = 0, length; + + CHECK_VALID(NULL); + length = self->size; + + if (!PyArg_ParseTuple(args, "i|nn:madvise", &option, &start, &length)) { + return NULL; + } + + if (start < 0 || start >= self->size) { + PyErr_SetString(PyExc_ValueError, "madvise start out of bounds"); + return NULL; + } + if (length < 0) { + PyErr_SetString(PyExc_ValueError, "madvise length invalid"); + return NULL; + } + if (PY_SSIZE_T_MAX - start < length) { + PyErr_SetString(PyExc_OverflowError, "madvise length too large"); + return NULL; + } + + if (start + length > self->size) { + length = self->size - start; + } + + if (madvise(self->data + start, length, option) != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + Py_RETURN_NONE; +} +#endif // HAVE_MADVISE + static struct PyMethodDef mmap_object_methods[] = { {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, {"rfind", (PyCFunction) mmap_rfind_method, METH_VARARGS}, {"flush", (PyCFunction) mmap_flush_method, METH_VARARGS}, +#ifdef HAVE_MADVISE + {"madvise", (PyCFunction) mmap_madvise_method, METH_VARARGS}, +#endif {"move", (PyCFunction) mmap_move_method, METH_VARARGS}, {"read", (PyCFunction) mmap_read_method, METH_VARARGS}, {"read_byte", (PyCFunction) mmap_read_byte_method, METH_NOARGS}, @@ -1494,5 +1537,80 @@ PyInit_mmap(void) setint(dict, "ACCESS_READ", ACCESS_READ); setint(dict, "ACCESS_WRITE", ACCESS_WRITE); setint(dict, "ACCESS_COPY", ACCESS_COPY); + +#ifdef HAVE_MADVISE + // Conventional advice values +#ifdef MADV_NORMAL + setint(dict, "MADV_NORMAL", MADV_NORMAL); +#endif +#ifdef MADV_RANDOM + setint(dict, "MADV_RANDOM", MADV_RANDOM); +#endif +#ifdef MADV_SEQUENTIAL + setint(dict, "MADV_SEQUENTIAL", MADV_SEQUENTIAL); +#endif +#ifdef MADV_WILLNEED + setint(dict, "MADV_WILLNEED", MADV_WILLNEED); +#endif +#ifdef MADV_DONTNEED + setint(dict, "MADV_DONTNEED", MADV_DONTNEED); +#endif + + // Linux-specific advice values +#ifdef MADV_REMOVE + setint(dict, "MADV_REMOVE", MADV_REMOVE); +#endif +#ifdef MADV_DONTFORK + setint(dict, "MADV_DONTFORK", MADV_DONTFORK); +#endif +#ifdef MADV_DOFORK + setint(dict, "MADV_DOFORK", MADV_DOFORK); +#endif +#ifdef MADV_HWPOISON + setint(dict, "MADV_HWPOISON", MADV_HWPOISON); +#endif +#ifdef MADV_MERGEABLE + setint(dict, "MADV_MERGEABLE", MADV_MERGEABLE); +#endif +#ifdef MADV_UNMERGEABLE + setint(dict, "MADV_UNMERGEABLE", MADV_UNMERGEABLE); +#endif +#ifdef MADV_SOFT_OFFLINE + setint(dict, "MADV_SOFT_OFFLINE", MADV_SOFT_OFFLINE); +#endif +#ifdef MADV_HUGEPAGE + setint(dict, "MADV_HUGEPAGE", MADV_HUGEPAGE); +#endif +#ifdef MADV_NOHUGEPAGE + setint(dict, "MADV_NOHUGEPAGE", MADV_NOHUGEPAGE); +#endif +#ifdef MADV_DONTDUMP + setint(dict, "MADV_DONTDUMP", MADV_DONTDUMP); +#endif +#ifdef MADV_DODUMP + setint(dict, "MADV_DODUMP", MADV_DODUMP); +#endif +#ifdef MADV_FREE // (Also present on FreeBSD and macOS.) + setint(dict, "MADV_FREE", MADV_FREE); +#endif + + // FreeBSD-specific +#ifdef MADV_NOSYNC + setint(dict, "MADV_NOSYNC", MADV_NOSYNC); +#endif +#ifdef MADV_AUTOSYNC + setint(dict, "MADV_AUTOSYNC", MADV_AUTOSYNC); +#endif +#ifdef MADV_NOCORE + setint(dict, "MADV_NOCORE", MADV_NOCORE); +#endif +#ifdef MADV_CORE + setint(dict, "MADV_CORE", MADV_CORE); +#endif +#ifdef MADV_PROTECT + setint(dict, "MADV_PROTECT", MADV_PROTECT); +#endif +#endif // HAVE_MADVISE + return module; } diff --git a/configure b/configure index bc276ac58362bf..e8cbfeb154a543 100755 --- a/configure +++ b/configure @@ -11471,7 +11471,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ - initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ + initgroups kill killpg lchmod lchown lockf linkat lstat lutimes madvise mmap \ memrchr mbrtowc mkdirat mkfifo \ mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ diff --git a/configure.ac b/configure.ac index 5e565191f27de1..c743edfdeb183a 100644 --- a/configure.ac +++ b/configure.ac @@ -3527,7 +3527,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ - mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ + madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ readlink readlinkat readv realpath renameat \ diff --git a/pyconfig.h.in b/pyconfig.h.in index dd5f2e393be094..cc64355416463b 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -658,6 +658,9 @@ /* Define to 1 if you have the `lutimes' function. */ #undef HAVE_LUTIMES +/* Define to 1 if you have the `madvise' function. */ +#undef HAVE_MADVISE + /* Define this if you have the makedev macro. */ #undef HAVE_MAKEDEV From cc1c582f6fe450ce1c7de849137039e9b5fab8eb Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 27 May 2019 10:21:31 -0700 Subject: [PATCH 129/441] bpo-37051: Refine note on what objects are hashable (GH-13587) --- Doc/glossary.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index d3ce3652551998..177df54ef215d4 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -512,8 +512,10 @@ Glossary Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally. - All of Python's immutable built-in objects are hashable; mutable - containers (such as lists or dictionaries) are not. Objects which are + Most of Python's immutable built-in objects are hashable; mutable + containers (such as lists or dictionaries) are not; immutable + containers (such as tuples and frozensets) are only hashable if + their elements are hashable. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their :func:`id`. From a8e814db96ebfeb1f58bc471edffde2176c0ae05 Mon Sep 17 00:00:00 2001 From: Philippe Gagnon <12717218+pgagnon@users.noreply.github.com> Date: Mon, 27 May 2019 13:45:24 -0400 Subject: [PATCH 130/441] Fix a typo in SECURITY.md (GH-13568) There is a duplicated "in" in the Supported Versions text. --- .github/SECURITY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 23976fda4a7eb5..28aea946623cc5 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -2,7 +2,7 @@ ## Supported Versions -The Python team applies security fixes according to the table in +The Python team applies security fixes according to the table in [the devguide]( https://devguide.python.org/#status-of-python-branches ). From 695b1dd8cbf3a48fdb30ab96918a49b20b7ec3e7 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 27 May 2019 19:57:23 +0200 Subject: [PATCH 131/441] bpo-32941: Fix test_madvise failure when page size >= 8kiB (GH-13596) https://bugs.python.org/issue32941 --- Lib/test/test_mmap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 7b2b100dce0155..88c501d81a07f9 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -13,6 +13,7 @@ PAGESIZE = mmap.PAGESIZE + class MmapTests(unittest.TestCase): def setUp(self): @@ -741,7 +742,7 @@ def test_flush_return_value(self): @unittest.skipUnless(hasattr(mmap.mmap, 'madvise'), 'needs madvise') def test_madvise(self): - size = 8192 + size = 2 * PAGESIZE m = mmap.mmap(-1, size) with self.assertRaisesRegex(ValueError, "madvise start out of bounds"): From 6f6ff8a56518a80da406aad6ac8364c046cc7f18 Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Mon, 27 May 2019 15:31:52 -0400 Subject: [PATCH 132/441] bpo-37050: Remove expr_text from FormattedValue ast node, use Constant node instead (GH-13597) When using the "=" debug functionality of f-strings, use another Constant node (or a merged constant node) instead of adding expr_text to the FormattedValue node. --- Include/Python-ast.h | 7 +- Lib/test/test_fstring.py | 18 ++++ Lib/test/test_future.py | 15 ++-- .../2019-05-27-14-46-24.bpo-37050.7MyZGg.rst | 4 + Parser/Python.asdl | 2 +- Python/Python-ast.c | 35 ++------ Python/ast.c | 90 ++++++++++--------- Python/ast_unparse.c | 5 -- Python/compile.c | 11 --- 9 files changed, 87 insertions(+), 100 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 2fc50e3f53a21f..490d3b0846abe7 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -330,7 +330,6 @@ struct _expr { expr_ty value; int conversion; expr_ty format_spec; - string expr_text; } FormattedValue; struct { @@ -639,10 +638,10 @@ expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); -#define FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7, a8) +#define FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) _Py_FormattedValue(a0, a1, a2, a3, a4, a5, a6, a7) expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, - string expr_text, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena); + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena); #define JoinedStr(a0, a1, a2, a3, a4, a5) _Py_JoinedStr(a0, a1, a2, a3, a4, a5) expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 3484fcecf1c5e2..c9e6e7de5afdbf 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -1150,6 +1150,24 @@ def __repr__(self): self.assertRaises(SyntaxError, eval, "f'{C=]'") + # Make sure leading and following text works. + x = 'foo' + self.assertEqual(f'X{x=}Y', 'Xx='+repr(x)+'Y') + + # Make sure whitespace around the = works. + self.assertEqual(f'X{x =}Y', 'Xx ='+repr(x)+'Y') + self.assertEqual(f'X{x= }Y', 'Xx= '+repr(x)+'Y') + self.assertEqual(f'X{x = }Y', 'Xx = '+repr(x)+'Y') + + # These next lines contains tabs. Backslash escapes don't + # work in f-strings. + # patchcheck doens't like these tabs. So the only way to test + # this will be to dynamically created and exec the f-strings. But + # that's such a hassle I'll save it for another day. For now, convert + # the tabs to spaces just to shut up patchcheck. + #self.assertEqual(f'X{x =}Y', 'Xx\t='+repr(x)+'Y') + #self.assertEqual(f'X{x = }Y', 'Xx\t=\t'+repr(x)+'Y') + def test_walrus(self): x = 20 # This isn't an assignment expression, it's 'x', with a format diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index dd148b62956298..303c5f7fbed605 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -270,12 +270,6 @@ def test_annotations(self): eq("f'{x}'") eq("f'{x!r}'") eq("f'{x!a}'") - eq("f'{x=!r}'") - eq("f'{x=:}'") - eq("f'{x=:.2f}'") - eq("f'{x=!r}'") - eq("f'{x=!a}'") - eq("f'{x=!s:*^20}'") eq('(yield from outside_of_generator)') eq('(yield)') eq('(yield a + b)') @@ -290,6 +284,15 @@ def test_annotations(self): eq("(x:=10)") eq("f'{(x:=10):=10}'") + # f-strings with '=' don't round trip very well, so set the expected + # result explicitely. + self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'") + self.assertAnnotationEqual("f'{x=:}'", expected="f'x={x:}'") + self.assertAnnotationEqual("f'{x=:.2f}'", expected="f'x={x:.2f}'") + self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'") + self.assertAnnotationEqual("f'{x=!a}'", expected="f'x={x!a}'") + self.assertAnnotationEqual("f'{x=!s:*^20}'", expected="f'x={x!s:*^20}'") + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst new file mode 100644 index 00000000000000..0667c8ebd14898 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst @@ -0,0 +1,4 @@ +Improve the AST for "debug" f-strings, which use '=' to print out the source +of the expression being evaluated. Delete expr_text from the FormattedValue +node, and instead use a Constant string node (possibly merged with adjacent +constant expressions inside the f-string). diff --git a/Parser/Python.asdl b/Parser/Python.asdl index 882f5d1eba35bf..0c00d398b4610e 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -76,7 +76,7 @@ module Python -- x < 4 < 3 and (x < 4) < 3 | Compare(expr left, cmpop* ops, expr* comparators) | Call(expr func, expr* args, keyword* keywords) - | FormattedValue(expr value, int? conversion, expr? format_spec, string? expr_text) + | FormattedValue(expr value, int? conversion, expr? format_spec) | JoinedStr(expr* values) | Constant(constant value, string? kind) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 39a40eedca3267..7c8e438658f7fa 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -314,12 +314,10 @@ static char *Call_fields[]={ static PyTypeObject *FormattedValue_type; _Py_IDENTIFIER(conversion); _Py_IDENTIFIER(format_spec); -_Py_IDENTIFIER(expr_text); static char *FormattedValue_fields[]={ "value", "conversion", "format_spec", - "expr_text", }; static PyTypeObject *JoinedStr_type; static char *JoinedStr_fields[]={ @@ -954,7 +952,7 @@ static int init_types(void) Call_type = make_type("Call", expr_type, Call_fields, 3); if (!Call_type) return 0; FormattedValue_type = make_type("FormattedValue", expr_type, - FormattedValue_fields, 4); + FormattedValue_fields, 3); if (!FormattedValue_type) return 0; JoinedStr_type = make_type("JoinedStr", expr_type, JoinedStr_fields, 1); if (!JoinedStr_type) return 0; @@ -2253,9 +2251,9 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int } expr_ty -FormattedValue(expr_ty value, int conversion, expr_ty format_spec, string - expr_text, int lineno, int col_offset, int end_lineno, int - end_col_offset, PyArena *arena) +FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { expr_ty p; if (!value) { @@ -2270,7 +2268,6 @@ FormattedValue(expr_ty value, int conversion, expr_ty format_spec, string p->v.FormattedValue.value = value; p->v.FormattedValue.conversion = conversion; p->v.FormattedValue.format_spec = format_spec; - p->v.FormattedValue.expr_text = expr_text; p->lineno = lineno; p->col_offset = col_offset; p->end_lineno = end_lineno; @@ -3507,11 +3504,6 @@ ast2obj_expr(void* _o) if (_PyObject_SetAttrId(result, &PyId_format_spec, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(o->v.FormattedValue.expr_text); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_expr_text, value) == -1) - goto failed; - Py_DECREF(value); break; case JoinedStr_kind: result = PyType_GenericNew(JoinedStr_type, NULL, NULL); @@ -7169,7 +7161,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) expr_ty value; int conversion; expr_ty format_spec; - string expr_text; if (_PyObject_LookupAttrId(obj, &PyId_value, &tmp) < 0) { return 1; @@ -7210,22 +7201,8 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } - if (_PyObject_LookupAttrId(obj, &PyId_expr_text, &tmp) < 0) { - return 1; - } - if (tmp == NULL || tmp == Py_None) { - Py_CLEAR(tmp); - expr_text = NULL; - } - else { - int res; - res = obj2ast_string(tmp, &expr_text, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } - *out = FormattedValue(value, conversion, format_spec, expr_text, - lineno, col_offset, end_lineno, end_col_offset, - arena); + *out = FormattedValue(value, conversion, format_spec, lineno, + col_offset, end_lineno, end_col_offset, arena); if (*out == NULL) goto failed; return 0; } diff --git a/Python/ast.c b/Python/ast.c index 625982735775b8..7ffdf4a2a03709 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -5006,10 +5006,16 @@ fstring_parse(const char **str, const char *end, int raw, int recurse_lvl, closing brace doesn't match an opening paren, for example. It doesn't need to error on all invalid expressions, just correctly find the end of all valid ones. Any errors inside the expression - will be caught when we parse it later. */ + will be caught when we parse it later. + + *expression is set to the expression. For an '=' "debug" expression, + *expr_text is set to the debug text (the original text of the expression, + *including the '=' and any whitespace around it, as a string object). If + *not a debug expression, *expr_text set to NULL. */ static int fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, - expr_ty *expression, struct compiling *c, const node *n) + PyObject **expr_text, expr_ty *expression, + struct compiling *c, const node *n) { /* Return -1 on error, else 0. */ @@ -5020,9 +5026,6 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, int conversion = -1; /* The conversion char. Use default if not specified, or !r if using = and no format spec. */ - int equal_flag = 0; /* Are we using the = feature? */ - PyObject *expr_text = NULL; /* The text of the expression, used for =. */ - const char *expr_text_end; /* 0 if we're not in a string, else the quote char we're trying to match (single or double quote). */ @@ -5198,7 +5201,6 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, expr_text. */ if (**str == '=') { *str += 1; - equal_flag = 1; /* Skip over ASCII whitespace. No need to test for end of string here, since we know there's at least a trailing quote somewhere @@ -5206,7 +5208,14 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, while (Py_ISSPACE(**str)) { *str += 1; } - expr_text_end = *str; + + /* Set *expr_text to the text of the expression. */ + *expr_text = PyUnicode_FromStringAndSize(expr_start, *str-expr_start); + if (!*expr_text) { + goto error; + } + } else { + *expr_text = NULL; } /* Check for a conversion char, if present. */ @@ -5227,17 +5236,6 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, } } - if (equal_flag) { - Py_ssize_t len = expr_text_end - expr_start; - expr_text = PyUnicode_FromStringAndSize(expr_start, len); - if (!expr_text) { - goto error; - } - if (PyArena_AddPyObject(c->c_arena, expr_text) < 0) { - Py_DECREF(expr_text); - goto error; - } - } /* Check for the format spec, if present. */ if (*str >= end) @@ -5261,16 +5259,16 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, assert(**str == '}'); *str += 1; - /* If we're in = mode, and have no format spec and no explict conversion, - set the conversion to 'r'. */ - if (equal_flag && format_spec == NULL && conversion == -1) { + /* If we're in = mode (detected by non-NULL expr_text), and have no format + spec and no explict conversion, set the conversion to 'r'. */ + if (*expr_text && format_spec == NULL && conversion == -1) { conversion = 'r'; } /* And now create the FormattedValue node that represents this entire expression with the conversion and format spec. */ *expression = FormattedValue(simple_expression, conversion, - format_spec, expr_text, LINENO(n), + format_spec, LINENO(n), n->n_col_offset, n->n_end_lineno, n->n_end_col_offset, c->c_arena); if (!*expression) @@ -5313,7 +5311,7 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, static int fstring_find_literal_and_expr(const char **str, const char *end, int raw, int recurse_lvl, PyObject **literal, - expr_ty *expression, + PyObject **expr_text, expr_ty *expression, struct compiling *c, const node *n) { int result; @@ -5341,7 +5339,8 @@ fstring_find_literal_and_expr(const char **str, const char *end, int raw, /* We must now be the start of an expression, on a '{'. */ assert(**str == '{'); - if (fstring_find_expr(str, end, raw, recurse_lvl, expression, c, n) < 0) + if (fstring_find_expr(str, end, raw, recurse_lvl, expr_text, + expression, c, n) < 0) goto error; return 0; @@ -5604,7 +5603,7 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str, /* Parse the f-string. */ while (1) { - PyObject *literal = NULL; + PyObject *literal[2] = {NULL, NULL}; expr_ty expression = NULL; /* If there's a zero length literal in front of the @@ -5612,31 +5611,34 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str, the f-string, expression will be NULL (unless result == 1, see below). */ int result = fstring_find_literal_and_expr(str, end, raw, recurse_lvl, - &literal, &expression, - c, n); + &literal[0], &literal[1], + &expression, c, n); if (result < 0) return -1; - /* Add the literal, if any. */ - if (!literal) { - /* Do nothing. Just leave last_str alone (and possibly - NULL). */ - } else if (!state->last_str) { - /* Note that the literal can be zero length, if the - input string is "\\\n" or "\\\r", among others. */ - state->last_str = literal; - literal = NULL; - } else { - /* We have a literal, concatenate it. */ - assert(PyUnicode_GET_LENGTH(literal) != 0); - if (FstringParser_ConcatAndDel(state, literal) < 0) - return -1; - literal = NULL; + /* Add the literals, if any. */ + for (int i = 0; i < 2; i++) { + if (!literal[i]) { + /* Do nothing. Just leave last_str alone (and possibly + NULL). */ + } else if (!state->last_str) { + /* Note that the literal can be zero length, if the + input string is "\\\n" or "\\\r", among others. */ + state->last_str = literal[i]; + literal[i] = NULL; + } else { + /* We have a literal, concatenate it. */ + assert(PyUnicode_GET_LENGTH(literal[i]) != 0); + if (FstringParser_ConcatAndDel(state, literal[i]) < 0) + return -1; + literal[i] = NULL; + } } - /* We've dealt with the literal now. It can't be leaked on further + /* We've dealt with the literals now. They can't be leaked on further errors. */ - assert(literal == NULL); + assert(literal[0] == NULL); + assert(literal[1] == NULL); /* See if we should just loop around to get the next literal and expression, while ignoring the expression this diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index f1b991a7c38788..f376e86ddc4c0d 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -665,11 +665,6 @@ append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec) } Py_DECREF(temp_fv_str); - if (e->v.FormattedValue.expr_text) { - /* Use the = for debug text expansion. */ - APPEND_STR("="); - } - if (e->v.FormattedValue.conversion > 0) { switch (e->v.FormattedValue.conversion) { case 'a': diff --git a/Python/compile.c b/Python/compile.c index 425d0d68ac4adc..f1c97bdfe47f07 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3963,12 +3963,6 @@ compiler_formatted_value(struct compiler *c, expr_ty e) int conversion = e->v.FormattedValue.conversion; int oparg; - if (e->v.FormattedValue.expr_text) { - /* Push the text of the expression (which already has the '=' in - it. */ - ADDOP_LOAD_CONST(c, e->v.FormattedValue.expr_text); - } - /* The expression to be formatted. */ VISIT(c, expr, e->v.FormattedValue.value); @@ -3991,11 +3985,6 @@ compiler_formatted_value(struct compiler *c, expr_ty e) /* And push our opcode and oparg */ ADDOP_I(c, FORMAT_VALUE, oparg); - /* If we have expr_text, join the 2 strings on the stack. */ - if (e->v.FormattedValue.expr_text) { - ADDOP_I(c, BUILD_STRING, 2); - } - return 1; } From 23b4b697e5b6cc897696f9c0288c187d2d24bff2 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 27 May 2019 22:56:22 +0300 Subject: [PATCH 133/441] bpo-36889: Merge asyncio streams (GH-13251) https://bugs.python.org/issue36889 --- Lib/asyncio/__init__.py | 38 + Lib/asyncio/streams.py | 1256 +++++++++++++++-- Lib/asyncio/subprocess.py | 35 +- Lib/asyncio/windows_events.py | 2 +- Lib/test/test___all__.py | 36 +- Lib/test/test_asyncio/test_base_events.py | 5 +- Lib/test/test_asyncio/test_buffered_proto.py | 7 +- Lib/test/test_asyncio/test_pep492.py | 4 +- Lib/test/test_asyncio/test_server.py | 10 +- Lib/test/test_asyncio/test_sslproto.py | 37 +- Lib/test/test_asyncio/test_streams.py | 1008 ++++++++++--- Lib/test/test_asyncio/test_windows_events.py | 14 +- .../2019-05-14-12-25-44.bpo-36889.MChPqP.rst | 6 + 13 files changed, 2065 insertions(+), 393 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py index 28c2e2c429f34a..a6a29dbfecd507 100644 --- a/Lib/asyncio/__init__.py +++ b/Lib/asyncio/__init__.py @@ -3,6 +3,7 @@ # flake8: noqa import sys +import warnings # This relies on each of the submodules having an __all__ variable. from .base_events import * @@ -43,3 +44,40 @@ else: from .unix_events import * # pragma: no cover __all__ += unix_events.__all__ + + +__all__ += ('StreamReader', 'StreamWriter', 'StreamReaderProtocol') # deprecated + + +def __getattr__(name): + global StreamReader, StreamWriter, StreamReaderProtocol + if name == 'StreamReader': + warnings.warn("StreamReader is deprecated since Python 3.8 " + "in favor of Stream, and scheduled for removal " + "in Python 3.10", + DeprecationWarning, + stacklevel=2) + from .streams import StreamReader as sr + StreamReader = sr + return StreamReader + if name == 'StreamWriter': + warnings.warn("StreamWriter is deprecated since Python 3.8 " + "in favor of Stream, and scheduled for removal " + "in Python 3.10", + DeprecationWarning, + stacklevel=2) + from .streams import StreamWriter as sw + StreamWriter = sw + return StreamWriter + if name == 'StreamReaderProtocol': + warnings.warn("Using asyncio internal class StreamReaderProtocol " + "is deprecated since Python 3.8 " + " and scheduled for removal " + "in Python 3.10", + DeprecationWarning, + stacklevel=2) + from .streams import StreamReaderProtocol as srp + StreamReaderProtocol = srp + return StreamReaderProtocol + + raise AttributeError(f"module {__name__} has no attribute {name}") diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 2f0cbfdbe852d1..480f1a3fdd74ed 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -1,14 +1,19 @@ __all__ = ( - 'StreamReader', 'StreamWriter', 'StreamReaderProtocol', - 'open_connection', 'start_server') + 'Stream', 'StreamMode', + 'open_connection', 'start_server', + 'connect', 'connect_read_pipe', 'connect_write_pipe', + 'StreamServer') +import enum import socket import sys import warnings import weakref if hasattr(socket, 'AF_UNIX'): - __all__ += ('open_unix_connection', 'start_unix_server') + __all__ += ('open_unix_connection', 'start_unix_server', + 'connect_unix', + 'UnixStreamServer') from . import coroutines from . import events @@ -16,12 +21,134 @@ from . import format_helpers from . import protocols from .log import logger -from .tasks import sleep +from . import tasks _DEFAULT_LIMIT = 2 ** 16 # 64 KiB +class StreamMode(enum.Flag): + READ = enum.auto() + WRITE = enum.auto() + READWRITE = READ | WRITE + + +def _ensure_can_read(mode): + if not mode & StreamMode.READ: + raise RuntimeError("The stream is write-only") + + +def _ensure_can_write(mode): + if not mode & StreamMode.WRITE: + raise RuntimeError("The stream is read-only") + + +class _ContextManagerHelper: + __slots__ = ('_awaitable', '_result') + + def __init__(self, awaitable): + self._awaitable = awaitable + self._result = None + + def __await__(self): + return self._awaitable.__await__() + + async def __aenter__(self): + ret = await self._awaitable + result = await ret.__aenter__() + self._result = result + return result + + async def __aexit__(self, exc_type, exc_val, exc_tb): + return await self._result.__aexit__(exc_type, exc_val, exc_tb) + + +def connect(host=None, port=None, *, + limit=_DEFAULT_LIMIT, + ssl=None, family=0, proto=0, + flags=0, sock=None, local_addr=None, + server_hostname=None, + ssl_handshake_timeout=None, + happy_eyeballs_delay=None, interleave=None): + # Design note: + # Don't use decorator approach but exilicit non-async + # function to fail fast and explicitly + # if passed arguments don't match the function signature + return _ContextManagerHelper(_connect(host, port, limit, + ssl, family, proto, + flags, sock, local_addr, + server_hostname, + ssl_handshake_timeout, + happy_eyeballs_delay, + interleave)) + + +async def _connect(host, port, + limit, + ssl, family, proto, + flags, sock, local_addr, + server_hostname, + ssl_handshake_timeout, + happy_eyeballs_delay, interleave): + loop = events.get_running_loop() + stream = Stream(mode=StreamMode.READWRITE, + limit=limit, + loop=loop, + _asyncio_internal=True) + await loop.create_connection( + lambda: _StreamProtocol(stream, loop=loop, + _asyncio_internal=True), + host, port, + ssl=ssl, family=family, proto=proto, + flags=flags, sock=sock, local_addr=local_addr, + server_hostname=server_hostname, + ssl_handshake_timeout=ssl_handshake_timeout, + happy_eyeballs_delay=happy_eyeballs_delay, interleave=interleave) + return stream + + +def connect_read_pipe(pipe, *, limit=_DEFAULT_LIMIT): + # Design note: + # Don't use decorator approach but explicit non-async + # function to fail fast and explicitly + # if passed arguments don't match the function signature + return _ContextManagerHelper(_connect_read_pipe(pipe, limit)) + + +async def _connect_read_pipe(pipe, limit): + loop = events.get_running_loop() + stream = Stream(mode=StreamMode.READ, + limit=limit, + loop=loop, + _asyncio_internal=True) + await loop.connect_read_pipe( + lambda: _StreamProtocol(stream, loop=loop, + _asyncio_internal=True), + pipe) + return stream + + +def connect_write_pipe(pipe, *, limit=_DEFAULT_LIMIT): + # Design note: + # Don't use decorator approach but explicit non-async + # function to fail fast and explicitly + # if passed arguments don't match the function signature + return _ContextManagerHelper(_connect_write_pipe(pipe, limit)) + + +async def _connect_write_pipe(pipe, limit): + loop = events.get_running_loop() + stream = Stream(mode=StreamMode.WRITE, + limit=limit, + loop=loop, + _asyncio_internal=True) + await loop.connect_write_pipe( + lambda: _StreamProtocol(stream, loop=loop, + _asyncio_internal=True), + pipe) + return stream + + async def open_connection(host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): """A wrapper for create_connection() returning a (reader, writer) pair. @@ -41,16 +168,18 @@ async def open_connection(host=None, port=None, *, StreamReaderProtocol classes, just copy the code -- there's really nothing special here except some convenience.) """ + warnings.warn("open_connection() is deprecated since Python 3.8 " + "in favor of connect(), and scheduled for removal " + "in Python 3.10", + DeprecationWarning, + stacklevel=2) if loop is None: loop = events.get_event_loop() - reader = StreamReader(limit=limit, loop=loop, - _asyncio_internal=True) - protocol = StreamReaderProtocol(reader, loop=loop, - _asyncio_internal=True) + reader = StreamReader(limit=limit, loop=loop) + protocol = StreamReaderProtocol(reader, loop=loop, _asyncio_internal=True) transport, _ = await loop.create_connection( lambda: protocol, host, port, **kwds) - writer = StreamWriter(transport, protocol, reader, loop, - _asyncio_internal=True) + writer = StreamWriter(transport, protocol, reader, loop) return reader, writer @@ -77,12 +206,16 @@ async def start_server(client_connected_cb, host=None, port=None, *, The return value is the same as loop.create_server(), i.e. a Server object which can be used to stop the service. """ + warnings.warn("start_server() is deprecated since Python 3.8 " + "in favor of StreamServer(), and scheduled for removal " + "in Python 3.10", + DeprecationWarning, + stacklevel=2) if loop is None: loop = events.get_event_loop() def factory(): - reader = StreamReader(limit=limit, loop=loop, - _asyncio_internal=True) + reader = StreamReader(limit=limit, loop=loop) protocol = StreamReaderProtocol(reader, client_connected_cb, loop=loop, _asyncio_internal=True) @@ -91,33 +224,258 @@ def factory(): return await loop.create_server(factory, host, port, **kwds) +class _BaseStreamServer: + # Design notes. + # StreamServer and UnixStreamServer are exposed as FINAL classes, + # not function factories. + # async with serve(host, port) as server: + # server.start_serving() + # looks ugly. + # The class doesn't provide API for enumerating connected streams + # It can be a subject for improvements in Python 3.9 + + _server_impl = None + + def __init__(self, client_connected_cb, + /, + limit=_DEFAULT_LIMIT, + shutdown_timeout=60, + _asyncio_internal=False): + if not _asyncio_internal: + raise RuntimeError("_ServerStream is a private asyncio class") + self._client_connected_cb = client_connected_cb + self._limit = limit + self._loop = events.get_running_loop() + self._streams = {} + self._shutdown_timeout = shutdown_timeout + + def __init_subclass__(cls): + if not cls.__module__.startswith('asyncio.'): + raise TypeError(f"asyncio.{cls.__name__} " + "class cannot be inherited from") + + async def bind(self): + if self._server_impl is not None: + return + self._server_impl = await self._bind() + + def is_bound(self): + return self._server_impl is not None + + @property + def sockets(self): + # multiple value for socket bound to both IPv4 and IPv6 families + if self._server_impl is None: + return () + return self._server_impl.sockets + + def is_serving(self): + if self._server_impl is None: + return False + return self._server_impl.is_serving() + + async def start_serving(self): + await self.bind() + await self._server_impl.start_serving() + + async def serve_forever(self): + await self.start_serving() + await self._server_impl.serve_forever() + + async def close(self): + if self._server_impl is None: + return + self._server_impl.close() + streams = list(self._streams.keys()) + active_tasks = list(self._streams.values()) + if streams: + await tasks.wait([stream.close() for stream in streams]) + await self._server_impl.wait_closed() + self._server_impl = None + await self._shutdown_active_tasks(active_tasks) + + async def abort(self): + if self._server_impl is None: + return + self._server_impl.close() + streams = list(self._streams.keys()) + active_tasks = list(self._streams.values()) + if streams: + await tasks.wait([stream.abort() for stream in streams]) + await self._server_impl.wait_closed() + self._server_impl = None + await self._shutdown_active_tasks(active_tasks) + + async def __aenter__(self): + await self.bind() + return self + + async def __aexit__(self, exc_type, exc_value, exc_tb): + await self.close() + + def _attach(self, stream, task): + self._streams[stream] = task + + def _detach(self, stream, task): + del self._streams[stream] + + async def _shutdown_active_tasks(self, active_tasks): + if not active_tasks: + return + # NOTE: tasks finished with exception are reported + # by the Task.__del__() method. + done, pending = await tasks.wait(active_tasks, + timeout=self._shutdown_timeout) + if not pending: + return + for task in pending: + task.cancel() + done, pending = await tasks.wait(pending, + timeout=self._shutdown_timeout) + for task in pending: + self._loop.call_exception_handler({ + "message": (f'{task!r} ignored cancellation request ' + f'from a closing {self!r}'), + "stream_server": self + }) + + def __repr__(self): + ret = [f'{self.__class__.__name__}'] + if self.is_serving(): + ret.append('serving') + if self.sockets: + ret.append(f'sockets={self.sockets!r}') + return '<' + ' '.join(ret) + '>' + + def __del__(self, _warn=warnings.warn): + if self._server_impl is not None: + _warn(f"unclosed stream server {self!r}", + ResourceWarning, source=self) + self._server_impl.close() + + +class StreamServer(_BaseStreamServer): + + def __init__(self, client_connected_cb, /, host=None, port=None, *, + limit=_DEFAULT_LIMIT, + family=socket.AF_UNSPEC, + flags=socket.AI_PASSIVE, sock=None, backlog=100, + ssl=None, reuse_address=None, reuse_port=None, + ssl_handshake_timeout=None, + shutdown_timeout=60): + super().__init__(client_connected_cb, + limit=limit, + shutdown_timeout=shutdown_timeout, + _asyncio_internal=True) + self._host = host + self._port = port + self._family = family + self._flags = flags + self._sock = sock + self._backlog = backlog + self._ssl = ssl + self._reuse_address = reuse_address + self._reuse_port = reuse_port + self._ssl_handshake_timeout = ssl_handshake_timeout + + async def _bind(self): + def factory(): + protocol = _ServerStreamProtocol(self, + self._limit, + self._client_connected_cb, + loop=self._loop, + _asyncio_internal=True) + return protocol + return await self._loop.create_server( + factory, + self._host, + self._port, + start_serving=False, + family=self._family, + flags=self._flags, + sock=self._sock, + backlog=self._backlog, + ssl=self._ssl, + reuse_address=self._reuse_address, + reuse_port=self._reuse_port, + ssl_handshake_timeout=self._ssl_handshake_timeout) + + if hasattr(socket, 'AF_UNIX'): # UNIX Domain Sockets are supported on this platform async def open_unix_connection(path=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): """Similar to `open_connection` but works with UNIX Domain Sockets.""" + warnings.warn("open_unix_connection() is deprecated since Python 3.8 " + "in favor of connect_unix(), and scheduled for removal " + "in Python 3.10", + DeprecationWarning, + stacklevel=2) if loop is None: loop = events.get_event_loop() - reader = StreamReader(limit=limit, loop=loop, - _asyncio_internal=True) + reader = StreamReader(limit=limit, loop=loop) protocol = StreamReaderProtocol(reader, loop=loop, _asyncio_internal=True) transport, _ = await loop.create_unix_connection( lambda: protocol, path, **kwds) - writer = StreamWriter(transport, protocol, reader, loop, - _asyncio_internal=True) + writer = StreamWriter(transport, protocol, reader, loop) return reader, writer + + def connect_unix(path=None, *, + limit=_DEFAULT_LIMIT, + ssl=None, sock=None, + server_hostname=None, + ssl_handshake_timeout=None): + """Similar to `connect()` but works with UNIX Domain Sockets.""" + # Design note: + # Don't use decorator approach but exilicit non-async + # function to fail fast and explicitly + # if passed arguments don't match the function signature + return _ContextManagerHelper(_connect_unix(path, + limit, + ssl, sock, + server_hostname, + ssl_handshake_timeout)) + + + async def _connect_unix(path, + limit, + ssl, sock, + server_hostname, + ssl_handshake_timeout): + """Similar to `connect()` but works with UNIX Domain Sockets.""" + loop = events.get_running_loop() + stream = Stream(mode=StreamMode.READWRITE, + limit=limit, + loop=loop, + _asyncio_internal=True) + await loop.create_unix_connection( + lambda: _StreamProtocol(stream, + loop=loop, + _asyncio_internal=True), + path, + ssl=ssl, + sock=sock, + server_hostname=server_hostname, + ssl_handshake_timeout=ssl_handshake_timeout) + return stream + + async def start_unix_server(client_connected_cb, path=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): """Similar to `start_server` but works with UNIX Domain Sockets.""" + warnings.warn("start_unix_server() is deprecated since Python 3.8 " + "in favor of UnixStreamServer(), and scheduled " + "for removal in Python 3.10", + DeprecationWarning, + stacklevel=2) if loop is None: loop = events.get_event_loop() def factory(): - reader = StreamReader(limit=limit, loop=loop, - _asyncio_internal=True) + reader = StreamReader(limit=limit, loop=loop) protocol = StreamReaderProtocol(reader, client_connected_cb, loop=loop, _asyncio_internal=True) @@ -125,6 +483,42 @@ def factory(): return await loop.create_unix_server(factory, path, **kwds) + class UnixStreamServer(_BaseStreamServer): + + def __init__(self, client_connected_cb, /, path=None, *, + limit=_DEFAULT_LIMIT, + sock=None, + backlog=100, + ssl=None, + ssl_handshake_timeout=None, + shutdown_timeout=60): + super().__init__(client_connected_cb, + limit=limit, + shutdown_timeout=shutdown_timeout, + _asyncio_internal=True) + self._path = path + self._sock = sock + self._backlog = backlog + self._ssl = ssl + self._ssl_handshake_timeout = ssl_handshake_timeout + + async def _bind(self): + def factory(): + protocol = _ServerStreamProtocol(self, + self._limit, + self._client_connected_cb, + loop=self._loop, + _asyncio_internal=True) + return protocol + return await self._loop.create_unix_server( + factory, + self._path, + start_serving=False, + sock=self._sock, + backlog=self._backlog, + ssl=self._ssl, + ssl_handshake_timeout=self._ssl_handshake_timeout) + class FlowControlMixin(protocols.Protocol): """Reusable flow control logic for StreamWriter.drain(). @@ -203,6 +597,8 @@ def _get_close_waiter(self, stream): raise NotImplementedError +# begin legacy stream APIs + class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): """Helper class to adapt between Protocol and StreamReader. @@ -212,105 +608,47 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): call inappropriate methods of the protocol.) """ - _source_traceback = None - def __init__(self, stream_reader, client_connected_cb=None, loop=None, *, _asyncio_internal=False): super().__init__(loop=loop, _asyncio_internal=_asyncio_internal) - if stream_reader is not None: - self._stream_reader_wr = weakref.ref(stream_reader, - self._on_reader_gc) - self._source_traceback = stream_reader._source_traceback - else: - self._stream_reader_wr = None - if client_connected_cb is not None: - # This is a stream created by the `create_server()` function. - # Keep a strong reference to the reader until a connection - # is established. - self._strong_reader = stream_reader - self._reject_connection = False + self._stream_reader = stream_reader self._stream_writer = None - self._transport = None self._client_connected_cb = client_connected_cb self._over_ssl = False self._closed = self._loop.create_future() - def _on_reader_gc(self, wr): - transport = self._transport - if transport is not None: - # connection_made was called - context = { - 'message': ('An open stream object is being garbage ' - 'collected; call "stream.close()" explicitly.') - } - if self._source_traceback: - context['source_traceback'] = self._source_traceback - self._loop.call_exception_handler(context) - transport.abort() - else: - self._reject_connection = True - self._stream_reader_wr = None - - @property - def _stream_reader(self): - if self._stream_reader_wr is None: - return None - return self._stream_reader_wr() - def connection_made(self, transport): - if self._reject_connection: - context = { - 'message': ('An open stream was garbage collected prior to ' - 'establishing network connection; ' - 'call "stream.close()" explicitly.') - } - if self._source_traceback: - context['source_traceback'] = self._source_traceback - self._loop.call_exception_handler(context) - transport.abort() - return - self._transport = transport - reader = self._stream_reader - if reader is not None: - reader.set_transport(transport) + self._stream_reader.set_transport(transport) self._over_ssl = transport.get_extra_info('sslcontext') is not None if self._client_connected_cb is not None: self._stream_writer = StreamWriter(transport, self, - reader, - self._loop, - _asyncio_internal=True) - res = self._client_connected_cb(reader, + self._stream_reader, + self._loop) + res = self._client_connected_cb(self._stream_reader, self._stream_writer) if coroutines.iscoroutine(res): self._loop.create_task(res) - self._strong_reader = None def connection_lost(self, exc): - reader = self._stream_reader - if reader is not None: + if self._stream_reader is not None: if exc is None: - reader.feed_eof() + self._stream_reader.feed_eof() else: - reader.set_exception(exc) + self._stream_reader.set_exception(exc) if not self._closed.done(): if exc is None: self._closed.set_result(None) else: self._closed.set_exception(exc) super().connection_lost(exc) - self._stream_reader_wr = None + self._stream_reader = None self._stream_writer = None - self._transport = None def data_received(self, data): - reader = self._stream_reader - if reader is not None: - reader.feed_data(data) + self._stream_reader.feed_data(data) def eof_received(self): - reader = self._stream_reader - if reader is not None: - reader.feed_eof() + self._stream_reader.feed_eof() if self._over_ssl: # Prevent a warning in SSLProtocol.eof_received: # "returning true from eof_received() @@ -318,9 +656,6 @@ def eof_received(self): return False return True - def _get_close_waiter(self, stream): - return self._closed - def __del__(self): # Prevent reports about unhandled exceptions. # Better than self._closed._log_traceback = False hack @@ -329,13 +664,6 @@ def __del__(self): closed.exception() -def _swallow_unhandled_exception(task): - # Do a trick to suppress unhandled exception - # if stream.write() was used without await and - # stream.drain() was paused and resumed with an exception - task.exception() - - class StreamWriter: """Wraps a Transport. @@ -346,21 +674,13 @@ class StreamWriter: directly. """ - def __init__(self, transport, protocol, reader, loop, - *, _asyncio_internal=False): - if not _asyncio_internal: - warnings.warn(f"{self.__class__} should be instaniated " - "by asyncio internals only, " - "please avoid its creation from user code", - DeprecationWarning) + def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol # drain() expects that the reader has an exception() method assert reader is None or isinstance(reader, StreamReader) self._reader = reader self._loop = loop - self._complete_fut = self._loop.create_future() - self._complete_fut.set_result(None) def __repr__(self): info = [self.__class__.__name__, f'transport={self._transport!r}'] @@ -374,35 +694,9 @@ def transport(self): def write(self, data): self._transport.write(data) - return self._fast_drain() def writelines(self, data): self._transport.writelines(data) - return self._fast_drain() - - def _fast_drain(self): - # The helper tries to use fast-path to return already existing complete future - # object if underlying transport is not paused and actual waiting for writing - # resume is not needed - if self._reader is not None: - # this branch will be simplified after merging reader with writer - exc = self._reader.exception() - if exc is not None: - fut = self._loop.create_future() - fut.set_exception(exc) - return fut - if not self._transport.is_closing(): - if self._protocol._connection_lost: - fut = self._loop.create_future() - fut.set_exception(ConnectionResetError('Connection lost')) - return fut - if not self._protocol._paused: - # fast path, the stream is not paused - # no need to wait for resume signal - return self._complete_fut - ret = self._loop.create_task(self.drain()) - ret.add_done_callback(_swallow_unhandled_exception) - return ret def write_eof(self): return self._transport.write_eof() @@ -411,14 +705,13 @@ def can_write_eof(self): return self._transport.can_write_eof() def close(self): - self._transport.close() - return self._protocol._get_close_waiter(self) + return self._transport.close() def is_closing(self): return self._transport.is_closing() async def wait_closed(self): - await self._protocol._get_close_waiter(self) + await self._protocol._closed def get_extra_info(self, name, default=None): return self._transport.get_extra_info(name, default) @@ -436,25 +729,19 @@ async def drain(self): if exc is not None: raise exc if self._transport.is_closing(): - # Wait for protocol.connection_lost() call - # Raise connection closing error if any, - # ConnectionResetError otherwise - await sleep(0) + # Yield to the event loop so connection_lost() may be + # called. Without this, _drain_helper() would return + # immediately, and code that calls + # write(...); await drain() + # in a loop would never call connection_lost(), so it + # would not see an error when the socket is closed. + await tasks.sleep(0, loop=self._loop) await self._protocol._drain_helper() class StreamReader: - _source_traceback = None - - def __init__(self, limit=_DEFAULT_LIMIT, loop=None, - *, _asyncio_internal=False): - if not _asyncio_internal: - warnings.warn(f"{self.__class__} should be instaniated " - "by asyncio internals only, " - "please avoid its creation from user code", - DeprecationWarning) - + def __init__(self, limit=_DEFAULT_LIMIT, loop=None): # The line length limit is a security feature; # it also doubles as half the buffer limit. @@ -472,9 +759,6 @@ def __init__(self, limit=_DEFAULT_LIMIT, loop=None, self._exception = None self._transport = None self._paused = False - if self._loop.get_debug(): - self._source_traceback = format_helpers.extract_stack( - sys._getframe(1)) def __repr__(self): info = ['StreamReader'] @@ -802,3 +1086,671 @@ async def __anext__(self): if val == b'': raise StopAsyncIteration return val + + +# end legacy stream APIs + + +class _BaseStreamProtocol(FlowControlMixin, protocols.Protocol): + """Helper class to adapt between Protocol and StreamReader. + + (This is a helper class instead of making StreamReader itself a + Protocol subclass, because the StreamReader has other potential + uses, and to prevent the user of the StreamReader to accidentally + call inappropriate methods of the protocol.) + """ + + _stream = None # initialized in derived classes + + def __init__(self, loop=None, + *, _asyncio_internal=False): + super().__init__(loop=loop, _asyncio_internal=_asyncio_internal) + self._transport = None + self._over_ssl = False + self._closed = self._loop.create_future() + + def connection_made(self, transport): + self._transport = transport + self._over_ssl = transport.get_extra_info('sslcontext') is not None + + def connection_lost(self, exc): + stream = self._stream + if stream is not None: + if exc is None: + stream.feed_eof() + else: + stream.set_exception(exc) + if not self._closed.done(): + if exc is None: + self._closed.set_result(None) + else: + self._closed.set_exception(exc) + super().connection_lost(exc) + self._transport = None + + def data_received(self, data): + stream = self._stream + if stream is not None: + stream.feed_data(data) + + def eof_received(self): + stream = self._stream + if stream is not None: + stream.feed_eof() + if self._over_ssl: + # Prevent a warning in SSLProtocol.eof_received: + # "returning true from eof_received() + # has no effect when using ssl" + return False + return True + + def _get_close_waiter(self, stream): + return self._closed + + def __del__(self): + # Prevent reports about unhandled exceptions. + # Better than self._closed._log_traceback = False hack + closed = self._get_close_waiter(self._stream) + if closed.done() and not closed.cancelled(): + closed.exception() + + +class _StreamProtocol(_BaseStreamProtocol): + _source_traceback = None + + def __init__(self, stream, loop=None, + *, _asyncio_internal=False): + super().__init__(loop=loop, _asyncio_internal=_asyncio_internal) + self._source_traceback = stream._source_traceback + self._stream_wr = weakref.ref(stream, self._on_gc) + self._reject_connection = False + + def _on_gc(self, wr): + transport = self._transport + if transport is not None: + # connection_made was called + context = { + 'message': ('An open stream object is being garbage ' + 'collected; call "stream.close()" explicitly.') + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + transport.abort() + else: + self._reject_connection = True + self._stream_wr = None + + @property + def _stream(self): + if self._stream_wr is None: + return None + return self._stream_wr() + + def connection_made(self, transport): + if self._reject_connection: + context = { + 'message': ('An open stream was garbage collected prior to ' + 'establishing network connection; ' + 'call "stream.close()" explicitly.') + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + transport.abort() + return + super().connection_made(transport) + stream = self._stream + if stream is None: + return + stream.set_transport(transport) + stream._protocol = self + + def connection_lost(self, exc): + super().connection_lost(exc) + self._stream_wr = None + + +class _ServerStreamProtocol(_BaseStreamProtocol): + def __init__(self, server, limit, client_connected_cb, loop=None, + *, _asyncio_internal=False): + super().__init__(loop=loop, _asyncio_internal=_asyncio_internal) + assert self._closed + self._client_connected_cb = client_connected_cb + self._limit = limit + self._server = server + self._task = None + + def connection_made(self, transport): + super().connection_made(transport) + stream = Stream(mode=StreamMode.READWRITE, + transport=transport, + protocol=self, + limit=self._limit, + loop=self._loop, + is_server_side=True, + _asyncio_internal=True) + self._stream = stream + # If self._client_connected_cb(self._stream) fails + # the exception is logged by transport + self._task = self._loop.create_task( + self._client_connected_cb(self._stream)) + self._server._attach(stream, self._task) + + def connection_lost(self, exc): + super().connection_lost(exc) + self._server._detach(self._stream, self._task) + self._stream = None + + +class _OptionalAwait: + # The class doesn't create a coroutine + # if not awaited + # It prevents "coroutine is never awaited" message + + __slots___ = ('_method',) + + def __init__(self, method): + self._method = method + + def __await__(self): + return self._method().__await__() + + +class Stream: + """Wraps a Transport. + + This exposes write(), writelines(), [can_]write_eof(), + get_extra_info() and close(). It adds drain() which returns an + optional Future on which you can wait for flow control. It also + adds a transport property which references the Transport + directly. + """ + + _source_traceback = None + + def __init__(self, mode, *, + transport=None, + protocol=None, + loop=None, + limit=_DEFAULT_LIMIT, + is_server_side=False, + _asyncio_internal=False): + if not _asyncio_internal: + warnings.warn(f"{self.__class__} should be instaniated " + "by asyncio internals only, " + "please avoid its creation from user code", + DeprecationWarning) + self._mode = mode + self._transport = transport + self._protocol = protocol + self._is_server_side = is_server_side + + # The line length limit is a security feature; + # it also doubles as half the buffer limit. + + if limit <= 0: + raise ValueError('Limit cannot be <= 0') + + self._limit = limit + if loop is None: + self._loop = events.get_event_loop() + else: + self._loop = loop + self._buffer = bytearray() + self._eof = False # Whether we're done. + self._waiter = None # A future used by _wait_for_data() + self._exception = None + self._paused = False + self._complete_fut = self._loop.create_future() + self._complete_fut.set_result(None) + + if self._loop.get_debug(): + self._source_traceback = format_helpers.extract_stack( + sys._getframe(1)) + + def __repr__(self): + info = [self.__class__.__name__] + info.append(f'mode={self._mode}') + if self._buffer: + info.append(f'{len(self._buffer)} bytes') + if self._eof: + info.append('eof') + if self._limit != _DEFAULT_LIMIT: + info.append(f'limit={self._limit}') + if self._waiter: + info.append(f'waiter={self._waiter!r}') + if self._exception: + info.append(f'exception={self._exception!r}') + if self._transport: + info.append(f'transport={self._transport!r}') + if self._paused: + info.append('paused') + return '<{}>'.format(' '.join(info)) + + @property + def mode(self): + return self._mode + + def is_server_side(self): + return self._is_server_side + + @property + def transport(self): + return self._transport + + def write(self, data): + _ensure_can_write(self._mode) + self._transport.write(data) + return self._fast_drain() + + def writelines(self, data): + _ensure_can_write(self._mode) + self._transport.writelines(data) + return self._fast_drain() + + def _fast_drain(self): + # The helper tries to use fast-path to return already existing + # complete future object if underlying transport is not paused + #and actual waiting for writing resume is not needed + exc = self.exception() + if exc is not None: + fut = self._loop.create_future() + fut.set_exception(exc) + return fut + if not self._transport.is_closing(): + if self._protocol._connection_lost: + fut = self._loop.create_future() + fut.set_exception(ConnectionResetError('Connection lost')) + return fut + if not self._protocol._paused: + # fast path, the stream is not paused + # no need to wait for resume signal + return self._complete_fut + return _OptionalAwait(self.drain) + + def write_eof(self): + _ensure_can_write(self._mode) + return self._transport.write_eof() + + def can_write_eof(self): + if not self._mode.is_write(): + return False + return self._transport.can_write_eof() + + def close(self): + self._transport.close() + return _OptionalAwait(self.wait_closed) + + def is_closing(self): + return self._transport.is_closing() + + async def abort(self): + self._transport.abort() + await self.wait_closed() + + async def wait_closed(self): + await self._protocol._get_close_waiter(self) + + def get_extra_info(self, name, default=None): + return self._transport.get_extra_info(name, default) + + async def drain(self): + """Flush the write buffer. + + The intended use is to write + + w.write(data) + await w.drain() + """ + _ensure_can_write(self._mode) + exc = self.exception() + if exc is not None: + raise exc + if self._transport.is_closing(): + # Wait for protocol.connection_lost() call + # Raise connection closing error if any, + # ConnectionResetError otherwise + await tasks.sleep(0) + await self._protocol._drain_helper() + + async def sendfile(self, file, offset=0, count=None, *, fallback=True): + await self.drain() # check for stream mode and exceptions + return await self._loop.sendfile(self._transport, file, + offset, count, fallback=fallback) + + async def start_tls(self, sslcontext, *, + server_hostname=None, + ssl_handshake_timeout=None): + await self.drain() # check for stream mode and exceptions + transport = await self._loop.start_tls( + self._transport, self._protocol, sslcontext, + server_side=self._is_server_side, + server_hostname=server_hostname, + ssl_handshake_timeout=ssl_handshake_timeout) + self._transport = transport + self._protocol._transport = transport + self._protocol._over_ssl = True + + def exception(self): + return self._exception + + def set_exception(self, exc): + self._exception = exc + + waiter = self._waiter + if waiter is not None: + self._waiter = None + if not waiter.cancelled(): + waiter.set_exception(exc) + + def _wakeup_waiter(self): + """Wakeup read*() functions waiting for data or EOF.""" + waiter = self._waiter + if waiter is not None: + self._waiter = None + if not waiter.cancelled(): + waiter.set_result(None) + + def set_transport(self, transport): + if transport is self._transport: + return + assert self._transport is None, 'Transport already set' + self._transport = transport + + def _maybe_resume_transport(self): + if self._paused and len(self._buffer) <= self._limit: + self._paused = False + self._transport.resume_reading() + + def feed_eof(self): + self._eof = True + self._wakeup_waiter() + + def at_eof(self): + """Return True if the buffer is empty and 'feed_eof' was called.""" + return self._eof and not self._buffer + + def feed_data(self, data): + _ensure_can_read(self._mode) + assert not self._eof, 'feed_data after feed_eof' + + if not data: + return + + self._buffer.extend(data) + self._wakeup_waiter() + + if (self._transport is not None and + not self._paused and + len(self._buffer) > 2 * self._limit): + try: + self._transport.pause_reading() + except NotImplementedError: + # The transport can't be paused. + # We'll just have to buffer all data. + # Forget the transport so we don't keep trying. + self._transport = None + else: + self._paused = True + + async def _wait_for_data(self, func_name): + """Wait until feed_data() or feed_eof() is called. + + If stream was paused, automatically resume it. + """ + # StreamReader uses a future to link the protocol feed_data() method + # to a read coroutine. Running two read coroutines at the same time + # would have an unexpected behaviour. It would not possible to know + # which coroutine would get the next data. + if self._waiter is not None: + raise RuntimeError( + f'{func_name}() called while another coroutine is ' + f'already waiting for incoming data') + + assert not self._eof, '_wait_for_data after EOF' + + # Waiting for data while paused will make deadlock, so prevent it. + # This is essential for readexactly(n) for case when n > self._limit. + if self._paused: + self._paused = False + self._transport.resume_reading() + + self._waiter = self._loop.create_future() + try: + await self._waiter + finally: + self._waiter = None + + async def readline(self): + """Read chunk of data from the stream until newline (b'\n') is found. + + On success, return chunk that ends with newline. If only partial + line can be read due to EOF, return incomplete line without + terminating newline. When EOF was reached while no bytes read, empty + bytes object is returned. + + If limit is reached, ValueError will be raised. In that case, if + newline was found, complete line including newline will be removed + from internal buffer. Else, internal buffer will be cleared. Limit is + compared against part of the line without newline. + + If stream was paused, this function will automatically resume it if + needed. + """ + _ensure_can_read(self._mode) + sep = b'\n' + seplen = len(sep) + try: + line = await self.readuntil(sep) + except exceptions.IncompleteReadError as e: + return e.partial + except exceptions.LimitOverrunError as e: + if self._buffer.startswith(sep, e.consumed): + del self._buffer[:e.consumed + seplen] + else: + self._buffer.clear() + self._maybe_resume_transport() + raise ValueError(e.args[0]) + return line + + async def readuntil(self, separator=b'\n'): + """Read data from the stream until ``separator`` is found. + + On success, the data and separator will be removed from the + internal buffer (consumed). Returned data will include the + separator at the end. + + Configured stream limit is used to check result. Limit sets the + maximal length of data that can be returned, not counting the + separator. + + If an EOF occurs and the complete separator is still not found, + an IncompleteReadError exception will be raised, and the internal + buffer will be reset. The IncompleteReadError.partial attribute + may contain the separator partially. + + If the data cannot be read because of over limit, a + LimitOverrunError exception will be raised, and the data + will be left in the internal buffer, so it can be read again. + """ + _ensure_can_read(self._mode) + seplen = len(separator) + if seplen == 0: + raise ValueError('Separator should be at least one-byte string') + + if self._exception is not None: + raise self._exception + + # Consume whole buffer except last bytes, which length is + # one less than seplen. Let's check corner cases with + # separator='SEPARATOR': + # * we have received almost complete separator (without last + # byte). i.e buffer='some textSEPARATO'. In this case we + # can safely consume len(separator) - 1 bytes. + # * last byte of buffer is first byte of separator, i.e. + # buffer='abcdefghijklmnopqrS'. We may safely consume + # everything except that last byte, but this require to + # analyze bytes of buffer that match partial separator. + # This is slow and/or require FSM. For this case our + # implementation is not optimal, since require rescanning + # of data that is known to not belong to separator. In + # real world, separator will not be so long to notice + # performance problems. Even when reading MIME-encoded + # messages :) + + # `offset` is the number of bytes from the beginning of the buffer + # where there is no occurrence of `separator`. + offset = 0 + + # Loop until we find `separator` in the buffer, exceed the buffer size, + # or an EOF has happened. + while True: + buflen = len(self._buffer) + + # Check if we now have enough data in the buffer for `separator` to + # fit. + if buflen - offset >= seplen: + isep = self._buffer.find(separator, offset) + + if isep != -1: + # `separator` is in the buffer. `isep` will be used later + # to retrieve the data. + break + + # see upper comment for explanation. + offset = buflen + 1 - seplen + if offset > self._limit: + raise exceptions.LimitOverrunError( + 'Separator is not found, and chunk exceed the limit', + offset) + + # Complete message (with full separator) may be present in buffer + # even when EOF flag is set. This may happen when the last chunk + # adds data which makes separator be found. That's why we check for + # EOF *ater* inspecting the buffer. + if self._eof: + chunk = bytes(self._buffer) + self._buffer.clear() + raise exceptions.IncompleteReadError(chunk, None) + + # _wait_for_data() will resume reading if stream was paused. + await self._wait_for_data('readuntil') + + if isep > self._limit: + raise exceptions.LimitOverrunError( + 'Separator is found, but chunk is longer than limit', isep) + + chunk = self._buffer[:isep + seplen] + del self._buffer[:isep + seplen] + self._maybe_resume_transport() + return bytes(chunk) + + async def read(self, n=-1): + """Read up to `n` bytes from the stream. + + If n is not provided, or set to -1, read until EOF and return all read + bytes. If the EOF was received and the internal buffer is empty, return + an empty bytes object. + + If n is zero, return empty bytes object immediately. + + If n is positive, this function try to read `n` bytes, and may return + less or equal bytes than requested, but at least one byte. If EOF was + received before any byte is read, this function returns empty byte + object. + + Returned value is not limited with limit, configured at stream + creation. + + If stream was paused, this function will automatically resume it if + needed. + """ + _ensure_can_read(self._mode) + + if self._exception is not None: + raise self._exception + + if n == 0: + return b'' + + if n < 0: + # This used to just loop creating a new waiter hoping to + # collect everything in self._buffer, but that would + # deadlock if the subprocess sends more than self.limit + # bytes. So just call self.read(self._limit) until EOF. + blocks = [] + while True: + block = await self.read(self._limit) + if not block: + break + blocks.append(block) + return b''.join(blocks) + + if not self._buffer and not self._eof: + await self._wait_for_data('read') + + # This will work right even if buffer is less than n bytes + data = bytes(self._buffer[:n]) + del self._buffer[:n] + + self._maybe_resume_transport() + return data + + async def readexactly(self, n): + """Read exactly `n` bytes. + + Raise an IncompleteReadError if EOF is reached before `n` bytes can be + read. The IncompleteReadError.partial attribute of the exception will + contain the partial read bytes. + + if n is zero, return empty bytes object. + + Returned value is not limited with limit, configured at stream + creation. + + If stream was paused, this function will automatically resume it if + needed. + """ + _ensure_can_read(self._mode) + if n < 0: + raise ValueError('readexactly size can not be less than zero') + + if self._exception is not None: + raise self._exception + + if n == 0: + return b'' + + while len(self._buffer) < n: + if self._eof: + incomplete = bytes(self._buffer) + self._buffer.clear() + raise exceptions.IncompleteReadError(incomplete, n) + + await self._wait_for_data('readexactly') + + if len(self._buffer) == n: + data = bytes(self._buffer) + self._buffer.clear() + else: + data = bytes(self._buffer[:n]) + del self._buffer[:n] + self._maybe_resume_transport() + return data + + def __aiter__(self): + _ensure_can_read(self._mode) + return self + + async def __anext__(self): + val = await self.readline() + if val == b'': + raise StopAsyncIteration + return val + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.close() diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py index d34b6118fdcf72..e6bec71d6c7dac 100644 --- a/Lib/asyncio/subprocess.py +++ b/Lib/asyncio/subprocess.py @@ -27,6 +27,8 @@ def __init__(self, limit, loop, *, _asyncio_internal=False): self._process_exited = False self._pipe_fds = [] self._stdin_closed = self._loop.create_future() + self._stdout_closed = self._loop.create_future() + self._stderr_closed = self._loop.create_future() def __repr__(self): info = [self.__class__.__name__] @@ -40,30 +42,35 @@ def __repr__(self): def connection_made(self, transport): self._transport = transport - stdout_transport = transport.get_pipe_transport(1) if stdout_transport is not None: - self.stdout = streams.StreamReader(limit=self._limit, - loop=self._loop, - _asyncio_internal=True) + self.stdout = streams.Stream(mode=streams.StreamMode.READ, + transport=stdout_transport, + protocol=self, + limit=self._limit, + loop=self._loop, + _asyncio_internal=True) self.stdout.set_transport(stdout_transport) self._pipe_fds.append(1) stderr_transport = transport.get_pipe_transport(2) if stderr_transport is not None: - self.stderr = streams.StreamReader(limit=self._limit, - loop=self._loop, - _asyncio_internal=True) + self.stderr = streams.Stream(mode=streams.StreamMode.READ, + transport=stderr_transport, + protocol=self, + limit=self._limit, + loop=self._loop, + _asyncio_internal=True) self.stderr.set_transport(stderr_transport) self._pipe_fds.append(2) stdin_transport = transport.get_pipe_transport(0) if stdin_transport is not None: - self.stdin = streams.StreamWriter(stdin_transport, - protocol=self, - reader=None, - loop=self._loop, - _asyncio_internal=True) + self.stdin = streams.Stream(mode=streams.StreamMode.WRITE, + transport=stdin_transport, + protocol=self, + loop=self._loop, + _asyncio_internal=True) def pipe_data_received(self, fd, data): if fd == 1: @@ -114,6 +121,10 @@ def _maybe_close_transport(self): def _get_close_waiter(self, stream): if stream is self.stdin: return self._stdin_closed + elif stream is self.stdout: + return self._stdout_closed + elif stream is self.stderr: + return self._stderr_closed class Process: diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index b5b2e24c5ba4f3..61b40ba52a6486 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -607,7 +607,7 @@ async def connect_pipe(self, address): # ConnectPipe() failed with ERROR_PIPE_BUSY: retry later delay = min(delay * 2, CONNECT_PIPE_MAX_DELAY) - await tasks.sleep(delay, loop=self._loop) + await tasks.sleep(delay) return windows_utils.PipeHandle(handle) diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index f6e82eb64ab025..c077881511b8ce 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -30,21 +30,27 @@ def check_all(self, modname): raise NoAll(modname) names = {} with self.subTest(module=modname): - try: - exec("from %s import *" % modname, names) - except Exception as e: - # Include the module name in the exception string - self.fail("__all__ failure in {}: {}: {}".format( - modname, e.__class__.__name__, e)) - if "__builtins__" in names: - del names["__builtins__"] - if '__annotations__' in names: - del names['__annotations__'] - keys = set(names) - all_list = sys.modules[modname].__all__ - all_set = set(all_list) - self.assertCountEqual(all_set, all_list, "in module {}".format(modname)) - self.assertEqual(keys, all_set, "in module {}".format(modname)) + with support.check_warnings( + ("", DeprecationWarning), + ("", ResourceWarning), + quiet=True): + try: + exec("from %s import *" % modname, names) + except Exception as e: + # Include the module name in the exception string + self.fail("__all__ failure in {}: {}: {}".format( + modname, e.__class__.__name__, e)) + if "__builtins__" in names: + del names["__builtins__"] + if '__annotations__' in names: + del names['__annotations__'] + if "__warningregistry__" in names: + del names["__warningregistry__"] + keys = set(names) + all_list = sys.modules[modname].__all__ + all_set = set(all_list) + self.assertCountEqual(all_set, all_list, "in module {}".format(modname)) + self.assertEqual(keys, all_set, "in module {}".format(modname)) def walk_modules(self, basedir, modpath): for fn in sorted(os.listdir(basedir)): diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 31018c5c563637..02a97c60ac1a93 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1152,8 +1152,9 @@ def test_create_server_stream_bittype(self): @unittest.skipUnless(hasattr(socket, 'AF_INET6'), 'no IPv6 support') def test_create_server_ipv6(self): async def main(): - srv = await asyncio.start_server( - lambda: None, '::1', 0, loop=self.loop) + with self.assertWarns(DeprecationWarning): + srv = await asyncio.start_server( + lambda: None, '::1', 0, loop=self.loop) try: self.assertGreater(len(srv.sockets), 0) finally: diff --git a/Lib/test/test_asyncio/test_buffered_proto.py b/Lib/test/test_asyncio/test_buffered_proto.py index f24e363ebfcfa3..b1531fb9343f5e 100644 --- a/Lib/test/test_asyncio/test_buffered_proto.py +++ b/Lib/test/test_asyncio/test_buffered_proto.py @@ -58,9 +58,10 @@ async def on_server_client(reader, writer): writer.close() await writer.wait_closed() - srv = self.loop.run_until_complete( - asyncio.start_server( - on_server_client, '127.0.0.1', 0)) + with self.assertWarns(DeprecationWarning): + srv = self.loop.run_until_complete( + asyncio.start_server( + on_server_client, '127.0.0.1', 0)) addr = srv.sockets[0].getsockname() self.loop.run_until_complete( diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py index 297a3b3901d631..11c0ce495d5261 100644 --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -94,7 +94,9 @@ class StreamReaderTests(BaseTest): def test_readline(self): DATA = b'line1\nline2\nline3' - stream = asyncio.StreamReader(loop=self.loop, _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(DATA) stream.feed_eof() diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py index 4e758ad12e600e..0e38e6c8ecd4c2 100644 --- a/Lib/test/test_asyncio/test_server.py +++ b/Lib/test/test_asyncio/test_server.py @@ -46,8 +46,9 @@ async def main(srv): async with srv: await srv.serve_forever() - srv = self.loop.run_until_complete(asyncio.start_server( - serve, support.HOSTv4, 0, loop=self.loop, start_serving=False)) + with self.assertWarns(DeprecationWarning): + srv = self.loop.run_until_complete(asyncio.start_server( + serve, support.HOSTv4, 0, loop=self.loop, start_serving=False)) self.assertFalse(srv.is_serving()) @@ -102,8 +103,9 @@ async def main(srv): await srv.serve_forever() with test_utils.unix_socket_path() as addr: - srv = self.loop.run_until_complete(asyncio.start_unix_server( - serve, addr, loop=self.loop, start_serving=False)) + with self.assertWarns(DeprecationWarning): + srv = self.loop.run_until_complete(asyncio.start_unix_server( + serve, addr, loop=self.loop, start_serving=False)) main_task = self.loop.create_task(main(srv)) diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 079b25585566b1..4215abf5d8630b 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -649,12 +649,13 @@ def server(sock): sock.close() async def client(addr): - reader, writer = await asyncio.open_connection( - *addr, - ssl=client_sslctx, - server_hostname='', - loop=self.loop, - ssl_handshake_timeout=1.0) + with self.assertWarns(DeprecationWarning): + reader, writer = await asyncio.open_connection( + *addr, + ssl=client_sslctx, + server_hostname='', + loop=self.loop, + ssl_handshake_timeout=1.0) with self.tcp_server(server, max_clients=1, @@ -688,12 +689,13 @@ def server(sock): sock.close() async def client(addr): - reader, writer = await asyncio.open_connection( - *addr, - ssl=client_sslctx, - server_hostname='', - loop=self.loop, - ssl_handshake_timeout=1.0) + with self.assertWarns(DeprecationWarning): + reader, writer = await asyncio.open_connection( + *addr, + ssl=client_sslctx, + server_hostname='', + loop=self.loop, + ssl_handshake_timeout=1.0) with self.tcp_server(server, max_clients=1, @@ -724,11 +726,12 @@ def server(sock): sock.close() async def client(addr): - reader, writer = await asyncio.open_connection( - *addr, - ssl=client_sslctx, - server_hostname='', - loop=self.loop) + with self.assertWarns(DeprecationWarning): + reader, writer = await asyncio.open_connection( + *addr, + ssl=client_sslctx, + server_hostname='', + loop=self.loop) self.assertEqual(await reader.readline(), b'A\n') writer.write(b'B') diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index fed609816daca8..df3d7e7dfa455c 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -1,6 +1,8 @@ """Tests for streams.py.""" +import contextlib import gc +import io import os import queue import pickle @@ -16,6 +18,7 @@ ssl = None import asyncio +from asyncio.streams import _StreamProtocol, _ensure_can_read, _ensure_can_write from test.test_asyncio import utils as test_utils @@ -23,6 +26,24 @@ def tearDownModule(): asyncio.set_event_loop_policy(None) +class StreamModeTests(unittest.TestCase): + def test__ensure_can_read_ok(self): + self.assertIsNone(_ensure_can_read(asyncio.StreamMode.READ)) + self.assertIsNone(_ensure_can_read(asyncio.StreamMode.READWRITE)) + + def test__ensure_can_read_fail(self): + with self.assertRaisesRegex(RuntimeError, "The stream is write-only"): + _ensure_can_read(asyncio.StreamMode.WRITE) + + def test__ensure_can_write_ok(self): + self.assertIsNone(_ensure_can_write(asyncio.StreamMode.WRITE)) + self.assertIsNone(_ensure_can_write(asyncio.StreamMode.READWRITE)) + + def test__ensure_can_write_fail(self): + with self.assertRaisesRegex(RuntimeError, "The stream is read-only"): + _ensure_can_write(asyncio.StreamMode.READ) + + class StreamTests(test_utils.TestCase): DATA = b'line1\nline2\nline3\n' @@ -42,13 +63,15 @@ def tearDown(self): @mock.patch('asyncio.streams.events') def test_ctor_global_loop(self, m_events): - stream = asyncio.StreamReader(_asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + _asyncio_internal=True) self.assertIs(stream._loop, m_events.get_event_loop.return_value) def _basetest_open_connection(self, open_connection_fut): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) - reader, writer = self.loop.run_until_complete(open_connection_fut) + with self.assertWarns(DeprecationWarning): + reader, writer = self.loop.run_until_complete(open_connection_fut) writer.write(b'GET / HTTP/1.0\r\n\r\n') f = reader.readline() data = self.loop.run_until_complete(f) @@ -76,7 +99,9 @@ def _basetest_open_connection_no_loop_ssl(self, open_connection_fut): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) try: - reader, writer = self.loop.run_until_complete(open_connection_fut) + with self.assertWarns(DeprecationWarning): + reader, writer = self.loop.run_until_complete( + open_connection_fut) finally: asyncio.set_event_loop(None) writer.write(b'GET / HTTP/1.0\r\n\r\n') @@ -112,7 +137,8 @@ def test_open_unix_connection_no_loop_ssl(self): def _basetest_open_connection_error(self, open_connection_fut): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) - reader, writer = self.loop.run_until_complete(open_connection_fut) + with self.assertWarns(DeprecationWarning): + reader, writer = self.loop.run_until_complete(open_connection_fut) writer._protocol.connection_lost(ZeroDivisionError()) f = reader.read() with self.assertRaises(ZeroDivisionError): @@ -135,23 +161,26 @@ def test_open_unix_connection_error(self): self._basetest_open_connection_error(conn_fut) def test_feed_empty_data(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'') self.assertEqual(b'', stream._buffer) def test_feed_nonempty_data(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) self.assertEqual(self.DATA, stream._buffer) def test_read_zero(self): # Read zero bytes. - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.read(0)) @@ -160,8 +189,9 @@ def test_read_zero(self): def test_read(self): # Read bytes. - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) read_task = asyncio.Task(stream.read(30), loop=self.loop) def cb(): @@ -174,8 +204,9 @@ def cb(): def test_read_line_breaks(self): # Read bytes without line breaks. - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line1') stream.feed_data(b'line2') @@ -186,8 +217,9 @@ def test_read_line_breaks(self): def test_read_eof(self): # Read bytes, stop at eof. - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) read_task = asyncio.Task(stream.read(1024), loop=self.loop) def cb(): @@ -200,8 +232,9 @@ def cb(): def test_read_until_eof(self): # Read all bytes until eof. - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) read_task = asyncio.Task(stream.read(-1), loop=self.loop) def cb(): @@ -216,8 +249,9 @@ def cb(): self.assertEqual(b'', stream._buffer) def test_read_exception(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.read(2)) @@ -229,16 +263,19 @@ def test_read_exception(self): def test_invalid_limit(self): with self.assertRaisesRegex(ValueError, 'imit'): - asyncio.StreamReader(limit=0, loop=self.loop, - _asyncio_internal=True) + asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=0, loop=self.loop, + _asyncio_internal=True) with self.assertRaisesRegex(ValueError, 'imit'): - asyncio.StreamReader(limit=-1, loop=self.loop, - _asyncio_internal=True) + asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=-1, loop=self.loop, + _asyncio_internal=True) def test_read_limit(self): - stream = asyncio.StreamReader(limit=3, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'chunk') data = self.loop.run_until_complete(stream.read(5)) self.assertEqual(b'chunk', data) @@ -247,8 +284,9 @@ def test_read_limit(self): def test_readline(self): # Read one line. 'readline' will need to wait for the data # to come from 'cb' - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'chunk1 ') read_task = asyncio.Task(stream.readline(), loop=self.loop) @@ -263,11 +301,12 @@ def cb(): self.assertEqual(b' chunk4', stream._buffer) def test_readline_limit_with_existing_data(self): - # Read one line. The data is in StreamReader's buffer + # Read one line. The data is in Stream's buffer # before the event loop is run. - stream = asyncio.StreamReader(limit=3, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'li') stream.feed_data(b'ne1\nline2\n') @@ -276,8 +315,9 @@ def test_readline_limit_with_existing_data(self): # The buffer should contain the remaining data after exception self.assertEqual(b'line2\n', stream._buffer) - stream = asyncio.StreamReader(limit=3, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'li') stream.feed_data(b'ne1') stream.feed_data(b'li') @@ -292,8 +332,9 @@ def test_readline_limit_with_existing_data(self): self.assertEqual(b'', stream._buffer) def test_at_eof(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) self.assertFalse(stream.at_eof()) stream.feed_data(b'some data\n') @@ -308,11 +349,12 @@ def test_at_eof(self): self.assertTrue(stream.at_eof()) def test_readline_limit(self): - # Read one line. StreamReaders are fed with data after + # Read one line. Streams are fed with data after # their 'readline' methods are called. - stream = asyncio.StreamReader(limit=7, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=7, loop=self.loop, + _asyncio_internal=True) def cb(): stream.feed_data(b'chunk1') stream.feed_data(b'chunk2') @@ -326,8 +368,9 @@ def cb(): # a ValueError it should be empty. self.assertEqual(b'', stream._buffer) - stream = asyncio.StreamReader(limit=7, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=7, loop=self.loop, + _asyncio_internal=True) def cb(): stream.feed_data(b'chunk1') stream.feed_data(b'chunk2\n') @@ -340,8 +383,9 @@ def cb(): self.assertEqual(b'chunk3\n', stream._buffer) # check strictness of the limit - stream = asyncio.StreamReader(limit=7, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=7, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'1234567\n') line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'1234567\n', line) @@ -360,8 +404,9 @@ def cb(): def test_readline_nolimit_nowait(self): # All needed data for the first 'readline' call will be # in the buffer. - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA[:6]) stream.feed_data(self.DATA[6:]) @@ -371,8 +416,9 @@ def test_readline_nolimit_nowait(self): self.assertEqual(b'line2\nline3\n', stream._buffer) def test_readline_eof(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'some data') stream.feed_eof() @@ -380,16 +426,18 @@ def test_readline_eof(self): self.assertEqual(b'some data', line) def test_readline_empty_eof(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_eof() line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'', line) def test_readline_read_byte_count(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) self.loop.run_until_complete(stream.readline()) @@ -400,8 +448,9 @@ def test_readline_read_byte_count(self): self.assertEqual(b'ine3\n', stream._buffer) def test_readline_exception(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readline()) @@ -413,14 +462,16 @@ def test_readline_exception(self): self.assertEqual(b'', stream._buffer) def test_readuntil_separator(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) with self.assertRaisesRegex(ValueError, 'Separator should be'): self.loop.run_until_complete(stream.readuntil(separator=b'')) def test_readuntil_multi_chunks(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'lineAAA') data = self.loop.run_until_complete(stream.readuntil(separator=b'AAA')) @@ -438,8 +489,9 @@ def test_readuntil_multi_chunks(self): self.assertEqual(b'xxx', stream._buffer) def test_readuntil_multi_chunks_1(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'QWEaa') stream.feed_data(b'XYaa') @@ -474,8 +526,9 @@ def test_readuntil_multi_chunks_1(self): self.assertEqual(b'', stream._buffer) def test_readuntil_eof(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'some dataAA') stream.feed_eof() @@ -486,8 +539,9 @@ def test_readuntil_eof(self): self.assertEqual(b'', stream._buffer) def test_readuntil_limit_found_sep(self): - stream = asyncio.StreamReader(loop=self.loop, limit=3, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, limit=3, + _asyncio_internal=True) stream.feed_data(b'some dataAA') with self.assertRaisesRegex(asyncio.LimitOverrunError, @@ -505,8 +559,9 @@ def test_readuntil_limit_found_sep(self): def test_readexactly_zero_or_less(self): # Read exact number of bytes (zero or less). - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.readexactly(0)) @@ -519,8 +574,9 @@ def test_readexactly_zero_or_less(self): def test_readexactly(self): # Read exact number of bytes. - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) n = 2 * len(self.DATA) read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) @@ -536,8 +592,9 @@ def cb(): self.assertEqual(self.DATA, stream._buffer) def test_readexactly_limit(self): - stream = asyncio.StreamReader(limit=3, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + limit=3, loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'chunk') data = self.loop.run_until_complete(stream.readexactly(5)) self.assertEqual(b'chunk', data) @@ -545,8 +602,9 @@ def test_readexactly_limit(self): def test_readexactly_eof(self): # Read exact number of bytes (eof). - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) n = 2 * len(self.DATA) read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) @@ -564,8 +622,9 @@ def cb(): self.assertEqual(b'', stream._buffer) def test_readexactly_exception(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readexactly(2)) @@ -576,8 +635,9 @@ def test_readexactly_exception(self): ValueError, self.loop.run_until_complete, stream.readexactly(2)) def test_exception(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) self.assertIsNone(stream.exception()) exc = ValueError() @@ -585,8 +645,9 @@ def test_exception(self): self.assertIs(stream.exception(), exc) def test_exception_waiter(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) async def set_err(): stream.set_exception(ValueError()) @@ -599,8 +660,9 @@ async def set_err(): self.assertRaises(ValueError, t1.result) def test_exception_cancel(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) t = asyncio.Task(stream.readline(), loop=self.loop) test_utils.run_briefly(self.loop) @@ -655,8 +717,9 @@ def stop(self): self.server = None async def client(addr): - reader, writer = await asyncio.open_connection( - *addr, loop=self.loop) + with self.assertWarns(DeprecationWarning): + reader, writer = await asyncio.open_connection( + *addr, loop=self.loop) # send a line writer.write(b"hello world!\n") # read it back @@ -670,7 +733,8 @@ async def client(addr): # test the server variant with a coroutine as client handler server = MyServer(self.loop) - addr = server.start() + with self.assertWarns(DeprecationWarning): + addr = server.start() msg = self.loop.run_until_complete(asyncio.Task(client(addr), loop=self.loop)) server.stop() @@ -678,7 +742,8 @@ async def client(addr): # test the server variant with a callback as client handler server = MyServer(self.loop) - addr = server.start_callback() + with self.assertWarns(DeprecationWarning): + addr = server.start_callback() msg = self.loop.run_until_complete(asyncio.Task(client(addr), loop=self.loop)) server.stop() @@ -726,8 +791,9 @@ def stop(self): self.server = None async def client(path): - reader, writer = await asyncio.open_unix_connection( - path, loop=self.loop) + with self.assertWarns(DeprecationWarning): + reader, writer = await asyncio.open_unix_connection( + path, loop=self.loop) # send a line writer.write(b"hello world!\n") # read it back @@ -742,7 +808,8 @@ async def client(path): # test the server variant with a coroutine as client handler with test_utils.unix_socket_path() as path: server = MyServer(self.loop, path) - server.start() + with self.assertWarns(DeprecationWarning): + server.start() msg = self.loop.run_until_complete(asyncio.Task(client(path), loop=self.loop)) server.stop() @@ -751,7 +818,8 @@ async def client(path): # test the server variant with a callback as client handler with test_utils.unix_socket_path() as path: server = MyServer(self.loop, path) - server.start_callback() + with self.assertWarns(DeprecationWarning): + server.start_callback() msg = self.loop.run_until_complete(asyncio.Task(client(path), loop=self.loop)) server.stop() @@ -763,7 +831,7 @@ async def client(path): def test_read_all_from_pipe_reader(self): # See asyncio issue 168. This test is derived from the example # subprocess_attach_read_pipe.py, but we configure the - # StreamReader's limit so that twice it is less than the size + # Stream's limit so that twice it is less than the size # of the data writter. Also we must explicitly attach a child # watcher to the event loop. @@ -777,10 +845,11 @@ def test_read_all_from_pipe_reader(self): args = [sys.executable, '-c', code, str(wfd)] pipe = open(rfd, 'rb', 0) - reader = asyncio.StreamReader(loop=self.loop, limit=1, - _asyncio_internal=True) - protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, limit=1, + _asyncio_internal=True) + protocol = _StreamProtocol(stream, loop=self.loop, + _asyncio_internal=True) transport, _ = self.loop.run_until_complete( self.loop.connect_read_pipe(lambda: protocol, pipe)) @@ -797,29 +866,30 @@ def test_read_all_from_pipe_reader(self): asyncio.set_child_watcher(None) os.close(wfd) - data = self.loop.run_until_complete(reader.read(-1)) + data = self.loop.run_until_complete(stream.read(-1)) self.assertEqual(data, b'data') def test_streamreader_constructor(self): self.addCleanup(asyncio.set_event_loop, None) asyncio.set_event_loop(self.loop) - # asyncio issue #184: Ensure that StreamReaderProtocol constructor + # asyncio issue #184: Ensure that _StreamProtocol constructor # retrieves the current loop if the loop parameter is not set - reader = asyncio.StreamReader(_asyncio_internal=True) + reader = asyncio.Stream(mode=asyncio.StreamMode.READ, + _asyncio_internal=True) self.assertIs(reader._loop, self.loop) def test_streamreaderprotocol_constructor(self): self.addCleanup(asyncio.set_event_loop, None) asyncio.set_event_loop(self.loop) - # asyncio issue #184: Ensure that StreamReaderProtocol constructor + # asyncio issue #184: Ensure that _StreamProtocol constructor # retrieves the current loop if the loop parameter is not set - reader = mock.Mock() - protocol = asyncio.StreamReaderProtocol(reader, _asyncio_internal=True) + stream = mock.Mock() + protocol = _StreamProtocol(stream, _asyncio_internal=True) self.assertIs(protocol._loop, self.loop) - def test_drain_raises(self): + def test_drain_raises_deprecated(self): # See http://bugs.python.org/issue25441 # This test should not use asyncio for the mock server; the @@ -833,15 +903,16 @@ def test_drain_raises(self): def server(): # Runs in a separate thread. - with socket.create_server(('localhost', 0)) as sock: + with socket.create_server(('127.0.0.1', 0)) as sock: addr = sock.getsockname() q.put(addr) clt, _ = sock.accept() clt.close() async def client(host, port): - reader, writer = await asyncio.open_connection( - host, port, loop=self.loop) + with self.assertWarns(DeprecationWarning): + reader, writer = await asyncio.open_connection( + host, port, loop=self.loop) while True: writer.write(b"foo\n") @@ -863,55 +934,106 @@ async def client(host, port): thread.join() self.assertEqual([], messages) + def test_drain_raises(self): + # See http://bugs.python.org/issue25441 + + # This test should not use asyncio for the mock server; the + # whole point of the test is to test for a bug in drain() + # where it never gives up the event loop but the socket is + # closed on the server side. + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + q = queue.Queue() + + def server(): + # Runs in a separate thread. + with socket.create_server(('localhost', 0)) as sock: + addr = sock.getsockname() + q.put(addr) + clt, _ = sock.accept() + clt.close() + + async def client(host, port): + stream = await asyncio.connect(host, port) + + while True: + stream.write(b"foo\n") + await stream.drain() + + # Start the server thread and wait for it to be listening. + thread = threading.Thread(target=server) + thread.setDaemon(True) + thread.start() + addr = q.get() + + # Should not be stuck in an infinite loop. + with self.assertRaises((ConnectionResetError, ConnectionAbortedError, + BrokenPipeError)): + self.loop.run_until_complete(client(*addr)) + + # Clean up the thread. (Only on success; on failure, it may + # be stuck in accept().) + thread.join() + self.assertEqual([], messages) + def test___repr__(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) - self.assertEqual("", repr(stream)) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) + self.assertEqual("", repr(stream)) def test___repr__nondefault_limit(self): - stream = asyncio.StreamReader(loop=self.loop, limit=123, - _asyncio_internal=True) - self.assertEqual("", repr(stream)) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, limit=123, + _asyncio_internal=True) + self.assertEqual("", repr(stream)) def test___repr__eof(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_eof() - self.assertEqual("", repr(stream)) + self.assertEqual("", repr(stream)) def test___repr__data(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream.feed_data(b'data') - self.assertEqual("", repr(stream)) + self.assertEqual("", repr(stream)) def test___repr__exception(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) exc = RuntimeError() stream.set_exception(exc) - self.assertEqual("", + self.assertEqual("", repr(stream)) def test___repr__waiter(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream._waiter = asyncio.Future(loop=self.loop) self.assertRegex( repr(stream), - r">") + r">") stream._waiter.set_result(None) self.loop.run_until_complete(stream._waiter) stream._waiter = None - self.assertEqual("", repr(stream)) + self.assertEqual("", repr(stream)) def test___repr__transport(self): - stream = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) stream._transport = mock.Mock() stream._transport.__repr__ = mock.Mock() stream._transport.__repr__.return_value = "" - self.assertEqual(">", repr(stream)) + self.assertEqual(">", + repr(stream)) def test_IncompleteReadError_pickleable(self): e = asyncio.IncompleteReadError(b'abc', 10) @@ -930,10 +1052,11 @@ def test_LimitOverrunError_pickleable(self): self.assertEqual(str(e), str(e2)) self.assertEqual(e.consumed, e2.consumed) - def test_wait_closed_on_close(self): + def test_wait_closed_on_close_deprecated(self): with test_utils.run_test_server() as httpd: - rd, wr = self.loop.run_until_complete( - asyncio.open_connection(*httpd.address, loop=self.loop)) + with self.assertWarns(DeprecationWarning): + rd, wr = self.loop.run_until_complete( + asyncio.open_connection(*httpd.address, loop=self.loop)) wr.write(b'GET / HTTP/1.0\r\n\r\n') f = rd.readline() @@ -947,10 +1070,28 @@ def test_wait_closed_on_close(self): self.assertTrue(wr.is_closing()) self.loop.run_until_complete(wr.wait_closed()) - def test_wait_closed_on_close_with_unread_data(self): + def test_wait_closed_on_close(self): with test_utils.run_test_server() as httpd: - rd, wr = self.loop.run_until_complete( - asyncio.open_connection(*httpd.address, loop=self.loop)) + stream = self.loop.run_until_complete( + asyncio.connect(*httpd.address)) + + stream.write(b'GET / HTTP/1.0\r\n\r\n') + f = stream.readline() + data = self.loop.run_until_complete(f) + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + f = stream.read() + data = self.loop.run_until_complete(f) + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + self.assertFalse(stream.is_closing()) + stream.close() + self.assertTrue(stream.is_closing()) + self.loop.run_until_complete(stream.wait_closed()) + + def test_wait_closed_on_close_with_unread_data_deprecated(self): + with test_utils.run_test_server() as httpd: + with self.assertWarns(DeprecationWarning): + rd, wr = self.loop.run_until_complete( + asyncio.open_connection(*httpd.address, loop=self.loop)) wr.write(b'GET / HTTP/1.0\r\n\r\n') f = rd.readline() @@ -959,32 +1100,44 @@ def test_wait_closed_on_close_with_unread_data(self): wr.close() self.loop.run_until_complete(wr.wait_closed()) + def test_wait_closed_on_close_with_unread_data(self): + with test_utils.run_test_server() as httpd: + stream = self.loop.run_until_complete( + asyncio.connect(*httpd.address)) + + stream.write(b'GET / HTTP/1.0\r\n\r\n') + f = stream.readline() + data = self.loop.run_until_complete(f) + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + stream.close() + self.loop.run_until_complete(stream.wait_closed()) + def test_del_stream_before_sock_closing(self): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) - with test_utils.run_test_server() as httpd: - rd, wr = self.loop.run_until_complete( - asyncio.open_connection(*httpd.address, loop=self.loop)) - sock = wr.get_extra_info('socket') - self.assertNotEqual(sock.fileno(), -1) + async def test(): - wr.write(b'GET / HTTP/1.0\r\n\r\n') - f = rd.readline() - data = self.loop.run_until_complete(f) - self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + with test_utils.run_test_server() as httpd: + stream = await asyncio.connect(*httpd.address) + sock = stream.get_extra_info('socket') + self.assertNotEqual(sock.fileno(), -1) - # drop refs to reader/writer - del rd - del wr - gc.collect() - # make a chance to close the socket - test_utils.run_briefly(self.loop) + await stream.write(b'GET / HTTP/1.0\r\n\r\n') + data = await stream.readline() + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') - self.assertEqual(1, len(messages)) - self.assertEqual(sock.fileno(), -1) + # drop refs to reader/writer + del stream + gc.collect() + # make a chance to close the socket + await asyncio.sleep(0) - self.assertEqual(1, len(messages)) + self.assertEqual(1, len(messages), messages) + self.assertEqual(sock.fileno(), -1) + + self.loop.run_until_complete(test()) + self.assertEqual(1, len(messages), messages) self.assertEqual('An open stream object is being garbage ' 'collected; call "stream.close()" explicitly.', messages[0]['message']) @@ -994,11 +1147,12 @@ def test_del_stream_before_connection_made(self): self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) with test_utils.run_test_server() as httpd: - rd = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) - pr = asyncio.StreamReaderProtocol(rd, loop=self.loop, - _asyncio_internal=True) - del rd + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, + _asyncio_internal=True) + pr = _StreamProtocol(stream, loop=self.loop, + _asyncio_internal=True) + del stream gc.collect() tr, _ = self.loop.run_until_complete( self.loop.create_connection( @@ -1015,14 +1169,14 @@ def test_del_stream_before_connection_made(self): def test_async_writer_api(self): async def inner(httpd): - rd, wr = await asyncio.open_connection(*httpd.address) + stream = await asyncio.connect(*httpd.address) - await wr.write(b'GET / HTTP/1.0\r\n\r\n') - data = await rd.readline() + await stream.write(b'GET / HTTP/1.0\r\n\r\n') + data = await stream.readline() self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') - data = await rd.read() + data = await stream.read() self.assertTrue(data.endswith(b'\r\n\r\nTest message')) - await wr.close() + await stream.close() messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) @@ -1032,18 +1186,18 @@ async def inner(httpd): self.assertEqual(messages, []) - def test_async_writer_api(self): + def test_async_writer_api_exception_after_close(self): async def inner(httpd): - rd, wr = await asyncio.open_connection(*httpd.address) + stream = await asyncio.connect(*httpd.address) - await wr.write(b'GET / HTTP/1.0\r\n\r\n') - data = await rd.readline() + await stream.write(b'GET / HTTP/1.0\r\n\r\n') + data = await stream.readline() self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') - data = await rd.read() + data = await stream.read() self.assertTrue(data.endswith(b'\r\n\r\nTest message')) - wr.close() + stream.close() with self.assertRaises(ConnectionResetError): - await wr.write(b'data') + await stream.write(b'data') messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) @@ -1059,11 +1213,13 @@ def test_eof_feed_when_closing_writer(self): self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) with test_utils.run_test_server() as httpd: - rd, wr = self.loop.run_until_complete( - asyncio.open_connection(*httpd.address, - loop=self.loop)) + with self.assertWarns(DeprecationWarning): + rd, wr = self.loop.run_until_complete( + asyncio.open_connection(*httpd.address, + loop=self.loop)) - f = wr.close() + wr.close() + f = wr.wait_closed() self.loop.run_until_complete(f) assert rd.at_eof() f = rd.read() @@ -1074,22 +1230,514 @@ def test_eof_feed_when_closing_writer(self): def test_stream_reader_create_warning(self): with self.assertWarns(DeprecationWarning): - asyncio.StreamReader(loop=self.loop) - - def test_stream_reader_protocol_create_warning(self): - reader = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) - with self.assertWarns(DeprecationWarning): - asyncio.StreamReaderProtocol(reader, loop=self.loop) + asyncio.StreamReader def test_stream_writer_create_warning(self): - reader = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) - proto = asyncio.StreamReaderProtocol(reader, loop=self.loop, - _asyncio_internal=True) with self.assertWarns(DeprecationWarning): - asyncio.StreamWriter('transport', proto, reader, self.loop) + asyncio.StreamWriter + + def test_stream_reader_forbidden_ops(self): + async def inner(): + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + _asyncio_internal=True) + with self.assertRaisesRegex(RuntimeError, "The stream is read-only"): + await stream.write(b'data') + with self.assertRaisesRegex(RuntimeError, "The stream is read-only"): + await stream.writelines([b'data', b'other']) + with self.assertRaisesRegex(RuntimeError, "The stream is read-only"): + stream.write_eof() + with self.assertRaisesRegex(RuntimeError, "The stream is read-only"): + await stream.drain() + + self.loop.run_until_complete(inner()) + + def test_stream_writer_forbidden_ops(self): + async def inner(): + stream = asyncio.Stream(mode=asyncio.StreamMode.WRITE, + _asyncio_internal=True) + with self.assertRaisesRegex(RuntimeError, "The stream is write-only"): + stream.feed_data(b'data') + with self.assertRaisesRegex(RuntimeError, "The stream is write-only"): + await stream.readline() + with self.assertRaisesRegex(RuntimeError, "The stream is write-only"): + await stream.readuntil() + with self.assertRaisesRegex(RuntimeError, "The stream is write-only"): + await stream.read() + with self.assertRaisesRegex(RuntimeError, "The stream is write-only"): + await stream.readexactly(10) + with self.assertRaisesRegex(RuntimeError, "The stream is write-only"): + async for chunk in stream: + pass + + self.loop.run_until_complete(inner()) + + def _basetest_connect(self, stream): + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + + stream.write(b'GET / HTTP/1.0\r\n\r\n') + f = stream.readline() + data = self.loop.run_until_complete(f) + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + f = stream.read() + data = self.loop.run_until_complete(f) + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + stream.close() + self.loop.run_until_complete(stream.wait_closed()) + + self.assertEqual([], messages) + + def test_connect(self): + with test_utils.run_test_server() as httpd: + stream = self.loop.run_until_complete( + asyncio.connect(*httpd.address)) + self.assertFalse(stream.is_server_side()) + self._basetest_connect(stream) + + @support.skip_unless_bind_unix_socket + def test_connect_unix(self): + with test_utils.run_test_unix_server() as httpd: + stream = self.loop.run_until_complete( + asyncio.connect_unix(httpd.address)) + self._basetest_connect(stream) + + def test_stream_async_context_manager(self): + async def test(httpd): + stream = await asyncio.connect(*httpd.address) + async with stream: + await stream.write(b'GET / HTTP/1.0\r\n\r\n') + data = await stream.readline() + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + data = await stream.read() + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + self.assertTrue(stream.is_closing()) + + with test_utils.run_test_server() as httpd: + self.loop.run_until_complete(test(httpd)) + + def test_connect_async_context_manager(self): + async def test(httpd): + async with asyncio.connect(*httpd.address) as stream: + await stream.write(b'GET / HTTP/1.0\r\n\r\n') + data = await stream.readline() + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + data = await stream.read() + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + self.assertTrue(stream.is_closing()) + + with test_utils.run_test_server() as httpd: + self.loop.run_until_complete(test(httpd)) + + @support.skip_unless_bind_unix_socket + def test_connect_unix_async_context_manager(self): + async def test(httpd): + async with asyncio.connect_unix(httpd.address) as stream: + await stream.write(b'GET / HTTP/1.0\r\n\r\n') + data = await stream.readline() + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + data = await stream.read() + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + self.assertTrue(stream.is_closing()) + + with test_utils.run_test_unix_server() as httpd: + self.loop.run_until_complete(test(httpd)) + + def test_stream_server(self): + + async def handle_client(stream): + self.assertTrue(stream.is_server_side()) + data = await stream.readline() + await stream.write(data) + await stream.close() + + async def client(srv): + addr = srv.sockets[0].getsockname() + stream = await asyncio.connect(*addr) + # send a line + await stream.write(b"hello world!\n") + # read it back + msgback = await stream.readline() + await stream.close() + self.assertEqual(msgback, b"hello world!\n") + await srv.close() + + async def test(): + async with asyncio.StreamServer(handle_client, '127.0.0.1', 0) as server: + await server.start_serving() + task = asyncio.create_task(client(server)) + with contextlib.suppress(asyncio.CancelledError): + await server.serve_forever() + await task + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + + @support.skip_unless_bind_unix_socket + def test_unix_stream_server(self): + + async def handle_client(stream): + data = await stream.readline() + await stream.write(data) + await stream.close() + + async def client(srv): + addr = srv.sockets[0].getsockname() + stream = await asyncio.connect_unix(addr) + # send a line + await stream.write(b"hello world!\n") + # read it back + msgback = await stream.readline() + await stream.close() + self.assertEqual(msgback, b"hello world!\n") + await srv.close() + + async def test(): + with test_utils.unix_socket_path() as path: + async with asyncio.UnixStreamServer(handle_client, path) as server: + await server.start_serving() + task = asyncio.create_task(client(server)) + with contextlib.suppress(asyncio.CancelledError): + await server.serve_forever() + await task + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + + def test_stream_server_inheritance_forbidden(self): + with self.assertRaises(TypeError): + class MyServer(asyncio.StreamServer): + pass + + @support.skip_unless_bind_unix_socket + def test_unix_stream_server_inheritance_forbidden(self): + with self.assertRaises(TypeError): + class MyServer(asyncio.UnixStreamServer): + pass + + def test_stream_server_bind(self): + async def handle_client(stream): + await stream.close() + + async def test(): + srv = asyncio.StreamServer(handle_client, '127.0.0.1', 0) + self.assertFalse(srv.is_bound()) + self.assertEqual(0, len(srv.sockets)) + await srv.bind() + self.assertTrue(srv.is_bound()) + self.assertEqual(1, len(srv.sockets)) + await srv.close() + self.assertFalse(srv.is_bound()) + self.assertEqual(0, len(srv.sockets)) + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + + def test_stream_server_bind_async_with(self): + async def handle_client(stream): + await stream.close() + + async def test(): + async with asyncio.StreamServer(handle_client, '127.0.0.1', 0) as srv: + self.assertTrue(srv.is_bound()) + self.assertEqual(1, len(srv.sockets)) + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + + def test_stream_server_start_serving(self): + async def handle_client(stream): + await stream.close() + + async def test(): + async with asyncio.StreamServer(handle_client, '127.0.0.1', 0) as srv: + self.assertFalse(srv.is_serving()) + await srv.start_serving() + self.assertTrue(srv.is_serving()) + await srv.close() + self.assertFalse(srv.is_serving()) + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + + def test_stream_server_close(self): + server_stream_aborted = False + fut = self.loop.create_future() + + async def handle_client(stream): + await fut + self.assertEqual(b'', await stream.readline()) + nonlocal server_stream_aborted + server_stream_aborted = True + + async def client(srv): + addr = srv.sockets[0].getsockname() + stream = await asyncio.connect(*addr) + fut.set_result(None) + self.assertEqual(b'', await stream.readline()) + await stream.close() + + async def test(): + async with asyncio.StreamServer(handle_client, '127.0.0.1', 0) as server: + await server.start_serving() + task = asyncio.create_task(client(server)) + await fut + await server.close() + await task + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + self.assertTrue(fut.done()) + self.assertTrue(server_stream_aborted) + + def test_stream_server_abort(self): + server_stream_aborted = False + fut = self.loop.create_future() + + async def handle_client(stream): + await fut + self.assertEqual(b'', await stream.readline()) + nonlocal server_stream_aborted + server_stream_aborted = True + + async def client(srv): + addr = srv.sockets[0].getsockname() + stream = await asyncio.connect(*addr) + fut.set_result(None) + self.assertEqual(b'', await stream.readline()) + await stream.close() + + async def test(): + async with asyncio.StreamServer(handle_client, '127.0.0.1', 0) as server: + await server.start_serving() + task = asyncio.create_task(client(server)) + await fut + await server.abort() + await task + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + self.assertTrue(fut.done()) + self.assertTrue(server_stream_aborted) + + def test_stream_shutdown_hung_task(self): + fut1 = self.loop.create_future() + fut2 = self.loop.create_future() + + async def handle_client(stream): + while True: + await asyncio.sleep(0.01) + + async def client(srv): + addr = srv.sockets[0].getsockname() + stream = await asyncio.connect(*addr) + fut1.set_result(None) + await fut2 + self.assertEqual(b'', await stream.readline()) + await stream.close() + + async def test(): + async with asyncio.StreamServer(handle_client, + '127.0.0.1', + 0, + shutdown_timeout=0.3) as server: + await server.start_serving() + task = asyncio.create_task(client(server)) + await fut1 + await server.close() + fut2.set_result(None) + await task + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(messages, []) + self.assertTrue(fut1.done()) + self.assertTrue(fut2.done()) + + def test_stream_shutdown_hung_task_prevents_cancellation(self): + fut1 = self.loop.create_future() + fut2 = self.loop.create_future() + do_handle_client = True + + async def handle_client(stream): + while do_handle_client: + with contextlib.suppress(asyncio.CancelledError): + await asyncio.sleep(0.01) + + async def client(srv): + addr = srv.sockets[0].getsockname() + stream = await asyncio.connect(*addr) + fut1.set_result(None) + await fut2 + self.assertEqual(b'', await stream.readline()) + await stream.close() + + async def test(): + async with asyncio.StreamServer(handle_client, + '127.0.0.1', + 0, + shutdown_timeout=0.3) as server: + await server.start_serving() + task = asyncio.create_task(client(server)) + await fut1 + await server.close() + nonlocal do_handle_client + do_handle_client = False + fut2.set_result(None) + await task + + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) + self.loop.run_until_complete(test()) + self.assertEqual(1, len(messages)) + self.assertRegex(messages[0]['message'], + "', repr(srv)) + await srv.close() + + self.loop.run_until_complete(test()) + + def test_repr_bound(self): + async def serve(stream): + pass + + async def test(): + srv = asyncio.StreamServer(serve, '127.0.0.1', 0) + await srv.bind() + self.assertRegex(repr(srv), r'') + await srv.close() + + self.loop.run_until_complete(test()) + + def test_repr_serving(self): + async def serve(stream): + pass + + async def test(): + srv = asyncio.StreamServer(serve, '127.0.0.1', 0) + await srv.start_serving() + self.assertRegex(repr(srv), r'') + await srv.close() + + self.loop.run_until_complete(test()) + + + @unittest.skipUnless(sys.platform != 'win32', + "Don't support pipes for Windows") + def test_read_pipe(self): + async def test(): + rpipe, wpipe = os.pipe() + pipeobj = io.open(rpipe, 'rb', 1024) + + async with asyncio.connect_read_pipe(pipeobj) as stream: + self.assertEqual(stream.mode, asyncio.StreamMode.READ) + + os.write(wpipe, b'1') + data = await stream.readexactly(1) + self.assertEqual(data, b'1') + + os.write(wpipe, b'2345') + data = await stream.readexactly(4) + self.assertEqual(data, b'2345') + os.close(wpipe) + + self.loop.run_until_complete(test()) + + @unittest.skipUnless(sys.platform != 'win32', + "Don't support pipes for Windows") + def test_write_pipe(self): + async def test(): + rpipe, wpipe = os.pipe() + pipeobj = io.open(wpipe, 'wb', 1024) + + async with asyncio.connect_write_pipe(pipeobj) as stream: + self.assertEqual(stream.mode, asyncio.StreamMode.WRITE) + + await stream.write(b'1') + data = os.read(rpipe, 1024) + self.assertEqual(data, b'1') + + await stream.write(b'2345') + data = os.read(rpipe, 1024) + self.assertEqual(data, b'2345') + + os.close(rpipe) + self.loop.run_until_complete(test()) if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index e201a0696796d6..13aef7cf1f776b 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -17,6 +17,7 @@ import asyncio from asyncio import windows_events +from asyncio.streams import _StreamProtocol from test.test_asyncio import utils as test_utils from test.support.script_helper import spawn_python @@ -100,16 +101,16 @@ async def _test_pipe(self): clients = [] for i in range(5): - stream_reader = asyncio.StreamReader(loop=self.loop, - _asyncio_internal=True) - protocol = asyncio.StreamReaderProtocol(stream_reader, - loop=self.loop, - _asyncio_internal=True) + stream = asyncio.Stream(mode=asyncio.StreamMode.READ, + loop=self.loop, _asyncio_internal=True) + protocol = _StreamProtocol(stream, + loop=self.loop, + _asyncio_internal=True) trans, proto = await self.loop.create_pipe_connection( lambda: protocol, ADDRESS) self.assertIsInstance(trans, asyncio.Transport) self.assertEqual(protocol, proto) - clients.append((stream_reader, trans)) + clients.append((stream, trans)) for i, (r, w) in enumerate(clients): w.write('lower-{}\n'.format(i).encode()) @@ -118,6 +119,7 @@ async def _test_pipe(self): response = await r.readline() self.assertEqual(response, 'LOWER-{}\n'.format(i).encode()) w.close() + await r.close() server.close() diff --git a/Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst b/Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst new file mode 100644 index 00000000000000..d08c0e287edfb4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst @@ -0,0 +1,6 @@ +Introduce :class:`asyncio.Stream` class that merges :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter` functionality. +:class:`asyncio.Stream` can work in readonly, writeonly and readwrite modes. +Provide :func:`asyncio.connect`, :func:`asyncio.connect_unix`, :func:`asyncio.connect_read_pipe` and :func:`asyncio.connect_write_pipe` factories to open :class:`asyncio.Stream` connections. Provide :class:`asyncio.StreamServer` and :class:`UnixStreamServer` to serve servers with asyncio.Stream API. +Modify :func:`asyncio.create_subprocess_shell` and :func:`asyncio.create_subprocess_exec` to use :class:`asyncio.Stream` instead of deprecated :class:`StreamReader` and :class:`StreamWriter`. +Deprecate :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter`. +Deprecate usage of private classes, e.g. :class:`asyncio.FlowControlMixing` and :class:`asyncio.StreamReaderProtocol` outside of asyncio package. From cd590a7cede156a4244e7cac61e4504e5344d842 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 28 May 2019 00:39:52 +0200 Subject: [PATCH 134/441] bpo-1230540: Add threading.excepthook() (GH-13515) Add a new threading.excepthook() function which handles uncaught Thread.run() exception. It can be overridden to control how uncaught exceptions are handled. threading.ExceptHookArgs is not documented on purpose: it should not be used directly. * threading.excepthook() and threading.ExceptHookArgs. * Add _PyErr_Display(): similar to PyErr_Display(), but accept a 'file' parameter. * Add _thread._excepthook(): C implementation of the exception hook calling _PyErr_Display(). * Add _thread._ExceptHookArgs: structseq type. * Add threading._invoke_excepthook_wrapper() which handles the gory details to ensure that everything remains alive during Python shutdown. * Add unit tests. --- Doc/library/sys.rst | 6 +- Doc/library/threading.rst | 30 ++++ Doc/whatsnew/3.8.rst | 9 + Include/internal/pycore_pylifecycle.h | 2 + Lib/test/test_threading.py | 92 +++++++++++ Lib/threading.py | 155 +++++++++++------ ...2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst | 3 + Modules/_threadmodule.c | 156 ++++++++++++++++++ Python/pythonrun.c | 38 +++-- 9 files changed, 424 insertions(+), 67 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 51a208ee60405d..74aa2711dd01be 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -298,7 +298,11 @@ always available. before the program exits. The handling of such top-level exceptions can be customized by assigning another three-argument function to ``sys.excepthook``. - See also :func:`unraisablehook` which handles unraisable exceptions. + .. seealso:: + + The :func:`sys.unraisablehook` function handles unraisable exceptions + and the :func:`threading.excepthook` function handles exception raised + by :func:`threading.Thread.run`. .. data:: __breakpointhook__ diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 1df512f1d63265..ffe6d04258aa9e 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -38,6 +38,32 @@ This module defines the following functions: returned. +.. function:: excepthook(args, /) + + Handle uncaught exception raised by :func:`Thread.run`. + + The *args* argument has the following attributes: + + * *exc_type*: Exception type. + * *exc_value*: Exception value, can be ``None``. + * *exc_traceback*: Exception traceback, can be ``None``. + * *thread*: Thread which raised the exception, can be ``None``. + + If *exc_type* is :exc:`SystemExit`, the exception is silently ignored. + Otherwise, the exception is printed out on :data:`sys.stderr`. + + If this function raises an exception, :func:`sys.excepthook` is called to + handle it. + + :func:`threading.excepthook` can be overridden to control how uncaught + exceptions raised by :func:`Thread.run` are handled. + + .. seealso:: + :func:`sys.excepthook` handles uncaught exceptions. + + .. versionadded:: 3.8 + + .. function:: get_ident() Return the 'thread identifier' of the current thread. This is a nonzero @@ -191,6 +217,10 @@ called is terminated. A thread has a name. The name can be passed to the constructor, and read or changed through the :attr:`~Thread.name` attribute. +If the :meth:`~Thread.run` method raises an exception, +:func:`threading.excepthook` is called to handle it. By default, +:func:`threading.excepthook` ignores silently :exc:`SystemExit`. + A thread can be flagged as a "daemon thread". The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index fd5e6496ba2ed5..125cefe1113356 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -623,6 +623,15 @@ in a standardized and extensible format, and offers several other benefits. (Contributed by C.A.M. Gerlach in :issue:`36268`.) +threading +--------- + +Add a new :func:`threading.excepthook` function which handles uncaught +:meth:`threading.Thread.run` exception. It can be overridden to control how +uncaught :meth:`threading.Thread.run` exceptions are handled. +(Contributed by Victor Stinner in :issue:`1230540`.) + + tokenize -------- diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 69761cef982204..8a692ea1649512 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -107,6 +107,8 @@ PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p); PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); +PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, + PyObject *value, PyObject *tb); #ifdef __cplusplus } diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 3bfd6fa474ed04..8c8cc128b0513b 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -1112,6 +1112,98 @@ def run(self): # explicitly break the reference cycle to not leak a dangling thread thread.exc = None + +class ThreadRunFail(threading.Thread): + def run(self): + raise ValueError("run failed") + + +class ExceptHookTests(BaseTestCase): + def test_excepthook(self): + with support.captured_output("stderr") as stderr: + thread = ThreadRunFail(name="excepthook thread") + thread.start() + thread.join() + + stderr = stderr.getvalue().strip() + self.assertIn(f'Exception in thread {thread.name}:\n', stderr) + self.assertIn('Traceback (most recent call last):\n', stderr) + self.assertIn(' raise ValueError("run failed")', stderr) + self.assertIn('ValueError: run failed', stderr) + + @support.cpython_only + def test_excepthook_thread_None(self): + # threading.excepthook called with thread=None: log the thread + # identifier in this case. + with support.captured_output("stderr") as stderr: + try: + raise ValueError("bug") + except Exception as exc: + args = threading.ExceptHookArgs([*sys.exc_info(), None]) + threading.excepthook(args) + + stderr = stderr.getvalue().strip() + self.assertIn(f'Exception in thread {threading.get_ident()}:\n', stderr) + self.assertIn('Traceback (most recent call last):\n', stderr) + self.assertIn(' raise ValueError("bug")', stderr) + self.assertIn('ValueError: bug', stderr) + + def test_system_exit(self): + class ThreadExit(threading.Thread): + def run(self): + sys.exit(1) + + # threading.excepthook() silently ignores SystemExit + with support.captured_output("stderr") as stderr: + thread = ThreadExit() + thread.start() + thread.join() + + self.assertEqual(stderr.getvalue(), '') + + def test_custom_excepthook(self): + args = None + + def hook(hook_args): + nonlocal args + args = hook_args + + try: + with support.swap_attr(threading, 'excepthook', hook): + thread = ThreadRunFail() + thread.start() + thread.join() + + self.assertEqual(args.exc_type, ValueError) + self.assertEqual(str(args.exc_value), 'run failed') + self.assertEqual(args.exc_traceback, args.exc_value.__traceback__) + self.assertIs(args.thread, thread) + finally: + # Break reference cycle + args = None + + def test_custom_excepthook_fail(self): + def threading_hook(args): + raise ValueError("threading_hook failed") + + err_str = None + + def sys_hook(exc_type, exc_value, exc_traceback): + nonlocal err_str + err_str = str(exc_value) + + with support.swap_attr(threading, 'excepthook', threading_hook), \ + support.swap_attr(sys, 'excepthook', sys_hook), \ + support.captured_output('stderr') as stderr: + thread = ThreadRunFail() + thread.start() + thread.join() + + self.assertEqual(stderr.getvalue(), + 'Exception in threading.excepthook:\n') + self.assertEqual(err_str, 'threading_hook failed') + + class TimerTests(BaseTestCase): def setUp(self): diff --git a/Lib/threading.py b/Lib/threading.py index 77a2baec2accb5..3d197eed6a7251 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -5,7 +5,6 @@ import _thread from time import monotonic as _time -from traceback import format_exc as _format_exc from _weakrefset import WeakSet from itertools import islice as _islice, count as _count try: @@ -27,7 +26,8 @@ 'enumerate', 'main_thread', 'TIMEOUT_MAX', 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError', - 'setprofile', 'settrace', 'local', 'stack_size'] + 'setprofile', 'settrace', 'local', 'stack_size', + 'excepthook', 'ExceptHookArgs'] # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread @@ -752,14 +752,6 @@ class Thread: """ _initialized = False - # Need to store a reference to sys.exc_info for printing - # out exceptions when a thread tries to use a global var. during interp. - # shutdown and thus raises an exception about trying to perform some - # operation on/with a NoneType - _exc_info = _sys.exc_info - # Keep sys.exc_clear too to clear the exception just before - # allowing .join() to return. - #XXX __exc_clear = _sys.exc_clear def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): @@ -802,9 +794,9 @@ class is implemented. self._started = Event() self._is_stopped = False self._initialized = True - # sys.stderr is not stored in the class like - # sys.exc_info since it can be changed between instances + # Copy of sys.stderr used by self._invoke_excepthook() self._stderr = _sys.stderr + self._invoke_excepthook = _make_invoke_excepthook() # For debugging and _after_fork() _dangling.add(self) @@ -929,47 +921,8 @@ def _bootstrap_inner(self): try: self.run() - except SystemExit: - pass except: - # If sys.stderr is no more (most likely from interpreter - # shutdown) use self._stderr. Otherwise still use sys (as in - # _sys) in case sys.stderr was redefined since the creation of - # self. - if _sys and _sys.stderr is not None: - print("Exception in thread %s:\n%s" % - (self.name, _format_exc()), file=_sys.stderr) - elif self._stderr is not None: - # Do the best job possible w/o a huge amt. of code to - # approximate a traceback (code ideas from - # Lib/traceback.py) - exc_type, exc_value, exc_tb = self._exc_info() - try: - print(( - "Exception in thread " + self.name + - " (most likely raised during interpreter shutdown):"), file=self._stderr) - print(( - "Traceback (most recent call last):"), file=self._stderr) - while exc_tb: - print(( - ' File "%s", line %s, in %s' % - (exc_tb.tb_frame.f_code.co_filename, - exc_tb.tb_lineno, - exc_tb.tb_frame.f_code.co_name)), file=self._stderr) - exc_tb = exc_tb.tb_next - print(("%s: %s" % (exc_type, exc_value)), file=self._stderr) - self._stderr.flush() - # Make sure that exc_tb gets deleted since it is a memory - # hog; deleting everything else is just for thoroughness - finally: - del exc_type, exc_value, exc_tb - finally: - # Prevent a race in - # test_threading.test_no_refcycle_through_target when - # the exception keeps the target alive past when we - # assert that it's dead. - #XXX self._exc_clear() - pass + self._invoke_excepthook(self) finally: with _active_limbo_lock: try: @@ -1163,6 +1116,104 @@ def getName(self): def setName(self, name): self.name = name + +try: + from _thread import (_excepthook as excepthook, + _ExceptHookArgs as ExceptHookArgs) +except ImportError: + # Simple Python implementation if _thread._excepthook() is not available + from traceback import print_exception as _print_exception + from collections import namedtuple + + _ExceptHookArgs = namedtuple( + 'ExceptHookArgs', + 'exc_type exc_value exc_traceback thread') + + def ExceptHookArgs(args): + return _ExceptHookArgs(*args) + + def excepthook(args, /): + """ + Handle uncaught Thread.run() exception. + """ + if args.exc_type == SystemExit: + # silently ignore SystemExit + return + + if _sys is not None and _sys.stderr is not None: + stderr = _sys.stderr + elif args.thread is not None: + stderr = args.thread._stderr + if stderr is None: + # do nothing if sys.stderr is None and sys.stderr was None + # when the thread was created + return + else: + # do nothing if sys.stderr is None and args.thread is None + return + + if args.thread is not None: + name = args.thread.name + else: + name = get_ident() + print(f"Exception in thread {name}:", + file=stderr, flush=True) + _print_exception(args.exc_type, args.exc_value, args.exc_traceback, + file=stderr) + stderr.flush() + + +def _make_invoke_excepthook(): + # Create a local namespace to ensure that variables remain alive + # when _invoke_excepthook() is called, even if it is called late during + # Python shutdown. It is mostly needed for daemon threads. + + old_excepthook = excepthook + old_sys_excepthook = _sys.excepthook + if old_excepthook is None: + raise RuntimeError("threading.excepthook is None") + if old_sys_excepthook is None: + raise RuntimeError("sys.excepthook is None") + + sys_exc_info = _sys.exc_info + local_print = print + local_sys = _sys + + def invoke_excepthook(thread): + global excepthook + try: + hook = excepthook + if hook is None: + hook = old_excepthook + + args = ExceptHookArgs([*sys_exc_info(), thread]) + + hook(args) + except Exception as exc: + exc.__suppress_context__ = True + del exc + + if local_sys is not None and local_sys.stderr is not None: + stderr = local_sys.stderr + else: + stderr = thread._stderr + + local_print("Exception in threading.excepthook:", + file=stderr, flush=True) + + if local_sys is not None and local_sys.excepthook is not None: + sys_excepthook = local_sys.excepthook + else: + sys_excepthook = old_sys_excepthook + + sys_excepthook(*sys_exc_info()) + finally: + # Break reference cycle (exception stored in a variable) + args = None + + return invoke_excepthook + + # The timer class was contributed by Itamar Shtull-Trauring class Timer(Thread): diff --git a/Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst b/Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst new file mode 100644 index 00000000000000..250a64237d1822 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst @@ -0,0 +1,3 @@ +Add a new :func:`threading.excepthook` function which handles uncaught +:meth:`threading.Thread.run` exception. It can be overridden to control how +uncaught :meth:`threading.Thread.run` exceptions are handled. diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index fee25abe283a8d..680e8ca7108c18 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -3,6 +3,7 @@ /* Interface to Sjoerd's portable C thread library */ #include "Python.h" +#include "pycore_pylifecycle.h" #include "pycore_pystate.h" #include "structmember.h" /* offsetof */ #include "pythread.h" @@ -11,6 +12,7 @@ static PyObject *ThreadError; static PyObject *str_dict; _Py_IDENTIFIER(stderr); +_Py_IDENTIFIER(flush); /* Lock objects */ @@ -1309,6 +1311,147 @@ requiring allocation in multiples of the system memory page size\n\ (4 KiB pages are common; using multiples of 4096 for the stack size is\n\ the suggested approach in the absence of more specific information)."); +static int +thread_excepthook_file(PyObject *file, PyObject *exc_type, PyObject *exc_value, + PyObject *exc_traceback, PyObject *thread) +{ + /* print(f"Exception in thread {thread.name}:", file=file) */ + if (PyFile_WriteString("Exception in thread ", file) < 0) { + return -1; + } + + PyObject *name = NULL; + if (thread != Py_None) { + name = PyObject_GetAttrString(thread, "name"); + } + if (name != NULL) { + if (PyFile_WriteObject(name, file, Py_PRINT_RAW) < 0) { + Py_DECREF(name); + return -1; + } + Py_DECREF(name); + } + else { + PyErr_Clear(); + + unsigned long ident = PyThread_get_thread_ident(); + PyObject *str = PyUnicode_FromFormat("%lu", ident); + if (str != NULL) { + if (PyFile_WriteObject(str, file, Py_PRINT_RAW) < 0) { + Py_DECREF(str); + return -1; + } + Py_DECREF(str); + } + else { + PyErr_Clear(); + + if (PyFile_WriteString("", file) < 0) { + return -1; + } + } + } + + if (PyFile_WriteString(":\n", file) < 0) { + return -1; + } + + /* Display the traceback */ + _PyErr_Display(file, exc_type, exc_value, exc_traceback); + + /* Call file.flush() */ + PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + if (!res) { + return -1; + } + Py_DECREF(res); + + return 0; +} + + +PyDoc_STRVAR(ExceptHookArgs__doc__, +"ExceptHookArgs\n\ +\n\ +Type used to pass arguments to threading.excepthook."); + +static PyTypeObject ExceptHookArgsType; + +static PyStructSequence_Field ExceptHookArgs_fields[] = { + {"exc_type", "Exception type"}, + {"exc_value", "Exception value"}, + {"exc_traceback", "Exception traceback"}, + {"thread", "Thread"}, + {0} +}; + +static PyStructSequence_Desc ExceptHookArgs_desc = { + .name = "_thread.ExceptHookArgs", + .doc = ExceptHookArgs__doc__, + .fields = ExceptHookArgs_fields, + .n_in_sequence = 4 +}; + + +static PyObject * +thread_excepthook(PyObject *self, PyObject *args) +{ + if (Py_TYPE(args) != &ExceptHookArgsType) { + PyErr_SetString(PyExc_TypeError, + "_thread.excepthook argument type " + "must be ExceptHookArgs"); + return NULL; + } + + /* Borrowed reference */ + PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0); + if (exc_type == PyExc_SystemExit) { + /* silently ignore SystemExit */ + Py_RETURN_NONE; + } + + /* Borrowed references */ + PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1); + PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2); + PyObject *thread = PyStructSequence_GET_ITEM(args, 3); + + PyObject *file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL || file == Py_None) { + if (thread == Py_None) { + /* do nothing if sys.stderr is None and thread is None */ + Py_RETURN_NONE; + } + + file = PyObject_GetAttrString(thread, "_stderr"); + if (file == NULL) { + return NULL; + } + if (file == Py_None) { + Py_DECREF(file); + /* do nothing if sys.stderr is None and sys.stderr was None + when the thread was created */ + Py_RETURN_NONE; + } + } + else { + Py_INCREF(file); + } + + int res = thread_excepthook_file(file, exc_type, exc_value, exc_tb, + thread); + Py_DECREF(file); + if (res < 0) { + return NULL; + } + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(excepthook_doc, +"excepthook(exc_type, exc_value, exc_traceback, thread)\n\ +\n\ +Handle uncaught Thread.run() exception."); + static PyMethodDef thread_methods[] = { {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread, METH_VARARGS, start_new_doc}, @@ -1336,6 +1479,8 @@ static PyMethodDef thread_methods[] = { METH_VARARGS, stack_size_doc}, {"_set_sentinel", thread__set_sentinel, METH_NOARGS, _set_sentinel_doc}, + {"_excepthook", thread_excepthook, + METH_O, excepthook_doc}, {NULL, NULL} /* sentinel */ }; @@ -1388,6 +1533,12 @@ PyInit__thread(void) return NULL; if (PyType_Ready(&RLocktype) < 0) return NULL; + if (ExceptHookArgsType.tp_name == NULL) { + if (PyStructSequence_InitType2(&ExceptHookArgsType, + &ExceptHookArgs_desc) < 0) { + return NULL; + } + } /* Create the module and add the functions */ m = PyModule_Create(&threadmodule); @@ -1424,6 +1575,11 @@ PyInit__thread(void) if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0) return NULL; + Py_INCREF(&ExceptHookArgsType); + if (PyModule_AddObject(m, "_ExceptHookArgs", + (PyObject *)&ExceptHookArgsType) < 0) + return NULL; + interp->num_threads = 0; str_dict = PyUnicode_InternFromString("__dict__"); diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 665c9c9586e1e0..ba1d1cf02f2584 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -953,10 +953,11 @@ print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen) } void -PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) +_PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb) { + assert(file != NULL && file != Py_None); + PyObject *seen; - PyObject *f = _PySys_GetObjectId(&PyId_stderr); if (PyExceptionInstance_Check(value) && tb != NULL && PyTraceBack_Check(tb)) { /* Put the traceback on the exception, otherwise it won't get @@ -967,23 +968,32 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) else Py_DECREF(cur_tb); } - if (f == Py_None) { - /* pass */ + + /* We choose to ignore seen being possibly NULL, and report + at least the main exception (it could be a MemoryError). + */ + seen = PySet_New(NULL); + if (seen == NULL) { + PyErr_Clear(); } - else if (f == NULL) { + print_exception_recursive(file, value, seen); + Py_XDECREF(seen); +} + +void +PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) +{ + PyObject *file = _PySys_GetObjectId(&PyId_stderr); + if (file == NULL) { _PyObject_Dump(value); fprintf(stderr, "lost sys.stderr\n"); + return; } - else { - /* We choose to ignore seen being possibly NULL, and report - at least the main exception (it could be a MemoryError). - */ - seen = PySet_New(NULL); - if (seen == NULL) - PyErr_Clear(); - print_exception_recursive(f, value, seen); - Py_XDECREF(seen); + if (file == Py_None) { + return; } + + _PyErr_Display(file, exception, value, tb); } PyObject * From df9b032f47e4edaf306d95449370e565ee470018 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 27 May 2019 19:16:46 -0400 Subject: [PATCH 135/441] bpo-37039: IDLE - zoomheight fixes (GH-13576) Move doc entry to match menu and refactor zoom function. A followup patch will include a blurb. --- Doc/library/idle.rst | 10 +++++----- Lib/idlelib/help.html | 10 +++++----- Lib/idlelib/zoomheight.py | 28 ++++++++-------------------- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index c51cf19e97bd05..bd24695c728233 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -281,16 +281,16 @@ Configure IDLE menu. For more, see :ref:`Setting preferences ` under Help and preferences. -Zoom/Restore Height - Toggles the window between normal size and maximum height. The initial size - defaults to 40 lines by 80 chars unless changed on the General tab of the - Configure IDLE dialog. - Show/Hide Code Context (Editor Window only) Open a pane at the top of the edit window which shows the block context of the code which has scrolled above the top of the window. See :ref:`Code Context ` in the Editing and Navigation section below. +Zoom/Restore Height + Toggles the window between normal size and maximum height. The initial size + defaults to 40 lines by 80 chars unless changed on the General tab of the + Configure IDLE dialog. + Window menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index bc287d637ab738..228b3195cf9253 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -313,14 +313,14 @@

Options menu (Shell and Editor)Setting preferences under Help and preferences. -
Zoom/Restore Height
-
Toggles the window between normal size and maximum height. The initial size -defaults to 40 lines by 80 chars unless changed on the General tab of the -Configure IDLE dialog.
Show/Hide Code Context (Editor Window only)
Open a pane at the top of the edit window which shows the block context of the code which has scrolled above the top of the window. See Code Context in the Editing and Navigation section below.
+
Zoom/Restore Height
+
Toggles the window between normal size and maximum height. The initial size +defaults to 40 lines by 80 chars unless changed on the General tab of the +Configure IDLE dialog.
@@ -943,7 +943,7 @@

Navigation



- Last updated on May 19, 2019. + Last updated on May 25, 2019. Found a bug?
diff --git a/Lib/idlelib/zoomheight.py b/Lib/idlelib/zoomheight.py index 35e285f0ba414b..523f5d51e02fd2 100644 --- a/Lib/idlelib/zoomheight.py +++ b/Lib/idlelib/zoomheight.py @@ -28,26 +28,14 @@ def zoom_height(top): return width, height, x, y = map(int, m.groups()) newheight = top.winfo_screenheight() - if sys.platform == 'win32': - newy = 0 - newheight = newheight - 72 - - elif macosx.isAquaTk(): - # The '88' below is a magic number that avoids placing the bottom - # of the window below the panel on my machine. I don't know how - # to calculate the correct value for this with tkinter. - newy = 22 - newheight = newheight - newy - 88 - - else: - #newy = 24 - newy = 0 - #newheight = newheight - 96 - newheight = newheight - 88 - if height >= newheight: - newgeom = "" - else: - newgeom = "%dx%d+%d+%d" % (width, newheight, x, newy) + + # The constants below for Windows and Mac Aqua are visually determined + # to avoid taskbar or menubar and app icons. + newy, bot_y = ((0, 72) if sys.platform == 'win32' else + (22, 88) if macosx.isAquaTk() else + (0, 88) ) # Guess for anything else. + newheight = newheight - newy - bot_y + newgeom = '' if height >= newheight else f"{width}x{newheight}+{x}+{newy}" top.wm_geometry(newgeom) return newgeom != "" From a3568417c49f36860393075b21c93996a5f6799b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 28 May 2019 01:44:21 +0200 Subject: [PATCH 136/441] bpo-37054, _pyio: Fix BytesIO and TextIOWrapper __del__() (GH-13601) Fix destructor _pyio.BytesIO and _pyio.TextIOWrapper: initialize their _buffer attribute as soon as possible (in the class body), because it's used by __del__() which calls close(). --- Lib/_pyio.py | 11 ++++++++++- .../Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 5baca4df82ff44..43c24342ad6162 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -873,6 +873,10 @@ class BytesIO(BufferedIOBase): """Buffered I/O implementation using an in-memory bytes buffer.""" + # Initialize _buffer as soon as possible since it's used by __del__() + # which calls close() + _buffer = None + def __init__(self, initial_bytes=None): buf = bytearray() if initial_bytes is not None: @@ -900,7 +904,8 @@ def getbuffer(self): return memoryview(self._buffer) def close(self): - self._buffer.clear() + if self._buffer is not None: + self._buffer.clear() super().close() def read(self, size=-1): @@ -1970,6 +1975,10 @@ class TextIOWrapper(TextIOBase): _CHUNK_SIZE = 2048 + # Initialize _buffer as soon as possible since it's used by __del__() + # which calls close() + _buffer = None + # The write_through argument has no effect here since this # implementation always writes through. The argument is present only # so that the signature can match the signature of the C version. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst b/Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst new file mode 100644 index 00000000000000..9a2433abd0d000 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst @@ -0,0 +1,3 @@ +Fix destructor :class:`_pyio.BytesIO` and :class:`_pyio.TextIOWrapper`: +initialize their ``_buffer`` attribute as soon as possible (in the class +body), because it's used by ``__del__()`` which calls ``close()``. From f0d4c64019ecf8a5f362aa5a478786241613e5c3 Mon Sep 17 00:00:00 2001 From: sbstp Date: Mon, 27 May 2019 19:51:19 -0400 Subject: [PATCH 137/441] bpo-36686: Improve the documentation of the std* params in loop.subprocess_exec (GH-13586) https://bugs.python.org/issue36686 --- Doc/library/asyncio-eventloop.rst | 68 +++++++++----- Lib/asyncio/base_events.py | 19 +++- Lib/test/test_asyncio/test_subprocess.py | 90 +++++++++++++++++++ .../2019-05-27-17-28-58.bpo-36686.Zot4sx.rst | 6 ++ 4 files changed, 158 insertions(+), 25 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 06f673be7902c2..4acd23f594652a 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -1217,32 +1217,52 @@ async/await code consider using the high-level Other parameters: - * *stdin*: either a file-like object representing a pipe to be - connected to the subprocess's standard input stream using - :meth:`~loop.connect_write_pipe`, or the - :const:`subprocess.PIPE` constant (default). By default a new - pipe will be created and connected. - - * *stdout*: either a file-like object representing the pipe to be - connected to the subprocess's standard output stream using - :meth:`~loop.connect_read_pipe`, or the - :const:`subprocess.PIPE` constant (default). By default a new pipe - will be created and connected. - - * *stderr*: either a file-like object representing the pipe to be - connected to the subprocess's standard error stream using - :meth:`~loop.connect_read_pipe`, or one of - :const:`subprocess.PIPE` (default) or :const:`subprocess.STDOUT` - constants. - - By default a new pipe will be created and connected. When - :const:`subprocess.STDOUT` is specified, the subprocess' standard - error stream will be connected to the same pipe as the standard - output stream. + * *stdin* can be any of these: + + * a file-like object representing a pipe to be connected to the + subprocess's standard input stream using + :meth:`~loop.connect_write_pipe` + * the :const:`subprocess.PIPE` constant (default) which will create a new + pipe and connect it, + * the value ``None`` which will make the subprocess inherit the file + descriptor from this process + * the :const:`subprocess.DEVNULL` constant which indicates that the + special :data:`os.devnull` file will be used + + * *stdout* can be any of these: + + * a file-like object representing a pipe to be connected to the + subprocess's standard output stream using + :meth:`~loop.connect_write_pipe` + * the :const:`subprocess.PIPE` constant (default) which will create a new + pipe and connect it, + * the value ``None`` which will make the subprocess inherit the file + descriptor from this process + * the :const:`subprocess.DEVNULL` constant which indicates that the + special :data:`os.devnull` file will be used + + * *stderr* can be any of these: + + * a file-like object representing a pipe to be connected to the + subprocess's standard error stream using + :meth:`~loop.connect_write_pipe` + * the :const:`subprocess.PIPE` constant (default) which will create a new + pipe and connect it, + * the value ``None`` which will make the subprocess inherit the file + descriptor from this process + * the :const:`subprocess.DEVNULL` constant which indicates that the + special :data:`os.devnull` file will be used + * the :const:`subprocess.STDOUT` constant which will connect the standard + error stream to the process' standard output stream * All other keyword arguments are passed to :class:`subprocess.Popen` - without interpretation, except for *bufsize*, *universal_newlines* - and *shell*, which should not be specified at all. + without interpretation, except for *bufsize*, *universal_newlines*, + *shell*, *text*, *encoding* and *errors*, which should not be specified + at all. + + The ``asyncio`` subprocess API does not support decoding the streams + as text. :func:`bytes.decode` can be used to convert the bytes returned + from the stream to text. See the constructor of the :class:`subprocess.Popen` class for documentation on other arguments. diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index e5cd14b59af5d6..68105eec8132e7 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1555,6 +1555,7 @@ async def subprocess_shell(self, protocol_factory, cmd, *, stderr=subprocess.PIPE, universal_newlines=False, shell=True, bufsize=0, + encoding=None, errors=None, text=None, **kwargs): if not isinstance(cmd, (bytes, str)): raise ValueError("cmd must be a string") @@ -1564,6 +1565,13 @@ async def subprocess_shell(self, protocol_factory, cmd, *, raise ValueError("shell must be True") if bufsize != 0: raise ValueError("bufsize must be 0") + if text: + raise ValueError("text must be False") + if encoding is not None: + raise ValueError("encoding must be None") + if errors is not None: + raise ValueError("errors must be None") + protocol = protocol_factory() debug_log = None if self._debug: @@ -1580,13 +1588,22 @@ async def subprocess_shell(self, protocol_factory, cmd, *, async def subprocess_exec(self, protocol_factory, program, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, - shell=False, bufsize=0, **kwargs): + shell=False, bufsize=0, + encoding=None, errors=None, text=None, + **kwargs): if universal_newlines: raise ValueError("universal_newlines must be False") if shell: raise ValueError("shell must be False") if bufsize != 0: raise ValueError("bufsize must be 0") + if text: + raise ValueError("text must be False") + if encoding is not None: + raise ValueError("encoding must be None") + if errors is not None: + raise ValueError("errors must be None") + popen_args = (program,) + args for arg in popen_args: if not isinstance(arg, (str, bytes)): diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 551974a1806a84..f1ab039ad6639b 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -335,6 +335,63 @@ async def empty_input(): self.assertEqual(output.rstrip(), b'0') self.assertEqual(exitcode, 0) + def test_devnull_input(self): + + async def empty_input(): + code = 'import sys; data = sys.stdin.read(); print(len(data))' + proc = await asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.DEVNULL, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + close_fds=False, + loop=self.loop) + stdout, stderr = await proc.communicate() + exitcode = await proc.wait() + return (stdout, exitcode) + + output, exitcode = self.loop.run_until_complete(empty_input()) + self.assertEqual(output.rstrip(), b'0') + self.assertEqual(exitcode, 0) + + def test_devnull_output(self): + + async def empty_output(): + code = 'import sys; data = sys.stdin.read(); print(len(data))' + proc = await asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.DEVNULL, + stderr=asyncio.subprocess.PIPE, + close_fds=False, + loop=self.loop) + stdout, stderr = await proc.communicate(b"abc") + exitcode = await proc.wait() + return (stdout, exitcode) + + output, exitcode = self.loop.run_until_complete(empty_output()) + self.assertEqual(output, None) + self.assertEqual(exitcode, 0) + + def test_devnull_error(self): + + async def empty_error(): + code = 'import sys; data = sys.stdin.read(); print(len(data))' + proc = await asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.DEVNULL, + close_fds=False, + loop=self.loop) + stdout, stderr = await proc.communicate(b"abc") + exitcode = await proc.wait() + return (stderr, exitcode) + + output, exitcode = self.loop.run_until_complete(empty_error()) + self.assertEqual(output, None) + self.assertEqual(exitcode, 0) + def test_cancel_process_wait(self): # Issue #23140: cancel Process.wait() @@ -531,6 +588,39 @@ def test_process_create_warning(self): with self.assertWarns(DeprecationWarning): subprocess.Process(transp, proto, loop=self.loop) + def test_create_subprocess_exec_text_mode_fails(self): + async def execute(): + with self.assertRaises(ValueError): + await subprocess.create_subprocess_exec(sys.executable, + text=True) + + with self.assertRaises(ValueError): + await subprocess.create_subprocess_exec(sys.executable, + encoding="utf-8") + + with self.assertRaises(ValueError): + await subprocess.create_subprocess_exec(sys.executable, + errors="strict") + + self.loop.run_until_complete(execute()) + + def test_create_subprocess_shell_text_mode_fails(self): + + async def execute(): + with self.assertRaises(ValueError): + await subprocess.create_subprocess_shell(sys.executable, + text=True) + + with self.assertRaises(ValueError): + await subprocess.create_subprocess_shell(sys.executable, + encoding="utf-8") + + with self.assertRaises(ValueError): + await subprocess.create_subprocess_shell(sys.executable, + errors="strict") + + self.loop.run_until_complete(execute()) + if sys.platform != 'win32': # Unix diff --git a/Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst b/Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst new file mode 100644 index 00000000000000..2ea42adf131735 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst @@ -0,0 +1,6 @@ +Improve documentation of the stdin, stdout, and stderr arguments of of the +``asyncio.subprocess_exec`` function to specficy which values are supported. +Also mention that decoding as text is not supported. + +Add a few tests to verify that the various values passed to the std* +arguments actually work. From 71dc7c5fbd856df83202f39c1f41ccd07c6eceb7 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Tue, 28 May 2019 00:15:48 -0400 Subject: [PATCH 138/441] Add @maxking to CODEOWNERS file (GH-13599) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fae5138435665e..1638a8b4b44370 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -37,7 +37,7 @@ Objects/dict* @methane Python/bootstrap_hash.c @python/crypto-team # Email and related -**/*mail* @python/email-team +**/*mail* @python/email-team @maxking **/*smtp* @python/email-team **/*mime* @python/email-team **/*imap* @python/email-team From 436c2b0d67da68465e709a96daac7340af3a5238 Mon Sep 17 00:00:00 2001 From: Xtreak Date: Tue, 28 May 2019 12:37:39 +0530 Subject: [PATCH 139/441] bpo-36996: Handle async functions when mock.patch is used as a decorator (GH-13562) Return a coroutine while patching async functions with a decorator. Co-authored-by: Andrew Svetlov https://bugs.python.org/issue36996 --- Lib/unittest/mock.py | 84 +++++++++++++------ Lib/unittest/test/testmock/testasync.py | 16 ++++ .../2019-05-22-22-55-18.bpo-36996.XQx08d.rst | 1 + 3 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index b91afd88dd132e..fac4535747c4c8 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -26,6 +26,7 @@ __version__ = '1.0' import asyncio +import contextlib import io import inspect import pprint @@ -1220,6 +1221,8 @@ def copy(self): def __call__(self, func): if isinstance(func, type): return self.decorate_class(func) + if inspect.iscoroutinefunction(func): + return self.decorate_async_callable(func) return self.decorate_callable(func) @@ -1237,41 +1240,68 @@ def decorate_class(self, klass): return klass + @contextlib.contextmanager + def decoration_helper(self, patched, args, keywargs): + extra_args = [] + entered_patchers = [] + patching = None + + exc_info = tuple() + try: + for patching in patched.patchings: + arg = patching.__enter__() + entered_patchers.append(patching) + if patching.attribute_name is not None: + keywargs.update(arg) + elif patching.new is DEFAULT: + extra_args.append(arg) + + args += tuple(extra_args) + yield (args, keywargs) + except: + if (patching not in entered_patchers and + _is_started(patching)): + # the patcher may have been started, but an exception + # raised whilst entering one of its additional_patchers + entered_patchers.append(patching) + # Pass the exception to __exit__ + exc_info = sys.exc_info() + # re-raise the exception + raise + finally: + for patching in reversed(entered_patchers): + patching.__exit__(*exc_info) + + def decorate_callable(self, func): + # NB. Keep the method in sync with decorate_async_callable() if hasattr(func, 'patchings'): func.patchings.append(self) return func @wraps(func) def patched(*args, **keywargs): - extra_args = [] - entered_patchers = [] + with self.decoration_helper(patched, + args, + keywargs) as (newargs, newkeywargs): + return func(*newargs, **newkeywargs) - exc_info = tuple() - try: - for patching in patched.patchings: - arg = patching.__enter__() - entered_patchers.append(patching) - if patching.attribute_name is not None: - keywargs.update(arg) - elif patching.new is DEFAULT: - extra_args.append(arg) - - args += tuple(extra_args) - return func(*args, **keywargs) - except: - if (patching not in entered_patchers and - _is_started(patching)): - # the patcher may have been started, but an exception - # raised whilst entering one of its additional_patchers - entered_patchers.append(patching) - # Pass the exception to __exit__ - exc_info = sys.exc_info() - # re-raise the exception - raise - finally: - for patching in reversed(entered_patchers): - patching.__exit__(*exc_info) + patched.patchings = [self] + return patched + + + def decorate_async_callable(self, func): + # NB. Keep the method in sync with decorate_callable() + if hasattr(func, 'patchings'): + func.patchings.append(self) + return func + + @wraps(func) + async def patched(*args, **keywargs): + with self.decoration_helper(patched, + args, + keywargs) as (newargs, newkeywargs): + return await func(*newargs, **newkeywargs) patched.patchings = [self] return patched diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index 0519d59696f6c6..ccea4fe242dc07 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -66,6 +66,14 @@ def test_async(mock_method): test_async() + def test_async_def_patch(self): + @patch(f"{__name__}.async_func", AsyncMock()) + async def test_async(): + self.assertIsInstance(async_func, AsyncMock) + + asyncio.run(test_async()) + self.assertTrue(inspect.iscoroutinefunction(async_func)) + class AsyncPatchCMTest(unittest.TestCase): def test_is_async_function_cm(self): @@ -91,6 +99,14 @@ def test_async(): test_async() + def test_async_def_cm(self): + async def test_async(): + with patch(f"{__name__}.async_func", AsyncMock()): + self.assertIsInstance(async_func, AsyncMock) + self.assertTrue(inspect.iscoroutinefunction(async_func)) + + asyncio.run(test_async()) + class AsyncMockTest(unittest.TestCase): def test_iscoroutinefunction_default(self): diff --git a/Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst b/Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst new file mode 100644 index 00000000000000..69d18d9713b4f7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst @@ -0,0 +1 @@ +Handle :func:`unittest.mock.patch` used as a decorator on async functions. From 3880f263d2994fb1eba25835dddccb0cf696fdf0 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 28 May 2019 00:10:59 -0700 Subject: [PATCH 140/441] bpo-36933: Remove sys.set_coroutine_wrapper (marked for removal in 3.8) (GH-13577) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has been documented as deprecated and to be removed in 3.8; From a comment on another thread – which I can't find ; leave get_coro_wrapper() for now, but always return `None`. https://bugs.python.org/issue36933 --- Doc/library/sys.rst | 59 ------------ Doc/tools/susp-ignored.csv | 1 - Doc/whatsnew/3.8.rst | 4 + Include/ceval.h | 2 - Include/cpython/pystate.h | 3 - Lib/test/test_coroutines.py | 93 ------------------- .../2019-05-26-10-16-55.bpo-36933.4w3eP9.rst | 2 + Python/ceval.c | 39 -------- Python/clinic/sysmodule.c.h | 29 +----- Python/pystate.c | 4 - Python/sysmodule.c | 58 ------------ 11 files changed, 7 insertions(+), 287 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 74aa2711dd01be..5bde6870717c90 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -781,22 +781,6 @@ always available. for details.) Use it only for debugging purposes. -.. function:: get_coroutine_wrapper() - - Returns ``None``, or a wrapper set by :func:`set_coroutine_wrapper`. - - .. versionadded:: 3.5 - See :pep:`492` for more details. - - .. note:: - This function has been added on a provisional basis (see :pep:`411` - for details.) Use it only for debugging purposes. - - .. deprecated:: 3.7 - The coroutine wrapper functionality has been deprecated, and - will be removed in 3.8. See :issue:`32591` for details. - - .. data:: hash_info A :term:`struct sequence` giving parameters of the numeric hash @@ -1384,49 +1368,6 @@ always available. This function has been added on a provisional basis (see :pep:`411` for details.) Use it only for debugging purposes. -.. function:: set_coroutine_wrapper(wrapper) - - Allows intercepting creation of :term:`coroutine` objects (only ones that - are created by an :keyword:`async def` function; generators decorated with - :func:`types.coroutine` or :func:`asyncio.coroutine` will not be - intercepted). - - The *wrapper* argument must be either: - - * a callable that accepts one argument (a coroutine object); - * ``None``, to reset the wrapper. - - If called twice, the new wrapper replaces the previous one. The function - is thread-specific. - - The *wrapper* callable cannot define new coroutines directly or indirectly:: - - def wrapper(coro): - async def wrap(coro): - return await coro - return wrap(coro) - sys.set_coroutine_wrapper(wrapper) - - async def foo(): - pass - - # The following line will fail with a RuntimeError, because - # ``wrapper`` creates a ``wrap(coro)`` coroutine: - foo() - - See also :func:`get_coroutine_wrapper`. - - .. versionadded:: 3.5 - See :pep:`492` for more details. - - .. note:: - This function has been added on a provisional basis (see :pep:`411` - for details.) Use it only for debugging purposes. - - .. deprecated-removed:: 3.7 3.8 - The coroutine wrapper functionality has been deprecated, and - will be removed in 3.8. See :issue:`32591` for details. - .. function:: _enablelegacywindowsfsencoding() Changes the default filesystem encoding and errors mode to 'mbcs' and diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index a0e7868a037ac0..85263d47c8bba8 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -337,7 +337,6 @@ library/zipapp,,:main,"$ python -m zipapp myapp -m ""myapp:main""" library/zipapp,,:fn,"pkg.mod:fn" library/zipapp,,:callable,"pkg.module:callable" library/stdtypes,,::,>>> m[::2].tolist() -library/sys,,`,# ``wrapper`` creates a ``wrap(coro)`` coroutine: whatsnew/3.5,,:root,'WARNING:root:warning\n' whatsnew/3.5,,:warning,'WARNING:root:warning\n' whatsnew/3.5,,::,>>> addr6 = ipaddress.IPv6Address('::1') diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 125cefe1113356..860d6cc18f1152 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -973,6 +973,10 @@ The following features and APIs have been removed from Python 3.8: :func:`fileinput.FileInput` which was ignored and deprecated since Python 3.6 has been removed. :issue:`36952` (Contributed by Matthias Bussonnier) +* The function :func:`sys.set_coroutine_wrapper` deprecated in Python 3.7 has + been removed; :func:`sys.get_coroutine_wrapper` now always return ``None``. + :issue:`36933` (Contributed by Matthias Bussonnier) + Porting to Python 3.8 ===================== diff --git a/Include/ceval.h b/Include/ceval.h index 8cdf353b05fd07..6fb224b2885017 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -33,8 +33,6 @@ PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth(int new_depth); PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); -PyAPI_FUNC(void) _PyEval_SetCoroutineWrapper(PyObject *); -PyAPI_FUNC(PyObject *) _PyEval_GetCoroutineWrapper(void); PyAPI_FUNC(void) _PyEval_SetAsyncGenFirstiter(PyObject *); PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); PyAPI_FUNC(void) _PyEval_SetAsyncGenFinalizer(PyObject *); diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 6b7663fe33157a..94b0809cd4f015 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -126,9 +126,6 @@ struct _ts { int coroutine_origin_tracking_depth; - PyObject *coroutine_wrapper; - int in_coroutine_wrapper; - PyObject *async_gen_firstiter; PyObject *async_gen_finalizer; diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 036f13fa50e9ae..0e7eb3a1af47eb 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2146,99 +2146,6 @@ async def f(): self.assertEqual(buffer, [1, 2, 'MyException']) -class SysSetCoroWrapperTest(unittest.TestCase): - - def test_set_wrapper_1(self): - async def foo(): - return 'spam' - - wrapped = None - def wrap(gen): - nonlocal wrapped - wrapped = gen - return gen - - with self.assertWarns(DeprecationWarning): - self.assertIsNone(sys.get_coroutine_wrapper()) - - with self.assertWarns(DeprecationWarning): - sys.set_coroutine_wrapper(wrap) - with self.assertWarns(DeprecationWarning): - self.assertIs(sys.get_coroutine_wrapper(), wrap) - try: - f = foo() - self.assertTrue(wrapped) - - self.assertEqual(run_async(f), ([], 'spam')) - finally: - with self.assertWarns(DeprecationWarning): - sys.set_coroutine_wrapper(None) - f.close() - - with self.assertWarns(DeprecationWarning): - self.assertIsNone(sys.get_coroutine_wrapper()) - - wrapped = None - coro = foo() - self.assertFalse(wrapped) - coro.close() - - def test_set_wrapper_2(self): - with self.assertWarns(DeprecationWarning): - self.assertIsNone(sys.get_coroutine_wrapper()) - with self.assertRaisesRegex(TypeError, "callable expected, got int"): - with self.assertWarns(DeprecationWarning): - sys.set_coroutine_wrapper(1) - with self.assertWarns(DeprecationWarning): - self.assertIsNone(sys.get_coroutine_wrapper()) - - def test_set_wrapper_3(self): - async def foo(): - return 'spam' - - def wrapper(coro): - async def wrap(coro): - return await coro - return wrap(coro) - - with self.assertWarns(DeprecationWarning): - sys.set_coroutine_wrapper(wrapper) - try: - with silence_coro_gc(), self.assertRaisesRegex( - RuntimeError, - r"coroutine wrapper.*\.wrapper at 0x.*attempted to " - r"recursively wrap .* wrap .*"): - - foo() - - finally: - with self.assertWarns(DeprecationWarning): - sys.set_coroutine_wrapper(None) - - def test_set_wrapper_4(self): - @types.coroutine - def foo(): - return 'spam' - - wrapped = None - def wrap(gen): - nonlocal wrapped - wrapped = gen - return gen - - with self.assertWarns(DeprecationWarning): - sys.set_coroutine_wrapper(wrap) - try: - foo() - self.assertIs( - wrapped, None, - "generator-based coroutine was wrapped via " - "sys.set_coroutine_wrapper") - finally: - with self.assertWarns(DeprecationWarning): - sys.set_coroutine_wrapper(None) - - class OriginTrackingTest(unittest.TestCase): def here(self): info = inspect.getframeinfo(inspect.currentframe().f_back) diff --git a/Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst b/Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst new file mode 100644 index 00000000000000..dc2be7a140cf78 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst @@ -0,0 +1,2 @@ +The functions ``sys.set_coroutine_wrapper`` and ``sys.get_coroutine_wrapper`` +that were deprecated and marked for removal in 3.8 have been removed. diff --git a/Python/ceval.c b/Python/ceval.c index cb5a4beb2a6633..9263df9b8fc490 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4143,19 +4143,8 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, /* Handle generator/coroutine/asynchronous generator */ if (co->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { PyObject *gen; - PyObject *coro_wrapper = tstate->coroutine_wrapper; int is_coro = co->co_flags & CO_COROUTINE; - if (is_coro && tstate->in_coroutine_wrapper) { - assert(coro_wrapper != NULL); - _PyErr_Format(tstate, PyExc_RuntimeError, - "coroutine wrapper %.200R attempted " - "to recursively wrap %.200R", - coro_wrapper, - co); - goto fail; - } - /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ Py_CLEAR(f->f_back); @@ -4175,14 +4164,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, _PyObject_GC_TRACK(f); - if (is_coro && coro_wrapper != NULL) { - PyObject *wrapped; - tstate->in_coroutine_wrapper = 1; - wrapped = PyObject_CallFunction(coro_wrapper, "N", gen); - tstate->in_coroutine_wrapper = 0; - return wrapped; - } - return gen; } @@ -4633,26 +4614,6 @@ _PyEval_GetCoroutineOriginTrackingDepth(void) return tstate->coroutine_origin_tracking_depth; } -void -_PyEval_SetCoroutineWrapper(PyObject *wrapper) -{ - PyThreadState *tstate = _PyThreadState_GET(); - - if (PySys_Audit("sys.set_coroutine_wrapper", NULL) < 0) { - return; - } - - Py_XINCREF(wrapper); - Py_XSETREF(tstate->coroutine_wrapper, wrapper); -} - -PyObject * -_PyEval_GetCoroutineWrapper(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return tstate->coroutine_wrapper; -} - void _PyEval_SetAsyncGenFirstiter(PyObject *firstiter) { diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 5df8af1a1172c6..6f248ff18d9d7f 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -510,33 +510,6 @@ sys_get_coroutine_origin_tracking_depth(PyObject *module, PyObject *Py_UNUSED(ig return return_value; } -PyDoc_STRVAR(sys_set_coroutine_wrapper__doc__, -"set_coroutine_wrapper($module, wrapper, /)\n" -"--\n" -"\n" -"Set a wrapper for coroutine objects."); - -#define SYS_SET_COROUTINE_WRAPPER_METHODDEF \ - {"set_coroutine_wrapper", (PyCFunction)sys_set_coroutine_wrapper, METH_O, sys_set_coroutine_wrapper__doc__}, - -PyDoc_STRVAR(sys_get_coroutine_wrapper__doc__, -"get_coroutine_wrapper($module, /)\n" -"--\n" -"\n" -"Return the wrapper for coroutines set by sys.set_coroutine_wrapper."); - -#define SYS_GET_COROUTINE_WRAPPER_METHODDEF \ - {"get_coroutine_wrapper", (PyCFunction)sys_get_coroutine_wrapper, METH_NOARGS, sys_get_coroutine_wrapper__doc__}, - -static PyObject * -sys_get_coroutine_wrapper_impl(PyObject *module); - -static PyObject * -sys_get_coroutine_wrapper(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys_get_coroutine_wrapper_impl(module); -} - PyDoc_STRVAR(sys_get_asyncgen_hooks__doc__, "get_asyncgen_hooks($module, /)\n" "--\n" @@ -1109,4 +1082,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=03da2eb03135d9f2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=43c4fde7b5783d8d input=a9049054013a1b77]*/ diff --git a/Python/pystate.c b/Python/pystate.c index d1a8d24724707e..833e0fb30dcb26 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -606,9 +606,6 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->coroutine_origin_tracking_depth = 0; - tstate->coroutine_wrapper = NULL; - tstate->in_coroutine_wrapper = 0; - tstate->async_gen_firstiter = NULL; tstate->async_gen_finalizer = NULL; @@ -802,7 +799,6 @@ PyThreadState_Clear(PyThreadState *tstate) Py_CLEAR(tstate->c_profileobj); Py_CLEAR(tstate->c_traceobj); - Py_CLEAR(tstate->coroutine_wrapper); Py_CLEAR(tstate->async_gen_firstiter); Py_CLEAR(tstate->async_gen_finalizer); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 24018e25fa579d..343601ec8596f1 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1158,62 +1158,6 @@ sys_get_coroutine_origin_tracking_depth_impl(PyObject *module) return _PyEval_GetCoroutineOriginTrackingDepth(); } -/*[clinic input] -sys.set_coroutine_wrapper - - wrapper: object - / - -Set a wrapper for coroutine objects. -[clinic start generated code]*/ - -static PyObject * -sys_set_coroutine_wrapper(PyObject *module, PyObject *wrapper) -/*[clinic end generated code: output=9c7db52d65f6b188 input=df6ac09a06afef34]*/ -{ - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "set_coroutine_wrapper is deprecated", 1) < 0) { - return NULL; - } - - if (wrapper != Py_None) { - if (!PyCallable_Check(wrapper)) { - PyErr_Format(PyExc_TypeError, - "callable expected, got %.50s", - Py_TYPE(wrapper)->tp_name); - return NULL; - } - _PyEval_SetCoroutineWrapper(wrapper); - } - else { - _PyEval_SetCoroutineWrapper(NULL); - } - Py_RETURN_NONE; -} - -/*[clinic input] -sys.get_coroutine_wrapper - -Return the wrapper for coroutines set by sys.set_coroutine_wrapper. -[clinic start generated code]*/ - -static PyObject * -sys_get_coroutine_wrapper_impl(PyObject *module) -/*[clinic end generated code: output=b74a7e4b14fe898e input=ef0351fb9ece0bb4]*/ -{ - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "get_coroutine_wrapper is deprecated", 1) < 0) { - return NULL; - } - PyObject *wrapper = _PyEval_GetCoroutineWrapper(); - if (wrapper == NULL) { - wrapper = Py_None; - } - Py_INCREF(wrapper); - return wrapper; -} - - static PyTypeObject AsyncGenHooksType; PyDoc_STRVAR(asyncgen_hooks_doc, @@ -2002,8 +1946,6 @@ static PyMethodDef sys_methods[] = { SYS__DEBUGMALLOCSTATS_METHODDEF SYS_SET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF SYS_GET_COROUTINE_ORIGIN_TRACKING_DEPTH_METHODDEF - SYS_SET_COROUTINE_WRAPPER_METHODDEF - SYS_GET_COROUTINE_WRAPPER_METHODDEF {"set_asyncgen_hooks", (PyCFunction)(void(*)(void))sys_set_asyncgen_hooks, METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, SYS_GET_ASYNCGEN_HOOKS_METHODDEF From 74d7f76e2c953fbfdb7ce01b7319d91d471cc5ef Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Tue, 28 May 2019 08:40:15 +0100 Subject: [PATCH 141/441] bpo-37058: PEP 544: Add Protocol to typing module (GH-13585) I tried to get rid of the `_ProtocolMeta`, but unfortunately it didn'y work. My idea to return a generic alias from `@runtime_checkable` made runtime protocols unpickleable. I am not sure what is worse (a custom metaclass or having some classes unpickleable), so I decided to stick with the status quo (since there were no complains so far). So essentially this is a copy of the implementation in `typing_extensions` with two modifications: * Rename `@runtime` to `@runtime_checkable` (plus corresponding updates). * Allow protocols that extend `collections.abc.Iterable` etc. --- Doc/library/typing.rst | 98 ++- Lib/test/test_typing.py | 731 +++++++++++++++++- Lib/typing.py | 342 +++++--- .../2019-05-26-19-05-24.bpo-37058.jmRu_g.rst | 1 + 4 files changed, 1053 insertions(+), 119 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 27787fc2cb86b3..709580ad2159df 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -17,7 +17,8 @@ -------------- -This module supports type hints as specified by :pep:`484` and :pep:`526`. +This module provides runtime support for type hints as specified by +:pep:`484`, :pep:`526`, :pep:`544`, :pep:`586`, :pep:`589`, and :pep:`591`. The most fundamental support consists of the types :data:`Any`, :data:`Union`, :data:`Tuple`, :data:`Callable`, :class:`TypeVar`, and :class:`Generic`. For full specification please see :pep:`484`. For @@ -392,6 +393,48 @@ it as a return value) of a more specialized type is a type error. For example:: Use :class:`object` to indicate that a value could be any type in a typesafe manner. Use :data:`Any` to indicate that a value is dynamically typed. + +Nominal vs structural subtyping +------------------------------- + +Initially :pep:`484` defined Python static type system as using +*nominal subtyping*. This means that a class ``A`` is allowed where +a class ``B`` is expected if and only if ``A`` is a subclass of ``B``. + +This requirement previously also applied to abstract base classes, such as +:class:`Iterable`. The problem with this approach is that a class had +to be explicitly marked to support them, which is unpythonic and unlike +what one would normally do in idiomatic dynamically typed Python code. +For example, this conforms to the :pep:`484`:: + + from typing import Sized, Iterable, Iterator + + class Bucket(Sized, Iterable[int]): + ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[int]: ... + +:pep:`544` allows to solve this problem by allowing users to write +the above code without explicit base classes in the class definition, +allowing ``Bucket`` to be implicitly considered a subtype of both ``Sized`` +and ``Iterable[int]`` by static type checkers. This is known as +*structural subtyping* (or static duck-typing):: + + from typing import Iterator, Iterable + + class Bucket: # Note: no base classes + ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[int]: ... + + def collect(items: Iterable[int]) -> int: ... + result = collect(Bucket()) # Passes type check + +Moreover, by subclassing a special class :class:`Protocol`, a user +can define new custom protocols to fully enjoy structural subtyping +(see examples below). + + Classes, functions, and decorators ---------------------------------- @@ -459,6 +502,39 @@ The module defines the following classes, functions and decorators: except KeyError: return default +.. class:: Protocol(Generic) + + Base class for protocol classes. Protocol classes are defined like this:: + + class Proto(Protocol): + def meth(self) -> int: + ... + + Such classes are primarily used with static type checkers that recognize + structural subtyping (static duck-typing), for example:: + + class C: + def meth(self) -> int: + return 0 + + def func(x: Proto) -> int: + return x.meth() + + func(C()) # Passes static type check + + See :pep:`544` for details. Protocol classes decorated with + :func:`runtime_checkable` (described later) act as simple-minded runtime + protocols that check only the presence of given attributes, ignoring their + type signatures. + + Protocol classes can be generic, for example:: + + class GenProto(Protocol[T]): + def meth(self) -> T: + ... + + .. versionadded:: 3.8 + .. class:: Type(Generic[CT_co]) A variable annotated with ``C`` may accept a value of type ``C``. In @@ -1033,6 +1109,26 @@ The module defines the following classes, functions and decorators: Note that returning instances of private classes is not recommended. It is usually preferable to make such classes public. +.. decorator:: runtime_checkable + + Mark a protocol class as a runtime protocol. + + Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. + This raises :exc:`TypeError` when applied to a non-protocol class. This + allows a simple-minded structural check, very similar to "one trick ponies" + in :mod:`collections.abc` such as :class:`Iterable`. For example:: + + @runtime_checkable + class Closable(Protocol): + def close(self): ... + + assert isinstance(open('/some/file'), Closable) + + **Warning:** this will check only the presence of the required methods, + not their type signatures! + + .. versionadded:: 3.8 + .. data:: Any Special type indicating an unconstrained type. diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 46b7621182d6fd..2b4b934d69f2b5 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -12,8 +12,8 @@ from typing import Union, Optional, Literal from typing import Tuple, List, MutableMapping from typing import Callable -from typing import Generic, ClassVar, Final, final -from typing import cast +from typing import Generic, ClassVar, Final, final, Protocol +from typing import cast, runtime_checkable from typing import get_type_hints from typing import no_type_check, no_type_check_decorator from typing import Type @@ -24,6 +24,7 @@ import abc import typing import weakref +import types from test import mod_generics_cache @@ -585,7 +586,710 @@ def get(self, key: str, default=None): return default +class Coordinate(Protocol): + x: int + y: int + +@runtime_checkable +class Point(Coordinate, Protocol): + label: str + +class MyPoint: + x: int + y: int + label: str + +class XAxis(Protocol): + x: int + +class YAxis(Protocol): + y: int + +@runtime_checkable +class Position(XAxis, YAxis, Protocol): + pass + +@runtime_checkable +class Proto(Protocol): + attr: int + def meth(self, arg: str) -> int: + ... + +class Concrete(Proto): + pass + +class Other: + attr: int = 1 + def meth(self, arg: str) -> int: + if arg == 'this': + return 1 + return 0 + +class NT(NamedTuple): + x: int + y: int + +@runtime_checkable +class HasCallProtocol(Protocol): + __call__: typing.Callable + + class ProtocolTests(BaseTestCase): + def test_basic_protocol(self): + @runtime_checkable + class P(Protocol): + def meth(self): + pass + + class C: pass + + class D: + def meth(self): + pass + + def f(): + pass + + self.assertIsSubclass(D, P) + self.assertIsInstance(D(), P) + self.assertNotIsSubclass(C, P) + self.assertNotIsInstance(C(), P) + self.assertNotIsSubclass(types.FunctionType, P) + self.assertNotIsInstance(f, P) + + def test_everything_implements_empty_protocol(self): + @runtime_checkable + class Empty(Protocol): + pass + + class C: + pass + + def f(): + pass + + for thing in (object, type, tuple, C, types.FunctionType): + self.assertIsSubclass(thing, Empty) + for thing in (object(), 1, (), typing, f): + self.assertIsInstance(thing, Empty) + + def test_function_implements_protocol(self): + def f(): + pass + + self.assertIsInstance(f, HasCallProtocol) + + def test_no_inheritance_from_nominal(self): + class C: pass + + class BP(Protocol): pass + + with self.assertRaises(TypeError): + class P(C, Protocol): + pass + with self.assertRaises(TypeError): + class P(Protocol, C): + pass + with self.assertRaises(TypeError): + class P(BP, C, Protocol): + pass + + class D(BP, C): pass + + class E(C, BP): pass + + self.assertNotIsInstance(D(), E) + self.assertNotIsInstance(E(), D) + + def test_no_instantiation(self): + class P(Protocol): pass + + with self.assertRaises(TypeError): + P() + + class C(P): pass + + self.assertIsInstance(C(), C) + T = TypeVar('T') + + class PG(Protocol[T]): pass + + with self.assertRaises(TypeError): + PG() + with self.assertRaises(TypeError): + PG[int]() + with self.assertRaises(TypeError): + PG[T]() + + class CG(PG[T]): pass + + self.assertIsInstance(CG[int](), CG) + + def test_cannot_instantiate_abstract(self): + @runtime_checkable + class P(Protocol): + @abc.abstractmethod + def ameth(self) -> int: + raise NotImplementedError + + class B(P): + pass + + class C(B): + def ameth(self) -> int: + return 26 + + with self.assertRaises(TypeError): + B() + self.assertIsInstance(C(), P) + + def test_subprotocols_extending(self): + class P1(Protocol): + def meth1(self): + pass + + @runtime_checkable + class P2(P1, Protocol): + def meth2(self): + pass + + class C: + def meth1(self): + pass + + def meth2(self): + pass + + class C1: + def meth1(self): + pass + + class C2: + def meth2(self): + pass + + self.assertNotIsInstance(C1(), P2) + self.assertNotIsInstance(C2(), P2) + self.assertNotIsSubclass(C1, P2) + self.assertNotIsSubclass(C2, P2) + self.assertIsInstance(C(), P2) + self.assertIsSubclass(C, P2) + + def test_subprotocols_merging(self): + class P1(Protocol): + def meth1(self): + pass + + class P2(Protocol): + def meth2(self): + pass + + @runtime_checkable + class P(P1, P2, Protocol): + pass + + class C: + def meth1(self): + pass + + def meth2(self): + pass + + class C1: + def meth1(self): + pass + + class C2: + def meth2(self): + pass + + self.assertNotIsInstance(C1(), P) + self.assertNotIsInstance(C2(), P) + self.assertNotIsSubclass(C1, P) + self.assertNotIsSubclass(C2, P) + self.assertIsInstance(C(), P) + self.assertIsSubclass(C, P) + + def test_protocols_issubclass(self): + T = TypeVar('T') + + @runtime_checkable + class P(Protocol): + def x(self): ... + + @runtime_checkable + class PG(Protocol[T]): + def x(self): ... + + class BadP(Protocol): + def x(self): ... + + class BadPG(Protocol[T]): + def x(self): ... + + class C: + def x(self): ... + + self.assertIsSubclass(C, P) + self.assertIsSubclass(C, PG) + self.assertIsSubclass(BadP, PG) + + with self.assertRaises(TypeError): + issubclass(C, PG[T]) + with self.assertRaises(TypeError): + issubclass(C, PG[C]) + with self.assertRaises(TypeError): + issubclass(C, BadP) + with self.assertRaises(TypeError): + issubclass(C, BadPG) + with self.assertRaises(TypeError): + issubclass(P, PG[T]) + with self.assertRaises(TypeError): + issubclass(PG, PG[int]) + + def test_protocols_issubclass_non_callable(self): + class C: + x = 1 + + @runtime_checkable + class PNonCall(Protocol): + x = 1 + + with self.assertRaises(TypeError): + issubclass(C, PNonCall) + self.assertIsInstance(C(), PNonCall) + PNonCall.register(C) + with self.assertRaises(TypeError): + issubclass(C, PNonCall) + self.assertIsInstance(C(), PNonCall) + + # check that non-protocol subclasses are not affected + class D(PNonCall): ... + + self.assertNotIsSubclass(C, D) + self.assertNotIsInstance(C(), D) + D.register(C) + self.assertIsSubclass(C, D) + self.assertIsInstance(C(), D) + with self.assertRaises(TypeError): + issubclass(D, PNonCall) + + def test_protocols_isinstance(self): + T = TypeVar('T') + + @runtime_checkable + class P(Protocol): + def meth(x): ... + + @runtime_checkable + class PG(Protocol[T]): + def meth(x): ... + + class BadP(Protocol): + def meth(x): ... + + class BadPG(Protocol[T]): + def meth(x): ... + + class C: + def meth(x): ... + + self.assertIsInstance(C(), P) + self.assertIsInstance(C(), PG) + with self.assertRaises(TypeError): + isinstance(C(), PG[T]) + with self.assertRaises(TypeError): + isinstance(C(), PG[C]) + with self.assertRaises(TypeError): + isinstance(C(), BadP) + with self.assertRaises(TypeError): + isinstance(C(), BadPG) + + def test_protocols_isinstance_py36(self): + class APoint: + def __init__(self, x, y, label): + self.x = x + self.y = y + self.label = label + + class BPoint: + label = 'B' + + def __init__(self, x, y): + self.x = x + self.y = y + + class C: + def __init__(self, attr): + self.attr = attr + + def meth(self, arg): + return 0 + + class Bad: pass + + self.assertIsInstance(APoint(1, 2, 'A'), Point) + self.assertIsInstance(BPoint(1, 2), Point) + self.assertNotIsInstance(MyPoint(), Point) + self.assertIsInstance(BPoint(1, 2), Position) + self.assertIsInstance(Other(), Proto) + self.assertIsInstance(Concrete(), Proto) + self.assertIsInstance(C(42), Proto) + self.assertNotIsInstance(Bad(), Proto) + self.assertNotIsInstance(Bad(), Point) + self.assertNotIsInstance(Bad(), Position) + self.assertNotIsInstance(Bad(), Concrete) + self.assertNotIsInstance(Other(), Concrete) + self.assertIsInstance(NT(1, 2), Position) + + def test_protocols_isinstance_init(self): + T = TypeVar('T') + + @runtime_checkable + class P(Protocol): + x = 1 + + @runtime_checkable + class PG(Protocol[T]): + x = 1 + + class C: + def __init__(self, x): + self.x = x + + self.assertIsInstance(C(1), P) + self.assertIsInstance(C(1), PG) + + def test_protocols_support_register(self): + @runtime_checkable + class P(Protocol): + x = 1 + + class PM(Protocol): + def meth(self): pass + + class D(PM): pass + + class C: pass + + D.register(C) + P.register(C) + self.assertIsInstance(C(), P) + self.assertIsInstance(C(), D) + + def test_none_on_non_callable_doesnt_block_implementation(self): + @runtime_checkable + class P(Protocol): + x = 1 + + class A: + x = 1 + + class B(A): + x = None + + class C: + def __init__(self): + self.x = None + + self.assertIsInstance(B(), P) + self.assertIsInstance(C(), P) + + def test_none_on_callable_blocks_implementation(self): + @runtime_checkable + class P(Protocol): + def x(self): ... + + class A: + def x(self): ... + + class B(A): + x = None + + class C: + def __init__(self): + self.x = None + + self.assertNotIsInstance(B(), P) + self.assertNotIsInstance(C(), P) + + def test_non_protocol_subclasses(self): + class P(Protocol): + x = 1 + + @runtime_checkable + class PR(Protocol): + def meth(self): pass + + class NonP(P): + x = 1 + + class NonPR(PR): pass + + class C: + x = 1 + + class D: + def meth(self): pass + + self.assertNotIsInstance(C(), NonP) + self.assertNotIsInstance(D(), NonPR) + self.assertNotIsSubclass(C, NonP) + self.assertNotIsSubclass(D, NonPR) + self.assertIsInstance(NonPR(), PR) + self.assertIsSubclass(NonPR, PR) + + def test_custom_subclasshook(self): + class P(Protocol): + x = 1 + + class OKClass: pass + + class BadClass: + x = 1 + + class C(P): + @classmethod + def __subclasshook__(cls, other): + return other.__name__.startswith("OK") + + self.assertIsInstance(OKClass(), C) + self.assertNotIsInstance(BadClass(), C) + self.assertIsSubclass(OKClass, C) + self.assertNotIsSubclass(BadClass, C) + + def test_issubclass_fails_correctly(self): + @runtime_checkable + class P(Protocol): + x = 1 + + class C: pass + + with self.assertRaises(TypeError): + issubclass(C(), P) + + def test_defining_generic_protocols(self): + T = TypeVar('T') + S = TypeVar('S') + + @runtime_checkable + class PR(Protocol[T, S]): + def meth(self): pass + + class P(PR[int, T], Protocol[T]): + y = 1 + + with self.assertRaises(TypeError): + PR[int] + with self.assertRaises(TypeError): + P[int, str] + with self.assertRaises(TypeError): + PR[int, 1] + with self.assertRaises(TypeError): + PR[int, ClassVar] + + class C(PR[int, T]): pass + + self.assertIsInstance(C[str](), C) + + def test_defining_generic_protocols_old_style(self): + T = TypeVar('T') + S = TypeVar('S') + + @runtime_checkable + class PR(Protocol, Generic[T, S]): + def meth(self): pass + + class P(PR[int, str], Protocol): + y = 1 + + with self.assertRaises(TypeError): + issubclass(PR[int, str], PR) + self.assertIsSubclass(P, PR) + with self.assertRaises(TypeError): + PR[int] + with self.assertRaises(TypeError): + PR[int, 1] + + class P1(Protocol, Generic[T]): + def bar(self, x: T) -> str: ... + + class P2(Generic[T], Protocol): + def bar(self, x: T) -> str: ... + + @runtime_checkable + class PSub(P1[str], Protocol): + x = 1 + + class Test: + x = 1 + + def bar(self, x: str) -> str: + return x + + self.assertIsInstance(Test(), PSub) + with self.assertRaises(TypeError): + PR[int, ClassVar] + + def test_init_called(self): + T = TypeVar('T') + + class P(Protocol[T]): pass + + class C(P[T]): + def __init__(self): + self.test = 'OK' + + self.assertEqual(C[int]().test, 'OK') + + def test_protocols_bad_subscripts(self): + T = TypeVar('T') + S = TypeVar('S') + with self.assertRaises(TypeError): + class P(Protocol[T, T]): pass + with self.assertRaises(TypeError): + class P(Protocol[int]): pass + with self.assertRaises(TypeError): + class P(Protocol[T], Protocol[S]): pass + with self.assertRaises(TypeError): + class P(typing.Mapping[T, S], Protocol[T]): pass + + def test_generic_protocols_repr(self): + T = TypeVar('T') + S = TypeVar('S') + + class P(Protocol[T, S]): pass + + self.assertTrue(repr(P[T, S]).endswith('P[~T, ~S]')) + self.assertTrue(repr(P[int, str]).endswith('P[int, str]')) + + def test_generic_protocols_eq(self): + T = TypeVar('T') + S = TypeVar('S') + + class P(Protocol[T, S]): pass + + self.assertEqual(P, P) + self.assertEqual(P[int, T], P[int, T]) + self.assertEqual(P[T, T][Tuple[T, S]][int, str], + P[Tuple[int, str], Tuple[int, str]]) + + def test_generic_protocols_special_from_generic(self): + T = TypeVar('T') + + class P(Protocol[T]): pass + + self.assertEqual(P.__parameters__, (T,)) + self.assertEqual(P[int].__parameters__, ()) + self.assertEqual(P[int].__args__, (int,)) + self.assertIs(P[int].__origin__, P) + + def test_generic_protocols_special_from_protocol(self): + @runtime_checkable + class PR(Protocol): + x = 1 + + class P(Protocol): + def meth(self): + pass + + T = TypeVar('T') + + class PG(Protocol[T]): + x = 1 + + def meth(self): + pass + + self.assertTrue(P._is_protocol) + self.assertTrue(PR._is_protocol) + self.assertTrue(PG._is_protocol) + self.assertFalse(P._is_runtime_protocol) + self.assertTrue(PR._is_runtime_protocol) + self.assertTrue(PG[int]._is_protocol) + self.assertEqual(typing._get_protocol_attrs(P), {'meth'}) + self.assertEqual(typing._get_protocol_attrs(PR), {'x'}) + self.assertEqual(frozenset(typing._get_protocol_attrs(PG)), + frozenset({'x', 'meth'})) + + def test_no_runtime_deco_on_nominal(self): + with self.assertRaises(TypeError): + @runtime_checkable + class C: pass + + class Proto(Protocol): + x = 1 + + with self.assertRaises(TypeError): + @runtime_checkable + class Concrete(Proto): + pass + + def test_none_treated_correctly(self): + @runtime_checkable + class P(Protocol): + x = None # type: int + + class B(object): pass + + self.assertNotIsInstance(B(), P) + + class C: + x = 1 + + class D: + x = None + + self.assertIsInstance(C(), P) + self.assertIsInstance(D(), P) + + class CI: + def __init__(self): + self.x = 1 + + class DI: + def __init__(self): + self.x = None + + self.assertIsInstance(C(), P) + self.assertIsInstance(D(), P) + + def test_protocols_in_unions(self): + class P(Protocol): + x = None # type: int + + Alias = typing.Union[typing.Iterable, P] + Alias2 = typing.Union[P, typing.Iterable] + self.assertEqual(Alias, Alias2) + + def test_protocols_pickleable(self): + global P, CP # pickle wants to reference the class by name + T = TypeVar('T') + + @runtime_checkable + class P(Protocol[T]): + x = 1 + + class CP(P[int]): + pass + + c = CP() + c.foo = 42 + c.bar = 'abc' + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(c, proto) + x = pickle.loads(z) + self.assertEqual(x.foo, 42) + self.assertEqual(x.bar, 'abc') + self.assertEqual(x.x, 1) + self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) + s = pickle.dumps(P) + D = pickle.loads(s) + + class E: + x = 1 + + self.assertIsInstance(E(), D) def test_supports_int(self): self.assertIsSubclass(int, typing.SupportsInt) @@ -634,9 +1338,8 @@ def test_supports_index(self): self.assertIsSubclass(int, typing.SupportsIndex) self.assertNotIsSubclass(str, typing.SupportsIndex) - def test_protocol_instance_type_error(self): - with self.assertRaises(TypeError): - isinstance(0, typing.SupportsAbs) + def test_bundled_protocol_instance_works(self): + self.assertIsInstance(0, typing.SupportsAbs) class C1(typing.SupportsInt): def __int__(self) -> int: return 42 @@ -645,6 +1348,20 @@ class C2(C1): c = C2() self.assertIsInstance(c, C1) + def test_collections_protocols_allowed(self): + @runtime_checkable + class Custom(collections.abc.Iterable, Protocol): + def close(self): ... + + class A: pass + class B: + def __iter__(self): + return [] + def close(self): + return 0 + + self.assertIsSubclass(B, Custom) + self.assertNotIsSubclass(A, Custom) class GenericTests(BaseTestCase): @@ -771,7 +1488,7 @@ def test_new_repr_complex(self): def test_new_repr_bare(self): T = TypeVar('T') self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') - self.assertEqual(repr(typing._Protocol[T]), 'typing._Protocol[~T]') + self.assertEqual(repr(typing.Protocol[T]), 'typing.Protocol[~T]') class C(typing.Dict[Any, Any]): ... # this line should just work repr(C.__mro__) @@ -1067,7 +1784,7 @@ def test_fail_with_bare_generic(self): with self.assertRaises(TypeError): Tuple[Generic[T]] with self.assertRaises(TypeError): - List[typing._Protocol] + List[typing.Protocol] def test_type_erasure_special(self): T = TypeVar('T') diff --git a/Lib/typing.py b/Lib/typing.py index d3e84cd64abe8c..14bd06b2b745b9 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -9,8 +9,7 @@ * The core of internal generics API: _GenericAlias and _VariadicGenericAlias, the latter is currently only used by Tuple and Callable. All subscripted types like X[int], Union[int, str], etc., are instances of either of these classes. -* The public counterpart of the generics API consists of two classes: Generic and Protocol - (the latter is currently private, but will be made public after PEP 544 acceptance). +* The public counterpart of the generics API consists of two classes: Generic and Protocol. * Public helper functions: get_type_hints, overload, cast, no_type_check, no_type_check_decorator. * Generic aliases for collections.abc ABCs and few additional protocols. @@ -18,7 +17,7 @@ * Wrapper submodules for re and io related types. """ -from abc import abstractmethod, abstractproperty +from abc import abstractmethod, abstractproperty, ABCMeta import collections import collections.abc import contextlib @@ -39,6 +38,7 @@ 'Generic', 'Literal', 'Optional', + 'Protocol', 'Tuple', 'Type', 'TypeVar', @@ -102,6 +102,7 @@ 'no_type_check_decorator', 'NoReturn', 'overload', + 'runtime_checkable', 'Text', 'TYPE_CHECKING', ] @@ -123,7 +124,7 @@ def _type_check(arg, msg, is_argument=True): We append the repr() of the actual value (truncated to 100 chars). """ - invalid_generic_forms = (Generic, _Protocol) + invalid_generic_forms = (Generic, Protocol) if is_argument: invalid_generic_forms = invalid_generic_forms + (ClassVar, Final) @@ -135,7 +136,7 @@ def _type_check(arg, msg, is_argument=True): arg.__origin__ in invalid_generic_forms): raise TypeError(f"{arg} is not valid as type argument") if (isinstance(arg, _SpecialForm) and arg not in (Any, NoReturn) or - arg in (Generic, _Protocol)): + arg in (Generic, Protocol)): raise TypeError(f"Plain {arg} is not valid as type argument") if isinstance(arg, (type, TypeVar, ForwardRef)): return arg @@ -665,8 +666,8 @@ def __init__(self, origin, params, *, inst=True, special=False, name=None): @_tp_cache def __getitem__(self, params): - if self.__origin__ in (Generic, _Protocol): - # Can't subscript Generic[...] or _Protocol[...]. + if self.__origin__ in (Generic, Protocol): + # Can't subscript Generic[...] or Protocol[...]. raise TypeError(f"Cannot subscript already-subscripted {self}") if not isinstance(params, tuple): params = (params,) @@ -733,6 +734,8 @@ def __mro_entries__(self, bases): res.append(Generic) return tuple(res) if self.__origin__ is Generic: + if Protocol in bases: + return () i = bases.index(self) for b in bases[i+1:]: if isinstance(b, _GenericAlias) and b is not self: @@ -850,10 +853,11 @@ def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: return default """ __slots__ = () + _is_protocol = False def __new__(cls, *args, **kwds): - if cls is Generic: - raise TypeError("Type Generic cannot be instantiated; " + if cls in (Generic, Protocol): + raise TypeError(f"Type {cls.__name__} cannot be instantiated; " "it can be used only as a base class") if super().__new__ is object.__new__ and cls.__init__ is not object.__init__: obj = super().__new__(cls) @@ -870,17 +874,14 @@ def __class_getitem__(cls, params): f"Parameter list to {cls.__qualname__}[...] cannot be empty") msg = "Parameters to generic types must be types." params = tuple(_type_check(p, msg) for p in params) - if cls is Generic: - # Generic can only be subscripted with unique type variables. + if cls in (Generic, Protocol): + # Generic and Protocol can only be subscripted with unique type variables. if not all(isinstance(p, TypeVar) for p in params): raise TypeError( - "Parameters to Generic[...] must all be type variables") + f"Parameters to {cls.__name__}[...] must all be type variables") if len(set(params)) != len(params): raise TypeError( - "Parameters to Generic[...] must all be unique") - elif cls is _Protocol: - # _Protocol is internal at the moment, just skip the check - pass + f"Parameters to {cls.__name__}[...] must all be unique") else: # Subscripting a regular Generic subclass. _check_generic(cls, params) @@ -892,7 +893,7 @@ def __init_subclass__(cls, *args, **kwargs): if '__orig_bases__' in cls.__dict__: error = Generic in cls.__orig_bases__ else: - error = Generic in cls.__bases__ and cls.__name__ != '_Protocol' + error = Generic in cls.__bases__ and cls.__name__ != 'Protocol' if error: raise TypeError("Cannot inherit from plain Generic") if '__orig_bases__' in cls.__dict__: @@ -910,9 +911,7 @@ def __init_subclass__(cls, *args, **kwargs): raise TypeError( "Cannot inherit from Generic[...] multiple types.") gvars = base.__parameters__ - if gvars is None: - gvars = tvars - else: + if gvars is not None: tvarset = set(tvars) gvarset = set(gvars) if not tvarset <= gvarset: @@ -935,6 +934,204 @@ class _TypingEllipsis: """Internal placeholder for ... (ellipsis).""" +_TYPING_INTERNALS = ['__parameters__', '__orig_bases__', '__orig_class__', + '_is_protocol', '_is_runtime_protocol'] + +_SPECIAL_NAMES = ['__abstractmethods__', '__annotations__', '__dict__', '__doc__', + '__init__', '__module__', '__new__', '__slots__', + '__subclasshook__', '__weakref__'] + +# These special attributes will be not collected as protocol members. +EXCLUDED_ATTRIBUTES = _TYPING_INTERNALS + _SPECIAL_NAMES + ['_MutableMapping__marker'] + + +def _get_protocol_attrs(cls): + """Collect protocol members from a protocol class objects. + + This includes names actually defined in the class dictionary, as well + as names that appear in annotations. Special names (above) are skipped. + """ + attrs = set() + for base in cls.__mro__[:-1]: # without object + if base.__name__ in ('Protocol', 'Generic'): + continue + annotations = getattr(base, '__annotations__', {}) + for attr in list(base.__dict__.keys()) + list(annotations.keys()): + if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: + attrs.add(attr) + return attrs + + +def _is_callable_members_only(cls): + # PEP 544 prohibits using issubclass() with protocols that have non-method members. + return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls)) + + +def _no_init(self, *args, **kwargs): + if type(self)._is_protocol: + raise TypeError('Protocols cannot be instantiated') + + +def _allow_reckless_class_cheks(): + """Allow instnance and class checks for special stdlib modules. + + The abc and functools modules indiscriminately call isinstance() and + issubclass() on the whole MRO of a user class, which may contain protocols. + """ + try: + return sys._getframe(3).f_globals['__name__'] in ['abc', 'functools'] + except (AttributeError, ValueError): # For platforms without _getframe(). + return True + + +_PROTO_WHITELIST = ['Callable', 'Awaitable', + 'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator', + 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', + 'ContextManager', 'AsyncContextManager'] + + +class _ProtocolMeta(ABCMeta): + # This metaclass is really unfortunate and exists only because of + # the lack of __instancehook__. + def __instancecheck__(cls, instance): + # We need this method for situations where attributes are + # assigned in __init__. + if ((not getattr(cls, '_is_protocol', False) or + _is_callable_members_only(cls)) and + issubclass(instance.__class__, cls)): + return True + if cls._is_protocol: + if all(hasattr(instance, attr) and + # All *methods* can be blocked by setting them to None. + (not callable(getattr(cls, attr, None)) or + getattr(instance, attr) is not None) + for attr in _get_protocol_attrs(cls)): + return True + return super().__instancecheck__(instance) + + +class Protocol(Generic, metaclass=_ProtocolMeta): + """Base class for protocol classes. + + Protocol classes are defined as:: + + class Proto(Protocol): + def meth(self) -> int: + ... + + Such classes are primarily used with static type checkers that recognize + structural subtyping (static duck-typing), for example:: + + class C: + def meth(self) -> int: + return 0 + + def func(x: Proto) -> int: + return x.meth() + + func(C()) # Passes static type check + + See PEP 544 for details. Protocol classes decorated with + @typing.runtime_checkable act as simple-minded runtime protocols that check + only the presence of given attributes, ignoring their type signatures. + Protocol classes can be generic, they are defined as:: + + class GenProto(Protocol[T]): + def meth(self) -> T: + ... + """ + __slots__ = () + _is_protocol = True + _is_runtime_protocol = False + + def __init_subclass__(cls, *args, **kwargs): + super().__init_subclass__(*args, **kwargs) + + # Determine if this is a protocol or a concrete subclass. + if not cls.__dict__.get('_is_protocol', False): + cls._is_protocol = any(b is Protocol for b in cls.__bases__) + + # Set (or override) the protocol subclass hook. + def _proto_hook(other): + if not cls.__dict__.get('_is_protocol', False): + return NotImplemented + + # First, perform various sanity checks. + if not getattr(cls, '_is_runtime_protocol', False): + if _allow_reckless_class_cheks(): + return NotImplemented + raise TypeError("Instance and class checks can only be used with" + " @runtime_checkable protocols") + if not _is_callable_members_only(cls): + if _allow_reckless_class_cheks(): + return NotImplemented + raise TypeError("Protocols with non-method members" + " don't support issubclass()") + if not isinstance(other, type): + # Same error message as for issubclass(1, int). + raise TypeError('issubclass() arg 1 must be a class') + + # Second, perform the actual structural compatibility check. + for attr in _get_protocol_attrs(cls): + for base in other.__mro__: + # Check if the members appears in the class dictionary... + if attr in base.__dict__: + if base.__dict__[attr] is None: + return NotImplemented + break + + # ...or in annotations, if it is a sub-protocol. + annotations = getattr(base, '__annotations__', {}) + if (isinstance(annotations, collections.abc.Mapping) and + attr in annotations and + issubclass(other, Generic) and other._is_protocol): + break + else: + return NotImplemented + return True + + if '__subclasshook__' not in cls.__dict__: + cls.__subclasshook__ = _proto_hook + + # We have nothing more to do for non-protocols... + if not cls._is_protocol: + return + + # ... otherwise check consistency of bases, and prohibit instantiation. + for base in cls.__bases__: + if not (base in (object, Generic) or + base.__module__ == 'collections.abc' and base.__name__ in _PROTO_WHITELIST or + issubclass(base, Generic) and base._is_protocol): + raise TypeError('Protocols can only inherit from other' + ' protocols, got %r' % base) + cls.__init__ = _no_init + + +def runtime_checkable(cls): + """Mark a protocol class as a runtime protocol. + + Such protocol can be used with isinstance() and issubclass(). + Raise TypeError if applied to a non-protocol class. + This allows a simple-minded structural check very similar to + one trick ponies in collections.abc such as Iterable. + For example:: + + @runtime_checkable + class Closable(Protocol): + def close(self): ... + + assert isinstance(open('/some/file'), Closable) + + Warning: this will check only the presence of the required methods, + not their type signatures! + """ + if not issubclass(cls, Generic) or not cls._is_protocol: + raise TypeError('@runtime_checkable can be only applied to protocol classes,' + ' got %r' % cls) + cls._is_runtime_protocol = True + return cls + + def cast(typ, val): """Cast a value to a type. @@ -1159,90 +1356,6 @@ class Other(Leaf): # Error reported by type checker return f -class _ProtocolMeta(type): - """Internal metaclass for _Protocol. - - This exists so _Protocol classes can be generic without deriving - from Generic. - """ - - def __instancecheck__(self, obj): - if _Protocol not in self.__bases__: - return super().__instancecheck__(obj) - raise TypeError("Protocols cannot be used with isinstance().") - - def __subclasscheck__(self, cls): - if not self._is_protocol: - # No structural checks since this isn't a protocol. - return NotImplemented - - if self is _Protocol: - # Every class is a subclass of the empty protocol. - return True - - # Find all attributes defined in the protocol. - attrs = self._get_protocol_attrs() - - for attr in attrs: - if not any(attr in d.__dict__ for d in cls.__mro__): - return False - return True - - def _get_protocol_attrs(self): - # Get all Protocol base classes. - protocol_bases = [] - for c in self.__mro__: - if getattr(c, '_is_protocol', False) and c.__name__ != '_Protocol': - protocol_bases.append(c) - - # Get attributes included in protocol. - attrs = set() - for base in protocol_bases: - for attr in base.__dict__.keys(): - # Include attributes not defined in any non-protocol bases. - for c in self.__mro__: - if (c is not base and attr in c.__dict__ and - not getattr(c, '_is_protocol', False)): - break - else: - if (not attr.startswith('_abc_') and - attr != '__abstractmethods__' and - attr != '__annotations__' and - attr != '__weakref__' and - attr != '_is_protocol' and - attr != '_gorg' and - attr != '__dict__' and - attr != '__args__' and - attr != '__slots__' and - attr != '_get_protocol_attrs' and - attr != '__next_in_mro__' and - attr != '__parameters__' and - attr != '__origin__' and - attr != '__orig_bases__' and - attr != '__extra__' and - attr != '__tree_hash__' and - attr != '__module__'): - attrs.add(attr) - - return attrs - - -class _Protocol(Generic, metaclass=_ProtocolMeta): - """Internal base class for protocol classes. - - This implements a simple-minded structural issubclass check - (similar but more general than the one-offs in collections.abc - such as Hashable). - """ - - __slots__ = () - - _is_protocol = True - - def __class_getitem__(cls, params): - return super().__class_getitem__(params) - - # Some unconstrained type variables. These are used by the container types. # (These are not for export.) T = TypeVar('T') # Any type. @@ -1347,7 +1460,8 @@ def new_user(user_class: Type[U]) -> U: """ -class SupportsInt(_Protocol): +@runtime_checkable +class SupportsInt(Protocol): __slots__ = () @abstractmethod @@ -1355,7 +1469,8 @@ def __int__(self) -> int: pass -class SupportsFloat(_Protocol): +@runtime_checkable +class SupportsFloat(Protocol): __slots__ = () @abstractmethod @@ -1363,7 +1478,8 @@ def __float__(self) -> float: pass -class SupportsComplex(_Protocol): +@runtime_checkable +class SupportsComplex(Protocol): __slots__ = () @abstractmethod @@ -1371,7 +1487,8 @@ def __complex__(self) -> complex: pass -class SupportsBytes(_Protocol): +@runtime_checkable +class SupportsBytes(Protocol): __slots__ = () @abstractmethod @@ -1379,7 +1496,8 @@ def __bytes__(self) -> bytes: pass -class SupportsIndex(_Protocol): +@runtime_checkable +class SupportsIndex(Protocol): __slots__ = () @abstractmethod @@ -1387,7 +1505,8 @@ def __index__(self) -> int: pass -class SupportsAbs(_Protocol[T_co]): +@runtime_checkable +class SupportsAbs(Protocol[T_co]): __slots__ = () @abstractmethod @@ -1395,7 +1514,8 @@ def __abs__(self) -> T_co: pass -class SupportsRound(_Protocol[T_co]): +@runtime_checkable +class SupportsRound(Protocol[T_co]): __slots__ = () @abstractmethod diff --git a/Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst b/Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst new file mode 100644 index 00000000000000..329b82c12adfb4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst @@ -0,0 +1 @@ +PEP 544: Add ``Protocol`` and ``@runtime_checkable`` to the ``typing`` module. \ No newline at end of file From 9ee2c264c37a71bd1c60f6032c50630b87e3c611 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Tue, 28 May 2019 10:35:25 +0200 Subject: [PATCH 142/441] DOC: Unnecessary plural. (GH-13613) --- Doc/library/gettext.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 7f4eab5843f5f2..937330bb201b08 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -39,7 +39,7 @@ class-based API instead. Bind the *domain* to the locale directory *localedir*. More concretely, :mod:`gettext` will look for binary :file:`.mo` files for the given domain using the path (on Unix): :file:`{localedir}/{language}/LC_MESSAGES/{domain}.mo`, where - *languages* is searched for in the environment variables :envvar:`LANGUAGE`, + *language* is searched for in the environment variables :envvar:`LANGUAGE`, :envvar:`LC_ALL`, :envvar:`LC_MESSAGES`, and :envvar:`LANG` respectively. If *localedir* is omitted or ``None``, then the current binding for *domain* is From bafd4b5ac83b6cc0b7455290a04c4bfad34bdc90 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Tue, 28 May 2019 12:52:15 +0300 Subject: [PATCH 143/441] bpo-29883: Asyncio proactor udp (GH-13440) Follow-up for #1067 https://bugs.python.org/issue29883 --- Doc/library/asyncio-eventloop.rst | 5 +- Doc/library/asyncio-platforms.rst | 3 - Lib/asyncio/proactor_events.py | 169 +++++++- Lib/asyncio/windows_events.py | 46 +++ Lib/test/test_asyncio/test_events.py | 9 - Lib/test/test_asyncio/test_proactor_events.py | 278 +++++++++++++ .../2018-09-15-11-36-55.bpo-29883.HErerE.rst | 2 + Modules/overlapped.c | 372 +++++++++++++++++- 8 files changed, 838 insertions(+), 46 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 4acd23f594652a..8673f84e96382e 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -504,8 +504,6 @@ Opening network connections transport. If specified, *local_addr* and *remote_addr* should be omitted (must be :const:`None`). - On Windows, with :class:`ProactorEventLoop`, this method is not supported. - See :ref:`UDP echo client protocol ` and :ref:`UDP echo server protocol ` examples. @@ -513,6 +511,9 @@ Opening network connections The *family*, *proto*, *flags*, *reuse_address*, *reuse_port, *allow_broadcast*, and *sock* parameters were added. + .. versionchanged:: 3.8 + Added support for Windows. + .. coroutinemethod:: loop.create_unix_connection(protocol_factory, \ path=None, \*, ssl=None, sock=None, \ server_hostname=None, ssl_handshake_timeout=None) diff --git a/Doc/library/asyncio-platforms.rst b/Doc/library/asyncio-platforms.rst index 81d840e23277ea..7e4a70f91c6ed5 100644 --- a/Doc/library/asyncio-platforms.rst +++ b/Doc/library/asyncio-platforms.rst @@ -53,9 +53,6 @@ All event loops on Windows do not support the following methods: :class:`ProactorEventLoop` has the following limitations: -* The :meth:`loop.create_datagram_endpoint` method - is not supported. - * The :meth:`loop.add_reader` and :meth:`loop.add_writer` methods are not supported. diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 6a53b2edaac125..9b8ae064a8926b 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -11,6 +11,7 @@ import socket import warnings import signal +import collections from . import base_events from . import constants @@ -23,6 +24,24 @@ from .log import logger +def _set_socket_extra(transport, sock): + transport._extra['socket'] = trsock.TransportSocket(sock) + + try: + transport._extra['sockname'] = sock.getsockname() + except socket.error: + if transport._loop.get_debug(): + logger.warning( + "getsockname() failed on %r", sock, exc_info=True) + + if 'peername' not in transport._extra: + try: + transport._extra['peername'] = sock.getpeername() + except socket.error: + # UDP sockets may not have a peer name + transport._extra['peername'] = None + + class _ProactorBasePipeTransport(transports._FlowControlMixin, transports.BaseTransport): """Base class for pipe and socket transports.""" @@ -430,6 +449,134 @@ def _pipe_closed(self, fut): self.close() +class _ProactorDatagramTransport(_ProactorBasePipeTransport): + max_size = 256 * 1024 + def __init__(self, loop, sock, protocol, address=None, + waiter=None, extra=None): + self._address = address + self._empty_waiter = None + # We don't need to call _protocol.connection_made() since our base + # constructor does it for us. + super().__init__(loop, sock, protocol, waiter=waiter, extra=extra) + + # The base constructor sets _buffer = None, so we set it here + self._buffer = collections.deque() + self._loop.call_soon(self._loop_reading) + + def _set_extra(self, sock): + _set_socket_extra(self, sock) + + def get_write_buffer_size(self): + return sum(len(data) for data, _ in self._buffer) + + def abort(self): + self._force_close(None) + + def sendto(self, data, addr=None): + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError('data argument must be bytes-like object (%r)', + type(data)) + + if not data: + return + + if self._address is not None and addr not in (None, self._address): + raise ValueError( + f'Invalid address: must be None or {self._address}') + + if self._conn_lost and self._address: + if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES: + logger.warning('socket.sendto() raised exception.') + self._conn_lost += 1 + return + + # Ensure that what we buffer is immutable. + self._buffer.append((bytes(data), addr)) + + if self._write_fut is None: + # No current write operations are active, kick one off + self._loop_writing() + # else: A write operation is already kicked off + + self._maybe_pause_protocol() + + def _loop_writing(self, fut=None): + try: + if self._conn_lost: + return + + assert fut is self._write_fut + self._write_fut = None + if fut: + # We are in a _loop_writing() done callback, get the result + fut.result() + + if not self._buffer or (self._conn_lost and self._address): + # The connection has been closed + if self._closing: + self._loop.call_soon(self._call_connection_lost, None) + return + + data, addr = self._buffer.popleft() + if self._address is not None: + self._write_fut = self._loop._proactor.send(self._sock, + data) + else: + self._write_fut = self._loop._proactor.sendto(self._sock, + data, + addr=addr) + except OSError as exc: + self._protocol.error_received(exc) + except Exception as exc: + self._fatal_error(exc, 'Fatal write error on datagram transport') + else: + self._write_fut.add_done_callback(self._loop_writing) + self._maybe_resume_protocol() + + def _loop_reading(self, fut=None): + data = None + try: + if self._conn_lost: + return + + assert self._read_fut is fut or (self._read_fut is None and + self._closing) + + self._read_fut = None + if fut is not None: + res = fut.result() + + if self._closing: + # since close() has been called we ignore any read data + data = None + return + + if self._address is not None: + data, addr = res, self._address + else: + data, addr = res + + if self._conn_lost: + return + if self._address is not None: + self._read_fut = self._loop._proactor.recv(self._sock, + self.max_size) + else: + self._read_fut = self._loop._proactor.recvfrom(self._sock, + self.max_size) + except OSError as exc: + self._protocol.error_received(exc) + except exceptions.CancelledError: + if not self._closing: + raise + else: + if self._read_fut is not None: + self._read_fut.add_done_callback(self._loop_reading) + finally: + if data: + self._protocol.datagram_received(data, addr) + + class _ProactorDuplexPipeTransport(_ProactorReadPipeTransport, _ProactorBaseWritePipeTransport, transports.Transport): @@ -455,22 +602,7 @@ def __init__(self, loop, sock, protocol, waiter=None, base_events._set_nodelay(sock) def _set_extra(self, sock): - self._extra['socket'] = trsock.TransportSocket(sock) - - try: - self._extra['sockname'] = sock.getsockname() - except (socket.error, AttributeError): - if self._loop.get_debug(): - logger.warning( - "getsockname() failed on %r", sock, exc_info=True) - - if 'peername' not in self._extra: - try: - self._extra['peername'] = sock.getpeername() - except (socket.error, AttributeError): - if self._loop.get_debug(): - logger.warning("getpeername() failed on %r", - sock, exc_info=True) + _set_socket_extra(self, sock) def can_write_eof(self): return True @@ -515,6 +647,11 @@ def _make_ssl_transport( extra=extra, server=server) return ssl_protocol._app_transport + def _make_datagram_transport(self, sock, protocol, + address=None, waiter=None, extra=None): + return _ProactorDatagramTransport(self, sock, protocol, address, + waiter, extra) + def _make_duplex_pipe_transport(self, sock, protocol, waiter=None, extra=None): return _ProactorDuplexPipeTransport(self, diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index 61b40ba52a6486..ac51109ff1a83d 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -483,6 +483,44 @@ def finish_recv(trans, key, ov): return self._register(ov, conn, finish_recv) + def recvfrom(self, conn, nbytes, flags=0): + self._register_with_iocp(conn) + ov = _overlapped.Overlapped(NULL) + try: + ov.WSARecvFrom(conn.fileno(), nbytes, flags) + except BrokenPipeError: + return self._result((b'', None)) + + def finish_recv(trans, key, ov): + try: + return ov.getresult() + except OSError as exc: + if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, + _overlapped.ERROR_OPERATION_ABORTED): + raise ConnectionResetError(*exc.args) + else: + raise + + return self._register(ov, conn, finish_recv) + + def sendto(self, conn, buf, flags=0, addr=None): + self._register_with_iocp(conn) + ov = _overlapped.Overlapped(NULL) + + ov.WSASendTo(conn.fileno(), buf, flags, addr) + + def finish_send(trans, key, ov): + try: + return ov.getresult() + except OSError as exc: + if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, + _overlapped.ERROR_OPERATION_ABORTED): + raise ConnectionResetError(*exc.args) + else: + raise + + return self._register(ov, conn, finish_send) + def send(self, conn, buf, flags=0): self._register_with_iocp(conn) ov = _overlapped.Overlapped(NULL) @@ -532,6 +570,14 @@ async def accept_coro(future, conn): return future def connect(self, conn, address): + if conn.type == socket.SOCK_DGRAM: + # WSAConnect will complete immediately for UDP sockets so we don't + # need to register any IOCP operation + _overlapped.WSAConnect(conn.fileno(), address) + fut = self._loop.create_future() + fut.set_result(None) + return fut + self._register_with_iocp(conn) # The socket needs to be locally bound before we call ConnectEx(). try: diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index e89db99df31214..045654e87a85a6 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1249,11 +1249,6 @@ def datagram_received(self, data, addr): server.transport.close() def test_create_datagram_endpoint_sock(self): - if (sys.platform == 'win32' and - isinstance(self.loop, proactor_events.BaseProactorEventLoop)): - raise unittest.SkipTest( - 'UDP is not supported with proactor event loops') - sock = None local_address = ('127.0.0.1', 0) infos = self.loop.run_until_complete( @@ -2004,10 +1999,6 @@ def test_writer_callback(self): def test_writer_callback_cancel(self): raise unittest.SkipTest("IocpEventLoop does not have add_writer()") - def test_create_datagram_endpoint(self): - raise unittest.SkipTest( - "IocpEventLoop does not have create_datagram_endpoint()") - def test_remove_fds_after_closing(self): raise unittest.SkipTest("IocpEventLoop does not have add_reader()") else: diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 5952ccccce0e5d..2e9995d3280736 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -4,6 +4,7 @@ import socket import unittest import sys +from collections import deque from unittest import mock import asyncio @@ -12,6 +13,7 @@ from asyncio.proactor_events import _ProactorSocketTransport from asyncio.proactor_events import _ProactorWritePipeTransport from asyncio.proactor_events import _ProactorDuplexPipeTransport +from asyncio.proactor_events import _ProactorDatagramTransport from test import support from test.test_asyncio import utils as test_utils @@ -725,6 +727,208 @@ def test_pause_resume_reading(self): self.assertFalse(tr.is_reading()) +class ProactorDatagramTransportTests(test_utils.TestCase): + + def setUp(self): + super().setUp() + self.loop = self.new_test_loop() + self.proactor = mock.Mock() + self.loop._proactor = self.proactor + self.protocol = test_utils.make_test_protocol(asyncio.DatagramProtocol) + self.sock = mock.Mock(spec_set=socket.socket) + self.sock.fileno.return_value = 7 + + def datagram_transport(self, address=None): + self.sock.getpeername.side_effect = None if address else OSError + transport = _ProactorDatagramTransport(self.loop, self.sock, + self.protocol, + address=address) + self.addCleanup(close_transport, transport) + return transport + + def test_sendto(self): + data = b'data' + transport = self.datagram_transport() + transport.sendto(data, ('0.0.0.0', 1234)) + self.assertTrue(self.proactor.sendto.called) + self.proactor.sendto.assert_called_with( + self.sock, data, addr=('0.0.0.0', 1234)) + + def test_sendto_bytearray(self): + data = bytearray(b'data') + transport = self.datagram_transport() + transport.sendto(data, ('0.0.0.0', 1234)) + self.assertTrue(self.proactor.sendto.called) + self.proactor.sendto.assert_called_with( + self.sock, b'data', addr=('0.0.0.0', 1234)) + + def test_sendto_memoryview(self): + data = memoryview(b'data') + transport = self.datagram_transport() + transport.sendto(data, ('0.0.0.0', 1234)) + self.assertTrue(self.proactor.sendto.called) + self.proactor.sendto.assert_called_with( + self.sock, b'data', addr=('0.0.0.0', 1234)) + + def test_sendto_no_data(self): + transport = self.datagram_transport() + transport._buffer.append((b'data', ('0.0.0.0', 12345))) + transport.sendto(b'', ()) + self.assertFalse(self.sock.sendto.called) + self.assertEqual( + [(b'data', ('0.0.0.0', 12345))], list(transport._buffer)) + + def test_sendto_buffer(self): + transport = self.datagram_transport() + transport._buffer.append((b'data1', ('0.0.0.0', 12345))) + transport._write_fut = object() + transport.sendto(b'data2', ('0.0.0.0', 12345)) + self.assertFalse(self.proactor.sendto.called) + self.assertEqual( + [(b'data1', ('0.0.0.0', 12345)), + (b'data2', ('0.0.0.0', 12345))], + list(transport._buffer)) + + def test_sendto_buffer_bytearray(self): + data2 = bytearray(b'data2') + transport = self.datagram_transport() + transport._buffer.append((b'data1', ('0.0.0.0', 12345))) + transport._write_fut = object() + transport.sendto(data2, ('0.0.0.0', 12345)) + self.assertFalse(self.proactor.sendto.called) + self.assertEqual( + [(b'data1', ('0.0.0.0', 12345)), + (b'data2', ('0.0.0.0', 12345))], + list(transport._buffer)) + self.assertIsInstance(transport._buffer[1][0], bytes) + + def test_sendto_buffer_memoryview(self): + data2 = memoryview(b'data2') + transport = self.datagram_transport() + transport._buffer.append((b'data1', ('0.0.0.0', 12345))) + transport._write_fut = object() + transport.sendto(data2, ('0.0.0.0', 12345)) + self.assertFalse(self.proactor.sendto.called) + self.assertEqual( + [(b'data1', ('0.0.0.0', 12345)), + (b'data2', ('0.0.0.0', 12345))], + list(transport._buffer)) + self.assertIsInstance(transport._buffer[1][0], bytes) + + @mock.patch('asyncio.proactor_events.logger') + def test_sendto_exception(self, m_log): + data = b'data' + err = self.proactor.sendto.side_effect = RuntimeError() + + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() + transport.sendto(data, ()) + + self.assertTrue(transport._fatal_error.called) + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on datagram transport') + transport._conn_lost = 1 + + transport._address = ('123',) + transport.sendto(data) + transport.sendto(data) + transport.sendto(data) + transport.sendto(data) + transport.sendto(data) + m_log.warning.assert_called_with('socket.sendto() raised exception.') + + def test_sendto_error_received(self): + data = b'data' + + self.sock.sendto.side_effect = ConnectionRefusedError + + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() + transport.sendto(data, ()) + + self.assertEqual(transport._conn_lost, 0) + self.assertFalse(transport._fatal_error.called) + + def test_sendto_error_received_connected(self): + data = b'data' + + self.proactor.send.side_effect = ConnectionRefusedError + + transport = self.datagram_transport(address=('0.0.0.0', 1)) + transport._fatal_error = mock.Mock() + transport.sendto(data) + + self.assertFalse(transport._fatal_error.called) + self.assertTrue(self.protocol.error_received.called) + + def test_sendto_str(self): + transport = self.datagram_transport() + self.assertRaises(TypeError, transport.sendto, 'str', ()) + + def test_sendto_connected_addr(self): + transport = self.datagram_transport(address=('0.0.0.0', 1)) + self.assertRaises( + ValueError, transport.sendto, b'str', ('0.0.0.0', 2)) + + def test_sendto_closing(self): + transport = self.datagram_transport(address=(1,)) + transport.close() + self.assertEqual(transport._conn_lost, 1) + transport.sendto(b'data', (1,)) + self.assertEqual(transport._conn_lost, 2) + + def test__loop_writing_closing(self): + transport = self.datagram_transport() + transport._closing = True + transport._loop_writing() + self.assertIsNone(transport._write_fut) + test_utils.run_briefly(self.loop) + self.sock.close.assert_called_with() + self.protocol.connection_lost.assert_called_with(None) + + def test__loop_writing_exception(self): + err = self.proactor.sendto.side_effect = RuntimeError() + + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() + transport._buffer.append((b'data', ())) + transport._loop_writing() + + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on datagram transport') + + def test__loop_writing_error_received(self): + self.proactor.sendto.side_effect = ConnectionRefusedError + + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() + transport._buffer.append((b'data', ())) + transport._loop_writing() + + self.assertFalse(transport._fatal_error.called) + + def test__loop_writing_error_received_connection(self): + self.proactor.send.side_effect = ConnectionRefusedError + + transport = self.datagram_transport(address=('0.0.0.0', 1)) + transport._fatal_error = mock.Mock() + transport._buffer.append((b'data', ())) + transport._loop_writing() + + self.assertFalse(transport._fatal_error.called) + self.assertTrue(self.protocol.error_received.called) + + @mock.patch('asyncio.base_events.logger.error') + def test_fatal_error_connected(self, m_exc): + transport = self.datagram_transport(address=('0.0.0.0', 1)) + err = ConnectionRefusedError() + transport._fatal_error(err) + self.assertFalse(self.protocol.error_received.called) + m_exc.assert_not_called() + + class BaseProactorEventLoopTests(test_utils.TestCase): def setUp(self): @@ -864,6 +1068,80 @@ def test_stop_serving(self): self.assertFalse(sock2.close.called) self.assertFalse(future2.cancel.called) + def datagram_transport(self): + self.protocol = test_utils.make_test_protocol(asyncio.DatagramProtocol) + return self.loop._make_datagram_transport(self.sock, self.protocol) + + def test_make_datagram_transport(self): + tr = self.datagram_transport() + self.assertIsInstance(tr, _ProactorDatagramTransport) + close_transport(tr) + + def test_datagram_loop_writing(self): + tr = self.datagram_transport() + tr._buffer.appendleft((b'data', ('127.0.0.1', 12068))) + tr._loop_writing() + self.loop._proactor.sendto.assert_called_with(self.sock, b'data', addr=('127.0.0.1', 12068)) + self.loop._proactor.sendto.return_value.add_done_callback.\ + assert_called_with(tr._loop_writing) + + close_transport(tr) + + def test_datagram_loop_reading(self): + tr = self.datagram_transport() + tr._loop_reading() + self.loop._proactor.recvfrom.assert_called_with(self.sock, 256 * 1024) + self.assertFalse(self.protocol.datagram_received.called) + self.assertFalse(self.protocol.error_received.called) + close_transport(tr) + + def test_datagram_loop_reading_data(self): + res = asyncio.Future(loop=self.loop) + res.set_result((b'data', ('127.0.0.1', 12068))) + + tr = self.datagram_transport() + tr._read_fut = res + tr._loop_reading(res) + self.loop._proactor.recvfrom.assert_called_with(self.sock, 256 * 1024) + self.protocol.datagram_received.assert_called_with(b'data', ('127.0.0.1', 12068)) + close_transport(tr) + + def test_datagram_loop_reading_no_data(self): + res = asyncio.Future(loop=self.loop) + res.set_result((b'', ('127.0.0.1', 12068))) + + tr = self.datagram_transport() + self.assertRaises(AssertionError, tr._loop_reading, res) + + tr.close = mock.Mock() + tr._read_fut = res + tr._loop_reading(res) + self.assertTrue(self.loop._proactor.recvfrom.called) + self.assertFalse(self.protocol.error_received.called) + self.assertFalse(tr.close.called) + close_transport(tr) + + def test_datagram_loop_reading_aborted(self): + err = self.loop._proactor.recvfrom.side_effect = ConnectionAbortedError() + + tr = self.datagram_transport() + tr._fatal_error = mock.Mock() + tr._protocol.error_received = mock.Mock() + tr._loop_reading() + tr._protocol.error_received.assert_called_with(err) + close_transport(tr) + + def test_datagram_loop_writing_aborted(self): + err = self.loop._proactor.sendto.side_effect = ConnectionAbortedError() + + tr = self.datagram_transport() + tr._fatal_error = mock.Mock() + tr._protocol.error_received = mock.Mock() + tr._buffer.appendleft((b'Hello', ('127.0.0.1', 12068))) + tr._loop_writing() + tr._protocol.error_received.assert_called_with(err) + close_transport(tr) + @unittest.skipIf(sys.platform != 'win32', 'Proactor is supported on Windows only') diff --git a/Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst b/Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst new file mode 100644 index 00000000000000..b6d1375c775263 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst @@ -0,0 +1,2 @@ +Add Windows support for UDP transports for the Proactor Event Loop. Patch by +Adam Meily. diff --git a/Modules/overlapped.c b/Modules/overlapped.c index e5a209bf758297..aad531e478931f 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -39,7 +39,8 @@ enum {TYPE_NONE, TYPE_NOT_STARTED, TYPE_READ, TYPE_READINTO, TYPE_WRITE, TYPE_ACCEPT, TYPE_CONNECT, TYPE_DISCONNECT, TYPE_CONNECT_NAMED_PIPE, - TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE}; + TYPE_WAIT_NAMED_PIPE_AND_CONNECT, TYPE_TRANSMIT_FILE, TYPE_READ_FROM, + TYPE_WRITE_TO}; typedef struct { PyObject_HEAD @@ -53,8 +54,19 @@ typedef struct { union { /* Buffer allocated by us: TYPE_READ and TYPE_ACCEPT */ PyObject *allocated_buffer; - /* Buffer passed by the user: TYPE_WRITE and TYPE_READINTO */ + /* Buffer passed by the user: TYPE_WRITE, TYPE_WRITE_TO, and TYPE_READINTO */ Py_buffer user_buffer; + + /* Data used for reading from a connectionless socket: + TYPE_READ_FROM */ + struct { + // A (buffer, (host, port)) tuple + PyObject *result; + // The actual read buffer + PyObject *allocated_buffer; + struct sockaddr_in6 address; + int address_length; + } read_from; }; } OverlappedObject; @@ -570,16 +582,32 @@ static int Overlapped_clear(OverlappedObject *self) { switch (self->type) { - case TYPE_READ: - case TYPE_ACCEPT: - Py_CLEAR(self->allocated_buffer); - break; - case TYPE_WRITE: - case TYPE_READINTO: - if (self->user_buffer.obj) { - PyBuffer_Release(&self->user_buffer); + case TYPE_READ: + case TYPE_ACCEPT: { + Py_CLEAR(self->allocated_buffer); + break; + } + case TYPE_READ_FROM: { + // An initial call to WSARecvFrom will only allocate the buffer. + // The result tuple of (message, address) is only + // allocated _after_ a message has been received. + if(self->read_from.result) { + // We've received a message, free the result tuple. + Py_CLEAR(self->read_from.result); + } + if(self->read_from.allocated_buffer) { + Py_CLEAR(self->read_from.allocated_buffer); + } + break; + } + case TYPE_WRITE: + case TYPE_WRITE_TO: + case TYPE_READINTO: { + if (self->user_buffer.obj) { + PyBuffer_Release(&self->user_buffer); + } + break; } - break; } self->type = TYPE_NOT_STARTED; return 0; @@ -627,6 +655,73 @@ Overlapped_dealloc(OverlappedObject *self) SetLastError(olderr); } + +/* Convert IPv4 sockaddr to a Python str. */ + +static PyObject * +make_ipv4_addr(const struct sockaddr_in *addr) +{ + char buf[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyUnicode_FromString(buf); +} + +#ifdef ENABLE_IPV6 +/* Convert IPv6 sockaddr to a Python str. */ + +static PyObject * +make_ipv6_addr(const struct sockaddr_in6 *addr) +{ + char buf[INET6_ADDRSTRLEN]; + if (inet_ntop(AF_INET6, &addr->sin6_addr, buf, sizeof(buf)) == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyUnicode_FromString(buf); +} +#endif + +static PyObject* +unparse_address(LPSOCKADDR Address, DWORD Length) +{ + /* The function is adopted from mocketmodule.c makesockaddr()*/ + + switch(Address->sa_family) { + case AF_INET: { + const struct sockaddr_in *a = (const struct sockaddr_in *)Address; + PyObject *addrobj = make_ipv4_addr(a); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("Oi", addrobj, ntohs(a->sin_port)); + Py_DECREF(addrobj); + } + return ret; + } +#ifdef ENABLE_IPV6 + case AF_INET6: { + const struct sockaddr_in6 *a = (const struct sockaddr_in6 *)Address; + PyObject *addrobj = make_ipv6_addr(a); + PyObject *ret = NULL; + if (addrobj) { + ret = Py_BuildValue("OiII", + addrobj, + ntohs(a->sin6_port), + ntohl(a->sin6_flowinfo), + a->sin6_scope_id); + Py_DECREF(addrobj); + } + return ret; + } +#endif /* ENABLE_IPV6 */ + default: { + return SetFromWindowsErr(ERROR_INVALID_PARAMETER); + } + } +} + PyDoc_STRVAR( Overlapped_cancel_doc, "cancel() -> None\n\n" @@ -670,6 +765,7 @@ Overlapped_getresult(OverlappedObject *self, PyObject *args) DWORD transferred = 0; BOOL ret; DWORD err; + PyObject *addr; if (!PyArg_ParseTuple(args, "|" F_BOOL, &wait)) return NULL; @@ -695,8 +791,15 @@ Overlapped_getresult(OverlappedObject *self, PyObject *args) case ERROR_MORE_DATA: break; case ERROR_BROKEN_PIPE: - if (self->type == TYPE_READ || self->type == TYPE_READINTO) + if (self->type == TYPE_READ || self->type == TYPE_READINTO) { break; + } + else if (self->type == TYPE_READ_FROM && + (self->read_from.result != NULL || + self->read_from.allocated_buffer != NULL)) + { + break; + } /* fall through */ default: return SetFromWindowsErr(err); @@ -708,8 +811,43 @@ Overlapped_getresult(OverlappedObject *self, PyObject *args) if (transferred != PyBytes_GET_SIZE(self->allocated_buffer) && _PyBytes_Resize(&self->allocated_buffer, transferred)) return NULL; + Py_INCREF(self->allocated_buffer); return self->allocated_buffer; + case TYPE_READ_FROM: + assert(PyBytes_CheckExact(self->read_from.allocated_buffer)); + + if (transferred != PyBytes_GET_SIZE( + self->read_from.allocated_buffer) && + _PyBytes_Resize(&self->read_from.allocated_buffer, transferred)) + { + return NULL; + } + + // unparse the address + addr = unparse_address((SOCKADDR*)&self->read_from.address, + self->read_from.address_length); + + if (addr == NULL) { + return NULL; + } + + // The result is a two item tuple: (message, address) + self->read_from.result = PyTuple_New(2); + if (self->read_from.result == NULL) { + Py_CLEAR(addr); + return NULL; + } + + // first item: message + Py_INCREF(self->read_from.allocated_buffer); + PyTuple_SET_ITEM(self->read_from.result, 0, + self->read_from.allocated_buffer); + // second item: address + PyTuple_SET_ITEM(self->read_from.result, 1, addr); + + Py_INCREF(self->read_from.result); + return self->read_from.result; default: return PyLong_FromUnsignedLong((unsigned long) transferred); } @@ -1121,7 +1259,6 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) return -1; } - PyDoc_STRVAR( Overlapped_ConnectEx_doc, "ConnectEx(client_handle, address_as_bytes) -> Overlapped[None]\n\n" @@ -1314,7 +1451,7 @@ PyDoc_STRVAR( "Connect to the pipe for asynchronous I/O (overlapped)."); static PyObject * -ConnectPipe(OverlappedObject *self, PyObject *args) +overlapped_ConnectPipe(PyObject *self, PyObject *args) { PyObject *AddressObj; wchar_t *Address; @@ -1362,15 +1499,213 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) Py_VISIT(self->allocated_buffer); break; case TYPE_WRITE: + case TYPE_WRITE_TO: case TYPE_READINTO: if (self->user_buffer.obj) { Py_VISIT(&self->user_buffer.obj); } break; + case TYPE_READ_FROM: + if(self->read_from.result) { + Py_VISIT(self->read_from.result); + } + if(self->read_from.allocated_buffer) { + Py_VISIT(self->read_from.allocated_buffer); + } } return 0; } +// UDP functions + +PyDoc_STRVAR( + WSAConnect_doc, + "WSAConnect(client_handle, address_as_bytes) -> Overlapped[None]\n\n" + "Bind a remote address to a connectionless (UDP) socket"); + +/* + * Note: WSAConnect does not support Overlapped I/O so this function should + * _only_ be used for connectionless sockets (UDP). + */ +static PyObject * +overlapped_WSAConnect(PyObject *self, PyObject *args) +{ + SOCKET ConnectSocket; + PyObject *AddressObj; + char AddressBuf[sizeof(struct sockaddr_in6)]; + SOCKADDR *Address = (SOCKADDR*)AddressBuf; + int Length; + int err; + + if (!PyArg_ParseTuple(args, F_HANDLE "O", &ConnectSocket, &AddressObj)) { + return NULL; + } + + Length = sizeof(AddressBuf); + Length = parse_address(AddressObj, Address, Length); + if (Length < 0) { + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + // WSAConnect does not support overlapped I/O so this call will + // successfully complete immediately. + err = WSAConnect(ConnectSocket, Address, Length, + NULL, NULL, NULL, NULL); + Py_END_ALLOW_THREADS + + if (err == 0) { + Py_RETURN_NONE; + } + else { + return SetFromWindowsErr(WSAGetLastError()); + } +} + +PyDoc_STRVAR( + Overlapped_WSASendTo_doc, + "WSASendTo(handle, buf, flags, address_as_bytes) -> " + "Overlapped[bytes_transferred]\n\n" + "Start overlapped sendto over a connectionless (UDP) socket"); + +static PyObject * +Overlapped_WSASendTo(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + PyObject *bufobj; + DWORD flags; + PyObject *AddressObj; + char AddressBuf[sizeof(struct sockaddr_in6)]; + SOCKADDR *Address = (SOCKADDR*)AddressBuf; + int AddressLength; + DWORD written; + WSABUF wsabuf; + int ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE "O" F_DWORD "O", + &handle, &bufobj, &flags, &AddressObj)) + { + return NULL; + } + + // Parse the "to" address + AddressLength = sizeof(AddressBuf); + AddressLength = parse_address(AddressObj, Address, AddressLength); + if (AddressLength < 0) { + return NULL; + } + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + + if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) { + return NULL; + } + +#if SIZEOF_SIZE_T > SIZEOF_LONG + if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { + PyBuffer_Release(&self->user_buffer); + PyErr_SetString(PyExc_ValueError, "buffer too large"); + return NULL; + } +#endif + + self->type = TYPE_WRITE_TO; + self->handle = handle; + wsabuf.len = (DWORD)self->user_buffer.len; + wsabuf.buf = self->user_buffer.buf; + + Py_BEGIN_ALLOW_THREADS + ret = WSASendTo((SOCKET)handle, &wsabuf, 1, &written, flags, + Address, AddressLength, &self->overlapped, NULL); + Py_END_ALLOW_THREADS + + self->error = err = (ret == SOCKET_ERROR ? WSAGetLastError() : + ERROR_SUCCESS); + + switch(err) { + case ERROR_SUCCESS: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + self->type = TYPE_NOT_STARTED; + return SetFromWindowsErr(err); + } +} + + + +PyDoc_STRVAR( + Overlapped_WSARecvFrom_doc, + "RecvFile(handle, size, flags) -> Overlapped[(message, (host, port))]\n\n" + "Start overlapped receive"); + +static PyObject * +Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *args) +{ + HANDLE handle; + DWORD size; + DWORD flags = 0; + DWORD nread; + PyObject *buf; + WSABUF wsabuf; + int ret; + DWORD err; + + if (!PyArg_ParseTuple(args, F_HANDLE F_DWORD "|" F_DWORD, + &handle, &size, &flags)) + { + return NULL; + } + + if (self->type != TYPE_NONE) { + PyErr_SetString(PyExc_ValueError, "operation already attempted"); + return NULL; + } + +#if SIZEOF_SIZE_T <= SIZEOF_LONG + size = Py_MIN(size, (DWORD)PY_SSIZE_T_MAX); +#endif + buf = PyBytes_FromStringAndSize(NULL, Py_MAX(size, 1)); + if (buf == NULL) { + return NULL; + } + + wsabuf.len = size; + wsabuf.buf = PyBytes_AS_STRING(buf); + + self->type = TYPE_READ_FROM; + self->handle = handle; + self->read_from.allocated_buffer = buf; + memset(&self->read_from.address, 0, sizeof(self->read_from.address)); + self->read_from.address_length = sizeof(self->read_from.address); + + Py_BEGIN_ALLOW_THREADS + ret = WSARecvFrom((SOCKET)handle, &wsabuf, 1, &nread, &flags, + (SOCKADDR*)&self->read_from.address, + &self->read_from.address_length, + &self->overlapped, NULL); + Py_END_ALLOW_THREADS + + self->error = err = (ret < 0 ? WSAGetLastError() : ERROR_SUCCESS); + + switch(err) { + case ERROR_BROKEN_PIPE: + mark_as_completed(&self->overlapped); + return SetFromWindowsErr(err); + case ERROR_SUCCESS: + case ERROR_MORE_DATA: + case ERROR_IO_PENDING: + Py_RETURN_NONE; + default: + self->type = TYPE_NOT_STARTED; + return SetFromWindowsErr(err); + } +} + static PyMethodDef Overlapped_methods[] = { {"getresult", (PyCFunction) Overlapped_getresult, @@ -1399,6 +1734,10 @@ static PyMethodDef Overlapped_methods[] = { METH_VARARGS, Overlapped_TransmitFile_doc}, {"ConnectNamedPipe", (PyCFunction) Overlapped_ConnectNamedPipe, METH_VARARGS, Overlapped_ConnectNamedPipe_doc}, + {"WSARecvFrom", (PyCFunction) Overlapped_WSARecvFrom, + METH_VARARGS, Overlapped_WSARecvFrom_doc }, + {"WSASendTo", (PyCFunction) Overlapped_WSASendTo, + METH_VARARGS, Overlapped_WSASendTo_doc }, {NULL} }; @@ -1484,9 +1823,10 @@ static PyMethodDef overlapped_functions[] = { METH_VARARGS, SetEvent_doc}, {"ResetEvent", overlapped_ResetEvent, METH_VARARGS, ResetEvent_doc}, - {"ConnectPipe", - (PyCFunction) ConnectPipe, + {"ConnectPipe", overlapped_ConnectPipe, METH_VARARGS, ConnectPipe_doc}, + {"WSAConnect", overlapped_WSAConnect, + METH_VARARGS, WSAConnect_doc}, {NULL} }; From 9ea277a788eabec102e8fe613b7f1e27995d5918 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 28 May 2019 12:24:00 +0200 Subject: [PATCH 144/441] bpo-36900: Fix compilation on HP-UX (GH-13614) dynload_hpux.c: add #include "pycore_pystate.h" for _PyInterpreterState_GET_UNSAFE(). --- Python/dynload_hpux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c index da9baa4b998920..e59d00435ec7d4 100644 --- a/Python/dynload_hpux.c +++ b/Python/dynload_hpux.c @@ -6,6 +6,7 @@ #include "Python.h" #include "importdl.h" +#include "pycore_pystate.h" #if defined(__hp9000s300) #define FUNCNAME_PATTERN "_%.20s_%.200s" From 293e9f86b8d10fcd88d6a2015babae76e9a8bd8f Mon Sep 17 00:00:00 2001 From: Brad Date: Tue, 28 May 2019 06:47:24 -0400 Subject: [PATCH 145/441] Remove outdated time.monotonic reference (GH-13264) Per ae58649, time.monotonic is always available, making the old note outdated. --- Doc/library/sched.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index ad96dbc95b0cd2..fab16f52c46218 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -20,8 +20,7 @@ scheduler: The :class:`scheduler` class defines a generic interface to scheduling events. It needs two functions to actually deal with the "outside world" --- *timefunc* should be callable without arguments, and return a number (the "time", in any - units whatsoever). If time.monotonic is not available, the *timefunc* default - is time.time instead. The *delayfunc* function should be callable with one + units whatsoever). The *delayfunc* function should be callable with one argument, compatible with the output of *timefunc*, and should delay that many time units. *delayfunc* will also be called with the argument ``0`` after each event is run to allow other threads an opportunity to run in multi-threaded From 9a7e5b1b42abcedb895b1ce49d83fe067d01835c Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 28 May 2019 21:02:52 +0900 Subject: [PATCH 146/441] bpo-35279: reduce default max_workers of ThreadPoolExecutor (GH-13618) --- Doc/library/concurrent.futures.rst | 9 +++++++++ Lib/concurrent/futures/thread.py | 11 ++++++++--- Lib/test/test_concurrent_futures.py | 4 ++-- .../Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst | 3 +++ 4 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index ffc29d782ec026..f2491dd24571be 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -159,6 +159,15 @@ And:: .. versionchanged:: 3.7 Added the *initializer* and *initargs* arguments. + .. versionchanged:: 3.8 + Default value of *max_workers* is changed to ``min(32, os.cpu_count() + 4)``. + This default value preserves at least 5 workers for I/O bound tasks. + It utilizes at most 32 CPU cores for CPU bound tasks which release the GIL. + And it avoids using very large resources implicitly on many-core machines. + + ThreadPoolExecutor now reuses idle worker threads before starting + *max_workers* worker threads too. + .. _threadpoolexecutor-example: diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index ad6b4c20b56681..2426e94de91fcb 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -129,9 +129,14 @@ def __init__(self, max_workers=None, thread_name_prefix='', initargs: A tuple of arguments to pass to the initializer. """ if max_workers is None: - # Use this number because ThreadPoolExecutor is often - # used to overlap I/O instead of CPU work. - max_workers = (os.cpu_count() or 1) * 5 + # ThreadPoolExecutor is often used to: + # * CPU bound task which releases GIL + # * I/O bound task (which releases GIL, of course) + # + # We use cpu_count + 4 for both types of tasks. + # But we limit it to 32 to avoid consuming surprisingly large resource + # on many core machine. + max_workers = min(32, (os.cpu_count() or 1) + 4) if max_workers <= 0: raise ValueError("max_workers must be greater than 0") diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index de6ad8f2aa1202..b27ae719482285 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -755,8 +755,8 @@ def record_finished(n): def test_default_workers(self): executor = self.executor_type() - self.assertEqual(executor._max_workers, - (os.cpu_count() or 1) * 5) + expected = min(32, (os.cpu_count() or 1) + 4) + self.assertEqual(executor._max_workers, expected) def test_saturation(self): executor = self.executor_type(4) diff --git a/Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst b/Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst new file mode 100644 index 00000000000000..41ee5c2fe8bf38 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst @@ -0,0 +1,3 @@ +Change default *max_workers* of ``ThreadPoolExecutor`` from ``cpu_count() * +5`` to ``min(32, cpu_count() + 4))``. Previous value was unreasonably +large on many cores machines. From 0811f2d81a12a3415dc2cb2744b41520c48d4db5 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Tue, 28 May 2019 14:04:42 +0200 Subject: [PATCH 147/441] Doc: Space breaking whole definition. (GH-13615) --- Doc/glossary.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 177df54ef215d4..0f2a3a1fdf0510 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -225,7 +225,7 @@ Glossary statement by defining :meth:`__enter__` and :meth:`__exit__` methods. See :pep:`343`. - context variable + context variable A variable which can have different values depending on its context. This is similar to Thread-Local Storage in which each execution thread may have a different value for a variable. However, with context From eb65e2443ac21739baf6d373abc7b4638b9d6927 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Tue, 28 May 2019 14:42:53 +0200 Subject: [PATCH 148/441] bpo-36922: implement PEP-590 Py_TPFLAGS_METHOD_DESCRIPTOR (GH-13338) Co-authored-by: Mark Shannon --- Doc/c-api/typeobj.rst | 26 +++++++++ Include/object.h | 3 + Lib/test/test_capi.py | 24 ++++++++ .../2019-05-15-10-46-55.bpo-36922.J3EFK_.rst | 3 + Modules/_functoolsmodule.c | 3 +- Modules/_testcapimodule.c | 57 +++++++++++++++++++ Objects/descrobject.c | 6 +- Objects/funcobject.c | 3 +- Objects/object.c | 3 +- Objects/typeobject.c | 11 +++- 10 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index e0ea9b9b5f9663..aa667846a0da26 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1045,6 +1045,32 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? + + .. data:: Py_TPFLAGS_METHOD_DESCRIPTOR + + This bit indicates that objects behave like unbound methods. + + If this flag is set for ``type(meth)``, then: + + - ``meth.__get__(obj, cls)(*args, **kwds)`` (with ``obj`` not None) + must be equivalent to ``meth(obj, *args, **kwds)``. + + - ``meth.__get__(None, cls)(*args, **kwds)`` + must be equivalent to ``meth(*args, **kwds)``. + + This flag enables an optimization for typical method calls like + ``obj.meth()``: it avoids creating a temporary "bound method" object for + ``obj.meth``. + + .. versionadded:: 3.8 + + **Inheritance:** + + This flag is never inherited by heap types. + For extension types, it is inherited whenever + :c:member:`~PyTypeObject.tp_descr_get` is inherited. + + .. XXX Document more flags here? diff --git a/Include/object.h b/Include/object.h index 6464f33be49190..d5d98d3bd885be 100644 --- a/Include/object.h +++ b/Include/object.h @@ -307,6 +307,9 @@ given type object has a specified feature. #define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 #endif +/* Objects behave like an unbound method */ +#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17) + /* Objects support type attribute cache */ #define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) #define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index a062a6563fa2b6..f3d41a20ab0560 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -27,6 +27,8 @@ # Were we compiled --with-pydebug or with #define Py_DEBUG? Py_DEBUG = hasattr(sys, 'gettotalrefcount') +Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17 + def testfunction(self): """some doc""" @@ -456,6 +458,28 @@ def test_pendingcalls_non_threaded(self): self.pendingcalls_wait(l, n) +class TestPEP590(unittest.TestCase): + + def test_method_descriptor_flag(self): + import functools + cached = functools.lru_cache(1)(testfunction) + + self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + + self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + + # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + pass + self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + + class SubinterpreterTest(unittest.TestCase): def test_subinterps(self): diff --git a/Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst b/Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst new file mode 100644 index 00000000000000..8eee208f905b5f --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst @@ -0,0 +1,3 @@ +Add new type flag ``Py_TPFLAGS_METHOD_DESCRIPTOR`` for objects behaving like +unbound methods. These are objects supporting the optimization given by the +``LOAD_METHOD``/``CALL_METHOD`` opcodes. See PEP 590. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index dcc9129fc6b183..13f2db939bb78a 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1333,7 +1333,8 @@ static PyTypeObject lru_cache_type = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ lru_cache_doc, /* tp_doc */ (traverseproc)lru_cache_tp_traverse,/* tp_traverse */ diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 51e5d80d1f51b3..8ba927039c2705 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5787,6 +5787,46 @@ static PyTypeObject Generic_Type = { }; +/* Test PEP 590 */ + +static PyObject * +func_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + if (obj == Py_None || obj == NULL) { + Py_INCREF(func); + return func; + } + return PyMethod_New(func, obj); +} + +static PyObject * +nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + Py_INCREF(func); + return func; +} + +static PyTypeObject MethodDescriptorBase_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorBase", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_METHOD_DESCRIPTOR, + .tp_descr_get = func_descr_get, +}; + +static PyTypeObject MethodDescriptorDerived_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorDerived", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +}; + +static PyTypeObject MethodDescriptorNopGet_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorNopGet", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_descr_get = nop_descr_get, +}; + + static struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, "_testcapi", @@ -5834,6 +5874,23 @@ PyInit__testcapi(void) Py_INCREF(&MyList_Type); PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type); + if (PyType_Ready(&MethodDescriptorBase_Type) < 0) + return NULL; + Py_INCREF(&MethodDescriptorBase_Type); + PyModule_AddObject(m, "MethodDescriptorBase", (PyObject *)&MethodDescriptorBase_Type); + + MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) + return NULL; + Py_INCREF(&MethodDescriptorDerived_Type); + PyModule_AddObject(m, "MethodDescriptorDerived", (PyObject *)&MethodDescriptorDerived_Type); + + MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) + return NULL; + Py_INCREF(&MethodDescriptorNopGet_Type); + PyModule_AddObject(m, "MethodDescriptorNopGet", (PyObject *)&MethodDescriptorNopGet_Type); + if (PyType_Ready(&GenericAlias_Type) < 0) return NULL; Py_INCREF(&GenericAlias_Type); diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 0db8057334fd36..6c99f9b211b93b 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -556,7 +556,8 @@ PyTypeObject PyMethodDescr_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -705,7 +706,8 @@ PyTypeObject PyWrapperDescr_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 09b94c26423666..fb7abfacb2e40b 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -663,7 +663,8 @@ PyTypeObject PyFunction_Type = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ func_new__doc__, /* tp_doc */ (traverseproc)func_traverse, /* tp_traverse */ (inquiry)func_clear, /* tp_clear */ diff --git a/Objects/object.c b/Objects/object.c index 270716f397c974..87dba9898e3a8a 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1155,8 +1155,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) descr = _PyType_Lookup(tp, name); if (descr != NULL) { Py_INCREF(descr); - if (PyFunction_Check(descr) || - (Py_TYPE(descr) == &PyMethodDescr_Type)) { + if (PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) { meth_found = 1; } else { f = descr->ob_type->tp_descr_get; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index fc809d36e10be0..06e045bd1597f0 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4950,7 +4950,7 @@ static void inherit_special(PyTypeObject *type, PyTypeObject *base) { - /* Copying basicsize is connected to the GC flags */ + /* Copying tp_traverse and tp_clear is connected to the GC flags */ if (!(type->tp_flags & Py_TPFLAGS_HAVE_GC) && (base->tp_flags & Py_TPFLAGS_HAVE_GC) && (!type->tp_traverse && !type->tp_clear)) { @@ -5165,6 +5165,15 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) } { COPYSLOT(tp_descr_get); + /* Inherit Py_TPFLAGS_METHOD_DESCRIPTOR if tp_descr_get was inherited, + * but only for extension types */ + if (base->tp_descr_get && + type->tp_descr_get == base->tp_descr_get && + !(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && + (base->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR)) + { + type->tp_flags |= Py_TPFLAGS_METHOD_DESCRIPTOR; + } COPYSLOT(tp_descr_set); COPYSLOT(tp_dictoffset); COPYSLOT(tp_init); From 04530812e90e45a37ed84e83505d63db7edc1262 Mon Sep 17 00:00:00 2001 From: Mario Corchero Date: Tue, 28 May 2019 13:53:31 +0100 Subject: [PATCH 149/441] bpo-32299: Return patched dict when using patch.dict as a context manager (GH-11062) --- Doc/library/unittest.mock.rst | 11 ++++++++++- Lib/unittest/mock.py | 1 + Lib/unittest/test/testmock/testpatch.py | 7 +++++++ .../Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst | 2 ++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 36ac24afa2bc07..da6cdfe648b0b1 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1556,15 +1556,24 @@ patch.dict decorator. When used as a class decorator :func:`patch.dict` honours ``patch.TEST_PREFIX`` for choosing which methods to wrap. + .. versionchanged:: 3.8 + + :func:`patch.dict` now returns the patched dictionary when used as a context + manager. + :func:`patch.dict` can be used to add members to a dictionary, or simply let a test change a dictionary, and ensure the dictionary is restored when the test ends. >>> foo = {} - >>> with patch.dict(foo, {'newkey': 'newvalue'}): + >>> with patch.dict(foo, {'newkey': 'newvalue'}) as patched_foo: ... assert foo == {'newkey': 'newvalue'} + ... assert patched_foo == {'newkey': 'newvalue'} + ... # You can add, update or delete keys of foo (or patched_foo, it's the same dict) + ... patched_foo['spam'] = 'eggs' ... >>> assert foo == {} + >>> assert patched_foo == {} >>> import os >>> with patch.dict('os.environ', {'newkey': 'newvalue'}): diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index fac4535747c4c8..055fbb350ce882 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1730,6 +1730,7 @@ def decorate_class(self, klass): def __enter__(self): """Patch the dict.""" self._patch_dict() + return self.in_dict def _patch_dict(self): diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index 3295c5b2420e88..27914a9d71780a 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -619,6 +619,13 @@ def test(): self.assertEqual(foo.values, original) + def test_patch_dict_as_context_manager(self): + foo = {'a': 'b'} + with patch.dict(foo, a='c') as patched: + self.assertEqual(patched, {'a': 'c'}) + self.assertEqual(foo, {'a': 'b'}) + + def test_name_preserved(self): foo = {} diff --git a/Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst b/Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst new file mode 100644 index 00000000000000..4e1afa9a43eac5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst @@ -0,0 +1,2 @@ +Changed :func:`unittest.mock.patch.dict` to return the patched +dictionary when used as context manager. Patch by Vadim Tsander. From 05f16416d99dc9fc76fef11e56f16593e7a5955e Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Tue, 28 May 2019 06:55:29 -0600 Subject: [PATCH 150/441] bpo-26423: Fix possible overflow in wrap_lenfunc() (GH-13606) Fix possible overflow in wrap_lenfunc() when sizeof(long) < sizeof(Py_ssize_t) (e.g., 64-bit Windows). --- Lib/test/test_descr.py | 4 ++++ .../2019-05-27-18-00-19.bpo-26423.RgUOE8.rst | 2 ++ Objects/typeobject.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index e37a98417f505c..6b018ccc56fa1d 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -389,6 +389,10 @@ def foo(self): return 1 a.setstate(100) self.assertEqual(a.getstate(), 100) + def test_wrap_lenfunc_bad_cast(self): + self.assertEqual(range(sys.maxsize).__len__(), sys.maxsize) + + class ClassPropertiesAndMethods(unittest.TestCase): def assertHasAttr(self, obj, name): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst new file mode 100644 index 00000000000000..6bf2031a338488 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst @@ -0,0 +1,2 @@ +Fix possible overflow in ``wrap_lenfunc()`` when +``sizeof(long) < sizeof(Py_ssize_t)`` (e.g., 64-bit Windows). diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 06e045bd1597f0..c14cbad875b443 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5536,7 +5536,7 @@ wrap_lenfunc(PyObject *self, PyObject *args, void *wrapped) res = (*func)(self); if (res == -1 && PyErr_Occurred()) return NULL; - return PyLong_FromLong((long)res); + return PyLong_FromSsize_t(res); } static PyObject * From 51ddab8dae056867f3595ab3400bffc93f67c8d4 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Tue, 28 May 2019 15:10:23 +0200 Subject: [PATCH 151/441] Doc: Add missing forward reference in the tutorial. (GH-13499) --- Doc/tutorial/controlflow.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 905734539c6851..cfb9645e0da1e1 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -482,9 +482,9 @@ When a final formal parameter of the form ``**name`` is present, it receives a dictionary (see :ref:`typesmapping`) containing all keyword arguments except for those corresponding to a formal parameter. This may be combined with a formal parameter of the form ``*name`` (described in the next subsection) which -receives a tuple containing the positional arguments beyond the formal parameter -list. (``*name`` must occur before ``**name``.) For example, if we define a -function like this:: +receives a :ref:`tuple ` containing the positional +arguments beyond the formal parameter list. (``*name`` must occur +before ``**name``.) For example, if we define a function like this:: def cheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") From a85a1d337d26a65036e427341d15e3979f7e9ced Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 28 May 2019 16:01:17 +0200 Subject: [PATCH 152/441] bpo-36829: sys.excepthook and sys.unraisablehook flush (GH-13620) sys.excepthook() and sys.unraisablehook() now explicitly flush the file (usually sys.stderr). If file.flush() fails, sys.excepthook() silently ignores the error, whereas sys.unraisablehook() logs the new exception. --- Python/errors.c | 9 +++++++++ Python/pythonrun.c | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/Python/errors.c b/Python/errors.c index bd33d4d340f668..8a94afdd8c4101 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -26,6 +26,7 @@ extern "C" { _Py_IDENTIFIER(builtins); _Py_IDENTIFIER(stderr); +_Py_IDENTIFIER(flush); /* Forward declarations */ @@ -1254,6 +1255,14 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type, if (PyFile_WriteString("\n", file) < 0) { return -1; } + + /* Explicitly call file.flush() */ + PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + if (!res) { + return -1; + } + Py_DECREF(res); + return 0; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ba1d1cf02f2584..ace9f2f9874e74 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -978,6 +978,16 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t } print_exception_recursive(file, value, seen); Py_XDECREF(seen); + + /* Call file.flush() */ + PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL); + if (!res) { + /* Silently ignore file.flush() error */ + PyErr_Clear(); + } + else { + Py_DECREF(res); + } } void From 17a5588740b3d126d546ad1a13bdac4e028e6d50 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 28 May 2019 16:02:50 +0200 Subject: [PATCH 153/441] bpo-33725: multiprocessing uses spawn by default on macOS (GH-13603) On macOS, the multiprocessing module now uses the "spawn" start method by default. --- Doc/library/multiprocessing.rst | 7 ++++++- Doc/whatsnew/3.8.rst | 10 ++++++++++ Lib/multiprocessing/context.py | 7 ++++++- .../Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst | 2 ++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index cc6dd4e9d70226..a4771d3a84cd40 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -102,7 +102,7 @@ to start a process. These *start methods* are will not be inherited. Starting a process using this method is rather slow compared to using *fork* or *forkserver*. - Available on Unix and Windows. The default on Windows. + Available on Unix and Windows. The default on Windows and macOS. *fork* The parent process uses :func:`os.fork` to fork the Python @@ -124,6 +124,11 @@ to start a process. These *start methods* are Available on Unix platforms which support passing file descriptors over Unix pipes. +.. versionchanged:: 3.8 + + On macOS, *spawn* start method is now the default: *fork* start method is no + longer reliable on macOS, see :issue:`33725`. + .. versionchanged:: 3.4 *spawn* added on all unix platforms, and *forkserver* added for some unix platforms. diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 860d6cc18f1152..547e795d85fb1e 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -469,6 +469,16 @@ access the ``madvise()`` system call. (Contributed by Zackery Spytz in :issue:`32941`.) +multiprocessing +--------------- + +Added new :mod:`multiprocessing.shared_memory` module. +(Contributed Davin Potts in :issue:`35813`.) + +On macOS, the *spawn* start method is now used by default. +(Contributed by Victor Stinner in :issue:`33725`.) + + os -- diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index 5a4865751c2272..5f8e0f0cd46585 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -309,7 +309,12 @@ def _check_available(self): 'spawn': SpawnContext(), 'forkserver': ForkServerContext(), } - _default_context = DefaultContext(_concrete_contexts['fork']) + if sys.platform == 'darwin': + # bpo-33725: running arbitrary code after fork() is no longer reliable + # on macOS since macOS 10.14 (Mojave). Use spawn by default instead. + _default_context = DefaultContext(_concrete_contexts['spawn']) + else: + _default_context = DefaultContext(_concrete_contexts['fork']) else: diff --git a/Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst b/Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst new file mode 100644 index 00000000000000..6f1665f6fab328 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst @@ -0,0 +1,2 @@ +On macOS, the :mod:`multiprocessing` module now uses *spawn* start method by +default. From 3c8724fc60163f4f3c3b0d531c84cc7b36783f82 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Tue, 28 May 2019 09:16:33 -0600 Subject: [PATCH 154/441] bpo-33407: Implement Py_DEPRECATED() on MSVC (GH-8980) --- Doc/c-api/intro.rst | 12 ++ Doc/whatsnew/3.8.rst | 9 ++ Include/abstract.h | 15 +-- Include/ceval.h | 4 +- Include/cpython/pyerrors.h | 18 +-- Include/cpython/unicodeobject.h | 127 +++++++++--------- Include/intrcheck.h | 2 +- Include/longobject.h | 3 +- Include/moduleobject.h | 2 +- Include/pyport.h | 10 +- Include/pythread.h | 13 +- Include/sliceobject.h | 4 +- Include/unicodeobject.h | 20 +-- .../2018-08-28-17-23-49.bpo-33407.ARG0W_.rst | 1 + 14 files changed, 136 insertions(+), 104 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index 672936a458f463..a1c8d34a7ea02f 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -160,6 +160,18 @@ complete listing. .. versionadded:: 3.4 +.. c:macro:: Py_DEPRECATED(version) + + Use this for deprecated declarations. The macro must be placed before the + symbol name. + + Example:: + + Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); + + .. versionchanged:: 3.8 + MSVC support was added. + .. _api-objects: diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 547e795d85fb1e..b32cec1edaca74 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1240,6 +1240,15 @@ Changes in the C API (Contributed by Eddie Elizondo in :issue:`35810`.) +* The :c:macro:`Py_DEPRECATED()` macro has been implemented for MSVC. + The macro now must be placed before the symbol name. + + Example:: + + Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); + + (Contributed by Zackery Spytz in :issue:`33407`.) + CPython bytecode changes ------------------------ diff --git a/Include/abstract.h b/Include/abstract.h index 79002a76a8c88e..c226aab9b73040 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -316,17 +316,16 @@ PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key); Return 0 on success. buffer and buffer_len are only set in case no error occurs. Otherwise, -1 is returned and an exception set. */ +Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj, const char **buffer, - Py_ssize_t *buffer_len) - Py_DEPRECATED(3.0); + Py_ssize_t *buffer_len); /* Checks whether an arbitrary object supports the (character, single segment) buffer interface. Returns 1 on success, 0 on failure. */ -PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj) - Py_DEPRECATED(3.0); +Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj); /* Same as PyObject_AsCharBuffer() except that this API expects (readable, single segment) buffer interface and returns a pointer to a read-only memory @@ -334,10 +333,10 @@ PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj) 0 is returned on success. buffer and buffer_len are only set in case no error occurs. Otherwise, -1 is returned and an exception set. */ +Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj, const void **buffer, - Py_ssize_t *buffer_len) - Py_DEPRECATED(3.0); + Py_ssize_t *buffer_len); /* Takes an arbitrary object which must support the (writable, single segment) buffer interface and returns a pointer to a writable memory location in @@ -345,10 +344,10 @@ PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj, Return 0 on success. buffer and buffer_len are only set in case no error occurs. Otherwise, -1 is returned and an exception set. */ +Py_DEPRECATED(3.0) PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj, void **buffer, - Py_ssize_t *buffer_len) - Py_DEPRECATED(3.0); + Py_ssize_t *buffer_len); /* === New Buffer API ============================================ */ diff --git a/Include/ceval.h b/Include/ceval.h index 6fb224b2885017..36fd014a91a7dd 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -189,8 +189,8 @@ PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); PyAPI_FUNC(void) PyEval_InitThreads(void); -PyAPI_FUNC(void) PyEval_AcquireLock(void) Py_DEPRECATED(3.2); -PyAPI_FUNC(void) PyEval_ReleaseLock(void) /* Py_DEPRECATED(3.2) */; +Py_DEPRECATED(3.2) PyAPI_FUNC(void) PyEval_AcquireLock(void); +/* Py_DEPRECATED(3.2) */ PyAPI_FUNC(void) PyEval_ReleaseLock(void); PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index 6b0ccedac52dab..e3098b3925bd79 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -88,8 +88,9 @@ PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); /* Convenience functions */ #ifdef MS_WINDOWS +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename( - PyObject *, const Py_UNICODE *) Py_DEPRECATED(3.3); + PyObject *, const Py_UNICODE *); #endif /* MS_WINDOWS */ /* Like PyErr_Format(), but saves current exception as __context__ and @@ -103,11 +104,12 @@ PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause( #ifdef MS_WINDOWS /* XXX redeclare to use WSTRING */ +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( - int, const Py_UNICODE *) Py_DEPRECATED(3.3); - + int, const Py_UNICODE *); +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename( - PyObject *,int, const Py_UNICODE *) Py_DEPRECATED(3.3); + PyObject *,int, const Py_UNICODE *); #endif /* In exceptions.c */ @@ -147,23 +149,23 @@ PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( int lineno); /* Create a UnicodeEncodeError object */ -PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( const char *encoding, /* UTF-8 encoded string */ const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason /* UTF-8 encoded string */ - ) Py_DEPRECATED(3.3); + ); /* Create a UnicodeTranslateError object */ -PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason /* UTF-8 encoded string */ - ) Py_DEPRECATED(3.3); + ); PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( PyObject *object, Py_ssize_t start, diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 806c3aa7cedbcf..c11503d3399921 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -11,7 +11,7 @@ extern "C" { With PEP 393, Py_UNICODE is deprecated and replaced with a typedef to wchar_t. */ #define PY_UNICODE_TYPE wchar_t -typedef wchar_t Py_UNICODE /* Py_DEPRECATED(3.3) */; +/* Py_DEPRECATED(3.3) */ typedef wchar_t Py_UNICODE; /* --- Internal Unicode Operations ---------------------------------------- */ @@ -257,6 +257,7 @@ typedef struct { If the Py_UNICODE representation is not available, it will be computed on request. Use PyUnicode_GET_LENGTH() for the length in code points. */ +/* Py_DEPRECATED(3.3) */ #define PyUnicode_GET_SIZE(op) \ (assert(PyUnicode_Check(op)), \ (((PyASCIIObject *)(op))->wstr) ? \ @@ -264,26 +265,25 @@ typedef struct { ((void)PyUnicode_AsUnicode(_PyObject_CAST(op)),\ assert(((PyASCIIObject *)(op))->wstr), \ PyUnicode_WSTR_LENGTH(op))) - /* Py_DEPRECATED(3.3) */ +/* Py_DEPRECATED(3.3) */ #define PyUnicode_GET_DATA_SIZE(op) \ (PyUnicode_GET_SIZE(op) * Py_UNICODE_SIZE) - /* Py_DEPRECATED(3.3) */ /* Alias for PyUnicode_AsUnicode(). This will create a wchar_t/Py_UNICODE representation on demand. Using this macro is very inefficient now, try to port your code to use the new PyUnicode_*BYTE_DATA() macros or use PyUnicode_WRITE() and PyUnicode_READ(). */ +/* Py_DEPRECATED(3.3) */ #define PyUnicode_AS_UNICODE(op) \ (assert(PyUnicode_Check(op)), \ (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \ PyUnicode_AsUnicode(_PyObject_CAST(op))) - /* Py_DEPRECATED(3.3) */ +/* Py_DEPRECATED(3.3) */ #define PyUnicode_AS_DATA(op) \ ((const char *)(PyUnicode_AS_UNICODE(op))) - /* Py_DEPRECATED(3.3) */ /* --- Flexible String Representation Helper Macros (PEP 393) -------------- */ @@ -543,10 +543,10 @@ PyAPI_FUNC(void) _PyUnicode_FastFill( only allowed if u was set to NULL. The buffer is copied into the new object. */ -PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( const Py_UNICODE *u, /* Unicode buffer */ Py_ssize_t size /* size of buffer */ - ) /* Py_DEPRECATED(3.3) */; + ); /* Create a new string from a buffer of Py_UCS1, Py_UCS2 or Py_UCS4 characters. Scan the string to find the maximum character. */ @@ -572,9 +572,9 @@ PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( Py_UNICODE buffer. If the wchar_t/Py_UNICODE representation is not yet available, this function will calculate it. */ -PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( PyObject *unicode /* Unicode object */ - ) /* Py_DEPRECATED(3.3) */; + ); /* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string contains null characters. */ @@ -587,13 +587,13 @@ PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( If the wchar_t/Py_UNICODE representation is not yet available, this function will calculate it. */ -PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( PyObject *unicode, /* Unicode object */ Py_ssize_t *size /* location where to save the length */ - ) /* Py_DEPRECATED(3.3) */; + ); /* Get the maximum ordinal for a Unicode character. */ -PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void) Py_DEPRECATED(3.3); +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); /* --- _PyUnicodeWriter API ----------------------------------------------- */ @@ -784,22 +784,22 @@ PyAPI_FUNC(const char *) PyUnicode_AsUTF8(PyObject *unicode); /* Encodes a Py_UNICODE buffer of the given size and returns a Python string object. */ -PyAPI_FUNC(PyObject*) PyUnicode_Encode( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_Encode( const Py_UNICODE *s, /* Unicode char buffer */ Py_ssize_t size, /* number of Py_UNICODE chars to encode */ const char *encoding, /* encoding */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); /* --- UTF-7 Codecs ------------------------------------------------------- */ -PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ int base64SetO, /* Encode RFC2152 Set O characters in base64 */ int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF7( PyObject *unicode, /* Unicode object */ @@ -814,20 +814,20 @@ PyAPI_FUNC(PyObject*) _PyUnicode_AsUTF8String( PyObject *unicode, const char *errors); -PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); /* --- UTF-32 Codecs ------------------------------------------------------ */ -PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ const char *errors, /* error handling */ int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ - ) Py_DEPRECATED(3.3); + ); PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( PyObject *object, /* Unicode object */ @@ -856,12 +856,12 @@ PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32( at a later point without compromising the APIs. */ -PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ const char *errors, /* error handling */ int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ - ) Py_DEPRECATED(3.3); + ); PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF16( PyObject* unicode, /* Unicode object */ @@ -882,17 +882,17 @@ PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscape( string. */ ); -PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length /* Number of Py_UNICODE chars to encode */ - ) Py_DEPRECATED(3.3); + ); /* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ -PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length /* Number of Py_UNICODE chars to encode */ - ) Py_DEPRECATED(3.3); + ); /* --- Latin-1 Codecs ----------------------------------------------------- */ @@ -900,11 +900,11 @@ PyAPI_FUNC(PyObject*) _PyUnicode_AsLatin1String( PyObject* unicode, const char* errors); -PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); /* --- ASCII Codecs ------------------------------------------------------- */ @@ -912,20 +912,20 @@ PyAPI_FUNC(PyObject*) _PyUnicode_AsASCIIString( PyObject* unicode, const char* errors); -PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); /* --- Character Map Codecs ----------------------------------------------- */ -PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ PyObject *mapping, /* encoding mapping */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( PyObject *unicode, /* Unicode object */ @@ -945,21 +945,21 @@ PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( are copied as-is. */ -PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ PyObject *table, /* Translate table */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); /* --- MBCS codecs for Windows -------------------------------------------- */ #ifdef MS_WINDOWS -PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( +Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* number of Py_UNICODE chars to encode */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.3); + ); #endif /* --- Decimal Encoder ---------------------------------------------------- */ @@ -986,12 +986,12 @@ PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( */ -PyAPI_FUNC(int) PyUnicode_EncodeDecimal( +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(int) PyUnicode_EncodeDecimal( Py_UNICODE *s, /* Unicode buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ char *output, /* Output buffer; must have size >= length */ const char *errors /* error handling */ - ) /* Py_DEPRECATED(3.3) */; + ); /* Transforms code points that have decimal digit property to the corresponding ASCII digit code points. @@ -999,10 +999,11 @@ PyAPI_FUNC(int) PyUnicode_EncodeDecimal( Returns a new Unicode string on success, NULL on failure. */ +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(PyObject*) PyUnicode_TransformDecimalToASCII( Py_UNICODE *s, /* Unicode buffer */ Py_ssize_t length /* Number of Py_UNICODE chars to transform */ - ) /* Py_DEPRECATED(3.3) */; + ); /* Coverts a Unicode object holding a decimal value to an ASCII string for using in int, float and complex parsers. @@ -1101,17 +1102,17 @@ PyAPI_FUNC(int) _PyUnicode_IsLinebreak( const Py_UCS4 ch /* Unicode character */ ); -PyAPI_FUNC(Py_UCS4) _PyUnicode_ToLowercase( +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToLowercase( Py_UCS4 ch /* Unicode character */ - ) /* Py_DEPRECATED(3.3) */; + ); -PyAPI_FUNC(Py_UCS4) _PyUnicode_ToUppercase( +/* Py_DEPRECATED(3.3) */ PyAPI_FUNC(Py_UCS4) _PyUnicode_ToUppercase( Py_UCS4 ch /* Unicode character */ - ) /* Py_DEPRECATED(3.3) */; + ); -PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase( +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UCS4) _PyUnicode_ToTitlecase( Py_UCS4 ch /* Unicode character */ - ) Py_DEPRECATED(3.3); + ); PyAPI_FUNC(int) _PyUnicode_ToLowerFull( Py_UCS4 ch, /* Unicode character */ @@ -1173,42 +1174,42 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha( Py_UCS4 ch /* Unicode character */ ); -PyAPI_FUNC(size_t) Py_UNICODE_strlen( +Py_DEPRECATED(3.3) PyAPI_FUNC(size_t) Py_UNICODE_strlen( const Py_UNICODE *u - ) Py_DEPRECATED(3.3); + ); -PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcpy( +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcpy( Py_UNICODE *s1, - const Py_UNICODE *s2) Py_DEPRECATED(3.3); + const Py_UNICODE *s2); -PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcat( - Py_UNICODE *s1, const Py_UNICODE *s2) Py_DEPRECATED(3.3); +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcat( + Py_UNICODE *s1, const Py_UNICODE *s2); -PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy( +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy( Py_UNICODE *s1, const Py_UNICODE *s2, - size_t n) Py_DEPRECATED(3.3); + size_t n); -PyAPI_FUNC(int) Py_UNICODE_strcmp( +Py_DEPRECATED(3.3) PyAPI_FUNC(int) Py_UNICODE_strcmp( const Py_UNICODE *s1, const Py_UNICODE *s2 - ) Py_DEPRECATED(3.3); + ); -PyAPI_FUNC(int) Py_UNICODE_strncmp( +Py_DEPRECATED(3.3) PyAPI_FUNC(int) Py_UNICODE_strncmp( const Py_UNICODE *s1, const Py_UNICODE *s2, size_t n - ) Py_DEPRECATED(3.3); + ); -PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( const Py_UNICODE *s, Py_UNICODE c - ) Py_DEPRECATED(3.3); + ); -PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( const Py_UNICODE *s, Py_UNICODE c - ) Py_DEPRECATED(3.3); + ); PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); @@ -1216,9 +1217,9 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); and raise a MemoryError exception on memory allocation failure, otherwise return a new allocated buffer (use PyMem_Free() to free the buffer). */ -PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( PyObject *unicode - ) Py_DEPRECATED(3.3); + ); /* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); diff --git a/Include/intrcheck.h b/Include/intrcheck.h index 2e17336ca659ed..e5bf5a834e44c8 100644 --- a/Include/intrcheck.h +++ b/Include/intrcheck.h @@ -15,7 +15,7 @@ PyAPI_FUNC(void) PyOS_AfterFork_Child(void); #endif #endif /* Deprecated, please use PyOS_AfterFork_Child() instead */ -PyAPI_FUNC(void) PyOS_AfterFork(void) Py_DEPRECATED(3.7); +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyOS_AfterFork(void); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyOS_IsMainThread(void); diff --git a/Include/longobject.h b/Include/longobject.h index a24bbea3a9044f..1e7a58d994b8a4 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -102,7 +102,8 @@ PyAPI_FUNC(long long) PyLong_AsLongLongAndOverflow(PyObject *, int *); PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int); #ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int) Py_DEPRECATED(3.3); +Py_DEPRECATED(3.3) +PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int); PyAPI_FUNC(PyObject *) PyLong_FromUnicodeObject(PyObject *u, int base); PyAPI_FUNC(PyObject *) _PyLong_FromBytes(const char *, Py_ssize_t, int); #endif diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 4d173808738cc9..e246fd2faf9184 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -25,7 +25,7 @@ PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); PyAPI_FUNC(PyObject *) PyModule_GetNameObject(PyObject *); #endif PyAPI_FUNC(const char *) PyModule_GetName(PyObject *); -PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *) Py_DEPRECATED(3.2); +Py_DEPRECATED(3.2) PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyModule_Clear(PyObject *); diff --git a/Include/pyport.h b/Include/pyport.h index ab88a9ac5c529e..32d98c59a7c134 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -504,14 +504,18 @@ extern "C" { /* Py_DEPRECATED(version) * Declare a variable, type, or function deprecated. + * The macro must be placed before the declaration. * Usage: - * extern int old_var Py_DEPRECATED(2.3); - * typedef int T1 Py_DEPRECATED(2.4); - * extern int x() Py_DEPRECATED(2.5); + * Py_DEPRECATED(3.3) extern int old_var; + * Py_DEPRECATED(3.4) typedef int T1; + * Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void); */ #if defined(__GNUC__) \ && ((__GNUC__ >= 4) || (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +#elif defined(_MSC_VER) +#define Py_DEPRECATED(VERSION) __declspec(deprecated( \ + "deprecated in " #VERSION)) #else #define Py_DEPRECATED(VERSION_UNUSED) #endif diff --git a/Include/pythread.h b/Include/pythread.h index 40f12d257c14ab..c0f1eb9789b352 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -97,14 +97,15 @@ PyAPI_FUNC(PyObject*) PyThread_GetInfo(void); platforms, but it is not POSIX-compliant. Therefore, the new TSS API uses opaque data type to represent TSS keys to be compatible (see PEP 539). */ -PyAPI_FUNC(int) PyThread_create_key(void) Py_DEPRECATED(3.7); -PyAPI_FUNC(void) PyThread_delete_key(int key) Py_DEPRECATED(3.7); -PyAPI_FUNC(int) PyThread_set_key_value(int key, void *value) Py_DEPRECATED(3.7); -PyAPI_FUNC(void *) PyThread_get_key_value(int key) Py_DEPRECATED(3.7); -PyAPI_FUNC(void) PyThread_delete_key_value(int key) Py_DEPRECATED(3.7); +Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_create_key(void); +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key(int key); +Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_set_key_value(int key, + void *value); +Py_DEPRECATED(3.7) PyAPI_FUNC(void *) PyThread_get_key_value(int key); +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key_value(int key); /* Cleanup after a fork */ -PyAPI_FUNC(void) PyThread_ReInitTLS(void) Py_DEPRECATED(3.7); +Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_ReInitTLS(void); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 diff --git a/Include/sliceobject.h b/Include/sliceobject.h index c238b099ea8151..aae6f3cc7945e1 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -40,9 +40,11 @@ PyAPI_FUNC(int) _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, #endif PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +Py_DEPRECATED(3.7) PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, - Py_ssize_t *step, Py_ssize_t *slicelength) Py_DEPRECATED(3.7); + Py_ssize_t *step, + Py_ssize_t *slicelength); #if !defined(Py_LIMITED_API) || (Py_LIMITED_API+0 >= 0x03050400 && Py_LIMITED_API+0 < 0x03060000) || Py_LIMITED_API+0 >= 0x03060100 #define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \ diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 503aeb5d19a677..6d141b37bf8909 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -174,9 +174,9 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_GetLength( /* Get the number of Py_UNICODE units in the string representation. */ -PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( +Py_DEPRECATED(3.3) PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( PyObject *unicode /* Unicode object */ - ) Py_DEPRECATED(3.3); + ); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Read a character from the string. */ @@ -381,11 +381,11 @@ PyAPI_FUNC(PyObject*) PyUnicode_Decode( Use PyCodec_Decode() to decode with rot13 and non-standard codecs that decode from str. */ -PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedObject( +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedObject( PyObject *unicode, /* Unicode object */ const char *encoding, /* encoding */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.6); + ); /* Decode a Unicode object unicode and return the result as Unicode object. @@ -394,11 +394,11 @@ PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedObject( Use PyCodec_Decode() to decode with rot13 and non-standard codecs that decode from str to str. */ -PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedUnicode( +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedUnicode( PyObject *unicode, /* Unicode object */ const char *encoding, /* encoding */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.6); + ); /* Encodes a Unicode object and returns the result as Python object. @@ -408,11 +408,11 @@ PyAPI_FUNC(PyObject*) PyUnicode_AsDecodedUnicode( Use PyCodec_Encode() for encoding with rot13 and non-standard codecs that encode form str to non-bytes. */ -PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject( +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject( PyObject *unicode, /* Unicode object */ const char *encoding, /* encoding */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.6); + ); /* Encodes a Unicode object and returns the result as Python string object. */ @@ -430,11 +430,11 @@ PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedString( Use PyCodec_Encode() to encode with rot13 and non-standard codecs that encode from str to str. */ -PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedUnicode( +Py_DEPRECATED(3.6) PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedUnicode( PyObject *unicode, /* Unicode object */ const char *encoding, /* encoding */ const char *errors /* error handling */ - ) Py_DEPRECATED(3.6); + ); /* Build an encoding map. */ diff --git a/Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst b/Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst new file mode 100644 index 00000000000000..47b1e0668b18b8 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst @@ -0,0 +1 @@ +The :c:macro:`Py_DEPRECATED()` macro has been implemented for MSVC. From 2e33ecd7c9b0cac3efc6fcbdd4547fd086b4e2d1 Mon Sep 17 00:00:00 2001 From: Joannah Nanjekye <33177550+nanjekyejoannah@users.noreply.github.com> Date: Tue, 28 May 2019 13:29:04 -0300 Subject: [PATCH 155/441] bpo-22640: Add silent mode to py_compile.compile() (GH-12976) --- Doc/library/py_compile.rst | 10 ++++++++ Doc/whatsnew/3.8.rst | 7 ++++++ Lib/py_compile.py | 24 ++++++++++++------- Lib/test/test_py_compile.py | 9 +++++++ .../2019-04-26-22-13-26.bpo-22640.p3rheW.rst | 2 ++ 5 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index 8cb5a4d546c874..3824353abda1f8 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -42,6 +42,13 @@ byte-code cache files in the directory containing the source code. is raised. This function returns the path to byte-compiled file, i.e. whatever *cfile* value was used. + The *doraise* and *quiet* arguments determine how errors are handled while + compiling file. If *quiet* is 0 or 1, and *doraise* is false, the default + behaviour is enabled: an error string is written to ``sys.stderr``, and the + function returns ``None`` instead of a path. If *doraise* is true, + a :exc:`PyCompileError` is raised instead. However if *quiet* is 2, + no message is written, and *doraise* has no effect. + If the path that *cfile* becomes (either explicitly specified or computed) is a symlink or non-regular file, :exc:`FileExistsError` will be raised. This is to act as a warning that import will turn those paths into regular @@ -82,6 +89,9 @@ byte-code cache files in the directory containing the source code. overrides the value of the *invalidation_mode* argument, and determines its default value instead. + .. versionchanged:: 3.8 + The *quiet* parameter was added. + .. class:: PycInvalidationMode diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index b32cec1edaca74..aaa6ffe1abdf3e 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -537,6 +537,13 @@ NSKeyedArchiver-encoded binary plists. (Contributed by Jon Janzen in :issue:`26707`.) +py_compile +---------- + +:func:`py_compile.compile` now supports silent mode. +(Contributed by Joannah Nanjekye in :issue:`22640`.) + + socket ------ diff --git a/Lib/py_compile.py b/Lib/py_compile.py index 8e9dd57a544017..21736896afc21b 100644 --- a/Lib/py_compile.py +++ b/Lib/py_compile.py @@ -77,7 +77,7 @@ def _get_default_invalidation_mode(): def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, - invalidation_mode=None): + invalidation_mode=None, quiet=0): """Byte-compile one Python source file to Python bytecode. :param file: The source file name. @@ -95,6 +95,8 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, are -1, 0, 1 and 2. A value of -1 means to use the optimization level of the current interpreter, as given by -O command line options. :param invalidation_mode: + :param quiet: Return full output with False or 0, errors only with 1, + and no output with 2. :return: Path to the resulting byte compiled file. @@ -143,11 +145,12 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, _optimize=optimize) except Exception as err: py_exc = PyCompileError(err.__class__, err, dfile or file) - if doraise: - raise py_exc - else: - sys.stderr.write(py_exc.msg + '\n') - return + if quiet < 2: + if doraise: + raise py_exc + else: + sys.stderr.write(py_exc.msg + '\n') + return try: dirname = os.path.dirname(cfile) if dirname: @@ -194,10 +197,12 @@ def main(args=None): compile(filename, doraise=True) except PyCompileError as error: rv = 1 - sys.stderr.write("%s\n" % error.msg) + if quiet < 2: + sys.stderr.write("%s\n" % error.msg) except OSError as error: rv = 1 - sys.stderr.write("%s\n" % error) + if quiet < 2: + sys.stderr.write("%s\n" % error) else: for filename in args: try: @@ -205,7 +210,8 @@ def main(args=None): except PyCompileError as error: # return value to indicate at least one failure rv = 1 - sys.stderr.write("%s\n" % error.msg) + if quiet < 2: + sys.stderr.write("%s\n" % error.msg) return rv if __name__ == "__main__": diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index f86abe26f97ae2..d6677ab45ff509 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -192,6 +192,15 @@ def test_invalidation_mode(self): fp.read(), 'test', {}) self.assertEqual(flags, 0b1) + def test_quiet(self): + bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + with support.captured_stderr() as stderr: + self.assertIsNone(py_compile.compile(bad_coding, doraise=False, quiet=2)) + self.assertIsNone(py_compile.compile(bad_coding, doraise=True, quiet=2)) + self.assertEqual(stderr.getvalue(), '') + with self.assertRaises(py_compile.PyCompileError): + py_compile.compile(bad_coding, doraise=True, quiet=1) + class PyCompileTestsWithSourceEpoch(PyCompileTestsBase, unittest.TestCase, diff --git a/Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst b/Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst new file mode 100644 index 00000000000000..8ac6be92044317 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst @@ -0,0 +1,2 @@ +:func:`py_compile.compile` now supports silent mode. +Patch by Joannah Nanjekye \ No newline at end of file From 382034b255935fbf0b5516708ac16a020d27af39 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Tue, 28 May 2019 10:30:35 -0700 Subject: [PATCH 156/441] bpo-36933: fix what's new. (GH-13627) Original Pr was reformed and news not updated. https://bugs.python.org/issue36933 --- Doc/whatsnew/3.8.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index aaa6ffe1abdf3e..d1305dc1e7dfb7 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -990,9 +990,9 @@ The following features and APIs have been removed from Python 3.8: :func:`fileinput.FileInput` which was ignored and deprecated since Python 3.6 has been removed. :issue:`36952` (Contributed by Matthias Bussonnier) -* The function :func:`sys.set_coroutine_wrapper` deprecated in Python 3.7 has - been removed; :func:`sys.get_coroutine_wrapper` now always return ``None``. - :issue:`36933` (Contributed by Matthias Bussonnier) +* The functions :func:`sys.set_coroutine_wrapper` and + :func:`sys.get_coroutine_wrapper` deprecated in Python 3.7 have been removed; + :issue:`36933` (Contributed by Matthias Bussonnier) Porting to Python 3.8 From 1b05aa219041eb1c9dbcb4ec6c1fa5b20f060bf5 Mon Sep 17 00:00:00 2001 From: karl ding Date: Tue, 28 May 2019 11:35:26 -0700 Subject: [PATCH 157/441] Fix typo in docs for socket.CAN_RAW_FD_FRAMES (GH-13635) There is an extra "one" in the text description for the constant socket.CAN_RAW_FD_FRAMES --- Doc/library/socket.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index e23a4f5380bd7b..5be2b76113eb04 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -380,7 +380,7 @@ Constants Enables CAN FD support in a CAN_RAW socket. This is disabled by default. This allows your application to send both CAN and CAN FD frames; however, - you one must accept both CAN and CAN FD frames when reading from the socket. + you must accept both CAN and CAN FD frames when reading from the socket. This constant is documented in the Linux documentation. From 9e3c4526394856d6376eed4968d27d53e1d69b7d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 28 May 2019 22:49:35 +0300 Subject: [PATCH 158/441] bpo-31961: Fix support of path-like executables in subprocess. (GH-5914) --- Doc/library/subprocess.rst | 29 +++++++++- Lib/subprocess.py | 25 ++++++++- Lib/test/test_subprocess.py | 55 +++++++++++++++++++ .../2018-03-27-13-28-16.bpo-31961.GjLoYu.rst | 6 ++ 4 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index d840b461f98cb7..ede5c3c5a369e3 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -347,7 +347,8 @@ functions. the class uses the Windows ``CreateProcess()`` function. The arguments to :class:`Popen` are as follows. - *args* should be a sequence of program arguments or else a single string. + *args* should be a sequence of program arguments or else a single string + or :term:`path-like object`. By default, the program to execute is the first item in *args* if *args* is a sequence. If *args* is a string, the interpretation is platform-dependent and described below. See the *shell* and *executable* @@ -381,6 +382,15 @@ functions. manner described in :ref:`converting-argument-sequence`. This is because the underlying ``CreateProcess()`` operates on strings. + .. versionchanged:: 3.6 + *args* parameter accepts a :term:`path-like object` if *shell* is + ``False`` and a sequence containing path-like objects on POSIX. + + .. versionchanged:: 3.8 + *args* parameter accepts a :term:`path-like object` if *shell* is + ``False`` and a sequence containing bytes and path-like objects + on Windows. + The *shell* argument (which defaults to ``False``) specifies whether to use the shell as the program to execute. If *shell* is ``True``, it is recommended to pass *args* as a string rather than as a sequence. @@ -436,6 +446,13 @@ functions. :program:`ps`. If ``shell=True``, on POSIX the *executable* argument specifies a replacement shell for the default :file:`/bin/sh`. + .. versionchanged:: 3.6 + *executable* parameter accepts a :term:`path-like object` on POSIX. + + .. versionchanged:: 3.8 + *executable* parameter accepts a bytes and :term:`path-like object` + on Windows. + *stdin*, *stdout* and *stderr* specify the executed program's standard input, standard output and standard error file handles, respectively. Valid values are :data:`PIPE`, :data:`DEVNULL`, an existing file descriptor (a positive @@ -492,13 +509,19 @@ functions. The *pass_fds* parameter was added. If *cwd* is not ``None``, the function changes the working directory to - *cwd* before executing the child. *cwd* can be a :class:`str` and + *cwd* before executing the child. *cwd* can be a string, bytes or :term:`path-like ` object. In particular, the function looks for *executable* (or for the first item in *args*) relative to *cwd* if the executable path is a relative path. .. versionchanged:: 3.6 - *cwd* parameter accepts a :term:`path-like object`. + *cwd* parameter accepts a :term:`path-like object` on POSIX. + + .. versionchanged:: 3.7 + *cwd* parameter accepts a :term:`path-like object` on Windows. + + .. versionchanged:: 3.8 + *cwd* parameter accepts a bytes object on Windows. If *restore_signals* is true (the default) all signals that Python has set to SIG_IGN are restored to SIG_DFL in the child process before the exec. diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 6cc9eb322e280b..9e36b9de6b349c 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -521,7 +521,7 @@ def list2cmdline(seq): # "Parsing C++ Command-Line Arguments" result = [] needquote = False - for arg in seq: + for arg in map(os.fsdecode, seq): bs_buf = [] # Add a space to separate this argument from the others @@ -1203,9 +1203,23 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, assert not pass_fds, "pass_fds not supported on Windows." - if not isinstance(args, str): + if isinstance(args, str): + pass + elif isinstance(args, bytes): + if shell: + raise TypeError('bytes args is not allowed on Windows') + args = list2cmdline([args]) + elif isinstance(args, os.PathLike): + if shell: + raise TypeError('path-like args is not allowed when ' + 'shell is true') + args = list2cmdline([args]) + else: args = list2cmdline(args) + if executable is not None: + executable = os.fsdecode(executable) + # Process startup details if startupinfo is None: startupinfo = STARTUPINFO() @@ -1262,7 +1276,7 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, int(not close_fds), creationflags, env, - os.fspath(cwd) if cwd is not None else None, + os.fsdecode(cwd) if cwd is not None else None, startupinfo) finally: # Child is launched. Close the parent's copy of those pipe @@ -1510,6 +1524,11 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, if isinstance(args, (str, bytes)): args = [args] + elif isinstance(args, os.PathLike): + if shell: + raise TypeError('path-like args is not allowed when ' + 'shell is true') + args = [args] else: args = list(args) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index b0b6b06e92759e..fca3ed62099bde 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -304,6 +304,18 @@ def test_executable(self): "doesnotexist") self._assert_python([doesnotexist, "-c"], executable=sys.executable) + def test_bytes_executable(self): + doesnotexist = os.path.join(os.path.dirname(sys.executable), + "doesnotexist") + self._assert_python([doesnotexist, "-c"], + executable=os.fsencode(sys.executable)) + + def test_pathlike_executable(self): + doesnotexist = os.path.join(os.path.dirname(sys.executable), + "doesnotexist") + self._assert_python([doesnotexist, "-c"], + executable=FakePath(sys.executable)) + def test_executable_takes_precedence(self): # Check that the executable argument takes precedence over args[0]. # @@ -320,6 +332,16 @@ def test_executable_replaces_shell(self): # when shell=True. self._assert_python([], executable=sys.executable, shell=True) + @unittest.skipIf(mswindows, "executable argument replaces shell") + def test_bytes_executable_replaces_shell(self): + self._assert_python([], executable=os.fsencode(sys.executable), + shell=True) + + @unittest.skipIf(mswindows, "executable argument replaces shell") + def test_pathlike_executable_replaces_shell(self): + self._assert_python([], executable=FakePath(sys.executable), + shell=True) + # For use in the test_cwd* tests below. def _normalize_cwd(self, cwd): # Normalize an expected cwd (for Tru64 support). @@ -358,6 +380,11 @@ def test_cwd(self): temp_dir = self._normalize_cwd(temp_dir) self._assert_cwd(temp_dir, sys.executable, cwd=temp_dir) + def test_cwd_with_bytes(self): + temp_dir = tempfile.gettempdir() + temp_dir = self._normalize_cwd(temp_dir) + self._assert_cwd(temp_dir, sys.executable, cwd=os.fsencode(temp_dir)) + def test_cwd_with_pathlike(self): temp_dir = tempfile.gettempdir() temp_dir = self._normalize_cwd(temp_dir) @@ -1473,6 +1500,34 @@ def test_run_kwargs(self): env=newenv) self.assertEqual(cp.returncode, 33) + def test_run_with_pathlike_path(self): + # bpo-31961: test run(pathlike_object) + # the name of a command that can be run without + # any argumenets that exit fast + prog = 'tree.com' if mswindows else 'ls' + path = shutil.which(prog) + if path is None: + self.skipTest(f'{prog} required for this test') + path = FakePath(path) + res = subprocess.run(path, stdout=subprocess.DEVNULL) + self.assertEqual(res.returncode, 0) + with self.assertRaises(TypeError): + subprocess.run(path, stdout=subprocess.DEVNULL, shell=True) + + def test_run_with_bytes_path_and_arguments(self): + # bpo-31961: test run([bytes_object, b'additional arguments']) + path = os.fsencode(sys.executable) + args = [path, '-c', b'import sys; sys.exit(57)'] + res = subprocess.run(args) + self.assertEqual(res.returncode, 57) + + def test_run_with_pathlike_path_and_arguments(self): + # bpo-31961: test run([pathlike_object, 'additional arguments']) + path = FakePath(sys.executable) + args = [path, '-c', 'import sys; sys.exit(57)'] + res = subprocess.run(args) + self.assertEqual(res.returncode, 57) + def test_capture_output(self): cp = self.run_python(("import sys;" "sys.stdout.write('BDFL'); " diff --git a/Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst b/Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst new file mode 100644 index 00000000000000..a38db6790f47ec --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst @@ -0,0 +1,6 @@ +Added support for bytes and path-like objects in :func:`subprocess.Popen` +on Windows. The *args* parameter now accepts a :term:`path-like object` if +*shell* is ``False`` and a sequence containing bytes and path-like objects. +The *executable* parameter now accepts a bytes and :term:`path-like object`. +The *cwd* parameter now accepts a bytes object. +Based on patch by Anders Lorentsen. From 33ce3f012f249782507df896824b045b34f765aa Mon Sep 17 00:00:00 2001 From: MandarJKulkarni <33712629+MandarJKulkarni@users.noreply.github.com> Date: Wed, 29 May 2019 04:25:05 +0530 Subject: [PATCH 159/441] Fix comments in initconfig.h (GH-13636) --- Include/cpython/initconfig.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index a98b91a86943ba..67f38e26505c2a 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -71,11 +71,11 @@ typedef struct { Set to 0 by PYTHONCOERCECLOCALE=0. Set to 1 by PYTHONCOERCECLOCALE=1. Set to 2 if the user preferred LC_CTYPE locale is "C". - If it is equal to 1, LC_CTYPE locale is read to decide it it should be + If it is equal to 1, LC_CTYPE locale is read to decide if it should be coerced or not (ex: PYTHONCOERCECLOCALE=1). Internally, it is set to 2 if the LC_CTYPE locale must be coerced. - Disable by default (set to 0). Set it to -1 to let Python decides if it + Disable by default (set to 0). Set it to -1 to let Python decide if it should be enabled or not. */ int coerce_c_locale; @@ -83,7 +83,7 @@ typedef struct { Set to 1 by PYTHONCOERCECLOCALE=warn. - Disable by default (set to 0). Set it to -1 to let Python decides if it + Disable by default (set to 0). Set it to -1 to let Python decide if it should be enabled or not. */ int coerce_c_locale_warn; From ab0716ed1ea2957396054730afbb80c1825f9786 Mon Sep 17 00:00:00 2001 From: Francisco Facioni Date: Wed, 29 May 2019 00:15:11 +0100 Subject: [PATCH 160/441] bpo-22102: Fixes zip files with disks set to 0 (GH-5985) --- Lib/zipfile.py | 2 +- .../next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 8f8cb863b00343..5496f6eb18678b 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -226,7 +226,7 @@ def _EndRecData64(fpin, offset, endrec): if sig != stringEndArchive64Locator: return endrec - if diskno != 0 or disks != 1: + if diskno != 0 or disks > 1: raise BadZipFile("zipfiles that span multiple disks are not supported") # Assume no 'zip64 extensible data' diff --git a/Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst b/Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst new file mode 100644 index 00000000000000..ad690f57c52384 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst @@ -0,0 +1,2 @@ +Added support for ZIP files with disks set to 0. Such files are commonly created by builtin tools on Windows when use ZIP64 extension. +Patch by Francisco Facioni. From 415406999d7c09af9f3dcacfb4578b9e97b2ce77 Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Tue, 28 May 2019 16:21:17 -0700 Subject: [PATCH 161/441] bpo-37001: Makes symtable.symtable have parity with compile for input (#13483) * Makes symtable.symtable have parity for accepted datatypes for source code as compile() * Add NEWS blurb --- Include/pythonrun.h | 13 ++++ Lib/test/test_symtable.py | 9 +++ .../2019-05-23-21-10-57.bpo-37001.DoLvTK.rst | 2 + Modules/clinic/symtablemodule.c.h | 24 ++----- Modules/symtablemodule.c | 23 +++++-- Python/bltinmodule.c | 55 +--------------- Python/pythonrun.c | 64 +++++++++++++++++-- 7 files changed, 111 insertions(+), 79 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst diff --git a/Include/pythonrun.h b/Include/pythonrun.h index e83846add981cd..196355cb8f40bf 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -119,10 +119,23 @@ PyAPI_FUNC(struct symtable *) Py_SymtableString( const char *filename, /* decoded from the filesystem encoding */ int start); #ifndef Py_LIMITED_API +PyAPI_FUNC(const char *) _Py_SourceAsString( + PyObject *cmd, + const char *funcname, + const char *what, + PyCompilerFlags *cf, + PyObject **cmd_copy); + PyAPI_FUNC(struct symtable *) Py_SymtableStringObject( const char *str, PyObject *filename, int start); + +PyAPI_FUNC(struct symtable *) _Py_SymtableStringObjectFlags( + const char *str, + PyObject *filename, + int start, + PyCompilerFlags *flags); #endif PyAPI_FUNC(void) PyErr_Print(void); diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 0a1cb8d5b43283..bea2ce120ca96b 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -215,6 +215,15 @@ def test_single(self): def test_exec(self): symbols = symtable.symtable("def f(x): return x", "?", "exec") + def test_bytes(self): + top = symtable.symtable(TEST_CODE.encode('utf8'), "?", "exec") + self.assertIsNotNone(find_block(top, "Mine")) + + code = b'# -*- coding: iso8859-15 -*-\nclass \xb4: pass\n' + + top = symtable.symtable(code, "?", "exec") + self.assertIsNotNone(find_block(top, "\u017d")) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst b/Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst new file mode 100644 index 00000000000000..5bcd7a9976c553 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst @@ -0,0 +1,2 @@ +:func:`symtable.symtable` now accepts the same input types for source code as the +built-in :func:`compile` function. Patch by Dino Viehland. diff --git a/Modules/clinic/symtablemodule.c.h b/Modules/clinic/symtablemodule.c.h index 73e340bd462a63..7d8b0ad300c2cf 100644 --- a/Modules/clinic/symtablemodule.c.h +++ b/Modules/clinic/symtablemodule.c.h @@ -3,7 +3,7 @@ preserve [clinic start generated code]*/ PyDoc_STRVAR(_symtable_symtable__doc__, -"symtable($module, str, filename, startstr, /)\n" +"symtable($module, source, filename, startstr, /)\n" "--\n" "\n" "Return symbol and scope dictionaries used internally by compiler."); @@ -12,33 +12,21 @@ PyDoc_STRVAR(_symtable_symtable__doc__, {"symtable", (PyCFunction)(void(*)(void))_symtable_symtable, METH_FASTCALL, _symtable_symtable__doc__}, static PyObject * -_symtable_symtable_impl(PyObject *module, const char *str, +_symtable_symtable_impl(PyObject *module, PyObject *source, PyObject *filename, const char *startstr); static PyObject * _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - const char *str; + PyObject *source; PyObject *filename; const char *startstr; if (!_PyArg_CheckPositional("symtable", nargs, 3, 3)) { goto exit; } - if (!PyUnicode_Check(args[0])) { - _PyArg_BadArgument("symtable", 1, "str", args[0]); - goto exit; - } - Py_ssize_t str_length; - str = PyUnicode_AsUTF8AndSize(args[0], &str_length); - if (str == NULL) { - goto exit; - } - if (strlen(str) != (size_t)str_length) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - goto exit; - } + source = args[0]; if (!PyUnicode_FSDecoder(args[1], &filename)) { goto exit; } @@ -55,9 +43,9 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = _symtable_symtable_impl(module, str, filename, startstr); + return_value = _symtable_symtable_impl(module, source, filename, startstr); exit: return return_value; } -/*[clinic end generated code: output=be1cca59de019984 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=de655625eee705f4 input=a9049054013a1b77]*/ diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index e8d2f5b582be20..d66cb44f69bdfe 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -14,7 +14,7 @@ module _symtable /*[clinic input] _symtable.symtable - str: str + source: object filename: object(converter='PyUnicode_FSDecoder') startstr: str / @@ -23,13 +23,23 @@ Return symbol and scope dictionaries used internally by compiler. [clinic start generated code]*/ static PyObject * -_symtable_symtable_impl(PyObject *module, const char *str, +_symtable_symtable_impl(PyObject *module, PyObject *source, PyObject *filename, const char *startstr) -/*[clinic end generated code: output=914b369c9b785956 input=6c615e84d5f408e3]*/ +/*[clinic end generated code: output=59eb0d5fc7285ac4 input=9dd8a50c0c36a4d7]*/ { struct symtable *st; PyObject *t; int start; + PyCompilerFlags cf; + PyObject *source_copy = NULL; + + cf.cf_flags = PyCF_SOURCE_IS_UTF8; + cf.cf_feature_version = PY_MINOR_VERSION; + + const char *str = _Py_SourceAsString(source, "symtable", "string or bytes", &cf, &source_copy); + if (str == NULL) { + return NULL; + } if (strcmp(startstr, "exec") == 0) start = Py_file_input; @@ -41,12 +51,15 @@ _symtable_symtable_impl(PyObject *module, const char *str, PyErr_SetString(PyExc_ValueError, "symtable() arg 3 must be 'exec' or 'eval' or 'single'"); Py_DECREF(filename); + Py_XDECREF(source_copy); return NULL; } - st = Py_SymtableStringObject(str, filename, start); + st = _Py_SymtableStringObjectFlags(str, filename, start, &cf); Py_DECREF(filename); - if (st == NULL) + Py_XDECREF(source_copy); + if (st == NULL) { return NULL; + } t = (PyObject *)st->st_top; Py_INCREF(t); PyMem_Free((void *)st->st_future); diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 5d5808530e1197..065ad95c95b151 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -687,55 +687,6 @@ builtin_chr_impl(PyObject *module, int i) } -static const char * -source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) -{ - const char *str; - Py_ssize_t size; - Py_buffer view; - - *cmd_copy = NULL; - if (PyUnicode_Check(cmd)) { - cf->cf_flags |= PyCF_IGNORE_COOKIE; - str = PyUnicode_AsUTF8AndSize(cmd, &size); - if (str == NULL) - return NULL; - } - else if (PyBytes_Check(cmd)) { - str = PyBytes_AS_STRING(cmd); - size = PyBytes_GET_SIZE(cmd); - } - else if (PyByteArray_Check(cmd)) { - str = PyByteArray_AS_STRING(cmd); - size = PyByteArray_GET_SIZE(cmd); - } - else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) { - /* Copy to NUL-terminated buffer. */ - *cmd_copy = PyBytes_FromStringAndSize( - (const char *)view.buf, view.len); - PyBuffer_Release(&view); - if (*cmd_copy == NULL) { - return NULL; - } - str = PyBytes_AS_STRING(*cmd_copy); - size = PyBytes_GET_SIZE(*cmd_copy); - } - else { - PyErr_Format(PyExc_TypeError, - "%s() arg 1 must be a %s object", - funcname, what); - return NULL; - } - - if (strlen(str) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, - "source code string cannot contain null bytes"); - Py_CLEAR(*cmd_copy); - return NULL; - } - return str; -} - /*[clinic input] compile as builtin_compile @@ -855,7 +806,7 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, goto finally; } - str = source_as_string(source, "compile", "string, bytes or AST", &cf, &source_copy); + str = _Py_SourceAsString(source, "compile", "string, bytes or AST", &cf, &source_copy); if (str == NULL) goto error; @@ -991,7 +942,7 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, cf.cf_flags = PyCF_SOURCE_IS_UTF8; cf.cf_feature_version = PY_MINOR_VERSION; - str = source_as_string(source, "eval", "string, bytes or code", &cf, &source_copy); + str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy); if (str == NULL) return NULL; @@ -1083,7 +1034,7 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, PyCompilerFlags cf; cf.cf_flags = PyCF_SOURCE_IS_UTF8; cf.cf_feature_version = PY_MINOR_VERSION; - str = source_as_string(source, "exec", + str = _Py_SourceAsString(source, "exec", "string, bytes or code", &cf, &source_copy); if (str == NULL) diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ace9f2f9874e74..784c15bb4b22ce 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1231,21 +1231,77 @@ PyCompileString(const char *str, const char *filename, int start) return Py_CompileStringFlags(str, filename, start, NULL); } +const char * +_Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) +{ + const char *str; + Py_ssize_t size; + Py_buffer view; + + *cmd_copy = NULL; + if (PyUnicode_Check(cmd)) { + cf->cf_flags |= PyCF_IGNORE_COOKIE; + str = PyUnicode_AsUTF8AndSize(cmd, &size); + if (str == NULL) + return NULL; + } + else if (PyBytes_Check(cmd)) { + str = PyBytes_AS_STRING(cmd); + size = PyBytes_GET_SIZE(cmd); + } + else if (PyByteArray_Check(cmd)) { + str = PyByteArray_AS_STRING(cmd); + size = PyByteArray_GET_SIZE(cmd); + } + else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) { + /* Copy to NUL-terminated buffer. */ + *cmd_copy = PyBytes_FromStringAndSize( + (const char *)view.buf, view.len); + PyBuffer_Release(&view); + if (*cmd_copy == NULL) { + return NULL; + } + str = PyBytes_AS_STRING(*cmd_copy); + size = PyBytes_GET_SIZE(*cmd_copy); + } + else { + PyErr_Format(PyExc_TypeError, + "%s() arg 1 must be a %s object", + funcname, what); + return NULL; + } + + if (strlen(str) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, + "source code string cannot contain null bytes"); + Py_CLEAR(*cmd_copy); + return NULL; + } + return str; +} + struct symtable * Py_SymtableStringObject(const char *str, PyObject *filename, int start) +{ + PyCompilerFlags flags; + + flags.cf_flags = 0; + flags.cf_feature_version = PY_MINOR_VERSION; + return _Py_SymtableStringObjectFlags(str, filename, start, &flags); +} + +struct symtable * +_Py_SymtableStringObjectFlags(const char *str, PyObject *filename, int start, PyCompilerFlags *flags) { struct symtable *st; mod_ty mod; - PyCompilerFlags flags; PyArena *arena; arena = PyArena_New(); if (arena == NULL) return NULL; - flags.cf_flags = 0; - flags.cf_feature_version = PY_MINOR_VERSION; - mod = PyParser_ASTFromStringObject(str, filename, start, &flags, arena); + mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; From 44bfff2ec220f2e0291150a776d4d77af7c821ef Mon Sep 17 00:00:00 2001 From: hydrogen-mvm Date: Tue, 28 May 2019 19:22:24 -0400 Subject: [PATCH 162/441] Fix markup and minor grammar improvements in Code_of_conduct.md (GH-13640) The old link had a > in the url which prevented the browser from jumping down to the correct section on that page. That PSF page itself has an error: There's a duplicate "the" in that paragraph that needs to be removed: "...and conform to **the the** Python Community Code of Conduct." While I was editing this file, I also fixed some grammar and bolded the 3 important keywords so that they catch the viewer's eyes. I can revert these changes if they are unwanted. Thanks. --- CODE_OF_CONDUCT.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index ed15b520548c74..c5f24abe2ca661 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,11 +2,11 @@ Please note that all interactions on [Python Software Foundation](https://www.python.org/psf-landing/)-supported -infrastructure is [covered](https://www.python.org/psf/records/board/minutes/2014-01-06/#management-of-the-psfs-web-properties>) +infrastructure is [covered](https://www.python.org/psf/records/board/minutes/2014-01-06/#management-of-the-psfs-web-properties) by the [PSF Code of Conduct](https://www.python.org/psf/codeofconduct/), -which includes all infrastructure used in the development of Python itself +which includes all the infrastructure used in the development of Python itself (e.g. mailing lists, issue trackers, GitHub, etc.). -In general this means everyone is expected to be open, considerate, and -respectful of others no matter what their position is within the project. +In general, this means that everyone is expected to be **open**, **considerate**, and +**respectful** of others no matter what their position is within the project. From 77f0ed7a42606d03ebfe48ab152caf0d796d6540 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 28 May 2019 16:44:58 -0700 Subject: [PATCH 163/441] bpo-37072: Fix crash in PyAST_FromNodeObject() when flags is NULL (#13634) I'm confident that this fixes the reported crash. flags=NULL is treated as using the latest minor version. https://bugs.python.org/issue37072 --- .../Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst | 1 + Python/ast.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst new file mode 100644 index 00000000000000..15bcc5ed2bb0ca --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst @@ -0,0 +1 @@ +Fix crash in PyAST_FromNodeObject() when flags is NULL. \ No newline at end of file diff --git a/Python/ast.c b/Python/ast.c index 7ffdf4a2a03709..12a45f9bbb0074 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -786,7 +786,7 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags, /* borrowed reference */ c.c_filename = filename; c.c_normalize = NULL; - c.c_feature_version = flags->cf_feature_version; + c.c_feature_version = flags ? flags->cf_feature_version : PY_MINOR_VERSION; if (TYPE(n) == encoding_decl) n = CHILD(n, 0); From b76302ddd0896cb39ce69909349b53db6e7776e2 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 29 May 2019 00:45:32 +0100 Subject: [PATCH 164/441] bpo-36540: Documentation for PEP570 - Python positional only arguments (#13202) * bpo-36540: Documentation for PEP570 - Python positional only arguments * fixup! bpo-36540: Documentation for PEP570 - Python positional only arguments * Update reference for compound statements * Apply suggestions from Carol Co-Authored-By: Carol Willing * Update Doc/tutorial/controlflow.rst Co-Authored-By: Carol Willing * Add extra bullet point and minor edits --- Doc/c-api/code.rst | 2 +- Doc/data/refcounts.dat | 1 + Doc/library/inspect.rst | 13 ++- Doc/reference/compound_stmts.rst | 6 +- Doc/tutorial/controlflow.rst | 170 +++++++++++++++++++++++++++++++ 5 files changed, 182 insertions(+), 10 deletions(-) diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index fd3f6919d6d75e..e2b0b23335e33c 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -33,7 +33,7 @@ bound into a function. Return the number of free variables in *co*. -.. c:function:: PyCodeObject* PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab) +.. c:function:: PyCodeObject* PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *lnotab) Return a new code object. If you need a dummy code object to create a frame, use :c:func:`PyCode_NewEmpty` instead. Calling diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 213ddcb61fae60..aca57a1dae9d8c 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -236,6 +236,7 @@ PyCode_GetNumFree:PyCodeObject*:co:0: PyCode_New:PyCodeObject*::+1: PyCode_New:int:argcount:: +PyCode_New:int:posonlyargcount:: PyCode_New:int:kwonlyargcount:: PyCode_New:int:nlocals:: PyCode_New:int:stacksize:: diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 81824ddc1e54db..1cc503a8e94b6d 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -169,6 +169,9 @@ attributes: | | | variables (referenced via | | | | a function's closure) | +-----------+-------------------+---------------------------+ +| | co_posonlyargcount| number of positional only | +| | | arguments | ++-----------+-------------------+---------------------------+ | | co_kwonlyargcount | number of keyword only | | | | arguments (not including | | | | \*\* arg) | @@ -724,13 +727,9 @@ function. | Name | Meaning | +========================+==============================================+ | *POSITIONAL_ONLY* | Value must be supplied as a positional | - | | argument. | - | | | - | | Python has no explicit syntax for defining | - | | positional-only parameters, but many built-in| - | | and extension module functions (especially | - | | those that accept only one or two parameters)| - | | accept them. | + | | argument. Positional only parameters are | + | | those which appear before a ``/`` entry (if | + | | present) in a Python function definition. | +------------------------+----------------------------------------------+ | *POSITIONAL_OR_KEYWORD*| Value may be supplied as either a keyword or | | | positional argument (this is the standard | diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index 42fa8647623935..bf53cb5a48ab03 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -483,8 +483,10 @@ A function definition defines a user-defined function object (see section decorators: `decorator`+ decorator: "@" `dotted_name` ["(" [`argument_list` [","]] ")"] NEWLINE dotted_name: `identifier` ("." `identifier`)* - parameter_list: `defparameter` ("," `defparameter`)* ["," [`parameter_list_starargs`]] - : | `parameter_list_starargs` + parameter_list: `defparameter` ("," `defparameter`)* ',' '/' [',' [`parameter_list_no_posonly`]] + : | `parameter_list_no_posonly` + parameter_list_no_posonly: `defparameter` ("," `defparameter`)* ["," [`parameter_list_starargs`]] + : | `parameter_list_starargs` parameter_list_starargs: "*" [`parameter`] ("," `defparameter`)* ["," ["**" `parameter` [","]]] : | "**" `parameter` [","] parameter: `identifier` [":" `expression`] diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index cfb9645e0da1e1..813b7ca93c7290 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -519,6 +519,176 @@ and of course it would print: Note that the order in which the keyword arguments are printed is guaranteed to match the order in which they were provided in the function call. +Special parameters +------------------ + +By default, arguments may be passed to a Python function either by position +or explicitly by keyword. For readability and performance, it makes sense to +restrict the way arguments can be passed so that a developer need only look +at the function definition to determine if items are passed by position, by +position or keyword, or by keyword. + +A function definition may look like: + +.. code-block:: none + + def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): + ----------- ---------- ---------- + | | | + | Positional or keyword | + | - Keyword only + -- Positional only + +where ``/`` and ``*`` are optional. If used, these symbols indicate the kind of +parameter by how the arguments may be passed to the function: +positional-only, positional-or-keyword, and keyword-only. Keyword parameters +are also referred to as named parameters. + +------------------------------- +Positional-or-Keyword Arguments +------------------------------- + +If ``/`` and ``*`` are not present in the function definition, arguments may +be passed to a function by position or by keyword. + +-------------------------- +Positional-Only Parameters +-------------------------- + +Looking at this in a bit more detail, it is possible to mark certain parameters +as *positional-only*. If *positional-only*, the parameters' order matters, and +the parameters cannot be passed by keyword. Positional-only parameters are +placed before a ``/`` (forward-slash). The ``/`` is used to logically +separate the positional-only parameters from the rest of the parameters. +If there is no ``/`` in the function definition, there are no positional-only +parameters. + +Parameters following the ``/`` may be *positional-or-keyword* or *keyword-only*. + +---------------------- +Keyword-Only Arguments +---------------------- + +To mark parameters as *keyword-only*, indicating the parameters must be passed +by keyword argument, place an ``*`` in the arguments list just before the first +*keyword-only* parameter. + +----------------- +Function Examples +----------------- + +Consider the following example function definitions paying close attention to the +markers ``/`` and ``*``:: + + >>> def standard_arg(arg): + ... print(arg) + ... + >>> def pos_only_arg(arg, /): + ... print(arg) + ... + >>> def kwd_only_arg(*, arg): + ... print(arg) + ... + >>> def combined_example(pos_only, /, standard, *, kwd_only): + ... print(pos_only, standard, kwd_only) + + +The first function definition, ``standard_arg``, the most familiar form, +places no restrictions on the calling convention and arguments may be +passed by position or keyword:: + + >>> standard_arg(2) + 2 + + >>> standard_arg(arg=2) + 2 + +The second function ``pos_only_arg`` is restricted to only use positional +parameters as there is a ``/`` in the function definition:: + + >>> pos_only_arg(1) + 1 + + >>> pos_only_arg(arg=1) + Traceback (most recent call last): + File "", line 1, in + TypeError: pos_only_arg() got an unexpected keyword argument 'arg' + +The third function ``kwd_only_args`` only allows keyword arguments as indicated +by a ``*`` in the function definition:: + + >>> kwd_only_arg(3) + Traceback (most recent call last): + File "", line 1, in + TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given + + >>> kwd_only_arg(arg=3) + 3 + +And the last uses all three calling conventions in the same function +definition:: + + >>> combined_example(1, 2, 3) + Traceback (most recent call last): + File "", line 1, in + TypeError: combined_example() takes 2 positional arguments but 3 were given + + >>> combined_example(1, 2, kwd_only=3) + 1 2 3 + + >>> combined_example(1, standard=2, kwd_only=3) + 1 2 3 + + >>> combined_example(pos_only=1, standard=2, kwd_only=3) + Traceback (most recent call last): + File "", line 1, in + TypeError: combined_example() got an unexpected keyword argument 'pos_only' + + +Finally, consider this function definition which has a potential collision between the positional argument ``name`` and ``**kwds`` which has ``name`` as a key:: + + def foo(name, **kwds): + return 'name' in kwds + +There is no possible call that will make it return ``True`` as the keyword ``'name'`` +will always to bind to the first parameter. For example:: + + >>> foo(1, **{'name': 2}) + Traceback (most recent call last): + File "", line 1, in + TypeError: foo() got multiple values for argument 'name' + >>> + +But using ``/`` (positional only arguments), it is possible since it allows ``name`` as a positional argument and ``'name'`` as a key in the keyword arguments:: + + def foo(name, /, **kwds): + return 'name' in kwds + >>> foo(1, **{'name': 2}) + True + +In other words, the names of positional-only parameters can be used in +``**kwds`` without ambiguity. + +----- +Recap +----- + +The use case will determine which parameters to use in the function definition:: + + def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): + +As guidance: + +* Use positional-only if you want the name of the parameters to not be + available to the user. This is useful when parameter names have no real + meaning, if you want to enforce the order of the arguments when the function + is called or if you need to take some positional parameters and arbitrary + keywords. +* Use keyword-only when names have meaning and the function definition is + more understandable by being explicit with names or you want to prevent + users relying on the position of the argument being passed. +* For an API, use positional-only to prevent prevent breaking API changes + if the parameter's name is modified in the future. .. _tut-arbitraryargs: From 8b09500345d998f3ff1e363a5210bc87f42ff306 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 29 May 2019 02:57:56 +0200 Subject: [PATCH 165/441] bpo-37076: _thread.start_new_thread() calls _PyErr_WriteUnraisableMsg() (GH-13617) _thread.start_new_thread() now logs uncaught exception raised by the function using sys.unraisablehook(), rather than sys.excepthook(), so the hook gets access to the function which raised the exception. --- Doc/library/_thread.rst | 22 ++++++++++++++----- Lib/test/test_thread.py | 18 +++++++++++++++ .../2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst | 3 +++ Modules/_threadmodule.c | 18 ++++----------- 4 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index a6ce945c72057c..48d36e85c9e5ab 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -43,12 +43,22 @@ This module defines the following constants and functions: .. function:: start_new_thread(function, args[, kwargs]) - Start a new thread and return its identifier. The thread executes the function - *function* with the argument list *args* (which must be a tuple). The optional - *kwargs* argument specifies a dictionary of keyword arguments. When the function - returns, the thread silently exits. When the function terminates with an - unhandled exception, a stack trace is printed and then the thread exits (but - other threads continue to run). + Start a new thread and return its identifier. The thread executes the + function *function* with the argument list *args* (which must be a tuple). + The optional *kwargs* argument specifies a dictionary of keyword arguments. + + When the function returns, the thread silently exits. + + When the function terminates with an unhandled exception, + :func:`sys.unraisablehook` is called to handle the exception. The *object* + attribute of the hook argument is *function*. By default, a stack trace is + printed and then the thread exits (but other threads continue to run). + + When the function raises a :exc:`SystemExit` exception, it is silently + ignored. + + .. versionchanged:: 3.8 + :func:`sys.unraisablehook` is now used to handle unhandled exceptions. .. function:: interrupt_main() diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index f4eb830cf6d746..f946f7bc839928 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -154,6 +154,24 @@ def mywrite(self, *args): started.acquire() self.assertIn("Traceback", stderr.getvalue()) + def test_unraisable_exception(self): + def task(): + started.release() + raise ValueError("task failed") + + started = thread.allocate_lock() + with support.catch_unraisable_exception() as cm: + with support.wait_threads_exit(): + started.acquire() + thread.start_new_thread(task, ()) + started.acquire() + + self.assertEqual(str(cm.unraisable.exc_value), "task failed") + self.assertIs(cm.unraisable.object, task) + self.assertEqual(cm.unraisable.err_msg, + "Exception ignored in thread started by") + self.assertIsNotNone(cm.unraisable.exc_traceback) + class Barrier: def __init__(self, num_threads): diff --git a/Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst b/Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst new file mode 100644 index 00000000000000..2773675cb5ad71 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst @@ -0,0 +1,3 @@ +:func:`_thread.start_new_thread` now logs uncaught exception raised by the +function using :func:`sys.unraisablehook`, rather than :func:`sys.excepthook`, +so the hook gets access to the function which raised the exception. diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 680e8ca7108c18..2b1a98f81b1a4e 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1002,25 +1002,15 @@ t_bootstrap(void *boot_raw) res = PyObject_Call(boot->func, boot->args, boot->keyw); if (res == NULL) { if (PyErr_ExceptionMatches(PyExc_SystemExit)) + /* SystemExit is ignored silently */ PyErr_Clear(); else { - PyObject *file; - PyObject *exc, *value, *tb; - PySys_WriteStderr( - "Unhandled exception in thread started by "); - PyErr_Fetch(&exc, &value, &tb); - file = _PySys_GetObjectId(&PyId_stderr); - if (file != NULL && file != Py_None) - PyFile_WriteObject(boot->func, file, 0); - else - PyObject_Print(boot->func, stderr, 0); - PySys_WriteStderr("\n"); - PyErr_Restore(exc, value, tb); - PyErr_PrintEx(0); + _PyErr_WriteUnraisableMsg("in thread started by", boot->func); } } - else + else { Py_DECREF(res); + } Py_DECREF(boot->func); Py_DECREF(boot->args); Py_XDECREF(boot->keyw); From e1f95e77e0647aff602e0660ba3c282b71045875 Mon Sep 17 00:00:00 2001 From: pbhd Date: Wed, 29 May 2019 05:38:03 +0200 Subject: [PATCH 166/441] bpo-36739: Update controlflow.rst (GH-12983) in addition to global-statement also mention nonlocal-statement (in the paragraph describing access to variables which are non local to a function --- Doc/tutorial/controlflow.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 813b7ca93c7290..81a28a6e53257f 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -279,9 +279,11 @@ variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table -of built-in names. Thus, global variables cannot be directly assigned a value -within a function (unless named in a :keyword:`global` statement), although they -may be referenced. +of built-in names. Thus, global variables and variables of enclosing functions +cannot be directly assigned a value within a function (unless, for global +variables, named in a :keyword:`global` statement, or, for variables of enclosing +functions, named in a :keyword:`nonlocal` statement), although they may be +referenced. The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are From 744c08a9c75a1a53b7a6521fcee3e7c513919ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BE=9D=E4=BA=91?= Date: Wed, 29 May 2019 14:50:59 +0800 Subject: [PATCH 167/441] bpo-35246: fix support for path-like args in asyncio subprocess (GH-13628) Drop isinstance checks from create_subprocess_exec function and let subprocess module do them. https://bugs.python.org/issue35246 https://bugs.python.org/issue35246 --- Lib/asyncio/base_events.py | 5 ----- Lib/test/test_asyncio/test_subprocess.py | 11 +++++++++++ .../Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst | 1 + 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 68105eec8132e7..e0025397fa8a85 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1605,11 +1605,6 @@ async def subprocess_exec(self, protocol_factory, program, *args, raise ValueError("errors must be None") popen_args = (program,) + args - for arg in popen_args: - if not isinstance(arg, (str, bytes)): - raise TypeError( - f"program arguments must be a bytes or text string, " - f"not {type(arg).__name__}") protocol = protocol_factory() debug_log = None if self._debug: diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index f1ab039ad6639b..7d72e6cde4e7a8 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -622,6 +622,17 @@ async def execute(): self.loop.run_until_complete(execute()) + def test_create_subprocess_exec_with_path(self): + async def execute(): + p = await subprocess.create_subprocess_exec( + support.FakePath(sys.executable), '-c', 'pass') + await p.wait() + p = await subprocess.create_subprocess_exec( + sys.executable, '-c', 'pass', support.FakePath('.')) + await p.wait() + + self.assertIsNone(self.loop.run_until_complete(execute())) + if sys.platform != 'win32': # Unix class SubprocessWatcherMixin(SubprocessMixin): diff --git a/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst b/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst new file mode 100644 index 00000000000000..39d4469cd10177 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst @@ -0,0 +1 @@ +Make :func:`asyncio.create_subprocess_exec` accept path-like arguments. From 0ae022c6a47abffce22ec185552e319b7b93dbf4 Mon Sep 17 00:00:00 2001 From: Xtreak Date: Wed, 29 May 2019 12:32:26 +0530 Subject: [PATCH 168/441] bpo-37075: Fix string concatenation in assert_has_awaits error message (GH-13616) * Fix the implicit string concatenation in `assert_has_awaits` error message. * Use "await" instead of "call" in `assert_awaited_with` error message. https://bugs.python.org/issue37075 --- Doc/library/unittest.mock.rst | 3 ++- Lib/unittest/mock.py | 10 +++++----- Lib/unittest/test/testmock/testasync.py | 6 ++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index da6cdfe648b0b1..46e8ef38ab11bd 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1954,7 +1954,7 @@ The full list of supported magic methods is: * Container methods: ``__getitem__``, ``__setitem__``, ``__delitem__``, ``__contains__``, ``__len__``, ``__iter__``, ``__reversed__`` and ``__missing__`` -* Context manager: ``__enter__``, ``__exit__``, ``__aenter`` and ``__aexit__`` +* Context manager: ``__enter__``, ``__exit__``, ``__aenter__`` and ``__aexit__`` * Unary numeric methods: ``__neg__``, ``__pos__`` and ``__invert__`` * The numeric methods (including right hand and in-place variants): ``__add__``, ``__sub__``, ``__mul__``, ``__matmul__``, ``__div__``, ``__truediv__``, @@ -2036,6 +2036,7 @@ Methods and their defaults: * ``__len__``: 0 * ``__iter__``: iter([]) * ``__exit__``: False +* ``__aexit__``: False * ``__complex__``: 1j * ``__float__``: 1.0 * ``__bool__``: True diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 055fbb350ce882..be96194793ef28 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -791,12 +791,12 @@ def _format_mock_call_signature(self, args, kwargs): return _format_call_signature(name, args, kwargs) - def _format_mock_failure_message(self, args, kwargs): - message = 'expected call not found.\nExpected: %s\nActual: %s' + def _format_mock_failure_message(self, args, kwargs, action='call'): + message = 'expected %s not found.\nExpected: %s\nActual: %s' expected_string = self._format_mock_call_signature(args, kwargs) call_args = self.call_args actual_string = self._format_mock_call_signature(*call_args) - return message % (expected_string, actual_string) + return message % (action, expected_string, actual_string) def _call_matcher(self, _call): @@ -2139,7 +2139,7 @@ def assert_awaited_with(_mock_self, *args, **kwargs): raise AssertionError(f'Expected await: {expected}\nNot awaited') def _error_message(): - msg = self._format_mock_failure_message(args, kwargs) + msg = self._format_mock_failure_message(args, kwargs, action='await') return msg expected = self._call_matcher((args, kwargs)) @@ -2193,7 +2193,7 @@ def assert_has_awaits(_mock_self, calls, any_order=False): if not any_order: if expected not in all_awaits: raise AssertionError( - f'Awaits not found.\nExpected: {_CallList(calls)}\n', + f'Awaits not found.\nExpected: {_CallList(calls)}\n' f'Actual: {self.await_args_list}' ) from cause return diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/unittest/test/testmock/testasync.py index ccea4fe242dc07..fa906e4f7152f8 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/unittest/test/testmock/testasync.py @@ -542,7 +542,8 @@ def test_assert_awaited_once(self): def test_assert_awaited_with(self): asyncio.run(self._runnable_test()) - with self.assertRaises(AssertionError): + msg = 'expected await not found' + with self.assertRaisesRegex(AssertionError, msg): self.mock.assert_awaited_with('foo') asyncio.run(self._runnable_test('foo')) @@ -580,8 +581,9 @@ def test_assert_any_wait(self): def test_assert_has_awaits_no_order(self): calls = [call('NormalFoo'), call('baz')] - with self.assertRaises(AssertionError): + with self.assertRaises(AssertionError) as cm: self.mock.assert_has_awaits(calls) + self.assertEqual(len(cm.exception.args), 1) asyncio.run(self._runnable_test('foo')) with self.assertRaises(AssertionError): From f83d1dbd3bfbde940117c85f5c70de00e47b7e6e Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Wed, 29 May 2019 03:55:44 -0400 Subject: [PATCH 169/441] bpo-37070: Cleanup fstring debug handling (GH-13607) * Clean up some comments, fix potential memory leaks, clarify literal and expr_text. --- Lib/test/test_future.py | 1 + Python/ast.c | 45 +++++++++++++++++------------------------ 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index 303c5f7fbed605..fd468b57b477e9 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -284,6 +284,7 @@ def test_annotations(self): eq("(x:=10)") eq("f'{(x:=10):=10}'") + def test_fstring_debug_annotations(self): # f-strings with '=' don't round trip very well, so set the expected # result explicitely. self.assertAnnotationEqual("f'{x=!r}'", expected="f'x={x!r}'") diff --git a/Python/ast.c b/Python/ast.c index 12a45f9bbb0074..183b08d6ba1286 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -5010,8 +5010,8 @@ fstring_parse(const char **str, const char *end, int raw, int recurse_lvl, *expression is set to the expression. For an '=' "debug" expression, *expr_text is set to the debug text (the original text of the expression, - *including the '=' and any whitespace around it, as a string object). If - *not a debug expression, *expr_text set to NULL. */ + including the '=' and any whitespace around it, as a string object). If + not a debug expression, *expr_text set to NULL. */ static int fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, PyObject **expr_text, expr_ty *expression, @@ -5039,6 +5039,8 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, Py_ssize_t nested_depth = 0; char parenstack[MAXLEVEL]; + *expr_text = NULL; + /* Can only nest one level deep. */ if (recurse_lvl >= 2) { ast_error(c, n, "f-string: expressions nested too deeply"); @@ -5214,8 +5216,6 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, if (!*expr_text) { goto error; } - } else { - *expr_text = NULL; } /* Check for a conversion char, if present. */ @@ -5281,6 +5281,7 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl, /* Falls through to error. */ error: + Py_XDECREF(*expr_text); return -1; } @@ -5603,7 +5604,8 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str, /* Parse the f-string. */ while (1) { - PyObject *literal[2] = {NULL, NULL}; + PyObject *literal = NULL; + PyObject *expr_text = NULL; expr_ty expression = NULL; /* If there's a zero length literal in front of the @@ -5611,34 +5613,23 @@ FstringParser_ConcatFstring(FstringParser *state, const char **str, the f-string, expression will be NULL (unless result == 1, see below). */ int result = fstring_find_literal_and_expr(str, end, raw, recurse_lvl, - &literal[0], &literal[1], + &literal, &expr_text, &expression, c, n); if (result < 0) return -1; - /* Add the literals, if any. */ - for (int i = 0; i < 2; i++) { - if (!literal[i]) { - /* Do nothing. Just leave last_str alone (and possibly - NULL). */ - } else if (!state->last_str) { - /* Note that the literal can be zero length, if the - input string is "\\\n" or "\\\r", among others. */ - state->last_str = literal[i]; - literal[i] = NULL; - } else { - /* We have a literal, concatenate it. */ - assert(PyUnicode_GET_LENGTH(literal[i]) != 0); - if (FstringParser_ConcatAndDel(state, literal[i]) < 0) - return -1; - literal[i] = NULL; - } + /* Add the literal, if any. */ + if (literal && FstringParser_ConcatAndDel(state, literal) < 0) { + Py_XDECREF(expr_text); + return -1; + } + /* Add the expr_text, if any. */ + if (expr_text && FstringParser_ConcatAndDel(state, expr_text) < 0) { + return -1; } - /* We've dealt with the literals now. They can't be leaked on further - errors. */ - assert(literal[0] == NULL); - assert(literal[1] == NULL); + /* We've dealt with the literal and expr_text, their ownership has + been transferred to the state object. Don't look at them again. */ /* See if we should just loop around to get the next literal and expression, while ignoring the expression this From ca804955927dddb6ae5a846dbc0248a932be9a4e Mon Sep 17 00:00:00 2001 From: Bo Bayles Date: Wed, 29 May 2019 03:06:12 -0500 Subject: [PATCH 170/441] bpo-22454: Add shlex.join() (the opposite of shlex.split()) (GH-7605) --- Doc/library/shlex.rst | 15 ++++++++++++++ Doc/whatsnew/3.8.rst | 5 +++++ Lib/shlex.py | 7 ++++++- Lib/test/test_shlex.py | 20 +++++++++++++++++++ .../2018-06-10-17-48-07.bpo-22454.qeiy_X.rst | 2 ++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index fb335c69006816..8c5b0239d1f08b 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -37,6 +37,21 @@ The :mod:`shlex` module defines the following functions: standard input. +.. function:: join(split_command) + + Concatenate the tokens of the list *split_command* and return a string. + This function is the inverse of :func:`split`. + + >>> from shlex import join + >>> print(join(['echo', '-n', 'Multiple words'])) + echo -n 'Multiple words' + + The returned value is shell-escaped to protect against injection + vulnerabilities (see :func:`quote`). + + .. versionadded:: 3.8 + + .. function:: quote(s) Return a shell-escaped version of the string *s*. The returned value is a diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index d1305dc1e7dfb7..f704b47098e647 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -552,6 +552,11 @@ convenience functions to automate the necessary tasks usually involved when creating a server socket, including accepting both IPv4 and IPv6 connections on the same socket. (Contributed by Giampaolo Rodola in :issue:`17561`.) +shlex +---------- + +The new :func:`shlex.join` function acts as the inverse of :func:`shlex.split`. +(Contributed by Bo Bayles in :issue:`32102`.) shutil ------ diff --git a/Lib/shlex.py b/Lib/shlex.py index 2c9786c517a350..fb1130d4eac207 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -14,7 +14,7 @@ from io import StringIO -__all__ = ["shlex", "split", "quote"] +__all__ = ["shlex", "split", "quote", "join"] class shlex: "A lexical analyzer class for simple shell-like syntaxes." @@ -305,6 +305,11 @@ def split(s, comments=False, posix=True): return list(lex) +def join(split_command): + """Return a shell-escaped string from *split_command*.""" + return ' '.join(quote(arg) for arg in split_command) + + _find_unsafe = re.compile(r'[^\w@%+=:,./-]', re.ASCII).search def quote(s): diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index fd35788e81b272..a432610d3af460 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -308,6 +308,26 @@ def testQuote(self): self.assertEqual(shlex.quote("test%s'name'" % u), "'test%s'\"'\"'name'\"'\"''" % u) + def testJoin(self): + for split_command, command in [ + (['a ', 'b'], "'a ' b"), + (['a', ' b'], "a ' b'"), + (['a', ' ', 'b'], "a ' ' b"), + (['"a', 'b"'], '\'"a\' \'b"\''), + ]: + with self.subTest(command=command): + joined = shlex.join(split_command) + self.assertEqual(joined, command) + + def testJoinRoundtrip(self): + all_data = self.data + self.posix_data + for command, *split_command in all_data: + with self.subTest(command=command): + joined = shlex.join(split_command) + resplit = shlex.split(joined) + self.assertEqual(split_command, resplit) + + # Allow this test to be used with old shlex.py if not getattr(shlex, "split", None): for methname in dir(ShlexTest): diff --git a/Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst b/Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst new file mode 100644 index 00000000000000..2f30e5c893cfb4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst @@ -0,0 +1,2 @@ +The :mod:`shlex` module now exposes :func:`shlex.join`, the inverse of +:func:`shlex.split`. Patch by Bo Bayles. From 7d408697a96953a182328ec0b0650e9999da4116 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Wed, 29 May 2019 17:23:27 +0900 Subject: [PATCH 171/441] remove unnecessary tp_dealloc (GH-13647) --- Objects/bytesobject.c | 10 +--------- Objects/complexobject.c | 8 +------- Objects/longobject.c | 8 +------- Objects/unicodeobject.c | 8 +------- 4 files changed, 4 insertions(+), 30 deletions(-) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 0a3ed8691a222f..6f34037154d64d 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1077,14 +1077,6 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, return NULL; } -/* =-= */ - -static void -bytes_dealloc(PyObject *op) -{ - Py_TYPE(op)->tp_free(op); -} - /* Unescape a backslash-escaped string. If unicode is non-zero, the string is a u-literal. If recode_encoding is non-zero, the string is UTF-8 encoded and should be re-encoded in the @@ -2875,7 +2867,7 @@ PyTypeObject PyBytes_Type = { "bytes", PyBytesObject_SIZE, sizeof(char), - bytes_dealloc, /* tp_dealloc */ + 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ diff --git a/Objects/complexobject.c b/Objects/complexobject.c index cae2bf11dc9b39..6d4d8c56f701a8 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -343,12 +343,6 @@ PyComplex_AsCComplex(PyObject *op) } } -static void -complex_dealloc(PyObject *op) -{ - op->ob_type->tp_free(op); -} - static PyObject * complex_repr(PyComplexObject *v) { @@ -1118,7 +1112,7 @@ PyTypeObject PyComplex_Type = { "complex", sizeof(PyComplexObject), 0, - complex_dealloc, /* tp_dealloc */ + 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ diff --git a/Objects/longobject.c b/Objects/longobject.c index 1934328820c0c5..3ebbd3e7f9c907 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3053,12 +3053,6 @@ PyLong_AsDouble(PyObject *v) /* Methods */ -static void -long_dealloc(PyObject *v) -{ - Py_TYPE(v)->tp_free(v); -} - static int long_compare(PyLongObject *a, PyLongObject *b) { @@ -5628,7 +5622,7 @@ PyTypeObject PyLong_Type = { "int", /* tp_name */ offsetof(PyLongObject, ob_digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ - long_dealloc, /* tp_dealloc */ + 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 0fe7b5658bef36..eafda633a3e2ff 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8099,19 +8099,13 @@ static PyMethodDef encoding_map_methods[] = { { 0 } }; -static void -encoding_map_dealloc(PyObject* o) -{ - PyObject_FREE(o); -} - static PyTypeObject EncodingMapType = { PyVarObject_HEAD_INIT(NULL, 0) "EncodingMap", /*tp_name*/ sizeof(struct encoding_map), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ - encoding_map_dealloc, /*tp_dealloc*/ + 0, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ From 4dd3e3f9bbd320f0dd556688e04db0a6b55a7b52 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 29 May 2019 12:33:59 +0300 Subject: [PATCH 172/441] bpo-32972: Async test case (GH-13386) Add explicit `asyncSetUp` and `asyncTearDown` methods. The rest is the same as for #13228 `AsyncTestCase` create a loop instance for every test for the sake of test isolation. Sometimes a loop shared between all tests can speed up tests execution time a lot but it requires control of closed resources after every test finish. Basically, it requires nested supervisors support that was discussed with @1st1 many times. Sorry, asyncio supervisors have no chance to land on Python 3.8. The PR intentionally does not provide API for changing the used event loop or getting the test loop: use `asyncio.set_event_loop_policy()` and `asyncio.get_event_loop()` instead. The PR adds four overridable methods to base `unittest.TestCase` class: ``` def _callSetUp(self): self.setUp() def _callTestMethod(self, method): method() def _callTearDown(self): self.tearDown() def _callCleanup(self, function, /, *args, **kwargs): function(*args, **kwargs) ``` It allows using asyncio facilities with minimal influence on the unittest code. The last but not least: the PR respects contextvars. The context variable installed by `asyncSetUp` is available on test, `tearDown` and a coroutine scheduled by `addCleanup`. https://bugs.python.org/issue32972 --- Lib/test/test_support.py | 2 +- Lib/unittest/__init__.py | 3 +- Lib/unittest/async_case.py | 158 ++++++++++++++ Lib/unittest/case.py | 20 +- Lib/unittest/test/test_async_case.py | 195 ++++++++++++++++++ .../2019-05-20-14-47-55.bpo-32972.LoeUNh.rst | 1 + 6 files changed, 373 insertions(+), 6 deletions(-) create mode 100644 Lib/unittest/async_case.py create mode 100644 Lib/unittest/test/test_async_case.py create mode 100644 Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index cb664bab17109d..8f0746aed8299a 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -403,7 +403,7 @@ def test_check__all__(self): ("unittest.result", "unittest.case", "unittest.suite", "unittest.loader", "unittest.main", "unittest.runner", - "unittest.signals"), + "unittest.signals", "unittest.async_case"), extra=extra, blacklist=blacklist) diff --git a/Lib/unittest/__init__.py b/Lib/unittest/__init__.py index 5ff1bf37b16965..ace3a6fb1dd971 100644 --- a/Lib/unittest/__init__.py +++ b/Lib/unittest/__init__.py @@ -44,7 +44,7 @@ def testMultiply(self): SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ -__all__ = ['TestResult', 'TestCase', 'TestSuite', +__all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', @@ -57,6 +57,7 @@ def testMultiply(self): __unittest = True from .result import TestResult +from .async_case import IsolatedAsyncioTestCase from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure) from .suite import BaseTestSuite, TestSuite diff --git a/Lib/unittest/async_case.py b/Lib/unittest/async_case.py new file mode 100644 index 00000000000000..a3c8bfb9eca758 --- /dev/null +++ b/Lib/unittest/async_case.py @@ -0,0 +1,158 @@ +import asyncio +import inspect + +from .case import TestCase + + + +class IsolatedAsyncioTestCase(TestCase): + # Names intentionally have a long prefix + # to reduce a chance of clashing with user-defined attributes + # from inherited test case + # + # The class doesn't call loop.run_until_complete(self.setUp()) and family + # but uses a different approach: + # 1. create a long-running task that reads self.setUp() + # awaitable from queue along with a future + # 2. await the awaitable object passing in and set the result + # into the future object + # 3. Outer code puts the awaitable and the future object into a queue + # with waiting for the future + # The trick is necessary because every run_until_complete() call + # creates a new task with embedded ContextVar context. + # To share contextvars between setUp(), test and tearDown() we need to execute + # them inside the same task. + + # Note: the test case modifies event loop policy if the policy was not instantiated + # yet. + # asyncio.get_event_loop_policy() creates a default policy on demand but never + # returns None + # I believe this is not an issue in user level tests but python itself for testing + # should reset a policy in every test module + # by calling asyncio.set_event_loop_policy(None) in tearDownModule() + + def __init__(self, methodName='runTest'): + super().__init__(methodName) + self._asyncioTestLoop = None + self._asyncioCallsQueue = None + + async def asyncSetUp(self): + pass + + async def asyncTearDown(self): + pass + + def addAsyncCleanup(self, func, /, *args, **kwargs): + # A trivial trampoline to addCleanup() + # the function exists because it has a different semantics + # and signature: + # addCleanup() accepts regular functions + # but addAsyncCleanup() accepts coroutines + # + # We intentionally don't add inspect.iscoroutinefunction() check + # for func argument because there is no way + # to check for async function reliably: + # 1. It can be "async def func()" iself + # 2. Class can implement "async def __call__()" method + # 3. Regular "def func()" that returns awaitable object + self.addCleanup(*(func, *args), **kwargs) + + def _callSetUp(self): + self.setUp() + self._callAsync(self.asyncSetUp) + + def _callTestMethod(self, method): + self._callMaybeAsync(method) + + def _callTearDown(self): + self._callAsync(self.asyncTearDown) + self.tearDown() + + def _callCleanup(self, function, *args, **kwargs): + self._callMaybeAsync(function, *args, **kwargs) + + def _callAsync(self, func, /, *args, **kwargs): + assert self._asyncioTestLoop is not None + ret = func(*args, **kwargs) + assert inspect.isawaitable(ret) + fut = self._asyncioTestLoop.create_future() + self._asyncioCallsQueue.put_nowait((fut, ret)) + return self._asyncioTestLoop.run_until_complete(fut) + + def _callMaybeAsync(self, func, /, *args, **kwargs): + assert self._asyncioTestLoop is not None + ret = func(*args, **kwargs) + if inspect.isawaitable(ret): + fut = self._asyncioTestLoop.create_future() + self._asyncioCallsQueue.put_nowait((fut, ret)) + return self._asyncioTestLoop.run_until_complete(fut) + else: + return ret + + async def _asyncioLoopRunner(self): + queue = self._asyncioCallsQueue + while True: + query = await queue.get() + queue.task_done() + if query is None: + return + fut, awaitable = query + try: + ret = await awaitable + if not fut.cancelled(): + fut.set_result(ret) + except asyncio.CancelledError: + raise + except Exception as ex: + if not fut.cancelled(): + fut.set_exception(ex) + + def _setupAsyncioLoop(self): + assert self._asyncioTestLoop is None + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + loop.set_debug(True) + self._asyncioTestLoop = loop + self._asyncioCallsQueue = asyncio.Queue(loop=loop) + self._asyncioCallsTask = loop.create_task(self._asyncioLoopRunner()) + + def _tearDownAsyncioLoop(self): + assert self._asyncioTestLoop is not None + loop = self._asyncioTestLoop + self._asyncioTestLoop = None + self._asyncioCallsQueue.put_nowait(None) + loop.run_until_complete(self._asyncioCallsQueue.join()) + + try: + # cancel all tasks + to_cancel = asyncio.all_tasks(loop) + if not to_cancel: + return + + for task in to_cancel: + task.cancel() + + loop.run_until_complete( + asyncio.gather(*to_cancel, loop=loop, return_exceptions=True)) + + for task in to_cancel: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler({ + 'message': 'unhandled exception during test shutdown', + 'exception': task.exception(), + 'task': task, + }) + # shutdown asyncgens + loop.run_until_complete(loop.shutdown_asyncgens()) + finally: + asyncio.set_event_loop(None) + loop.close() + + def run(self, result=None): + self._setupAsyncioLoop() + try: + return super().run(result) + finally: + self._tearDownAsyncioLoop() diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 8e01c3dc7bbd12..7b1e86941315e8 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -645,6 +645,18 @@ def _addUnexpectedSuccess(self, result): else: addUnexpectedSuccess(self) + def _callSetUp(self): + self.setUp() + + def _callTestMethod(self, method): + method() + + def _callTearDown(self): + self.tearDown() + + def _callCleanup(self, function, /, *args, **kwargs): + function(*args, **kwargs) + def run(self, result=None): orig_result = result if result is None: @@ -676,14 +688,14 @@ def run(self, result=None): self._outcome = outcome with outcome.testPartExecutor(self): - self.setUp() + self._callSetUp() if outcome.success: outcome.expecting_failure = expecting_failure with outcome.testPartExecutor(self, isTest=True): - testMethod() + self._callTestMethod(testMethod) outcome.expecting_failure = False with outcome.testPartExecutor(self): - self.tearDown() + self._callTearDown() self.doCleanups() for test, reason in outcome.skipped: @@ -721,7 +733,7 @@ def doCleanups(self): while self._cleanups: function, args, kwargs = self._cleanups.pop() with outcome.testPartExecutor(self): - function(*args, **kwargs) + self._callCleanup(function, *args, **kwargs) # return this for backwards compatibility # even though we no longer use it internally diff --git a/Lib/unittest/test/test_async_case.py b/Lib/unittest/test/test_async_case.py new file mode 100644 index 00000000000000..2db441da202a01 --- /dev/null +++ b/Lib/unittest/test/test_async_case.py @@ -0,0 +1,195 @@ +import asyncio +import unittest + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +class TestAsyncCase(unittest.TestCase): + def test_full_cycle(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + def setUp(self): + self.assertEqual(events, []) + events.append('setUp') + + async def asyncSetUp(self): + self.assertEqual(events, ['setUp']) + events.append('asyncSetUp') + + async def test_func(self): + self.assertEqual(events, ['setUp', + 'asyncSetUp']) + events.append('test') + self.addAsyncCleanup(self.on_cleanup) + + async def asyncTearDown(self): + self.assertEqual(events, ['setUp', + 'asyncSetUp', + 'test']) + events.append('asyncTearDown') + + def tearDown(self): + self.assertEqual(events, ['setUp', + 'asyncSetUp', + 'test', + 'asyncTearDown']) + events.append('tearDown') + + async def on_cleanup(self): + self.assertEqual(events, ['setUp', + 'asyncSetUp', + 'test', + 'asyncTearDown', + 'tearDown']) + events.append('cleanup') + + test = Test("test_func") + test.run() + self.assertEqual(events, ['setUp', + 'asyncSetUp', + 'test', + 'asyncTearDown', + 'tearDown', + 'cleanup']) + + def test_exception_in_setup(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + events.append('asyncSetUp') + raise Exception() + + async def test_func(self): + events.append('test') + self.addAsyncCleanup(self.on_cleanup) + + async def asyncTearDown(self): + events.append('asyncTearDown') + + async def on_cleanup(self): + events.append('cleanup') + + + test = Test("test_func") + test.run() + self.assertEqual(events, ['asyncSetUp']) + + def test_exception_in_test(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + events.append('asyncSetUp') + + async def test_func(self): + events.append('test') + raise Exception() + self.addAsyncCleanup(self.on_cleanup) + + async def asyncTearDown(self): + events.append('asyncTearDown') + + async def on_cleanup(self): + events.append('cleanup') + + test = Test("test_func") + test.run() + self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown']) + + def test_exception_in_test_after_adding_cleanup(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + events.append('asyncSetUp') + + async def test_func(self): + events.append('test') + self.addAsyncCleanup(self.on_cleanup) + raise Exception() + + async def asyncTearDown(self): + events.append('asyncTearDown') + + async def on_cleanup(self): + events.append('cleanup') + + test = Test("test_func") + test.run() + self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup']) + + def test_exception_in_tear_down(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + events.append('asyncSetUp') + + async def test_func(self): + events.append('test') + self.addAsyncCleanup(self.on_cleanup) + + async def asyncTearDown(self): + events.append('asyncTearDown') + raise Exception() + + async def on_cleanup(self): + events.append('cleanup') + + test = Test("test_func") + test.run() + self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup']) + + + def test_exception_in_tear_clean_up(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + events.append('asyncSetUp') + + async def test_func(self): + events.append('test') + self.addAsyncCleanup(self.on_cleanup) + + async def asyncTearDown(self): + events.append('asyncTearDown') + + async def on_cleanup(self): + events.append('cleanup') + raise Exception() + + test = Test("test_func") + test.run() + self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup']) + + def test_cleanups_interleave_order(self): + events = [] + + class Test(unittest.IsolatedAsyncioTestCase): + async def test_func(self): + self.addAsyncCleanup(self.on_sync_cleanup, 1) + self.addAsyncCleanup(self.on_async_cleanup, 2) + self.addAsyncCleanup(self.on_sync_cleanup, 3) + self.addAsyncCleanup(self.on_async_cleanup, 4) + + async def on_sync_cleanup(self, val): + events.append(f'sync_cleanup {val}') + + async def on_async_cleanup(self, val): + events.append(f'async_cleanup {val}') + + test = Test("test_func") + test.run() + self.assertEqual(events, ['async_cleanup 4', + 'sync_cleanup 3', + 'async_cleanup 2', + 'sync_cleanup 1']) + + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst b/Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst new file mode 100644 index 00000000000000..c8c47cd7763554 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst @@ -0,0 +1 @@ +Implement ``unittest.AsyncTestCase`` to help testing asyncio-based code. From d8b755167235e0621814eb5ac39163b3db6879bb Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 29 May 2019 11:58:11 +0100 Subject: [PATCH 173/441] bpo-33164: blake2 fix for HP-UX (GH-13633) --- Modules/_blake2/impl/blake2-impl.h | 3 +++ configure.ac | 2 ++ 2 files changed, 5 insertions(+) diff --git a/Modules/_blake2/impl/blake2-impl.h b/Modules/_blake2/impl/blake2-impl.h index 5bebd83a2b7dd3..9d2fbb72fc1c03 100644 --- a/Modules/_blake2/impl/blake2-impl.h +++ b/Modules/_blake2/impl/blake2-impl.h @@ -140,6 +140,9 @@ static inline void secure_zero_memory(void *v, size_t n) { #if defined(_WIN32) || defined(WIN32) SecureZeroMemory(v, n); +#elif defined(__hpux) + static void *(*const volatile memset_v)(void *, int, size_t) = &memset; + memset_v(v, 0, n); #else // prioritize first the general C11 call #if defined(HAVE_MEMSET_S) diff --git a/configure.ac b/configure.ac index c743edfdeb183a..864c0abcf93e19 100644 --- a/configure.ac +++ b/configure.ac @@ -3527,6 +3527,8 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ + initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ + memrchr mbrtowc mkdirat mkfifo \ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ From 9ddc416e9f6635376312c3615193f19480ac772a Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 29 May 2019 08:20:35 -0700 Subject: [PATCH 174/441] bpo-36842: Fix reference leak in tests by running out-of-proc (GH-13556) --- Lib/test/audit-tests.py | 269 ++++++++++++++++++++++++++++++++++ Lib/test/libregrtest/setup.py | 47 +++--- Lib/test/test_audit.py | 237 ++++-------------------------- 3 files changed, 323 insertions(+), 230 deletions(-) create mode 100644 Lib/test/audit-tests.py diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py new file mode 100644 index 00000000000000..7a7725f7c212cc --- /dev/null +++ b/Lib/test/audit-tests.py @@ -0,0 +1,269 @@ +"""This script contains the actual auditing tests. + +It should not be imported directly, but should be run by the test_audit +module with arguments identifying each test. + +""" + +import contextlib +import sys + + +class TestHook: + """Used in standard hook tests to collect any logged events. + + Should be used in a with block to ensure that it has no impact + after the test completes. + """ + + def __init__(self, raise_on_events=None, exc_type=RuntimeError): + self.raise_on_events = raise_on_events or () + self.exc_type = exc_type + self.seen = [] + self.closed = False + + def __enter__(self, *a): + sys.addaudithook(self) + return self + + def __exit__(self, *a): + self.close() + + def close(self): + self.closed = True + + @property + def seen_events(self): + return [i[0] for i in self.seen] + + def __call__(self, event, args): + if self.closed: + return + self.seen.append((event, args)) + if event in self.raise_on_events: + raise self.exc_type("saw event " + event) + + +class TestFinalizeHook: + """Used in the test_finalize_hooks function to ensure that hooks + are correctly cleaned up, that they are notified about the cleanup, + and are unable to prevent it. + """ + + def __init__(self): + print("Created", id(self), file=sys.stdout, flush=True) + + def __call__(self, event, args): + # Avoid recursion when we call id() below + if event == "builtins.id": + return + + print(event, id(self), file=sys.stdout, flush=True) + + if event == "cpython._PySys_ClearAuditHooks": + raise RuntimeError("Should be ignored") + elif event == "cpython.PyInterpreterState_Clear": + raise RuntimeError("Should be ignored") + + +# Simple helpers, since we are not in unittest here +def assertEqual(x, y): + if x != y: + raise AssertionError(f"{x!r} should equal {y!r}") + + +def assertIn(el, series): + if el not in series: + raise AssertionError(f"{el!r} should be in {series!r}") + + +def assertNotIn(el, series): + if el in series: + raise AssertionError(f"{el!r} should not be in {series!r}") + + +def assertSequenceEqual(x, y): + if len(x) != len(y): + raise AssertionError(f"{x!r} should equal {y!r}") + if any(ix != iy for ix, iy in zip(x, y)): + raise AssertionError(f"{x!r} should equal {y!r}") + + +@contextlib.contextmanager +def assertRaises(ex_type): + try: + yield + assert False, f"expected {ex_type}" + except BaseException as ex: + if isinstance(ex, AssertionError): + raise + assert type(ex) is ex_type, f"{ex} should be {ex_type}" + + +def test_basic(): + with TestHook() as hook: + sys.audit("test_event", 1, 2, 3) + assertEqual(hook.seen[0][0], "test_event") + assertEqual(hook.seen[0][1], (1, 2, 3)) + + +def test_block_add_hook(): + # Raising an exception should prevent a new hook from being added, + # but will not propagate out. + with TestHook(raise_on_events="sys.addaudithook") as hook1: + with TestHook() as hook2: + sys.audit("test_event") + assertIn("test_event", hook1.seen_events) + assertNotIn("test_event", hook2.seen_events) + + +def test_block_add_hook_baseexception(): + # Raising BaseException will propagate out when adding a hook + with assertRaises(BaseException): + with TestHook( + raise_on_events="sys.addaudithook", exc_type=BaseException + ) as hook1: + # Adding this next hook should raise BaseException + with TestHook() as hook2: + pass + + +def test_finalize_hooks(): + sys.addaudithook(TestFinalizeHook()) + + +def test_pickle(): + import pickle + + class PicklePrint: + def __reduce_ex__(self, p): + return str, ("Pwned!",) + + payload_1 = pickle.dumps(PicklePrint()) + payload_2 = pickle.dumps(("a", "b", "c", 1, 2, 3)) + + # Before we add the hook, ensure our malicious pickle loads + assertEqual("Pwned!", pickle.loads(payload_1)) + + with TestHook(raise_on_events="pickle.find_class") as hook: + with assertRaises(RuntimeError): + # With the hook enabled, loading globals is not allowed + pickle.loads(payload_1) + # pickles with no globals are okay + pickle.loads(payload_2) + + +def test_monkeypatch(): + class A: + pass + + class B: + pass + + class C(A): + pass + + a = A() + + with TestHook() as hook: + # Catch name changes + C.__name__ = "X" + # Catch type changes + C.__bases__ = (B,) + # Ensure bypassing __setattr__ is still caught + type.__dict__["__bases__"].__set__(C, (B,)) + # Catch attribute replacement + C.__init__ = B.__init__ + # Catch attribute addition + C.new_attr = 123 + # Catch class changes + a.__class__ = B + + actual = [(a[0], a[1]) for e, a in hook.seen if e == "object.__setattr__"] + assertSequenceEqual( + [(C, "__name__"), (C, "__bases__"), (C, "__bases__"), (a, "__class__")], actual + ) + + +def test_open(): + # SSLContext.load_dh_params uses _Py_fopen_obj rather than normal open() + try: + import ssl + + load_dh_params = ssl.create_default_context().load_dh_params + except ImportError: + load_dh_params = None + + # Try a range of "open" functions. + # All of them should fail + with TestHook(raise_on_events={"open"}) as hook: + for fn, *args in [ + (open, sys.argv[2], "r"), + (open, sys.executable, "rb"), + (open, 3, "wb"), + (open, sys.argv[2], "w", -1, None, None, None, False, lambda *a: 1), + (load_dh_params, sys.argv[2]), + ]: + if not fn: + continue + with assertRaises(RuntimeError): + fn(*args) + + actual_mode = [(a[0], a[1]) for e, a in hook.seen if e == "open" and a[1]] + actual_flag = [(a[0], a[2]) for e, a in hook.seen if e == "open" and not a[1]] + assertSequenceEqual( + [ + i + for i in [ + (sys.argv[2], "r"), + (sys.executable, "r"), + (3, "w"), + (sys.argv[2], "w"), + (sys.argv[2], "rb") if load_dh_params else None, + ] + if i is not None + ], + actual_mode, + ) + assertSequenceEqual([], actual_flag) + + +def test_cantrace(): + traced = [] + + def trace(frame, event, *args): + if frame.f_code == TestHook.__call__.__code__: + traced.append(event) + + old = sys.settrace(trace) + try: + with TestHook() as hook: + # No traced call + eval("1") + + # No traced call + hook.__cantrace__ = False + eval("2") + + # One traced call + hook.__cantrace__ = True + eval("3") + + # Two traced calls (writing to private member, eval) + hook.__cantrace__ = 1 + eval("4") + + # One traced call (writing to private member) + hook.__cantrace__ = 0 + finally: + sys.settrace(old) + + assertSequenceEqual(["call"] * 4, traced) + + +if __name__ == "__main__": + from test.libregrtest.setup import suppress_msvcrt_asserts + suppress_msvcrt_asserts(False) + + test = sys.argv[1] + globals()[test]() diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index 84931140b10286..fb5ac350cd0847 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -83,27 +83,7 @@ def setup_tests(ns): if ns.threshold is not None: gc.set_threshold(ns.threshold) - try: - import msvcrt - except ImportError: - pass - else: - msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS| - msvcrt.SEM_NOALIGNMENTFAULTEXCEPT| - msvcrt.SEM_NOGPFAULTERRORBOX| - msvcrt.SEM_NOOPENFILEERRORBOX) - try: - msvcrt.CrtSetReportMode - except AttributeError: - # release build - pass - else: - for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: - if ns.verbose and ns.verbose >= 2: - msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) - msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) - else: - msvcrt.CrtSetReportMode(m, 0) + suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2) support.use_resources = ns.use_resources @@ -114,6 +94,31 @@ def _test_audit_hook(name, args): sys.addaudithook(_test_audit_hook) +def suppress_msvcrt_asserts(verbose): + try: + import msvcrt + except ImportError: + return + + msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS| + msvcrt.SEM_NOALIGNMENTFAULTEXCEPT| + msvcrt.SEM_NOGPFAULTERRORBOX| + msvcrt.SEM_NOOPENFILEERRORBOX) + try: + msvcrt.CrtSetReportMode + except AttributeError: + # release build + return + + for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: + if verbose: + msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) + msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) + else: + msvcrt.CrtSetReportMode(m, 0) + + + def replace_stdout(): """Set stdout encoder error handler to backslashreplace (as stderr error handler) to avoid UnicodeEncodeError when printing a traceback""" diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 5b33d978f99d48..f629b7b3d073cc 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -10,111 +10,47 @@ if not hasattr(sys, "addaudithook") or not hasattr(sys, "audit"): raise unittest.SkipTest("test only relevant when sys.audit is available") - -class TestHook: - """Used in standard hook tests to collect any logged events. - - Should be used in a with block to ensure that it has no impact - after the test completes. Audit hooks cannot be removed, so the - best we can do for the test run is disable it by calling close(). - """ - - def __init__(self, raise_on_events=None, exc_type=RuntimeError): - self.raise_on_events = raise_on_events or () - self.exc_type = exc_type - self.seen = [] - self.closed = False - - def __enter__(self, *a): - sys.addaudithook(self) - return self - - def __exit__(self, *a): - self.close() - - def close(self): - self.closed = True - - @property - def seen_events(self): - return [i[0] for i in self.seen] - - def __call__(self, event, args): - if self.closed: - return - self.seen.append((event, args)) - if event in self.raise_on_events: - raise self.exc_type("saw event " + event) - - -class TestFinalizeHook: - """Used in the test_finalize_hooks function to ensure that hooks - are correctly cleaned up, that they are notified about the cleanup, - and are unable to prevent it. - """ - - def __init__(self): - print("Created", id(self), file=sys.stderr, flush=True) - - def __call__(self, event, args): - # Avoid recursion when we call id() below - if event == "builtins.id": - return - - print(event, id(self), file=sys.stderr, flush=True) - - if event == "cpython._PySys_ClearAuditHooks": - raise RuntimeError("Should be ignored") - elif event == "cpython.PyInterpreterState_Clear": - raise RuntimeError("Should be ignored") - - -def run_finalize_test(): - """Called by test_finalize_hooks in a subprocess.""" - sys.addaudithook(TestFinalizeHook()) +AUDIT_TESTS_PY = support.findfile("audit-tests.py") class AuditTest(unittest.TestCase): + def do_test(self, *args): + with subprocess.Popen( + [sys.executable, "-X utf8", AUDIT_TESTS_PY, *args], + encoding="utf-8", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as p: + p.wait() + sys.stdout.writelines(p.stdout) + sys.stderr.writelines(p.stderr) + if p.returncode: + self.fail(''.join(p.stderr)) + def test_basic(self): - with TestHook() as hook: - sys.audit("test_event", 1, 2, 3) - self.assertEqual(hook.seen[0][0], "test_event") - self.assertEqual(hook.seen[0][1], (1, 2, 3)) + self.do_test("test_basic") def test_block_add_hook(self): - # Raising an exception should prevent a new hook from being added, - # but will not propagate out. - with TestHook(raise_on_events="sys.addaudithook") as hook1: - with TestHook() as hook2: - sys.audit("test_event") - self.assertIn("test_event", hook1.seen_events) - self.assertNotIn("test_event", hook2.seen_events) + self.do_test("test_block_add_hook") def test_block_add_hook_baseexception(self): - # Raising BaseException will propagate out when adding a hook - with self.assertRaises(BaseException): - with TestHook( - raise_on_events="sys.addaudithook", exc_type=BaseException - ) as hook1: - # Adding this next hook should raise BaseException - with TestHook() as hook2: - pass + self.do_test("test_block_add_hook_baseexception") def test_finalize_hooks(self): events = [] with subprocess.Popen( - [ - sys.executable, - "-c", - "import test.test_audit; test.test_audit.run_finalize_test()", - ], + [sys.executable, "-X utf8", AUDIT_TESTS_PY, "test_finalize_hooks"], encoding="utf-8", stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) as p: p.wait() - for line in p.stderr: + for line in p.stdout: events.append(line.strip().partition(" ")) + sys.stderr.writelines(p.stderr) + if p.returncode: + self.fail(''.join(p.stderr)) + firstId = events[0][2] self.assertSequenceEqual( [ @@ -125,136 +61,19 @@ def test_finalize_hooks(self): ) def test_pickle(self): - pickle = support.import_module("pickle") + support.import_module("pickle") - class PicklePrint: - def __reduce_ex__(self, p): - return str, ("Pwned!",) - - payload_1 = pickle.dumps(PicklePrint()) - payload_2 = pickle.dumps(("a", "b", "c", 1, 2, 3)) - - # Before we add the hook, ensure our malicious pickle loads - self.assertEqual("Pwned!", pickle.loads(payload_1)) - - with TestHook(raise_on_events="pickle.find_class") as hook: - with self.assertRaises(RuntimeError): - # With the hook enabled, loading globals is not allowed - pickle.loads(payload_1) - # pickles with no globals are okay - pickle.loads(payload_2) + self.do_test("test_pickle") def test_monkeypatch(self): - class A: - pass - - class B: - pass - - class C(A): - pass - - a = A() - - with TestHook() as hook: - # Catch name changes - C.__name__ = "X" - # Catch type changes - C.__bases__ = (B,) - # Ensure bypassing __setattr__ is still caught - type.__dict__["__bases__"].__set__(C, (B,)) - # Catch attribute replacement - C.__init__ = B.__init__ - # Catch attribute addition - C.new_attr = 123 - # Catch class changes - a.__class__ = B - - actual = [(a[0], a[1]) for e, a in hook.seen if e == "object.__setattr__"] - self.assertSequenceEqual( - [(C, "__name__"), (C, "__bases__"), (C, "__bases__"), (a, "__class__")], - actual, - ) + self.do_test("test_monkeypatch") def test_open(self): - # SSLContext.load_dh_params uses _Py_fopen_obj rather than normal open() - try: - import ssl - - load_dh_params = ssl.create_default_context().load_dh_params - except ImportError: - load_dh_params = None - - # Try a range of "open" functions. - # All of them should fail - with TestHook(raise_on_events={"open"}) as hook: - for fn, *args in [ - (open, support.TESTFN, "r"), - (open, sys.executable, "rb"), - (open, 3, "wb"), - (open, support.TESTFN, "w", -1, None, None, None, False, lambda *a: 1), - (load_dh_params, support.TESTFN), - ]: - if not fn: - continue - self.assertRaises(RuntimeError, fn, *args) - - actual_mode = [(a[0], a[1]) for e, a in hook.seen if e == "open" and a[1]] - actual_flag = [(a[0], a[2]) for e, a in hook.seen if e == "open" and not a[1]] - self.assertSequenceEqual( - [ - i - for i in [ - (support.TESTFN, "r"), - (sys.executable, "r"), - (3, "w"), - (support.TESTFN, "w"), - (support.TESTFN, "rb") if load_dh_params else None, - ] - if i is not None - ], - actual_mode, - ) - self.assertSequenceEqual([], actual_flag) + self.do_test("test_open", support.TESTFN) def test_cantrace(self): - traced = [] - - def trace(frame, event, *args): - if frame.f_code == TestHook.__call__.__code__: - traced.append(event) - - old = sys.settrace(trace) - try: - with TestHook() as hook: - # No traced call - eval("1") - - # No traced call - hook.__cantrace__ = False - eval("2") - - # One traced call - hook.__cantrace__ = True - eval("3") - - # Two traced calls (writing to private member, eval) - hook.__cantrace__ = 1 - eval("4") - - # One traced call (writing to private member) - hook.__cantrace__ = 0 - finally: - sys.settrace(old) - - self.assertSequenceEqual(["call"] * 4, traced) + self.do_test("test_cantrace") if __name__ == "__main__": - if len(sys.argv) >= 2 and sys.argv[1] == "spython_test": - # Doesn't matter what we add - it will be blocked - sys.addaudithook(None) - - sys.exit(0) - unittest.main() From 1c999262281c4a946c49614c3f8549f68049c0d9 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Wed, 29 May 2019 17:45:19 +0200 Subject: [PATCH 175/441] Add my to code owner for more areas (#13650) --- .github/CODEOWNERS | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1638a8b4b44370..6a4ca54dd34e16 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,8 +14,14 @@ Objects/dict* @methane # Hashing -**/*hashlib* @python/crypto-team -**/*pyhash* @python/crypto-team +**/*hashlib* @python/crypto-team @tiran +**/*pyhash* @python/crypto-team @tiran +**/*sha* @python/crypto-team @tiran +**/*md5* @python/crypto-team @tiran +**/*blake* @python/crypto-team @tiran +/Modules/_blake2/** @python/crypto-team @tiran +/Modules/_sha3/** @python/crypto-team @tiran + # HTML /Lib/html/ @ezio-melotti @@ -31,10 +37,11 @@ Objects/dict* @methane # SSL -**/*ssl* @python/crypto-team +**/*ssl* @python/crypto-team @tiran +**/*.pem @python/crypto-team @tiran # CSPRNG -Python/bootstrap_hash.c @python/crypto-team +Python/bootstrap_hash.c @python/crypto-team @tiran # Email and related **/*mail* @python/email-team @maxking From 46ed90dd014010703c7a3b2a61c4927644fa8210 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Wed, 29 May 2019 18:34:04 +0200 Subject: [PATCH 176/441] Doc: Add an optional obsolete header. (GH-13638) --- Doc/README.rst | 9 +++++++++ Doc/tools/templates/layout.html | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/Doc/README.rst b/Doc/README.rst index 31f8a8b7f59328..380ea4fa9b26ad 100644 --- a/Doc/README.rst +++ b/Doc/README.rst @@ -113,6 +113,15 @@ Then, from the ``Doc`` directory, run :: where ```` is one of html, text, latex, or htmlhelp (for explanations see the make targets above). +Deprecation header +================== + +You can define the ``outdated`` variable in ``html_context`` to show a +red banner on each page redirecting to the "latest" version. + +The link points to the same page on ``/3/``, sadly for the moment the +language is lost during the process. + Contributing ============ diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index c3992245614082..a765a5de8a2dfb 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -1,5 +1,15 @@ {% extends "!layout.html" %} +{% block header %} +{%- if outdated %} +
+ {% trans %}This document is for an old version of Python that is no longer supported. + You should upgrade, and read the {% endtrans %} + {% trans %} Python documentation for the last stable release {% endtrans %}. +
+{%- endif %} +{% endblock %} + {% block rootrellink %} {{ super() }}
  • From 34f4f5efea730504216ee19f237734e0bb0104ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hrvoje=20Nik=C5=A1i=C4=87?= Date: Wed, 29 May 2019 19:08:17 +0200 Subject: [PATCH 177/441] bpo-36794: Document that Lock.acquire is fair. (GH-13082) https://bugs.python.org/issue36794 --- Doc/library/asyncio-sync.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst index e3f18ccb4341fe..79f6b02d85e2e5 100644 --- a/Doc/library/asyncio-sync.rst +++ b/Doc/library/asyncio-sync.rst @@ -66,6 +66,13 @@ Lock This method waits until the lock is *unlocked*, sets it to *locked* and returns ``True``. + When more than one coroutine is blocked in :meth:`acquire` + waiting for the lock to be unlocked, only one coroutine + eventually proceeds. + + Acquiring a lock is *fair*: the coroutine that proceeds will be + the first coroutine that started waiting on the lock. + .. method:: release() Release the lock. From d30da5dd9a8a965cf24a22bbaff8a5b1341c2944 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 29 May 2019 11:19:38 -0700 Subject: [PATCH 178/441] bpo-36983: Fix typing.__all__ and add test for exported names (GH-13456) https://bugs.python.org/issue36983 --- Lib/test/test_typing.py | 24 +++++++++++++++++++ Lib/typing.py | 3 +++ .../2019-05-20-20-41-30.bpo-36983.hz-fLr.rst | 2 ++ 3 files changed, 29 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 2b4b934d69f2b5..f9c18c84c8f9e6 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3605,6 +3605,30 @@ def test_all(self): self.assertIn('SupportsBytes', a) self.assertIn('SupportsComplex', a) + def test_all_exported_names(self): + import typing + + actual_all = set(typing.__all__) + computed_all = { + k for k, v in vars(typing).items() + # explicitly exported, not a thing with __module__ + if k in actual_all or ( + # avoid private names + not k.startswith('_') and + # avoid things in the io / re typing submodules + k not in typing.io.__all__ and + k not in typing.re.__all__ and + k not in {'io', 're'} and + # there's a few types and metaclasses that aren't exported + not k.endswith(('Meta', '_contra', '_co')) and + not k.upper() == k and + # but export all things that have __module__ == 'typing' + getattr(v, '__module__', None) == typing.__name__ + ) + } + self.assertSetEqual(computed_all, actual_all) + + if __name__ == '__main__': main() diff --git a/Lib/typing.py b/Lib/typing.py index 14bd06b2b745b9..3b4e9df0482eda 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -35,6 +35,7 @@ 'Callable', 'ClassVar', 'Final', + 'ForwardRef', 'Generic', 'Literal', 'Optional', @@ -81,11 +82,13 @@ 'SupportsRound', # Concrete collection types. + 'ChainMap', 'Counter', 'Deque', 'Dict', 'DefaultDict', 'List', + 'OrderedDict', 'Set', 'FrozenSet', 'NamedTuple', # Not really a type. diff --git a/Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst b/Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst new file mode 100644 index 00000000000000..bd2d91ad9234e3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst @@ -0,0 +1,2 @@ +Add missing names to ``typing.__all__``: ``ChainMap``, ``ForwardRef``, +``OrderedDict`` - by Anthony Sottile. From aacc77fbd77640a8f03638216fa09372cc21673d Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Wed, 29 May 2019 20:31:52 +0200 Subject: [PATCH 179/441] bpo-36974: implement PEP 590 (GH-13185) Co-authored-by: Jeroen Demeyer Co-authored-by: Mark Shannon --- Include/classobject.h | 1 + Include/cpython/abstract.h | 117 +++++++--- Include/cpython/object.h | 15 +- Include/descrobject.h | 3 +- Include/funcobject.h | 3 +- Include/methodobject.h | 3 +- Include/object.h | 5 + Lib/test/test_call.py | 16 +- Lib/test/test_capi.py | 47 ++++ Lib/test/test_sys.py | 8 +- .../2019-05-22-15-24-08.bpo-36974.TkySRe.rst | 2 + Modules/_asynciomodule.c | 6 +- Modules/_testcapimodule.c | 31 ++- Objects/call.c | 208 +++++++++--------- Objects/classobject.c | 45 +++- Objects/descrobject.c | 10 +- Objects/funcobject.c | 4 +- Objects/methodobject.c | 13 +- Python/bltinmodule.c | 4 +- Python/ceval.c | 92 ++++---- Python/context.c | 2 +- Python/sysmodule.c | 2 +- 22 files changed, 404 insertions(+), 233 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst diff --git a/Include/classobject.h b/Include/classobject.h index 209f0f4a284301..c83303c3900553 100644 --- a/Include/classobject.h +++ b/Include/classobject.h @@ -14,6 +14,7 @@ typedef struct { PyObject *im_func; /* The callable object implementing the method */ PyObject *im_self; /* The instance it is bound to */ PyObject *im_weakreflist; /* List of weak references */ + vectorcallfunc vectorcall; } PyMethodObject; PyAPI_DATA(PyTypeObject) PyMethod_Type; diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index b8b2d449faf306..7099178f82087d 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -47,7 +47,7 @@ PyAPI_FUNC(int) _PyStack_UnpackDict( /* Suggested size (number of positional arguments) for arrays of PyObject* allocated on a C stack to avoid allocating memory on the heap memory. Such array is used to pass positional arguments to call functions of the - _PyObject_FastCall() family. + _PyObject_Vectorcall() family. The size is chosen to not abuse the C stack and so limit the risk of stack overflow. The size is also chosen to allow using the small stack for most @@ -56,50 +56,103 @@ PyAPI_FUNC(int) _PyStack_UnpackDict( #define _PY_FASTCALL_SMALL_STACK 5 /* Return 1 if callable supports FASTCALL calling convention for positional - arguments: see _PyObject_FastCallDict() and _PyObject_FastCallKeywords() */ + arguments: see _PyObject_Vectorcall() and _PyObject_FastCallDict() */ PyAPI_FUNC(int) _PyObject_HasFastCall(PyObject *callable); -/* Call the callable object 'callable' with the "fast call" calling convention: - args is a C array for positional arguments (nargs is the number of - positional arguments), kwargs is a dictionary for keyword arguments. +PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable, + PyObject *result, + const char *where); - If nargs is equal to zero, args can be NULL. kwargs can be NULL. - nargs must be greater or equal to zero. +/* === Vectorcall protocol (PEP 590) ============================= */ - Return the result on success. Raise an exception and return NULL on - error. */ -PyAPI_FUNC(PyObject *) _PyObject_FastCallDict( +/* Call callable using tp_call. Arguments are like _PyObject_Vectorcall() + or _PyObject_FastCallDict() (both forms are supported), + except that nargs is plainly the number of arguments without flags. */ +PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( PyObject *callable, - PyObject *const *args, - Py_ssize_t nargs, - PyObject *kwargs); + PyObject *const *args, Py_ssize_t nargs, + PyObject *keywords); -/* Call the callable object 'callable' with the "fast call" calling convention: - args is a C array for positional arguments followed by values of - keyword arguments. Keys of keyword arguments are stored as a tuple - of strings in kwnames. nargs is the number of positional parameters at - the beginning of stack. The size of kwnames gives the number of keyword - values in the stack after positional arguments. +#define PY_VECTORCALL_ARGUMENTS_OFFSET ((size_t)1 << (8 * sizeof(size_t) - 1)) - kwnames must only contains str strings, no subclass, and all keys must - be unique. +static inline Py_ssize_t +PyVectorcall_NARGS(size_t n) +{ + return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; +} + +static inline vectorcallfunc +_PyVectorcall_Function(PyObject *callable) +{ + PyTypeObject *tp = Py_TYPE(callable); + if (!PyType_HasFeature(tp, _Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + Py_ssize_t offset = tp->tp_vectorcall_offset; + assert(offset > 0); + vectorcallfunc *ptr = (vectorcallfunc *)(((char *)callable) + offset); + return *ptr; +} + +/* Call the callable object 'callable' with the "vectorcall" calling + convention. + + args is a C array for positional arguments. + + nargsf is the number of positional arguments plus optionally the flag + PY_VECTORCALL_ARGUMENTS_OFFSET which means that the caller is allowed to + modify args[-1]. - If nargs is equal to zero and there is no keyword argument (kwnames is - NULL or its size is zero), args can be NULL. + kwnames is a tuple of keyword names. The values of the keyword arguments + are stored in "args" after the positional arguments (note that the number + of keyword arguments does not change nargsf). kwnames can also be NULL if + there are no keyword arguments. + + keywords must only contains str strings (no subclass), and all keys must + be unique. Return the result on success. Raise an exception and return NULL on error. */ -PyAPI_FUNC(PyObject *) _PyObject_FastCallKeywords( +static inline PyObject * +_PyObject_Vectorcall(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + assert(kwnames == NULL || PyTuple_Check(kwnames)); + assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); + vectorcallfunc func = _PyVectorcall_Function(callable); + if (func == NULL) { + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + return _PyObject_MakeTpCall(callable, args, nargs, kwnames); + } + PyObject *res = func(callable, args, nargsf, kwnames); + return _Py_CheckFunctionResult(callable, res, NULL); +} + +/* Same as _PyObject_Vectorcall except that keyword arguments are passed as + dict, which may be NULL if there are no keyword arguments. */ +PyAPI_FUNC(PyObject *) _PyObject_FastCallDict( PyObject *callable, PyObject *const *args, - Py_ssize_t nargs, - PyObject *kwnames); + size_t nargsf, + PyObject *kwargs); -#define _PyObject_FastCall(func, args, nargs) \ - _PyObject_FastCallDict((func), (args), (nargs), NULL) +/* Call "callable" (which must support vectorcall) with positional arguments + "tuple" and keyword arguments "dict". "dict" may also be NULL */ +PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); -#define _PyObject_CallNoArg(func) \ - _PyObject_FastCallDict((func), NULL, 0, NULL) +/* Same as _PyObject_Vectorcall except without keyword arguments */ +static inline PyObject * +_PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) +{ + return _PyObject_Vectorcall(func, args, (size_t)nargs, NULL); +} + +/* Call a callable without any arguments */ +static inline PyObject * +_PyObject_CallNoArg(PyObject *func) { + return _PyObject_Vectorcall(func, NULL, 0, NULL); +} PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( PyObject *callable, @@ -113,10 +166,6 @@ PyAPI_FUNC(PyObject *) _PyObject_FastCall_Prepend( PyObject *const *args, Py_ssize_t nargs); -PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable, - PyObject *result, - const char *where); - /* Like PyObject_CallMethod(), but expect a _Py_Identifier* as the method name. */ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj, diff --git a/Include/cpython/object.h b/Include/cpython/object.h index ba52a4835823b6..a65aaf6482159c 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -55,6 +55,9 @@ typedef struct bufferinfo { typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); typedef void (*releasebufferproc)(PyObject *, Py_buffer *); +typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); + /* Maximum number of dimensions */ #define PyBUF_MAX_NDIM 64 @@ -167,12 +170,9 @@ typedef struct { releasebufferproc bf_releasebuffer; } PyBufferProcs; -/* We can't provide a full compile-time check that limited-API - users won't implement tp_print. However, not defining printfunc - and making tp_print of a different function pointer type - if Py_LIMITED_API is set should at least cause a warning - in most cases. */ -typedef int (*printfunc)(PyObject *, FILE *, int); +/* Allow printfunc in the tp_vectorcall_offset slot for + * backwards-compatibility */ +typedef Py_ssize_t printfunc; typedef struct _typeobject { PyObject_VAR_HEAD @@ -182,7 +182,7 @@ typedef struct _typeobject { /* Methods to implement standard operations */ destructor tp_dealloc; - printfunc tp_print; + Py_ssize_t tp_vectorcall_offset; getattrfunc tp_getattr; setattrfunc tp_setattr; PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) @@ -254,6 +254,7 @@ typedef struct _typeobject { unsigned int tp_version_tag; destructor tp_finalize; + vectorcallfunc tp_vectorcall; #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ diff --git a/Include/descrobject.h b/Include/descrobject.h index 73bbb3fe54e5d0..3db09635399cc2 100644 --- a/Include/descrobject.h +++ b/Include/descrobject.h @@ -53,6 +53,7 @@ typedef struct { typedef struct { PyDescr_COMMON; PyMethodDef *d_method; + vectorcallfunc vectorcall; } PyMethodDescrObject; typedef struct { @@ -92,7 +93,7 @@ PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyMethodDescr_FastCallKeywords( - PyObject *descrobj, PyObject *const *stack, Py_ssize_t nargs, PyObject *kwnames); + PyObject *descrobj, PyObject *const *args, size_t nargsf, PyObject *kwnames); PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); #define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL) diff --git a/Include/funcobject.h b/Include/funcobject.h index 86674ac90a08de..7ba000e1f13cc2 100644 --- a/Include/funcobject.h +++ b/Include/funcobject.h @@ -32,6 +32,7 @@ typedef struct { PyObject *func_module; /* The __module__ attribute, can be anything */ PyObject *func_annotations; /* Annotations, a dict or NULL */ PyObject *func_qualname; /* The qualified name */ + vectorcallfunc vectorcall; /* Invariant: * func_closure contains the bindings for func_code->co_freevars, so @@ -68,7 +69,7 @@ PyAPI_FUNC(PyObject *) _PyFunction_FastCallDict( PyAPI_FUNC(PyObject *) _PyFunction_FastCallKeywords( PyObject *func, PyObject *const *stack, - Py_ssize_t nargs, + size_t nargsf, PyObject *kwnames); #endif diff --git a/Include/methodobject.h b/Include/methodobject.h index ea35d86bcd171d..5dbe2145dadc39 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -49,7 +49,7 @@ PyAPI_FUNC(PyObject *) _PyCFunction_FastCallDict(PyObject *func, PyAPI_FUNC(PyObject *) _PyCFunction_FastCallKeywords(PyObject *func, PyObject *const *stack, - Py_ssize_t nargs, + size_t nargsf, PyObject *kwnames); #endif @@ -105,6 +105,7 @@ typedef struct { PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ PyObject *m_module; /* The __module__ attribute, can be anything */ PyObject *m_weakreflist; /* List of weak references */ + vectorcallfunc vectorcall; } PyCFunctionObject; PyAPI_FUNC(PyObject *) _PyMethodDef_RawFastCallDict( diff --git a/Include/object.h b/Include/object.h index d5d98d3bd885be..11ba2bb8e2388c 100644 --- a/Include/object.h +++ b/Include/object.h @@ -291,6 +291,11 @@ given type object has a specified feature. /* Set if the type allows subclassing */ #define Py_TPFLAGS_BASETYPE (1UL << 10) +/* Set if the type implements the vectorcall protocol (PEP 590) */ +#ifndef Py_LIMITED_API +#define _Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) +#endif + /* Set if the type is 'ready' -- fully initialized */ #define Py_TPFLAGS_READY (1UL << 12) diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index e4ab33cbc16b58..9f0a75b84a03c3 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -402,7 +402,7 @@ def test_fastcall(self): result = _testcapi.pyobject_fastcall(func, None) self.check_result(result, expected) - def test_fastcall_dict(self): + def test_vectorcall_dict(self): # Test _PyObject_FastCallDict() for func, args, expected in self.CALLS_POSARGS: @@ -429,33 +429,33 @@ def test_fastcall_dict(self): result = _testcapi.pyobject_fastcalldict(func, args, kwargs) self.check_result(result, expected) - def test_fastcall_keywords(self): - # Test _PyObject_FastCallKeywords() + def test_vectorcall(self): + # Test _PyObject_Vectorcall() for func, args, expected in self.CALLS_POSARGS: with self.subTest(func=func, args=args): # kwnames=NULL - result = _testcapi.pyobject_fastcallkeywords(func, args, None) + result = _testcapi.pyobject_vectorcall(func, args, None) self.check_result(result, expected) # kwnames=() - result = _testcapi.pyobject_fastcallkeywords(func, args, ()) + result = _testcapi.pyobject_vectorcall(func, args, ()) self.check_result(result, expected) if not args: # kwnames=NULL - result = _testcapi.pyobject_fastcallkeywords(func, None, None) + result = _testcapi.pyobject_vectorcall(func, None, None) self.check_result(result, expected) # kwnames=() - result = _testcapi.pyobject_fastcallkeywords(func, None, ()) + result = _testcapi.pyobject_vectorcall(func, None, ()) self.check_result(result, expected) for func, args, kwargs, expected in self.CALLS_KWARGS: with self.subTest(func=func, args=args, kwargs=kwargs): kwnames = tuple(kwargs.keys()) args = args + tuple(kwargs.values()) - result = _testcapi.pyobject_fastcallkeywords(func, args, kwnames) + result = _testcapi.pyobject_vectorcall(func, args, kwnames) self.check_result(result, expected) def test_fastcall_clearing_dict(self): diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index f3d41a20ab0560..0813abb9a69722 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -34,6 +34,11 @@ def testfunction(self): """some doc""" return self +def testfunction_kw(self, *, kw): + """some doc""" + return self + + class InstanceMethod: id = _testcapi.instancemethod(id) testfunction = _testcapi.instancemethod(testfunction) @@ -479,6 +484,48 @@ class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): pass self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + def test_vectorcall(self): + # Test a bunch of different ways to call objects: + # 1. normal call + # 2. vectorcall using _PyObject_Vectorcall() + # 3. vectorcall using PyVectorcall_Call() + # 4. call as bound method + # 5. call using functools.partial + + # A list of (function, args, kwargs, result) calls to test + calls = [(len, (range(42),), {}, 42), + (list.append, ([], 0), {}, None), + ([].append, (0,), {}, None), + (sum, ([36],), {"start":6}, 42), + (testfunction, (42,), {}, 42), + (testfunction_kw, (42,), {"kw":None}, 42)] + + from _testcapi import pyobject_vectorcall, pyvectorcall_call + from types import MethodType + from functools import partial + + def vectorcall(func, args, kwargs): + args = *args, *kwargs.values() + kwnames = tuple(kwargs) + return pyobject_vectorcall(func, args, kwnames) + + for (func, args, kwargs, expected) in calls: + with self.subTest(str(func)): + args1 = args[1:] + meth = MethodType(func, args[0]) + wrapped = partial(func) + if not kwargs: + self.assertEqual(expected, func(*args)) + self.assertEqual(expected, pyobject_vectorcall(func, args, None)) + self.assertEqual(expected, pyvectorcall_call(func, args)) + self.assertEqual(expected, meth(*args1)) + self.assertEqual(expected, wrapped(*args)) + self.assertEqual(expected, func(*args, **kwargs)) + self.assertEqual(expected, vectorcall(func, args, kwargs)) + self.assertEqual(expected, pyvectorcall_call(func, args, kwargs)) + self.assertEqual(expected, meth(*args1, **kwargs)) + self.assertEqual(expected, wrapped(*args, **kwargs)) + class SubinterpreterTest(unittest.TestCase): diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index dfe63b1aade2eb..c558d116e6fe9d 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1064,7 +1064,7 @@ def test_objecttypes(self): # buffer # XXX # builtin_function_or_method - check(len, size('4P')) # XXX check layout + check(len, size('5P')) # bytearray samples = [b'', b'u'*100000] for sample in samples: @@ -1095,7 +1095,7 @@ def inner(): # complex check(complex(0,1), size('2d')) # method_descriptor (descriptor object) - check(str.lower, size('3PP')) + check(str.lower, size('3PPP')) # classmethod_descriptor (descriptor object) # XXX # member_descriptor (descriptor object) @@ -1164,7 +1164,7 @@ class C(object): pass check(x, vsize('5P2c4P3ic' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P')) # function def func(): pass - check(func, size('12P')) + check(func, size('13P')) class c(): @staticmethod def foo(): @@ -1259,7 +1259,7 @@ def delx(self): del self.__x check((1,2,3), vsize('') + 3*self.P) # type # static type: PyTypeObject - fmt = 'P2n15Pl4Pn9Pn11PIP' + fmt = 'P2nPI13Pl4Pn9Pn11PIPP' if hasattr(sys, 'getcounts'): fmt += '3n2P' s = vsize(fmt) diff --git a/Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst b/Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst new file mode 100644 index 00000000000000..c51c2e2419d1fa --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst @@ -0,0 +1,2 @@ +Implement :pep:`590`: Vectorcall: a fast calling protocol for CPython. +This is a new protocol to optimize calls of custom callable objects. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index ac15d0169b8158..60136082a7eecf 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -367,8 +367,7 @@ call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx) } stack[nargs] = (PyObject *)ctx; - handle = _PyObject_FastCallKeywords( - callable, stack, nargs, context_kwname); + handle = _PyObject_Vectorcall(callable, stack, nargs, context_kwname); Py_DECREF(callable); } @@ -2805,8 +2804,7 @@ task_step_impl(TaskObj *task, PyObject *exc) PyObject *stack[2]; stack[0] = wrapper; stack[1] = (PyObject *)task->task_context; - res = _PyObject_FastCallKeywords( - add_cb, stack, 1, context_kwname); + res = _PyObject_Vectorcall(add_cb, stack, 1, context_kwname); Py_DECREF(add_cb); Py_DECREF(wrapper); if (res == NULL) { diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 8ba927039c2705..f2f418c997ab59 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4713,7 +4713,7 @@ test_pyobject_fastcalldict(PyObject *self, PyObject *args) static PyObject * -test_pyobject_fastcallkeywords(PyObject *self, PyObject *args) +test_pyobject_vectorcall(PyObject *self, PyObject *args) { PyObject *func, *func_args, *kwnames = NULL; PyObject **stack; @@ -4742,7 +4742,31 @@ test_pyobject_fastcallkeywords(PyObject *self, PyObject *args) PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); return NULL; } - return _PyObject_FastCallKeywords(func, stack, nargs, kwnames); + return _PyObject_Vectorcall(func, stack, nargs, kwnames); +} + + +static PyObject * +test_pyvectorcall_call(PyObject *self, PyObject *args) +{ + PyObject *func; + PyObject *argstuple; + PyObject *kwargs = NULL; + + if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) { + return NULL; + } + + if (!PyTuple_Check(argstuple)) { + PyErr_SetString(PyExc_TypeError, "args must be a tuple"); + return NULL; + } + if (kwargs != NULL && !PyDict_Check(kwargs)) { + PyErr_SetString(PyExc_TypeError, "kwargs must be a dict"); + return NULL; + } + + return PyVectorcall_Call(func, argstuple, kwargs); } @@ -5230,7 +5254,8 @@ static PyMethodDef TestMethods[] = { {"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS}, {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, - {"pyobject_fastcallkeywords", test_pyobject_fastcallkeywords, METH_VARARGS}, + {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, + {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, {"stack_pointer", stack_pointer, METH_NOARGS}, #ifdef W_STOPCODE {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, diff --git a/Objects/call.c b/Objects/call.c index b608492dd6bef5..183a5c2e5a24ff 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -5,6 +5,10 @@ #include "frameobject.h" +static PyObject * +cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs); + + int _PyObject_HasFastCall(PyObject *callable) { @@ -83,131 +87,132 @@ _Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where) /* --- Core PyObject call functions ------------------------------- */ PyObject * -_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs) +_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwargs) { /* _PyObject_FastCallDict() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ assert(!PyErr_Occurred()); - assert(callable != NULL); + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); assert(nargs >= 0); assert(nargs == 0 || args != NULL); assert(kwargs == NULL || PyDict_Check(kwargs)); - if (PyFunction_Check(callable)) { - return _PyFunction_FastCallDict(callable, args, nargs, kwargs); + vectorcallfunc func = _PyVectorcall_Function(callable); + if (func == NULL) { + /* Use tp_call instead */ + return _PyObject_MakeTpCall(callable, args, nargs, kwargs); } - else if (PyCFunction_Check(callable)) { - return _PyCFunction_FastCallDict(callable, args, nargs, kwargs); + + PyObject *res; + if (kwargs == NULL) { + res = func(callable, args, nargsf, NULL); } else { - PyObject *argstuple, *result; - ternaryfunc call; - - /* Slow-path: build a temporary tuple */ - call = callable->ob_type->tp_call; - if (call == NULL) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", - callable->ob_type->tp_name); - return NULL; - } - - argstuple = _PyTuple_FromArray(args, nargs); - if (argstuple == NULL) { + PyObject *kwnames; + PyObject *const *newargs; + if (_PyStack_UnpackDict(args, nargs, kwargs, &newargs, &kwnames) < 0) { return NULL; } - - if (Py_EnterRecursiveCall(" while calling a Python object")) { - Py_DECREF(argstuple); - return NULL; + res = func(callable, newargs, nargs, kwnames); + if (kwnames != NULL) { + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames) + nargs; + for (i = 0; i < n; i++) { + Py_DECREF(newargs[i]); + } + PyMem_Free((PyObject **)newargs); + Py_DECREF(kwnames); } - - result = (*call)(callable, argstuple, kwargs); - - Py_LeaveRecursiveCall(); - Py_DECREF(argstuple); - - result = _Py_CheckFunctionResult(callable, result, NULL); - return result; } + return _Py_CheckFunctionResult(callable, res, NULL); } PyObject * -_PyObject_FastCallKeywords(PyObject *callable, PyObject *const *stack, Py_ssize_t nargs, - PyObject *kwnames) +_PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) { - /* _PyObject_FastCallKeywords() must not be called with an exception set, - because it can clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!PyErr_Occurred()); + /* Slow path: build a temporary tuple for positional arguments and a + * temporary dictionary for keyword arguments (if any) */ + ternaryfunc call = Py_TYPE(callable)->tp_call; + if (call == NULL) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", + Py_TYPE(callable)->tp_name); + return NULL; + } assert(nargs >= 0); - assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); - - /* kwnames must only contains str strings, no subclass, and all keys must - be unique: these checks are implemented in Python/ceval.c and - _PyArg_ParseStackAndKeywords(). */ - - if (PyFunction_Check(callable)) { - return _PyFunction_FastCallKeywords(callable, stack, nargs, kwnames); + assert(nargs == 0 || args != NULL); + assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); + PyObject *argstuple = _PyTuple_FromArray(args, nargs); + if (argstuple == NULL) { + return NULL; } - if (PyCFunction_Check(callable)) { - return _PyCFunction_FastCallKeywords(callable, stack, nargs, kwnames); + + PyObject *kwdict; + if (keywords == NULL || PyDict_Check(keywords)) { + kwdict = keywords; } else { - /* Slow-path: build a temporary tuple for positional arguments and a - temporary dictionary for keyword arguments (if any) */ - - ternaryfunc call; - PyObject *argstuple; - PyObject *kwdict, *result; - Py_ssize_t nkwargs; - - nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); - assert((nargs == 0 && nkwargs == 0) || stack != NULL); - - call = callable->ob_type->tp_call; - if (call == NULL) { - PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", - callable->ob_type->tp_name); - return NULL; - } - - argstuple = _PyTuple_FromArray(stack, nargs); - if (argstuple == NULL) { - return NULL; - } - - if (nkwargs > 0) { - kwdict = _PyStack_AsDict(stack + nargs, kwnames); + if (PyTuple_GET_SIZE(keywords)) { + assert(args != NULL); + kwdict = _PyStack_AsDict(args + nargs, keywords); if (kwdict == NULL) { Py_DECREF(argstuple); return NULL; } } else { - kwdict = NULL; + keywords = kwdict = NULL; } + } - if (Py_EnterRecursiveCall(" while calling a Python object")) { - Py_DECREF(argstuple); - Py_XDECREF(kwdict); - return NULL; - } + PyObject *result = NULL; + if (Py_EnterRecursiveCall(" while calling a Python object") == 0) + { + result = call(callable, argstuple, kwdict); + Py_LeaveRecursiveCall(); + } - result = (*call)(callable, argstuple, kwdict); + Py_DECREF(argstuple); + if (kwdict != keywords) { + Py_DECREF(kwdict); + } - Py_LeaveRecursiveCall(); + result = _Py_CheckFunctionResult(callable, result, NULL); + return result; +} - Py_DECREF(argstuple); - Py_XDECREF(kwdict); - result = _Py_CheckFunctionResult(callable, result, NULL); - return result; +PyObject * +PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) +{ + vectorcallfunc func = _PyVectorcall_Function(callable); + if (func == NULL) { + PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", + Py_TYPE(callable)->tp_name); + return NULL; } + PyObject *const *args; + Py_ssize_t nargs = PyTuple_GET_SIZE(tuple); + PyObject *kwnames; + if (_PyStack_UnpackDict(_PyTuple_ITEMS(tuple), nargs, + kwargs, &args, &kwnames) < 0) { + return NULL; + } + PyObject *result = func(callable, args, nargs, kwnames); + if (kwnames != NULL) { + Py_ssize_t i, n = PyTuple_GET_SIZE(kwnames) + nargs; + for (i = 0; i < n; i++) { + Py_DECREF(args[i]); + } + PyMem_Free((PyObject **)args); + Py_DECREF(kwnames); + } + + return result; } @@ -224,14 +229,13 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) assert(PyTuple_Check(args)); assert(kwargs == NULL || PyDict_Check(kwargs)); - if (PyFunction_Check(callable)) { - return _PyFunction_FastCallDict(callable, - _PyTuple_ITEMS(args), - PyTuple_GET_SIZE(args), - kwargs); + if (_PyVectorcall_Function(callable) != NULL) { + return PyVectorcall_Call(callable, args, kwargs); } else if (PyCFunction_Check(callable)) { - return PyCFunction_Call(callable, args, kwargs); + /* This must be a METH_VARARGS function, otherwise we would be + * in the previous case */ + return cfunction_call_varargs(callable, args, kwargs); } else { call = callable->ob_type->tp_call; @@ -384,9 +388,10 @@ _PyFunction_FastCallDict(PyObject *func, PyObject *const *args, Py_ssize_t nargs return result; } + PyObject * -_PyFunction_FastCallKeywords(PyObject *func, PyObject *const *stack, - Py_ssize_t nargs, PyObject *kwnames) +_PyFunction_FastCallKeywords(PyObject *func, PyObject* const* stack, + size_t nargsf, PyObject *kwnames) { PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); PyObject *globals = PyFunction_GET_GLOBALS(func); @@ -397,6 +402,7 @@ _PyFunction_FastCallKeywords(PyObject *func, PyObject *const *stack, Py_ssize_t nd; assert(PyFunction_Check(func)); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); assert(nargs >= 0); assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); assert((nargs == 0 && nkwargs == 0) || stack != NULL); @@ -725,13 +731,14 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject * _PyCFunction_FastCallKeywords(PyObject *func, - PyObject *const *args, Py_ssize_t nargs, + PyObject *const *args, size_t nargsf, PyObject *kwnames) { PyObject *result; assert(func != NULL); assert(PyCFunction_Check(func)); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); result = _PyMethodDef_RawFastCallKeywords(((PyCFunctionObject*)func)->m_ml, PyCFunction_GET_SELF(func), @@ -751,6 +758,7 @@ cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs) PyObject *self = PyCFunction_GET_SELF(func); PyObject *result; + assert(PyCFunction_GET_FLAGS(func) & METH_VARARGS); if (PyCFunction_GET_FLAGS(func) & METH_KEYWORDS) { if (Py_EnterRecursiveCall(" while calling a Python object")) { return NULL; @@ -783,18 +791,12 @@ cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs) PyObject * PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs) { - /* first try METH_VARARGS to pass directly args tuple unchanged. - _PyMethodDef_RawFastCallDict() creates a new temporary tuple - for METH_VARARGS. */ + /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer + * is NULL. This is intentional, since vectorcall would be slower. */ if (PyCFunction_GET_FLAGS(func) & METH_VARARGS) { return cfunction_call_varargs(func, args, kwargs); } - else { - return _PyCFunction_FastCallDict(func, - _PyTuple_ITEMS(args), - PyTuple_GET_SIZE(args), - kwargs); - } + return PyVectorcall_Call(func, args, kwargs); } diff --git a/Objects/classobject.c b/Objects/classobject.c index 1ee897847fb03e..cfc24460a747b0 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -40,6 +40,45 @@ PyMethod_Self(PyObject *im) return ((PyMethodObject *)im)->im_self; } + +static PyObject * +method_vectorcall(PyObject *method, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + assert(Py_TYPE(method) == &PyMethod_Type); + PyObject *self, *func, *result; + self = PyMethod_GET_SELF(method); + func = PyMethod_GET_FUNCTION(method); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + + if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { + /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */ + PyObject **newargs = (PyObject**)args - 1; + nargs += 1; + PyObject *tmp = newargs[0]; + newargs[0] = self; + result = _PyObject_Vectorcall(func, newargs, nargs, kwnames); + newargs[0] = tmp; + } + else { + Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); + PyObject **newargs; + Py_ssize_t totalargs = nargs + nkwargs; + newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); + if (newargs == NULL) { + PyErr_NoMemory(); + return NULL; + } + /* use borrowed references */ + newargs[0] = self; + memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); + result = _PyObject_Vectorcall(func, newargs, nargs+1, kwnames); + PyMem_Free(newargs); + } + return result; +} + + /* Method objects are used for bound instance methods returned by instancename.methodname. ClassName.methodname returns an ordinary function. @@ -69,6 +108,7 @@ PyMethod_New(PyObject *func, PyObject *self) im->im_func = func; Py_XINCREF(self); im->im_self = self; + im->vectorcall = method_vectorcall; _PyObject_GC_TRACK(im); return (PyObject *)im; } @@ -309,7 +349,7 @@ PyTypeObject PyMethod_Type = { sizeof(PyMethodObject), 0, (destructor)method_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + offsetof(PyMethodObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ @@ -323,7 +363,8 @@ PyTypeObject PyMethod_Type = { method_getattro, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ method_doc, /* tp_doc */ (traverseproc)method_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 6c99f9b211b93b..759018503c65e0 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -265,13 +265,14 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) // same to methoddescr_call(), but use FASTCALL convention. PyObject * _PyMethodDescr_FastCallKeywords(PyObject *descrobj, - PyObject *const *args, Py_ssize_t nargs, + PyObject *const *args, size_t nargsf, PyObject *kwnames) { assert(Py_TYPE(descrobj) == &PyMethodDescr_Type); PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj; PyObject *self, *result; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); /* Make sure that the first argument is acceptable as 'self' */ if (nargs < 1) { PyErr_Format(PyExc_TypeError, @@ -542,7 +543,7 @@ PyTypeObject PyMethodDescr_Type = { sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ @@ -557,6 +558,7 @@ PyTypeObject PyMethodDescr_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + _Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ 0, /* tp_doc */ descr_traverse, /* tp_traverse */ @@ -752,8 +754,10 @@ PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, type, method->ml_name); - if (descr != NULL) + if (descr != NULL) { descr->d_method = method; + descr->vectorcall = &_PyMethodDescr_FastCallKeywords; + } return (PyObject *)descr; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index fb7abfacb2e40b..2b1f42db746dbc 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -36,6 +36,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname op->func_defaults = NULL; /* No default arguments */ op->func_kwdefaults = NULL; /* No keyword only defaults */ op->func_closure = NULL; + op->vectorcall = _PyFunction_FastCallKeywords; consts = ((PyCodeObject *)code)->co_consts; if (PyTuple_Size(consts) >= 1) { @@ -649,7 +650,7 @@ PyTypeObject PyFunction_Type = { sizeof(PyFunctionObject), 0, (destructor)func_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + offsetof(PyFunctionObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ @@ -664,6 +665,7 @@ PyTypeObject PyFunction_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + _Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_METHOD_DESCRIPTOR, /* tp_flags */ func_new__doc__, /* tp_doc */ (traverseproc)func_traverse, /* tp_traverse */ diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 9fed3fca99be9f..76497c93894a89 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -46,6 +46,14 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) op->m_self = self; Py_XINCREF(module); op->m_module = module; + if (ml->ml_flags & METH_VARARGS) { + /* For METH_VARARGS functions, it's more efficient to use tp_call + * instead of vectorcall. */ + op->vectorcall = NULL; + } + else { + op->vectorcall = &_PyCFunction_FastCallKeywords; + } _PyObject_GC_TRACK(op); return (PyObject *)op; } @@ -264,7 +272,7 @@ PyTypeObject PyCFunction_Type = { sizeof(PyCFunctionObject), 0, (destructor)meth_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + offsetof(PyCFunctionObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ @@ -278,7 +286,8 @@ PyTypeObject PyCFunction_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + _Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ 0, /* tp_doc */ (traverseproc)meth_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 065ad95c95b151..48dadcc9d4964d 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -483,7 +483,7 @@ builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb return NULL; } Py_INCREF(hook); - PyObject *retval = _PyObject_FastCallKeywords(hook, args, nargs, keywords); + PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords); Py_DECREF(hook); return retval; } @@ -2231,7 +2231,7 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } assert(nargs >= 1); - v = _PyObject_FastCallKeywords(callable, args + 1, nargs - 1, kwnames); + v = _PyObject_Vectorcall(callable, args + 1, nargs - 1, kwnames); Py_DECREF(callable); if (v == NULL) { Py_DECREF(newlist); diff --git a/Python/ceval.c b/Python/ceval.c index 9263df9b8fc490..47baa4d03ed9cc 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4806,6 +4806,40 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \ x = call; \ } + +static PyObject * +trace_call_function(PyThreadState *tstate, + PyObject *func, + PyObject **args, Py_ssize_t nargs, + PyObject *kwnames) +{ + PyObject *x; + if (PyCFunction_Check(func)) { + C_TRACE(x, _PyCFunction_FastCallKeywords(func, args, nargs, kwnames)); + return x; + } + else if (Py_TYPE(func) == &PyMethodDescr_Type && nargs > 0) { + /* We need to create a temporary bound method as argument + for profiling. + + If nargs == 0, then this cannot work because we have no + "self". In any case, the call itself would raise + TypeError (foo needs an argument), so we just skip + profiling. */ + PyObject *self = args[0]; + func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); + if (func == NULL) { + return NULL; + } + C_TRACE(x, _PyCFunction_FastCallKeywords(func, + args+1, nargs-1, + kwnames)); + Py_DECREF(func); + return x; + } + return _PyObject_Vectorcall(func, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); +} + /* Issue #29227: Inline call_function() into _PyEval_EvalFrameDefault() to reduce the stack consumption. */ Py_LOCAL_INLINE(PyObject *) _Py_HOT_FUNCTION @@ -4818,63 +4852,11 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO Py_ssize_t nargs = oparg - nkwargs; PyObject **stack = (*pp_stack) - nargs - nkwargs; - /* Always dispatch PyCFunction first, because these are - presumed to be the most frequent callable object. - */ - if (PyCFunction_Check(func)) { - C_TRACE(x, _PyCFunction_FastCallKeywords(func, stack, nargs, kwnames)); - } - else if (Py_TYPE(func) == &PyMethodDescr_Type) { - if (nargs > 0 && tstate->use_tracing) { - /* We need to create a temporary bound method as argument - for profiling. - - If nargs == 0, then this cannot work because we have no - "self". In any case, the call itself would raise - TypeError (foo needs an argument), so we just skip - profiling. */ - PyObject *self = stack[0]; - func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); - if (func != NULL) { - C_TRACE(x, _PyCFunction_FastCallKeywords(func, - stack+1, nargs-1, - kwnames)); - Py_DECREF(func); - } - else { - x = NULL; - } - } - else { - x = _PyMethodDescr_FastCallKeywords(func, stack, nargs, kwnames); - } + if (tstate->use_tracing) { + x = trace_call_function(tstate, func, stack, nargs, kwnames); } else { - if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) { - /* Optimize access to bound methods. Reuse the Python stack - to pass 'self' as the first argument, replace 'func' - with 'self'. It avoids the creation of a new temporary tuple - for arguments (to replace func with self) when the method uses - FASTCALL. */ - PyObject *self = PyMethod_GET_SELF(func); - Py_INCREF(self); - func = PyMethod_GET_FUNCTION(func); - Py_INCREF(func); - Py_SETREF(*pfunc, self); - nargs++; - stack--; - } - else { - Py_INCREF(func); - } - - if (PyFunction_Check(func)) { - x = _PyFunction_FastCallKeywords(func, stack, nargs, kwnames); - } - else { - x = _PyObject_FastCallKeywords(func, stack, nargs, kwnames); - } - Py_DECREF(func); + x = _PyObject_Vectorcall(func, stack, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); } assert((x != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); diff --git a/Python/context.c b/Python/context.c index 9a50ea91a77ee3..f48c376b4ffaa9 100644 --- a/Python/context.c +++ b/Python/context.c @@ -631,7 +631,7 @@ context_run(PyContext *self, PyObject *const *args, return NULL; } - PyObject *call_result = _PyObject_FastCallKeywords( + PyObject *call_result = _PyObject_Vectorcall( args[0], args + 1, nargs - 1, kwnames); if (PyContext_Exit((PyObject *)self)) { diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 343601ec8596f1..12b1bd7711d5b8 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -481,7 +481,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb return NULL; } PyMem_RawFree(envar); - PyObject *retval = _PyObject_FastCallKeywords(hook, args, nargs, keywords); + PyObject *retval = _PyObject_Vectorcall(hook, args, nargs, keywords); Py_DECREF(hook); return retval; From 0c2f9305640f7655ba0cd5f478948b2763b376b3 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Wed, 29 May 2019 11:46:58 -0700 Subject: [PATCH 180/441] bpo-22385: Support output separators in hex methods. (#13578) * bpo-22385: Support output separators in hex methods. Also in binascii.hexlify aka b2a_hex. The underlying implementation behind all hex generation in CPython uses the same pystrhex.c implementation. This adds support to bytes, bytearray, and memoryview objects. The binascii module functions exist rather than being slated for deprecation because they return bytes rather than requiring an intermediate step through a str object. This change was inspired by MicroPython which supports sep in its binascii implementation (and does not yet support the .hex methods). https://bugs.python.org/issue22385 --- Doc/library/binascii.rst | 22 +++- Doc/library/stdtypes.rst | 18 +++ Include/pystrhex.h | 3 + Lib/test/test_binascii.py | 12 ++ Lib/test/test_bytes.py | 57 +++++++++ Lib/test/test_doctest.py | 5 +- .../2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst | 4 + Modules/binascii.c | 33 +++-- Modules/clinic/binascii.c.h | 115 +++++++++++++++--- Objects/bytearrayobject.c | 34 ++++-- Objects/bytesobject.c | 34 ++++-- Objects/clinic/bytearrayobject.c.h | 71 ++++++++++- Objects/clinic/bytesobject.c.h | 71 ++++++++++- Objects/clinic/memoryobject.c.h | 74 +++++++++++ Objects/memoryobject.c | 45 +++++-- Python/pystrhex.c | 90 ++++++++++++-- 16 files changed, 624 insertions(+), 64 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst create mode 100644 Objects/clinic/memoryobject.c.h diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 89ecddc7780fa3..98d8679fa3dcda 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -145,8 +145,8 @@ The :mod:`binascii` module defines the following functions: platforms, use ``crc32(data) & 0xffffffff``. -.. function:: b2a_hex(data) - hexlify(data) +.. function:: b2a_hex(data[, sep[, bytes_per_sep=1]]) + hexlify(data[, sep[, bytes_per_sep=1]]) Return the hexadecimal representation of the binary *data*. Every byte of *data* is converted into the corresponding 2-digit hex representation. The @@ -155,6 +155,24 @@ The :mod:`binascii` module defines the following functions: Similar functionality (but returning a text string) is also conveniently accessible using the :meth:`bytes.hex` method. + If *sep* is specified, it must be a single character str or bytes object. + It will be inserted in the output after every *bytes_per_sep* input bytes. + Separator placement is counted from the right end of the output by default, + if you wish to count from the left, supply a negative *bytes_per_sep* value. + + >>> import binascii + >>> binascii.b2a_hex(b'\xb9\x01\xef') + b'b901ef' + >>> binascii.hexlify(b'\xb9\x01\xef', '-') + b'b9-01-ef' + >>> binascii.b2a_hex(b'\xb9\x01\xef', b'_', 2) + b'b9_01ef' + >>> binascii.b2a_hex(b'\xb9\x01\xef', b' ', -2) + b'b901 ef' + + .. versionchanged:: 3.8 + The *sep* and *bytes_per_sep* parameters were added. + .. function:: a2b_hex(hexstr) unhexlify(hexstr) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 293a1ab6a0d966..fcb0da74e158b0 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2404,8 +2404,26 @@ data and are closely related to string objects in a variety of other ways. >>> b'\xf0\xf1\xf2'.hex() 'f0f1f2' + If you want to make the hex string easier to read, you can specify a + single character separator *sep* parameter to include in the output. + By default between each byte. A second optional *bytes_per_sep* + parameter controls the spacing. Positive values calculate the + separator position from the right, negative values from the left. + + >>> value = b'\xf0\xf1\xf2' + >>> value.hex('-') + 'f0-f1-f2' + >>> value.hex('_', 2) + 'f0_f1f2' + >>> b'UUDDLRLRAB'.hex(' ', -4) + '55554444 4c524c52 4142' + .. versionadded:: 3.5 + .. versionchanged:: 3.8 + :meth:`bytes.hex` now supports optional *sep* and *bytes_per_sep* + parameters to insert separators between bytes in the hex output. + Since bytes objects are sequences of integers (akin to a tuple), for a bytes object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes object of length 1. (This contrasts with text strings, where both indexing diff --git a/Include/pystrhex.h b/Include/pystrhex.h index 66a30e2233ce98..a4f36305bac69b 100644 --- a/Include/pystrhex.h +++ b/Include/pystrhex.h @@ -10,6 +10,9 @@ extern "C" { PyAPI_FUNC(PyObject*) _Py_strhex(const char* argbuf, const Py_ssize_t arglen); /* Returns a bytes() containing the ASCII hex representation of argbuf. */ PyAPI_FUNC(PyObject*) _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen); +/* These variants include support for a separator between every N bytes: */ +PyAPI_FUNC(PyObject*) _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group); +PyAPI_FUNC(PyObject*) _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group); #endif /* !Py_LIMITED_API */ #ifdef __cplusplus diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 572e50c3e25e8a..08de5c9fc7cc39 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -240,6 +240,18 @@ def test_hex(self): self.assertEqual(binascii.hexlify(self.type2test(s)), t) self.assertEqual(binascii.unhexlify(self.type2test(t)), u) + def test_hex_separator(self): + """Test that hexlify and b2a_hex are binary versions of bytes.hex.""" + # Logic of separators is tested in test_bytes.py. This checks that + # arg parsing works and exercises the direct to bytes object code + # path within pystrhex.c. + s = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000' + self.assertEqual(binascii.hexlify(self.type2test(s)), s.hex().encode('ascii')) + expected8 = s.hex('.', 8).encode('ascii') + self.assertEqual(binascii.hexlify(self.type2test(s), '.', 8), expected8) + expected1 = s.hex(':').encode('ascii') + self.assertEqual(binascii.b2a_hex(self.type2test(s), ':'), expected1) + def test_qp(self): type2test = self.type2test a2b_qp = binascii.a2b_qp diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 9502a8f974bd37..bbd45c75298e72 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -417,6 +417,63 @@ def test_hex(self): self.assertEqual(self.type2test(b"\x1a\x2b\x30").hex(), '1a2b30') self.assertEqual(memoryview(b"\x1a\x2b\x30").hex(), '1a2b30') + def test_hex_separator_basics(self): + three_bytes = self.type2test(b'\xb9\x01\xef') + self.assertEqual(three_bytes.hex(), 'b901ef') + with self.assertRaises(ValueError): + three_bytes.hex('') + with self.assertRaises(ValueError): + three_bytes.hex('xx') + self.assertEqual(three_bytes.hex(':', 0), 'b901ef') + with self.assertRaises(TypeError): + three_bytes.hex(None, 0) + with self.assertRaises(ValueError): + three_bytes.hex('\xff') + with self.assertRaises(ValueError): + three_bytes.hex(b'\xff') + with self.assertRaises(ValueError): + three_bytes.hex(b'\x80') + with self.assertRaises(ValueError): + three_bytes.hex(chr(0x100)) + self.assertEqual(three_bytes.hex(':', 0), 'b901ef') + self.assertEqual(three_bytes.hex(b'\x00'), 'b9\x0001\x00ef') + self.assertEqual(three_bytes.hex('\x00'), 'b9\x0001\x00ef') + self.assertEqual(three_bytes.hex(b'\x7f'), 'b9\x7f01\x7fef') + self.assertEqual(three_bytes.hex('\x7f'), 'b9\x7f01\x7fef') + self.assertEqual(three_bytes.hex(':', 3), 'b901ef') + self.assertEqual(three_bytes.hex(':', 4), 'b901ef') + self.assertEqual(three_bytes.hex(':', -4), 'b901ef') + self.assertEqual(three_bytes.hex(':'), 'b9:01:ef') + self.assertEqual(three_bytes.hex(b'$'), 'b9$01$ef') + self.assertEqual(three_bytes.hex(':', 1), 'b9:01:ef') + self.assertEqual(three_bytes.hex(':', -1), 'b9:01:ef') + self.assertEqual(three_bytes.hex(':', 2), 'b9:01ef') + self.assertEqual(three_bytes.hex(':', 1), 'b9:01:ef') + self.assertEqual(three_bytes.hex('*', -2), 'b901*ef') + + value = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000' + self.assertEqual(value.hex('.', 8), '7b7305000000776f.726c646902000000.730500000068656c.6c6f690100000030') + + def test_hex_separator_five_bytes(self): + five_bytes = self.type2test(range(90,95)) + self.assertEqual(five_bytes.hex(), '5a5b5c5d5e') + + def test_hex_separator_six_bytes(self): + six_bytes = self.type2test(x*3 for x in range(1, 7)) + self.assertEqual(six_bytes.hex(), '0306090c0f12') + self.assertEqual(six_bytes.hex('.', 1), '03.06.09.0c.0f.12') + self.assertEqual(six_bytes.hex(' ', 2), '0306 090c 0f12') + self.assertEqual(six_bytes.hex('-', 3), '030609-0c0f12') + self.assertEqual(six_bytes.hex(':', 4), '0306:090c0f12') + self.assertEqual(six_bytes.hex(':', 5), '03:06090c0f12') + self.assertEqual(six_bytes.hex(':', 6), '0306090c0f12') + self.assertEqual(six_bytes.hex(':', 95), '0306090c0f12') + self.assertEqual(six_bytes.hex('_', -3), '030609_0c0f12') + self.assertEqual(six_bytes.hex(':', -4), '0306090c:0f12') + self.assertEqual(six_bytes.hex(b'@', -5), '0306090c0f@12') + self.assertEqual(six_bytes.hex(':', -6), '0306090c0f12') + self.assertEqual(six_bytes.hex(' ', -95), '0306090c0f12') + def test_join(self): self.assertEqual(self.type2test(b"").join([]), b"") self.assertEqual(self.type2test(b"").join([b""]), b"") diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index f1013f25725964..5ea18f52c4fcf2 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -665,11 +665,13 @@ def non_Python_modules(): r""" True >>> real_tests = [t for t in tests if len(t.examples) > 0] >>> len(real_tests) # objects that actually have doctests - 9 + 12 >>> for t in real_tests: ... print('{} {}'.format(len(t.examples), t.name)) ... 1 builtins.bin + 5 builtins.bytearray.hex + 5 builtins.bytes.hex 3 builtins.float.as_integer_ratio 2 builtins.float.fromhex 2 builtins.float.hex @@ -677,6 +679,7 @@ def non_Python_modules(): r""" 1 builtins.int 3 builtins.int.as_integer_ratio 2 builtins.int.bit_length + 5 builtins.memoryview.hex 1 builtins.oct Note here that 'bin', 'oct', and 'hex' are functions; 'float.as_integer_ratio', diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst new file mode 100644 index 00000000000000..e10690b3a560d7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst @@ -0,0 +1,4 @@ +The `bytes.hex`, `bytearray.hex`, and `memoryview.hex` methods as well as +the `binascii.hexlify` and `b2a_hex` functions now have the ability to +include an optional separator between hex bytes. This functionality was +inspired by MicroPython's hexlify implementation. diff --git a/Modules/binascii.c b/Modules/binascii.c index d22ab7b4683887..1c7dc35882dee6 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1159,19 +1159,33 @@ binascii_crc32_impl(PyObject *module, Py_buffer *data, unsigned int crc) binascii.b2a_hex data: Py_buffer - / + sep: object = NULL + An optional single character or byte to separate hex bytes. + bytes_per_sep: int = 1 + How many bytes between separators. Positive values count from the + right, negative values count from the left. Hexadecimal representation of binary data. The return value is a bytes object. This function is also available as "hexlify()". + +Example: +>>> binascii.b2a_hex(b'\xb9\x01\xef') +b'b901ef' +>>> binascii.hexlify(b'\xb9\x01\xef', ':') +b'b9:01:ef' +>>> binascii.b2a_hex(b'\xb9\x01\xef', b'_', 2) +b'b9_01ef' [clinic start generated code]*/ static PyObject * -binascii_b2a_hex_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=92fec1a95c9897a0 input=96423cfa299ff3b1]*/ +binascii_b2a_hex_impl(PyObject *module, Py_buffer *data, PyObject *sep, + int bytes_per_sep) +/*[clinic end generated code: output=a26937946a81d2c7 input=ec0ade6ba2e43543]*/ { - return _Py_strhex_bytes((const char *)data->buf, data->len); + return _Py_strhex_bytes_with_sep((const char *)data->buf, data->len, + sep, bytes_per_sep); } /*[clinic input] @@ -1179,14 +1193,17 @@ binascii.hexlify = binascii.b2a_hex Hexadecimal representation of binary data. -The return value is a bytes object. +The return value is a bytes object. This function is also +available as "b2a_hex()". [clinic start generated code]*/ static PyObject * -binascii_hexlify_impl(PyObject *module, Py_buffer *data) -/*[clinic end generated code: output=749e95e53c14880c input=2e3afae7f083f061]*/ +binascii_hexlify_impl(PyObject *module, Py_buffer *data, PyObject *sep, + int bytes_per_sep) +/*[clinic end generated code: output=d12aa1b001b15199 input=bc317bd4e241f76b]*/ { - return _Py_strhex_bytes((const char *)data->buf, data->len); + return _Py_strhex_bytes_with_sep((const char *)data->buf, data->len, + sep, bytes_per_sep); } /*[clinic input] diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index 4043d89d97db3b..d4850485690278 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -432,34 +432,78 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs) } PyDoc_STRVAR(binascii_b2a_hex__doc__, -"b2a_hex($module, data, /)\n" +"b2a_hex($module, /, data, sep=None, bytes_per_sep=1)\n" "--\n" "\n" "Hexadecimal representation of binary data.\n" "\n" +" sep\n" +" An optional single character or byte to separate hex bytes.\n" +" bytes_per_sep\n" +" How many bytes between separators. Positive values count from the\n" +" right, negative values count from the left.\n" +"\n" "The return value is a bytes object. This function is also\n" -"available as \"hexlify()\"."); +"available as \"hexlify()\".\n" +"\n" +"Example:\n" +">>> binascii.b2a_hex(b\'\\xb9\\x01\\xef\')\n" +"b\'b901ef\'\n" +">>> binascii.hexlify(b\'\\xb9\\x01\\xef\', \':\')\n" +"b\'b9:01:ef\'\n" +">>> binascii.b2a_hex(b\'\\xb9\\x01\\xef\', b\'_\', 2)\n" +"b\'b9_01ef\'"); #define BINASCII_B2A_HEX_METHODDEF \ - {"b2a_hex", (PyCFunction)binascii_b2a_hex, METH_O, binascii_b2a_hex__doc__}, + {"b2a_hex", (PyCFunction)(void(*)(void))binascii_b2a_hex, METH_FASTCALL|METH_KEYWORDS, binascii_b2a_hex__doc__}, static PyObject * -binascii_b2a_hex_impl(PyObject *module, Py_buffer *data); +binascii_b2a_hex_impl(PyObject *module, Py_buffer *data, PyObject *sep, + int bytes_per_sep); static PyObject * -binascii_b2a_hex(PyObject *module, PyObject *arg) +binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "b2a_hex", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; + PyObject *sep = NULL; + int bytes_per_sep = 1; - if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("b2a_hex", 0, "contiguous buffer", arg); + _PyArg_BadArgument("b2a_hex", 1, "contiguous buffer", args[0]); goto exit; } - return_value = binascii_b2a_hex_impl(module, &data); + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + sep = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[2]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = binascii_b2a_hex_impl(module, &data, sep, bytes_per_sep); exit: /* Cleanup for data */ @@ -471,33 +515,70 @@ binascii_b2a_hex(PyObject *module, PyObject *arg) } PyDoc_STRVAR(binascii_hexlify__doc__, -"hexlify($module, data, /)\n" +"hexlify($module, /, data, sep=None, bytes_per_sep=1)\n" "--\n" "\n" "Hexadecimal representation of binary data.\n" "\n" -"The return value is a bytes object."); +" sep\n" +" An optional single character or byte to separate hex bytes.\n" +" bytes_per_sep\n" +" How many bytes between separators. Positive values count from the\n" +" right, negative values count from the left.\n" +"\n" +"The return value is a bytes object. This function is also\n" +"available as \"b2a_hex()\"."); #define BINASCII_HEXLIFY_METHODDEF \ - {"hexlify", (PyCFunction)binascii_hexlify, METH_O, binascii_hexlify__doc__}, + {"hexlify", (PyCFunction)(void(*)(void))binascii_hexlify, METH_FASTCALL|METH_KEYWORDS, binascii_hexlify__doc__}, static PyObject * -binascii_hexlify_impl(PyObject *module, Py_buffer *data); +binascii_hexlify_impl(PyObject *module, Py_buffer *data, PyObject *sep, + int bytes_per_sep); static PyObject * -binascii_hexlify(PyObject *module, PyObject *arg) +binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hexlify", 0}; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; + PyObject *sep = NULL; + int bytes_per_sep = 1; - if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) != 0) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&data, 'C')) { - _PyArg_BadArgument("hexlify", 0, "contiguous buffer", arg); + _PyArg_BadArgument("hexlify", 1, "contiguous buffer", args[0]); goto exit; } - return_value = binascii_hexlify_impl(module, &data); + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + sep = args[1]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[2]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = binascii_hexlify_impl(module, &data, sep, bytes_per_sep); exit: /* Cleanup for data */ @@ -720,4 +801,4 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj return return_value; } -/*[clinic end generated code: output=a4a38e162605aca2 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f7b8049edb130c63 input=a9049054013a1b77]*/ diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c7c28312b0052b..b9fcc01b70322a 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2020,18 +2020,36 @@ bytearray_fromhex_impl(PyTypeObject *type, PyObject *string) return result; } -PyDoc_STRVAR(hex__doc__, -"B.hex() -> string\n\ -\n\ -Create a string of hexadecimal numbers from a bytearray object.\n\ -Example: bytearray([0xb9, 0x01, 0xef]).hex() -> 'b901ef'."); +/*[clinic input] +bytearray.hex + + sep: object = NULL + An optional single character or byte to separate hex bytes. + bytes_per_sep: int = 1 + How many bytes between separators. Positive values count from the + right, negative values count from the left. + +Create a str of hexadecimal numbers from a bytearray object. + +Example: +>>> value = bytearray([0xb9, 0x01, 0xef]) +>>> value.hex() +'b901ef' +>>> value.hex(':') +'b9:01:ef' +>>> value.hex(':', 2) +'b9:01ef' +>>> value.hex(':', -2) +'b901:ef' +[clinic start generated code]*/ static PyObject * -bytearray_hex(PyBytesObject *self, PyObject *Py_UNUSED(ignored)) +bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep) +/*[clinic end generated code: output=29c4e5ef72c565a0 input=814c15830ac8c4b5]*/ { char* argbuf = PyByteArray_AS_STRING(self); Py_ssize_t arglen = PyByteArray_GET_SIZE(self); - return _Py_strhex(argbuf, arglen); + return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep); } static PyObject * @@ -2160,7 +2178,7 @@ bytearray_methods[] = { {"find", (PyCFunction)bytearray_find, METH_VARARGS, _Py_find__doc__}, BYTEARRAY_FROMHEX_METHODDEF - {"hex", (PyCFunction)bytearray_hex, METH_NOARGS, hex__doc__}, + BYTEARRAY_HEX_METHODDEF {"index", (PyCFunction)bytearray_index, METH_VARARGS, _Py_index__doc__}, BYTEARRAY_INSERT_METHODDEF {"isalnum", stringlib_isalnum, METH_NOARGS, diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 6f34037154d64d..bf7c7da423b725 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2416,18 +2416,36 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray) return NULL; } -PyDoc_STRVAR(hex__doc__, -"B.hex() -> string\n\ -\n\ -Create a string of hexadecimal numbers from a bytes object.\n\ -Example: b'\\xb9\\x01\\xef'.hex() -> 'b901ef'."); +/*[clinic input] +bytes.hex + + sep: object = NULL + An optional single character or byte to separate hex bytes. + bytes_per_sep: int = 1 + How many bytes between separators. Positive values count from the + right, negative values count from the left. + +Create a str of hexadecimal numbers from a bytes object. + +Example: +>>> value = b'\xb9\x01\xef' +>>> value.hex() +'b901ef' +>>> value.hex(':') +'b9:01:ef' +>>> value.hex(':', 2) +'b9:01ef' +>>> value.hex(':', -2) +'b901:ef' +[clinic start generated code]*/ static PyObject * -bytes_hex(PyBytesObject *self, PyObject *Py_UNUSED(ignored)) +bytes_hex_impl(PyBytesObject *self, PyObject *sep, int bytes_per_sep) +/*[clinic end generated code: output=1f134da504064139 input=f1238d3455990218]*/ { char* argbuf = PyBytes_AS_STRING(self); Py_ssize_t arglen = PyBytes_GET_SIZE(self); - return _Py_strhex(argbuf, arglen); + return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep); } static PyObject * @@ -2452,7 +2470,7 @@ bytes_methods[] = { {"find", (PyCFunction)bytes_find, METH_VARARGS, _Py_find__doc__}, BYTES_FROMHEX_METHODDEF - {"hex", (PyCFunction)bytes_hex, METH_NOARGS, hex__doc__}, + BYTES_HEX_METHODDEF {"index", (PyCFunction)bytes_index, METH_VARARGS, _Py_index__doc__}, {"isalnum", stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index da1dc6a40af0a3..08c6eb53f5878a 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -867,6 +867,75 @@ bytearray_fromhex(PyTypeObject *type, PyObject *arg) return return_value; } +PyDoc_STRVAR(bytearray_hex__doc__, +"hex($self, /, sep=None, bytes_per_sep=1)\n" +"--\n" +"\n" +"Create a str of hexadecimal numbers from a bytearray object.\n" +"\n" +" sep\n" +" An optional single character or byte to separate hex bytes.\n" +" bytes_per_sep\n" +" How many bytes between separators. Positive values count from the\n" +" right, negative values count from the left.\n" +"\n" +"Example:\n" +">>> value = bytearray([0xb9, 0x01, 0xef])\n" +">>> value.hex()\n" +"\'b901ef\'\n" +">>> value.hex(\':\')\n" +"\'b9:01:ef\'\n" +">>> value.hex(\':\', 2)\n" +"\'b9:01ef\'\n" +">>> value.hex(\':\', -2)\n" +"\'b901:ef\'"); + +#define BYTEARRAY_HEX_METHODDEF \ + {"hex", (PyCFunction)(void(*)(void))bytearray_hex, METH_FASTCALL|METH_KEYWORDS, bytearray_hex__doc__}, + +static PyObject * +bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep); + +static PyObject * +bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[1]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = bytearray_hex_impl(self, sep, bytes_per_sep); + +exit: + return return_value; +} + PyDoc_STRVAR(bytearray_reduce__doc__, "__reduce__($self, /)\n" "--\n" @@ -942,4 +1011,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=272fcb836b92da32 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7848247e5469ba1b input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index b03078305a6006..69c35063c6cf76 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -686,4 +686,73 @@ bytes_fromhex(PyTypeObject *type, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=af9f51b9b185567d input=a9049054013a1b77]*/ + +PyDoc_STRVAR(bytes_hex__doc__, +"hex($self, /, sep=None, bytes_per_sep=1)\n" +"--\n" +"\n" +"Create a str of hexadecimal numbers from a bytes object.\n" +"\n" +" sep\n" +" An optional single character or byte to separate hex bytes.\n" +" bytes_per_sep\n" +" How many bytes between separators. Positive values count from the\n" +" right, negative values count from the left.\n" +"\n" +"Example:\n" +">>> value = b\'\\xb9\\x01\\xef\'\n" +">>> value.hex()\n" +"\'b901ef\'\n" +">>> value.hex(\':\')\n" +"\'b9:01:ef\'\n" +">>> value.hex(\':\', 2)\n" +"\'b9:01ef\'\n" +">>> value.hex(\':\', -2)\n" +"\'b901:ef\'"); + +#define BYTES_HEX_METHODDEF \ + {"hex", (PyCFunction)(void(*)(void))bytes_hex, METH_FASTCALL|METH_KEYWORDS, bytes_hex__doc__}, + +static PyObject * +bytes_hex_impl(PyBytesObject *self, PyObject *sep, int bytes_per_sep); + +static PyObject * +bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[1]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = bytes_hex_impl(self, sep, bytes_per_sep); + +exit: + return return_value; +} +/*[clinic end generated code: output=2d0a3733e13e753a input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h new file mode 100644 index 00000000000000..64fce10acb5c5f --- /dev/null +++ b/Objects/clinic/memoryobject.c.h @@ -0,0 +1,74 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(memoryview_hex__doc__, +"hex($self, /, sep=None, bytes_per_sep=1)\n" +"--\n" +"\n" +"Return the data in the buffer as a str of hexadecimal numbers.\n" +"\n" +" sep\n" +" An optional single character or byte to separate hex bytes.\n" +" bytes_per_sep\n" +" How many bytes between separators. Positive values count from the\n" +" right, negative values count from the left.\n" +"\n" +"Example:\n" +">>> value = memoryview(b\'\\xb9\\x01\\xef\')\n" +">>> value.hex()\n" +"\'b901ef\'\n" +">>> value.hex(\':\')\n" +"\'b9:01:ef\'\n" +">>> value.hex(\':\', 2)\n" +"\'b9:01ef\'\n" +">>> value.hex(\':\', -2)\n" +"\'b901:ef\'"); + +#define MEMORYVIEW_HEX_METHODDEF \ + {"hex", (PyCFunction)(void(*)(void))memoryview_hex, METH_FASTCALL|METH_KEYWORDS, memoryview_hex__doc__}, + +static PyObject * +memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep, + int bytes_per_sep); + +static PyObject * +memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *sep = NULL; + int bytes_per_sep = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + sep = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + bytes_per_sep = _PyLong_AsInt(args[1]); + if (bytes_per_sep == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = memoryview_hex_impl(self, sep, bytes_per_sep); + +exit: + return return_value; +} +/*[clinic end generated code: output=5e44e2bcf01057b5 input=a9049054013a1b77]*/ diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 6bbb413c3c106a..3955c58ee5d2eb 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -7,6 +7,12 @@ #include "pystrhex.h" #include +/*[clinic input] +class memoryview "PyMemoryViewObject *" "&PyMemoryView_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e2e49d2192835219]*/ + +#include "clinic/memoryobject.c.h" /****************************************************************************/ /* ManagedBuffer Object */ @@ -2160,8 +2166,33 @@ memory_tobytes(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) return bytes; } +/*[clinic input] +memoryview.hex + + sep: object = NULL + An optional single character or byte to separate hex bytes. + bytes_per_sep: int = 1 + How many bytes between separators. Positive values count from the + right, negative values count from the left. + +Return the data in the buffer as a str of hexadecimal numbers. + +Example: +>>> value = memoryview(b'\xb9\x01\xef') +>>> value.hex() +'b901ef' +>>> value.hex(':') +'b9:01:ef' +>>> value.hex(':', 2) +'b9:01ef' +>>> value.hex(':', -2) +'b901:ef' +[clinic start generated code]*/ + static PyObject * -memory_hex(PyMemoryViewObject *self, PyObject *dummy) +memoryview_hex_impl(PyMemoryViewObject *self, PyObject *sep, + int bytes_per_sep) +/*[clinic end generated code: output=430ca760f94f3ca7 input=539f6a3a5fb56946]*/ { Py_buffer *src = VIEW_ADDR(self); PyObject *bytes; @@ -2170,7 +2201,7 @@ memory_hex(PyMemoryViewObject *self, PyObject *dummy) CHECK_RELEASED(self); if (MV_C_CONTIGUOUS(self->flags)) { - return _Py_strhex(src->buf, src->len); + return _Py_strhex_with_sep(src->buf, src->len, sep, bytes_per_sep); } bytes = PyBytes_FromStringAndSize(NULL, src->len); @@ -2182,7 +2213,9 @@ memory_hex(PyMemoryViewObject *self, PyObject *dummy) return NULL; } - ret = _Py_strhex(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); + ret = _Py_strhex_with_sep( + PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes), + sep, bytes_per_sep); Py_DECREF(bytes); return ret; @@ -3090,10 +3123,6 @@ When order is 'C' or 'F', the data of the original array is converted to C or\n\ Fortran order. For contiguous views, 'A' returns an exact copy of the physical\n\ memory. In particular, in-memory Fortran order is preserved. For non-contiguous\n\ views, the data is converted to C first. order=None is the same as order='C'."); -PyDoc_STRVAR(memory_hex_doc, -"hex($self, /)\n--\n\ -\n\ -Return the data in the buffer as a string of hexadecimal numbers."); PyDoc_STRVAR(memory_tolist_doc, "tolist($self, /)\n--\n\ \n\ @@ -3110,7 +3139,7 @@ Return a readonly version of the memoryview."); static PyMethodDef memory_methods[] = { {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc}, {"tobytes", (PyCFunction)(void(*)(void))memory_tobytes, METH_VARARGS|METH_KEYWORDS, memory_tobytes_doc}, - {"hex", (PyCFunction)memory_hex, METH_NOARGS, memory_hex_doc}, + MEMORYVIEW_HEX_METHODDEF {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc}, {"cast", (PyCFunction)(void(*)(void))memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc}, {"toreadonly", (PyCFunction)memory_toreadonly, METH_NOARGS, memory_toreadonly_doc}, diff --git a/Python/pystrhex.c b/Python/pystrhex.c index 028f187c707cdd..695a3c394e9b06 100644 --- a/Python/pystrhex.c +++ b/Python/pystrhex.c @@ -5,40 +5,96 @@ #include "pystrhex.h" static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, - int return_bytes) + const PyObject* sep, int bytes_per_sep_group, + const int return_bytes) { PyObject *retval; Py_UCS1* retbuf; - Py_ssize_t i, j; + Py_ssize_t i, j, resultlen = 0; + Py_UCS1 sep_char; + unsigned int abs_bytes_per_sep; + + if (sep) { + Py_ssize_t seplen = PyObject_Length(sep); + if (seplen < 0) { + return NULL; + } + if (seplen != 1) { + PyErr_SetString(PyExc_ValueError, "sep must be length 1."); + return NULL; + } + if (PyUnicode_Check(sep)) { + if (PyUnicode_READY(sep)) + return NULL; + if (PyUnicode_KIND(sep) != PyUnicode_1BYTE_KIND) { + PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); + return NULL; + } + sep_char = PyUnicode_READ_CHAR(sep, 0); + } else if (PyBytes_Check(sep)) { + sep_char = PyBytes_AS_STRING(sep)[0]; + } else { + PyErr_SetString(PyExc_TypeError, "sep must be str or bytes."); + return NULL; + } + if (sep_char > 127 && !return_bytes) { + PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); + return NULL; + } + } else { + bytes_per_sep_group = 0; + } assert(arglen >= 0); - if (arglen > PY_SSIZE_T_MAX / 2) + abs_bytes_per_sep = abs(bytes_per_sep_group); + if (bytes_per_sep_group && arglen > 0) { + /* How many sep characters we'll be inserting. */ + resultlen = (arglen - 1) / abs_bytes_per_sep; + } + /* Bounds checking for our Py_ssize_t indices. */ + if (arglen >= PY_SSIZE_T_MAX / 2 - resultlen) { return PyErr_NoMemory(); + } + resultlen += arglen * 2; + + if (abs_bytes_per_sep >= arglen) { + bytes_per_sep_group = 0; + abs_bytes_per_sep = 0; + } if (return_bytes) { /* If _PyBytes_FromSize() were public we could avoid malloc+copy. */ - retbuf = (Py_UCS1*) PyMem_Malloc(arglen*2); + retbuf = (Py_UCS1*) PyMem_Malloc(resultlen); if (!retbuf) return PyErr_NoMemory(); retval = NULL; /* silence a compiler warning, assigned later. */ } else { - retval = PyUnicode_New(arglen*2, 127); + retval = PyUnicode_New(resultlen, 127); if (!retval) return NULL; retbuf = PyUnicode_1BYTE_DATA(retval); } - /* make hex version of string, taken from shamodule.c */ - for (i=j=0; i < arglen; i++) { + /* Hexlify */ + for (i=j=0; i < arglen; ++i) { + assert(j < resultlen); unsigned char c; c = (argbuf[i] >> 4) & 0xf; retbuf[j++] = Py_hexdigits[c]; c = argbuf[i] & 0xf; retbuf[j++] = Py_hexdigits[c]; + if (bytes_per_sep_group && i < arglen - 1) { + Py_ssize_t anchor; + anchor = (bytes_per_sep_group > 0) ? (arglen - 1 - i) : (i + 1); + if (anchor % abs_bytes_per_sep == 0) { + retbuf[j++] = sep_char; + } + } } + assert(j == resultlen); if (return_bytes) { - retval = PyBytes_FromStringAndSize((const char *)retbuf, arglen*2); + retval = PyBytes_FromStringAndSize((const char *)retbuf, resultlen); PyMem_Free(retbuf); } #ifdef Py_DEBUG @@ -52,12 +108,26 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, PyObject * _Py_strhex(const char* argbuf, const Py_ssize_t arglen) { - return _Py_strhex_impl(argbuf, arglen, 0); + return _Py_strhex_impl(argbuf, arglen, NULL, 0, 0); } /* Same as above but returns a bytes() instead of str() to avoid the * need to decode the str() when bytes are needed. */ PyObject * _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) { - return _Py_strhex_impl(argbuf, arglen, 1); + return _Py_strhex_impl(argbuf, arglen, NULL, 0, 1); +} + +/* These variants include support for a separator between every N bytes: */ + +PyObject * _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +{ + return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 0); +} + +/* Same as above but returns a bytes() instead of str() to avoid the + * need to decode the str() when bytes are needed. */ +PyObject * _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) +{ + return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 1); } From 43fdbd2729cb7cdbb5afb5d16352f6604859e564 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 29 May 2019 13:57:07 -0600 Subject: [PATCH 181/441] bpo-26836: Add os.memfd_create() (#13567) * bpo-26836: Add os.memfd_create() * Use the glibc wrapper for memfd_create() Co-Authored-By: Christian Heimes * Fix deletions caused by autoreconf. * Use MFD_CLOEXEC as the default value for *flags*. * Add memset_s to configure.ac. * Revert memset_s changes. * Apply the requested changes. * Tweak the docs. --- Doc/library/os.rst | 38 +++++++++++ Doc/whatsnew/3.8.rst | 4 ++ Lib/test/test_os.py | 16 +++++ .../2019-05-25-08-18-01.bpo-26836.rplYWW.rst | 1 + Modules/clinic/posixmodule.c.h | 61 +++++++++++++++++- Modules/posixmodule.c | 64 +++++++++++++++++++ aclocal.m4 | 10 +-- configure | 49 +++++++++++++- configure.ac | 16 ++++- pyconfig.h.in | 12 +++- 10 files changed, 259 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 6df2b49c5325e6..b53fd71e65b31a 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2982,6 +2982,44 @@ features: Added support for :class:`bytes` paths. +.. function:: memfd_create(name[, flags=os.MFD_CLOEXEC]) + + Create an anonymous file and return a file descriptor that refers to it. + *flags* must be one of the ``os.MFD_*`` constants available on the system + (or a bitwise ORed combination of them). By default, the new file + descriptor is :ref:`non-inheritable `. + + .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. + + .. versionadded:: 3.8 + + +.. data:: MFD_CLOEXEC + MFD_ALLOW_SEALING + MFD_HUGETLB + MFD_HUGE_SHIFT + MFD_HUGE_MASK + MFD_HUGE_64KB + MFD_HUGE_512KB + MFD_HUGE_1MB + MFD_HUGE_2MB + MFD_HUGE_8MB + MFD_HUGE_16MB + MFD_HUGE_32MB + MFD_HUGE_256MB + MFD_HUGE_512MB + MFD_HUGE_1GB + MFD_HUGE_2GB + MFD_HUGE_16GB + + These flags can be passed to :func:`memfd_create`. + + .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. The + ``MFD_HUGE*`` flags are only available since Linux 4.14. + + .. versionadded:: 3.8 + + Linux extended attributes ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index f704b47098e647..b4a80309170152 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -486,6 +486,10 @@ Added new function :func:`~os.add_dll_directory` on Windows for providing additional search paths for native dependencies when importing extension modules or loading DLLs using :mod:`ctypes`. +A new :func:`os.memfd_create` function was added to wrap the +``memfd_create()`` syscall. +(Contributed by Zackery Spytz and Christian Heimes in :issue:`26836`.) + os.path ------- diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 353b9a50a2b7fb..820c99c7a07cb4 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3122,6 +3122,22 @@ def test_stty_match(self): self.assertEqual(expected, actual) +@unittest.skipUnless(hasattr(os, 'memfd_create'), 'requires os.memfd_create') +class MemfdCreateTests(unittest.TestCase): + def test_memfd_create(self): + fd = os.memfd_create("Hi", os.MFD_CLOEXEC) + self.assertNotEqual(fd, -1) + self.addCleanup(os.close, fd) + self.assertFalse(os.get_inheritable(fd)) + with open(fd, "wb", closefd=False) as f: + f.write(b'memfd_create') + self.assertEqual(f.tell(), 12) + + fd2 = os.memfd_create("Hi") + self.addCleanup(os.close, fd2) + self.assertFalse(os.get_inheritable(fd2)) + + class OSErrorTests(unittest.TestCase): def setUp(self): class Str(str): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst new file mode 100644 index 00000000000000..bbf63ec82ca6cd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst @@ -0,0 +1 @@ +Add :func:`os.memfd_create`. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index f2745591b2353d..13f25460b4f6cf 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -7343,6 +7343,61 @@ os_urandom(PyObject *module, PyObject *arg) return return_value; } +#if defined(HAVE_MEMFD_CREATE) + +PyDoc_STRVAR(os_memfd_create__doc__, +"memfd_create($module, /, name, flags=MFD_CLOEXEC)\n" +"--\n" +"\n"); + +#define OS_MEMFD_CREATE_METHODDEF \ + {"memfd_create", (PyCFunction)(void(*)(void))os_memfd_create, METH_FASTCALL|METH_KEYWORDS, os_memfd_create__doc__}, + +static PyObject * +os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags); + +static PyObject * +os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"name", "flags", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "memfd_create", 0}; + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *name = NULL; + unsigned int flags = MFD_CLOEXEC; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_FSConverter(args[0], &name)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + flags = (unsigned int)PyLong_AsUnsignedLongMask(args[1]); + if (flags == (unsigned int)-1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = os_memfd_create_impl(module, name, flags); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + + return return_value; +} + +#endif /* defined(HAVE_MEMFD_CREATE) */ + PyDoc_STRVAR(os_cpu_count__doc__, "cpu_count($module, /)\n" "--\n" @@ -8549,6 +8604,10 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #define OS_LISTXATTR_METHODDEF #endif /* !defined(OS_LISTXATTR_METHODDEF) */ +#ifndef OS_MEMFD_CREATE_METHODDEF + #define OS_MEMFD_CREATE_METHODDEF +#endif /* !defined(OS_MEMFD_CREATE_METHODDEF) */ + #ifndef OS_GET_HANDLE_INHERITABLE_METHODDEF #define OS_GET_HANDLE_INHERITABLE_METHODDEF #endif /* !defined(OS_GET_HANDLE_INHERITABLE_METHODDEF) */ @@ -8576,4 +8635,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=5ee9420fb2e7aa2c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=855b81aafd05beed input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index cd5b5ce082ece4..a3d979c3bcd78d 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -389,6 +389,19 @@ extern char *ctermid_r(char *); #define HAVE_STRUCT_STAT_ST_FSTYPE 1 #endif +/* memfd_create is either defined in sys/mman.h or sys/memfd.h + * linux/memfd.h defines additional flags + */ +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_SYS_MEMFD_H +#include +#endif +#ifdef HAVE_LINUX_MEMFD_H +#include +#endif + #ifdef _Py_MEMORY_SANITIZER # include #endif @@ -11897,6 +11910,31 @@ os_urandom_impl(PyObject *module, Py_ssize_t size) return bytes; } +#ifdef HAVE_MEMFD_CREATE +/*[clinic input] +os.memfd_create + + name: FSConverter + flags: unsigned_int(bitwise=True, c_default="MFD_CLOEXEC") = MFD_CLOEXEC + +[clinic start generated code]*/ + +static PyObject * +os_memfd_create_impl(PyObject *module, PyObject *name, unsigned int flags) +/*[clinic end generated code: output=6681ede983bdb9a6 input=a42cfc199bcd56e9]*/ +{ + int fd; + const char *bytes = PyBytes_AS_STRING(name); + Py_BEGIN_ALLOW_THREADS + fd = memfd_create(bytes, flags); + Py_END_ALLOW_THREADS + if (fd == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + return PyLong_FromLong(fd); +} +#endif + /* Terminal size querying */ static PyTypeObject* TerminalSizeType; @@ -13554,6 +13592,7 @@ static PyMethodDef posix_methods[] = { OS_SCANDIR_METHODDEF OS_FSPATH_METHODDEF OS_GETRANDOM_METHODDEF + OS_MEMFD_CREATE_METHODDEF #ifdef MS_WINDOWS OS__ADD_DLL_DIRECTORY_METHODDEF OS__REMOVE_DLL_DIRECTORY_METHODDEF @@ -14003,6 +14042,27 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1; if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1; #endif +#ifdef HAVE_MEMFD_CREATE + if (PyModule_AddIntMacro(m, MFD_CLOEXEC)) return -1; + if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1; +#ifdef MFD_HUGETLB + if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1; + if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1; +#endif +#endif #if defined(__APPLE__) if (PyModule_AddIntConstant(m, "_COPYFILE_DATA", COPYFILE_DATA)) return -1; @@ -14119,6 +14179,10 @@ static const char * const have_functions[] = { "HAVE_LUTIMES", #endif +#ifdef HAVE_MEMFD_CREATE + "HAVE_MEMFD_CREATE", +#endif + #ifdef HAVE_MKDIRAT "HAVE_MKDIRAT", #endif diff --git a/aclocal.m4 b/aclocal.m4 index 038bd4e2cea25d..85f00dd5fac7f2 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -55,7 +55,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.2]) +[m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -156,7 +156,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $2]) +AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -166,11 +166,11 @@ and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -187,7 +187,7 @@ installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full diff --git a/configure b/configure index e8cbfeb154a543..cc18322d7514c3 100755 --- a/configure +++ b/configure @@ -785,6 +785,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -897,6 +898,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1149,6 +1151,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1286,7 +1297,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1439,6 +1450,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -7892,7 +7904,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h +sys/endian.h sys/sysmacros.h linux/memfd.h sys/memfd.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -11785,6 +11797,39 @@ $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for memfd_create" >&5 +$as_echo_n "checking for memfd_create... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_SYS_MEMFD_H +#include +#endif + +int +main () +{ +void *x=memfd_create + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define HAVE_MEMFD_CREATE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # On some systems (eg. FreeBSD 5), we would find a definition of the # functions ctermid_r, setgroups in the library, but no prototype # (e.g. because we use _XOPEN_SOURCE). See whether we can take their diff --git a/configure.ac b/configure.ac index 864c0abcf93e19..1190b37e9f9dfe 100644 --- a/configure.ac +++ b/configure.ac @@ -2133,7 +2133,7 @@ sys/stat.h sys/syscall.h sys/sys_domain.h sys/termio.h sys/time.h \ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \ libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \ linux/tipc.h linux/random.h spawn.h util.h alloca.h endian.h \ -sys/endian.h sys/sysmacros.h) +sys/endian.h sys/sysmacros.h linux/memfd.h sys/memfd.h sys/mman.h) AC_HEADER_DIRENT AC_HEADER_MAJOR @@ -3626,6 +3626,20 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ [AC_MSG_RESULT(no) ]) +AC_MSG_CHECKING(for memfd_create) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#ifdef HAVE_SYS_MEMFD_H +#include +#endif +]], [[void *x=memfd_create]])], + [AC_DEFINE(HAVE_MEMFD_CREATE, 1, Define if you have the 'memfd_create' function.) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) +]) + # On some systems (eg. FreeBSD 5), we would find a definition of the # functions ctermid_r, setgroups in the library, but no prototype # (e.g. because we use _XOPEN_SOURCE). See whether we can take their diff --git a/pyconfig.h.in b/pyconfig.h.in index cc64355416463b..b9bb3ffa6f6935 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -625,6 +625,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CAN_RAW_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_MEMFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_NETLINK_H @@ -667,15 +670,15 @@ /* Define to 1 if you have the `mbrtowc' function. */ #undef HAVE_MBRTOWC +/* Define if you have the 'memfd_create' function. */ +#undef HAVE_MEMFD_CREATE + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR -/* Define to 1 if you have the `memset_s' function. */ -#undef HAVE_MEMSET_S - /* Define to 1 if you have the `mkdirat' function. */ #undef HAVE_MKDIRAT @@ -1119,6 +1122,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LOCK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MEMFD_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MKDEV_H From ada319bb6d0ebcc68d3e0ef2b4279ea061877ac8 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 29 May 2019 22:12:38 +0200 Subject: [PATCH 182/441] bpo-32388: Remove cross-version binary compatibility requirement in tp_flags (GH-4944) It is now allowed to add new fields at the end of the PyTypeObject struct without having to allocate a dedicated compatibility flag in tp_flags. This will reduce the risk of running out of bits in the 32-bit tp_flags value. --- Doc/c-api/typeobj.rst | 5 +++++ Doc/whatsnew/3.8.rst | 9 +++++++++ Include/object.h | 18 ++++++++++-------- .../2017-12-21-20-37-40.bpo-32388.6w-i5t.rst | 1 + Modules/_asynciomodule.c | 6 ++---- Modules/_io/bufferedio.c | 11 +++++------ Modules/_io/fileio.c | 6 +++--- Modules/_io/iobase.c | 4 ++-- Modules/_io/textio.c | 5 ++--- Modules/_io/winconsoleio.c | 2 +- Modules/_testmultiphase.c | 2 +- Modules/gcmodule.c | 1 - Modules/posixmodule.c | 3 +-- Modules/socketmodule.c | 3 +-- Modules/xxlimited.c | 2 +- Objects/genobject.c | 9 +++------ Objects/object.c | 5 +---- Objects/typeobject.c | 11 ++++------- 18 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index aa667846a0da26..e2f8f54be79ae8 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1099,6 +1099,11 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.4 + .. deprecated:: 3.8 + This flag isn't necessary anymore, as the interpreter assumes the + :c:member:`~PyTypeObject.tp_finalize` slot is always present in the + type structure. + .. c:member:: const char* PyTypeObject.tp_doc diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index b4a80309170152..5cd9a8edc7935d 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1265,6 +1265,15 @@ Changes in the C API (Contributed by Zackery Spytz in :issue:`33407`.) +* The interpreter does not pretend to support binary compatibility of + extension types accross feature releases, anymore. A :c:type:`PyTypeObject` + exported by a third-party extension module is supposed to have all the + slots expected in the current Python version, including + :c:member:`~PyTypeObject.tp_finalize` (:const:`Py_TPFLAGS_HAVE_FINALIZE` + is not checked anymore before reading :c:member:`~PyTypeObject.tp_finalize`). + + (Contributed by Antoine Pitrou in :issue:`32388`.) + CPython bytecode changes ------------------------ diff --git a/Include/object.h b/Include/object.h index 11ba2bb8e2388c..cc98d8a1def7e7 100644 --- a/Include/object.h +++ b/Include/object.h @@ -263,17 +263,14 @@ PyAPI_FUNC(void) Py_ReprLeave(PyObject *); #define Py_PRINT_RAW 1 /* No string quotes etc. */ /* -`Type flags (tp_flags) +Type flags (tp_flags) -These flags are used to extend the type structure in a backwards-compatible -fashion. Extensions can use the flags to indicate (and test) when a given -type structure contains a new feature. The Python core will use these when -introducing new functionality between major revisions (to avoid mid-version -changes in the PYTHON_API_VERSION). +These flags are used to change expected features and behavior for a +particular type. Arbitration of the flag bit positions will need to be coordinated among all extension writers who publicly release their extensions (this will -be fewer than you might expect!).. +be fewer than you might expect!). Most flags were removed as of Python 3.0 to make room for new flags. (Some flags are not for backwards compatibility but to indicate the presence of an @@ -302,7 +299,7 @@ given type object has a specified feature. /* Set while the type is being 'readied', to prevent recursive ready calls */ #define Py_TPFLAGS_READYING (1UL << 13) -/* Objects support garbage collection (see objimp.h) */ +/* Objects support garbage collection (see objimpl.h) */ #define Py_TPFLAGS_HAVE_GC (1UL << 14) /* These two bits are preserved for Stackless Python, next after this is 17 */ @@ -340,6 +337,11 @@ given type object has a specified feature. /* NOTE: The following flags reuse lower bits (removed as part of the * Python 3.0 transition). */ +/* The following flag is kept for compatibility. Starting with 3.8, + * binary compatibility of C extensions accross feature releases of + * Python is not supported anymore, except when using the stable ABI. + */ + /* Type structure has tp_finalize member (3.4) */ #define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst new file mode 100644 index 00000000000000..60615d47f60d4d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst @@ -0,0 +1 @@ +Remove cross-version binary compatibility requirement in tp_flags. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 60136082a7eecf..d8b631b7c7a292 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1430,8 +1430,7 @@ static PyTypeObject FutureType = { .tp_dealloc = FutureObj_dealloc, .tp_as_async = &FutureType_as_async, .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .tp_doc = _asyncio_Future___init____doc__, .tp_traverse = (traverseproc)FutureObj_traverse, .tp_clear = (inquiry)FutureObj_clear, @@ -2461,8 +2460,7 @@ static PyTypeObject TaskType = { .tp_dealloc = TaskObj_dealloc, .tp_as_async = &FutureType_as_async, .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .tp_doc = _asyncio_Task___init____doc__, .tp_traverse = (traverseproc)TaskObj_traverse, .tp_clear = (inquiry)TaskObj_clear, diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 6f855b9edd0842..9c0eeb56860eea 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -2342,8 +2342,7 @@ PyTypeObject PyBufferedIOBase_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ bufferediobase_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -2434,7 +2433,7 @@ PyTypeObject PyBufferedReader_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ _io_BufferedReader___init____doc__, /* tp_doc */ (traverseproc)buffered_traverse, /* tp_traverse */ (inquiry)buffered_clear, /* tp_clear */ @@ -2520,7 +2519,7 @@ PyTypeObject PyBufferedWriter_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ _io_BufferedWriter___init____doc__, /* tp_doc */ (traverseproc)buffered_traverse, /* tp_traverse */ (inquiry)buffered_clear, /* tp_clear */ @@ -2597,7 +2596,7 @@ PyTypeObject PyBufferedRWPair_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + | Py_TPFLAGS_HAVE_GC, /* tp_flags */ _io_BufferedRWPair___init____doc__, /* tp_doc */ (traverseproc)bufferedrwpair_traverse, /* tp_traverse */ (inquiry)bufferedrwpair_clear, /* tp_clear */ @@ -2691,7 +2690,7 @@ PyTypeObject PyBufferedRandom_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ _io_BufferedRandom___init____doc__, /* tp_doc */ (traverseproc)buffered_traverse, /* tp_traverse */ (inquiry)buffered_clear, /* tp_clear */ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 52a6f49e1d325b..582a8130f622af 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -1200,12 +1200,12 @@ PyTypeObject PyFileIO_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + | Py_TPFLAGS_HAVE_GC, /* tp_flags */ _io_FileIO___init____doc__, /* tp_doc */ (traverseproc)fileio_traverse, /* tp_traverse */ (inquiry)fileio_clear, /* tp_clear */ 0, /* tp_richcompare */ - offsetof(fileio, weakreflist), /* tp_weaklistoffset */ + offsetof(fileio, weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ fileio_methods, /* tp_methods */ @@ -1215,7 +1215,7 @@ PyTypeObject PyFileIO_Type = { 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof(fileio, dict), /* tp_dictoffset */ + offsetof(fileio, dict), /* tp_dictoffset */ _io_FileIO___init__, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ fileio_new, /* tp_new */ diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index a5727b8deed35a..8c8112d10f0ba8 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -856,7 +856,7 @@ PyTypeObject PyIOBase_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ iobase_doc, /* tp_doc */ (traverseproc)iobase_traverse, /* tp_traverse */ (inquiry)iobase_clear, /* tp_clear */ @@ -1051,7 +1051,7 @@ PyTypeObject PyRawIOBase_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ rawiobase_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index a08ab5b0e27ff6..3eb0dcc865ba2e 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -183,8 +183,7 @@ PyTypeObject PyTextIOBase_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ textiobase_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -3258,7 +3257,7 @@ PyTypeObject PyTextIOWrapper_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ _io_TextIOWrapper___init____doc__, /* tp_doc */ (traverseproc)textiowrapper_traverse, /* tp_traverse */ (inquiry)textiowrapper_clear, /* tp_clear */ diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 70a723ed746a75..7700bd5b7c0d31 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -1133,7 +1133,7 @@ PyTypeObject PyWindowsConsoleIO_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + | Py_TPFLAGS_HAVE_GC, /* tp_flags */ _io__WindowsConsoleIO___init____doc__, /* tp_doc */ (traverseproc)winconsoleio_traverse, /* tp_traverse */ (inquiry)winconsoleio_clear, /* tp_clear */ diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index db5bb7d6b8a22d..4933abbabbe307 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -98,7 +98,7 @@ static PyType_Spec Example_Type_spec = { "_testimportexec.Example", sizeof(ExampleObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, Example_Type_slots }; diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 3b15c7ba5b6284..0cf00e839661f0 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -858,7 +858,6 @@ finalize_garbage(PyGC_Head *collectable) PyObject *op = FROM_GC(gc); gc_list_move(gc, &seen); if (!_PyGCHead_FINALIZED(gc) && - PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) && (finalize = Py_TYPE(op)->tp_finalize) != NULL) { _PyGCHead_SET_FINALIZED(gc); Py_INCREF(op); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a3d979c3bcd78d..a25ff7a895c01d 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -13032,8 +13032,7 @@ static PyTypeObject ScandirIteratorType = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 74cdc0f2f6caed..ca4d760f8cb4f4 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5286,8 +5286,7 @@ static PyTypeObject sock_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ sock_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 190f9937d0de9f..ffc04e0310e392 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -123,7 +123,7 @@ static PyType_Spec Xxo_Type_spec = { "xxlimited.Xxo", sizeof(XxoObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, Xxo_Type_slots }; diff --git a/Objects/genobject.c b/Objects/genobject.c index e2def38af541a5..0d0a02d76ccf21 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -742,8 +742,7 @@ PyTypeObject PyGen_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)gen_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -997,8 +996,7 @@ PyTypeObject PyCoro_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)gen_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -1394,8 +1392,7 @@ PyTypeObject PyAsyncGen_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)async_gen_traverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/object.c b/Objects/object.c index 87dba9898e3a8a..f9c75b7c6a4e95 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -298,10 +298,7 @@ PyObject_CallFinalizer(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); - /* The former could happen on heaptypes created from the C API, e.g. - PyType_FromSpec(). */ - if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_FINALIZE) || - tp->tp_finalize == NULL) + if (tp->tp_finalize == NULL) return; /* tp_finalize should only be called once. */ if (PyType_IS_GC(tp) && _PyGC_FINALIZED(self)) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index c14cbad875b443..071ff27d532397 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -248,8 +248,8 @@ PyType_Modified(PyTypeObject *type) Invariants: - Py_TPFLAGS_VALID_VERSION_TAG is never set if - Py_TPFLAGS_HAVE_VERSION_TAG is not set (e.g. on type - objects coming from non-recompiled extension modules) + Py_TPFLAGS_HAVE_VERSION_TAG is not set (in case of a + bizarre MRO, see type_mro_modified()). - before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type, it must first be set on all super types. @@ -2571,7 +2571,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) /* Initialize tp_flags */ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_FINALIZE; + Py_TPFLAGS_BASETYPE; if (base->tp_flags & Py_TPFLAGS_HAVE_GC) type->tp_flags |= Py_TPFLAGS_HAVE_GC; @@ -5179,10 +5179,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) COPYSLOT(tp_init); COPYSLOT(tp_alloc); COPYSLOT(tp_is_gc); - if ((type->tp_flags & Py_TPFLAGS_HAVE_FINALIZE) && - (base->tp_flags & Py_TPFLAGS_HAVE_FINALIZE)) { - COPYSLOT(tp_finalize); - } + COPYSLOT(tp_finalize); if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) == (base->tp_flags & Py_TPFLAGS_HAVE_GC)) { /* They agree about gc. */ From e70bfa95e6f0c98b9906f306f24d71f8b7689f87 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 29 May 2019 14:43:50 -0600 Subject: [PATCH 183/441] bpo-26836: Add ifdefs for all MFD_HUGE* constants (GH-13666) https://bugs.python.org/issue26836 --- Modules/posixmodule.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a25ff7a895c01d..7588d3cde71666 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -14046,19 +14046,47 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, MFD_ALLOW_SEALING)) return -1; #ifdef MFD_HUGETLB if (PyModule_AddIntMacro(m, MFD_HUGETLB)) return -1; +#endif +#ifdef MFD_HUGE_SHIFT if (PyModule_AddIntMacro(m, MFD_HUGE_SHIFT)) return -1; +#endif +#ifdef MFD_HUGE_MASK if (PyModule_AddIntMacro(m, MFD_HUGE_MASK)) return -1; +#endif +#ifdef MFD_HUGE_64KB if (PyModule_AddIntMacro(m, MFD_HUGE_64KB)) return -1; +#endif +#ifdef MFD_HUGE_512KB if (PyModule_AddIntMacro(m, MFD_HUGE_512KB)) return -1; +#endif +#ifdef MFD_HUGE_1MB if (PyModule_AddIntMacro(m, MFD_HUGE_1MB)) return -1; +#endif +#ifdef MFD_HUGE_2MB if (PyModule_AddIntMacro(m, MFD_HUGE_2MB)) return -1; +#endif +#ifdef MFD_HUGE_8MB if (PyModule_AddIntMacro(m, MFD_HUGE_8MB)) return -1; +#endif +#ifdef MFD_HUGE_16MB if (PyModule_AddIntMacro(m, MFD_HUGE_16MB)) return -1; +#endif +#ifdef MFD_HUGE_32MB if (PyModule_AddIntMacro(m, MFD_HUGE_32MB)) return -1; +#endif +#ifdef MFD_HUGE_256MB if (PyModule_AddIntMacro(m, MFD_HUGE_256MB)) return -1; +#endif +#ifdef MFD_HUGE_512MB if (PyModule_AddIntMacro(m, MFD_HUGE_512MB)) return -1; +#endif +#ifdef MFD_HUGE_1GB if (PyModule_AddIntMacro(m, MFD_HUGE_1GB)) return -1; +#endif +#ifdef MFD_HUGE_2GB if (PyModule_AddIntMacro(m, MFD_HUGE_2GB)) return -1; +#endif +#ifdef MFD_HUGE_16GB if (PyModule_AddIntMacro(m, MFD_HUGE_16GB)) return -1; #endif #endif From fecb75c1bb46c818e6579ba422cfa5d0d9d104d1 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 29 May 2019 22:45:41 +0200 Subject: [PATCH 184/441] bpo-36974: Fix GDB integration (GH-13665) As it changes the way functions are called, the PEP 590 implementation skipped the functions that the GDB integration is looking for (by name) to find function calls. Looking for the new helper `cfunction_call_varargs` hopefully fixes the tests, and thus buildbots. The changed frame nuber in test_gdb is due to there being fewer C calls when calling a built-in method. --- Lib/test/test_gdb.py | 2 +- Tools/gdb/libpython.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index dbcb5983e9ba1d..3127e69ca9ba1d 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -887,7 +887,7 @@ def test_pycfunction(self): breakpoint='time_gmtime', cmds_after_breakpoint=['py-bt-full'], ) - self.assertIn('#2 Date: Wed, 29 May 2019 15:02:37 -0600 Subject: [PATCH 185/441] bpo-37007: Implement socket.if_nametoindex(), if_indextoname() and if_nameindex() on Windows (GH-13522) --- Doc/library/socket.rst | 15 ++++- Doc/whatsnew/3.8.rst | 4 ++ Lib/test/test_socket.py | 24 ++++---- .../2019-05-23-04-19-13.bpo-37007.d1SOtF.rst | 2 + Modules/socketmodule.c | 60 +++++++++++++++---- PCbuild/_socket.vcxproj | 2 +- 6 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 5be2b76113eb04..e0dbbb4c0d3201 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -1034,10 +1034,13 @@ The :mod:`socket` module also offers various network-related services: (index int, name string) tuples. :exc:`OSError` if the system call fails. - .. availability:: Unix. + .. availability:: Unix, Windows. .. versionadded:: 3.3 + .. versionchanged:: 3.8 + Windows support was added. + .. function:: if_nametoindex(if_name) @@ -1045,10 +1048,13 @@ The :mod:`socket` module also offers various network-related services: interface name. :exc:`OSError` if no interface with the given name exists. - .. availability:: Unix. + .. availability:: Unix, Windows. .. versionadded:: 3.3 + .. versionchanged:: 3.8 + Windows support was added. + .. function:: if_indextoname(if_index) @@ -1056,10 +1062,13 @@ The :mod:`socket` module also offers various network-related services: interface index number. :exc:`OSError` if no interface with the given index exists. - .. availability:: Unix. + .. availability:: Unix, Windows. .. versionadded:: 3.3 + .. versionchanged:: 3.8 + Windows support was added. + .. _socket-objects: diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 5cd9a8edc7935d..5ee9cf07ebaf11 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -556,6 +556,10 @@ convenience functions to automate the necessary tasks usually involved when creating a server socket, including accepting both IPv4 and IPv6 connections on the same socket. (Contributed by Giampaolo Rodola in :issue:`17561`.) +The :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, and +:func:`socket.if_indextoname()` functions have been implemented on Windows. +(Contributed by Zackery Spytz in :issue:`37007`.) + shlex ---------- diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 0094cecb79cca6..74662cfeb327af 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -973,16 +973,18 @@ def testInterfaceNameIndex(self): self.assertIsInstance(_name, str) self.assertEqual(name, _name) - @unittest.skipUnless(hasattr(socket, 'if_nameindex'), - 'socket.if_nameindex() not available.') - def testInvalidInterfaceNameIndex(self): - # test nonexistent interface index/name + @unittest.skipUnless(hasattr(socket, 'if_indextoname'), + 'socket.if_indextoname() not available.') + def testInvalidInterfaceIndexToName(self): self.assertRaises(OSError, socket.if_indextoname, 0) - self.assertRaises(OSError, socket.if_nametoindex, '_DEADBEEF') - # test with invalid values - self.assertRaises(TypeError, socket.if_nametoindex, 0) self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF') + @unittest.skipUnless(hasattr(socket, 'if_nametoindex'), + 'socket.if_nametoindex() not available.') + def testInvalidInterfaceNameToIndex(self): + self.assertRaises(TypeError, socket.if_nametoindex, 0) + self.assertRaises(OSError, socket.if_nametoindex, '_DEADBEEF') + @unittest.skipUnless(hasattr(sys, 'getrefcount'), 'test needs sys.getrefcount()') def testRefCountGetNameInfo(self): @@ -1638,9 +1640,7 @@ def test_getaddrinfo_ipv6_basic(self): self.assertEqual(sockaddr, ('ff02::1de:c0:face:8d', 1234, 0, 0)) @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') - @unittest.skipUnless( - hasattr(socket, 'if_nameindex'), - 'if_nameindex is not supported') + @unittest.skipIf(sys.platform == 'win32', 'does not work on Windows') @unittest.skipIf(AIX, 'Symbolic scope id does not work') def test_getaddrinfo_ipv6_scopeid_symbolic(self): # Just pick up any network interface (Linux, Mac OS X) @@ -1672,9 +1672,7 @@ def test_getaddrinfo_ipv6_scopeid_numeric(self): self.assertEqual(sockaddr, ('ff02::1de:c0:face:8d', 1234, 0, ifindex)) @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') - @unittest.skipUnless( - hasattr(socket, 'if_nameindex'), - 'if_nameindex is not supported') + @unittest.skipIf(sys.platform == 'win32', 'does not work on Windows') @unittest.skipIf(AIX, 'Symbolic scope id does not work') def test_getnameinfo_ipv6_scopeid_symbolic(self): # Just pick up any network interface. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst new file mode 100644 index 00000000000000..ac344a57c83d93 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst @@ -0,0 +1,2 @@ +Implement :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, and +:func:`socket.if_indextoname()` on Windows. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ca4d760f8cb4f4..ac1698c6c767f2 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -345,6 +345,8 @@ if_indextoname(index) -- return the corresponding interface name\n\ /* Provides the IsWindows7SP1OrGreater() function */ #include +// For if_nametoindex() and if_indextoname() +#include /* remove some flags on older version Windows during run-time. https://msdn.microsoft.com/en-us/library/windows/desktop/ms738596.aspx */ @@ -6667,28 +6669,56 @@ Set the default timeout in seconds (float) for new socket objects.\n\ A value of None indicates that new socket objects have no timeout.\n\ When the socket module is first imported, the default is None."); -#ifdef HAVE_IF_NAMEINDEX +#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) /* Python API for getting interface indices and names */ static PyObject * socket_if_nameindex(PyObject *self, PyObject *arg) { - PyObject *list; + PyObject *list = PyList_New(0); + if (list == NULL) { + return NULL; + } +#ifdef MS_WINDOWS + PMIB_IF_TABLE2 tbl; + int ret; + if ((ret = GetIfTable2Ex(MibIfTableRaw, &tbl)) != NO_ERROR) { + Py_DECREF(list); + // ret is used instead of GetLastError() + return PyErr_SetFromWindowsErr(ret); + } + for (ULONG i = 0; i < tbl->NumEntries; ++i) { + MIB_IF_ROW2 r = tbl->Table[i]; + WCHAR buf[NDIS_IF_MAX_STRING_SIZE + 1]; + if ((ret = ConvertInterfaceLuidToNameW(&r.InterfaceLuid, buf, + Py_ARRAY_LENGTH(buf)))) { + Py_DECREF(list); + FreeMibTable(tbl); + // ret is used instead of GetLastError() + return PyErr_SetFromWindowsErr(ret); + } + PyObject *tuple = Py_BuildValue("Iu", r.InterfaceIndex, buf); + if (tuple == NULL || PyList_Append(list, tuple) == -1) { + Py_XDECREF(tuple); + Py_DECREF(list); + FreeMibTable(tbl); + return NULL; + } + Py_DECREF(tuple); + } + FreeMibTable(tbl); + return list; +#else int i; struct if_nameindex *ni; ni = if_nameindex(); if (ni == NULL) { + Py_DECREF(list); PyErr_SetFromErrno(PyExc_OSError); return NULL; } - list = PyList_New(0); - if (list == NULL) { - if_freenameindex(ni); - return NULL; - } - #ifdef _Py_MEMORY_SANITIZER __msan_unpoison(ni, sizeof(ni)); __msan_unpoison(&ni[0], sizeof(ni[0])); @@ -6720,6 +6750,7 @@ socket_if_nameindex(PyObject *self, PyObject *arg) if_freenameindex(ni); return list; +#endif } PyDoc_STRVAR(if_nameindex_doc, @@ -6731,8 +6762,11 @@ static PyObject * socket_if_nametoindex(PyObject *self, PyObject *args) { PyObject *oname; +#ifdef MS_WINDOWS + NET_IFINDEX index; +#else unsigned long index; - +#endif if (!PyArg_ParseTuple(args, "O&:if_nametoindex", PyUnicode_FSConverter, &oname)) return NULL; @@ -6756,7 +6790,11 @@ Returns the interface index corresponding to the interface name if_name."); static PyObject * socket_if_indextoname(PyObject *self, PyObject *arg) { +#ifdef MS_WINDOWS + NET_IFINDEX index; +#else unsigned long index; +#endif char name[IF_NAMESIZE + 1]; index = PyLong_AsUnsignedLong(arg); @@ -6776,7 +6814,7 @@ PyDoc_STRVAR(if_indextoname_doc, \n\ Returns the interface name corresponding to the interface index if_index."); -#endif /* HAVE_IF_NAMEINDEX */ +#endif // defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) #ifdef CMSG_LEN @@ -6898,7 +6936,7 @@ static PyMethodDef socket_methods[] = { METH_NOARGS, getdefaulttimeout_doc}, {"setdefaulttimeout", socket_setdefaulttimeout, METH_O, setdefaulttimeout_doc}, -#ifdef HAVE_IF_NAMEINDEX +#if defined(HAVE_IF_NAMEINDEX) || defined(MS_WINDOWS) {"if_nameindex", socket_if_nameindex, METH_NOARGS, if_nameindex_doc}, {"if_nametoindex", socket_if_nametoindex, diff --git a/PCbuild/_socket.vcxproj b/PCbuild/_socket.vcxproj index 9498abf8fb5e2a..8fd75f90e7ee1e 100644 --- a/PCbuild/_socket.vcxproj +++ b/PCbuild/_socket.vcxproj @@ -93,7 +93,7 @@ - ws2_32.lib;%(AdditionalDependencies) + ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies) From 29cb21ddb92413931e473eb799a02e2d8cdf4a45 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 29 May 2019 22:59:00 +0100 Subject: [PATCH 186/441] Regenerate topics file (GH-13642) --- Doc/reference/compound_stmts.rst | 2 +- Lib/pydoc_data/topics.py | 118 +++++++++++++++++-------------- 2 files changed, 67 insertions(+), 53 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index bf53cb5a48ab03..988eec6d254e10 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -483,7 +483,7 @@ A function definition defines a user-defined function object (see section decorators: `decorator`+ decorator: "@" `dotted_name` ["(" [`argument_list` [","]] ")"] NEWLINE dotted_name: `identifier` ("." `identifier`)* - parameter_list: `defparameter` ("," `defparameter`)* ',' '/' [',' [`parameter_list_no_posonly`]] + parameter_list: `defparameter` ("," `defparameter`)* "," "/" ["," [`parameter_list_no_posonly`]] : | `parameter_list_no_posonly` parameter_list_no_posonly: `defparameter` ("," `defparameter`)* ["," [`parameter_list_starargs`]] : | `parameter_list_starargs` diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 875d6e890347c3..3361c6b5568a4d 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Mon May 6 20:27:55 2019 +# Autogenerated by Sphinx on Wed May 29 01:18:52 2019 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -2044,7 +2044,7 @@ 'exception is raised, it is as if "in" raised that ' 'exception).\n' '\n' - 'The operator "not in" is defined to have the inverse true ' + 'The operator "not in" is defined to have the inverse truth ' 'value of\n' '"in".\n' '\n' @@ -2052,13 +2052,13 @@ 'Identity comparisons\n' '====================\n' '\n' - 'The operators "is" and "is not" test for object identity: "x ' - 'is y" is\n' - 'true if and only if *x* and *y* are the same object. Object ' - 'identity\n' - 'is determined using the "id()" function. "x is not y" yields ' - 'the\n' - 'inverse truth value. [4]\n', + 'The operators "is" and "is not" test for an object’s ' + 'identity: "x is\n' + 'y" is true if and only if *x* and *y* are the same object. ' + 'An\n' + 'Object’s identity is determined using the "id()" function. ' + '"x is not\n' + 'y" yields the inverse truth value. [4]\n', 'compound': 'Compound statements\n' '*******************\n' '\n' @@ -2558,22 +2558,25 @@ '(see\n' 'section The standard type hierarchy):\n' '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' + ' funcdef ::= [decorators] "def" funcname "(" ' '[parameter_list] ")"\n' ' ["->" expression] ":" suite\n' - ' decorators ::= decorator+\n' - ' decorator ::= "@" dotted_name ["(" ' + ' decorators ::= decorator+\n' + ' decorator ::= "@" dotted_name ["(" ' '[argument_list [","]] ")"] NEWLINE\n' - ' dotted_name ::= identifier ("." identifier)*\n' - ' parameter_list ::= defparameter ("," defparameter)* ' - '["," [parameter_list_starargs]]\n' - ' | parameter_list_starargs\n' - ' parameter_list_starargs ::= "*" [parameter] ("," ' + ' dotted_name ::= identifier ("." identifier)*\n' + ' parameter_list ::= defparameter ("," ' + 'defparameter)* "," "/" ["," [parameter_list_no_posonly]]\n' + ' | parameter_list_no_posonly\n' + ' parameter_list_no_posonly ::= defparameter ("," ' + 'defparameter)* ["," [parameter_list_starargs]]\n' + ' | parameter_list_starargs\n' + ' parameter_list_starargs ::= "*" [parameter] ("," ' 'defparameter)* ["," ["**" parameter [","]]]\n' ' | "**" parameter [","]\n' - ' parameter ::= identifier [":" expression]\n' - ' defparameter ::= parameter ["=" expression]\n' - ' funcname ::= identifier\n' + ' parameter ::= identifier [":" expression]\n' + ' defparameter ::= parameter ["=" expression]\n' + ' funcname ::= identifier\n' '\n' 'A function definition is an executable statement. Its execution ' 'binds\n' @@ -4363,7 +4366,7 @@ 'terminates\n' 'execution of the program, or returns to its interactive main ' 'loop. In\n' - 'either case, it prints a stack backtrace, except when the ' + 'either case, it prints a stack traceback, except when the ' 'exception is\n' '"SystemExit".\n' '\n' @@ -4684,7 +4687,7 @@ 'terminates\n' 'execution of the program, or returns to its interactive main ' 'loop. In\n' - 'either case, it prints a stack backtrace, except when the ' + 'either case, it prints a stack traceback, except when the ' 'exception is\n' '"SystemExit".\n' '\n' @@ -5078,7 +5081,7 @@ 'Meaning ' '|\n' ' ' - '+===========+============================================================+\n' + '|===========|============================================================|\n' ' | "\'<\'" | Forces the field to be left-aligned ' 'within the available |\n' ' | | space (this is the default for most ' @@ -5127,7 +5130,7 @@ 'Meaning ' '|\n' ' ' - '+===========+============================================================+\n' + '|===========|============================================================|\n' ' | "\'+\'" | indicates that a sign should be used for ' 'both positive as |\n' ' | | well as negative ' @@ -5231,7 +5234,7 @@ 'Meaning ' '|\n' ' ' - '+===========+============================================================+\n' + '|===========|============================================================|\n' ' | "\'s\'" | String format. This is the default type ' 'for strings and |\n' ' | | may be ' @@ -5251,7 +5254,7 @@ 'Meaning ' '|\n' ' ' - '+===========+============================================================+\n' + '|===========|============================================================|\n' ' | "\'b\'" | Binary format. Outputs the number in ' 'base 2. |\n' ' ' @@ -5313,7 +5316,7 @@ 'Meaning ' '|\n' ' ' - '+===========+============================================================+\n' + '|===========|============================================================|\n' ' | "\'e\'" | Exponent notation. Prints the number in ' 'scientific |\n' ' | | notation using the letter ‘e’ to indicate ' @@ -5584,22 +5587,25 @@ '(see\n' 'section The standard type hierarchy):\n' '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' + ' funcdef ::= [decorators] "def" funcname "(" ' '[parameter_list] ")"\n' ' ["->" expression] ":" suite\n' - ' decorators ::= decorator+\n' - ' decorator ::= "@" dotted_name ["(" ' + ' decorators ::= decorator+\n' + ' decorator ::= "@" dotted_name ["(" ' '[argument_list [","]] ")"] NEWLINE\n' - ' dotted_name ::= identifier ("." identifier)*\n' - ' parameter_list ::= defparameter ("," defparameter)* ' - '["," [parameter_list_starargs]]\n' - ' | parameter_list_starargs\n' - ' parameter_list_starargs ::= "*" [parameter] ("," ' + ' dotted_name ::= identifier ("." identifier)*\n' + ' parameter_list ::= defparameter ("," ' + 'defparameter)* "," "/" ["," [parameter_list_no_posonly]]\n' + ' | parameter_list_no_posonly\n' + ' parameter_list_no_posonly ::= defparameter ("," ' + 'defparameter)* ["," [parameter_list_starargs]]\n' + ' | parameter_list_starargs\n' + ' parameter_list_starargs ::= "*" [parameter] ("," ' 'defparameter)* ["," ["**" parameter [","]]]\n' ' | "**" parameter [","]\n' - ' parameter ::= identifier [":" expression]\n' - ' defparameter ::= parameter ["=" expression]\n' - ' funcname ::= identifier\n' + ' parameter ::= identifier [":" expression]\n' + ' defparameter ::= parameter ["=" expression]\n' + ' funcname ::= identifier\n' '\n' 'A function definition is an executable statement. Its execution ' 'binds\n' @@ -6338,7 +6344,7 @@ 'integer indices do not raise "IndexError" exception. (If any other\n' 'exception is raised, it is as if "in" raised that exception).\n' '\n' - 'The operator "not in" is defined to have the inverse true value of\n' + 'The operator "not in" is defined to have the inverse truth value of\n' '"in".\n', 'integers': 'Integer literals\n' '****************\n' @@ -7019,7 +7025,7 @@ '+-------------------------------------------------+---------------------------------------+\n' '| Operator | ' 'Description |\n' - '+=================================================+=======================================+\n' + '|=================================================|=======================================|\n' '| "lambda" | ' 'Lambda expression |\n' '+-------------------------------------------------+---------------------------------------+\n' @@ -10263,7 +10269,7 @@ ' | Representation | ' 'Description |\n' ' ' - '+=========================+===============================+\n' + '|=========================|===============================|\n' ' | "\\n" | Line ' 'Feed |\n' ' ' @@ -10602,7 +10608,7 @@ '+-------------------+-----------------------------------+---------+\n' '| Escape Sequence | Meaning | Notes ' '|\n' - '+===================+===================================+=========+\n' + '|===================|===================================|=========|\n' '| "\\newline" | Backslash and newline ignored ' '| |\n' '+-------------------+-----------------------------------+---------+\n' @@ -10648,7 +10654,7 @@ '+-------------------+-----------------------------------+---------+\n' '| Escape Sequence | Meaning | Notes ' '|\n' - '+===================+===================================+=========+\n' + '|===================|===================================|=========|\n' '| "\\N{name}" | Character named *name* in the | ' '(4) |\n' '| | Unicode database | ' @@ -11286,7 +11292,7 @@ ' | Attribute | Meaning ' '| |\n' ' ' - '+===========================+=================================+=============+\n' + '|===========================|=================================|=============|\n' ' | "__doc__" | The function’s documentation ' '| Writable |\n' ' | | string, or "None" if ' @@ -12557,7 +12563,7 @@ '+----------------------------+----------------------------------+------------+\n' '| Operation | Result ' '| Notes |\n' - '+============================+==================================+============+\n' + '|============================|==================================|============|\n' '| "x in s" | "True" if an item of *s* is ' '| (1) |\n' '| | equal to *x*, else "False" ' @@ -12786,7 +12792,7 @@ '+--------------------------------+----------------------------------+-----------------------+\n' '| Operation | ' 'Result | Notes |\n' - '+================================+==================================+=======================+\n' + '|================================|==================================|=======================|\n' '| "s[i] = x" | item *i* of *s* is replaced ' 'by | |\n' '| | ' @@ -12872,7 +12878,7 @@ 'default\n' ' the last item is removed and returned.\n' '\n' - '3. "remove" raises "ValueError" when *x* is not found in *s*.\n' + '3. "remove()" raises "ValueError" when *x* is not found in *s*.\n' '\n' '4. The "reverse()" method modifies the sequence in place for\n' ' economy of space when reversing a large sequence. To remind ' @@ -12883,7 +12889,11 @@ '\n' '5. "clear()" and "copy()" are included for consistency with the\n' ' interfaces of mutable containers that don’t support slicing\n' - ' operations (such as "dict" and "set")\n' + ' operations (such as "dict" and "set"). "copy()" is not part ' + 'of the\n' + ' "collections.abc.MutableSequence" ABC, but most concrete ' + 'mutable\n' + ' sequence classes provide it.\n' '\n' ' New in version 3.3: "clear()" and "copy()" methods.\n' '\n' @@ -13244,7 +13254,7 @@ '| Operation | ' 'Result | Notes ' '|\n' - '+================================+==================================+=======================+\n' + '|================================|==================================|=======================|\n' '| "s[i] = x" | item *i* of *s* is ' 'replaced by | |\n' '| | ' @@ -13333,8 +13343,8 @@ 'by default\n' ' the last item is removed and returned.\n' '\n' - '3. "remove" raises "ValueError" when *x* is not found in ' - '*s*.\n' + '3. "remove()" raises "ValueError" when *x* is not found ' + 'in *s*.\n' '\n' '4. The "reverse()" method modifies the sequence in place ' 'for\n' @@ -13348,7 +13358,11 @@ 'with the\n' ' interfaces of mutable containers that don’t support ' 'slicing\n' - ' operations (such as "dict" and "set")\n' + ' operations (such as "dict" and "set"). "copy()" is ' + 'not part of the\n' + ' "collections.abc.MutableSequence" ABC, but most ' + 'concrete mutable\n' + ' sequence classes provide it.\n' '\n' ' New in version 3.3: "clear()" and "copy()" methods.\n' '\n' From 80878312316bfb4011157f13cf040f6d885f808b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Wed, 29 May 2019 17:13:12 -0700 Subject: [PATCH 187/441] Don't crash if there exists an EGG-INFO directory on sys.path (#13667) * Don't crash if there exists an EGG-INFO directory on sys.path cross-port of https://gitlab.com/python-devs/importlib_metadata/merge_requests/72 * Also catch PermissionError for windows --- Lib/importlib/metadata/__init__.py | 3 ++- Lib/test/test_importlib/test_main.py | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index 24d45d2caad0ad..a1abdd64815bff 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -320,7 +320,8 @@ def __init__(self, path): self._path = path def read_text(self, filename): - with suppress(FileNotFoundError, NotADirectoryError, KeyError): + with suppress(FileNotFoundError, IsADirectoryError, KeyError, + NotADirectoryError, PermissionError): return self._path.joinpath(filename).read_text(encoding='utf-8') read_text.__doc__ = Distribution.read_text.__doc__ diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py index b70f9440f6973a..844ed26c3ec79f 100644 --- a/Lib/test/test_importlib/test_main.py +++ b/Lib/test/test_importlib/test_main.py @@ -156,3 +156,11 @@ def test_package_discovery(self): dist.metadata['Name'] == 'distinfo-pkg' for dist in dists ) + + +class DirectoryTest(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): + def test(self): + # make an `EGG-INFO` directory that's unrelated + self.site_dir.joinpath('EGG-INFO').mkdir() + # used to crash with `IsADirectoryError` + self.assertIsNone(version('unknown-package')) From a16387ab2d85f19665920bb6ff91a7e57f59dd2a Mon Sep 17 00:00:00 2001 From: Ying Wang Date: Wed, 29 May 2019 23:25:31 -0400 Subject: [PATCH 188/441] bpo-24564: shutil.copystat(): ignore EINVAL on os.setxattr() (GH-13369) --- Lib/shutil.py | 5 +++-- .../next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst diff --git a/Lib/shutil.py b/Lib/shutil.py index b2e8f5fd759bc6..2dfae87c9ce964 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -309,7 +309,7 @@ def _copyxattr(src, dst, *, follow_symlinks=True): try: names = os.listxattr(src, follow_symlinks=follow_symlinks) except OSError as e: - if e.errno not in (errno.ENOTSUP, errno.ENODATA): + if e.errno not in (errno.ENOTSUP, errno.ENODATA, errno.EINVAL): raise return for name in names: @@ -317,7 +317,8 @@ def _copyxattr(src, dst, *, follow_symlinks=True): value = os.getxattr(src, name, follow_symlinks=follow_symlinks) os.setxattr(dst, name, value, follow_symlinks=follow_symlinks) except OSError as e: - if e.errno not in (errno.EPERM, errno.ENOTSUP, errno.ENODATA): + if e.errno not in (errno.EPERM, errno.ENOTSUP, errno.ENODATA, + errno.EINVAL): raise else: def _copyxattr(*args, **kwargs): diff --git a/Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst b/Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst new file mode 100644 index 00000000000000..27cb6178b54e46 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst @@ -0,0 +1,3 @@ +:func:`shutil.copystat` now ignores :const:`errno.EINVAL` on :func:`os.setxattr` which may occur when copying files on filesystems without extended attributes support. + +Original patch by Giampaolo Rodola, updated by Ying Wang. From 413d955f8ec88a7183f91d7ad8b0ff7def803de3 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Thu, 30 May 2019 14:05:41 +0800 Subject: [PATCH 189/441] bpo-36610: shutil.copyfile(): use sendfile() on Linux only (GH-13675) ...and avoid using it on Solaris as it can raise EINVAL if offset is equal or bigger than the size of the file --- Doc/library/shutil.rst | 3 +-- Doc/whatsnew/3.8.rst | 2 +- Lib/shutil.py | 12 ++++++------ Lib/test/test_shutil.py | 6 +++--- Misc/NEWS.d/3.8.0a1.rst | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 4af5a16806088d..dcb2a16cff98cb 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -420,8 +420,7 @@ the use of userspace buffers in Python as in "``outfd.write(infd.read())``". On macOS `fcopyfile`_ is used to copy the file content (not metadata). -On Linux, Solaris and other POSIX platforms where :func:`os.sendfile` supports -copies between 2 regular file descriptors :func:`os.sendfile` is used. +On Linux :func:`os.sendfile` is used. On Windows :func:`shutil.copyfile` uses a bigger default buffer size (1 MiB instead of 64 KiB) and a :func:`memoryview`-based variant of diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 5ee9cf07ebaf11..98f0c3474f26ed 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -772,7 +772,7 @@ Optimizations * :func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, :func:`shutil.copytree` and :func:`shutil.move` use platform-specific - "fast-copy" syscalls on Linux, macOS and Solaris in order to copy the file + "fast-copy" syscalls on Linux and macOS in order to copy the file more efficiently. "fast-copy" means that the copying operation occurs within the kernel, avoiding the use of userspace buffers in Python as in diff --git a/Lib/shutil.py b/Lib/shutil.py index 2dfae87c9ce964..dae916b41605c6 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -50,7 +50,7 @@ import nt COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024 -_HAS_SENDFILE = posix and hasattr(os, "sendfile") +_USE_CP_SENDFILE = hasattr(os, "sendfile") and sys.platform.startswith("linux") _HAS_FCOPYFILE = posix and hasattr(posix, "_fcopyfile") # macOS __all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", @@ -111,7 +111,7 @@ def _fastcopy_fcopyfile(fsrc, fdst, flags): def _fastcopy_sendfile(fsrc, fdst): """Copy data from one regular mmap-like fd to another by using high-performance sendfile(2) syscall. - This should work on Linux >= 2.6.33 and Solaris only. + This should work on Linux >= 2.6.33 only. """ # Note: copyfileobj() is left alone in order to not introduce any # unexpected breakage. Possible risks by using zero-copy calls @@ -122,7 +122,7 @@ def _fastcopy_sendfile(fsrc, fdst): # GzipFile (which decompresses data), HTTPResponse (which decodes # chunks). # - possibly others (e.g. encrypted fs/partition?) - global _HAS_SENDFILE + global _USE_CP_SENDFILE try: infd = fsrc.fileno() outfd = fdst.fileno() @@ -152,7 +152,7 @@ def _fastcopy_sendfile(fsrc, fdst): # sendfile() on this platform (probably Linux < 2.6.33) # does not support copies between regular files (only # sockets). - _HAS_SENDFILE = False + _USE_CP_SENDFILE = False raise _GiveupOnFastCopy(err) if err.errno == errno.ENOSPC: # filesystem is full @@ -260,8 +260,8 @@ def copyfile(src, dst, *, follow_symlinks=True): return dst except _GiveupOnFastCopy: pass - # Linux / Solaris - elif _HAS_SENDFILE: + # Linux + elif _USE_CP_SENDFILE: try: _fastcopy_sendfile(fsrc, fdst) return dst diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index eeebb97ff6921c..208718bb128105 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -2315,7 +2315,7 @@ def test_file2file_not_supported(self): # Emulate a case where sendfile() only support file->socket # fds. In such a case copyfile() is supposed to skip the # fast-copy attempt from then on. - assert shutil._HAS_SENDFILE + assert shutil._USE_CP_SENDFILE try: with unittest.mock.patch( self.PATCHPOINT, @@ -2324,13 +2324,13 @@ def test_file2file_not_supported(self): with self.assertRaises(_GiveupOnFastCopy): shutil._fastcopy_sendfile(src, dst) assert m.called - assert not shutil._HAS_SENDFILE + assert not shutil._USE_CP_SENDFILE with unittest.mock.patch(self.PATCHPOINT) as m: shutil.copyfile(TESTFN, TESTFN2) assert not m.called finally: - shutil._HAS_SENDFILE = True + shutil._USE_CP_SENDFILE = True @unittest.skipIf(not MACOS, 'macOS only') diff --git a/Misc/NEWS.d/3.8.0a1.rst b/Misc/NEWS.d/3.8.0a1.rst index 3d5e6336246e40..f4b0a048330004 100644 --- a/Misc/NEWS.d/3.8.0a1.rst +++ b/Misc/NEWS.d/3.8.0a1.rst @@ -4450,7 +4450,7 @@ data_received() being called before connection_made(). :func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, :func:`shutil.copytree` and :func:`shutil.move` use platform-specific -fast-copy syscalls on Linux, Solaris and macOS in order to copy the file +fast-copy syscalls on Linux and macOS in order to copy the file more efficiently. On Windows :func:`shutil.copyfile` uses a bigger default buffer size (1 MiB instead of 16 KiB) and a :func:`memoryview`-based variant of :func:`shutil.copyfileobj` is used. The speedup for copying a 512MiB file From bee31ce775ec70013d360b353572bd1a01d78e67 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Thu, 30 May 2019 16:35:41 +0900 Subject: [PATCH 190/441] autoreconf (GH-13651) --- configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index cc18322d7514c3..cacf9fc4189441 100755 --- a/configure +++ b/configure @@ -11483,9 +11483,9 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getpwnam_r getpwuid_r getspnam getspent getsid getwd \ if_nameindex \ - initgroups kill killpg lchmod lchown lockf linkat lstat lutimes madvise mmap \ + initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mmap \ memrchr mbrtowc mkdirat mkfifo \ - mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ + madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \ pthread_condattr_setclock pthread_init pthread_kill putenv pwrite pwritev pwritev2 \ readlink readlinkat readv realpath renameat \ From eda385c0dca62f97a8ae80feb57c2a51df3c807f Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 30 May 2019 01:58:50 -0600 Subject: [PATCH 191/441] bpo-36935: Remove usage of the deprecated PyErr_SetFromWindowsErrWithUnicodeFilename() (GH-13355) In e895de3e7f3cc2f7213b87621cfe9812ea4343f0, the deprecated function PyErr_SetFromWindowsErrWithUnicodeFilename() was added in two functions in Modules/_winapi.c. This function was deprecated in 3.3. --- Modules/_winapi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 1317fc9a172c0d..e9dcec6590b6ce 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -508,7 +508,9 @@ _winapi_CreateFileMapping_impl(PyObject *module, HANDLE file_handle, Py_END_ALLOW_THREADS if (handle == NULL) { - PyErr_SetFromWindowsErrWithUnicodeFilename(0, name); + PyObject *temp = PyUnicode_FromWideChar(name, -1); + PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp); + Py_XDECREF(temp); handle = INVALID_HANDLE_VALUE; } @@ -1405,7 +1407,9 @@ _winapi_OpenFileMapping_impl(PyObject *module, DWORD desired_access, Py_END_ALLOW_THREADS if (handle == NULL) { - PyErr_SetFromWindowsErrWithUnicodeFilename(0, name); + PyObject *temp = PyUnicode_FromWideChar(name, -1); + PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, temp); + Py_XDECREF(temp); handle = INVALID_HANDLE_VALUE; } From 6eb814b8ce9a4fed8773a65501fb96aad8b3ecf2 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Thu, 30 May 2019 11:27:06 +0200 Subject: [PATCH 192/441] bpo-37098: Skip memfd_create test before Linux 3.17 (GH-13677) --- Lib/test/test_os.py | 1 + Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst | 1 + 2 files changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 820c99c7a07cb4..f17a19a7585d02 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3123,6 +3123,7 @@ def test_stty_match(self): @unittest.skipUnless(hasattr(os, 'memfd_create'), 'requires os.memfd_create') +@support.requires_linux_version(3, 17) class MemfdCreateTests(unittest.TestCase): def test_memfd_create(self): fd = os.memfd_create("Hi", os.MFD_CLOEXEC) diff --git a/Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst b/Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst new file mode 100644 index 00000000000000..84e06e71869f68 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst @@ -0,0 +1 @@ +Fix test_memfd_create on older Linux Kernels. From 0f39c2b1919727904f4fac2d79cb41dc6bfe41fe Mon Sep 17 00:00:00 2001 From: Xtreak Date: Thu, 30 May 2019 15:30:29 +0530 Subject: [PATCH 193/441] bpo-37015: Ensure tasks created by _accept_connection2 due to AsyncMock are completed (GH-13661) From 3.8 async functions used with mock.patch return an `AsyncMock`. `_accept_connection2` is an async function where create_task is also mocked. Don't mock `create_task` so that tasks are created out of coroutine returned by `AsyncMock` and the tasks are completed. https://bugs.python.org/issue37015 --- Lib/test/test_asyncio/test_selector_events.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 2e52e9df5c3b6e..68b7853b2eba24 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -363,14 +363,16 @@ def test_accept_connection_multiple(self): sock.accept.return_value = (mock.Mock(), mock.Mock()) backlog = 100 # Mock the coroutine generation for a connection to prevent - # warnings related to un-awaited coroutines. + # warnings related to un-awaited coroutines. _accept_connection2 + # is an async function that is patched with AsyncMock. create_task + # creates a task out of coroutine returned by AsyncMock, so use + # asyncio.sleep(0) to ensure created tasks are complete to avoid + # task pending warnings. mock_obj = mock.patch.object with mock_obj(self.loop, '_accept_connection2') as accept2_mock: - accept2_mock.return_value = None - with mock_obj(self.loop, 'create_task') as task_mock: - task_mock.return_value = None - self.loop._accept_connection( - mock.Mock(), sock, backlog=backlog) + self.loop._accept_connection( + mock.Mock(), sock, backlog=backlog) + self.loop.run_until_complete(asyncio.sleep(0)) self.assertEqual(sock.accept.call_count, backlog) From 735e8afa9ee942367b5d0807633a2b9f662cbdbf Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 30 May 2019 12:43:19 +0200 Subject: [PATCH 194/441] bpo-36974: inherit the vectorcall protocol (GH-13498) --- Lib/test/test_capi.py | 27 +++++++++++++++- Modules/_testcapimodule.c | 68 ++++++++++++++++++++++++++++++++++++++- Objects/typeobject.c | 11 +++++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 0813abb9a69722..795aa78d886676 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -27,6 +27,7 @@ # Were we compiled --with-pydebug or with #define Py_DEBUG? Py_DEBUG = hasattr(sys, 'gettotalrefcount') +Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11 Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17 @@ -484,6 +485,27 @@ class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): pass self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + def test_vectorcall_flag(self): + self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + + # Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + pass + self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + + def test_vectorcall_override(self): + # Check that tp_call can correctly override vectorcall. + # MethodDescriptorNopGet implements tp_call but it inherits from + # MethodDescriptorBase, which implements vectorcall. Since + # MethodDescriptorNopGet returns the args tuple when called, we check + # additionally that no new tuple is created for this call. + args = tuple(range(5)) + f = _testcapi.MethodDescriptorNopGet() + self.assertIs(f(*args), args) + def test_vectorcall(self): # Test a bunch of different ways to call objects: # 1. normal call @@ -498,7 +520,10 @@ def test_vectorcall(self): ([].append, (0,), {}, None), (sum, ([36],), {"start":6}, 42), (testfunction, (42,), {}, 42), - (testfunction_kw, (42,), {"kw":None}, 42)] + (testfunction_kw, (42,), {"kw":None}, 42), + (_testcapi.MethodDescriptorBase(), (0,), {}, True), + (_testcapi.MethodDescriptorDerived(), (0,), {}, True), + (_testcapi.MethodDescriptor2(), (0,), {}, False)] from _testcapi import pyobject_vectorcall, pyvectorcall_call from types import MethodType diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index f2f418c997ab59..a7451c66359d81 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5814,6 +5814,29 @@ static PyTypeObject Generic_Type = { /* Test PEP 590 */ +typedef struct { + PyObject_HEAD + vectorcallfunc vectorcall; +} MethodDescriptorObject; + +static PyObject * +MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + /* True if using the vectorcall function in MethodDescriptorObject + * but False for MethodDescriptor2Object */ + MethodDescriptorObject *md = (MethodDescriptorObject *)callable; + return PyBool_FromLong(md->vectorcall != NULL); +} + +static PyObject * +MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + MethodDescriptorObject *op = PyObject_New(MethodDescriptorObject, type); + op->vectorcall = MethodDescriptor_vectorcall; + return (PyObject *)op; +} + static PyObject * func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { @@ -5831,10 +5854,22 @@ nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) return func; } +static PyObject * +call_return_args(PyObject *self, PyObject *args, PyObject *kwargs) +{ + Py_INCREF(args); + return args; +} + static PyTypeObject MethodDescriptorBase_Type = { PyVarObject_HEAD_INIT(NULL, 0) "MethodDescriptorBase", - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_METHOD_DESCRIPTOR, + sizeof(MethodDescriptorObject), + .tp_new = MethodDescriptor_new, + .tp_call = PyVectorcall_Call, + .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_METHOD_DESCRIPTOR | _Py_TPFLAGS_HAVE_VECTORCALL, .tp_descr_get = func_descr_get, }; @@ -5848,9 +5883,34 @@ static PyTypeObject MethodDescriptorNopGet_Type = { PyVarObject_HEAD_INIT(NULL, 0) "MethodDescriptorNopGet", .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_call = call_return_args, .tp_descr_get = nop_descr_get, }; +typedef struct { + MethodDescriptorObject base; + vectorcallfunc vectorcall; +} MethodDescriptor2Object; + +static PyObject * +MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type); + op->base.vectorcall = NULL; + op->vectorcall = MethodDescriptor_vectorcall; + return (PyObject *)op; +} + +static PyTypeObject MethodDescriptor2_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptor2", + sizeof(MethodDescriptor2Object), + .tp_new = MethodDescriptor2_new, + .tp_call = PyVectorcall_Call, + .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_HAVE_VECTORCALL, +}; + static struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, @@ -5916,6 +5976,12 @@ PyInit__testcapi(void) Py_INCREF(&MethodDescriptorNopGet_Type); PyModule_AddObject(m, "MethodDescriptorNopGet", (PyObject *)&MethodDescriptorNopGet_Type); + MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptor2_Type) < 0) + return NULL; + Py_INCREF(&MethodDescriptor2_Type); + PyModule_AddObject(m, "MethodDescriptor2", (PyObject *)&MethodDescriptor2_Type); + if (PyType_Ready(&GenericAlias_Type) < 0) return NULL; Py_INCREF(&GenericAlias_Type); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 071ff27d532397..ac5a68681d15d0 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5147,6 +5147,17 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) COPYSLOT(tp_repr); /* tp_hash see tp_richcompare */ COPYSLOT(tp_call); + /* Inherit tp_vectorcall_offset and _Py_TPFLAGS_HAVE_VECTORCALL if tp_call + * was inherited, but only for extension types */ + if ((base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && + !(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && + !(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && + base->tp_call && + type->tp_call == base->tp_call) + { + type->tp_vectorcall_offset = base->tp_vectorcall_offset; + type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; + } COPYSLOT(tp_str); { /* Copy comparison-related slots only when From c145f3bfbe80d498d40848450d4d33c14e2cf782 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 30 May 2019 12:43:59 +0200 Subject: [PATCH 195/441] bpo-36974: remove _PyObject_HasFastCall (GH-13460) --- Include/cpython/abstract.h | 4 ---- Modules/_functoolsmodule.c | 4 ++-- Objects/call.c | 16 ---------------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 7099178f82087d..7ab2045923d83d 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -55,10 +55,6 @@ PyAPI_FUNC(int) _PyStack_UnpackDict( 40 bytes on the stack. */ #define _PY_FASTCALL_SMALL_STACK 5 -/* Return 1 if callable supports FASTCALL calling convention for positional - arguments: see _PyObject_Vectorcall() and _PyObject_FastCallDict() */ -PyAPI_FUNC(int) _PyObject_HasFastCall(PyObject *callable); - PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where); diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 13f2db939bb78a..213fb3ea336c5a 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -107,7 +107,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) return NULL; } - pto->use_fastcall = _PyObject_HasFastCall(func); + pto->use_fastcall = (_PyVectorcall_Function(func) != NULL); return (PyObject *)pto; } @@ -365,7 +365,7 @@ partial_setstate(partialobject *pto, PyObject *state) Py_INCREF(dict); Py_INCREF(fn); - pto->use_fastcall = _PyObject_HasFastCall(fn); + pto->use_fastcall = (_PyVectorcall_Function(fn) != NULL); Py_SETREF(pto->fn, fn); Py_SETREF(pto->args, fnargs); Py_SETREF(pto->kw, kw); diff --git a/Objects/call.c b/Objects/call.c index 183a5c2e5a24ff..55dfc520f1deb1 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -9,22 +9,6 @@ static PyObject * cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs); -int -_PyObject_HasFastCall(PyObject *callable) -{ - if (PyFunction_Check(callable)) { - return 1; - } - else if (PyCFunction_Check(callable)) { - return !(PyCFunction_GET_FLAGS(callable) & METH_VARARGS); - } - else { - assert (PyCallable_Check(callable)); - return 0; - } -} - - static PyObject * null_error(void) { From 249b7d59d8038f9017fc95dc28a3ce3494aaf832 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 30 May 2019 05:08:24 -0600 Subject: [PATCH 196/441] bpo-20602: Do not clear sys.flags and sys.float_info during shutdown (GH-8096) There is no need to clear these immutable objects during shutdown. --- Lib/test/test_sys.py | 16 ++++++++++++++++ .../2018-07-04-16-57-59.bpo-20602.sDLElw.rst | 2 ++ Python/import.c | 2 -- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index c558d116e6fe9d..49f2722d95140e 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -822,6 +822,22 @@ def __del__(self): rc, stdout, stderr = assert_python_ok('-c', code) self.assertEqual(stdout.rstrip(), b'True') + @test.support.requires_type_collecting + def test_issue20602(self): + # sys.flags and sys.float_info were wiped during shutdown. + code = """if 1: + import sys + class A: + def __del__(self, sys=sys): + print(sys.flags) + print(sys.float_info) + a = A() + """ + rc, out, err = assert_python_ok('-c', code) + out = out.splitlines() + self.assertIn(b'sys.flags', out[0]) + self.assertIn(b'sys.float_info', out[1]) + @unittest.skipUnless(hasattr(sys, 'getandroidapilevel'), 'need sys.getandroidapilevel()') def test_getandroidapilevel(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst new file mode 100644 index 00000000000000..ab37a020d8036f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst @@ -0,0 +1,2 @@ +Do not clear :data:`sys.flags` and :data:`sys.float_info` during shutdown. +Patch by Zackery Spytz. diff --git a/Python/import.c b/Python/import.c index 41a5c01cadf3ad..ab7db6bc17f6b1 100644 --- a/Python/import.c +++ b/Python/import.c @@ -383,8 +383,6 @@ static const char * const sys_deletes[] = { "last_type", "last_value", "last_traceback", "path_hooks", "path_importer_cache", "meta_path", "__interactivehook__", - /* misc stuff */ - "flags", "float_info", NULL }; From 6d0b7470a4738a403ef48cfd50d9447e0f32f00c Mon Sep 17 00:00:00 2001 From: Xtreak Date: Thu, 30 May 2019 17:31:39 +0530 Subject: [PATCH 197/441] bpo-37099: Silence DeprecationWarning in test_inspect (GH-13679) Fix DeprecationWarning introduced in aee19f54f6fe45f6b3c906987941e5a8af4468e9 https://bugs.python.org/issue37099 --- Lib/test/test_inspect.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index b3aae3a18ecfae..83a5f7ec1f5385 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -750,14 +750,16 @@ class D(B, C): pass def assertArgSpecEquals(self, routine, args_e, varargs_e=None, varkw_e=None, defaults_e=None, formatted=None): - args, varargs, varkw, defaults = inspect.getargspec(routine) + with self.assertWarns(DeprecationWarning): + args, varargs, varkw, defaults = inspect.getargspec(routine) self.assertEqual(args, args_e) self.assertEqual(varargs, varargs_e) self.assertEqual(varkw, varkw_e) self.assertEqual(defaults, defaults_e) if formatted is not None: - self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults), - formatted) + with self.assertWarns(DeprecationWarning): + self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults), + formatted) def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None, varkw_e=None, defaults_e=None, @@ -774,9 +776,10 @@ def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None, self.assertEqual(kwonlydefaults, kwonlydefaults_e) self.assertEqual(ann, ann_e) if formatted is not None: - self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults, - kwonlyargs, kwonlydefaults, ann), - formatted) + with self.assertWarns(DeprecationWarning): + self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults, + kwonlyargs, kwonlydefaults, ann), + formatted) def test_getargspec(self): self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)') From 37788bc23f6f1ed0362b9b3b248daf296c024849 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 30 May 2019 15:11:22 +0200 Subject: [PATCH 198/441] bpo-36974: rename _FastCallKeywords -> _Vectorcall (GH-13653) --- Include/descrobject.h | 2 +- Include/funcobject.h | 2 +- Include/methodobject.h | 2 +- Objects/call.c | 10 +++++----- Objects/descrobject.c | 8 ++++---- Objects/funcobject.c | 2 +- Objects/methodobject.c | 2 +- Python/ceval.c | 8 ++++---- Tools/gdb/libpython.py | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Include/descrobject.h b/Include/descrobject.h index 3db09635399cc2..d7114852c1e210 100644 --- a/Include/descrobject.h +++ b/Include/descrobject.h @@ -92,7 +92,7 @@ PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, struct PyGetSetDef *); #ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyMethodDescr_FastCallKeywords( +PyAPI_FUNC(PyObject *) _PyMethodDescr_Vectorcall( PyObject *descrobj, PyObject *const *args, size_t nargsf, PyObject *kwnames); PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); diff --git a/Include/funcobject.h b/Include/funcobject.h index 7ba000e1f13cc2..e563a74a15b6e1 100644 --- a/Include/funcobject.h +++ b/Include/funcobject.h @@ -66,7 +66,7 @@ PyAPI_FUNC(PyObject *) _PyFunction_FastCallDict( Py_ssize_t nargs, PyObject *kwargs); -PyAPI_FUNC(PyObject *) _PyFunction_FastCallKeywords( +PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( PyObject *func, PyObject *const *stack, size_t nargsf, diff --git a/Include/methodobject.h b/Include/methodobject.h index 5dbe2145dadc39..e92adde7bf6bd7 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -47,7 +47,7 @@ PyAPI_FUNC(PyObject *) _PyCFunction_FastCallDict(PyObject *func, Py_ssize_t nargs, PyObject *kwargs); -PyAPI_FUNC(PyObject *) _PyCFunction_FastCallKeywords(PyObject *func, +PyAPI_FUNC(PyObject *) _PyCFunction_Vectorcall(PyObject *func, PyObject *const *stack, size_t nargsf, PyObject *kwnames); diff --git a/Objects/call.c b/Objects/call.c index 55dfc520f1deb1..acd1f26dcbb576 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -374,8 +374,8 @@ _PyFunction_FastCallDict(PyObject *func, PyObject *const *args, Py_ssize_t nargs PyObject * -_PyFunction_FastCallKeywords(PyObject *func, PyObject* const* stack, - size_t nargsf, PyObject *kwnames) +_PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, + size_t nargsf, PyObject *kwnames) { PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); PyObject *globals = PyFunction_GET_GLOBALS(func); @@ -714,9 +714,9 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject * -_PyCFunction_FastCallKeywords(PyObject *func, - PyObject *const *args, size_t nargsf, - PyObject *kwnames) +_PyCFunction_Vectorcall(PyObject *func, + PyObject *const *args, size_t nargsf, + PyObject *kwnames) { PyObject *result; diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 759018503c65e0..3aaeaa6e890fdf 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -264,9 +264,9 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) // same to methoddescr_call(), but use FASTCALL convention. PyObject * -_PyMethodDescr_FastCallKeywords(PyObject *descrobj, - PyObject *const *args, size_t nargsf, - PyObject *kwnames) +_PyMethodDescr_Vectorcall(PyObject *descrobj, + PyObject *const *args, size_t nargsf, + PyObject *kwnames) { assert(Py_TYPE(descrobj) == &PyMethodDescr_Type); PyMethodDescrObject *descr = (PyMethodDescrObject *)descrobj; @@ -756,7 +756,7 @@ PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) type, method->ml_name); if (descr != NULL) { descr->d_method = method; - descr->vectorcall = &_PyMethodDescr_FastCallKeywords; + descr->vectorcall = _PyMethodDescr_Vectorcall; } return (PyObject *)descr; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 2b1f42db746dbc..6f5b5d223d9be0 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -36,7 +36,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname op->func_defaults = NULL; /* No default arguments */ op->func_kwdefaults = NULL; /* No keyword only defaults */ op->func_closure = NULL; - op->vectorcall = _PyFunction_FastCallKeywords; + op->vectorcall = _PyFunction_Vectorcall; consts = ((PyCodeObject *)code)->co_consts; if (PyTuple_Size(consts) >= 1) { diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 76497c93894a89..544baee09113ab 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -52,7 +52,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) op->vectorcall = NULL; } else { - op->vectorcall = &_PyCFunction_FastCallKeywords; + op->vectorcall = _PyCFunction_Vectorcall; } _PyObject_GC_TRACK(op); return (PyObject *)op; diff --git a/Python/ceval.c b/Python/ceval.c index 47baa4d03ed9cc..71e6eb8ebcfd3e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4815,7 +4815,7 @@ trace_call_function(PyThreadState *tstate, { PyObject *x; if (PyCFunction_Check(func)) { - C_TRACE(x, _PyCFunction_FastCallKeywords(func, args, nargs, kwnames)); + C_TRACE(x, _PyCFunction_Vectorcall(func, args, nargs, kwnames)); return x; } else if (Py_TYPE(func) == &PyMethodDescr_Type && nargs > 0) { @@ -4831,9 +4831,9 @@ trace_call_function(PyThreadState *tstate, if (func == NULL) { return NULL; } - C_TRACE(x, _PyCFunction_FastCallKeywords(func, - args+1, nargs-1, - kwnames)); + C_TRACE(x, _PyCFunction_Vectorcall(func, + args+1, nargs-1, + kwnames)); Py_DECREF(func); return x; } diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index d49546fa9c46db..93f720ab7e2a10 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1564,7 +1564,7 @@ def is_other_python_frame(self): return False if caller in ('_PyCFunction_FastCallDict', - '_PyCFunction_FastCallKeywords', + '_PyCFunction_Vectorcall', 'cfunction_call_varargs'): arg_name = 'func' # Within that frame: From 25ee0c3bf10820496448e2886069f9c2794be7ac Mon Sep 17 00:00:00 2001 From: Brett Cannon <54418+brettcannon@users.noreply.github.com> Date: Thu, 30 May 2019 07:59:01 -0700 Subject: [PATCH 199/441] Revert adding @maxking to CODEOWNERS file (GH-13660) This reverts commit 71dc7c5fbd856df83202f39c1f41ccd07c6eceb7. Turns out you must have write access for CODEOWNERS to work. --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6a4ca54dd34e16..963ab4dcff425b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -44,7 +44,7 @@ Objects/dict* @methane Python/bootstrap_hash.c @python/crypto-team @tiran # Email and related -**/*mail* @python/email-team @maxking +**/*mail* @python/email-team **/*smtp* @python/email-team **/*mime* @python/email-team **/*imap* @python/email-team From 98ef92002ec289bf8086b0ef3d4f96c2589f4e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Thu, 30 May 2019 18:30:09 +0300 Subject: [PATCH 200/441] bpo-36999: Add asyncio.Task.get_coro() (GH-13680) https://bugs.python.org/issue36999 --- Doc/library/asyncio-task.rst | 6 ++++++ Lib/asyncio/tasks.py | 3 +++ Lib/test/test_asyncio/test_tasks.py | 10 ++++++++++ .../2019-05-30-13-30-46.bpo-36999.EjY_L2.rst | 2 ++ Modules/_asynciomodule.c | 13 +++++++++++++ Modules/clinic/_asynciomodule.c.h | 19 ++++++++++++++++++- 6 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index d94fa587cd3a47..1fcdcb985d8842 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -842,6 +842,12 @@ Task Object The *file* argument is an I/O stream to which the output is written; by default output is written to :data:`sys.stderr`. + .. method:: get_coro() + + Return the coroutine object wrapped by the :class:`Task`. + + .. versionadded:: 3.8 + .. method:: get_name() Return the name of the Task. diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 78e76003b3ac22..95e85600a2e802 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -152,6 +152,9 @@ def __del__(self): def _repr_info(self): return base_tasks._task_repr_info(self) + def get_coro(self): + return self._coro + def get_name(self): return self._name diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 114dd76687cd70..74ce25908a3308 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2425,6 +2425,16 @@ async def main(): self.assertEqual(cvar.get(), -1) + def test_get_coro(self): + loop = asyncio.new_event_loop() + coro = coroutine_function() + try: + task = self.new_task(loop, coro) + loop.run_until_complete(task) + self.assertIs(task.get_coro(), coro) + finally: + loop.close() + def add_subclass_tests(cls): BaseTask = cls.Task diff --git a/Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst b/Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst new file mode 100644 index 00000000000000..5c897fb4dbc745 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst @@ -0,0 +1,2 @@ +Add the ``asyncio.Task.get_coro()`` method to publicly expose the tasks's +coroutine object. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index d8b631b7c7a292..281161b68611ae 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2313,6 +2313,18 @@ _asyncio_Task_set_exception(TaskObj *self, PyObject *exception) return NULL; } +/*[clinic input] +_asyncio.Task.get_coro +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_get_coro_impl(TaskObj *self) +/*[clinic end generated code: output=bcac27c8cc6c8073 input=d2e8606c42a7b403]*/ +{ + Py_INCREF(self->task_coro); + return self->task_coro; +} + /*[clinic input] _asyncio.Task.get_name [clinic start generated code]*/ @@ -2439,6 +2451,7 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK__REPR_INFO_METHODDEF _ASYNCIO_TASK_GET_NAME_METHODDEF _ASYNCIO_TASK_SET_NAME_METHODDEF + _ASYNCIO_TASK_GET_CORO_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index 87669f7c9f32eb..b9daee6aae965b 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -569,6 +569,23 @@ PyDoc_STRVAR(_asyncio_Task_set_exception__doc__, #define _ASYNCIO_TASK_SET_EXCEPTION_METHODDEF \ {"set_exception", (PyCFunction)_asyncio_Task_set_exception, METH_O, _asyncio_Task_set_exception__doc__}, +PyDoc_STRVAR(_asyncio_Task_get_coro__doc__, +"get_coro($self, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK_GET_CORO_METHODDEF \ + {"get_coro", (PyCFunction)_asyncio_Task_get_coro, METH_NOARGS, _asyncio_Task_get_coro__doc__}, + +static PyObject * +_asyncio_Task_get_coro_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_get_coro(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_get_coro_impl(self); +} + PyDoc_STRVAR(_asyncio_Task_get_name__doc__, "get_name($self, /)\n" "--\n" @@ -815,4 +832,4 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=e3b02d96da56e80c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=51c50219f6a0863a input=a9049054013a1b77]*/ From 1b69c09248c4b51962933e3551f1ae6fc11369b6 Mon Sep 17 00:00:00 2001 From: Xtreak Date: Thu, 30 May 2019 23:28:28 +0530 Subject: [PATCH 201/441] Fix audit event typo : urllib.request -> urllib.Request (GH-13550) As per the PEP and the [audit event raised](https://github.com/python/cpython/blob/13d4e6a4a090031f8214e058ed3c8fd47767e05f/Lib/urllib/request.py#L524) in urllib.request this should be `urllib.Request` cc: @zooba --- Doc/library/urllib.request.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 1895ae74b4f5de..a53c969ec629a5 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -95,10 +95,10 @@ The :mod:`urllib.request` module defines the following functions: parameter to ``urllib.urlopen``, can be obtained by using :class:`ProxyHandler` objects. - .. audit-event:: urllib.request "fullurl data headers method" + .. audit-event:: urllib.Request "fullurl data headers method" The default opener raises an :func:`auditing event ` - ``urllib.request`` with arguments ``fullurl``, ``data``, ``headers``, + ``urllib.Request`` with arguments ``fullurl``, ``data``, ``headers``, ``method`` taken from the request object. .. versionchanged:: 3.2 From 1e36f75d634383eb243aa1798c0f2405c9ceb5d4 Mon Sep 17 00:00:00 2001 From: Andrew Carr Date: Thu, 30 May 2019 13:31:51 -0600 Subject: [PATCH 202/441] bpo-5028: fix doc bug for tokenize (GH-11683) https://bugs.python.org/issue5028 --- Doc/library/tokenize.rst | 2 +- Lib/lib2to3/pgen2/tokenize.py | 2 +- Lib/tokenize.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index 111289c767f35c..c89d3d4b082f5e 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -39,7 +39,7 @@ The primary entry point is a :term:`generator`: column where the token begins in the source; a 2-tuple ``(erow, ecol)`` of ints specifying the row and column where the token ends in the source; and the line on which the token was found. The line passed (the last tuple item) - is the *logical* line; continuation lines are included. The 5 tuple is + is the *physical* line; continuation lines are included. The 5 tuple is returned as a :term:`named tuple` with the field names: ``type string start end line``. diff --git a/Lib/lib2to3/pgen2/tokenize.py b/Lib/lib2to3/pgen2/tokenize.py index 279d322971da99..0f9fde3fb0d5f6 100644 --- a/Lib/lib2to3/pgen2/tokenize.py +++ b/Lib/lib2to3/pgen2/tokenize.py @@ -346,7 +346,7 @@ def generate_tokens(readline): column where the token begins in the source; a 2-tuple (erow, ecol) of ints specifying the row and column where the token ends in the source; and the line on which the token was found. The line passed is the - logical line; continuation lines are included. + physical line; continuation lines are included. """ lnum = parenlev = continued = 0 contstr, needcont = '', 0 diff --git a/Lib/tokenize.py b/Lib/tokenize.py index 0f9d5dd554d530..738fb71d188b47 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -415,7 +415,7 @@ def tokenize(readline): column where the token begins in the source; a 2-tuple (erow, ecol) of ints specifying the row and column where the token ends in the source; and the line on which the token was found. The line passed is the - logical line; continuation lines are included. + physical line; continuation lines are included. The first token sequence will always be an ENCODING token which tells you which encoding was used to decode the bytes stream. From 2f5b9dcc0a89cbde1499c76df81c36bfd5ef9aa8 Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Thu, 30 May 2019 23:19:29 +0300 Subject: [PATCH 203/441] bpo-30969: Fix docs about the comparison in absence of __contains__ (GH-2761) --- Doc/reference/expressions.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 52b41929d7bc7c..8b7110615240ee 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1563,14 +1563,15 @@ y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and ``False`` otherwise. For user-defined classes which do not define :meth:`__contains__` but do define -:meth:`__iter__`, ``x in y`` is ``True`` if some value ``z`` with ``x == z`` is -produced while iterating over ``y``. If an exception is raised during the -iteration, it is as if :keyword:`in` raised that exception. +:meth:`__iter__`, ``x in y`` is ``True`` if some value ``z``, for which the +expression ``x is z or x == z`` is true, is produced while iterating over ``y``. +If an exception is raised during the iteration, it is as if :keyword:`in` raised +that exception. Lastly, the old-style iteration protocol is tried: if a class defines :meth:`__getitem__`, ``x in y`` is ``True`` if and only if there is a non-negative -integer index *i* such that ``x == y[i]``, and all lower integer indices do not -raise :exc:`IndexError` exception. (If any other exception is raised, it is as +integer index *i* such that ``x is y[i] or x == y[i]``, and no lower integer index +raises the :exc:`IndexError` exception. (If any other exception is raised, it is as if :keyword:`in` raised that exception). .. index:: From 5437ccca1424e415a938c583df43d8cc74047d16 Mon Sep 17 00:00:00 2001 From: xdegaye Date: Thu, 30 May 2019 23:42:29 +0200 Subject: [PATCH 204/441] bpo-36342: Fix test_multiprocessing in test_venv (GH-12513) when platform lacks a functioning sem_open implementation https://bugs.python.org/issue36342 --- Lib/test/test_venv.py | 7 ++++++- .../next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 6822d567e42b58..278c68699d8e60 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -14,7 +14,8 @@ import sys import tempfile from test.support import (captured_stdout, captured_stderr, requires_zlib, - can_symlink, EnvironmentVarGuard, rmtree) + can_symlink, EnvironmentVarGuard, rmtree, + import_module) import threading import unittest import venv @@ -315,6 +316,10 @@ def test_multiprocessing(self): """ Test that the multiprocessing is able to spawn. """ + # Issue bpo-36342: Instanciation of a Pool object imports the + # multiprocessing.synchronize module. Skip the test if this module + # cannot be imported. + import_module('multiprocessing.synchronize') rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) envpy = os.path.join(os.path.realpath(self.env_dir), diff --git a/Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst b/Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst new file mode 100644 index 00000000000000..a7c92980fd77ee --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst @@ -0,0 +1 @@ +Fix test_multiprocessing in test_venv if platform lacks functioning sem_open. From eea47e09394dfb64d3a59a601d947d25bb1bdc96 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 30 May 2019 14:45:48 -0700 Subject: [PATCH 205/441] bpo-36953: Delay removal of ABCs from collections. (GH-13409) Bump the removal to 3.9, indicate collections.abc available since 3.3, replace version-changed directive to deprecated-removed. https://bugs.python.org/issue36953 --- Doc/library/collections.rst | 4 ++-- Lib/collections/__init__.py | 4 ++-- .../next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index ae21db216fdebe..ec921d79d0c48b 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -33,10 +33,10 @@ Python's general purpose built-in containers, :class:`dict`, :class:`list`, :class:`UserString` wrapper around string objects for easier string subclassing ===================== ==================================================================== -.. versionchanged:: 3.3 +.. deprecated-removed:: 3.3 3.9 Moved :ref:`collections-abstract-base-classes` to the :mod:`collections.abc` module. For backwards compatibility, they continue to be visible in this module through - Python 3.7. Subsequently, they will be removed entirely. + Python 3.8. :class:`ChainMap` objects diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index cb7f1bb1fcfe41..5b740d84c27507 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -47,8 +47,8 @@ def __getattr__(name): obj = getattr(_collections_abc, name) import warnings warnings.warn("Using or importing the ABCs from 'collections' instead " - "of from 'collections.abc' is deprecated, " - "and in 3.8 it will stop working", + "of from 'collections.abc' is deprecated since Python 3.3," + "and in 3.9 it will stop working", DeprecationWarning, stacklevel=2) globals()[name] = obj return obj diff --git a/Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst b/Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst new file mode 100644 index 00000000000000..eeb4fd71e67bf5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst @@ -0,0 +1,5 @@ +Starting with Python 3.3, importing ABCs from :mod:`collections` is +deprecated, and import should be done from :mod:`collections.abc`. Still +being able to import from :mod:`collections` was marked for removal in 3.8, +but has been delayed to 3.9; documentation and ``DeprecationWarning`` +clarified. From 2a58b0636d1f620f8a85a2e4c030cc10551936a5 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 30 May 2019 15:06:32 -0700 Subject: [PATCH 206/441] bpo-5028: Fix up rest of documentation for tokenize documenting line (GH-13686) https://bugs.python.org/issue5028 --- Doc/library/tokenize.rst | 4 ++-- Lib/lib2to3/pgen2/tokenize.py | 2 +- Lib/tokenize.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index c89d3d4b082f5e..b208ba46d17d99 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -39,8 +39,8 @@ The primary entry point is a :term:`generator`: column where the token begins in the source; a 2-tuple ``(erow, ecol)`` of ints specifying the row and column where the token ends in the source; and the line on which the token was found. The line passed (the last tuple item) - is the *physical* line; continuation lines are included. The 5 tuple is - returned as a :term:`named tuple` with the field names: + is the *physical* line. The 5 tuple is returned as a :term:`named tuple` + with the field names: ``type string start end line``. The returned :term:`named tuple` has an additional property named diff --git a/Lib/lib2to3/pgen2/tokenize.py b/Lib/lib2to3/pgen2/tokenize.py index 0f9fde3fb0d5f6..7924ff3cd582fc 100644 --- a/Lib/lib2to3/pgen2/tokenize.py +++ b/Lib/lib2to3/pgen2/tokenize.py @@ -346,7 +346,7 @@ def generate_tokens(readline): column where the token begins in the source; a 2-tuple (erow, ecol) of ints specifying the row and column where the token ends in the source; and the line on which the token was found. The line passed is the - physical line; continuation lines are included. + physical line. """ lnum = parenlev = continued = 0 contstr, needcont = '', 0 diff --git a/Lib/tokenize.py b/Lib/tokenize.py index 738fb71d188b47..1aee21b5e18fa7 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -415,7 +415,7 @@ def tokenize(readline): column where the token begins in the source; a 2-tuple (erow, ecol) of ints specifying the row and column where the token ends in the source; and the line on which the token was found. The line passed is the - physical line; continuation lines are included. + physical line. The first token sequence will always be an ENCODING token which tells you which encoding was used to decode the bytes stream. From 4c23aff065fb28aba789a211937a2af974842110 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Fri, 31 May 2019 00:10:07 +0100 Subject: [PATCH 207/441] bpo-29262: Add get_origin() and get_args() introspection helpers to typing (GH-13685) This is an old feature request that appears from time to time. After a year of experimenting with various introspection capabilities in `typing_inspect` on PyPI, I propose to add these two most commonly used functions: `get_origin()` and `get_args()`. These are essentially thin public wrappers around private APIs: `__origin__` and `__args__`. As discussed in the issue and on the typing tracker, exposing some public helpers instead of `__origin__` and `__args__` directly will give us more flexibility if we will decide to update the internal representation, while still maintaining backwards compatibility. The implementation is very simple an is essentially a copy from `typing_inspect` with one exception: `ClassVar` was special-cased in `typing_inspect`, but I think this special-casing doesn't really help and only makes things more complicated. --- Doc/library/typing.rst | 19 +++++++++ Lib/test/test_typing.py | 37 ++++++++++++++++ Lib/typing.py | 42 +++++++++++++++++++ .../2019-05-30-21-25-14.bpo-29262.LdIzun.rst | 1 + 4 files changed, 99 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 709580ad2159df..2575a995817d73 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -1021,6 +1021,25 @@ The module defines the following classes, functions and decorators: a dictionary constructed by merging all the ``__annotations__`` along ``C.__mro__`` in reverse order. +.. function:: get_origin(typ) +.. function:: get_args(typ) + + Provide basic introspection for generic types and special typing forms. + + For a typing object of the form ``X[Y, Z, ...]`` these functions return + ``X`` and ``(Y, Z, ...)``. If ``X`` is a generic alias for a builtin or + :mod:`collections` class, it gets normalized to the original class. + For unsupported objects return ``None`` and ``()`` correspondingly. + Examples:: + + assert get_origin(Dict[str, int]) is dict + assert get_args(Dict[int, str]) == (int, str) + + assert get_origin(Union[int, str]) is Union + assert get_args(Union[int, str]) == (int, str) + + .. versionadded:: 3.8 + .. decorator:: overload The ``@overload`` decorator allows describing functions and methods diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index f9c18c84c8f9e6..a65d639fe9e112 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -15,6 +15,7 @@ from typing import Generic, ClassVar, Final, final, Protocol from typing import cast, runtime_checkable from typing import get_type_hints +from typing import get_origin, get_args from typing import no_type_check, no_type_check_decorator from typing import Type from typing import NewType @@ -2735,6 +2736,42 @@ def test_get_type_hints_ClassVar(self): self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) +class GetUtilitiesTestCase(TestCase): + def test_get_origin(self): + T = TypeVar('T') + class C(Generic[T]): pass + self.assertIs(get_origin(C[int]), C) + self.assertIs(get_origin(C[T]), C) + self.assertIs(get_origin(int), None) + self.assertIs(get_origin(ClassVar[int]), ClassVar) + self.assertIs(get_origin(Union[int, str]), Union) + self.assertIs(get_origin(Literal[42, 43]), Literal) + self.assertIs(get_origin(Final[List[int]]), Final) + self.assertIs(get_origin(Generic), Generic) + self.assertIs(get_origin(Generic[T]), Generic) + self.assertIs(get_origin(List[Tuple[T, T]][int]), list) + + def test_get_args(self): + T = TypeVar('T') + class C(Generic[T]): pass + self.assertEqual(get_args(C[int]), (int,)) + self.assertEqual(get_args(C[T]), (T,)) + self.assertEqual(get_args(int), ()) + self.assertEqual(get_args(ClassVar[int]), (int,)) + self.assertEqual(get_args(Union[int, str]), (int, str)) + self.assertEqual(get_args(Literal[42, 43]), (42, 43)) + self.assertEqual(get_args(Final[List[int]]), (List[int],)) + self.assertEqual(get_args(Union[int, Tuple[T, int]][str]), + (int, Tuple[str, int])) + self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]), + (int, Tuple[Optional[int], Optional[int]])) + self.assertEqual(get_args(Callable[[], T][int]), ([], int,)) + self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), + (int, Callable[[Tuple[T, ...]], str])) + self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) + self.assertEqual(get_args(Tuple[()]), ((),)) + + class CollectionsAbcTests(BaseTestCase): def test_hashable(self): diff --git a/Lib/typing.py b/Lib/typing.py index 3b4e9df0482eda..16ccfad049f42d 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -99,6 +99,8 @@ 'AnyStr', 'cast', 'final', + 'get_args', + 'get_origin', 'get_type_hints', 'NewType', 'no_type_check', @@ -1253,6 +1255,46 @@ def get_type_hints(obj, globalns=None, localns=None): return hints +def get_origin(tp): + """Get the unsubscripted version of a type. + + This supports generic types, Callable, Tuple, Union, Literal, Final and ClassVar. + Return None for unsupported types. Examples:: + + get_origin(Literal[42]) is Literal + get_origin(int) is None + get_origin(ClassVar[int]) is ClassVar + get_origin(Generic) is Generic + get_origin(Generic[T]) is Generic + get_origin(Union[T, int]) is Union + get_origin(List[Tuple[T, T]][int]) == list + """ + if isinstance(tp, _GenericAlias): + return tp.__origin__ + if tp is Generic: + return Generic + return None + + +def get_args(tp): + """Get type arguments with all substitutions performed. + + For unions, basic simplifications used by Union constructor are performed. + Examples:: + get_args(Dict[str, int]) == (str, int) + get_args(int) == () + get_args(Union[int, Union[T, int], str][int]) == (int, str) + get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) + get_args(Callable[[], T][int]) == ([], int) + """ + if isinstance(tp, _GenericAlias): + res = tp.__args__ + if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis: + res = (list(res[:-1]), res[-1]) + return res + return () + + def no_type_check(arg): """Decorator to indicate that annotations are not type hints. diff --git a/Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst b/Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst new file mode 100644 index 00000000000000..e1154ef575a539 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst @@ -0,0 +1 @@ +Add ``get_origin()`` and ``get_args()`` introspection helpers to ``typing`` module. \ No newline at end of file From 530f506ac91338b55cf2be71b1cdf50cb077512f Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 31 May 2019 04:13:39 +0200 Subject: [PATCH 208/441] bpo-36974: tp_print -> tp_vectorcall_offset and tp_reserved -> tp_as_async (GH-13464) Automatically replace tp_print -> tp_vectorcall_offset tp_compare -> tp_as_async tp_reserved -> tp_as_async --- Modules/_blake2/blake2b_impl.c | 4 +- Modules/_blake2/blake2s_impl.c | 4 +- Modules/_bz2module.c | 8 +-- Modules/_collectionsmodule.c | 20 +++---- Modules/_csv.c | 12 ++--- Modules/_ctypes/_ctypes.c | 60 ++++++++++----------- Modules/_ctypes/callbacks.c | 4 +- Modules/_ctypes/callproc.c | 4 +- Modules/_ctypes/cfield.c | 4 +- Modules/_ctypes/stgdict.c | 4 +- Modules/_cursesmodule.c | 4 +- Modules/_datetimemodule.c | 27 +++++----- Modules/_dbmmodule.c | 4 +- Modules/_decimal/_decimal.c | 16 +++--- Modules/_elementtree.c | 16 +++--- Modules/_functoolsmodule.c | 16 +++--- Modules/_gdbmmodule.c | 4 +- Modules/_hashopenssl.c | 4 +- Modules/_io/bufferedio.c | 20 +++---- Modules/_io/bytesio.c | 8 +-- Modules/_io/fileio.c | 4 +- Modules/_io/iobase.c | 8 +-- Modules/_io/stringio.c | 4 +- Modules/_io/textio.c | 12 ++--- Modules/_io/winconsoleio.c | 4 +- Modules/_json.c | 8 +-- Modules/_lsprof.c | 4 +- Modules/_lzmamodule.c | 8 +-- Modules/_multiprocessing/semaphore.c | 4 +- Modules/_operator.c | 12 ++--- Modules/_pickle.c | 16 +++--- Modules/_queuemodule.c | 4 +- Modules/_randommodule.c | 4 +- Modules/_sha3/sha3module.c | 4 +- Modules/_sqlite/cache.c | 8 +-- Modules/_sqlite/connection.c | 4 +- Modules/_sqlite/cursor.c | 4 +- Modules/_sqlite/prepare_protocol.c | 4 +- Modules/_sqlite/row.c | 4 +- Modules/_sqlite/statement.c | 4 +- Modules/_sre.c | 12 ++--- Modules/_ssl.c | 16 +++--- Modules/_struct.c | 8 +-- Modules/_testbuffer.c | 8 +-- Modules/_testcapimodule.c | 22 ++++---- Modules/_threadmodule.c | 16 +++--- Modules/_winapi.c | 4 +- Modules/_xxsubinterpretersmodule.c | 2 +- Modules/arraymodule.c | 8 +-- Modules/cjkcodecs/multibytecodec.c | 20 +++---- Modules/itertoolsmodule.c | 80 ++++++++++++++-------------- Modules/md5module.c | 4 +- Modules/mmapmodule.c | 4 +- Modules/ossaudiodev.c | 8 +-- Modules/overlapped.c | 4 +- Modules/parsermodule.c | 4 +- Modules/posixmodule.c | 8 +-- Modules/pyexpat.c | 4 +- Modules/selectmodule.c | 20 +++---- Modules/sha1module.c | 4 +- Modules/sha256module.c | 8 +-- Modules/sha512module.c | 8 +-- Modules/socketmodule.c | 4 +- Modules/unicodedata.c | 4 +- Modules/xxmodule.c | 12 ++--- Modules/xxsubtype.c | 8 +-- Modules/zlibmodule.c | 8 +-- Objects/boolobject.c | 4 +- Objects/bytearrayobject.c | 8 +-- Objects/bytesobject.c | 8 +-- Objects/capsule.c | 4 +- Objects/cellobject.c | 4 +- Objects/classobject.c | 6 +-- Objects/codeobject.c | 4 +- Objects/complexobject.c | 4 +- Objects/descrobject.c | 30 +++++------ Objects/dictobject.c | 28 +++++----- Objects/enumobject.c | 8 +-- Objects/exceptions.c | 4 +- Objects/fileobject.c | 4 +- Objects/floatobject.c | 4 +- Objects/frameobject.c | 4 +- Objects/funcobject.c | 10 ++-- Objects/genobject.c | 14 ++--- Objects/interpreteridobject.c | 2 +- Objects/iterobject.c | 8 +-- Objects/listobject.c | 12 ++--- Objects/longobject.c | 4 +- Objects/memoryobject.c | 8 +-- Objects/methodobject.c | 2 +- Objects/moduleobject.c | 4 +- Objects/namespaceobject.c | 4 +- Objects/object.c | 10 ++-- Objects/odictobject.c | 20 +++---- Objects/rangeobject.c | 12 ++--- Objects/setobject.c | 16 +++--- Objects/sliceobject.c | 8 +-- Objects/stringlib/unicode_format.h | 8 +-- Objects/tupleobject.c | 8 +-- Objects/typeobject.c | 13 +++-- Objects/unicodeobject.c | 12 ++--- Objects/weakrefobject.c | 12 ++--- PC/_msi.c | 16 +++--- PC/winreg.c | 4 +- Parser/asdl_c.py | 4 +- Python/Python-ast.c | 4 +- Python/bltinmodule.c | 12 ++--- Python/symtable.c | 4 +- Python/traceback.c | 4 +- 109 files changed, 516 insertions(+), 518 deletions(-) diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index 788c15c31d8c89..edab31ea222ab8 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -401,10 +401,10 @@ PyTypeObject PyBlake2_BLAKE2bType = { sizeof(BLAKE2bObject), /* tp_basicsize */ 0, /* tp_itemsize */ py_blake2b_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /*tp_vectorcall_offset*/ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index c8bcedeabd5703..ef2f7e1980ff30 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -401,10 +401,10 @@ PyTypeObject PyBlake2_BLAKE2sType = { sizeof(BLAKE2sObject), /* tp_basicsize */ 0, /* tp_itemsize */ py_blake2s_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /*tp_vectorcall_offset*/ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index b5e5a79d50a5bb..31bbf66104119c 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -349,10 +349,10 @@ static PyTypeObject BZ2Compressor_Type = { sizeof(BZ2Compressor), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)BZ2Compressor_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -690,10 +690,10 @@ static PyTypeObject BZ2Decompressor_Type = { sizeof(BZ2Decompressor), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)BZ2Decompressor_dealloc,/* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index a40b681d2835f5..dacea3a0243914 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1620,10 +1620,10 @@ static PyTypeObject deque_type = { 0, /* tp_itemsize */ /* methods */ (destructor)deque_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ deque_repr, /* tp_repr */ &deque_as_number, /* tp_as_number */ &deque_as_sequence, /* tp_as_sequence */ @@ -1788,10 +1788,10 @@ static PyTypeObject dequeiter_type = { 0, /* tp_itemsize */ /* methods */ (destructor)dequeiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1910,10 +1910,10 @@ static PyTypeObject dequereviter_type = { 0, /* tp_itemsize */ /* methods */ (destructor)dequeiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2189,10 +2189,10 @@ static PyTypeObject defdict_type = { 0, /* tp_itemsize */ /* methods */ (destructor)defdict_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)defdict_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2464,10 +2464,10 @@ static PyTypeObject tuplegetter_type = { 0, /* tp_itemsize */ /* methods */ (destructor)tuplegetter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_csv.c b/Modules/_csv.c index e31b158c601e86..7eb9d8b796dd78 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -469,10 +469,10 @@ static PyTypeObject Dialect_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)Dialect_dealloc, /* tp_dealloc */ - (printfunc)0, /* tp_print */ + 0, /* tp_vectorcall_offset */ (getattrfunc)0, /* tp_getattr */ (setattrfunc)0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -902,10 +902,10 @@ static PyTypeObject Reader_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)Reader_dealloc, /*tp_dealloc*/ - (printfunc)0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ (getattrfunc)0, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -1332,10 +1332,10 @@ static PyTypeObject Writer_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)Writer_dealloc, /*tp_dealloc*/ - (printfunc)0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ (getattrfunc)0, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 21b08f8e332d44..f7513a3d74c4bc 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -165,10 +165,10 @@ static PyTypeObject DictRemover_Type = { sizeof(DictRemoverObject), /* tp_basicsize */ 0, /* tp_itemsize */ _DictRemover_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -855,10 +855,10 @@ PyTypeObject PyCStructType_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &CDataType_as_sequence, /* tp_as_sequence */ @@ -897,10 +897,10 @@ static PyTypeObject UnionType_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &CDataType_as_sequence, /* tp_as_sequence */ @@ -1151,10 +1151,10 @@ PyTypeObject PyCPointerType_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &CDataType_as_sequence, /* tp_as_sequence */ @@ -1573,10 +1573,10 @@ PyTypeObject PyCArrayType_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &CDataType_as_sequence, /* tp_as_sequence */ @@ -2267,10 +2267,10 @@ PyTypeObject PyCSimpleType_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &CDataType_as_sequence, /* tp_as_sequence */ @@ -2503,10 +2503,10 @@ PyTypeObject PyCFuncPtrType_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &CDataType_as_sequence, /* tp_as_sequence */ @@ -2808,10 +2808,10 @@ PyTypeObject PyCData_Type = { sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ PyCData_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4201,10 +4201,10 @@ PyTypeObject PyCFuncPtr_Type = { sizeof(PyCFuncPtrObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)PyCFuncPtr_repr, /* tp_repr */ &PyCFuncPtr_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4355,10 +4355,10 @@ static PyTypeObject Struct_Type = { sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4397,10 +4397,10 @@ static PyTypeObject Union_Type = { sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4713,10 +4713,10 @@ PyTypeObject PyCArray_Type = { sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &Array_as_sequence, /* tp_as_sequence */ @@ -4932,10 +4932,10 @@ static PyTypeObject Simple_Type = { sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)&Simple_repr, /* tp_repr */ &Simple_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5315,10 +5315,10 @@ PyTypeObject PyCPointer_Type = { sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ &Pointer_as_number, /* tp_as_number */ &Pointer_as_sequence, /* tp_as_sequence */ @@ -5406,10 +5406,10 @@ static PyTypeObject PyComError_Type = { sizeof(PyBaseExceptionObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 9f793c2771bfb9..97463b599bc004 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -48,10 +48,10 @@ PyTypeObject PyCThunk_Type = { sizeof(CThunkObject), /* tp_basicsize */ sizeof(ffi_type), /* tp_itemsize */ CThunkObject_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 8682d548722015..67665246414e21 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -555,10 +555,10 @@ PyTypeObject PyCArg_Type = { sizeof(PyCArgObject), 0, (destructor)PyCArg_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)PyCArg_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 157c32fd90967f..95367d50937654 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -305,10 +305,10 @@ PyTypeObject PyCField_Type = { sizeof(CFieldObject), /* tp_basicsize */ 0, /* tp_itemsize */ PyCField_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)PyCField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 3f8a0316616bf3..235a4d79ad2ca1 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -132,10 +132,10 @@ PyTypeObject PyCStgDict_Type = { sizeof(StgDictObject), 0, (destructor)PyCStgDict_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 9a1d2efd256ea5..2435e1c1295514 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -2424,10 +2424,10 @@ PyTypeObject PyCursesWindow_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ (getattrfunc)0, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 83e43a24395b45..4d3562cbe64f69 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1704,8 +1704,7 @@ build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) * Miscellaneous helpers. */ -/* For various reasons, we need to use tp_richcompare instead of tp_reserved. - * The comparisons here all most naturally compute a cmp()-like result. +/* The comparisons here all most naturally compute a cmp()-like result. * This little helper turns that into a bool result for rich comparisons. */ static PyObject * @@ -2720,10 +2719,10 @@ static PyTypeObject PyDateTime_DeltaType = { sizeof(PyDateTime_Delta), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)delta_repr, /* tp_repr */ &delta_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3431,10 +3430,10 @@ static PyTypeObject PyDateTime_DateType = { sizeof(PyDateTime_Date), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)date_repr, /* tp_repr */ &date_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3681,10 +3680,10 @@ static PyTypeObject PyDateTime_TZInfoType = { sizeof(PyDateTime_TZInfo), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3920,10 +3919,10 @@ static PyTypeObject PyDateTime_TimeZoneType = { sizeof(PyDateTime_TimeZone), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)timezone_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)timezone_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4583,10 +4582,10 @@ static PyTypeObject PyDateTime_TimeType = { sizeof(PyDateTime_Time), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)time_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)time_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -6299,10 +6298,10 @@ static PyTypeObject PyDateTime_DateTimeType = { sizeof(PyDateTime_DateTime), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)datetime_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)datetime_repr, /* tp_repr */ &datetime_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 21784ae2ce4fd2..ea0a9d6fc957b6 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -390,10 +390,10 @@ static PyTypeObject Dbmtype = { sizeof(dbmobject), 0, (destructor)dbm_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ &dbm_as_sequence, /*tp_as_sequence*/ diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index d977b14f5b0cb8..e2ac19800315ce 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -672,10 +672,10 @@ static PyTypeObject PyDecSignalDictMixin_Type = sizeof(PyDecSignalDictObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ (getattrfunc) 0, /* tp_getattr */ (setattrfunc) 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc) signaldict_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1665,10 +1665,10 @@ static PyTypeObject PyDecContextManager_Type = sizeof(PyDecContextManagerObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) ctxmanager_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ (getattrfunc) 0, /* tp_getattr */ (setattrfunc) 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc) 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4694,10 +4694,10 @@ static PyTypeObject PyDec_Type = sizeof(PyDecObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) dec_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ (getattrfunc) 0, /* tp_getattr */ (setattrfunc) 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc) dec_repr, /* tp_repr */ &dec_number_methods, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5380,10 +5380,10 @@ static PyTypeObject PyDecContext_Type = sizeof(PyDecContextObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) context_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ (getattrfunc) 0, /* tp_getattr */ (setattrfunc) 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc) context_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index b1fb3eeffb110f..8119c8b1e2b10f 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2322,10 +2322,10 @@ static PyTypeObject ElementIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)elementiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4228,10 +4228,10 @@ static PyTypeObject Element_Type = { "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, /* methods */ (destructor)element_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)element_repr, /* tp_repr */ 0, /* tp_as_number */ &element_as_sequence, /* tp_as_sequence */ @@ -4280,10 +4280,10 @@ static PyTypeObject TreeBuilder_Type = { "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, /* methods */ (destructor)treebuilder_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4330,10 +4330,10 @@ static PyTypeObject XMLParser_Type = { "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, /* methods */ (destructor)xmlparser_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 213fb3ea336c5a..aca5bad23f585b 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -386,10 +386,10 @@ static PyTypeObject partial_type = { 0, /* tp_itemsize */ /* methods */ (destructor)partial_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)partial_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -478,10 +478,10 @@ static PyTypeObject keyobject_type = { 0, /* tp_itemsize */ /* methods */ (destructor)keyobject_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -709,10 +709,10 @@ static PyTypeObject lru_list_elem_type = { 0, /* tp_itemsize */ /* methods */ (destructor)lru_list_elem_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1319,10 +1319,10 @@ static PyTypeObject lru_cache_type = { 0, /* tp_itemsize */ /* methods */ (destructor)lru_cache_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index adf2a5865bfb81..77e7887525069a 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -520,10 +520,10 @@ static PyTypeObject Dbmtype = { sizeof(dbmobject), 0, (destructor)dbm_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ &dbm_as_sequence, /*tp_as_sequence*/ diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index e560c18b63c348..a806241897fcbd 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -368,10 +368,10 @@ static PyTypeObject EVPtype = { 0, /*tp_itemsize*/ /* methods */ (destructor)EVP_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ (reprfunc)EVP_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 9c0eeb56860eea..44e12db6a30ed0 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -2328,10 +2328,10 @@ PyTypeObject PyBufferedIOBase_Type = { 0, /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -2418,10 +2418,10 @@ PyTypeObject PyBufferedReader_Type = { sizeof(buffered), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)buffered_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ (reprfunc)buffered_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -2504,10 +2504,10 @@ PyTypeObject PyBufferedWriter_Type = { sizeof(buffered), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)buffered_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ (reprfunc)buffered_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -2581,10 +2581,10 @@ PyTypeObject PyBufferedRWPair_Type = { sizeof(rwpair), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -2675,10 +2675,10 @@ PyTypeObject PyBufferedRandom_Type = { sizeof(buffered), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)buffered_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ (reprfunc)buffered_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 55e34c677670d5..32427e44de5b1c 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -1002,10 +1002,10 @@ PyTypeObject PyBytesIO_Type = { sizeof(bytesio), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)bytesio_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -1102,10 +1102,10 @@ PyTypeObject _PyBytesIOBuffer_Type = { sizeof(bytesiobuf), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)bytesiobuf_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 582a8130f622af..7f784a34c30d33 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -1185,10 +1185,10 @@ PyTypeObject PyFileIO_Type = { sizeof(fileio), 0, (destructor)fileio_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)fileio_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 8c8112d10f0ba8..fab450977ffa7c 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -841,10 +841,10 @@ PyTypeObject PyIOBase_Type = { sizeof(iobase), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)iobase_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -1037,10 +1037,10 @@ PyTypeObject PyRawIOBase_Type = { 0, /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index bb5c3736a77a1c..9e9724db2d3308 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -1007,10 +1007,10 @@ PyTypeObject PyStringIO_Type = { sizeof(stringio), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)stringio_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 3eb0dcc865ba2e..73b2756afce5e6 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -169,10 +169,10 @@ PyTypeObject PyTextIOBase_Type = { 0, /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -3158,10 +3158,10 @@ PyTypeObject PyIncrementalNewlineDecoder_Type = { sizeof(nldecoder_object), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -3242,10 +3242,10 @@ PyTypeObject PyTextIOWrapper_Type = { sizeof(textio), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)textiowrapper_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tps_etattr*/ - 0, /*tp_compare */ + 0, /*tp_as_async*/ (reprfunc)textiowrapper_repr,/*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 7700bd5b7c0d31..ea5d24f950a1e2 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -1118,10 +1118,10 @@ PyTypeObject PyWindowsConsoleIO_Type = { sizeof(winconsoleio), 0, (destructor)winconsoleio_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)winconsoleio_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_json.c b/Modules/_json.c index 4faa9cc22edf01..e3aa997598fc2e 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -1257,10 +1257,10 @@ PyTypeObject PyScannerType = { sizeof(PyScannerObject), /* tp_basicsize */ 0, /* tp_itemsize */ scanner_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1849,10 +1849,10 @@ PyTypeObject PyEncoderType = { sizeof(PyEncoderObject), /* tp_basicsize */ 0, /* tp_itemsize */ encoder_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index c4e0f52389d952..c5a6f4445872ca 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -754,10 +754,10 @@ static PyTypeObject PyProfiler_Type = { sizeof(ProfilerObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)profiler_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 18bc3dc296e00b..9e68cbb78af50d 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -823,10 +823,10 @@ static PyTypeObject Compressor_type = { sizeof(Compressor), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)Compressor_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1251,10 +1251,10 @@ static PyTypeObject Decompressor_type = { sizeof(Decompressor), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)Decompressor_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index cbcc64cb578fe5..4be2deae377504 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -633,10 +633,10 @@ PyTypeObject _PyMp_SemLockType = { /* tp_basicsize */ sizeof(SemLockObject), /* tp_itemsize */ 0, /* tp_dealloc */ (destructor)semlock_dealloc, - /* tp_print */ 0, + /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, - /* tp_reserved */ 0, + /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, diff --git a/Modules/_operator.c b/Modules/_operator.c index d291ec1f920ed1..5aa229fa781ebb 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -1098,10 +1098,10 @@ static PyTypeObject itemgetter_type = { 0, /* tp_itemsize */ /* methods */ (destructor)itemgetter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)itemgetter_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1443,10 +1443,10 @@ static PyTypeObject attrgetter_type = { 0, /* tp_itemsize */ /* methods */ (destructor)attrgetter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)attrgetter_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1709,10 +1709,10 @@ static PyTypeObject methodcaller_type = { 0, /* tp_itemsize */ /* methods */ (destructor)methodcaller_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)methodcaller_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_pickle.c b/Modules/_pickle.c index a3f02ae8813d91..57145beb8fff88 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4867,10 +4867,10 @@ static PyTypeObject PicklerMemoProxyType = { sizeof(PicklerMemoProxyObject), /*tp_basicsize*/ 0, (destructor)PicklerMemoProxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5028,10 +5028,10 @@ static PyTypeObject Pickler_Type = { sizeof(PicklerObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)Pickler_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -7404,10 +7404,10 @@ static PyTypeObject UnpicklerMemoProxyType = { sizeof(UnpicklerMemoProxyObject), /*tp_basicsize*/ 0, (destructor)UnpicklerMemoProxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -7575,10 +7575,10 @@ static PyTypeObject Unpickler_Type = { sizeof(UnpicklerObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)Unpickler_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 35906f08c12b72..e033da50a5ee3b 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -313,10 +313,10 @@ static PyTypeObject PySimpleQueueType = { 0, /*tp_itemsize*/ /* methods */ (destructor)simplequeue_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 85f6e402929975..4e9ac4073c7774 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -534,10 +534,10 @@ static PyTypeObject Random_Type = { 0, /*tp_itemsize*/ /* methods */ 0, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index b737363d717247..c1fb6185e243da 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -493,10 +493,10 @@ static PyGetSetDef SHA3_getseters[] = { 0, /* tp_itemsize */ \ /* methods */ \ (destructor)SHA3_dealloc, /* tp_dealloc */ \ - 0, /* tp_print */ \ + 0, /* tp_vectorcall_offset */ \ 0, /* tp_getattr */ \ 0, /* tp_setattr */ \ - 0, /* tp_reserved */ \ + 0, /* tp_as_async */ \ 0, /* tp_repr */ \ 0, /* tp_as_number */ \ 0, /* tp_as_sequence */ \ diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 4270473ae994df..4d4180421871de 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -265,10 +265,10 @@ PyTypeObject pysqlite_NodeType = { sizeof(pysqlite_Node), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_node_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -307,10 +307,10 @@ PyTypeObject pysqlite_CacheType = { sizeof(pysqlite_Cache), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_cache_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index e3340bf19f7bd3..0d6462ef7dc290 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1838,10 +1838,10 @@ PyTypeObject pysqlite_ConnectionType = { sizeof(pysqlite_Connection), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_connection_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 2bc19311a81d21..01b9dc44cb5da5 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -922,10 +922,10 @@ PyTypeObject pysqlite_CursorType = { sizeof(pysqlite_Cursor), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_cursor_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index f2c85f9af6cb68..181c7edf96b45c 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -39,10 +39,10 @@ PyTypeObject pysqlite_PrepareProtocolType= { sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_prepare_protocol_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 3cfbeeb93bbae6..5c2f40082402e3 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -231,10 +231,10 @@ PyTypeObject pysqlite_RowType = { sizeof(pysqlite_Row), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_row_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 575ac69d9030ef..491294b0209cca 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -459,10 +459,10 @@ PyTypeObject pysqlite_StatementType = { sizeof(pysqlite_Statement), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pysqlite_statement_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_sre.c b/Modules/_sre.c index 014cc546e345d9..d4fe588cbe27c6 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -2594,10 +2594,10 @@ static PyTypeObject Pattern_Type = { "re.Pattern", sizeof(PatternObject), sizeof(SRE_CODE), (destructor)pattern_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)pattern_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2672,10 +2672,10 @@ static PyTypeObject Match_Type = { "re.Match", sizeof(MatchObject), sizeof(Py_ssize_t), (destructor)match_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)match_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2716,10 +2716,10 @@ static PyTypeObject Scanner_Type = { "_" SRE_MODULE ".SRE_Scanner", sizeof(ScannerObject), 0, (destructor)scanner_dealloc,/* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 390a1af1e59de7..755097256acb30 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2874,10 +2874,10 @@ static PyTypeObject PySSLSocket_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)PySSL_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -4599,10 +4599,10 @@ static PyTypeObject PySSLContext_Type = { sizeof(PySSLContext), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)context_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -4824,10 +4824,10 @@ static PyTypeObject PySSLMemoryBIO_Type = { sizeof(PySSLMemoryBIO), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)memory_bio_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -5021,10 +5021,10 @@ static PyTypeObject PySSLSession_Type = { sizeof(PySSLSession), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PySSLSession_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/_struct.c b/Modules/_struct.c index 90839b2ead7508..9281c6803f3a68 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -1669,10 +1669,10 @@ static PyTypeObject unpackiter_type = { sizeof(unpackiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)unpackiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2029,10 +2029,10 @@ PyTypeObject PyStructType = { sizeof(PyStructObject), 0, (destructor)s_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 9d7b3e8b0b3ff0..d7d3cc8d0d53a6 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -2646,10 +2646,10 @@ static PyTypeObject NDArray_Type = { sizeof(NDArrayObject), /* Basic object size */ 0, /* Item size for varobject */ (destructor)ndarray_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &ndarray_as_sequence, /* tp_as_sequence */ @@ -2766,10 +2766,10 @@ static PyTypeObject StaticArray_Type = { sizeof(StaticArrayObject), /* Basic object size */ 0, /* Item size for varobject */ (destructor)staticarray_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index a7451c66359d81..ca6e87b79c47fc 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -288,10 +288,10 @@ static PyTypeObject _HashInheritanceTester_Type = { sizeof(PyObject), /* Basic object size */ 0, /* Item size for varobject */ (destructor)PyObject_Del, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5383,10 +5383,10 @@ static PyTypeObject test_structmembersType = { sizeof(test_structmembers), /* tp_basicsize */ 0, /* tp_itemsize */ test_structmembers_free, /* destructor tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5486,10 +5486,10 @@ static PyTypeObject matmulType = { sizeof(matmulObject), /* tp_basicsize */ 0, /* tp_itemsize */ matmulType_dealloc, /* destructor tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ &matmulType_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5578,7 +5578,7 @@ static PyTypeObject awaitType = { sizeof(awaitObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)awaitObject_dealloc, /* destructor tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ &awaitType_as_async, /* tp_as_async */ @@ -5623,10 +5623,10 @@ static PyTypeObject PyRecursingInfinitelyError_Type = { sizeof(PyBaseExceptionObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5704,10 +5704,10 @@ static PyTypeObject MyList_Type = { sizeof(MyListObject), 0, (destructor)MyList_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 2b1a98f81b1a4e..d5e40ef999e3d5 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -232,10 +232,10 @@ static PyTypeObject Locktype = { 0, /*tp_itemsize*/ /* methods */ (destructor)lock_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ (reprfunc)lock_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -493,10 +493,10 @@ static PyTypeObject RLocktype = { 0, /*tp_itemsize*/ /* methods */ (destructor)rlock_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ (reprfunc)rlock_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -609,10 +609,10 @@ static PyTypeObject localdummytype = { /* tp_basicsize */ sizeof(localdummyobject), /* tp_itemsize */ 0, /* tp_dealloc */ (destructor)localdummy_dealloc, - /* tp_print */ 0, + /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, - /* tp_reserved */ 0, + /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, @@ -874,10 +874,10 @@ static PyTypeObject localtype = { /* tp_basicsize */ sizeof(localobject), /* tp_itemsize */ 0, /* tp_dealloc */ (destructor)local_dealloc, - /* tp_print */ 0, + /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, - /* tp_reserved */ 0, + /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, diff --git a/Modules/_winapi.c b/Modules/_winapi.c index e9dcec6590b6ce..647075cdb1788c 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -310,10 +310,10 @@ PyTypeObject OverlappedType = { /* tp_basicsize */ sizeof(OverlappedObject), /* tp_itemsize */ 0, /* tp_dealloc */ (destructor) overlapped_dealloc, - /* tp_print */ 0, + /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, - /* tp_reserved */ 0, + /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 0d8e5f3127d5cf..19d98fd9693446 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1740,7 +1740,7 @@ static PyTypeObject ChannelIDtype = { sizeof(channelid), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)channelid_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 423cac9910a293..26c90a8a5983d4 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2839,10 +2839,10 @@ static PyTypeObject Arraytype = { sizeof(arrayobject), 0, (destructor)array_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)array_repr, /* tp_repr */ 0, /* tp_as_number*/ &array_as_sequence, /* tp_as_sequence*/ @@ -2995,10 +2995,10 @@ static PyTypeObject PyArrayIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)arrayiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index f266e5f33a60b1..c01a0e5dfadfd0 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -711,10 +711,10 @@ static PyTypeObject MultibyteCodec_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)multibytecodec_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1088,10 +1088,10 @@ static PyTypeObject MultibyteIncrementalEncoder_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)mbiencoder_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1387,10 +1387,10 @@ static PyTypeObject MultibyteIncrementalDecoder_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)mbidecoder_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1734,10 +1734,10 @@ static PyTypeObject MultibyteStreamReader_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)mbstreamreader_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1980,10 +1980,10 @@ static PyTypeObject MultibyteStreamWriter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)mbstreamwriter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 103029d251e0da..00e3cbb31b53b8 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -241,10 +241,10 @@ static PyTypeObject groupby_type = { 0, /* tp_itemsize */ /* methods */ (destructor)groupby_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -390,10 +390,10 @@ static PyTypeObject _grouper_type = { 0, /* tp_itemsize */ /* methods */ (destructor)_grouper_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -636,10 +636,10 @@ static PyTypeObject teedataobject_type = { 0, /* tp_itemsize */ /* methods */ (destructor)teedataobject_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -825,10 +825,10 @@ static PyTypeObject tee_type = { 0, /* tp_itemsize */ /* methods */ (destructor)tee_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1091,10 +1091,10 @@ static PyTypeObject cycle_type = { 0, /* tp_itemsize */ /* methods */ (destructor)cycle_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1258,10 +1258,10 @@ static PyTypeObject dropwhile_type = { 0, /* tp_itemsize */ /* methods */ (destructor)dropwhile_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1420,10 +1420,10 @@ static PyTypeObject takewhile_type = { 0, /* tp_itemsize */ /* methods */ (destructor)takewhile_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1679,10 +1679,10 @@ static PyTypeObject islice_type = { 0, /* tp_itemsize */ /* methods */ (destructor)islice_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1820,10 +1820,10 @@ static PyTypeObject starmap_type = { 0, /* tp_itemsize */ /* methods */ (destructor)starmap_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2041,10 +2041,10 @@ static PyTypeObject chain_type = { 0, /* tp_itemsize */ /* methods */ (destructor)chain_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2394,10 +2394,10 @@ static PyTypeObject product_type = { 0, /* tp_itemsize */ /* methods */ (destructor)product_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2702,10 +2702,10 @@ static PyTypeObject combinations_type = { 0, /* tp_itemsize */ /* methods */ (destructor)combinations_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3026,10 +3026,10 @@ static PyTypeObject cwr_type = { 0, /* tp_itemsize */ /* methods */ (destructor)cwr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3412,10 +3412,10 @@ static PyTypeObject permutations_type = { 0, /* tp_itemsize */ /* methods */ (destructor)permutations_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3620,10 +3620,10 @@ static PyTypeObject accumulate_type = { 0, /* tp_itemsize */ /* methods */ (destructor)accumulate_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3787,10 +3787,10 @@ static PyTypeObject compress_type = { 0, /* tp_itemsize */ /* methods */ (destructor)compress_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3941,10 +3941,10 @@ static PyTypeObject filterfalse_type = { 0, /* tp_itemsize */ /* methods */ (destructor)filterfalse_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4191,10 +4191,10 @@ static PyTypeObject count_type = { 0, /* tp_itemsize */ /* methods */ (destructor)count_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)count_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4346,10 +4346,10 @@ static PyTypeObject repeat_type = { 0, /* tp_itemsize */ /* methods */ (destructor)repeat_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)repeat_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4623,10 +4623,10 @@ static PyTypeObject ziplongest_type = { 0, /* tp_itemsize */ /* methods */ (destructor)zip_longest_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/md5module.c b/Modules/md5module.c index d377f0bb4615c5..b9a351a8c1cdd2 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -469,10 +469,10 @@ static PyTypeObject MD5type = { 0, /*tp_itemsize*/ /* methods */ MD5_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 36cbaf9fb8b23d..755f1669d8d321 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1045,10 +1045,10 @@ static PyTypeObject mmap_object_type = { 0, /* tp_itemsize */ /* methods */ (destructor) mmap_object_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ &mmap_as_sequence, /*tp_as_sequence*/ diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index 2222148c85161c..affaf1d9680be2 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -965,10 +965,10 @@ static PyTypeObject OSSAudioType = { 0, /*tp_itemsize*/ /* methods */ (destructor)oss_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -999,10 +999,10 @@ static PyTypeObject OSSMixerType = { 0, /*tp_itemsize*/ /* methods */ (destructor)oss_mixer_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index aad531e478931f..44a0a5a834633f 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1765,10 +1765,10 @@ PyTypeObject OverlappedType = { /* tp_basicsize */ sizeof(OverlappedObject), /* tp_itemsize */ 0, /* tp_dealloc */ (destructor) Overlapped_dealloc, - /* tp_print */ 0, + /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, - /* tp_reserved */ 0, + /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 0f681622f28820..36f92141915365 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -224,10 +224,10 @@ PyTypeObject PyST_Type = { (int) sizeof(PyST_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)parser_free, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7588d3cde71666..77a3700ab22e0f 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12580,10 +12580,10 @@ static PyTypeObject DirEntryType = { 0, /* tp_itemsize */ /* methods */ (destructor)DirEntry_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ (reprfunc)DirEntry_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -13018,10 +13018,10 @@ static PyTypeObject ScandirIteratorType = { 0, /* tp_itemsize */ /* methods */ (destructor)ScandirIterator_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 2e8be3706db914..45a1e684d19fe8 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1468,10 +1468,10 @@ static PyTypeObject Xmlparsetype = { 0, /*tp_itemsize*/ /* methods */ (destructor)xmlparse_dealloc, /*tp_dealloc*/ - (printfunc)0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 88130a1ecda0af..ed71d8b0d59852 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -2219,10 +2219,10 @@ static PyTypeObject poll_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)poll_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -2265,10 +2265,10 @@ static PyTypeObject devpoll_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)devpoll_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -2317,10 +2317,10 @@ static PyTypeObject pyEpoll_Type = { sizeof(pyEpoll_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)pyepoll_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2363,10 +2363,10 @@ static PyTypeObject kqueue_event_Type = { sizeof(kqueue_event_Object), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)kqueue_event_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2413,10 +2413,10 @@ static PyTypeObject kqueue_queue_Type = { sizeof(kqueue_queue_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)kqueue_queue_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 998ebd437dff0c..ce2ad267e775b7 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -446,10 +446,10 @@ static PyTypeObject SHA1type = { 0, /*tp_itemsize*/ /* methods */ SHA1_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/sha256module.c b/Modules/sha256module.c index 20b5f02f5481b1..b8d6c4cf8006a1 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -533,10 +533,10 @@ static PyTypeObject SHA224type = { 0, /*tp_itemsize*/ /* methods */ SHA_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -567,10 +567,10 @@ static PyTypeObject SHA256type = { 0, /*tp_itemsize*/ /* methods */ SHA_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/sha512module.c b/Modules/sha512module.c index e070e4389f4cfd..98b97917f4caf8 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -598,10 +598,10 @@ static PyTypeObject SHA384type = { 0, /*tp_itemsize*/ /* methods */ SHA512_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -632,10 +632,10 @@ static PyTypeObject SHA512type = { 0, /*tp_itemsize*/ /* methods */ SHA512_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index ac1698c6c767f2..36d13e768cd378 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5274,10 +5274,10 @@ static PyTypeObject sock_type = { sizeof(PySocketSockObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)sock_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)sock_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 7fdbf332ee7423..ae0d4e46f9a409 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -1365,10 +1365,10 @@ static PyTypeObject UCD_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)PyObject_Del, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c index d546901582fbf2..0250031d722d3a 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -106,10 +106,10 @@ static PyTypeObject Xxo_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)Xxo_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ (getattrfunc)0, /*tp_getattr*/ (setattrfunc)Xxo_setattr, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -224,10 +224,10 @@ static PyTypeObject Str_Type = { 0, /*tp_itemsize*/ /* methods */ 0, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -279,10 +279,10 @@ static PyTypeObject Null_Type = { 0, /*tp_itemsize*/ /* methods */ 0, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c index bacbdf15361814..031005d36e20f2 100644 --- a/Modules/xxsubtype.c +++ b/Modules/xxsubtype.c @@ -106,10 +106,10 @@ static PyTypeObject spamlist_type = { sizeof(spamlistobject), 0, 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -197,10 +197,10 @@ static PyTypeObject spamdict_type = { sizeof(spamdictobject), 0, 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index 5778dbb715f92c..a3d9ed6646dec8 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -1315,10 +1315,10 @@ static PyTypeObject Comptype = { sizeof(compobject), 0, (destructor)Comp_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -1346,10 +1346,10 @@ static PyTypeObject Decomptype = { sizeof(compobject), 0, (destructor)Decomp_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Objects/boolobject.c b/Objects/boolobject.c index 508ea61f180017..720835b98aa65e 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -137,10 +137,10 @@ PyTypeObject PyBool_Type = { sizeof(struct _longobject), 0, 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ bool_repr, /* tp_repr */ &bool_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index b9fcc01b70322a..c684db76736462 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2265,10 +2265,10 @@ PyTypeObject PyByteArray_Type = { sizeof(PyByteArrayObject), 0, (destructor)bytearray_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)bytearray_repr, /* tp_repr */ &bytearray_as_number, /* tp_as_number */ &bytearray_as_sequence, /* tp_as_sequence */ @@ -2412,10 +2412,10 @@ PyTypeObject PyByteArrayIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)bytearrayiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index bf7c7da423b725..06c87b0c62d3bb 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2886,10 +2886,10 @@ PyTypeObject PyBytes_Type = { PyBytesObject_SIZE, sizeof(char), 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)bytes_repr, /* tp_repr */ &bytes_as_number, /* tp_as_number */ &bytes_as_sequence, /* tp_as_sequence */ @@ -3165,10 +3165,10 @@ PyTypeObject PyBytesIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)striter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/capsule.c b/Objects/capsule.c index 4e15b440b170be..599893a320dba6 100644 --- a/Objects/capsule.c +++ b/Objects/capsule.c @@ -303,10 +303,10 @@ PyTypeObject PyCapsule_Type = { 0, /*tp_itemsize*/ /* methods */ capsule_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ capsule_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Objects/cellobject.c b/Objects/cellobject.c index 4e359f889fdc81..911cf527a43485 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -162,10 +162,10 @@ PyTypeObject PyCell_Type = { sizeof(PyCellObject), 0, (destructor)cell_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)cell_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/classobject.c b/Objects/classobject.c index cfc24460a747b0..ffd3f875c0e7ba 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -352,7 +352,7 @@ PyTypeObject PyMethod_Type = { offsetof(PyMethodObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -621,10 +621,10 @@ PyTypeObject PyInstanceMethod_Type = { sizeof(PyInstanceMethodObject), /* tp_basicsize */ 0, /* tp_itemsize */ instancemethod_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)instancemethod_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 1e76f26d98fe67..886ce4194438aa 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -831,10 +831,10 @@ PyTypeObject PyCode_Type = { sizeof(PyCodeObject), 0, (destructor)code_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)code_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 6d4d8c56f701a8..a5f95186d62575 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1113,10 +1113,10 @@ PyTypeObject PyComplex_Type = { sizeof(PyComplexObject), 0, 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)complex_repr, /* tp_repr */ &complex_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 3aaeaa6e890fdf..6c95a8726c4202 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -546,7 +546,7 @@ PyTypeObject PyMethodDescr_Type = { offsetof(PyMethodDescrObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -583,10 +583,10 @@ PyTypeObject PyClassMethodDescr_Type = { sizeof(PyMethodDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)method_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -620,10 +620,10 @@ PyTypeObject PyMemberDescr_Type = { sizeof(PyMemberDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)member_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -657,10 +657,10 @@ PyTypeObject PyGetSetDescr_Type = { sizeof(PyGetSetDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)getset_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -694,10 +694,10 @@ PyTypeObject PyWrapperDescr_Type = { sizeof(PyWrapperDescrObject), 0, (destructor)descr_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)wrapperdescr_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1173,10 +1173,10 @@ PyTypeObject _PyMethodWrapper_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)wrapper_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)wrapper_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1569,10 +1569,10 @@ PyTypeObject PyDictProxy_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)mappingproxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)mappingproxy_repr, /* tp_repr */ 0, /* tp_as_number */ &mappingproxy_as_sequence, /* tp_as_sequence */ @@ -1611,10 +1611,10 @@ PyTypeObject PyProperty_Type = { 0, /* tp_itemsize */ /* methods */ property_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 88ac1a9dcd0fb5..2b04b0b679651a 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3309,10 +3309,10 @@ PyTypeObject PyDict_Type = { sizeof(PyDictObject), 0, (destructor)dict_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)dict_repr, /* tp_repr */ 0, /* tp_as_number */ &dict_as_sequence, /* tp_as_sequence */ @@ -3572,10 +3572,10 @@ PyTypeObject PyDictIterKey_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)dictiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3659,10 +3659,10 @@ PyTypeObject PyDictIterValue_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)dictiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3766,10 +3766,10 @@ PyTypeObject PyDictIterItem_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)dictiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4322,10 +4322,10 @@ PyTypeObject PyDictKeys_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)dictview_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)dictview_repr, /* tp_repr */ &dictviews_as_number, /* tp_as_number */ &dictkeys_as_sequence, /* tp_as_sequence */ @@ -4428,10 +4428,10 @@ PyTypeObject PyDictItems_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)dictview_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)dictview_repr, /* tp_repr */ &dictviews_as_number, /* tp_as_number */ &dictitems_as_sequence, /* tp_as_sequence */ @@ -4509,10 +4509,10 @@ PyTypeObject PyDictValues_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)dictview_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)dictview_repr, /* tp_repr */ 0, /* tp_as_number */ &dictvalues_as_sequence, /* tp_as_sequence */ diff --git a/Objects/enumobject.c b/Objects/enumobject.c index d993a5063fdf60..4786297c41ace0 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -211,10 +211,10 @@ PyTypeObject PyEnum_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)enum_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -408,10 +408,10 @@ PyTypeObject PyReversed_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)reversed_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 8456a8f1828611..568d4959e3a0af 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -369,10 +369,10 @@ static PyTypeObject _PyExc_BaseException = { sizeof(PyBaseExceptionObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)BaseException_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /* tp_reserved; */ + 0, /*tp_as_async*/ (reprfunc)BaseException_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 3b026335d3f8f2..3791241e5c7c3d 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -479,10 +479,10 @@ PyTypeObject PyStdPrinter_Type = { 0, /* tp_itemsize */ /* methods */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)stdprinter_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 4ff43bb338f982..2bf7061d4f62c5 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1913,10 +1913,10 @@ PyTypeObject PyFloat_Type = { sizeof(PyFloatObject), 0, (destructor)float_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)float_repr, /* tp_repr */ &float_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/frameobject.c b/Objects/frameobject.c index b668465df3da19..5deb9858ce86c9 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -565,10 +565,10 @@ PyTypeObject PyFrame_Type = { sizeof(PyFrameObject), sizeof(PyObject *), (destructor)frame_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)frame_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 6f5b5d223d9be0..df5cc2d3f57024 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -653,7 +653,7 @@ PyTypeObject PyFunction_Type = { offsetof(PyFunctionObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)func_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -825,10 +825,10 @@ PyTypeObject PyClassMethod_Type = { sizeof(classmethod), 0, (destructor)cm_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1005,10 +1005,10 @@ PyTypeObject PyStaticMethod_Type = { sizeof(staticmethod), 0, (destructor)sm_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/genobject.c b/Objects/genobject.c index 0d0a02d76ccf21..2d9a2860a3d273 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -728,7 +728,7 @@ PyTypeObject PyGen_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)gen_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ @@ -982,7 +982,7 @@ PyTypeObject PyCoro_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)gen_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ &coro_as_async, /* tp_as_async */ @@ -1079,7 +1079,7 @@ PyTypeObject _PyCoroWrapper_Type = { sizeof(PyCoroWrapper), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)coro_wrapper_dealloc, /* destructor tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ @@ -1378,7 +1378,7 @@ PyTypeObject PyAsyncGen_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)gen_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ &async_gen_as_async, /* tp_as_async */ @@ -1609,7 +1609,7 @@ PyTypeObject _PyAsyncGenASend_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)async_gen_asend_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ &async_gen_asend_as_async, /* tp_as_async */ @@ -1706,7 +1706,7 @@ PyTypeObject _PyAsyncGenWrappedValue_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)async_gen_wrapped_val_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ @@ -1962,7 +1962,7 @@ PyTypeObject _PyAsyncGenAThrow_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)async_gen_athrow_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ &async_gen_athrow_as_async, /* tp_as_async */ diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index dd142b043d0ae7..0a1dfa25795fa9 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -236,7 +236,7 @@ PyTypeObject _PyInterpreterID_Type = { sizeof(interpid), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)interpid_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 5bee1e21e65e51..da89298edc5cf6 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -144,10 +144,10 @@ PyTypeObject PySeqIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)iter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -264,10 +264,10 @@ PyTypeObject PyCallIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)calliter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/listobject.c b/Objects/listobject.c index b210c005da13cf..233f13dbab0ef2 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2998,10 +2998,10 @@ PyTypeObject PyList_Type = { sizeof(PyListObject), 0, (destructor)list_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)list_repr, /* tp_repr */ 0, /* tp_as_number */ &list_as_sequence, /* tp_as_sequence */ @@ -3069,10 +3069,10 @@ PyTypeObject PyListIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)listiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3217,10 +3217,10 @@ PyTypeObject PyListRevIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)listreviter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/longobject.c b/Objects/longobject.c index 3ebbd3e7f9c907..5d2b595621f3d8 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5623,10 +5623,10 @@ PyTypeObject PyLong_Type = { offsetof(PyLongObject, ob_digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ long_to_decimal_string, /* tp_repr */ &long_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 3955c58ee5d2eb..a873ac1ec1ea5f 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -147,10 +147,10 @@ PyTypeObject _PyManagedBuffer_Type = { sizeof(_PyManagedBufferObject), 0, (destructor)mbuf_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -3155,10 +3155,10 @@ PyTypeObject PyMemoryView_Type = { offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */ sizeof(Py_ssize_t), /* tp_itemsize */ (destructor)memory_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)memory_repr, /* tp_repr */ 0, /* tp_as_number */ &memory_as_sequence, /* tp_as_sequence */ diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 544baee09113ab..c3bc0184796e40 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -275,7 +275,7 @@ PyTypeObject PyCFunction_Type = { offsetof(PyCFunctionObject, vectorcall), /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)meth_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 20e7d44ab5e187..85134c7a11c6bb 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -835,10 +835,10 @@ PyTypeObject PyModule_Type = { sizeof(PyModuleObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)module_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)module_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index aba3ff7b05e984..ddad39a910762b 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -207,10 +207,10 @@ PyTypeObject _PyNamespace_Type = { sizeof(_PyNamespaceObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)namespace_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)namespace_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/object.c b/Objects/object.c index f9c75b7c6a4e95..585a9748c84671 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -666,7 +666,7 @@ PyObject_Bytes(PyObject *v) /* For Python 3.0.1 and later, the old three-way comparison has been completely removed in favour of rich comparisons. PyObject_Compare() and PyObject_Cmp() are gone, and the builtin cmp function no longer exists. - The old tp_compare slot has been renamed to tp_reserved, and should no + The old tp_compare slot has been renamed to tp_as_async, and should no longer be used. Use tp_richcompare instead. See (*) below for practical amendments. @@ -1638,10 +1638,10 @@ PyTypeObject _PyNone_Type = { 0, 0, none_dealloc, /*tp_dealloc*/ /*never called*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ none_repr, /*tp_repr*/ &none_as_number, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -1723,10 +1723,10 @@ PyTypeObject _PyNotImplemented_Type = { 0, 0, notimplemented_dealloc, /*tp_dealloc*/ /*never called*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ NotImplemented_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 773827d85b3aa8..4c9ae3bc934686 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1551,10 +1551,10 @@ PyTypeObject PyODict_Type = { sizeof(PyODictObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)odict_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)odict_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1823,10 +1823,10 @@ PyTypeObject PyODictIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)odictiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1916,10 +1916,10 @@ PyTypeObject PyODictKeys_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1983,10 +1983,10 @@ PyTypeObject PyODictItems_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2050,10 +2050,10 @@ PyTypeObject PyODictValues_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index ac868f6951c29c..239ace6f4235ed 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -669,10 +669,10 @@ PyTypeObject PyRange_Type = { sizeof(rangeobject), /* Basic object size */ 0, /* Item size for varobject */ (destructor)range_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)range_repr, /* tp_repr */ &range_as_number, /* tp_as_number */ &range_as_sequence, /* tp_as_sequence */ @@ -805,10 +805,10 @@ PyTypeObject PyRangeIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)PyObject_Del, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1008,10 +1008,10 @@ PyTypeObject PyLongRangeIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)longrangeiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/setobject.c b/Objects/setobject.c index 82e9639d2884ca..bd031600c1be66 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -909,10 +909,10 @@ PyTypeObject PySetIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)setiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2118,10 +2118,10 @@ PyTypeObject PySet_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)set_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)set_repr, /* tp_repr */ &set_as_number, /* tp_as_number */ &set_as_sequence, /* tp_as_sequence */ @@ -2216,10 +2216,10 @@ PyTypeObject PyFrozenSet_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)set_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)set_repr, /* tp_repr */ &frozenset_as_number, /* tp_as_number */ &set_as_sequence, /* tp_as_sequence */ @@ -2532,10 +2532,10 @@ static PyTypeObject _PySetDummy_Type = { 0, 0, dummy_dealloc, /*tp_dealloc*/ /*never called*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ dummy_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 2dcb44fdee57ed..7c10eb6f638d3a 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -53,10 +53,10 @@ PyTypeObject PyEllipsis_Type = { 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /*never called*/ /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ ellipsis_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -625,10 +625,10 @@ PyTypeObject PySlice_Type = { sizeof(PySliceObject), /* Basic object size */ 0, /* Item size for varobject */ (destructor)slice_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)slice_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h index baaac811a56ed0..0fa54eb32cd361 100644 --- a/Objects/stringlib/unicode_format.h +++ b/Objects/stringlib/unicode_format.h @@ -1066,10 +1066,10 @@ static PyTypeObject PyFormatterIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)formatteriter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1202,10 +1202,10 @@ static PyTypeObject PyFieldNameIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)fieldnameiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 72556adb620746..fc2d2742dd2ca6 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -830,10 +830,10 @@ PyTypeObject PyTuple_Type = { sizeof(PyTupleObject) - sizeof(PyObject *), sizeof(PyObject *), (destructor)tupledealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)tuplerepr, /* tp_repr */ 0, /* tp_as_number */ &tuple_as_sequence, /* tp_as_sequence */ @@ -1067,10 +1067,10 @@ PyTypeObject PyTupleIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)tupleiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ac5a68681d15d0..64c2ceab5573f4 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3608,10 +3608,10 @@ PyTypeObject PyType_Type = { sizeof(PyHeapTypeObject), /* tp_basicsize */ sizeof(PyMemberDef), /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)type_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -4784,10 +4784,10 @@ PyTypeObject PyBaseObject_Type = { sizeof(PyObject), /* tp_basicsize */ 0, /* tp_itemsize */ object_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ object_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -5143,7 +5143,6 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) type->tp_setattr = base->tp_setattr; type->tp_setattro = base->tp_setattro; } - /* tp_reserved is ignored */ COPYSLOT(tp_repr); /* tp_hash see tp_richcompare */ COPYSLOT(tp_call); @@ -7920,10 +7919,10 @@ PyTypeObject PySuper_Type = { 0, /* tp_itemsize */ /* methods */ super_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ super_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index eafda633a3e2ff..6ec4127ff385b3 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8106,10 +8106,10 @@ static PyTypeObject EncodingMapType = { 0, /*tp_itemsize*/ /* methods */ 0, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -15155,10 +15155,10 @@ PyTypeObject PyUnicode_Type = { 0, /* tp_itemsize */ /* Slots */ (destructor)unicode_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ unicode_repr, /* tp_repr */ &unicode_as_number, /* tp_as_number */ &unicode_as_sequence, /* tp_as_sequence */ @@ -15483,10 +15483,10 @@ PyTypeObject PyUnicodeIter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)unicodeiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index ff6d92254f7fe2..8b8e71031afa6b 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -354,10 +354,10 @@ _PyWeakref_RefType = { sizeof(PyWeakReference), 0, weakref_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ (reprfunc)weakref_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -674,10 +674,10 @@ _PyWeakref_ProxyType = { 0, /* methods */ (destructor)proxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)proxy_repr, /* tp_repr */ &proxy_as_number, /* tp_as_number */ &proxy_as_sequence, /* tp_as_sequence */ @@ -708,10 +708,10 @@ _PyWeakref_CallableProxyType = { 0, /* methods */ (destructor)proxy_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (unaryfunc)proxy_repr, /* tp_repr */ &proxy_as_number, /* tp_as_number */ &proxy_as_sequence, /* tp_as_sequence */ diff --git a/PC/_msi.c b/PC/_msi.c index ae30acbc9b48d4..4c8df5b42b95c6 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -491,10 +491,10 @@ static PyTypeObject record_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)msiobj_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -677,10 +677,10 @@ static PyTypeObject summary_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)msiobj_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -826,10 +826,10 @@ static PyTypeObject msiview_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)msiobj_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ @@ -944,10 +944,10 @@ static PyTypeObject msidb_Type = { 0, /*tp_itemsize*/ /* methods */ (destructor)msiobj_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ diff --git a/PC/winreg.c b/PC/winreg.c index 5469fcba044432..5f5fc85d225075 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -355,10 +355,10 @@ PyTypeObject PyHKEY_Type = sizeof(PyHKEYObject), 0, PyHKEY_deallocFunc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ &PyHKEY_NumberMethods, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index d84c1b13cf103c..582c6ca57b65c4 100644 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -734,10 +734,10 @@ def visitModule(self, mod): sizeof(AST_object), 0, (destructor)ast_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 7c8e438658f7fa..dc2b1304f1f20b 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -640,10 +640,10 @@ static PyTypeObject AST_type = { sizeof(AST_object), 0, (destructor)ast_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 48dadcc9d4964d..56d882d387eeed 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -611,10 +611,10 @@ PyTypeObject PyFilter_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)filter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -1328,10 +1328,10 @@ PyTypeObject PyMap_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)map_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -2667,10 +2667,10 @@ PyTypeObject PyZip_Type = { 0, /* tp_itemsize */ /* methods */ (destructor)zip_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Python/symtable.c b/Python/symtable.c index fe6bc9aca4d08f..668cc21b2df987 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -140,10 +140,10 @@ PyTypeObject PySTEntry_Type = { sizeof(PySTEntryObject), 0, (destructor)ste_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)ste_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ diff --git a/Python/traceback.c b/Python/traceback.c index 04b52ad7680a11..0463eb6d8c98e7 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -192,10 +192,10 @@ PyTypeObject PyTraceBack_Type = { sizeof(PyTracebackObject), 0, (destructor)tb_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ + 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ - 0, /*tp_reserved*/ + 0, /*tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ From 65fb2c08c0d66fcf96fb1eb06270feadec830866 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 31 May 2019 10:39:15 +0300 Subject: [PATCH 209/441] bpo-339827: Do not swallow exceptions in the _ssl module. (GH-12756) --- Modules/_ssl.c | 89 +++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 755097256acb30..4fb7dca9bb04ae 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -590,19 +590,18 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, key = Py_BuildValue("ii", lib, reason); if (key == NULL) goto fail; - reason_obj = PyDict_GetItem(err_codes_to_names, key); + reason_obj = PyDict_GetItemWithError(err_codes_to_names, key); Py_DECREF(key); - if (reason_obj == NULL) { - /* XXX if reason < 100, it might reflect a library number (!!) */ - PyErr_Clear(); + if (reason_obj == NULL && PyErr_Occurred()) { + goto fail; } key = PyLong_FromLong(lib); if (key == NULL) goto fail; - lib_obj = PyDict_GetItem(lib_codes_to_names, key); + lib_obj = PyDict_GetItemWithError(lib_codes_to_names, key); Py_DECREF(key); - if (lib_obj == NULL) { - PyErr_Clear(); + if (lib_obj == NULL && PyErr_Occurred()) { + goto fail; } if (errstr == NULL) errstr = ERR_reason_error_string(errcode); @@ -3682,7 +3681,7 @@ _pwinfo_set(_PySSLPasswordInfo *pw_info, PyObject* password, Py_ssize_t size; if (PyUnicode_Check(password)) { - password_bytes = PyUnicode_AsEncodedString(password, NULL, NULL); + password_bytes = PyUnicode_AsUTF8String(password); if (!password_bytes) { goto error; } @@ -3787,13 +3786,17 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, if (keyfile == Py_None) keyfile = NULL; if (!PyUnicode_FSConverter(certfile, &certfile_bytes)) { - PyErr_SetString(PyExc_TypeError, - "certfile should be a valid filesystem path"); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "certfile should be a valid filesystem path"); + } return NULL; } if (keyfile && !PyUnicode_FSConverter(keyfile, &keyfile_bytes)) { - PyErr_SetString(PyExc_TypeError, - "keyfile should be a valid filesystem path"); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "keyfile should be a valid filesystem path"); + } goto error; } if (password && password != Py_None) { @@ -3985,22 +3988,44 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, goto error; } if (cafile && !PyUnicode_FSConverter(cafile, &cafile_bytes)) { - PyErr_SetString(PyExc_TypeError, - "cafile should be a valid filesystem path"); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "cafile should be a valid filesystem path"); + } goto error; } if (capath && !PyUnicode_FSConverter(capath, &capath_bytes)) { - PyErr_SetString(PyExc_TypeError, - "capath should be a valid filesystem path"); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "capath should be a valid filesystem path"); + } goto error; } /* validata cadata type and load cadata */ if (cadata) { - Py_buffer buf; - PyObject *cadata_ascii = NULL; - - if (PyObject_GetBuffer(cadata, &buf, PyBUF_SIMPLE) == 0) { + if (PyUnicode_Check(cadata)) { + PyObject *cadata_ascii = PyUnicode_AsASCIIString(cadata); + if (cadata_ascii == NULL) { + if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + goto invalid_cadata; + } + goto error; + } + r = _add_ca_certs(self, + PyBytes_AS_STRING(cadata_ascii), + PyBytes_GET_SIZE(cadata_ascii), + SSL_FILETYPE_PEM); + Py_DECREF(cadata_ascii); + if (r == -1) { + goto error; + } + } + else if (PyObject_CheckBuffer(cadata)) { + Py_buffer buf; + if (PyObject_GetBuffer(cadata, &buf, PyBUF_SIMPLE)) { + goto error; + } if (!PyBuffer_IsContiguous(&buf, 'C') || buf.ndim > 1) { PyBuffer_Release(&buf); PyErr_SetString(PyExc_TypeError, @@ -4013,23 +4038,13 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, if (r == -1) { goto error; } - } else { - PyErr_Clear(); - cadata_ascii = PyUnicode_AsASCIIString(cadata); - if (cadata_ascii == NULL) { - PyErr_SetString(PyExc_TypeError, - "cadata should be an ASCII string or a " - "bytes-like object"); - goto error; - } - r = _add_ca_certs(self, - PyBytes_AS_STRING(cadata_ascii), - PyBytes_GET_SIZE(cadata_ascii), - SSL_FILETYPE_PEM); - Py_DECREF(cadata_ascii); - if (r == -1) { - goto error; - } + } + else { + invalid_cadata: + PyErr_SetString(PyExc_TypeError, + "cadata should be an ASCII string or a " + "bytes-like object"); + goto error; } } From 14a0e16c8805f7ba7c98132ead815dcfdf0e9d33 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 31 May 2019 10:39:47 +0300 Subject: [PATCH 210/441] bpo-36548: Improve the repr of re flags. (GH-12715) --- Lib/re.py | 48 ++++++++++++------- Lib/test/test_re.py | 12 +++++ .../2019-04-07-14-30-10.bpo-36548.CJQiYw.rst | 1 + 3 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst diff --git a/Lib/re.py b/Lib/re.py index 68d62dc2a93b05..8f1d55ddf7d69d 100644 --- a/Lib/re.py +++ b/Lib/re.py @@ -141,24 +141,40 @@ __version__ = "2.2.1" class RegexFlag(enum.IntFlag): - ASCII = sre_compile.SRE_FLAG_ASCII # assume ascii "locale" - IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case - LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale - UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale" - MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline - DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline - VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments - A = ASCII - I = IGNORECASE - L = LOCALE - U = UNICODE - M = MULTILINE - S = DOTALL - X = VERBOSE + ASCII = A = sre_compile.SRE_FLAG_ASCII # assume ascii "locale" + IGNORECASE = I = sre_compile.SRE_FLAG_IGNORECASE # ignore case + LOCALE = L = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale + UNICODE = U = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale" + MULTILINE = M = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline + DOTALL = S = sre_compile.SRE_FLAG_DOTALL # make dot match newline + VERBOSE = X = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments # sre extensions (experimental, don't rely on these) - TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking - T = TEMPLATE + TEMPLATE = T = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation + + def __repr__(self): + if self._name_ is not None: + return f're.{self._name_}' + value = self._value_ + members = [] + negative = value < 0 + if negative: + value = ~value + for m in self.__class__: + if value & m._value_: + value &= ~m._value_ + members.append(f're.{m._name_}') + if value: + members.append(hex(value)) + res = '|'.join(members) + if negative: + if len(members) > 1: + res = f'~({res})' + else: + res = f'~{res}' + return res + __str__ = object.__str__ + globals().update(RegexFlag.__members__) # sre exception diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 137c31de59ae4a..4817d761a22df9 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -2170,6 +2170,18 @@ def test_long_pattern(self): self.assertEqual(r[:30], "re.compile('Very long long lon") self.assertEqual(r[-16:], ", re.IGNORECASE)") + def test_flags_repr(self): + self.assertEqual(repr(re.I), "re.IGNORECASE") + self.assertEqual(repr(re.I|re.S|re.X), + "re.IGNORECASE|re.DOTALL|re.VERBOSE") + self.assertEqual(repr(re.I|re.S|re.X|(1<<20)), + "re.IGNORECASE|re.DOTALL|re.VERBOSE|0x100000") + self.assertEqual(repr(~re.I), "~re.IGNORECASE") + self.assertEqual(repr(~(re.I|re.S|re.X)), + "~(re.IGNORECASE|re.DOTALL|re.VERBOSE)") + self.assertEqual(repr(~(re.I|re.S|re.X|(1<<20))), + "~(re.IGNORECASE|re.DOTALL|re.VERBOSE|0x100000)") + class ImplementationTest(unittest.TestCase): """ diff --git a/Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst b/Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst new file mode 100644 index 00000000000000..e72bb91174048e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst @@ -0,0 +1 @@ +Improved the repr of regular expression flags. From ba0430211f5101c9d748d72b03926ca79c5252a8 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 31 May 2019 04:26:35 -0400 Subject: [PATCH 211/441] IDLE - Capitalize search dialogs' 'Close' button label. (#13691) It seems to be the only widget label not capitalized. --- Lib/idlelib/idle_test/test_searchbase.py | 3 ++- Lib/idlelib/searchbase.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/idle_test/test_searchbase.py b/Lib/idlelib/idle_test/test_searchbase.py index 09a7fff51de1dc..6dd4d79337371d 100644 --- a/Lib/idlelib/idle_test/test_searchbase.py +++ b/Lib/idlelib/idle_test/test_searchbase.py @@ -32,6 +32,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): + cls.root.update_idletasks() cls.root.destroy() del cls.root @@ -149,7 +150,7 @@ def test_create_command_buttons(self): # Look for close button command in buttonframe closebuttoncommand = '' for child in self.dialog.buttonframe.winfo_children(): - if child['text'] == 'close': + if child['text'] == 'Close': closebuttoncommand = child['command'] self.assertIn('close', closebuttoncommand) diff --git a/Lib/idlelib/searchbase.py b/Lib/idlelib/searchbase.py index f0e3d6f14ba49b..74ba8538512b9d 100644 --- a/Lib/idlelib/searchbase.py +++ b/Lib/idlelib/searchbase.py @@ -172,7 +172,7 @@ def create_command_buttons(self): f = self.buttonframe = Frame(self.top) f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2) - b = self.make_button("close", self.close) + b = self.make_button("Close", self.close) b.lower() From 38ab7d4721b422547f7b46b9d68968863fa70573 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 31 May 2019 11:29:39 +0300 Subject: [PATCH 212/441] bpo-31829: Make protocol 0 pickles be loadable in text mode in Python 2. (GH-11859) Escape ``\r``, ``\0`` and ``\x1a`` (end-of-file on Windows) in Unicode strings. --- Lib/pickle.py | 3 +++ Lib/test/pickletester.py | 19 +++++++++++++++---- .../2017-10-21-12-07-56.bpo-31829.6IhP-O.rst | 3 +++ Modules/_pickle.c | 5 ++++- 4 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-10-21-12-07-56.bpo-31829.6IhP-O.rst diff --git a/Lib/pickle.py b/Lib/pickle.py index cb768b28586a1d..a67ac7dd8b686a 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -852,7 +852,10 @@ def save_str(self, obj): self.write(BINUNICODE + pack("= 256 || ch == '\\' || ch == '\n') { + else if (ch >= 256 || + ch == '\\' || ch == 0 || ch == '\n' || ch == '\r' || + ch == 0x1a) + { /* -1: subtract 1 preallocated byte */ p = _PyBytesWriter_Prepare(&writer, p, 6-1); if (p == NULL) From e9b51c0ad81da1da11ae65840ac8b50a8521373c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 31 May 2019 11:30:37 +0300 Subject: [PATCH 213/441] bpo-26660, bpo-35144: Fix permission errors in TemporaryDirectory cleanup. (GH-10320) TemporaryDirectory.cleanup() failed when non-writeable or non-searchable files or directories were created inside a temporary directory. --- Lib/shutil.py | 11 ++-- Lib/tempfile.py | 34 ++++++++++++- Lib/test/test_tempfile.py | 51 +++++++++++++++---- .../2018-11-04-16-39-46.bpo-26660.RdXz8a.rst | 4 ++ 4 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst diff --git a/Lib/shutil.py b/Lib/shutil.py index dae916b41605c6..6486cd6e5d2856 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -584,11 +584,16 @@ def _rmtree_safe_fd(topfd, path, onerror): fullname = os.path.join(path, entry.name) try: is_dir = entry.is_dir(follow_symlinks=False) - if is_dir: - orig_st = entry.stat(follow_symlinks=False) - is_dir = stat.S_ISDIR(orig_st.st_mode) except OSError: is_dir = False + else: + if is_dir: + try: + orig_st = entry.stat(follow_symlinks=False) + is_dir = stat.S_ISDIR(orig_st.st_mode) + except OSError: + onerror(os.lstat, fullname, sys.exc_info()) + continue if is_dir: try: dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd) diff --git a/Lib/tempfile.py b/Lib/tempfile.py index a66d6f3750cb65..e8b111eae223aa 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -777,9 +777,39 @@ def __init__(self, suffix=None, prefix=None, dir=None): self, self._cleanup, self.name, warn_message="Implicitly cleaning up {!r}".format(self)) + @classmethod + def _rmtree(cls, name): + def onerror(func, path, exc_info): + if issubclass(exc_info[0], PermissionError): + def resetperms(path): + try: + _os.chflags(path, 0) + except AttributeError: + pass + _os.chmod(path, 0o700) + + try: + if path != name: + resetperms(_os.path.dirname(path)) + resetperms(path) + + try: + _os.unlink(path) + # PermissionError is raised on FreeBSD for directories + except (IsADirectoryError, PermissionError): + cls._rmtree(path) + except FileNotFoundError: + pass + elif issubclass(exc_info[0], FileNotFoundError): + pass + else: + raise + + _shutil.rmtree(name, onerror=onerror) + @classmethod def _cleanup(cls, name, warn_message): - _shutil.rmtree(name) + cls._rmtree(name) _warnings.warn(warn_message, ResourceWarning) def __repr__(self): @@ -793,4 +823,4 @@ def __exit__(self, exc, value, tb): def cleanup(self): if self._finalizer.detach(): - _shutil.rmtree(self.name) + self._rmtree(self.name) diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 489141d6ad726a..bd4db839331b49 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1297,19 +1297,25 @@ def __exit__(self, *exc_info): class TestTemporaryDirectory(BaseTestCase): """Test TemporaryDirectory().""" - def do_create(self, dir=None, pre="", suf="", recurse=1): + def do_create(self, dir=None, pre="", suf="", recurse=1, dirs=1, files=1): if dir is None: dir = tempfile.gettempdir() tmp = tempfile.TemporaryDirectory(dir=dir, prefix=pre, suffix=suf) self.nameCheck(tmp.name, dir, pre, suf) - # Create a subdirectory and some files - if recurse: - d1 = self.do_create(tmp.name, pre, suf, recurse-1) - d1.name = None - with open(os.path.join(tmp.name, "test.txt"), "wb") as f: - f.write(b"Hello world!") + self.do_create2(tmp.name, recurse, dirs, files) return tmp + def do_create2(self, path, recurse=1, dirs=1, files=1): + # Create subdirectories and some files + if recurse: + for i in range(dirs): + name = os.path.join(path, "dir%d" % i) + os.mkdir(name) + self.do_create2(name, recurse-1, dirs, files) + for i in range(files): + with open(os.path.join(path, "test%d.txt" % i), "wb") as f: + f.write(b"Hello world!") + def test_mkdtemp_failure(self): # Check no additional exception if mkdtemp fails # Previously would raise AttributeError instead @@ -1349,7 +1355,7 @@ def test_cleanup_with_symlink_to_a_directory(self): "TemporaryDirectory %s exists after cleanup" % d1.name) self.assertTrue(os.path.exists(d2.name), "Directory pointed to by a symlink was deleted") - self.assertEqual(os.listdir(d2.name), ['test.txt'], + self.assertEqual(os.listdir(d2.name), ['test0.txt'], "Contents of the directory pointed to by a symlink " "were deleted") d2.cleanup() @@ -1384,7 +1390,7 @@ def test_del_on_shutdown(self): tmp2 = os.path.join(tmp.name, 'test_dir') os.mkdir(tmp2) - with open(os.path.join(tmp2, "test.txt"), "w") as f: + with open(os.path.join(tmp2, "test0.txt"), "w") as f: f.write("Hello world!") {mod}.tmp = tmp @@ -1452,6 +1458,33 @@ def test_context_manager(self): self.assertEqual(name, d.name) self.assertFalse(os.path.exists(name)) + def test_modes(self): + for mode in range(8): + mode <<= 6 + with self.subTest(mode=format(mode, '03o')): + d = self.do_create(recurse=3, dirs=2, files=2) + with d: + # Change files and directories mode recursively. + for root, dirs, files in os.walk(d.name, topdown=False): + for name in files: + os.chmod(os.path.join(root, name), mode) + os.chmod(root, mode) + d.cleanup() + self.assertFalse(os.path.exists(d.name)) + + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.lchflags') + def test_flags(self): + flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + d = self.do_create(recurse=3, dirs=2, files=2) + with d: + # Change files and directories flags recursively. + for root, dirs, files in os.walk(d.name, topdown=False): + for name in files: + os.chflags(os.path.join(root, name), flags) + os.chflags(root, flags) + d.cleanup() + self.assertFalse(os.path.exists(d.name)) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst b/Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst new file mode 100644 index 00000000000000..4448bf6b0164d0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst @@ -0,0 +1,4 @@ +Fixed permission errors in :class:`~tempfile.TemporaryDirectory` clean up. +Previously ``TemporaryDirectory.cleanup()`` failed when non-writeable or +non-searchable files or directories were created inside a temporary +directory. From c7f7069e77c58e83b847c0bfe4d5aadf6add2e68 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 31 May 2019 11:44:05 +0200 Subject: [PATCH 214/441] bpo-34271: Add ssl debugging helpers (GH-10031) The ssl module now can dump key material to a keylog file and trace TLS protocol messages with a tracing callback. The default and stdlib contexts also support SSLKEYLOGFILE env var. The msg_callback and related enums are private members. The feature is designed for internal debugging and not for end users. Signed-off-by: Christian Heimes --- Doc/library/ssl.rst | 23 ++ Lib/ssl.py | 172 +++++++++++++- Lib/test/test_ssl.py | 168 +++++++++++++- .../2018-10-21-17-39-32.bpo-34271.P15VLM.rst | 3 + Modules/_ssl.c | 104 ++++++++- Modules/_ssl/debughelpers.c | 213 ++++++++++++++++++ setup.py | 12 +- 7 files changed, 677 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst create mode 100644 Modules/_ssl/debughelpers.c diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 20f5724447164d..be09f38f7dfa0b 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -139,6 +139,10 @@ purposes. *cadata* is given) or uses :meth:`SSLContext.load_default_certs` to load default CA certificates. + When :attr:`~SSLContext.keylog_filename` is supported and the environment + variable :envvar:`SSLKEYLOGFILE` is set, :func:`create_default_context` + enables key logging. + .. note:: The protocol, options, cipher and other settings may change to more restrictive values anytime without prior deprecation. The values @@ -172,6 +176,10 @@ purposes. 3DES was dropped from the default cipher string. + .. versionchanged:: 3.8 + + Support for key logging to :envvar:`SSLKEYLOGFILE` was added. + Exceptions ^^^^^^^^^^ @@ -1056,6 +1064,7 @@ Constants SSL 3.0 to TLS 1.3. + SSL Sockets ----------- @@ -1901,6 +1910,20 @@ to speed up repeated connections from the same clients. This features requires OpenSSL 0.9.8f or newer. +.. attribute:: SSLContext.keylog_filename + + Write TLS keys to a keylog file, whenever key material is generated or + received. The keylog file is designed for debugging purposes only. The + file format is specified by NSS and used by many traffic analyzers such + as Wireshark. The log file is opened in append-only mode. Writes are + synchronized between threads, but not between processes. + + .. versionadded:: 3.8 + + .. note:: + + This features requires OpenSSL 1.1.1 or newer. + .. attribute:: SSLContext.maximum_version A :class:`TLSVersion` enum member representing the highest supported diff --git a/Lib/ssl.py b/Lib/ssl.py index 793ed496c77af4..f5fa6aeec2d21b 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -165,6 +165,90 @@ class TLSVersion(_IntEnum): MAXIMUM_SUPPORTED = _ssl.PROTO_MAXIMUM_SUPPORTED +class _TLSContentType(_IntEnum): + """Content types (record layer) + + See RFC 8446, section B.1 + """ + CHANGE_CIPHER_SPEC = 20 + ALERT = 21 + HANDSHAKE = 22 + APPLICATION_DATA = 23 + # pseudo content types + HEADER = 0x100 + INNER_CONTENT_TYPE = 0x101 + + +class _TLSAlertType(_IntEnum): + """Alert types for TLSContentType.ALERT messages + + See RFC 8466, section B.2 + """ + CLOSE_NOTIFY = 0 + UNEXPECTED_MESSAGE = 10 + BAD_RECORD_MAC = 20 + DECRYPTION_FAILED = 21 + RECORD_OVERFLOW = 22 + DECOMPRESSION_FAILURE = 30 + HANDSHAKE_FAILURE = 40 + NO_CERTIFICATE = 41 + BAD_CERTIFICATE = 42 + UNSUPPORTED_CERTIFICATE = 43 + CERTIFICATE_REVOKED = 44 + CERTIFICATE_EXPIRED = 45 + CERTIFICATE_UNKNOWN = 46 + ILLEGAL_PARAMETER = 47 + UNKNOWN_CA = 48 + ACCESS_DENIED = 49 + DECODE_ERROR = 50 + DECRYPT_ERROR = 51 + EXPORT_RESTRICTION = 60 + PROTOCOL_VERSION = 70 + INSUFFICIENT_SECURITY = 71 + INTERNAL_ERROR = 80 + INAPPROPRIATE_FALLBACK = 86 + USER_CANCELED = 90 + NO_RENEGOTIATION = 100 + MISSING_EXTENSION = 109 + UNSUPPORTED_EXTENSION = 110 + CERTIFICATE_UNOBTAINABLE = 111 + UNRECOGNIZED_NAME = 112 + BAD_CERTIFICATE_STATUS_RESPONSE = 113 + BAD_CERTIFICATE_HASH_VALUE = 114 + UNKNOWN_PSK_IDENTITY = 115 + CERTIFICATE_REQUIRED = 116 + NO_APPLICATION_PROTOCOL = 120 + + +class _TLSMessageType(_IntEnum): + """Message types (handshake protocol) + + See RFC 8446, section B.3 + """ + HELLO_REQUEST = 0 + CLIENT_HELLO = 1 + SERVER_HELLO = 2 + HELLO_VERIFY_REQUEST = 3 + NEWSESSION_TICKET = 4 + END_OF_EARLY_DATA = 5 + HELLO_RETRY_REQUEST = 6 + ENCRYPTED_EXTENSIONS = 8 + CERTIFICATE = 11 + SERVER_KEY_EXCHANGE = 12 + CERTIFICATE_REQUEST = 13 + SERVER_DONE = 14 + CERTIFICATE_VERIFY = 15 + CLIENT_KEY_EXCHANGE = 16 + FINISHED = 20 + CERTIFICATE_URL = 21 + CERTIFICATE_STATUS = 22 + SUPPLEMENTAL_DATA = 23 + KEY_UPDATE = 24 + NEXT_PROTO = 67 + MESSAGE_HASH = 254 + CHANGE_CIPHER_SPEC = 0x0101 + + if sys.platform == "win32": from _ssl import enum_certificates, enum_crls @@ -523,6 +607,83 @@ def hostname_checks_common_name(self, value): def hostname_checks_common_name(self): return True + @property + def _msg_callback(self): + """TLS message callback + + The message callback provides a debugging hook to analyze TLS + connections. The callback is called for any TLS protocol message + (header, handshake, alert, and more), but not for application data. + Due to technical limitations, the callback can't be used to filter + traffic or to abort a connection. Any exception raised in the + callback is delayed until the handshake, read, or write operation + has been performed. + + def msg_cb(conn, direction, version, content_type, msg_type, data): + pass + + conn + :class:`SSLSocket` or :class:`SSLObject` instance + direction + ``read`` or ``write`` + version + :class:`TLSVersion` enum member or int for unknown version. For a + frame header, it's the header version. + content_type + :class:`_TLSContentType` enum member or int for unsupported + content type. + msg_type + Either a :class:`_TLSContentType` enum number for a header + message, a :class:`_TLSAlertType` enum member for an alert + message, a :class:`_TLSMessageType` enum member for other + messages, or int for unsupported message types. + data + Raw, decrypted message content as bytes + """ + inner = super()._msg_callback + if inner is not None: + return inner.user_function + else: + return None + + @_msg_callback.setter + def _msg_callback(self, callback): + if callback is None: + super(SSLContext, SSLContext)._msg_callback.__set__(self, None) + return + + if not hasattr(callback, '__call__'): + raise TypeError(f"{callback} is not callable.") + + def inner(conn, direction, version, content_type, msg_type, data): + try: + version = TLSVersion(version) + except TypeError: + pass + + try: + content_type = _TLSContentType(content_type) + except TypeError: + pass + + if content_type == _TLSContentType.HEADER: + msg_enum = _TLSContentType + elif content_type == _TLSContentType.ALERT: + msg_enum = _TLSAlertType + else: + msg_enum = _TLSMessageType + try: + msg_type = msg_enum(msg_type) + except TypeError: + pass + + return callback(conn, direction, version, + content_type, msg_type, data) + + inner.user_function = callback + + super(SSLContext, SSLContext)._msg_callback.__set__(self, inner) + @property def protocol(self): return _SSLMethod(super().protocol) @@ -576,6 +737,11 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system # root CA certificates for the given purpose. This may fail silently. context.load_default_certs(purpose) + # OpenSSL 1.1.1 keylog file + if hasattr(context, 'keylog_filename'): + keylogfile = os.environ.get('SSLKEYLOGFILE') + if keylogfile and not sys.flags.ignore_environment: + context.keylog_filename = keylogfile return context def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE, @@ -617,7 +783,11 @@ def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE, # CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system # root CA certificates for the given purpose. This may fail silently. context.load_default_certs(purpose) - + # OpenSSL 1.1.1 keylog file + if hasattr(context, 'keylog_filename'): + keylogfile = os.environ.get('SSLKEYLOGFILE') + if keylogfile and not sys.flags.ignore_environment: + context.keylog_filename = keylogfile return context # Used by http.client if no context is explicitly passed. diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index d48d6e5569fc3e..f368906c8a94f9 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2,6 +2,7 @@ import sys import unittest +import unittest.mock from test import support import socket import select @@ -25,6 +26,7 @@ ssl = support.import_module("ssl") +from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) HOST = support.HOST @@ -4405,6 +4407,170 @@ def test_pha_not_tls13(self): self.assertIn(b'WRONG_SSL_VERSION', s.recv(1024)) +HAS_KEYLOG = hasattr(ssl.SSLContext, 'keylog_filename') +requires_keylog = unittest.skipUnless( + HAS_KEYLOG, 'test requires OpenSSL 1.1.1 with keylog callback') + +class TestSSLDebug(unittest.TestCase): + + def keylog_lines(self, fname=support.TESTFN): + with open(fname) as f: + return len(list(f)) + + @requires_keylog + def test_keylog_defaults(self): + self.addCleanup(support.unlink, support.TESTFN) + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + self.assertEqual(ctx.keylog_filename, None) + + self.assertFalse(os.path.isfile(support.TESTFN)) + ctx.keylog_filename = support.TESTFN + self.assertEqual(ctx.keylog_filename, support.TESTFN) + self.assertTrue(os.path.isfile(support.TESTFN)) + self.assertEqual(self.keylog_lines(), 1) + + ctx.keylog_filename = None + self.assertEqual(ctx.keylog_filename, None) + + with self.assertRaises((IsADirectoryError, PermissionError)): + # Windows raises PermissionError + ctx.keylog_filename = os.path.dirname( + os.path.abspath(support.TESTFN)) + + with self.assertRaises(TypeError): + ctx.keylog_filename = 1 + + @requires_keylog + def test_keylog_filename(self): + self.addCleanup(support.unlink, support.TESTFN) + client_context, server_context, hostname = testing_context() + + client_context.keylog_filename = support.TESTFN + server = ThreadedEchoServer(context=server_context, chatty=False) + with server: + with client_context.wrap_socket(socket.socket(), + server_hostname=hostname) as s: + s.connect((HOST, server.port)) + # header, 5 lines for TLS 1.3 + self.assertEqual(self.keylog_lines(), 6) + + client_context.keylog_filename = None + server_context.keylog_filename = support.TESTFN + server = ThreadedEchoServer(context=server_context, chatty=False) + with server: + with client_context.wrap_socket(socket.socket(), + server_hostname=hostname) as s: + s.connect((HOST, server.port)) + self.assertGreaterEqual(self.keylog_lines(), 11) + + client_context.keylog_filename = support.TESTFN + server_context.keylog_filename = support.TESTFN + server = ThreadedEchoServer(context=server_context, chatty=False) + with server: + with client_context.wrap_socket(socket.socket(), + server_hostname=hostname) as s: + s.connect((HOST, server.port)) + self.assertGreaterEqual(self.keylog_lines(), 21) + + client_context.keylog_filename = None + server_context.keylog_filename = None + + @requires_keylog + @unittest.skipIf(sys.flags.ignore_environment, + "test is not compatible with ignore_environment") + def test_keylog_env(self): + self.addCleanup(support.unlink, support.TESTFN) + with unittest.mock.patch.dict(os.environ): + os.environ['SSLKEYLOGFILE'] = support.TESTFN + self.assertEqual(os.environ['SSLKEYLOGFILE'], support.TESTFN) + + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + self.assertEqual(ctx.keylog_filename, None) + + ctx = ssl.create_default_context() + self.assertEqual(ctx.keylog_filename, support.TESTFN) + + ctx = ssl._create_stdlib_context() + self.assertEqual(ctx.keylog_filename, support.TESTFN) + + def test_msg_callback(self): + client_context, server_context, hostname = testing_context() + + def msg_cb(conn, direction, version, content_type, msg_type, data): + pass + + self.assertIs(client_context._msg_callback, None) + client_context._msg_callback = msg_cb + self.assertIs(client_context._msg_callback, msg_cb) + with self.assertRaises(TypeError): + client_context._msg_callback = object() + + def test_msg_callback_tls12(self): + client_context, server_context, hostname = testing_context() + client_context.options |= ssl.OP_NO_TLSv1_3 + + msg = [] + + def msg_cb(conn, direction, version, content_type, msg_type, data): + self.assertIsInstance(conn, ssl.SSLSocket) + self.assertIsInstance(data, bytes) + self.assertIn(direction, {'read', 'write'}) + msg.append((direction, version, content_type, msg_type)) + + client_context._msg_callback = msg_cb + + server = ThreadedEchoServer(context=server_context, chatty=False) + with server: + with client_context.wrap_socket(socket.socket(), + server_hostname=hostname) as s: + s.connect((HOST, server.port)) + + self.assertEqual(msg, [ + ("write", TLSVersion.TLSv1, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.CLIENT_HELLO), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.SERVER_HELLO), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.CERTIFICATE), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.SERVER_KEY_EXCHANGE), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.SERVER_DONE), + ("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.CLIENT_KEY_EXCHANGE), + ("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.FINISHED), + ("write", TLSVersion.TLSv1_2, _TLSContentType.CHANGE_CIPHER_SPEC, + _TLSMessageType.CHANGE_CIPHER_SPEC), + ("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.FINISHED), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.NEWSESSION_TICKET), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.FINISHED), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, + _TLSMessageType.CERTIFICATE_STATUS), + ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, + _TLSMessageType.FINISHED), + ]) + + def test_main(verbose=False): if support.verbose: import warnings @@ -4440,7 +4606,7 @@ def test_main(verbose=False): tests = [ ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests, SSLObjectTests, SimpleBackgroundTests, ThreadedTests, - TestPostHandshakeAuth + TestPostHandshakeAuth, TestSSLDebug ] if support.is_resource_enabled('network'): diff --git a/Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst b/Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst new file mode 100644 index 00000000000000..344388f7f2287f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst @@ -0,0 +1,3 @@ +Add debugging helpers to ssl module. It's now possible to dump key material +and to trace TLS protocol. The default and stdlib contexts also support +SSLKEYLOGFILE env var. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 4fb7dca9bb04ae..f40127d3d932bb 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -185,6 +185,10 @@ static void _PySSLFixErrno(void) { # define HAVE_NPN 0 #endif +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +#define HAVE_OPENSSL_KEYLOG 1 +#endif + #ifndef INVALID_SOCKET /* MS defines this */ #define INVALID_SOCKET (-1) #endif @@ -423,6 +427,11 @@ typedef struct { int protocol; #ifdef TLS1_3_VERSION int post_handshake_auth; +#endif + PyObject *msg_cb; +#ifdef HAVE_OPENSSL_KEYLOG + PyObject *keylog_filename; + BIO *keylog_bio; #endif } PySSLContext; @@ -444,6 +453,13 @@ typedef struct { PyObject *owner; /* Python level "owner" passed to servername callback */ PyObject *server_hostname; _PySSLError err; /* last seen error from various sources */ + /* Some SSL callbacks don't have error reporting. Callback wrappers + * store exception information on the socket. The handshake, read, write, + * and shutdown methods check for chained exceptions. + */ + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_tb; } PySSLSocket; typedef struct { @@ -517,6 +533,8 @@ typedef enum { #define GET_SOCKET_TIMEOUT(sock) \ ((sock != NULL) ? (sock)->sock_timeout : 0) +#include "_ssl/debughelpers.c" + /* * SSL errors. */ @@ -703,6 +721,18 @@ fill_and_set_sslerror(PySSLSocket *sslsock, PyObject *type, int ssl_errno, Py_XDECREF(verify_obj); } +static int +PySSL_ChainExceptions(PySSLSocket *sslsock) { + if (sslsock->exc_type == NULL) + return 0; + + _PyErr_ChainExceptions(sslsock->exc_type, sslsock->exc_value, sslsock->exc_tb); + sslsock->exc_type = NULL; + sslsock->exc_value = NULL; + sslsock->exc_tb = NULL; + return -1; +} + static PyObject * PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) { @@ -796,6 +826,7 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) } fill_and_set_sslerror(sslsock, type, p, errstr, lineno, e); ERR_clear_error(); + PySSL_ChainExceptions(sslsock); return NULL; } @@ -903,6 +934,9 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->owner = NULL; self->server_hostname = NULL; self->err = err; + self->exc_type = NULL; + self->exc_value = NULL; + self->exc_tb = NULL; /* Make sure the SSL error state is initialized */ ERR_clear_error(); @@ -1052,11 +1086,12 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self) Py_XDECREF(sock); if (ret < 1) return PySSL_SetError(self, ret, __FILE__, __LINE__); - + if (PySSL_ChainExceptions(self) < 0) + return NULL; Py_RETURN_NONE; - error: Py_XDECREF(sock); + PySSL_ChainExceptions(self); return NULL; } @@ -2151,8 +2186,26 @@ PyDoc_STRVAR(PySSL_get_owner_doc, "The Python-level owner of this object.\ Passed as \"self\" in servername callback."); +static int +PySSL_traverse(PySSLSocket *self, visitproc visit, void *arg) +{ + Py_VISIT(self->exc_type); + Py_VISIT(self->exc_value); + Py_VISIT(self->exc_tb); + return 0; +} + +static int +PySSL_clear(PySSLSocket *self) +{ + Py_CLEAR(self->exc_type); + Py_CLEAR(self->exc_value); + Py_CLEAR(self->exc_tb); + return 0; +} -static void PySSL_dealloc(PySSLSocket *self) +static void +PySSL_dealloc(PySSLSocket *self) { if (self->ssl) SSL_free(self->ssl); @@ -2333,13 +2386,14 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b) err.ssl == SSL_ERROR_WANT_WRITE); Py_XDECREF(sock); - if (len > 0) - return PyLong_FromLong(len); - else + if (len <= 0) return PySSL_SetError(self, len, __FILE__, __LINE__); - + if (PySSL_ChainExceptions(self) < 0) + return NULL; + return PyLong_FromLong(len); error: Py_XDECREF(sock); + PySSL_ChainExceptions(self); return NULL; } @@ -2486,6 +2540,8 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, PySSL_SetError(self, count, __FILE__, __LINE__); goto error; } + if (self->exc_type != NULL) + goto error; done: Py_XDECREF(sock); @@ -2498,6 +2554,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, int len, int group_right_1, } error: + PySSL_ChainExceptions(self); Py_XDECREF(sock); if (!group_right_1) Py_XDECREF(dest); @@ -2601,11 +2658,13 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) /* Retain the SSL error code */ break; } - if (ret < 0) { Py_XDECREF(sock); - return PySSL_SetError(self, ret, __FILE__, __LINE__); + PySSL_SetError(self, ret, __FILE__, __LINE__); + return NULL; } + if (self->exc_type != NULL) + goto error; if (sock) /* It's already INCREF'ed */ return (PyObject *) sock; @@ -2614,6 +2673,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) error: Py_XDECREF(sock); + PySSL_ChainExceptions(self); return NULL; } @@ -2889,8 +2949,8 @@ static PyTypeObject PySSLSocket_Type = { 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ + (traverseproc) PySSL_traverse, /*tp_traverse*/ + (inquiry) PySSL_clear, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ @@ -3002,6 +3062,11 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) self->ctx = ctx; self->hostflags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; self->protocol = proto_version; + self->msg_cb = NULL; +#ifdef HAVE_OPENSSL_KEYLOG + self->keylog_filename = NULL; + self->keylog_bio = NULL; +#endif #if HAVE_NPN self->npn_protocols = NULL; #endif @@ -3127,6 +3192,7 @@ context_traverse(PySSLContext *self, visitproc visit, void *arg) #ifndef OPENSSL_NO_TLSEXT Py_VISIT(self->set_sni_cb); #endif + Py_VISIT(self->msg_cb); return 0; } @@ -3135,6 +3201,16 @@ context_clear(PySSLContext *self) { #ifndef OPENSSL_NO_TLSEXT Py_CLEAR(self->set_sni_cb); +#endif + Py_CLEAR(self->msg_cb); +#ifdef HAVE_OPENSSL_KEYLOG + Py_CLEAR(self->keylog_filename); + if (self->keylog_bio != NULL) { + PySSL_BEGIN_ALLOW_THREADS + BIO_free_all(self->keylog_bio); + PySSL_END_ALLOW_THREADS + self->keylog_bio = NULL; + } #endif return 0; } @@ -4570,6 +4646,12 @@ static PyGetSetDef context_getsetlist[] = { {"maximum_version", (getter) get_maximum_version, (setter) set_maximum_version, NULL}, #endif +#ifdef HAVE_OPENSSL_KEYLOG + {"keylog_filename", (getter) _PySSLContext_get_keylog_filename, + (setter) _PySSLContext_set_keylog_filename, NULL}, +#endif + {"_msg_callback", (getter) _PySSLContext_get_msg_callback, + (setter) _PySSLContext_set_msg_callback, NULL}, {"sni_callback", (getter) get_sni_callback, (setter) set_sni_callback, PySSLContext_sni_callback_doc}, {"options", (getter) get_options, diff --git a/Modules/_ssl/debughelpers.c b/Modules/_ssl/debughelpers.c new file mode 100644 index 00000000000000..53b96674932805 --- /dev/null +++ b/Modules/_ssl/debughelpers.c @@ -0,0 +1,213 @@ +/* Debug helpers */ + +static void +_PySSL_msg_callback(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) +{ + const char *cbuf = (const char *)buf; + PyGILState_STATE threadstate; + PyObject *res = NULL; + PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ + PyObject *ssl_socket = NULL; /* ssl.SSLSocket or ssl.SSLObject */ + int msg_type; + + threadstate = PyGILState_Ensure(); + + ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); + assert(PySSLSocket_Check(ssl_obj)); + if (ssl_obj->ctx->msg_cb == NULL) { + return; + } + + if (ssl_obj->owner) + ssl_socket = PyWeakref_GetObject(ssl_obj->owner); + else if (ssl_obj->Socket) + ssl_socket = PyWeakref_GetObject(ssl_obj->Socket); + else + ssl_socket = (PyObject *)ssl_obj; + Py_INCREF(ssl_socket); + + /* assume that OpenSSL verifies all payload and buf len is of sufficient + length */ + switch(content_type) { + case SSL3_RT_CHANGE_CIPHER_SPEC: + msg_type = SSL3_MT_CHANGE_CIPHER_SPEC; + break; + case SSL3_RT_ALERT: + /* byte 0: level */ + /* byte 1: alert type */ + msg_type = (int)cbuf[1]; + break; + case SSL3_RT_HANDSHAKE: + msg_type = (int)cbuf[0]; + break; + case SSL3_RT_HEADER: + /* frame header encodes version in bytes 1..2 */ + version = cbuf[1] << 8 | cbuf[2]; + msg_type = (int)cbuf[0]; + break; +#ifdef SSL3_RT_INNER_CONTENT_TYPE + case SSL3_RT_INNER_CONTENT_TYPE: + msg_type = (int)cbuf[0]; + break; +#endif + default: + /* never SSL3_RT_APPLICATION_DATA */ + msg_type = -1; + break; + } + + res = PyObject_CallFunction( + ssl_obj->ctx->msg_cb, "Osiiiy#", + ssl_socket, write_p ? "write" : "read", + version, content_type, msg_type, + buf, len + ); + if (res == NULL) { + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + } else { + Py_DECREF(res); + } + Py_XDECREF(ssl_socket); + + PyGILState_Release(threadstate); +} + + +static PyObject * +_PySSLContext_get_msg_callback(PySSLContext *self, void *c) { + if (self->msg_cb != NULL) { + Py_INCREF(self->msg_cb); + return self->msg_cb; + } else { + Py_RETURN_NONE; + } +} + +static int +_PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) { + Py_CLEAR(self->msg_cb); + if (arg == Py_None) { + SSL_CTX_set_msg_callback(self->ctx, NULL); + } + else { + if (!PyCallable_Check(arg)) { + SSL_CTX_set_msg_callback(self->ctx, NULL); + PyErr_SetString(PyExc_TypeError, + "not a callable object"); + return -1; + } + Py_INCREF(arg); + self->msg_cb = arg; + SSL_CTX_set_msg_callback(self->ctx, _PySSL_msg_callback); + } + return 0; +} + +#ifdef HAVE_OPENSSL_KEYLOG + +static void +_PySSL_keylog_callback(const SSL *ssl, const char *line) +{ + PyGILState_STATE threadstate; + PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ + int res, e; + static PyThread_type_lock *lock = NULL; + + threadstate = PyGILState_Ensure(); + + /* Allocate a static lock to synchronize writes to keylog file. + * The lock is neither released on exit nor on fork(). The lock is + * also shared between all SSLContexts although contexts may write to + * their own files. IMHO that's good enough for a non-performance + * critical debug helper. + */ + if (lock == NULL) { + lock = PyThread_allocate_lock(); + if (lock == NULL) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, + &ssl_obj->exc_tb); + return; + } + } + + ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); + assert(PySSLSocket_Check(ssl_obj)); + if (ssl_obj->ctx->keylog_bio == NULL) { + return; + } + + PySSL_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(lock, 1); + res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line); + e = errno; + (void)BIO_flush(ssl_obj->ctx->keylog_bio); + PyThread_release_lock(lock); + PySSL_END_ALLOW_THREADS + + if (res == -1) { + errno = e; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, + ssl_obj->ctx->keylog_filename); + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + } + PyGILState_Release(threadstate); +} + +static PyObject * +_PySSLContext_get_keylog_filename(PySSLContext *self, void *c) { + if (self->keylog_filename != NULL) { + Py_INCREF(self->keylog_filename); + return self->keylog_filename; + } else { + Py_RETURN_NONE; + } +} + +static int +_PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { + FILE *fp; + /* Reset variables and callback first */ + SSL_CTX_set_keylog_callback(self->ctx, NULL); + Py_CLEAR(self->keylog_filename); + if (self->keylog_bio != NULL) { + BIO *bio = self->keylog_bio; + self->keylog_bio = NULL; + PySSL_BEGIN_ALLOW_THREADS + BIO_free_all(bio); + PySSL_END_ALLOW_THREADS + } + + if (arg == Py_None) { + /* None disables the callback */ + return 0; + } + + /* _Py_fopen_obj() also checks that arg is of proper type. */ + fp = _Py_fopen_obj(arg, "a" PY_STDIOTEXTMODE); + if (fp == NULL) + return -1; + + self->keylog_bio = BIO_new_fp(fp, BIO_CLOSE | BIO_FP_TEXT); + if (self->keylog_bio == NULL) { + PyErr_SetString(PySSLErrorObject, + "Can't malloc memory for keylog file"); + return -1; + } + Py_INCREF(arg); + self->keylog_filename = arg; + + /* Write a header for seekable, empty files (this excludes pipes). */ + PySSL_BEGIN_ALLOW_THREADS + if (BIO_tell(self->keylog_bio) == 0) { + BIO_puts(self->keylog_bio, + "# TLS secrets log file, generated by OpenSSL / Python\n"); + (void)BIO_flush(self->keylog_bio); + } + PySSL_END_ALLOW_THREADS + SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback); + return 0; +} + +#endif \ No newline at end of file diff --git a/setup.py b/setup.py index 96a49b4e353c72..7852c2dfa27e08 100644 --- a/setup.py +++ b/setup.py @@ -2178,11 +2178,13 @@ def split_var(name, sep): ssl_incs.extend(krb5_h) if config_vars.get("HAVE_X509_VERIFY_PARAM_SET1_HOST"): - self.add(Extension('_ssl', ['_ssl.c'], - include_dirs=openssl_includes, - library_dirs=openssl_libdirs, - libraries=openssl_libs, - depends=['socketmodule.h'])) + self.add(Extension( + '_ssl', ['_ssl.c'], + include_dirs=openssl_includes, + library_dirs=openssl_libdirs, + libraries=openssl_libs, + depends=['socketmodule.h', '_ssl/debughelpers.c']) + ) else: self.missing.append('_ssl') From c7f803b08ed5211701c75f98ba9ada85d45ac155 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 31 May 2019 03:46:36 -0600 Subject: [PATCH 215/441] bpo-36379: __ipow__ must be a ternaryfunc, not a binaryfunc (GH-13546) If a type's __ipow__ method was implemented in C, attempting to use the *modulo* parameter would cause crashes. https://bugs.python.org/issue36379 --- Lib/test/test_capi.py | 7 +++++ .../2019-05-24-07-11-08.bpo-36379.8zgoKe.rst | 2 ++ Modules/_testcapimodule.c | 26 +++++++++++++++++++ Objects/typeobject.c | 2 +- 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 795aa78d886676..4dd78bb9a2fd5f 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -184,6 +184,13 @@ def test_c_type_with_matrix_multiplication(self): o @= m1 self.assertEqual(o, ("matmul", 42, m1)) + def test_c_type_with_ipow(self): + # When the __ipow__ method of a type was implemented in C, using the + # modulo param would cause segfaults. + o = _testcapi.ipowType() + self.assertEqual(o.__ipow__(1), (1, None)) + self.assertEqual(o.__ipow__(2, 2), (2, 2)) + def test_return_null_without_error(self): # Issue #23571: A function must not return NULL without setting an # error diff --git a/Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst b/Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst new file mode 100644 index 00000000000000..6a699b2084e4a3 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst @@ -0,0 +1,2 @@ +Fix crashes when attempting to use the *modulo* parameter when ``__ipow__`` +is implemented in C. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index ca6e87b79c47fc..b42f41cc8d8fd7 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5522,6 +5522,27 @@ static PyTypeObject matmulType = { PyObject_Del, /* tp_free */ }; +typedef struct { + PyObject_HEAD +} ipowObject; + +static PyObject * +ipowType_ipow(PyObject *self, PyObject *other, PyObject *mod) +{ + return Py_BuildValue("OO", other, mod); +} + +static PyNumberMethods ipowType_as_number = { + .nb_inplace_power = ipowType_ipow +}; + +static PyTypeObject ipowType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "ipowType", + .tp_basicsize = sizeof(ipowObject), + .tp_as_number = &ipowType_as_number, + .tp_new = PyType_GenericNew +}; typedef struct { PyObject_HEAD @@ -5947,6 +5968,11 @@ PyInit__testcapi(void) return NULL; Py_INCREF(&matmulType); PyModule_AddObject(m, "matmulType", (PyObject *)&matmulType); + if (PyType_Ready(&ipowType) < 0) { + return NULL; + } + Py_INCREF(&ipowType); + PyModule_AddObject(m, "ipowType", (PyObject *)&ipowType); if (PyType_Ready(&awaitType) < 0) return NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 64c2ceab5573f4..b6d925c1442e78 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7016,7 +7016,7 @@ static slotdef slotdefs[] = { IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, wrap_binaryfunc, "%="), IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, - wrap_binaryfunc, "**="), + wrap_ternaryfunc, "**="), IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, wrap_binaryfunc, "<<="), IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, From 3a46d5c293d39995dc5218bf46a7d92b16fb2a15 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 31 May 2019 12:07:56 +0100 Subject: [PATCH 216/441] bpo-37108: Support super with methods that use positional-only arguments (GH-13695) --- Lib/test/test_positional_only_arg.py | 14 ++++++++++++++ Objects/typeobject.c | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index d4d259ef2693c4..0aaad84cb3bfcd 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -398,6 +398,20 @@ def f(a=1, /, b=2): gen = f() self.assertEqual(next(gen), (1, 2)) + def test_super(self): + + sentinel = object() + + class A: + def method(self): + return sentinel + + class C(A): + def method(self, /): + return super().method() + + self.assertEqual(C().method(), sentinel) + if __name__ == "__main__": unittest.main() diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b6d925c1442e78..da249b569ad2bb 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7807,7 +7807,7 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds) "super(): no code object"); return -1; } - if (co->co_argcount == 0) { + if (co->co_posonlyargcount + co->co_argcount == 0) { PyErr_SetString(PyExc_RuntimeError, "super(): no arguments"); return -1; From ed222a74a0ada1cb89ba0fd81f64e404ac50778d Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 31 May 2019 12:13:04 +0100 Subject: [PATCH 217/441] Update data model docs to include missing attributes for code objects (GH-13696) Include and document co_posonlyargcount and co_kwonlyargcount --- Doc/reference/datamodel.rst | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 9fc9f3a3848a4e..8b4d889535fbe1 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -890,6 +890,8 @@ Internal types .. index:: single: co_argcount (code object attribute) + single: co_posonlyargcount (code object attribute) + single: co_kwonlyargcount (code object attribute) single: co_code (code object attribute) single: co_consts (code object attribute) single: co_filename (code object attribute) @@ -906,18 +908,21 @@ Internal types Special read-only attributes: :attr:`co_name` gives the function name; :attr:`co_argcount` is the number of positional arguments (including arguments - with default values); :attr:`co_nlocals` is the number of local variables used - by the function (including arguments); :attr:`co_varnames` is a tuple containing - the names of the local variables (starting with the argument names); - :attr:`co_cellvars` is a tuple containing the names of local variables that are - referenced by nested functions; :attr:`co_freevars` is a tuple containing the - names of free variables; :attr:`co_code` is a string representing the sequence - of bytecode instructions; :attr:`co_consts` is a tuple containing the literals - used by the bytecode; :attr:`co_names` is a tuple containing the names used by - the bytecode; :attr:`co_filename` is the filename from which the code was - compiled; :attr:`co_firstlineno` is the first line number of the function; - :attr:`co_lnotab` is a string encoding the mapping from bytecode offsets to - line numbers (for details see the source code of the interpreter); + with default values); :attr:`co_posonlyargcount` is the number of + positional-only arguments (including arguments with default values); + :attr:`co_kwonlyargcount` is the number of keyword-only arguments (including + arguments with default values); :attr:`co_nlocals` is the number of local + variables used by the function (including arguments); :attr:`co_varnames` is a + tuple containing the names of the local variables (starting with the argument + names); :attr:`co_cellvars` is a tuple containing the names of local variables + that are referenced by nested functions; :attr:`co_freevars` is a tuple + containing the names of free variables; :attr:`co_code` is a string representing + the sequence of bytecode instructions; :attr:`co_consts` is a tuple containing + the literals used by the bytecode; :attr:`co_names` is a tuple containing the + names used by the bytecode; :attr:`co_filename` is the filename from which the + code was compiled; :attr:`co_firstlineno` is the first line number of the + function; :attr:`co_lnotab` is a string encoding the mapping from bytecode + offsets to line numbers (for details see the source code of the interpreter); :attr:`co_stacksize` is the required stack size (including local variables); :attr:`co_flags` is an integer encoding a number of flags for the interpreter. From 2f58a84104ef64f71deb71d264305bcd73e59c97 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 31 May 2019 14:09:49 +0100 Subject: [PATCH 218/441] bpo-37112: Allow compile to work on AST with positional only arguments with defaults (GH-13697) --- Lib/test/test_ast.py | 22 ++++++++++++++++++++++ Python/ast.c | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 0c5bbf6752a48e..e251e254afddaa 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -137,6 +137,18 @@ def to_tuple(t): "@deco(a for a in b)\ndef f(): pass", # Simple assignment expression "(a := 1)", + # Positional-only arguments + "def f(a, /,): pass", + "def f(a, /, c, d, e): pass", + "def f(a, /, c, *, d, e): pass", + "def f(a, /, c, *, d, e, **kwargs): pass", + # Positional-only arguments with defaults + "def f(a=1, /,): pass", + "def f(a=1, /, b=2, c=4): pass", + "def f(a=1, /, b=2, *, c=4): pass", + "def f(a=1, /, b=2, *, c): pass", + "def f(a=1, /, b=2, *, c=4, **kwargs): pass", + "def f(a=1, /, b=2, *, c, **kwargs): pass", ] @@ -1691,6 +1703,16 @@ def main(): ('Module', [('ClassDef', (3, 0), 'C', [], [], [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])])], []), ('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []), ('Module', [('Expr', (1, 0), ('NamedExpr', (1, 1), ('Name', (1, 1), 'a', ('Store',)), ('Constant', (1, 6), 1, None)))], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 14))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 12), 'c', None, None), ('arg', (1, 15), 'd', None, None), ('arg', (1, 18), 'e', None, None)], [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 22))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 12), 'c', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 12), 'c', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 18), 'd', None, None), ('arg', (1, 21), 'e', None, None)], [None, None], ('arg', (1, 26), 'kwargs', None, None), []), [('Pass', (1, 35))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 1, None)]), [('Pass', (1, 16))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None), ('arg', (1, 19), 'c', None, None)], [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None), ('Constant', (1, 21), 4, None)]), [('Pass', (1, 25))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 28))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], None, [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 26))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [('Constant', (1, 24), 4, None)], ('arg', (1, 29), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 38))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 14), 'b', None, None)], [('arg', (1, 6), 'a', None, None)], None, [('arg', (1, 22), 'c', None, None)], [None], ('arg', (1, 27), 'kwargs', None, None), [('Constant', (1, 8), 1, None), ('Constant', (1, 16), 2, None)]), [('Pass', (1, 36))], [], None, None)], []), ] single_results = [ ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Constant', (1, 0), 1, None), ('Add',), ('Constant', (1, 2), 2, None)))]), diff --git a/Python/ast.c b/Python/ast.c index 183b08d6ba1286..b77552274d2443 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -123,7 +123,7 @@ validate_arguments(arguments_ty args) && !validate_expr(args->kwarg->annotation, Load)) { return 0; } - if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->args)) { + if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) { PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments"); return 0; } From a0c01bf1364f2996bb0186ddfc41d74350e01c39 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 31 May 2019 15:19:50 +0100 Subject: [PATCH 219/441] bpo-37115: Support annotations in positional-only arguments (GH-13698) --- Lib/test/test_grammar.py | 13 ++++++++++ Lib/test/test_type_comments.py | 46 +++++++++++++++++++++++++++++++--- Python/compile.c | 2 ++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 6d7d5544ed9c3f..2a3b71fac4a5a0 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -620,14 +620,22 @@ def f(x) -> list: pass self.assertEqual(f.__annotations__, {'return': list}) def f(x: int): pass self.assertEqual(f.__annotations__, {'x': int}) + def f(x: int, /): pass + self.assertEqual(f.__annotations__, {'x': int}) + def f(x: int = 34, /): pass + self.assertEqual(f.__annotations__, {'x': int}) def f(*x: str): pass self.assertEqual(f.__annotations__, {'x': str}) def f(**x: float): pass self.assertEqual(f.__annotations__, {'x': float}) def f(x, y: 1+2): pass self.assertEqual(f.__annotations__, {'y': 3}) + def f(x, y: 1+2, /): pass + self.assertEqual(f.__annotations__, {'y': 3}) def f(a, b: 1, c: 2, d): pass self.assertEqual(f.__annotations__, {'b': 1, 'c': 2}) + def f(a, b: 1, /, c: 2, d): pass + self.assertEqual(f.__annotations__, {'b': 1, 'c': 2}) def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6): pass self.assertEqual(f.__annotations__, {'b': 1, 'c': 2, 'e': 3, 'g': 6}) @@ -636,6 +644,11 @@ def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6, h: 7, i=8, j: 9 = 10, self.assertEqual(f.__annotations__, {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, 'k': 11, 'return': 12}) + def f(a, b: 1, c: 2, d, e: 3 = 4, f: int = 5, /, *g: 6, h: 7, i=8, j: 9 = 10, + **k: 11) -> 12: pass + self.assertEqual(f.__annotations__, + {'b': 1, 'c': 2, 'e': 3, 'f': int, 'g': 6, 'h': 7, 'j': 9, + 'k': 11, 'return': 12}) # Check for issue #20625 -- annotations mangling class Spam: def f(self, *, __kw: 1): diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 83d8717247aab0..55b54e7f203edc 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -99,12 +99,25 @@ def fa( ): pass +def fa( + a = 1, # type: A + / +): + pass + def fab( a, # type: A b, # type: B ): pass +def fab( + a, # type: A + /, + b, # type: B +): + pass + def fab( a, # type: A b # type: B @@ -149,6 +162,13 @@ def fav( ): pass +def fav( + a, # type: A + /, + *v, # type: V +): + pass + def fav( a, # type: A *v # type: V @@ -161,6 +181,13 @@ def fak( ): pass +def fak( + a, # type: A + /, + **k, # type: K +): + pass + def fak( a, # type: A **k # type: K @@ -174,6 +201,14 @@ def favk( ): pass +def favk( + a, # type: A + /, + *v, # type: V + **k, # type: K +): + pass + def favk( a, # type: A *v, # type: V @@ -290,18 +325,21 @@ def test_longargs(self): for t in tree.body: # The expected args are encoded in the function name todo = set(t.name[1:]) - self.assertEqual(len(t.args.args), + self.assertEqual(len(t.args.args) + len(t.args.posonlyargs), len(todo) - bool(t.args.vararg) - bool(t.args.kwarg)) self.assertTrue(t.name.startswith('f'), t.name) - for c in t.name[1:]: + for index, c in enumerate(t.name[1:]): todo.remove(c) if c == 'v': arg = t.args.vararg elif c == 'k': arg = t.args.kwarg else: - assert 0 <= ord(c) - ord('a') < len(t.args.args) - arg = t.args.args[ord(c) - ord('a')] + assert 0 <= ord(c) - ord('a') < len(t.args.posonlyargs + t.args.args) + if index < len(t.args.posonlyargs): + arg = t.args.posonlyargs[ord(c) - ord('a')] + else: + arg = t.args.args[ord(c) - ord('a') - len(t.args.posonlyargs)] self.assertEqual(arg.arg, c) # That's the argument name self.assertEqual(arg.type_comment, arg.arg.upper()) assert not todo diff --git a/Python/compile.c b/Python/compile.c index f1c97bdfe47f07..f6ec929b3ca4eb 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1991,6 +1991,8 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (!compiler_visit_argannotations(c, args->args, names)) goto error; + if (!compiler_visit_argannotations(c, args->posonlyargs, names)) + goto error; if (args->vararg && args->vararg->annotation && !compiler_visit_argannotation(c, args->vararg->arg, args->vararg->annotation, names)) From ffed76b6fc4d7dd0244b662d6e5738eb496d9def Mon Sep 17 00:00:00 2001 From: Makdon Date: Sat, 1 Jun 2019 00:19:12 +0800 Subject: [PATCH 220/441] bpo-37094: Add example for TestCase.skipTest in unittest doc (GH-13645) Also includes other minor test skipping doc improvements. https://bugs.python.org/issue37094 --- Doc/library/unittest.rst | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 8ad2abd3d89a44..54a9f2c6f7355e 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -510,7 +510,8 @@ that is broken and will fail, but shouldn't be counted as a failure on a :class:`TestResult`. Skipping a test is simply a matter of using the :func:`skip` :term:`decorator` -or one of its conditional variants. +or one of its conditional variants, calling :meth:`TestCase.skipTest` within a +:meth:`~TestCase.setUp` or test method, or raising :exc:`SkipTest` directly. Basic skipping looks like this:: @@ -531,16 +532,23 @@ Basic skipping looks like this:: # windows specific testing code pass + def test_maybe_skipped(self): + if not external_resource_available(): + self.skipTest("external resource not available") + # test code that depends on the external resource + pass + This is the output of running the example above in verbose mode:: test_format (__main__.MyTestCase) ... skipped 'not supported in this library version' test_nothing (__main__.MyTestCase) ... skipped 'demonstrating skipping' + test_maybe_skipped (__main__.MyTestCase) ... skipped 'external resource not available' test_windows_support (__main__.MyTestCase) ... skipped 'requires Windows' ---------------------------------------------------------------------- - Ran 3 tests in 0.005s + Ran 4 tests in 0.005s - OK (skipped=3) + OK (skipped=4) Classes can be skipped just like methods:: @@ -568,7 +576,7 @@ the test unless the passed object has a certain attribute:: return lambda func: func return unittest.skip("{!r} doesn't have {!r}".format(obj, attr)) -The following decorators implement test skipping and expected failures: +The following decorators and exception implement test skipping and expected failures: .. decorator:: skip(reason) From 8cbb5b6625268400d6e9092b75b06d6f90398dc9 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Fri, 31 May 2019 18:32:33 +0200 Subject: [PATCH 221/441] bpo-26835: Add file sealing constants to fcntl (GH-13694) Co-authored-by: nanjekyejoannah --- Doc/library/fcntl.rst | 4 ++++ .../Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst | 1 + Modules/fcntlmodule.c | 10 +++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 88112f6b7e545b..2db9674952d7b6 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -28,6 +28,10 @@ descriptor. Operations in this module used to raise an :exc:`IOError` where they now raise an :exc:`OSError`. +.. versionchanged:: 3.8 + The fcntl module now contains ``F_ADD_SEALS``, ``F_GET_SEALS``, and + ``F_SEAL_*`` constants for sealing of :func:`os.memfd_create` file + descriptors. The module defines the following functions: diff --git a/Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst b/Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst new file mode 100644 index 00000000000000..1c5ed97a7d190b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst @@ -0,0 +1 @@ +The fcntl module now contains file sealing constants for sealing of memfds. diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index a938d9e88bf017..0fbf7876c3e207 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -620,7 +620,15 @@ all_ins(PyObject* m) if (PyModule_AddIntMacro(m, I_PLINK)) return -1; if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1; #endif - +#ifdef F_ADD_SEALS + /* Linux: file sealing for memfd_create() */ + if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1; + if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1; + if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1; + if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1; + if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1; + if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1; +#endif return 0; } From 4612671df2742eade8ecf8003a6ce1247973c135 Mon Sep 17 00:00:00 2001 From: Akshay Sharma Date: Fri, 31 May 2019 22:11:17 +0530 Subject: [PATCH 222/441] bpo-25735: math.factorial doc should mention integer return type (GH-6420) --- Doc/library/math.rst | 2 +- .../next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst diff --git a/Doc/library/math.rst b/Doc/library/math.rst index bf660ae9defa07..b51e96bc40743f 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -50,7 +50,7 @@ Number-theoretic and representation functions .. function:: factorial(x) - Return *x* factorial. Raises :exc:`ValueError` if *x* is not integral or + Return *x* factorial as an integer. Raises :exc:`ValueError` if *x* is not integral or is negative. diff --git a/Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst b/Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst new file mode 100644 index 00000000000000..8d22cf69e170c8 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst @@ -0,0 +1 @@ +Added documentation for func factorial to indicate that returns integer values From c8d5bf6c3fa09b43f6a5ee779d493d251dbcc53c Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 31 May 2019 10:43:13 -0600 Subject: [PATCH 223/441] bpo-12639: msilib.Directory.start_component() fails if *keyfile* is not None (GH-13688) msilib.Directory.start_component() was passing an extra argument to CAB.gen_id(). --- Lib/msilib/__init__.py | 2 +- Lib/test/test_msilib.py | 9 +++++++++ .../Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst diff --git a/Lib/msilib/__init__.py b/Lib/msilib/__init__.py index 8c5251d9baf81e..0bc8dd9952462c 100644 --- a/Lib/msilib/__init__.py +++ b/Lib/msilib/__init__.py @@ -273,7 +273,7 @@ def start_component(self, component = None, feature = None, flags = None, keyfil if AMD64: flags |= 256 if keyfile: - keyid = self.cab.gen_id(self.absolute, keyfile) + keyid = self.cab.gen_id(keyfile) self.keyfiles[keyfile] = keyid else: keyid = None diff --git a/Lib/test/test_msilib.py b/Lib/test/test_msilib.py index 4aa4753fc2a6db..265eaea59b5f4b 100644 --- a/Lib/test/test_msilib.py +++ b/Lib/test/test_msilib.py @@ -83,6 +83,15 @@ def test_get_property_vt_empty(self): db.Close() self.addCleanup(unlink, db_path) + def test_directory_start_component_keyfile(self): + db, db_path = init_database() + self.addCleanup(db.Close) + feature = msilib.Feature(db, 0, 'Feature', 'A feature', 'Python') + cab = msilib.CAB('CAB') + dir = msilib.Directory(db, cab, None, TESTFN, 'TARGETDIR', + 'SourceDir', 0) + dir.start_component(None, feature, None, 'keyfile') + class Test_make_id(unittest.TestCase): #http://msdn.microsoft.com/en-us/library/aa369212(v=vs.85).aspx diff --git a/Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst b/Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst new file mode 100644 index 00000000000000..aade9121b4bbbd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst @@ -0,0 +1,2 @@ +:meth:`msilib.Directory.start_component()` no longer fails if *keyfile* is +not ``None``. From 545a3b8814dbf2a5391e830d69e796fb1a1d62ec Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 31 May 2019 19:33:41 +0100 Subject: [PATCH 224/441] Document changes for PyCode_New regarding PEP570 (GH-13706) --- Doc/c-api/code.rst | 3 +++ Doc/whatsnew/3.8.rst | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index e2b0b23335e33c..7aa91ee84d2e47 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -40,6 +40,9 @@ bound into a function. :c:func:`PyCode_New` directly can bind you to a precise Python version since the definition of the bytecode changes often. + .. versionchanged:: 3.8 + An extra parameter is required (*posonlyargcount*) to support :PEP:`570`. + .. audit-event:: code.__new__ "code filename name argcount kwonlyargcount nlocals stacksize flags" .. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 98f0c3474f26ed..76d00938dbec46 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1278,6 +1278,9 @@ Changes in the C API (Contributed by Antoine Pitrou in :issue:`32388`.) +* The :c:func:`PyCode_New` has a new parameter in the second position (*posonlyargcount*) + to support :pep:`570`, indicating the number of positional-only arguments. + CPython bytecode changes ------------------------ From aac4d0342c3e692731c189d003dbd73a8c681a34 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 31 May 2019 19:39:47 +0100 Subject: [PATCH 225/441] bpo-26826: Expose copy_file_range in the os module (GH-7255) --- Doc/library/os.rst | 22 ++++ Lib/test/test_os.py | 83 ++++++++++++++ .../2018-05-30-23-43-03.bpo-26826.NkRzjb.rst | 1 + Modules/clinic/posixmodule.c.h | 108 +++++++++++++++++- Modules/posixmodule.c | 71 ++++++++++++ aclocal.m4 | 74 +++++++++++- configure | 17 +-- configure.ac | 3 +- pyconfig.h.in | 3 + 9 files changed, 363 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst diff --git a/Doc/library/os.rst b/Doc/library/os.rst index b53fd71e65b31a..107764ba4d539e 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -707,6 +707,28 @@ as internal buffering of data. pass +.. function:: copy_file_range(src, dst, count, offset_src=None, offset_dst=None) + + Copy *count* bytes from file descriptor *src*, starting from offset + *offset_src*, to file descriptor *dst*, starting from offset *offset_dst*. + If *offset_src* is None, then *src* is read from the current position; + respectively for *offset_dst*. The files pointed by *src* and *dst* + must reside in the same filesystem, otherwise an :exc:`OSError` is + raised with :attr:`~OSError.errno` set to :data:`errno.EXDEV`. + + This copy is done without the additional cost of transferring data + from the kernel to user space and then back into the kernel. Additionally, + some filesystems could implement extra optimizations. The copy is done as if + both files are opened as binary. + + The return value is the amount of bytes copied. This could be less than the + amount requested. + + .. availability:: Linux kernel >= 4.5 or glibc >= 2.27. + + .. versionadded:: 3.8 + + .. function:: device_encoding(fd) Return a string describing the encoding of the device associated with *fd* diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index f17a19a7585d02..a8eae6162057b7 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -231,6 +231,89 @@ def test_symlink_keywords(self): except (NotImplementedError, OSError): pass # No OS support or unprivileged user + @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()') + def test_copy_file_range_invalid_values(self): + with self.assertRaises(ValueError): + os.copy_file_range(0, 1, -10) + + @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()') + def test_copy_file_range(self): + TESTFN2 = support.TESTFN + ".3" + data = b'0123456789' + + create_file(support.TESTFN, data) + self.addCleanup(support.unlink, support.TESTFN) + + in_file = open(support.TESTFN, 'rb') + self.addCleanup(in_file.close) + in_fd = in_file.fileno() + + out_file = open(TESTFN2, 'w+b') + self.addCleanup(support.unlink, TESTFN2) + self.addCleanup(out_file.close) + out_fd = out_file.fileno() + + try: + i = os.copy_file_range(in_fd, out_fd, 5) + except OSError as e: + # Handle the case in which Python was compiled + # in a system with the syscall but without support + # in the kernel. + if e.errno != errno.ENOSYS: + raise + self.skipTest(e) + else: + # The number of copied bytes can be less than + # the number of bytes originally requested. + self.assertIn(i, range(0, 6)); + + with open(TESTFN2, 'rb') as in_file: + self.assertEqual(in_file.read(), data[:i]) + + @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()') + def test_copy_file_range_offset(self): + TESTFN4 = support.TESTFN + ".4" + data = b'0123456789' + bytes_to_copy = 6 + in_skip = 3 + out_seek = 5 + + create_file(support.TESTFN, data) + self.addCleanup(support.unlink, support.TESTFN) + + in_file = open(support.TESTFN, 'rb') + self.addCleanup(in_file.close) + in_fd = in_file.fileno() + + out_file = open(TESTFN4, 'w+b') + self.addCleanup(support.unlink, TESTFN4) + self.addCleanup(out_file.close) + out_fd = out_file.fileno() + + try: + i = os.copy_file_range(in_fd, out_fd, bytes_to_copy, + offset_src=in_skip, + offset_dst=out_seek) + except OSError as e: + # Handle the case in which Python was compiled + # in a system with the syscall but without support + # in the kernel. + if e.errno != errno.ENOSYS: + raise + self.skipTest(e) + else: + # The number of copied bytes can be less than + # the number of bytes originally requested. + self.assertIn(i, range(0, bytes_to_copy+1)); + + with open(TESTFN4, 'rb') as in_file: + read = in_file.read() + # seeked bytes (5) are zero'ed + self.assertEqual(read[:out_seek], b'\x00'*out_seek) + # 012 are skipped (in_skip) + # 345678 are copied in the file (in_skip + bytes_to_copy) + self.assertEqual(read[out_seek:], + data[in_skip:in_skip+i]) # Test attributes on return values from os.*stat* family. class StatAttributeTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst new file mode 100644 index 00000000000000..27d7f82a672db4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst @@ -0,0 +1 @@ +Expose :func:`copy_file_range` as a low level API in the :mod:`os` module. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 13f25460b4f6cf..22cb94761de5c7 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -5395,6 +5395,108 @@ os_pwritev(PyObject *module, PyObject *const *args, Py_ssize_t nargs) #endif /* (defined(HAVE_PWRITEV) || defined (HAVE_PWRITEV2)) */ +#if defined(HAVE_COPY_FILE_RANGE) + +PyDoc_STRVAR(os_copy_file_range__doc__, +"copy_file_range($module, /, src, dst, count, offset_src=None,\n" +" offset_dst=None)\n" +"--\n" +"\n" +"Copy count bytes from one file descriptor to another.\n" +"\n" +" src\n" +" Source file descriptor.\n" +" dst\n" +" Destination file descriptor.\n" +" count\n" +" Number of bytes to copy.\n" +" offset_src\n" +" Starting offset in src.\n" +" offset_dst\n" +" Starting offset in dst.\n" +"\n" +"If offset_src is None, then src is read from the current position;\n" +"respectively for offset_dst."); + +#define OS_COPY_FILE_RANGE_METHODDEF \ + {"copy_file_range", (PyCFunction)(void(*)(void))os_copy_file_range, METH_FASTCALL|METH_KEYWORDS, os_copy_file_range__doc__}, + +static PyObject * +os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, + PyObject *offset_src, PyObject *offset_dst); + +static PyObject * +os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "copy_file_range", 0}; + PyObject *argsbuf[5]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + int src; + int dst; + Py_ssize_t count; + PyObject *offset_src = Py_None; + PyObject *offset_dst = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 5, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyFloat_Check(args[0])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + src = _PyLong_AsInt(args[0]); + if (src == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[1])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + dst = _PyLong_AsInt(args[1]); + if (dst == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_Check(args[2])) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = PyNumber_Index(args[2]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + count = ival; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[3]) { + offset_src = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + offset_dst = args[4]; +skip_optional_pos: + return_value = os_copy_file_range_impl(module, src, dst, count, offset_src, offset_dst); + +exit: + return return_value; +} + +#endif /* defined(HAVE_COPY_FILE_RANGE) */ + #if defined(HAVE_MKFIFO) PyDoc_STRVAR(os_mkfifo__doc__, @@ -8460,6 +8562,10 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #define OS_PWRITEV_METHODDEF #endif /* !defined(OS_PWRITEV_METHODDEF) */ +#ifndef OS_COPY_FILE_RANGE_METHODDEF + #define OS_COPY_FILE_RANGE_METHODDEF +#endif /* !defined(OS_COPY_FILE_RANGE_METHODDEF) */ + #ifndef OS_MKFIFO_METHODDEF #define OS_MKFIFO_METHODDEF #endif /* !defined(OS_MKFIFO_METHODDEF) */ @@ -8635,4 +8741,4 @@ os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nar #ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF #define OS__REMOVE_DLL_DIRECTORY_METHODDEF #endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */ -/*[clinic end generated code: output=855b81aafd05beed input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b3ae8afd275ea5cd input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 77a3700ab22e0f..8f6cffffcdfbe8 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -117,6 +117,10 @@ corresponding Unix manual entries for more information on calls."); #include #endif +#ifdef HAVE_COPY_FILE_RANGE +#include +#endif + #if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) #undef HAVE_SCHED_SETAFFINITY #endif @@ -9455,8 +9459,74 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, } #endif /* HAVE_PWRITEV */ +#ifdef HAVE_COPY_FILE_RANGE +/*[clinic input] + +os.copy_file_range + src: int + Source file descriptor. + dst: int + Destination file descriptor. + count: Py_ssize_t + Number of bytes to copy. + offset_src: object = None + Starting offset in src. + offset_dst: object = None + Starting offset in dst. + +Copy count bytes from one file descriptor to another. + +If offset_src is None, then src is read from the current position; +respectively for offset_dst. +[clinic start generated code]*/ + +static PyObject * +os_copy_file_range_impl(PyObject *module, int src, int dst, Py_ssize_t count, + PyObject *offset_src, PyObject *offset_dst) +/*[clinic end generated code: output=1a91713a1d99fc7a input=42fdce72681b25a9]*/ +{ + off_t offset_src_val, offset_dst_val; + off_t *p_offset_src = NULL; + off_t *p_offset_dst = NULL; + Py_ssize_t ret; + int async_err = 0; + /* The flags argument is provided to allow + * for future extensions and currently must be to 0. */ + int flags = 0; + + + if (count < 0) { + PyErr_SetString(PyExc_ValueError, "negative value for 'count' not allowed"); + return NULL; + } + + if (offset_src != Py_None) { + if (!Py_off_t_converter(offset_src, &offset_src_val)) { + return NULL; + } + p_offset_src = &offset_src_val; + } + if (offset_dst != Py_None) { + if (!Py_off_t_converter(offset_dst, &offset_dst_val)) { + return NULL; + } + p_offset_dst = &offset_dst_val; + } + do { + Py_BEGIN_ALLOW_THREADS + ret = copy_file_range(src, p_offset_src, dst, p_offset_dst, count, flags); + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (ret < 0) { + return (!async_err) ? posix_error() : NULL; + } + + return PyLong_FromSsize_t(ret); +} +#endif /* HAVE_COPY_FILE_RANGE*/ #ifdef HAVE_MKFIFO /*[clinic input] @@ -13432,6 +13502,7 @@ static PyMethodDef posix_methods[] = { OS_POSIX_SPAWN_METHODDEF OS_POSIX_SPAWNP_METHODDEF OS_READLINK_METHODDEF + OS_COPY_FILE_RANGE_METHODDEF OS_RENAME_METHODDEF OS_REPLACE_METHODDEF OS_RMDIR_METHODDEF diff --git a/aclocal.m4 b/aclocal.m4 index 85f00dd5fac7f2..3d6b1a375fdca3 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -12,9 +12,9 @@ # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29.1) -dnl +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 11 (pkg-config-0.29.1) + dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl @@ -288,5 +288,73 @@ AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR +dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------ +dnl +dnl Prepare a "--with-" configure option using the lowercase +dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and +dnl PKG_CHECK_MODULES in a single macro. +AC_DEFUN([PKG_WITH_MODULES], +[ +m4_pushdef([with_arg], m4_tolower([$1])) + +m4_pushdef([description], + [m4_default([$5], [build with ]with_arg[ support])]) + +m4_pushdef([def_arg], [m4_default([$6], [auto])]) +m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) +m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) + +m4_case(def_arg, + [yes],[m4_pushdef([with_without], [--without-]with_arg)], + [m4_pushdef([with_without],[--with-]with_arg)]) + +AC_ARG_WITH(with_arg, + AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, + [AS_TR_SH([with_]with_arg)=def_arg]) + +AS_CASE([$AS_TR_SH([with_]with_arg)], + [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], + [auto],[PKG_CHECK_MODULES([$1],[$2], + [m4_n([def_action_if_found]) $3], + [m4_n([def_action_if_not_found]) $4])]) + +m4_popdef([with_arg]) +m4_popdef([description]) +m4_popdef([def_arg]) + +])dnl PKG_WITH_MODULES + +dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ----------------------------------------------- +dnl +dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES +dnl check._[VARIABLE-PREFIX] is exported as make variable. +AC_DEFUN([PKG_HAVE_WITH_MODULES], +[ +PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) + +AM_CONDITIONAL([HAVE_][$1], + [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) +])dnl PKG_HAVE_WITH_MODULES + +dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------------------ +dnl +dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after +dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make +dnl and preprocessor variable. +AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], +[ +PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) + +AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], + [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) +])dnl PKG_HAVE_DEFINE_WITH_MODULES + m4_include([m4/ax_c_float_words_bigendian.m4]) m4_include([m4/ax_check_openssl.m4]) diff --git a/configure b/configure index cacf9fc4189441..b606fc808c17c1 100755 --- a/configure +++ b/configure @@ -785,7 +785,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -898,7 +897,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1151,15 +1149,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1297,7 +1286,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1450,7 +1439,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -11476,7 +11464,8 @@ fi # checks for library functions for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr ctermid dup3 execv explicit_bzero explicit_memset faccessat fchmod fchmodat fchown fchownat \ + clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ + faccessat fchmod fchmodat fchown fchownat \ fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ diff --git a/configure.ac b/configure.ac index 1190b37e9f9dfe..3d589ac2589167 100644 --- a/configure.ac +++ b/configure.ac @@ -3520,7 +3520,8 @@ fi # checks for library functions AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ - clock confstr ctermid dup3 execv explicit_bzero explicit_memset faccessat fchmod fchmodat fchown fchownat \ + clock confstr copy_file_range ctermid dup3 execv explicit_bzero explicit_memset \ + faccessat fchmod fchmodat fchown fchownat \ fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ futimens futimes gai_strerror getentropy \ getgrgid_r getgrnam_r \ diff --git a/pyconfig.h.in b/pyconfig.h.in index b9bb3ffa6f6935..20cc901e473bee 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -148,6 +148,9 @@ /* Define to 1 if you have the `copysign' function. */ #undef HAVE_COPYSIGN +/* Define to 1 if you have the `copy_file_range' function. */ +#undef HAVE_COPY_FILE_RANGE + /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H From a6ec1ce1ac05b1258931422e96eac215b6a05459 Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Fri, 31 May 2019 12:44:01 -0700 Subject: [PATCH 226/441] bpo-33361: Fix bug with seeking in StreamRecoders (GH-8278) --- Lib/codecs.py | 6 +++++ Lib/test/test_codecs.py | 25 +++++++++++++++++++ .../2018-07-13-20-17-17.bpo-33361.dx2NVn.rst | 2 ++ 3 files changed, 33 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst diff --git a/Lib/codecs.py b/Lib/codecs.py index 884be0b2c02e43..21c45a7d10a4c9 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -847,6 +847,12 @@ def reset(self): self.reader.reset() self.writer.reset() + def seek(self, offset, whence=0): + # Seeks must be propagated to both the readers and writers + # as they might need to reset their internal buffers. + self.reader.seek(offset, whence) + self.writer.seek(offset, whence) + def __getattr__(self, name, getattr=getattr): diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index f665febfc90a21..47df88cedaafa7 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -3166,6 +3166,31 @@ def test_write(self): sr.write(text.encode('latin1')) self.assertEqual(bio.getvalue(), text.encode('utf-8')) + def test_seeking_read(self): + bio = io.BytesIO('line1\nline2\nline3\n'.encode('utf-16-le')) + sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le') + + self.assertEqual(sr.readline(), b'line1\n') + sr.seek(0) + self.assertEqual(sr.readline(), b'line1\n') + self.assertEqual(sr.readline(), b'line2\n') + self.assertEqual(sr.readline(), b'line3\n') + self.assertEqual(sr.readline(), b'') + + def test_seeking_write(self): + bio = io.BytesIO('123456789\n'.encode('utf-16-le')) + sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le') + + # Test that seek() only resets its internal buffer when offset + # and whence are zero. + sr.seek(2) + sr.write(b'\nabc\n') + self.assertEqual(sr.readline(), b'789\n') + sr.seek(0) + self.assertEqual(sr.readline(), b'1\n') + self.assertEqual(sr.readline(), b'abc\n') + self.assertEqual(sr.readline(), b'789\n') + @unittest.skipIf(_testcapi is None, 'need _testcapi module') class LocaleCodecTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst b/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst new file mode 100644 index 00000000000000..2b71095984a09e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst @@ -0,0 +1,2 @@ +Fix a bug in :class:`codecs.StreamRecoder` where seeking might leave old data in a +buffer and break subsequent read calls. Patch by Ammar Askar. From a747c3a5edf21fa5670bc30f5e1d804de89ebf62 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Fri, 31 May 2019 16:18:41 -0400 Subject: [PATCH 227/441] bpo-15115: Document deprecation of email.encoders in Python 3 (GH-5354) --- Doc/library/email.encoders.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/email.encoders.rst b/Doc/library/email.encoders.rst index 70bf61323c39ed..e4752a5edf841f 100644 --- a/Doc/library/email.encoders.rst +++ b/Doc/library/email.encoders.rst @@ -12,6 +12,11 @@ This module is part of the legacy (``Compat32``) email API. In the new API the functionality is provided by the *cte* parameter of the :meth:`~email.message.EmailMessage.set_content` method. +This module is deprecated in Python 3. The functions provided here +should not be called explicitly since the :class:`~email.mime.text.MIMEText` +class sets the content type and CTE header using the *_subtype* and *_charset* +values passed during the instaniation of that class. + The remaining text in this section is the original documentation of the module. When creating :class:`~email.message.Message` objects from scratch, you often From ed9f3562b637a59b9000abbceee5ae369d35444d Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Fri, 31 May 2019 17:48:57 -0300 Subject: [PATCH 228/441] bpo-37105: Add deprecated-remove information on stream doc (#13672) * Add deprecated-remove information on stream doc According to the code on streams.py the functions: ``open_connection()``, ``start_server()``, ``open_unix_connection()``, ``start_unix_server()`` are deprecated. I infor that on documentation. --- Doc/library/asyncio-stream.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index e735b81f234d26..28ca5d5f339692 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -67,6 +67,10 @@ and work with streams: The *ssl_handshake_timeout* parameter. + .. deprecated-removed:: 3.8 3.10 + + `open_connection()` is deprecated in favor of `connect()`. + .. coroutinefunction:: start_server(client_connected_cb, host=None, \ port=None, \*, loop=None, limit=None, \ family=socket.AF_UNSPEC, \ @@ -100,6 +104,10 @@ and work with streams: The *ssl_handshake_timeout* and *start_serving* parameters. + .. deprecated-removed:: 3.8 3.10 + + `start_server()` is deprecated if favor of `StreamServer()` + .. rubric:: Unix Sockets @@ -124,6 +132,10 @@ and work with streams: The *path* parameter can now be a :term:`path-like object` + .. deprecated-removed:: 3.8 3.10 + + `open_unix_connection()` is deprecated if favor of `connect_unix()`. + .. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \ \*, loop=None, limit=None, sock=None, \ @@ -146,6 +158,10 @@ and work with streams: The *path* parameter can now be a :term:`path-like object`. + .. deprecated-removed:: 3.8 3.10 + + `start_unix_server()` is deprecated in favor of `UnixStreamServer()`. + --------- From 549e55a3086d04c13da9b6f33214f6399681292a Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 31 May 2019 18:16:20 -0600 Subject: [PATCH 229/441] bpo-12202: Properly check MsiSummaryInfoGetProperty() calls in msilib (GH-13711) --- Lib/test/test_msilib.py | 9 +++++++++ .../Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst | 2 ++ PC/_msi.c | 3 +++ 3 files changed, 14 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst diff --git a/Lib/test/test_msilib.py b/Lib/test/test_msilib.py index 265eaea59b5f4b..fa0be581613de3 100644 --- a/Lib/test/test_msilib.py +++ b/Lib/test/test_msilib.py @@ -85,6 +85,7 @@ def test_get_property_vt_empty(self): def test_directory_start_component_keyfile(self): db, db_path = init_database() + self.addCleanup(unlink, db_path) self.addCleanup(db.Close) feature = msilib.Feature(db, 0, 'Feature', 'A feature', 'Python') cab = msilib.CAB('CAB') @@ -92,6 +93,14 @@ def test_directory_start_component_keyfile(self): 'SourceDir', 0) dir.start_component(None, feature, None, 'keyfile') + def test_getproperty_uninitialized_var(self): + db, db_path = init_database() + self.addCleanup(unlink, db_path) + self.addCleanup(db.Close) + si = db.GetSummaryInformation(0) + with self.assertRaises(msilib.MSIError): + si.GetProperty(-1) + class Test_make_id(unittest.TestCase): #http://msdn.microsoft.com/en-us/library/aa369212(v=vs.85).aspx diff --git a/Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst b/Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst new file mode 100644 index 00000000000000..1e561970445fa9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst @@ -0,0 +1,2 @@ +Fix the error handling in :meth:`msilib.SummaryInformation.GetProperty`. Patch +by Zackery Spytz. diff --git a/PC/_msi.c b/PC/_msi.c index 4c8df5b42b95c6..accbe7a7206944 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -571,6 +571,9 @@ summary_getproperty(msiobj* si, PyObject *args) status = MsiSummaryInfoGetProperty(si->h, field, &type, &ival, &fval, sval, &ssize); } + if (status != ERROR_SUCCESS) { + return msierror(status); + } switch(type) { case VT_I2: From 1c263e39c4ed28225a7dc8ca1f24953225ac48ca Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Fri, 31 May 2019 21:16:04 -0500 Subject: [PATCH 230/441] bpo-37029: keep usable_arenas in sorted order without searching (#13612) This adds a vector of "search fingers" so that usable_arenas can be kept in sorted order (by number of free pools) via constant-time operations instead of linear search. This should reduce worst-case time for reclaiming a great many objects from O(A**2) to O(A), where A is the number of arenas. See bpo-37029. --- .../2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst | 1 + Objects/obmalloc.c | 109 +++++++++++++----- 2 files changed, 78 insertions(+), 32 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst new file mode 100644 index 00000000000000..c18f5d23eaa26f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst @@ -0,0 +1 @@ +Freeing a great many small objects could take time quadratic in the number of arenas, due to using linear search to keep ``obmalloc.c``'s list of usable arenas sorted by order of number of free memory pools. This is accomplished without search now, leaving the worst-case time linear in the number of arenas. For programs where this quite visibly matters (typically with more than 100 thousand small objects alive simultaneously), this can greatly reduce the time needed to release their memory. \ No newline at end of file diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index f54856dcfe7166..fc7bef6199466d 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -918,6 +918,11 @@ static int running_on_valgrind = -1; #define POOL_SIZE SYSTEM_PAGE_SIZE /* must be 2^N */ #define POOL_SIZE_MASK SYSTEM_PAGE_SIZE_MASK +#define MAX_POOLS_IN_ARENA (ARENA_SIZE / POOL_SIZE) +#if MAX_POOLS_IN_ARENA * POOL_SIZE != ARENA_SIZE +# error "arena size not an exact multiple of pool size" +#endif + /* * -- End of tunable settings section -- */ @@ -1155,6 +1160,18 @@ usable_arenas Note that an arena_object associated with an arena all of whose pools are currently in use isn't on either list. + +Changed in Python 3.8: keeping usable_arenas sorted by number of free pools +used to be done by one-at-a-time linear search when an arena's number of +free pools changed. That could, overall, consume time quadratic in the +number of arenas. That didn't really matter when there were only a few +hundred arenas (typical!), but could be a timing disaster when there were +hundreds of thousands. See bpo-37029. + +Now we have a vector of "search fingers" to eliminate the need to search: +nfp2lasta[nfp] returns the last ("rightmost") arena in usable_arenas +with nfp free pools. This is NULL if and only if there is no arena with +nfp free pools in usable_arenas. */ /* Array of objects used to track chunks of memory (arenas). */ @@ -1172,6 +1189,9 @@ static struct arena_object* unused_arena_objects = NULL; */ static struct arena_object* usable_arenas = NULL; +/* nfp2lasta[nfp] is the last arena in usable_arenas with nfp free pools */ +static struct arena_object* nfp2lasta[MAX_POOLS_IN_ARENA + 1] = { NULL }; + /* How many arena_objects do we initially allocate? * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the * `arenas` vector. @@ -1281,8 +1301,7 @@ new_arena(void) /* pool_address <- first pool-aligned address in the arena nfreepools <- number of whole pools that fit after alignment */ arenaobj->pool_address = (block*)arenaobj->address; - arenaobj->nfreepools = ARENA_SIZE / POOL_SIZE; - assert(POOL_SIZE * arenaobj->nfreepools == ARENA_SIZE); + arenaobj->nfreepools = MAX_POOLS_IN_ARENA; excess = (uint)(arenaobj->address & POOL_SIZE_MASK); if (excess != 0) { --arenaobj->nfreepools; @@ -1478,22 +1497,32 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) } usable_arenas->nextarena = usable_arenas->prevarena = NULL; + assert(nfp2lasta[usable_arenas->nfreepools] == NULL); + nfp2lasta[usable_arenas->nfreepools] = usable_arenas; } assert(usable_arenas->address != 0); + /* This arena already had the smallest nfreepools value, so decreasing + * nfreepools doesn't change that, and we don't need to rearrange the + * usable_arenas list. However, if the arena becomes wholly allocated, + * we need to remove its arena_object from usable_arenas. + */ + assert(usable_arenas->nfreepools > 0); + if (nfp2lasta[usable_arenas->nfreepools] == usable_arenas) { + /* It's the last of this size, so there won't be any. */ + nfp2lasta[usable_arenas->nfreepools] = NULL; + } + /* If any free pools will remain, it will be the new smallest. */ + if (usable_arenas->nfreepools > 1) { + assert(nfp2lasta[usable_arenas->nfreepools - 1] == NULL); + nfp2lasta[usable_arenas->nfreepools - 1] = usable_arenas; + } + /* Try to get a cached free pool. */ pool = usable_arenas->freepools; if (pool != NULL) { /* Unlink from cached pools. */ usable_arenas->freepools = pool->nextpool; - - /* This arena already had the smallest nfreepools - * value, so decreasing nfreepools doesn't change - * that, and we don't need to rearrange the - * usable_arenas list. However, if the arena has - * become wholly allocated, we need to remove its - * arena_object from usable_arenas. - */ --usable_arenas->nfreepools; if (usable_arenas->nfreepools == 0) { /* Wholly allocated: remove. */ @@ -1501,7 +1530,6 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) assert(usable_arenas->nextarena == NULL || usable_arenas->nextarena->prevarena == usable_arenas); - usable_arenas = usable_arenas->nextarena; if (usable_arenas != NULL) { usable_arenas->prevarena = NULL; @@ -1709,7 +1737,23 @@ pymalloc_free(void *ctx, void *p) ao = &arenas[pool->arenaindex]; pool->nextpool = ao->freepools; ao->freepools = pool; - nf = ++ao->nfreepools; + nf = ao->nfreepools; + /* If this is the rightmost arena with this number of free pools, + * nfp2lasta[nf] needs to change. Caution: if nf is 0, there + * are no arenas in usable_arenas with that value. + */ + struct arena_object* lastnf = nfp2lasta[nf]; + assert((nf == 0 && lastnf == NULL) || + (nf > 0 && + lastnf != NULL && + lastnf->nfreepools == nf && + (lastnf->nextarena == NULL || + nf < lastnf->nextarena->nfreepools))); + if (lastnf == ao) { /* it is the rightmost */ + struct arena_object* p = ao->prevarena; + nfp2lasta[nf] = (p != NULL && p->nfreepools == nf) ? p : NULL; + } + ao->nfreepools = ++nf; /* All the rest is arena management. We just freed * a pool, and there are 4 cases for arena mgmt: @@ -1777,6 +1821,9 @@ pymalloc_free(void *ctx, void *p) usable_arenas->prevarena = ao; usable_arenas = ao; assert(usable_arenas->address != 0); + if (nfp2lasta[1] == NULL) { + nfp2lasta[1] = ao; + } goto success; } @@ -1788,14 +1835,23 @@ pymalloc_free(void *ctx, void *p) * a few un-scientific tests, it seems like this * approach allowed a lot more memory to be freed. */ - if (ao->nextarena == NULL || - nf <= ao->nextarena->nfreepools) { + /* If this is the only arena with nf, record that. */ + if (nfp2lasta[nf] == NULL) { + nfp2lasta[nf] = ao; + } /* else the rightmost with nf doesn't change */ + /* If this was the rightmost of the old size, it remains in place. */ + if (ao == lastnf) { /* Case 4. Nothing to do. */ goto success; } - /* Case 3: We have to move the arena towards the end - * of the list, because it has more free pools than - * the arena to its right. + /* If ao were the only arena in the list, the last block would have + * gotten us out. + */ + assert(ao->nextarena != NULL); + + /* Case 3: We have to move the arena towards the end of the list, + * because it has more free pools than the arena to its right. It needs + * to move to follow lastnf. * First unlink ao from usable_arenas. */ if (ao->prevarena != NULL) { @@ -1809,24 +1865,13 @@ pymalloc_free(void *ctx, void *p) usable_arenas = ao->nextarena; } ao->nextarena->prevarena = ao->prevarena; - - /* Locate the new insertion point by iterating over - * the list, using our nextarena pointer. - */ - while (ao->nextarena != NULL && nf > ao->nextarena->nfreepools) { - ao->prevarena = ao->nextarena; - ao->nextarena = ao->nextarena->nextarena; - } - - /* Insert ao at this point. */ - assert(ao->nextarena == NULL || ao->prevarena == ao->nextarena->prevarena); - assert(ao->prevarena->nextarena == ao->nextarena); - - ao->prevarena->nextarena = ao; + /* And insert after lastnf. */ + ao->prevarena = lastnf; + ao->nextarena = lastnf->nextarena; if (ao->nextarena != NULL) { ao->nextarena->prevarena = ao; } - + lastnf->nextarena = ao; /* Verify that the swaps worked. */ assert(ao->nextarena == NULL || nf <= ao->nextarena->nfreepools); assert(ao->prevarena == NULL || nf > ao->prevarena->nfreepools); From 396e0a8d9dc65453cb9d53500d0a620602656cfe Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 31 May 2019 21:16:47 -0600 Subject: [PATCH 231/441] bpo-36818: Add PyInterpreterState.runtime field. (gh-13129) https://bugs.python.org/issue36818 --- Include/cpython/pystate.h | 6 +- Include/internal/pycore_object.h | 7 +- Include/internal/pycore_pylifecycle.h | 10 +-- Include/internal/pycore_pystate.h | 12 +-- .../2019-05-06-14-46-48.bpo-36818.5UDDLj.rst | 1 + Modules/_threadmodule.c | 2 +- Python/ceval.c | 26 +++--- Python/import.c | 3 +- Python/pylifecycle.c | 15 ++-- Python/pystate.c | 89 +++++++++---------- Python/sysmodule.c | 31 +++---- 11 files changed, 99 insertions(+), 103 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 94b0809cd4f015..74e7fc96bec900 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -110,9 +110,9 @@ struct _ts { * if the thread holds the last reference to the lock, decref'ing the * lock will delete the lock, and that may trigger arbitrary Python code * if there's a weakref, with a callback, to the lock. But by this time - * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest - * of C code can be allowed to run (in particular it must not be possible to - * release the GIL). + * _PyRuntimeState.gilstate.tstate_current is already NULL, so only the + * simplest of C code can be allowed to run (in particular it must not be + * possible to release the GIL). * So instead of holding the lock directly, the tstate holds a weakref to * the lock: that's the value of on_delete_data below. Decref'ing a * weakref is harmless. diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 81548f819198e3..1c5beb01f45823 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -19,9 +19,10 @@ PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); * NB: While the object is tracked by the collector, it must be safe to call the * ob_traverse method. * - * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags - * because it's not object header. So we don't use _PyGCHead_PREV() and - * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. + * Internal note: _PyRuntimeState.gc.generation0->_gc_prev doesn't have + * any bit flags because it's not object header. So we don't use + * _PyGCHead_PREV() and _PyGCHead_SET_PREV() for it to avoid unnecessary + * bitwise operations. * * The PyObject_GC_Track() function is the public version of this macro. */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 8a692ea1649512..e30341710c20ae 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -39,13 +39,10 @@ extern PyStatus _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(void); extern PyStatus _PySys_Create( - _PyRuntimeState *runtime, PyInterpreterState *interp, PyObject **sysmod_p); extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); -extern int _PySys_InitMain( - _PyRuntimeState *runtime, - PyInterpreterState *interp); +extern int _PySys_InitMain(PyInterpreterState *interp); extern PyStatus _PyImport_Init(PyInterpreterState *interp); extern PyStatus _PyExc_Init(void); extern PyStatus _PyErr_Init(void); @@ -86,10 +83,7 @@ extern void _PyHash_Fini(void); extern int _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); -extern void _PyGILState_Init( - _PyRuntimeState *runtime, - PyInterpreterState *interp, - PyThreadState *tstate); +extern void _PyGILState_Init(PyThreadState *tstate); extern void _PyGILState_Fini(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 3ab4009770c9a0..520a74b8a61fde 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -19,6 +19,9 @@ extern "C" { #include "pycore_pymem.h" #include "pycore_warnings.h" +// forward +struct pyruntimestate; + /* ceval state */ @@ -68,6 +71,7 @@ struct _is { struct _is *next; struct _ts *tstate_head; + struct pyruntimestate *runtime; int64_t id; int64_t id_refcount; @@ -296,12 +300,8 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); /* Other */ -PyAPI_FUNC(void) _PyThreadState_Init( - _PyRuntimeState *runtime, - PyThreadState *tstate); -PyAPI_FUNC(void) _PyThreadState_DeleteExcept( - _PyRuntimeState *runtime, - PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( struct _gilstate_runtime_state *gilstate, diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst new file mode 100644 index 00000000000000..bb6c56a628e955 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst @@ -0,0 +1 @@ +Add PyInterpreterState.runtime (and use it). diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index d5e40ef999e3d5..099afd86d05505 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -996,7 +996,7 @@ t_bootstrap(void *boot_raw) tstate = boot->tstate; tstate->thread_id = PyThread_get_thread_ident(); - _PyThreadState_Init(&_PyRuntime, tstate); + _PyThreadState_Init(tstate); PyEval_AcquireThread(tstate); tstate->interp->num_threads++; res = PyObject_Call(boot->func, boot->args, boot->keyw); diff --git a/Python/ceval.c b/Python/ceval.c index 71e6eb8ebcfd3e..f9ff4e09f17e20 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -217,8 +217,9 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval) } static inline void -exit_thread_if_finalizing(_PyRuntimeState *runtime, PyThreadState *tstate) +exit_thread_if_finalizing(PyThreadState *tstate) { + _PyRuntimeState *runtime = tstate->interp->runtime; /* _Py_Finalizing is protected by the GIL */ if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { drop_gil(&runtime->ceval, tstate); @@ -236,7 +237,7 @@ PyEval_AcquireLock(void) Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); } take_gil(ceval, tstate); - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); } void @@ -257,14 +258,15 @@ PyEval_AcquireThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_AcquireThread: NULL new thread state"); } + assert(tstate->interp != NULL); - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = tstate->interp->runtime; struct _ceval_runtime_state *ceval = &runtime->ceval; /* Check someone has called PyEval_InitThreads() to create the lock */ assert(gil_created(&ceval->gil)); take_gil(ceval, tstate); - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); } @@ -276,8 +278,9 @@ PyEval_ReleaseThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_ReleaseThread: NULL thread state"); } + assert(tstate->interp != NULL); - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = tstate->interp->runtime; PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (new_tstate != tstate) { Py_FatalError("PyEval_ReleaseThread: wrong thread state"); @@ -308,7 +311,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) } /* Destroy all threads except the current one */ - _PyThreadState_DeleteExcept(runtime, current_tstate); + _PyThreadState_DeleteExcept(current_tstate); } /* This function is used to signal that async exceptions are waiting to be @@ -337,17 +340,18 @@ PyEval_SaveThread(void) void PyEval_RestoreThread(PyThreadState *tstate) { - _PyRuntimeState *runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - if (tstate == NULL) { Py_FatalError("PyEval_RestoreThread: NULL tstate"); } + assert(tstate->interp != NULL); + + _PyRuntimeState *runtime = tstate->interp->runtime; + struct _ceval_runtime_state *ceval = &runtime->ceval; assert(gil_created(&ceval->gil)); int err = errno; take_gil(ceval, tstate); - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); errno = err; _PyThreadState_Swap(&runtime->gilstate, tstate); @@ -1141,7 +1145,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) take_gil(ceval, tstate); /* Check if we should make a quick exit. */ - exit_thread_if_finalizing(runtime, tstate); + exit_thread_if_finalizing(tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("ceval: orphan tstate"); diff --git a/Python/import.c b/Python/import.c index ab7db6bc17f6b1..68d1f4003abcee 100644 --- a/Python/import.c +++ b/Python/import.c @@ -541,7 +541,8 @@ PyImport_Cleanup(void) _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings machinery. */ - _PyGC_DumpShutdownStats(&_PyRuntime); + _PyRuntimeState *runtime = interp->runtime; + _PyGC_DumpShutdownStats(runtime); /* Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 10a28813faa8db..6590ef8e9a27a0 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -545,7 +545,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, _PyEval_FiniThreads(&runtime->ceval); /* Auto-thread-state API */ - _PyGILState_Init(runtime, interp, tstate); + _PyGILState_Init(tstate); /* Create the GIL */ PyEval_InitThreads(); @@ -683,7 +683,7 @@ pyinit_config(_PyRuntimeState *runtime, } PyObject *sysmod; - status = _PySys_Create(runtime, interp, &sysmod); + status = _PySys_Create(interp, &sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -892,8 +892,9 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * non-zero return code. */ static PyStatus -pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) +pyinit_main(PyInterpreterState *interp) { + _PyRuntimeState *runtime = interp->runtime; if (!runtime->core_initialized) { return _PyStatus_ERR("runtime core not initialized"); } @@ -919,7 +920,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) return _PyStatus_ERR("can't initialize time"); } - if (_PySys_InitMain(runtime, interp) < 0) { + if (_PySys_InitMain(interp) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } @@ -999,7 +1000,7 @@ _Py_InitializeMain(void) _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - return pyinit_main(runtime, interp); + return pyinit_main(interp); } @@ -1026,7 +1027,7 @@ Py_InitializeFromConfig(const PyConfig *config) config = &interp->config; if (config->_init_main) { - status = pyinit_main(runtime, interp); + status = pyinit_main(interp); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1453,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p) } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); - if (_PySys_InitMain(runtime, interp) < 0) { + if (_PySys_InitMain(interp) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } } diff --git a/Python/pystate.c b/Python/pystate.c index 833e0fb30dcb26..2b7db0e48debe9 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -39,7 +39,6 @@ extern "C" { /* Forward declarations */ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); -static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate); static PyStatus @@ -192,6 +191,8 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) PyInterpreterState * PyInterpreterState_New(void) { + _PyRuntimeState *runtime = &_PyRuntime; + if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) { return NULL; } @@ -202,6 +203,9 @@ PyInterpreterState_New(void) } memset(interp, 0, sizeof(*interp)); + + interp->runtime = runtime; + interp->id_refcount = -1; interp->check_interval = 100; @@ -223,7 +227,6 @@ PyInterpreterState_New(void) #endif #endif - _PyRuntimeState *runtime = &_PyRuntime; struct pyinterpreters *interpreters = &runtime->interpreters; HEAD_LOCK(runtime); @@ -257,9 +260,11 @@ PyInterpreterState_New(void) } -static void -_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) +void +PyInterpreterState_Clear(PyInterpreterState *interp) { + _PyRuntimeState *runtime = interp->runtime; + if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) { PyErr_Clear(); } @@ -297,31 +302,25 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) // objects have been cleaned up at the point. } -void -PyInterpreterState_Clear(PyInterpreterState *interp) -{ - _PyInterpreterState_Clear(&_PyRuntime, interp); -} - static void -zapthreads(_PyRuntimeState *runtime, PyInterpreterState *interp) +zapthreads(PyInterpreterState *interp) { - PyThreadState *p; + PyThreadState *ts; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ - while ((p = interp->tstate_head) != NULL) { - _PyThreadState_Delete(runtime, p); + while ((ts = interp->tstate_head) != NULL) { + PyThreadState_Delete(ts); } } -static void -_PyInterpreterState_Delete(_PyRuntimeState *runtime, - PyInterpreterState *interp) +void +PyInterpreterState_Delete(PyInterpreterState *interp) { + _PyRuntimeState *runtime = interp->runtime; struct pyinterpreters *interpreters = &runtime->interpreters; - zapthreads(runtime, interp); + zapthreads(interp); HEAD_LOCK(runtime); PyInterpreterState **p; for (p = &interpreters->head; ; p = &(*p)->next) { @@ -350,13 +349,6 @@ _PyInterpreterState_Delete(_PyRuntimeState *runtime, } -void -PyInterpreterState_Delete(PyInterpreterState *interp) -{ - _PyInterpreterState_Delete(&_PyRuntime, interp); -} - - /* * Delete all interpreter states except the main interpreter. If there * is a current interpreter state, it *must* be the main interpreter. @@ -383,8 +375,8 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) continue; } - _PyInterpreterState_Clear(runtime, interp); // XXX must activate? - zapthreads(runtime, interp); + PyInterpreterState_Clear(interp); // XXX must activate? + zapthreads(interp); if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } @@ -497,7 +489,8 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) if (interp->id_mutex == NULL) { return; } - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + _PyRuntimeState *runtime = interp->runtime; + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); interp->id_refcount -= 1; @@ -559,7 +552,7 @@ threadstate_getframe(PyThreadState *self) static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { - _PyRuntimeState *runtime = &_PyRuntime; + _PyRuntimeState *runtime = interp->runtime; PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (tstate == NULL) { return NULL; @@ -615,7 +608,7 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->id = ++interp->tstate_next_unique_id; if (init) { - _PyThreadState_Init(runtime, tstate); + _PyThreadState_Init(tstate); } HEAD_LOCK(runtime); @@ -642,8 +635,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) } void -_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) +_PyThreadState_Init(PyThreadState *tstate) { + _PyRuntimeState *runtime = tstate->interp->runtime; _PyGILState_NoteThreadState(&runtime->gilstate, tstate); } @@ -808,7 +802,7 @@ PyThreadState_Clear(PyThreadState *tstate) /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) +tstate_delete_common(PyThreadState *tstate) { if (tstate == NULL) { Py_FatalError("PyThreadState_Delete: NULL tstate"); @@ -817,6 +811,7 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) if (interp == NULL) { Py_FatalError("PyThreadState_Delete: NULL interp"); } + _PyRuntimeState *runtime = interp->runtime; HEAD_LOCK(runtime); if (tstate->prev) tstate->prev->next = tstate->next; @@ -832,9 +827,10 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) } -static void -_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) +void +PyThreadState_Delete(PyThreadState *tstate) { + _PyRuntimeState *runtime = tstate->interp->runtime; struct _gilstate_runtime_state *gilstate = &runtime->gilstate; if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { Py_FatalError("PyThreadState_Delete: tstate is still current"); @@ -844,14 +840,7 @@ _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) { PyThread_tss_set(&gilstate->autoTSSkey, NULL); } - tstate_delete_common(runtime, tstate); -} - - -void -PyThreadState_Delete(PyThreadState *tstate) -{ - _PyThreadState_Delete(&_PyRuntime, tstate); + tstate_delete_common(tstate); } @@ -863,7 +852,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - tstate_delete_common(runtime, tstate); + tstate_delete_common(tstate); if (gilstate->autoInterpreterState && PyThread_tss_get(&gilstate->autoTSSkey) == tstate) { @@ -888,9 +877,10 @@ PyThreadState_DeleteCurrent() * be kept in those other interpreteres. */ void -_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) +_PyThreadState_DeleteExcept(PyThreadState *tstate) { PyInterpreterState *interp = tstate->interp; + _PyRuntimeState *runtime = interp->runtime; PyThreadState *p, *next, *garbage; HEAD_LOCK(runtime); /* Remove all thread states, except tstate, from the linked list of @@ -1129,8 +1119,9 @@ _PyThread_CurrentFrames(void) static int PyThreadState_IsCurrent(PyThreadState *tstate) { + _PyRuntimeState *runtime = tstate->interp->runtime; /* Must be the tstate for this thread */ - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + struct _gilstate_runtime_state *gilstate = &runtime->gilstate; assert(_PyGILState_GetThisThreadState(gilstate) == tstate); return tstate == _PyRuntimeGILState_GetThreadState(gilstate); } @@ -1139,12 +1130,14 @@ PyThreadState_IsCurrent(PyThreadState *tstate) Py_Initialize/Py_FinalizeEx */ void -_PyGILState_Init(_PyRuntimeState *runtime, - PyInterpreterState *interp, PyThreadState *tstate) +_PyGILState_Init(PyThreadState *tstate) { /* must init with valid states */ - assert(interp != NULL); assert(tstate != NULL); + PyInterpreterState *interp = tstate->interp; + assert(interp != NULL); + _PyRuntimeState *runtime = interp->runtime; + assert(runtime != NULL); struct _gilstate_runtime_state *gilstate = &runtime->gilstate; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 12b1bd7711d5b8..97bff94d8b4196 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -120,8 +120,9 @@ should_audit(void) if (!ts) { return 0; } - PyInterpreterState *is = ts ? ts->interp : NULL; - return _PyRuntime.audit_hook_head + PyInterpreterState *is = ts->interp; + _PyRuntimeState *runtime = is->runtime; + return runtime->audit_hook_head || (is && is->audit_hooks) || PyDTrace_AUDIT_ENABLED(); } @@ -280,8 +281,8 @@ void _PySys_ClearAuditHooks(void) { PySys_Audit("cpython._PySys_ClearAuditHooks", NULL); PyErr_Clear(); - _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n; - _PyRuntime.audit_hook_head = NULL; + _Py_AuditHookEntry *e = runtime->audit_hook_head, *n; + runtime->audit_hook_head = NULL; while (e) { n = e->next; PyMem_RawFree(e); @@ -292,6 +293,7 @@ void _PySys_ClearAuditHooks(void) { int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) { + _PyRuntimeState *runtime = &_PyRuntime; /* Invoke existing audit hooks to allow them an opportunity to abort. */ /* Cannot invoke hooks until we are initialized */ if (Py_IsInitialized()) { @@ -305,10 +307,10 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) } } - _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; + _Py_AuditHookEntry *e = runtime->audit_hook_head; if (!e) { e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); - _PyRuntime.audit_hook_head = e; + runtime->audit_hook_head = e; } else { while (e->next) e = e->next; @@ -2413,8 +2415,9 @@ static PyStructSequence_Desc flags_desc = { }; static PyObject* -make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) +make_flags(PyInterpreterState *interp) { + _PyRuntimeState *runtime = interp->runtime; int pos = 0; PyObject *seq; const PyPreConfig *preconfig = &runtime->preconfig; @@ -2633,8 +2636,7 @@ static struct PyModuleDef sysmodule = { } while (0) static PyStatus -_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, - PyObject *sysdict) +_PySys_InitCore(PyInterpreterState *interp, PyObject *sysdict) { PyObject *version_info; int res; @@ -2728,7 +2730,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, } } /* Set flags to their default values (updated by _PySys_InitMain()) */ - SET_SYS_FROM_STRING("flags", make_flags(runtime, interp)); + SET_SYS_FROM_STRING("flags", make_flags(interp)); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -2849,7 +2851,7 @@ sys_create_xoptions_dict(const PyConfig *config) int -_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) +_PySys_InitMain(PyInterpreterState *interp) { PyObject *sysdict = interp->sysdict; const PyConfig *config = &interp->config; @@ -2903,7 +2905,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) #undef SET_SYS_FROM_WSTR /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp)); + SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(interp)); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; @@ -2970,8 +2972,7 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict) /* Create sys module without all attributes: _PySys_InitMain() should be called later to add remaining attributes. */ PyStatus -_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, - PyObject **sysmod_p) +_PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p) { PyObject *modules = PyDict_New(); if (modules == NULL) { @@ -3000,7 +3001,7 @@ _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, return status; } - status = _PySys_InitCore(runtime, interp, sysdict); + status = _PySys_InitCore(interp, sysdict); if (_PyStatus_EXCEPTION(status)) { return status; } From 5c22476c01622f11b7745ee693f8b296a9d6a761 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Sat, 1 Jun 2019 06:10:02 +0200 Subject: [PATCH 232/441] Improve docstring of list.sort (GH-8516) --- Objects/clinic/listobject.c.h | 12 ++++++++++-- Objects/listobject.c | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index 7b8e2d9905f9c2..57f0a48eb0838b 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -156,7 +156,15 @@ PyDoc_STRVAR(list_sort__doc__, "sort($self, /, *, key=None, reverse=False)\n" "--\n" "\n" -"Stable sort *IN PLACE*."); +"Sort the list in ascending order and return None.\n" +"\n" +"The sort is in-place (i.e. the list itself is modified) and stable (i.e. the\n" +"order of two equal elements is maintained).\n" +"\n" +"If a key function is given, apply it once to each list item and sort them,\n" +"ascending or descending, according to their function values.\n" +"\n" +"The reverse flag can be set to sort in descending order."); #define LIST_SORT_METHODDEF \ {"sort", (PyCFunction)(void(*)(void))list_sort, METH_FASTCALL|METH_KEYWORDS, list_sort__doc__}, @@ -359,4 +367,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=d1d5078edb7d3cf4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=73718c0c33798c62 input=a9049054013a1b77]*/ diff --git a/Objects/listobject.c b/Objects/listobject.c index 233f13dbab0ef2..f8bf45e5f8cda2 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2197,12 +2197,20 @@ list.sort key as keyfunc: object = None reverse: bool(accept={int}) = False -Stable sort *IN PLACE*. +Sort the list in ascending order and return None. + +The sort is in-place (i.e. the list itself is modified) and stable (i.e. the +order of two equal elements is maintained). + +If a key function is given, apply it once to each list item and sort them, +ascending or descending, according to their function values. + +The reverse flag can be set to sort in descending order. [clinic start generated code]*/ static PyObject * list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) -/*[clinic end generated code: output=57b9f9c5e23fbe42 input=b0fcf743982c5b90]*/ +/*[clinic end generated code: output=57b9f9c5e23fbe42 input=cb56cd179a713060]*/ { MergeState ms; Py_ssize_t nremaining; From 664fe3996f7e05ae351526f02b21504bb065bcf8 Mon Sep 17 00:00:00 2001 From: Rob Day Date: Sat, 1 Jun 2019 05:13:57 +0100 Subject: [PATCH 233/441] bpo-29984: Improve 'heapq' test coverage (GH-992) --- Lib/heapq.py | 4 ++-- Lib/test/test_heapq.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Lib/heapq.py b/Lib/heapq.py index 0e3555cf9118ea..fabefd87f8bf8c 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -597,5 +597,5 @@ def nlargest(n, iterable, key=None): if __name__ == "__main__": - import doctest - print(doctest.testmod()) + import doctest # pragma: no cover + print(doctest.testmod()) # pragma: no cover diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py index 2f8c648d84a583..6c20b6297dfcc2 100644 --- a/Lib/test/test_heapq.py +++ b/Lib/test/test_heapq.py @@ -2,6 +2,7 @@ import random import unittest +import doctest from test import support from unittest import TestCase, skipUnless @@ -26,6 +27,23 @@ def test_c_functions(self): self.assertEqual(getattr(c_heapq, fname).__module__, '_heapq') +def load_tests(loader, tests, ignore): + # The 'merge' function has examples in its docstring which we should test + # with 'doctest'. + # + # However, doctest can't easily find all docstrings in the module (loading + # it through import_fresh_module seems to confuse it), so we specifically + # create a finder which returns the doctests from the merge method. + + class HeapqMergeDocTestFinder: + def find(self, *args, **kwargs): + dtf = doctest.DocTestFinder() + return dtf.find(py_heapq.merge) + + tests.addTests(doctest.DocTestSuite(py_heapq, + test_finder=HeapqMergeDocTestFinder())) + return tests + class TestHeap: def test_push_pop(self): @@ -135,6 +153,13 @@ def test_heappushpop(self): x = self.module.heappushpop(h, 11) self.assertEqual((h, x), ([11], 10)) + def test_heappop_max(self): + # _heapop_max has an optimization for one-item lists which isn't + # covered in other tests, so test that case explicitly here + h = [3, 2] + self.assertEqual(self.module._heappop_max(h), 3) + self.assertEqual(self.module._heappop_max(h), 2) + def test_heapsort(self): # Exercise everything with repeated heapsort checks for trial in range(100): @@ -168,6 +193,12 @@ def test_merge(self): list(self.module.merge(*seqs, key=key, reverse=reverse))) self.assertEqual(list(self.module.merge()), []) + def test_empty_merges(self): + # Merging two empty lists (with or without a key) should produce + # another empty list. + self.assertEqual(list(self.module.merge([], [])), []) + self.assertEqual(list(self.module.merge([], [], key=lambda: 6)), []) + def test_merge_does_not_suppress_index_error(self): # Issue 19018: Heapq.merge suppresses IndexError from user generator def iterable(): From 354227a1e90036d8c1481a211746de912c6c7c33 Mon Sep 17 00:00:00 2001 From: Mario Corchero Date: Sat, 1 Jun 2019 05:49:10 +0100 Subject: [PATCH 234/441] Add option to trace to run modules (GH-5134) Adds a new option in trace that allows tracing runnable modules. It is exposed as `--module module_name` as `-m` is already in use for another argument. --- Doc/library/trace.rst | 3 ++ Lib/test/test_trace.py | 7 ++- Lib/trace.py | 46 +++++++++++++------ .../2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst | 1 + 4 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index 5cb7029adf5e9e..85fec6830006c7 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -42,6 +42,9 @@ all Python modules imported during the execution into the current directory. Display the version of the module and exit. +.. versionadded:: 3.8 + Added ``--module`` option that allows to run an executable module. + Main options ^^^^^^^^^^^^ diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index afe79026766192..4bc21eae02ce10 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -474,7 +474,7 @@ class TestCommandLine(unittest.TestCase): def test_failures(self): _errors = ( - (b'filename is missing: required with the main options', '-l', '-T'), + (b'progname is missing: required with the main options', '-l', '-T'), (b'cannot specify both --listfuncs and (--trace or --count)', '-lc'), (b'argument -R/--no-report: not allowed with argument -r/--report', '-rR'), (b'must specify one of --trace, --count, --report, --listfuncs, or --trackcalls', '-g'), @@ -524,5 +524,10 @@ def f(): self.assertIn('lines cov% module (path)', stdout) self.assertIn(f'6 100% {TESTFN} ({filename})', stdout) + def test_run_as_module(self): + assert_python_ok('-m', 'trace', '-l', '--module', 'timeit', '-n', '1') + assert_python_failure('-m', 'trace', '-l', '--module', 'not_a_module_zzz') + + if __name__ == '__main__': unittest.main() diff --git a/Lib/trace.py b/Lib/trace.py index 63008a134a8aec..62325d3f238ad6 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -666,7 +666,9 @@ def main(): help='Ignore files in the given directory ' '(multiple directories can be joined by os.pathsep).') - parser.add_argument('filename', nargs='?', + parser.add_argument('--module', action='store_true', default=False, + help='Trace a module. ') + parser.add_argument('progname', nargs='?', help='file to run as main program') parser.add_argument('arguments', nargs=argparse.REMAINDER, help='arguments to the program') @@ -704,26 +706,40 @@ def parse_ignore_dir(s): if opts.summary and not opts.count: parser.error('--summary can only be used with --count or --report') - if opts.filename is None: - parser.error('filename is missing: required with the main options') - - sys.argv = [opts.filename, *opts.arguments] - sys.path[0] = os.path.dirname(opts.filename) + if opts.progname is None: + parser.error('progname is missing: required with the main options') t = Trace(opts.count, opts.trace, countfuncs=opts.listfuncs, countcallers=opts.trackcalls, ignoremods=opts.ignore_module, ignoredirs=opts.ignore_dir, infile=opts.file, outfile=opts.file, timing=opts.timing) try: - with open(opts.filename) as fp: - code = compile(fp.read(), opts.filename, 'exec') - # try to emulate __main__ namespace as much as possible - globs = { - '__file__': opts.filename, - '__name__': '__main__', - '__package__': None, - '__cached__': None, - } + if opts.module: + import runpy + module_name = opts.progname + mod_name, mod_spec, code = runpy._get_module_details(module_name) + sys.argv = [code.co_filename, *opts.arguments] + globs = { + '__name__': '__main__', + '__file__': code.co_filename, + '__package__': mod_spec.parent, + '__loader__': mod_spec.loader, + '__spec__': mod_spec, + '__cached__': None, + } + else: + sys.argv = [opts.progname, *opts.arguments] + sys.path[0] = os.path.dirname(opts.progname) + + with open(opts.progname) as fp: + code = compile(fp.read(), opts.progname, 'exec') + # try to emulate __main__ namespace as much as possible + globs = { + '__file__': opts.progname, + '__name__': '__main__', + '__package__': None, + '__cached__': None, + } t.runctx(code, globs, globs) except OSError as err: sys.exit("Cannot run file %r because: %s" % (sys.argv[0], err)) diff --git a/Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst b/Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst new file mode 100644 index 00000000000000..ad585b3ab5edfb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst @@ -0,0 +1 @@ +trace.py can now run modules via python3 -m trace -t --module module_name From 5ac0b988fd5f1428efe35329c531c7b5c74d37f6 Mon Sep 17 00:00:00 2001 From: Windson yang Date: Sat, 1 Jun 2019 14:33:16 +0800 Subject: [PATCH 235/441] bpo-18911: clarify that the minidom XML writer receives texts but not bytes (GH-13352) --- Doc/library/xml.dom.minidom.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 2423a0c15691f4..8711242d95d741 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -134,11 +134,12 @@ module documentation. This section lists the differences between the API and .. method:: Node.writexml(writer, indent="", addindent="", newl="") - Write XML to the writer object. The writer should have a :meth:`write` method - which matches that of the file object interface. The *indent* parameter is the - indentation of the current node. The *addindent* parameter is the incremental - indentation to use for subnodes of the current one. The *newl* parameter - specifies the string to use to terminate newlines. + Write XML to the writer object. The writer receives texts but not bytes as input, + it should have a :meth:`write` method which matches that of the file object + interface. The *indent* parameter is the indentation of the current node. + The *addindent* parameter is the incremental indentation to use for subnodes + of the current one. The *newl* parameter specifies the string to use to + terminate newlines. For the :class:`Document` node, an additional keyword argument *encoding* can be used to specify the encoding field of the XML header. From 4a686504eb2bbf69adf78077458508a7ba131667 Mon Sep 17 00:00:00 2001 From: Yash Aggarwal Date: Sat, 1 Jun 2019 12:51:27 +0530 Subject: [PATCH 236/441] bpo-35431: Implemented math.comb (GH-11414) --- Doc/library/math.rst | 15 +++ Lib/test/test_math.py | 51 ++++++++ .../2019-01-02-19-48-23.bpo-35431.FhG6QA.rst | 4 + Modules/clinic/mathmodule.c.h | 51 +++++++- Modules/mathmodule.c | 121 ++++++++++++++++++ 5 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst diff --git a/Doc/library/math.rst b/Doc/library/math.rst index b51e96bc40743f..5243970df806ae 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -232,6 +232,21 @@ Number-theoretic and representation functions :meth:`x.__trunc__() `. +.. function:: comb(n, k) + + Return the number of ways to choose *k* items from *n* items without repetition + and without order. + + Also called the binomial coefficient. It is mathematically equal to the expression + ``n! / (k! (n - k)!)``. It is equivalent to the coefficient of k-th term in + polynomial expansion of the expression ``(1 + x) ** n``. + + Raises :exc:`TypeError` if the arguments not integers. + Raises :exc:`ValueError` if the arguments are negative or if k > n. + + .. versionadded:: 3.8 + + Note that :func:`frexp` and :func:`modf` have a different call/return pattern than their C equivalents: they take a single argument and return a pair of values, rather than returning their second return value through an 'output diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 853a0e62f82351..9da7f7c4e6e2f2 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1862,6 +1862,57 @@ def test_fractions(self): self.assertAllClose(fraction_examples, rel_tol=1e-8) self.assertAllNotClose(fraction_examples, rel_tol=1e-9) + def testComb(self): + comb = math.comb + factorial = math.factorial + # Test if factorial defintion is satisfied + for n in range(100): + for k in range(n + 1): + self.assertEqual(comb(n, k), factorial(n) + // (factorial(k) * factorial(n - k))) + + # Test for Pascal's identity + for n in range(1, 100): + for k in range(1, n): + self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k)) + + # Test corner cases + for n in range(100): + self.assertEqual(comb(n, 0), 1) + self.assertEqual(comb(n, n), 1) + + for n in range(1, 100): + self.assertEqual(comb(n, 1), n) + self.assertEqual(comb(n, n - 1), n) + + # Test Symmetry + for n in range(100): + for k in range(n // 2): + self.assertEqual(comb(n, k), comb(n, n - k)) + + # Raises TypeError if any argument is non-integer or argument count is + # not 2 + self.assertRaises(TypeError, comb, 10, 1.0) + self.assertRaises(TypeError, comb, 10, "1") + self.assertRaises(TypeError, comb, "10", 1) + self.assertRaises(TypeError, comb, 10.0, 1) + + self.assertRaises(TypeError, comb, 10) + self.assertRaises(TypeError, comb, 10, 1, 3) + self.assertRaises(TypeError, comb) + + # Raises Value error if not k or n are negative numbers + self.assertRaises(ValueError, comb, -1, 1) + self.assertRaises(ValueError, comb, -10*10, 1) + self.assertRaises(ValueError, comb, 1, -1) + self.assertRaises(ValueError, comb, 1, -10*10) + + # Raises value error if k is greater than n + self.assertRaises(ValueError, comb, 1, 10**10) + self.assertRaises(ValueError, comb, 0, 1) + + + def test_main(): from doctest import DocFileSuite diff --git a/Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst b/Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst new file mode 100644 index 00000000000000..34687bdb8a251f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst @@ -0,0 +1,4 @@ +Implement :func:`math.comb` that returns binomial coefficient, that computes +the number of ways to choose k items from n items without repetition and +without order. +Patch by Yash Aggarwal and Keller Fuchs. diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index e677bd896cd885..cba791e2098f28 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -637,4 +637,53 @@ math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k exit: return return_value; } -/*[clinic end generated code: output=aeed62f403b90199 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(math_comb__doc__, +"comb($module, /, n, k)\n" +"--\n" +"\n" +"Number of ways to choose *k* items from *n* items without repetition and without order.\n" +"\n" +"Also called the binomial coefficient. It is mathematically equal to the expression\n" +"n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in\n" +"polynomial expansion of the expression (1 + x)**n.\n" +"\n" +"Raises TypeError if the arguments are not integers.\n" +"Raises ValueError if the arguments are negative or if k > n."); + +#define MATH_COMB_METHODDEF \ + {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL|METH_KEYWORDS, math_comb__doc__}, + +static PyObject * +math_comb_impl(PyObject *module, PyObject *n, PyObject *k); + +static PyObject * +math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"n", "k", NULL}; + static _PyArg_Parser _parser = {NULL, _keywords, "comb", 0}; + PyObject *argsbuf[2]; + PyObject *n; + PyObject *k; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyLong_Check(args[0])) { + _PyArg_BadArgument("comb", 1, "int", args[0]); + goto exit; + } + n = args[0]; + if (!PyLong_Check(args[1])) { + _PyArg_BadArgument("comb", 2, "int", args[1]); + goto exit; + } + k = args[1]; + return_value = math_comb_impl(module, n, k); + +exit: + return return_value; +} +/*[clinic end generated code: output=00aa76356759617a input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index a153e984ca59f2..007a8801429c56 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2998,6 +2998,126 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) } +/*[clinic input] +math.comb + + n: object(subclass_of='&PyLong_Type') + k: object(subclass_of='&PyLong_Type') + +Number of ways to choose *k* items from *n* items without repetition and without order. + +Also called the binomial coefficient. It is mathematically equal to the expression +n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in +polynomial expansion of the expression (1 + x)**n. + +Raises TypeError if the arguments are not integers. +Raises ValueError if the arguments are negative or if k > n. + +[clinic start generated code]*/ + +static PyObject * +math_comb_impl(PyObject *module, PyObject *n, PyObject *k) +/*[clinic end generated code: output=bd2cec8d854f3493 input=565f340f98efb5b5]*/ +{ + PyObject *val = NULL, + *temp_obj1 = NULL, + *temp_obj2 = NULL, + *dump_var = NULL; + int overflow, cmp; + long long i, terms; + + cmp = PyObject_RichCompareBool(n, k, Py_LT); + if (cmp < 0) { + goto fail_comb; + } + else if (cmp > 0) { + PyErr_Format(PyExc_ValueError, + "n must be an integer greater than or equal to k"); + goto fail_comb; + } + + /* b = min(b, a - b) */ + dump_var = PyNumber_Subtract(n, k); + if (dump_var == NULL) { + goto fail_comb; + } + cmp = PyObject_RichCompareBool(k, dump_var, Py_GT); + if (cmp < 0) { + goto fail_comb; + } + else if (cmp > 0) { + k = dump_var; + dump_var = NULL; + } + else { + Py_DECREF(dump_var); + dump_var = NULL; + } + + terms = PyLong_AsLongLongAndOverflow(k, &overflow); + if (terms < 0 && PyErr_Occurred()) { + goto fail_comb; + } + else if (overflow > 0) { + PyErr_Format(PyExc_OverflowError, + "minimum(n - k, k) must not exceed %lld", + LLONG_MAX); + goto fail_comb; + } + else if (overflow < 0 || terms < 0) { + PyErr_Format(PyExc_ValueError, + "k must be a positive integer"); + goto fail_comb; + } + + if (terms == 0) { + return PyNumber_Long(_PyLong_One); + } + + val = PyNumber_Long(n); + for (i = 1; i < terms; ++i) { + temp_obj1 = PyLong_FromSsize_t(i); + if (temp_obj1 == NULL) { + goto fail_comb; + } + temp_obj2 = PyNumber_Subtract(n, temp_obj1); + if (temp_obj2 == NULL) { + goto fail_comb; + } + dump_var = val; + val = PyNumber_Multiply(val, temp_obj2); + if (val == NULL) { + goto fail_comb; + } + Py_DECREF(dump_var); + dump_var = NULL; + Py_DECREF(temp_obj2); + temp_obj2 = PyLong_FromUnsignedLongLong((unsigned long long)(i + 1)); + if (temp_obj2 == NULL) { + goto fail_comb; + } + dump_var = val; + val = PyNumber_FloorDivide(val, temp_obj2); + if (val == NULL) { + goto fail_comb; + } + Py_DECREF(dump_var); + Py_DECREF(temp_obj1); + Py_DECREF(temp_obj2); + } + + return val; + +fail_comb: + Py_XDECREF(val); + Py_XDECREF(dump_var); + Py_XDECREF(temp_obj1); + Py_XDECREF(temp_obj2); + + return NULL; +} + + static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, {"acosh", math_acosh, METH_O, math_acosh_doc}, @@ -3047,6 +3167,7 @@ static PyMethodDef math_methods[] = { {"tanh", math_tanh, METH_O, math_tanh_doc}, MATH_TRUNC_METHODDEF MATH_PROD_METHODDEF + MATH_COMB_METHODDEF {NULL, NULL} /* sentinel */ }; From 2085bd0877e17ad4d98a4586d5eabb6faecbb190 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 1 Jun 2019 11:00:15 +0300 Subject: [PATCH 237/441] bpo-37116: Use PEP 570 syntax for positional-only parameters. (GH-13700) --- Doc/library/collections.rst | 2 +- Doc/library/contextlib.rst | 2 +- Doc/library/email.headerregistry.rst | 2 +- Doc/library/functools.rst | 4 +- Doc/library/inspect.rst | 2 +- Doc/library/operator.rst | 4 +- Doc/library/string.rst | 6 +- Doc/library/types.rst | 2 +- Doc/library/unittest.mock-examples.rst | 4 +- Doc/library/unittest.rst | 4 +- Doc/library/weakref.rst | 2 +- Doc/whatsnew/3.8.rst | 3 +- Lib/_collections_abc.py | 29 ++++----- Lib/_py_abc.py | 2 +- Lib/_threading_local.py | 4 +- Lib/collections/__init__.py | 46 ++++----------- Lib/contextlib.py | 6 +- Lib/dataclasses.py | 9 +-- Lib/functools.py | 16 +---- Lib/idlelib/debugger_r.py | 2 +- Lib/idlelib/rpc.py | 2 +- Lib/inspect.py | 12 ++-- Lib/multiprocessing/dummy/__init__.py | 2 +- Lib/multiprocessing/managers.py | 11 ++-- Lib/multiprocessing/pool.py | 2 +- Lib/operator.py | 10 +--- Lib/random.py | 2 +- Lib/string.py | 41 +++---------- Lib/test/support/script_helper.py | 2 +- Lib/typing.py | 2 +- Lib/unittest/case.py | 30 +--------- Lib/unittest/mock.py | 82 +++++++++++--------------- Lib/unittest/test/test_runner.py | 5 +- Lib/weakref.py | 33 ++++------- 34 files changed, 126 insertions(+), 261 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index ec921d79d0c48b..90a3f4bea9a45b 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -1140,7 +1140,7 @@ variants of :func:`functools.lru_cache`:: class LRU(OrderedDict): 'Limit size, evicting the least recently looked-up key when full' - def __init__(self, maxsize=128, *args, **kwds): + def __init__(self, maxsize=128, /, *args, **kwds): self.maxsize = maxsize super().__init__(*args, **kwds) diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 017a87a5648c39..73b24e5f251a94 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -637,7 +637,7 @@ even further by means of a small helper class:: from contextlib import ExitStack class Callback(ExitStack): - def __init__(self, callback, *args, **kwds): + def __init__(self, callback, /, *args, **kwds): super(Callback, self).__init__() self.callback(callback, *args, **kwds) diff --git a/Doc/library/email.headerregistry.rst b/Doc/library/email.headerregistry.rst index ce283c6b596cf2..c3ce90c2d6d952 100644 --- a/Doc/library/email.headerregistry.rst +++ b/Doc/library/email.headerregistry.rst @@ -107,7 +107,7 @@ headers. method if it wishes to set additional attributes beyond those provided by ``BaseHeader`` itself. Such an ``init`` method should look like this:: - def init(self, *args, **kw): + def init(self, /, *args, **kw): self._myattr = kw.pop('myattr') super().init(*args, **kw) diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 8b8b1f80a622e7..654a3efa214b05 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -221,7 +221,7 @@ The :mod:`functools` module defines the following functions: Returning NotImplemented from the underlying comparison function for unrecognised types is now supported. -.. function:: partial(func, *args, **keywords) +.. function:: partial(func, /, *args, **keywords) Return a new :ref:`partial object` which when called will behave like *func* called with the positional arguments *args* @@ -230,7 +230,7 @@ The :mod:`functools` module defines the following functions: supplied, they extend and override *keywords*. Roughly equivalent to:: - def partial(func, *args, **keywords): + def partial(func, /, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = {**keywords, **fkeywords} return func(*args, *fargs, **newkeywords) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 1cc503a8e94b6d..2a71201a80b2cb 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -1022,7 +1022,7 @@ Classes and functions metatype is in use, cls will be the first element of the tuple. -.. function:: getcallargs(func, *args, **kwds) +.. function:: getcallargs(func, /, *args, **kwds) Bind the *args* and *kwds* to the argument names of the Python function or method *func*, as if it was called with them. For bound methods, bind also the diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index 5d0ea7dfdd8928..fa02bde84650e1 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -339,7 +339,7 @@ expect a function argument. [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)] -.. function:: methodcaller(name[, args...]) +.. function:: methodcaller(name, /, *args, **kwargs) Return a callable object that calls the method *name* on its operand. If additional arguments and/or keyword arguments are given, they will be given @@ -352,7 +352,7 @@ expect a function argument. Equivalent to:: - def methodcaller(name, *args, **kwargs): + def methodcaller(name, /, *args, **kwargs): def caller(obj): return getattr(obj, name)(*args, **kwargs) return caller diff --git a/Doc/library/string.rst b/Doc/library/string.rst index c2f65224bc8daf..288dde6b3fe4c0 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -88,7 +88,7 @@ implementation as the built-in :meth:`~str.format` method. The :class:`Formatter` class has the following public methods: - .. method:: format(format_string, *args, **kwargs) + .. method:: format(format_string, /, *args, **kwargs) The primary API method. It takes a format string and an arbitrary set of positional and keyword arguments. @@ -720,7 +720,7 @@ these rules. The methods of :class:`Template` are: The constructor takes a single argument which is the template string. - .. method:: substitute(mapping, **kwds) + .. method:: substitute(mapping={}, /, **kwds) Performs the template substitution, returning a new string. *mapping* is any dictionary-like object with keys that match the placeholders in the @@ -729,7 +729,7 @@ these rules. The methods of :class:`Template` are: and there are duplicates, the placeholders from *kwds* take precedence. - .. method:: safe_substitute(mapping, **kwds) + .. method:: safe_substitute(mapping={}, /, **kwds) Like :meth:`substitute`, except that if placeholders are missing from *mapping* and *kwds*, instead of raising a :exc:`KeyError` exception, the diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 07c3a2e7f68276..e629c2935f27f4 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -327,7 +327,7 @@ Additional Utility Classes and Functions The type is roughly equivalent to the following code:: class SimpleNamespace: - def __init__(self, **kwargs): + def __init__(self, /, **kwargs): self.__dict__.update(kwargs) def __repr__(self): diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index 16690f349822ec..811f0fb1ce9397 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -848,7 +848,7 @@ Here's an example implementation: >>> from copy import deepcopy >>> class CopyingMock(MagicMock): - ... def __call__(self, *args, **kwargs): + ... def __call__(self, /, *args, **kwargs): ... args = deepcopy(args) ... kwargs = deepcopy(kwargs) ... return super(CopyingMock, self).__call__(*args, **kwargs) @@ -1042,7 +1042,7 @@ that it takes arbitrary keyword arguments (``**kwargs``) which are then passed onto the mock constructor: >>> class Subclass(MagicMock): - ... def _get_child_mock(self, **kwargs): + ... def _get_child_mock(self, /, **kwargs): ... return MagicMock(**kwargs) ... >>> mymock = Subclass() diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 54a9f2c6f7355e..5ec4b40856ae91 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1456,7 +1456,7 @@ Test cases .. versionadded:: 3.1 - .. classmethod:: addClassCleanup(function, *args, **kwargs) + .. classmethod:: addClassCleanup(function, /, *args, **kwargs) Add a function to be called after :meth:`tearDownClass` to cleanup resources used during the test class. Functions will be called in reverse @@ -2313,7 +2313,7 @@ To add cleanup code that must be run even in the case of an exception, use ``addModuleCleanup``: -.. function:: addModuleCleanup(function, *args, **kwargs) +.. function:: addModuleCleanup(function, /, *args, **kwargs) Add a function to be called after :func:`tearDownModule` to cleanup resources used during the test class. Functions will be called in reverse diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 80a908bbd83b0a..a28d71060f3836 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -396,7 +396,7 @@ the referent is accessed:: import weakref class ExtendedRef(weakref.ref): - def __init__(self, ob, callback=None, **annotations): + def __init__(self, ob, callback=None, /, **annotations): super(ExtendedRef, self).__init__(ob, callback) self.__counter = 0 for k, v in annotations.items(): diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 76d00938dbec46..bc7c9ef37442d0 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -941,8 +941,7 @@ Deprecated :meth:`profile.Profile.runcall`, :meth:`cProfile.Profile.runcall`, :meth:`bdb.Bdb.runcall`, :meth:`trace.Trace.runfunc` and :func:`curses.wrapper`. - - *function* in :func:`unittest.addModuleCleanup` and - :meth:`unittest.TestCase.addCleanup`. + - *function* in :meth:`unittest.TestCase.addCleanup`. - *fn* in the :meth:`~concurrent.futures.Executor.submit` method of :class:`concurrent.futures.ThreadPoolExecutor` and :class:`concurrent.futures.ProcessPoolExecutor`. diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index c363987970b4c6..2b2ddba170e1b1 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -821,30 +821,21 @@ def clear(self): except KeyError: pass - def update(*args, **kwds): + def update(self, other=(), /, **kwds): ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v ''' - if not args: - raise TypeError("descriptor 'update' of 'MutableMapping' object " - "needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('update expected at most 1 arguments, got %d' % - len(args)) - if args: - other = args[0] - if isinstance(other, Mapping): - for key in other: - self[key] = other[key] - elif hasattr(other, "keys"): - for key in other.keys(): - self[key] = other[key] - else: - for key, value in other: - self[key] = value + if isinstance(other, Mapping): + for key in other: + self[key] = other[key] + elif hasattr(other, "keys"): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value for key, value in kwds.items(): self[key] = value diff --git a/Lib/_py_abc.py b/Lib/_py_abc.py index 3c3aa8e3d61bee..c870ae9048b4f1 100644 --- a/Lib/_py_abc.py +++ b/Lib/_py_abc.py @@ -32,7 +32,7 @@ class ABCMeta(type): # external code. _abc_invalidation_counter = 0 - def __new__(mcls, name, bases, namespace, **kwargs): + def __new__(mcls, name, bases, namespace, /, **kwargs): cls = super().__new__(mcls, name, bases, namespace, **kwargs) # Compute set of abstract method names abstracts = {name diff --git a/Lib/_threading_local.py b/Lib/_threading_local.py index 245bd0ac91b799..b006d76c4e23df 100644 --- a/Lib/_threading_local.py +++ b/Lib/_threading_local.py @@ -56,7 +56,7 @@ >>> class MyLocal(local): ... number = 2 - ... def __init__(self, **kw): + ... def __init__(self, /, **kw): ... self.__dict__.update(kw) ... def squared(self): ... return self.number ** 2 @@ -204,7 +204,7 @@ def _patch(self): class local: __slots__ = '_local__impl', '__dict__' - def __new__(cls, *args, **kw): + def __new__(cls, /, *args, **kw): if (args or kw) and (cls.__init__ is object.__init__): raise TypeError("Initialization arguments are not supported") self = object.__new__(cls) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 5b740d84c27507..e9999e27d5f535 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -93,16 +93,10 @@ class OrderedDict(dict): # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. - def __init__(*args, **kwds): + def __init__(self, other=(), /, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries. Keyword argument order is preserved. ''' - if not args: - raise TypeError("descriptor '__init__' of 'OrderedDict' object " - "needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: self.__root except AttributeError: @@ -110,7 +104,7 @@ def __init__(*args, **kwds): self.__root = root = _proxy(self.__hardroot) root.prev = root.next = root self.__map = {} - self.__update(*args, **kwds) + self.__update(other, **kwds) def __setitem__(self, key, value, dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): @@ -413,8 +407,8 @@ def _make(cls, iterable): _make.__func__.__doc__ = (f'Make a new {typename} object from a sequence ' 'or iterable') - def _replace(_self, **kwds): - result = _self._make(_map(kwds.pop, field_names, _self)) + def _replace(self, /, **kwds): + result = self._make(_map(kwds.pop, field_names, self)) if kwds: raise ValueError(f'Got unexpected field names: {list(kwds)!r}') return result @@ -543,7 +537,7 @@ class Counter(dict): # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 - def __init__(*args, **kwds): + def __init__(self, iterable=None, /, **kwds): '''Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts. @@ -554,14 +548,8 @@ def __init__(*args, **kwds): >>> c = Counter(a=4, b=2) # a new counter from keyword args ''' - if not args: - raise TypeError("descriptor '__init__' of 'Counter' object " - "needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) super(Counter, self).__init__() - self.update(*args, **kwds) + self.update(iterable, **kwds) def __missing__(self, key): 'The count of elements not in the Counter is zero.' @@ -617,7 +605,7 @@ def fromkeys(cls, iterable, v=None): raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') - def update(*args, **kwds): + def update(self, iterable=None, /, **kwds): '''Like dict.update() but add counts instead of replacing them. Source can be an iterable, a dictionary, or another Counter instance. @@ -637,13 +625,6 @@ def update(*args, **kwds): # contexts. Instead, we implement straight-addition. Both the inputs # and outputs are allowed to contain zero and negative counts. - if not args: - raise TypeError("descriptor 'update' of 'Counter' object " - "needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - iterable = args[0] if args else None if iterable is not None: if isinstance(iterable, _collections_abc.Mapping): if self: @@ -657,7 +638,7 @@ def update(*args, **kwds): if kwds: self.update(kwds) - def subtract(*args, **kwds): + def subtract(self, iterable=None, /, **kwds): '''Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts. @@ -673,13 +654,6 @@ def subtract(*args, **kwds): -1 ''' - if not args: - raise TypeError("descriptor 'subtract' of 'Counter' object " - "needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - iterable = args[0] if args else None if iterable is not None: self_get = self.get if isinstance(iterable, _collections_abc.Mapping): @@ -1141,7 +1115,7 @@ def copy(self): return self.__class__(self) def count(self, item): return self.data.count(item) def index(self, item, *args): return self.data.index(item, *args) def reverse(self): self.data.reverse() - def sort(self, *args, **kwds): self.data.sort(*args, **kwds) + def sort(self, /, *args, **kwds): self.data.sort(*args, **kwds) def extend(self, other): if isinstance(other, UserList): self.data.extend(other.data) @@ -1240,7 +1214,7 @@ def find(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.find(sub, start, end) - def format(self, *args, **kwds): + def format(self, /, *args, **kwds): return self.data.format(*args, **kwds) def format_map(self, mapping): return self.data.format_map(mapping) diff --git a/Lib/contextlib.py b/Lib/contextlib.py index de989a001c6dfb..94dc2bfed06cd8 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -377,8 +377,7 @@ def _create_exit_wrapper(cm, cm_exit): return MethodType(cm_exit, cm) @staticmethod - def _create_cb_wrapper(*args, **kwds): - callback, *args = args + def _create_cb_wrapper(callback, /, *args, **kwds): def _exit_wrapper(exc_type, exc, tb): callback(*args, **kwds) return _exit_wrapper @@ -553,8 +552,7 @@ def _create_async_exit_wrapper(cm, cm_exit): return MethodType(cm_exit, cm) @staticmethod - def _create_async_cb_wrapper(*args, **kwds): - callback, *args = args + def _create_async_cb_wrapper(callback, /, *args, **kwds): async def _exit_wrapper(exc_type, exc, tb): await callback(*args, **kwds) return _exit_wrapper diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 325b822d9f06f1..75113f123b3af1 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -962,10 +962,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen): return cls -# _cls should never be specified by keyword, so start it with an -# underscore. The presence of _cls is used to detect if this -# decorator is being called with parameters or not. -def dataclass(_cls=None, *, init=True, repr=True, eq=True, order=False, +def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False): """Returns the same class as was passed in, with dunder methods added based on the fields defined in the class. @@ -983,12 +980,12 @@ def wrap(cls): return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen) # See if we're being called as @dataclass or @dataclass(). - if _cls is None: + if cls is None: # We're called with parens. return wrap # We're called as @dataclass without parens. - return wrap(_cls) + return wrap(cls) def fields(class_or_instance): diff --git a/Lib/functools.py b/Lib/functools.py index 30964a6fe3d83a..64d120182bb07a 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -273,15 +273,9 @@ class partial: __slots__ = "func", "args", "keywords", "__dict__", "__weakref__" - def __new__(*args, **keywords): - if not args: - raise TypeError("descriptor '__new__' of partial needs an argument") - if len(args) < 2: - raise TypeError("type 'partial' takes at least one argument") - cls, func, *args = args + def __new__(cls, func, /, *args, **keywords): if not callable(func): raise TypeError("the first argument must be callable") - args = tuple(args) if hasattr(func, "func"): args = func.args + args @@ -295,10 +289,7 @@ def __new__(*args, **keywords): self.keywords = keywords return self - def __call__(*args, **keywords): - if not args: - raise TypeError("descriptor '__call__' of partial needs an argument") - self, *args = args + def __call__(self, /, *args, **keywords): keywords = {**self.keywords, **keywords} return self.func(*self.args, *args, **keywords) @@ -402,8 +393,7 @@ def __repr__(self): keywords=keywords) def _make_unbound_method(self): - def _method(*args, **keywords): - cls_or_self, *args = args + def _method(cls_or_self, /, *args, **keywords): keywords = {**self.keywords, **keywords} return self.func(cls_or_self, *self.args, *args, **keywords) _method.__isabstractmethod__ = self.__isabstractmethod__ diff --git a/Lib/idlelib/debugger_r.py b/Lib/idlelib/debugger_r.py index 0e6dcfbd12c2ab..9dcfc56414c050 100644 --- a/Lib/idlelib/debugger_r.py +++ b/Lib/idlelib/debugger_r.py @@ -299,7 +299,7 @@ def __init__(self, conn, shell, oid): self.conn = conn self.shell = shell - def call(self, methodname, *args, **kwargs): + def call(self, methodname, /, *args, **kwargs): ##print("*** IdbProxy.call %s %s %s" % (methodname, args, kwargs)) value = self.conn.remotecall(self.oid, methodname, args, kwargs) ##print("*** IdbProxy.call %s returns %r" % (methodname, value)) diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index f035bde4a0a0e2..aa8cbd36c47926 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -603,7 +603,7 @@ def __init__(self, sockio, oid, name): self.oid = oid self.name = name - def __call__(self, *args, **kwargs): + def __call__(self, /, *args, **kwargs): value = self.sockio.remotecall(self.oid, self.name, args, kwargs) return value diff --git a/Lib/inspect.py b/Lib/inspect.py index a4f28f75570503..ca81a24f06415d 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1329,14 +1329,12 @@ def _too_many(f_name, args, kwonly, varargs, defcount, given, values): (f_name, sig, "s" if plural else "", given, kwonly_sig, "was" if given == 1 and not kwonly_given else "were")) -def getcallargs(*func_and_positional, **named): +def getcallargs(func, /, *positional, **named): """Get the mapping of arguments to values. A dict is returned, with keys the function argument names (including the names of the * and ** arguments, if any), and values the respective bound values from 'positional' and 'named'.""" - func = func_and_positional[0] - positional = func_and_positional[1:] spec = getfullargspec(func) args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec f_name = func.__name__ @@ -3027,19 +3025,19 @@ def _bind(self, args, kwargs, *, partial=False): return self._bound_arguments_cls(self, arguments) - def bind(*args, **kwargs): + def bind(self, /, *args, **kwargs): """Get a BoundArguments object, that maps the passed `args` and `kwargs` to the function's signature. Raises `TypeError` if the passed arguments can not be bound. """ - return args[0]._bind(args[1:], kwargs) + return self._bind(args, kwargs) - def bind_partial(*args, **kwargs): + def bind_partial(self, /, *args, **kwargs): """Get a BoundArguments object, that partially maps the passed `args` and `kwargs` to the function's signature. Raises `TypeError` if the passed arguments can not be bound. """ - return args[0]._bind(args[1:], kwargs, partial=True) + return self._bind(args, kwargs, partial=True) def __reduce__(self): return (type(self), diff --git a/Lib/multiprocessing/dummy/__init__.py b/Lib/multiprocessing/dummy/__init__.py index 403f5e5198e4ed..6a1468609e347b 100644 --- a/Lib/multiprocessing/dummy/__init__.py +++ b/Lib/multiprocessing/dummy/__init__.py @@ -80,7 +80,7 @@ def freeze_support(): # class Namespace(object): - def __init__(self, **kwds): + def __init__(self, /, **kwds): self.__dict__.update(kwds) def __repr__(self): items = list(self.__dict__.items()) diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 514152298b097c..7e1818bb099685 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -615,13 +615,10 @@ def _run_server(cls, registry, address, authkey, serializer, writer, util.info('manager serving at %r', server.address) server.serve_forever() - def _create(*args, **kwds): + def _create(self, typeid, /, *args, **kwds): ''' Create a new shared object; return the token and exposed tuple ''' - self, typeid, *args = args - args = tuple(args) - assert self._state.value == State.STARTED, 'server not yet started' conn = self._Client(self._address, authkey=self._authkey) try: @@ -738,7 +735,7 @@ def register(cls, typeid, callable=None, proxytype=None, exposed=None, ) if create_method: - def temp(self, *args, **kwds): + def temp(self, /, *args, **kwds): util.debug('requesting creation of a shared %r object', typeid) token, exp = self._create(typeid, *args, **kwds) proxy = proxytype( @@ -978,7 +975,7 @@ def MakeProxyType(name, exposed, _cache={}): dic = {} for meth in exposed: - exec('''def %s(self, *args, **kwds): + exec('''def %s(self, /, *args, **kwds): return self._callmethod(%r, args, kwds)''' % (meth, meth), dic) ProxyType = type(name, (BaseProxy,), dic) @@ -1017,7 +1014,7 @@ def AutoProxy(token, serializer, manager=None, authkey=None, # class Namespace(object): - def __init__(self, **kwds): + def __init__(self, /, **kwds): self.__dict__.update(kwds) def __repr__(self): items = list(self.__dict__.items()) diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 665ca067fa0763..b223d6aa724bb6 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -154,7 +154,7 @@ class _PoolCache(dict): notification is done by the use of a queue that is provided when instantiating the cache. """ - def __init__(self, *args, notifier=None, **kwds): + def __init__(self, /, *args, notifier=None, **kwds): self.notifier = notifier super().__init__(*args, **kwds) diff --git a/Lib/operator.py b/Lib/operator.py index 0e2e53efc69a77..fb58851fa6ef67 100644 --- a/Lib/operator.py +++ b/Lib/operator.py @@ -302,15 +302,11 @@ class methodcaller: """ __slots__ = ('_name', '_args', '_kwargs') - def __init__(*args, **kwargs): - if len(args) < 2: - msg = "methodcaller needs at least one argument, the method name" - raise TypeError(msg) - self = args[0] - self._name = args[1] + def __init__(self, name, /, *args, **kwargs): + self._name = name if not isinstance(self._name, str): raise TypeError('method name must be a string') - self._args = args[2:] + self._args = args self._kwargs = kwargs def __call__(self, obj): diff --git a/Lib/random.py b/Lib/random.py index 53981f3e4f89bd..365a01957203f2 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -100,7 +100,7 @@ def __init__(self, x=None): self.seed(x) self.gauss_next = None - def __init_subclass__(cls, **kwargs): + def __init_subclass__(cls, /, **kwargs): """Control how subclasses generate random integers. The algorithm a subclass can use depends on the random() and/or diff --git a/Lib/string.py b/Lib/string.py index b9d6f5eb5675f6..b423ff5dc6f69f 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -52,6 +52,8 @@ def capwords(s, sep=None): import re as _re from collections import ChainMap as _ChainMap +_sentinel_dict = {} + class _TemplateMetaclass(type): pattern = r""" %(delim)s(?: @@ -104,19 +106,11 @@ def _invalid(self, mo): raise ValueError('Invalid placeholder in string: line %d, col %d' % (lineno, colno)) - def substitute(*args, **kws): - if not args: - raise TypeError("descriptor 'substitute' of 'Template' object " - "needs an argument") - self, *args = args # allow the "self" keyword be passed - if len(args) > 1: - raise TypeError('Too many positional arguments') - if not args: + def substitute(self, mapping=_sentinel_dict, /, **kws): + if mapping is _sentinel_dict: mapping = kws elif kws: - mapping = _ChainMap(kws, args[0]) - else: - mapping = args[0] + mapping = _ChainMap(kws, mapping) # Helper function for .sub() def convert(mo): # Check the most common path first. @@ -131,19 +125,11 @@ def convert(mo): self.pattern) return self.pattern.sub(convert, self.template) - def safe_substitute(*args, **kws): - if not args: - raise TypeError("descriptor 'safe_substitute' of 'Template' object " - "needs an argument") - self, *args = args # allow the "self" keyword be passed - if len(args) > 1: - raise TypeError('Too many positional arguments') - if not args: + def safe_substitute(self, mapping=_sentinel_dict, /, **kws): + if mapping is _sentinel_dict: mapping = kws elif kws: - mapping = _ChainMap(kws, args[0]) - else: - mapping = args[0] + mapping = _ChainMap(kws, mapping) # Helper function for .sub() def convert(mo): named = mo.group('named') or mo.group('braced') @@ -173,16 +159,7 @@ def convert(mo): # The field name parser is implemented in _string.formatter_field_name_split class Formatter: - def format(*args, **kwargs): - if not args: - raise TypeError("descriptor 'format' of 'Formatter' object " - "needs an argument") - self, *args = args # allow the "self" keyword be passed - try: - format_string, *args = args # allow the "format_string" keyword be passed - except ValueError: - raise TypeError("format() missing 1 required positional " - "argument: 'format_string'") from None + def format(self, format_string, /, *args, **kwargs): return self.vformat(format_string, args, kwargs) def vformat(self, format_string, args, kwargs): diff --git a/Lib/test/support/script_helper.py b/Lib/test/support/script_helper.py index 27a47f2c4e668c..83519988e39478 100644 --- a/Lib/test/support/script_helper.py +++ b/Lib/test/support/script_helper.py @@ -137,7 +137,7 @@ def run_python_until_end(*args, **env_vars): err = strip_python_stderr(err) return _PythonRunResult(rc, out, err), cmd_line -def _assert_python(expected_success, *args, **env_vars): +def _assert_python(expected_success, /, *args, **env_vars): res, cmd_line = run_python_until_end(*args, **env_vars) if (res.rc and expected_success) or (not res.rc and not expected_success): res.fail(cmd_line) diff --git a/Lib/typing.py b/Lib/typing.py index 16ccfad049f42d..5f1a0ad3d63743 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -283,7 +283,7 @@ class _Final: __slots__ = ('__weakref__',) - def __init_subclass__(self, *args, **kwds): + def __init_subclass__(self, /, *args, **kwds): if '_root' not in kwds: raise TypeError("Cannot subclass special typing classes") diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 7b1e86941315e8..b363c635100726 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -86,23 +86,10 @@ def _id(obj): _module_cleanups = [] -def addModuleCleanup(*args, **kwargs): +def addModuleCleanup(function, /, *args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpModule fails (unlike tearDownModule).""" - if args: - function, *args = args - elif 'function' in kwargs: - function = kwargs.pop('function') - import warnings - warnings.warn("Passing 'function' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('addModuleCleanup expected at least 1 positional ' - 'argument, got %d' % (len(args)-1)) - args = tuple(args) - _module_cleanups.append((function, args, kwargs)) -addModuleCleanup.__text_signature__ = '(function, /, *args, **kwargs)' def doModuleCleanups(): @@ -501,22 +488,11 @@ def addCleanup(*args, **kwargs): self._cleanups.append((function, args, kwargs)) addCleanup.__text_signature__ = '($self, function, /, *args, **kwargs)' - def addClassCleanup(*args, **kwargs): + @classmethod + def addClassCleanup(cls, function, /, *args, **kwargs): """Same as addCleanup, except the cleanup items are called even if setUpClass fails (unlike tearDownClass).""" - if len(args) >= 2: - cls, function, *args = args - elif not args: - raise TypeError("descriptor 'addClassCleanup' of 'TestCase' object " - "needs an argument") - else: - raise TypeError('addClassCleanup expected at least 1 positional ' - 'argument, got %d' % (len(args)-1)) - args = tuple(args) - cls._class_cleanups.append((function, args, kwargs)) - addClassCleanup.__text_signature__ = '($cls, function, /, *args, **kwargs)' - addClassCleanup = classmethod(addClassCleanup) def setUp(self): "Hook method for setting up the test fixture before exercising it." diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index be96194793ef28..c2802726d75d9c 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -106,7 +106,7 @@ def _check_signature(func, mock, skipfirst, instance=False): if sig is None: return func, sig = sig - def checksig(_mock_self, *args, **kwargs): + def checksig(self, /, *args, **kwargs): sig.bind(*args, **kwargs) _copy_func_details(func, checksig) type(mock)._mock_check_sig = checksig @@ -243,7 +243,7 @@ def _setup_async_mock(mock): # Mock is not configured yet so the attributes are set # to a function and then the corresponding mock helper function # is called when the helper is accessed similar to _setup_func. - def wrapper(attr, *args, **kwargs): + def wrapper(attr, /, *args, **kwargs): return getattr(mock.mock, attr)(*args, **kwargs) for attribute in ('assert_awaited', @@ -387,7 +387,7 @@ def __next__(self): class Base(object): _mock_return_value = DEFAULT _mock_side_effect = None - def __init__(self, *args, **kwargs): + def __init__(self, /, *args, **kwargs): pass @@ -395,7 +395,7 @@ def __init__(self, *args, **kwargs): class NonCallableMock(Base): """A non-callable version of `Mock`""" - def __new__(cls, *args, **kw): + def __new__(cls, /, *args, **kw): # every instance has its own class # so we can create magic methods on the # class without stomping on other mocks @@ -602,7 +602,7 @@ def reset_mock(self, visited=None,*, return_value=False, side_effect=False): ret.reset_mock(visited) - def configure_mock(self, **kwargs): + def configure_mock(self, /, **kwargs): """Set attributes on the mock through keyword arguments. Attributes plus return values and side effects can be set on child @@ -820,10 +820,9 @@ def _call_matcher(self, _call): else: return _call - def assert_not_called(_mock_self): + def assert_not_called(self): """assert that the mock was never called. """ - self = _mock_self if self.call_count != 0: msg = ("Expected '%s' to not have been called. Called %s times.%s" % (self._mock_name or 'mock', @@ -831,19 +830,17 @@ def assert_not_called(_mock_self): self._calls_repr())) raise AssertionError(msg) - def assert_called(_mock_self): + def assert_called(self): """assert that the mock was called at least once """ - self = _mock_self if self.call_count == 0: msg = ("Expected '%s' to have been called." % self._mock_name or 'mock') raise AssertionError(msg) - def assert_called_once(_mock_self): + def assert_called_once(self): """assert that the mock was called only once. """ - self = _mock_self if not self.call_count == 1: msg = ("Expected '%s' to have been called once. Called %s times.%s" % (self._mock_name or 'mock', @@ -851,12 +848,11 @@ def assert_called_once(_mock_self): self._calls_repr())) raise AssertionError(msg) - def assert_called_with(_mock_self, *args, **kwargs): + def assert_called_with(self, /, *args, **kwargs): """assert that the mock was called with the specified arguments. Raises an AssertionError if the args and keyword args passed in are different to the last call to the mock.""" - self = _mock_self if self.call_args is None: expected = self._format_mock_call_signature(args, kwargs) actual = 'not called.' @@ -874,10 +870,9 @@ def _error_message(): raise AssertionError(_error_message()) from cause - def assert_called_once_with(_mock_self, *args, **kwargs): + def assert_called_once_with(self, /, *args, **kwargs): """assert that the mock was called exactly once and that that call was with the specified arguments.""" - self = _mock_self if not self.call_count == 1: msg = ("Expected '%s' to be called once. Called %s times.%s" % (self._mock_name or 'mock', @@ -924,7 +919,7 @@ def assert_has_calls(self, calls, any_order=False): ) from cause - def assert_any_call(self, *args, **kwargs): + def assert_any_call(self, /, *args, **kwargs): """assert the mock has been called with the specified arguments. The assert passes if the mock has *ever* been called, unlike @@ -940,7 +935,7 @@ def assert_any_call(self, *args, **kwargs): ) from cause - def _get_child_mock(self, **kw): + def _get_child_mock(self, /, **kw): """Create the child mocks for attributes and return value. By default child mocks will be the same type as the parent. Subclasses of Mock may want to override this to customize the way @@ -1016,20 +1011,19 @@ def __init__(self, spec=None, side_effect=None, return_value=DEFAULT, self.side_effect = side_effect - def _mock_check_sig(self, *args, **kwargs): + def _mock_check_sig(self, /, *args, **kwargs): # stub method that can be replaced with one with a specific signature pass - def __call__(_mock_self, *args, **kwargs): + def __call__(self, /, *args, **kwargs): # can't use self in-case a function / method we are mocking uses self # in the signature - _mock_self._mock_check_sig(*args, **kwargs) - return _mock_self._mock_call(*args, **kwargs) + self._mock_check_sig(*args, **kwargs) + return self._mock_call(*args, **kwargs) - def _mock_call(_mock_self, *args, **kwargs): - self = _mock_self + def _mock_call(self, /, *args, **kwargs): self.called = True self.call_count += 1 @@ -1840,7 +1834,7 @@ def _patch_stopall(): def _get_method(name, func): "Turns a callable object (like a mock) into a real function" - def method(self, *args, **kw): + def method(self, /, *args, **kw): return func(self, *args, **kw) method.__name__ = name return method @@ -1954,7 +1948,7 @@ def _set_return_value(mock, method, name): class MagicMixin(object): - def __init__(self, *args, **kw): + def __init__(self, /, *args, **kw): self._mock_set_magics() # make magic work for kwargs in init _safe_super(MagicMixin, self).__init__(*args, **kw) self._mock_set_magics() # fix magic broken by upper level init @@ -1996,7 +1990,7 @@ def mock_add_spec(self, spec, spec_set=False): class AsyncMagicMixin: - def __init__(self, *args, **kw): + def __init__(self, /, *args, **kw): self._mock_set_async_magics() # make magic work for kwargs in init _safe_super(AsyncMagicMixin, self).__init__(*args, **kw) self._mock_set_async_magics() # fix magic broken by upper level init @@ -2067,7 +2061,7 @@ class AsyncMockMixin(Base): await_args = _delegating_property('await_args') await_args_list = _delegating_property('await_args_list') - def __init__(self, *args, **kwargs): + def __init__(self, /, *args, **kwargs): super().__init__(*args, **kwargs) # asyncio.iscoroutinefunction() checks _is_coroutine property to say if an # object is a coroutine. Without this check it looks to see if it is a @@ -2084,8 +2078,7 @@ def __init__(self, *args, **kwargs): code_mock.co_flags = inspect.CO_COROUTINE self.__dict__['__code__'] = code_mock - async def _mock_call(_mock_self, *args, **kwargs): - self = _mock_self + async def _mock_call(self, /, *args, **kwargs): try: result = super()._mock_call(*args, **kwargs) except (BaseException, StopIteration) as e: @@ -2110,30 +2103,27 @@ async def proxy(): return await proxy() - def assert_awaited(_mock_self): + def assert_awaited(self): """ Assert that the mock was awaited at least once. """ - self = _mock_self if self.await_count == 0: msg = f"Expected {self._mock_name or 'mock'} to have been awaited." raise AssertionError(msg) - def assert_awaited_once(_mock_self): + def assert_awaited_once(self): """ Assert that the mock was awaited exactly once. """ - self = _mock_self if not self.await_count == 1: msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once." f" Awaited {self.await_count} times.") raise AssertionError(msg) - def assert_awaited_with(_mock_self, *args, **kwargs): + def assert_awaited_with(self, /, *args, **kwargs): """ Assert that the last await was with the specified arguments. """ - self = _mock_self if self.await_args is None: expected = self._format_mock_call_signature(args, kwargs) raise AssertionError(f'Expected await: {expected}\nNot awaited') @@ -2148,23 +2138,21 @@ def _error_message(): cause = expected if isinstance(expected, Exception) else None raise AssertionError(_error_message()) from cause - def assert_awaited_once_with(_mock_self, *args, **kwargs): + def assert_awaited_once_with(self, /, *args, **kwargs): """ Assert that the mock was awaited exactly once and with the specified arguments. """ - self = _mock_self if not self.await_count == 1: msg = (f"Expected {self._mock_name or 'mock'} to have been awaited once." f" Awaited {self.await_count} times.") raise AssertionError(msg) return self.assert_awaited_with(*args, **kwargs) - def assert_any_await(_mock_self, *args, **kwargs): + def assert_any_await(self, /, *args, **kwargs): """ Assert the mock has ever been awaited with the specified arguments. """ - self = _mock_self expected = self._call_matcher((args, kwargs)) actual = [self._call_matcher(c) for c in self.await_args_list] if expected not in actual: @@ -2174,7 +2162,7 @@ def assert_any_await(_mock_self, *args, **kwargs): '%s await not found' % expected_string ) from cause - def assert_has_awaits(_mock_self, calls, any_order=False): + def assert_has_awaits(self, calls, any_order=False): """ Assert the mock has been awaited with the specified calls. The :attr:`await_args_list` list is checked for the awaits. @@ -2186,7 +2174,6 @@ def assert_has_awaits(_mock_self, calls, any_order=False): If `any_order` is True then the awaits can be in any order, but they must all appear in :attr:`await_args_list`. """ - self = _mock_self expected = [self._call_matcher(c) for c in calls] cause = expected if isinstance(expected, Exception) else None all_awaits = _CallList(self._call_matcher(c) for c in self.await_args_list) @@ -2211,17 +2198,16 @@ def assert_has_awaits(_mock_self, calls, any_order=False): '%r not all found in await list' % (tuple(not_found),) ) from cause - def assert_not_awaited(_mock_self): + def assert_not_awaited(self): """ Assert that the mock was never awaited. """ - self = _mock_self if self.await_count != 0: msg = (f"Expected {self._mock_name or 'mock'} to not have been awaited." f" Awaited {self.await_count} times.") raise AssertionError(msg) - def reset_mock(self, *args, **kwargs): + def reset_mock(self, /, *args, **kwargs): """ See :func:`.Mock.reset_mock()` """ @@ -2424,7 +2410,7 @@ def __eq__(self, other): __ne__ = object.__ne__ - def __call__(self, *args, **kwargs): + def __call__(self, /, *args, **kwargs): if self._mock_name is None: return _Call(('', args, kwargs), name='()') @@ -2439,10 +2425,10 @@ def __getattr__(self, attr): return _Call(name=name, parent=self, from_kall=False) - def count(self, *args, **kwargs): + def count(self, /, *args, **kwargs): return self.__getattr__('count')(*args, **kwargs) - def index(self, *args, **kwargs): + def index(self, /, *args, **kwargs): return self.__getattr__('index')(*args, **kwargs) def _get_call_arguments(self): @@ -2778,7 +2764,7 @@ class PropertyMock(Mock): Fetching a `PropertyMock` instance from an object calls the mock, with no args. Setting it calls the mock with the value being set. """ - def _get_child_mock(self, **kwargs): + def _get_child_mock(self, /, **kwargs): return MagicMock(**kwargs) def __get__(self, obj, obj_type): diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py index 443b689dbea04f..7d36340741f463 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/unittest/test/test_runner.py @@ -410,14 +410,13 @@ def cleanup(*args, **kwargs): class Module(object): unittest.addModuleCleanup(cleanup, 1, 2, function='hello') - with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): unittest.addModuleCleanup(function=cleanup, arg='hello') with self.assertRaises(TypeError): unittest.addModuleCleanup() unittest.case.doModuleCleanups() self.assertEqual(cleanups, - [((), {'arg': 'hello'}), - ((1, 2), {'function': 'hello'})]) + [((1, 2), {'function': 'hello'})]) def test_run_module_cleanUp(self): blowUp = True diff --git a/Lib/weakref.py b/Lib/weakref.py index 1eeb7b0a0b4446..8d71af653b7ec4 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -99,13 +99,7 @@ class WeakValueDictionary(_collections_abc.MutableMapping): # objects are unwrapped on the way out, and we always wrap on the # way in). - def __init__(*args, **kw): - if not args: - raise TypeError("descriptor '__init__' of 'WeakValueDictionary' " - "object needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) + def __init__(self, other=(), /, **kw): def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref): self = selfref() if self is not None: @@ -120,7 +114,7 @@ def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref): self._pending_removals = [] self._iterating = set() self.data = d = {} - self.update(*args, **kw) + self.update(other, **kw) def _commit_removals(self): l = self._pending_removals @@ -287,24 +281,17 @@ def setdefault(self, key, default=None): else: return o - def update(*args, **kwargs): - if not args: - raise TypeError("descriptor 'update' of 'WeakValueDictionary' " - "object needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - dict = args[0] if args else None + def update(self, other=None, /, **kwargs): if self._pending_removals: self._commit_removals() d = self.data - if dict is not None: - if not hasattr(dict, "items"): - dict = type({})(dict) - for key, o in dict.items(): + if other is not None: + if not hasattr(other, "items"): + other = dict(other) + for key, o in other.items(): d[key] = KeyedRef(o, self._remove, key) - if len(kwargs): - self.update(kwargs) + for key, o in kwargs.items(): + d[key] = KeyedRef(o, self._remove, key) def valuerefs(self): """Return a list of weak references to the values. @@ -488,7 +475,7 @@ def pop(self, key, *args): def setdefault(self, key, default=None): return self.data.setdefault(ref(key, self._remove),default) - def update(self, dict=None, **kwargs): + def update(self, dict=None, /, **kwargs): d = self.data if dict is not None: if not hasattr(dict, "items"): From 70c5f2ae6e6a07d44a8d3f3202ea01bf697e05db Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 1 Jun 2019 11:38:24 +0300 Subject: [PATCH 238/441] Use more PEP 570 syntax in the documentation. (GH-13720) --- Doc/faq/programming.rst | 4 ++-- Doc/howto/logging-cookbook.rst | 30 +++++++++++++++--------------- Doc/library/functools.rst | 2 +- Doc/reference/datamodel.rst | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 9660a701427fd6..a00c6a053ef120 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -554,8 +554,8 @@ desired effect in a number of ways. 5) Or bundle up values in a class instance:: class callByRef: - def __init__(self, **args): - for (key, value) in args.items(): + def __init__(self, /, **args): + for key, value in args.items(): setattr(self, key, value) def func4(args): diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 4956aa0dd957bc..71f9fc920fdfc9 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -579,7 +579,7 @@ information. When you call one of the logging methods on an instance of information in the delegated call. Here's a snippet from the code of :class:`LoggerAdapter`:: - def debug(self, msg, *args, **kwargs): + def debug(self, msg, /, *args, **kwargs): """ Delegate a debug call to the underlying logger, after adding contextual information from this adapter instance. @@ -1079,7 +1079,7 @@ call ``str()`` on that object to get the actual format string. Consider the following two classes:: class BraceMessage: - def __init__(self, fmt, *args, **kwargs): + def __init__(self, fmt, /, *args, **kwargs): self.fmt = fmt self.args = args self.kwargs = kwargs @@ -1088,7 +1088,7 @@ following two classes:: return self.fmt.format(*self.args, **self.kwargs) class DollarMessage: - def __init__(self, fmt, **kwargs): + def __init__(self, fmt, /, **kwargs): self.fmt = fmt self.kwargs = kwargs @@ -1143,7 +1143,7 @@ to the above, as in the following example:: import logging - class Message(object): + class Message: def __init__(self, fmt, args): self.fmt = fmt self.args = args @@ -1155,7 +1155,7 @@ to the above, as in the following example:: def __init__(self, logger, extra=None): super(StyleAdapter, self).__init__(logger, extra or {}) - def log(self, level, msg, *args, **kwargs): + def log(self, level, msg, /, *args, **kwargs): if self.isEnabledFor(level): msg, kwargs = self.process(msg, kwargs) self.logger._log(level, Message(msg, args), (), **kwargs) @@ -1301,7 +1301,7 @@ You can also subclass :class:`QueueListener` to get messages from other kinds of queues, for example a ZeroMQ 'subscribe' socket. Here's an example:: class ZeroMQSocketListener(QueueListener): - def __init__(self, uri, *handlers, **kwargs): + def __init__(self, uri, /, *handlers, **kwargs): self.ctx = kwargs.get('ctx') or zmq.Context() socket = zmq.Socket(self.ctx, zmq.SUB) socket.setsockopt_string(zmq.SUBSCRIBE, '') # subscribe to everything @@ -1706,8 +1706,8 @@ which uses JSON to serialise the event in a machine-parseable manner:: import json import logging - class StructuredMessage(object): - def __init__(self, message, **kwargs): + class StructuredMessage: + def __init__(self, message, /, **kwargs): self.message = message self.kwargs = kwargs @@ -1750,8 +1750,8 @@ as in the following complete example:: return o.encode('unicode_escape').decode('ascii') return super(Encoder, self).default(o) - class StructuredMessage(object): - def __init__(self, message, **kwargs): + class StructuredMessage: + def __init__(self, message, /, **kwargs): self.message = message self.kwargs = kwargs @@ -1982,8 +1982,8 @@ object as a message format string, and that the logging package will call :func:`str` on that object to get the actual format string. Consider the following two classes:: - class BraceMessage(object): - def __init__(self, fmt, *args, **kwargs): + class BraceMessage: + def __init__(self, fmt, /, *args, **kwargs): self.fmt = fmt self.args = args self.kwargs = kwargs @@ -1991,8 +1991,8 @@ following two classes:: def __str__(self): return self.fmt.format(*self.args, **self.kwargs) - class DollarMessage(object): - def __init__(self, fmt, **kwargs): + class DollarMessage: + def __init__(self, fmt, /, **kwargs): self.fmt = fmt self.kwargs = kwargs @@ -2457,7 +2457,7 @@ scope of the context manager:: import logging import sys - class LoggingContext(object): + class LoggingContext: def __init__(self, logger, level=None, handler=None, close=True): self.logger = logger self.level = level diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 654a3efa214b05..3a0b554e923c7a 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -252,7 +252,7 @@ The :mod:`functools` module defines the following functions: 18 -.. class:: partialmethod(func, *args, **keywords) +.. class:: partialmethod(func, /, *args, **keywords) Return a new :class:`partialmethod` descriptor which behaves like :class:`partial` except that it is designed to be used as a method diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 8b4d889535fbe1..c566dfdf856dee 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1809,7 +1809,7 @@ class defining the method. class, as in:: class Philosopher: - def __init_subclass__(cls, default_name, **kwargs): + def __init_subclass__(cls, /, default_name, **kwargs): super().__init_subclass__(**kwargs) cls.default_name = default_name From 6b282e18877ec84e927b381b4ce187eaf4ba3dd7 Mon Sep 17 00:00:00 2001 From: Bar Harel Date: Sat, 1 Jun 2019 12:19:09 +0300 Subject: [PATCH 239/441] bpo-36813: Fix QueueListener to call task_done() upon termination. (GH-13113) Fixed QueueListener in order to avoid random deadlocks. Unable to add regression tests atm due to time constraints, will add it in a bit. Regarding implementation, although it's nested, it does not cause performance issues whatsoever, and does not call task_done() in case of an exception (which is the right thing to do IMHO). https://bugs.python.org/issue36813 --- Lib/logging/handlers.py | 2 ++ Lib/test/test_logging.py | 10 ++++++++++ .../Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst | 2 ++ 3 files changed, 14 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 3727bf0677cdce..a913d27389ab59 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1477,6 +1477,8 @@ def _monitor(self): try: record = self.dequeue(True) if record is self._sentinel: + if has_task_done: + q.task_done() break self.handle(record) if has_task_done: diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index b884753ad39785..50148dc2f252df 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -3633,6 +3633,16 @@ def test_no_messages_in_queue_after_stop(self): [m.msg if isinstance(m, logging.LogRecord) else m for m in items])) + def test_calls_task_done_after_stop(self): + # Issue 36813: Make sure queue.join does not deadlock. + log_queue = queue.Queue() + listener = logging.handlers.QueueListener(log_queue) + listener.start() + listener.stop() + with self.assertRaises(ValueError): + # Make sure all tasks are done and .join won't block. + log_queue.task_done() + ZERO = datetime.timedelta(0) diff --git a/Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst b/Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst new file mode 100644 index 00000000000000..e89358aa40512d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst @@ -0,0 +1,2 @@ +Fix :class:`~logging.handlers.QueueListener` to call ``queue.task_done()`` +upon stopping. Patch by Bar Harel. From a0adffb90287900a9e2c809ce2c1bbe481ac7dd0 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 1 Jun 2019 12:21:53 +0100 Subject: [PATCH 240/441] Move whats-new entry for math.factorial to the math module section. (GH-13723) --- Doc/whatsnew/3.8.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index bc7c9ef37442d0..2d5291102d2a39 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -460,6 +460,9 @@ numbers. (Contributed by Pablo Galindo in :issue:`35606`) Added new function :func:`math.isqrt` for computing integer square roots. (Contributed by Mark Dickinson in :issue:`36887`.) +The function :func:`math.factorial` no longer accepts arguments that are not +int-like. (Contributed by Pablo Galindo in :issue:`33083`.) + mmap ---- @@ -1140,9 +1143,6 @@ Changes in the Python API success; an exception was raised on error under Unix. (Contributed by Berker Peksag in :issue:`2122`.) -* The function :func:`math.factorial` no longer accepts arguments that are not - int-like. (Contributed by Pablo Galindo in :issue:`33083`.) - * :mod:`xml.dom.minidom` and :mod:`xml.sax` modules no longer process external entities by default. (Contributed by Christian Heimes in :issue:`17239`.) From 66501058fef76a5d77e6879f6da3282f0a9eef1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Wirtel?= Date: Sat, 1 Jun 2019 13:41:33 +0200 Subject: [PATCH 241/441] Doc: Correct the creation year and the credits of the Logo Programming language (GH-13520) --- Doc/library/turtle.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 3d90d3cbd974f5..7f9f0c34386799 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -20,8 +20,8 @@ Introduction ============ Turtle graphics is a popular way for introducing programming to kids. It was -part of the original Logo programming language developed by Wally Feurzig and -Seymour Papert in 1966. +part of the original Logo programming language developed by Wally Feurzeig, +Seymour Papert and Cynthia Solomon in 1967. Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it the command ``turtle.forward(15)``, and it moves (on-screen!) 15 pixels in the From 059b9ea5ac98f432e41b05d1fa5aab4ffa22df4d Mon Sep 17 00:00:00 2001 From: Anthony Shaw Date: Sun, 2 Jun 2019 01:51:58 +1000 Subject: [PATCH 242/441] bpo-31968: Documentation -- add clarification on the globals dict for exec() (GH-13140) --- Doc/library/functions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 7170a7817205b7..425a985320fcfb 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -499,7 +499,8 @@ are always available. They are listed here in alphabetical order. :func:`exec` function. The return value is ``None``. In all cases, if the optional parts are omitted, the code is executed in the - current scope. If only *globals* is provided, it must be a dictionary, which + current scope. If only *globals* is provided, it must be a dictionary + (and not a subclass of dictionary), which will be used for both the global and the local variables. If *globals* and *locals* are given, they are used for the global and local variables, respectively. If provided, *locals* can be any mapping object. Remember From cd74e66a8c420be675fd2fbf3fe708ac02ee9f21 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 1 Jun 2019 18:08:04 +0100 Subject: [PATCH 243/441] bpo-37122: Make co->co_argcount represent the total number of positonal arguments in the code object (GH-13726) --- Doc/c-api/code.rst | 2 + Doc/reference/datamodel.rst | 36 ++++++++------- Doc/whatsnew/3.8.rst | 6 ++- Lib/inspect.py | 28 ++++------- Lib/pdb.py | 2 +- Lib/test/test_code.py | 2 +- Lib/test/test_dis.py | 2 +- Lib/test/test_positional_only_arg.py | 4 +- .../2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst | 5 ++ Objects/call.c | 8 ++-- Objects/codeobject.c | 11 ++--- Objects/typeobject.c | 2 +- Python/ceval.c | 46 ++++++------------- Python/compile.c | 8 ++-- 14 files changed, 74 insertions(+), 88 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 7aa91ee84d2e47..92baa4c7df5cc1 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -42,6 +42,8 @@ bound into a function. .. versionchanged:: 3.8 An extra parameter is required (*posonlyargcount*) to support :PEP:`570`. + The first parameter (*argcount*) now represents the total number of positional arguments, + including positional-only. .. audit-event:: code.__new__ "code filename name argcount kwonlyargcount nlocals stacksize flags" diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index c566dfdf856dee..44017d8a55df52 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -907,24 +907,26 @@ Internal types single: co_freevars (code object attribute) Special read-only attributes: :attr:`co_name` gives the function name; - :attr:`co_argcount` is the number of positional arguments (including arguments - with default values); :attr:`co_posonlyargcount` is the number of - positional-only arguments (including arguments with default values); - :attr:`co_kwonlyargcount` is the number of keyword-only arguments (including - arguments with default values); :attr:`co_nlocals` is the number of local - variables used by the function (including arguments); :attr:`co_varnames` is a - tuple containing the names of the local variables (starting with the argument - names); :attr:`co_cellvars` is a tuple containing the names of local variables + :attr:`co_argcount` is the total number of positional arguments + (including positional-only arguments and arguments with default values); + :attr:`co_posonlyargcount` is the number of positional-only arguments + (including arguments with default values); :attr:`co_kwonlyargcount` is + the number of keyword-only arguments (including arguments with default + values); :attr:`co_nlocals` is the number of local variables used by the + function (including arguments); :attr:`co_varnames` is a tuple containing + the names of the local variables (starting with the argument names); + :attr:`co_cellvars` is a tuple containing the names of local variables that are referenced by nested functions; :attr:`co_freevars` is a tuple - containing the names of free variables; :attr:`co_code` is a string representing - the sequence of bytecode instructions; :attr:`co_consts` is a tuple containing - the literals used by the bytecode; :attr:`co_names` is a tuple containing the - names used by the bytecode; :attr:`co_filename` is the filename from which the - code was compiled; :attr:`co_firstlineno` is the first line number of the - function; :attr:`co_lnotab` is a string encoding the mapping from bytecode - offsets to line numbers (for details see the source code of the interpreter); - :attr:`co_stacksize` is the required stack size (including local variables); - :attr:`co_flags` is an integer encoding a number of flags for the interpreter. + containing the names of free variables; :attr:`co_code` is a string + representing the sequence of bytecode instructions; :attr:`co_consts` is + a tuple containing the literals used by the bytecode; :attr:`co_names` is + a tuple containing the names used by the bytecode; :attr:`co_filename` is + the filename from which the code was compiled; :attr:`co_firstlineno` is + the first line number of the function; :attr:`co_lnotab` is a string + encoding the mapping from bytecode offsets to line numbers (for details + see the source code of the interpreter); :attr:`co_stacksize` is the + required stack size (including local variables); :attr:`co_flags` is an + integer encoding a number of flags for the interpreter. .. index:: object: generator diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 2d5291102d2a39..4c5a9bb0cdb909 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1177,8 +1177,10 @@ Changes in the Python API * :class:`types.CodeType` has a new parameter in the second position of the constructor (*posonlyargcount*) to support positional-only arguments defined - in :pep:`570`. A new ``replace()`` method of :class:`types.CodeType` can be - used to make the code future-proof. + in :pep:`570`. The first argument (*argcount*) now represents the total + number of positional arguments (including positional-only arguments). A new + ``replace()`` method of :class:`types.CodeType` can be used to make the code + future-proof. Changes in the C API diff --git a/Lib/inspect.py b/Lib/inspect.py index ca81a24f06415d..91d209dc64bc9f 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1037,15 +1037,11 @@ def getargs(co): names = co.co_varnames nargs = co.co_argcount - nposonlyargs = co.co_posonlyargcount nkwargs = co.co_kwonlyargcount - nposargs = nargs + nposonlyargs - posonlyargs = list(names[:nposonlyargs]) - args = list(names[nposonlyargs:nposonlyargs+nargs]) - kwonlyargs = list(names[nposargs:nposargs+nkwargs]) + args = list(names[:nargs]) + kwonlyargs = list(names[nargs:nargs+nkwargs]) step = 0 - nargs += nposonlyargs nargs += nkwargs varargs = None if co.co_flags & CO_VARARGS: @@ -1054,7 +1050,7 @@ def getargs(co): varkw = None if co.co_flags & CO_VARKEYWORDS: varkw = co.co_varnames[nargs] - return Arguments(posonlyargs + args + kwonlyargs, varargs, varkw) + return Arguments(args + kwonlyargs, varargs, varkw) ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') @@ -2136,11 +2132,9 @@ def _signature_from_function(cls, func, skip_bound_arg=True): pos_count = func_code.co_argcount arg_names = func_code.co_varnames posonly_count = func_code.co_posonlyargcount - positional_count = posonly_count + pos_count - positional_only = tuple(arg_names[:posonly_count]) - positional = tuple(arg_names[posonly_count:positional_count]) + positional = arg_names[:pos_count] keyword_only_count = func_code.co_kwonlyargcount - keyword_only = arg_names[positional_count:(positional_count + keyword_only_count)] + keyword_only = arg_names[pos_count:pos_count + keyword_only_count] annotations = func.__annotations__ defaults = func.__defaults__ kwdefaults = func.__kwdefaults__ @@ -2152,13 +2146,11 @@ def _signature_from_function(cls, func, skip_bound_arg=True): parameters = [] - non_default_count = positional_count - pos_default_count - all_positional = positional_only + positional - + non_default_count = pos_count - pos_default_count posonly_left = posonly_count # Non-keyword-only parameters w/o defaults. - for name in all_positional[:non_default_count]: + for name in positional[:non_default_count]: kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD annotation = annotations.get(name, _empty) parameters.append(Parameter(name, annotation=annotation, @@ -2167,7 +2159,7 @@ def _signature_from_function(cls, func, skip_bound_arg=True): posonly_left -= 1 # ... w/ defaults. - for offset, name in enumerate(all_positional[non_default_count:]): + for offset, name in enumerate(positional[non_default_count:]): kind = _POSITIONAL_ONLY if posonly_left else _POSITIONAL_OR_KEYWORD annotation = annotations.get(name, _empty) parameters.append(Parameter(name, annotation=annotation, @@ -2178,7 +2170,7 @@ def _signature_from_function(cls, func, skip_bound_arg=True): # *args if func_code.co_flags & CO_VARARGS: - name = arg_names[positional_count + keyword_only_count] + name = arg_names[pos_count + keyword_only_count] annotation = annotations.get(name, _empty) parameters.append(Parameter(name, annotation=annotation, kind=_VAR_POSITIONAL)) @@ -2195,7 +2187,7 @@ def _signature_from_function(cls, func, skip_bound_arg=True): default=default)) # **kwargs if func_code.co_flags & CO_VARKEYWORDS: - index = positional_count + keyword_only_count + index = pos_count + keyword_only_count if func_code.co_flags & CO_VARARGS: index += 1 diff --git a/Lib/pdb.py b/Lib/pdb.py index 13068ce27bd166..0e7609e43d4eea 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1132,7 +1132,7 @@ def do_args(self, arg): """ co = self.curframe.f_code dict = self.curframe_locals - n = co.co_argcount + co.co_posonlyargcount + co.co_kwonlyargcount + n = co.co_argcount + co.co_kwonlyargcount if co.co_flags & inspect.CO_VARARGS: n = n+1 if co.co_flags & inspect.CO_VARKEYWORDS: n = n+1 for i in range(n): diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 91008c04f7fd2e..0d80af44d9f1ff 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -112,7 +112,7 @@ >>> dump(posonly_args.__code__) name: posonly_args -argcount: 1 +argcount: 3 posonlyargcount: 2 kwonlyargcount: 0 names: () diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 1561021f5bc732..652af45d55ade9 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -640,7 +640,7 @@ def f(c=c): code_info_tricky = """\ Name: tricky Filename: (.*) -Argument count: 3 +Argument count: 5 Positional-only arguments: 2 Kw-only arguments: 3 Number of locals: 10 diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index 0aaad84cb3bfcd..59b0b8fb55621c 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -100,14 +100,14 @@ def test_pos_only_definition(self): def f(a, b, c, /, d, e=1, *, f, g=2): pass - self.assertEqual(2, f.__code__.co_argcount) # 2 "standard args" + self.assertEqual(5, f.__code__.co_argcount) # 3 posonly + 2 "standard args" self.assertEqual(3, f.__code__.co_posonlyargcount) self.assertEqual((1,), f.__defaults__) def f(a, b, c=1, /, d=2, e=3, *, f, g=4): pass - self.assertEqual(2, f.__code__.co_argcount) # 2 "standard args" + self.assertEqual(5, f.__code__.co_argcount) # 3 posonly + 2 "standard args" self.assertEqual(3, f.__code__.co_posonlyargcount) self.assertEqual((1, 2, 3), f.__defaults__) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst new file mode 100644 index 00000000000000..b9584b50e61d95 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst @@ -0,0 +1,5 @@ +Make the *co_argcount* attribute of code objects represent the total number +of positional arguments (including positional-only arguments). The value of +*co_posonlyargcount* can be used to distinguish which arguments are +positional only, and the difference (*co_argcount* - *co_posonlyargcount*) +is the number of positional-or-keyword arguments. Patch by Pablo Galindo. diff --git a/Objects/call.c b/Objects/call.c index acd1f26dcbb576..c0d14567e43037 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -308,11 +308,11 @@ _PyFunction_FastCallDict(PyObject *func, PyObject *const *args, Py_ssize_t nargs (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { /* Fast paths */ - if (argdefs == NULL && co->co_argcount + co->co_posonlyargcount == nargs) { + if (argdefs == NULL && co->co_argcount == nargs) { return function_code_fastcall(co, args, nargs, globals); } else if (nargs == 0 && argdefs != NULL - && co->co_argcount + co->co_posonlyargcount == PyTuple_GET_SIZE(argdefs)) { + && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { /* function called with no arguments, but all parameters have a default value: use default values as arguments .*/ args = _PyTuple_ITEMS(argdefs); @@ -396,11 +396,11 @@ _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, if (co->co_kwonlyargcount == 0 && nkwargs == 0 && (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount + co->co_posonlyargcount== nargs) { + if (argdefs == NULL && co->co_argcount == nargs) { return function_code_fastcall(co, stack, nargs, globals); } else if (nargs == 0 && argdefs != NULL - && co->co_argcount + co->co_posonlyargcount == PyTuple_GET_SIZE(argdefs)) { + && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { /* function called with no arguments, but all parameters have a default value: use default values as arguments .*/ stack = _PyTuple_ITEMS(argdefs); diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 886ce4194438aa..bf68e54f42ec1c 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -114,8 +114,9 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, Py_ssize_t i, n_cellvars, n_varnames, total_args; /* Check argument types */ - if (argcount < 0 || posonlyargcount < 0 || kwonlyargcount < 0 || - nlocals < 0 || stacksize < 0 || flags < 0 || + if (argcount < posonlyargcount || posonlyargcount < 0 || + kwonlyargcount < 0 || nlocals < 0 || + stacksize < 0 || flags < 0 || code == NULL || !PyBytes_Check(code) || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || @@ -152,11 +153,9 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, } n_varnames = PyTuple_GET_SIZE(varnames); - if (posonlyargcount + argcount <= n_varnames - && kwonlyargcount <= n_varnames) { + if (argcount <= n_varnames && kwonlyargcount <= n_varnames) { /* Never overflows. */ - total_args = (Py_ssize_t)posonlyargcount + (Py_ssize_t)argcount - + (Py_ssize_t)kwonlyargcount + + total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); } else { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index da249b569ad2bb..b6d925c1442e78 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7807,7 +7807,7 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds) "super(): no code object"); return -1; } - if (co->co_posonlyargcount + co->co_argcount == 0) { + if (co->co_argcount == 0) { PyErr_SetString(PyExc_RuntimeError, "super(): no arguments"); return -1; diff --git a/Python/ceval.c b/Python/ceval.c index f9ff4e09f17e20..d9a71e942153ee 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3757,10 +3757,10 @@ missing_arguments(PyThreadState *tstate, PyCodeObject *co, return; if (positional) { start = 0; - end = co->co_posonlyargcount + co->co_argcount - defcount; + end = co->co_argcount - defcount; } else { - start = co->co_posonlyargcount + co->co_argcount; + start = co->co_argcount; end = start + co->co_kwonlyargcount; } for (i = start; i < end; i++) { @@ -3788,25 +3788,23 @@ too_many_positional(PyThreadState *tstate, PyCodeObject *co, Py_ssize_t kwonly_given = 0; Py_ssize_t i; PyObject *sig, *kwonly_sig; - Py_ssize_t co_posonlyargcount = co->co_posonlyargcount; Py_ssize_t co_argcount = co->co_argcount; - Py_ssize_t total_positional = co_argcount + co_posonlyargcount; assert((co->co_flags & CO_VARARGS) == 0); /* Count missing keyword-only args. */ - for (i = total_positional; i < total_positional + co->co_kwonlyargcount; i++) { + for (i = co_argcount; i < co_argcount + co->co_kwonlyargcount; i++) { if (GETLOCAL(i) != NULL) { kwonly_given++; } } if (defcount) { - Py_ssize_t atleast = total_positional - defcount; + Py_ssize_t atleast = co_argcount - defcount; plural = 1; - sig = PyUnicode_FromFormat("from %zd to %zd", atleast, total_positional); + sig = PyUnicode_FromFormat("from %zd to %zd", atleast, co_argcount); } else { - plural = (total_positional != 1); - sig = PyUnicode_FromFormat("%zd", total_positional); + plural = (co_argcount != 1); + sig = PyUnicode_FromFormat("%zd", co_argcount); } if (sig == NULL) return; @@ -3917,7 +3915,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, PyObject *retval = NULL; PyObject **fastlocals, **freevars; PyObject *x, *u; - const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount + co->co_posonlyargcount; + const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; Py_ssize_t i, j, n; PyObject *kwdict; @@ -3953,9 +3951,9 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, kwdict = NULL; } - /* Copy positional only arguments into local variables */ - if (argcount > co->co_argcount + co->co_posonlyargcount) { - n = co->co_posonlyargcount; + /* Copy all positional arguments into local variables */ + if (argcount > co->co_argcount) { + n = co->co_argcount; } else { n = argcount; @@ -3966,20 +3964,6 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, SETLOCAL(j, x); } - - /* Copy positional arguments into local variables */ - if (argcount > co->co_argcount + co->co_posonlyargcount) { - n += co->co_argcount; - } - else { - n = argcount; - } - for (i = j; i < n; i++) { - x = args[i]; - Py_INCREF(x); - SETLOCAL(i, x); - } - /* Pack other positional arguments into the *args argument */ if (co->co_flags & CO_VARARGS) { u = _PyTuple_FromArray(args + n, argcount - n); @@ -4059,14 +4043,14 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, } /* Check the number of positional arguments */ - if ((argcount > co->co_argcount + co->co_posonlyargcount) && !(co->co_flags & CO_VARARGS)) { + if ((argcount > co->co_argcount) && !(co->co_flags & CO_VARARGS)) { too_many_positional(tstate, co, argcount, defcount, fastlocals); goto fail; } /* Add missing positional arguments (copy default values from defs) */ - if (argcount < co->co_posonlyargcount + co->co_argcount) { - Py_ssize_t m = co->co_posonlyargcount + co->co_argcount - defcount; + if (argcount < co->co_argcount) { + Py_ssize_t m = co->co_argcount - defcount; Py_ssize_t missing = 0; for (i = argcount; i < m; i++) { if (GETLOCAL(i) == NULL) { @@ -4093,7 +4077,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, /* Add missing keyword arguments (copy default values from kwdefs) */ if (co->co_kwonlyargcount > 0) { Py_ssize_t missing = 0; - for (i = co->co_posonlyargcount + co->co_argcount; i < total_args; i++) { + for (i = co->co_argcount; i < total_args; i++) { PyObject *name; if (GETLOCAL(i) != NULL) continue; diff --git a/Python/compile.c b/Python/compile.c index f6ec929b3ca4eb..9e4a2094ac9b92 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -5764,7 +5764,7 @@ makecode(struct compiler *c, struct assembler *a) Py_ssize_t nlocals; int nlocals_int; int flags; - int argcount, posonlyargcount, kwonlyargcount, maxdepth; + int posorkeywordargcount, posonlyargcount, kwonlyargcount, maxdepth; consts = consts_dict_keys_inorder(c->u->u_consts); names = dict_keys_inorder(c->u->u_names, 0); @@ -5808,15 +5808,15 @@ makecode(struct compiler *c, struct assembler *a) goto error; } - argcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int); posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int); + posorkeywordargcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int); kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int); maxdepth = stackdepth(c); if (maxdepth < 0) { goto error; } - co = PyCode_New(argcount, posonlyargcount, kwonlyargcount, - nlocals_int, maxdepth, flags, + co = PyCode_New(posonlyargcount+posorkeywordargcount, posonlyargcount, + kwonlyargcount, nlocals_int, maxdepth, flags, bytecode, consts, names, varnames, freevars, cellvars, c->c_filename, c->u->u_name, From 9843bc110dc4241ba7cb05f3d3ef74ac6c77caf2 Mon Sep 17 00:00:00 2001 From: Francisco Couzo Date: Sat, 1 Jun 2019 14:14:00 -0300 Subject: [PATCH 244/441] Improve exception message for str.format (GH-12675) --- Objects/stringlib/unicode_format.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h index 0fa54eb32cd361..ddf1e26448693a 100644 --- a/Objects/stringlib/unicode_format.h +++ b/Objects/stringlib/unicode_format.h @@ -440,8 +440,13 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs, /* look up in args */ obj = PySequence_GetItem(args, index); - if (obj == NULL) - goto error; + if (obj == NULL) { + PyErr_Format(PyExc_IndexError, + "Replacement index %zd out of range for positional " + "args tuple", + index); + goto error; + } } /* iterate over the rest of the field_name */ From 2b843ac0ae745026ce39514573c5d075137bef65 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 1 Jun 2019 22:09:02 +0300 Subject: [PATCH 245/441] bpo-35431: Refactor math.comb() implementation. (GH-13725) * Fixed some bugs. * Added support for index-likes objects. * Improved error messages. * Cleaned up and optimized the code. * Added more tests. --- Doc/library/math.rst | 4 +- Lib/test/test_math.py | 29 +++++-- Modules/clinic/mathmodule.c.h | 24 ++---- Modules/mathmodule.c | 155 ++++++++++++++++++---------------- 4 files changed, 111 insertions(+), 101 deletions(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 5243970df806ae..206b06edd2a206 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -238,11 +238,11 @@ Number-theoretic and representation functions and without order. Also called the binomial coefficient. It is mathematically equal to the expression - ``n! / (k! (n - k)!)``. It is equivalent to the coefficient of k-th term in + ``n! / (k! (n - k)!)``. It is equivalent to the coefficient of the *k*-th term in the polynomial expansion of the expression ``(1 + x) ** n``. Raises :exc:`TypeError` if the arguments not integers. - Raises :exc:`ValueError` if the arguments are negative or if k > n. + Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*. .. versionadded:: 3.8 diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 9da7f7c4e6e2f2..e27092eefd6ed7 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1893,9 +1893,11 @@ def testComb(self): # Raises TypeError if any argument is non-integer or argument count is # not 2 self.assertRaises(TypeError, comb, 10, 1.0) + self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0)) self.assertRaises(TypeError, comb, 10, "1") - self.assertRaises(TypeError, comb, "10", 1) self.assertRaises(TypeError, comb, 10.0, 1) + self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1) + self.assertRaises(TypeError, comb, "10", 1) self.assertRaises(TypeError, comb, 10) self.assertRaises(TypeError, comb, 10, 1, 3) @@ -1903,15 +1905,28 @@ def testComb(self): # Raises Value error if not k or n are negative numbers self.assertRaises(ValueError, comb, -1, 1) - self.assertRaises(ValueError, comb, -10*10, 1) + self.assertRaises(ValueError, comb, -2**1000, 1) self.assertRaises(ValueError, comb, 1, -1) - self.assertRaises(ValueError, comb, 1, -10*10) + self.assertRaises(ValueError, comb, 1, -2**1000) # Raises value error if k is greater than n - self.assertRaises(ValueError, comb, 1, 10**10) - self.assertRaises(ValueError, comb, 0, 1) - - + self.assertRaises(ValueError, comb, 1, 2) + self.assertRaises(ValueError, comb, 1, 2**1000) + + n = 2**1000 + self.assertEqual(comb(n, 0), 1) + self.assertEqual(comb(n, 1), n) + self.assertEqual(comb(n, 2), n * (n-1) // 2) + self.assertEqual(comb(n, n), 1) + self.assertEqual(comb(n, n-1), n) + self.assertEqual(comb(n, n-2), n * (n-1) // 2) + self.assertRaises((OverflowError, MemoryError), comb, n, n//2) + + for n, k in (True, True), (True, False), (False, False): + self.assertEqual(comb(n, k), 1) + self.assertIs(type(comb(n, k)), int) + self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10) + self.assertIs(type(comb(MyIndexable(5), MyIndexable(2))), int) def test_main(): diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index cba791e2098f28..92ec4bec9bf17d 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -639,10 +639,10 @@ math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k } PyDoc_STRVAR(math_comb__doc__, -"comb($module, /, n, k)\n" +"comb($module, n, k, /)\n" "--\n" "\n" -"Number of ways to choose *k* items from *n* items without repetition and without order.\n" +"Number of ways to choose k items from n items without repetition and without order.\n" "\n" "Also called the binomial coefficient. It is mathematically equal to the expression\n" "n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in\n" @@ -652,38 +652,26 @@ PyDoc_STRVAR(math_comb__doc__, "Raises ValueError if the arguments are negative or if k > n."); #define MATH_COMB_METHODDEF \ - {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL|METH_KEYWORDS, math_comb__doc__}, + {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__}, static PyObject * math_comb_impl(PyObject *module, PyObject *n, PyObject *k); static PyObject * -math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"n", "k", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "comb", 0}; - PyObject *argsbuf[2]; PyObject *n; PyObject *k; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); - if (!args) { - goto exit; - } - if (!PyLong_Check(args[0])) { - _PyArg_BadArgument("comb", 1, "int", args[0]); + if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) { goto exit; } n = args[0]; - if (!PyLong_Check(args[1])) { - _PyArg_BadArgument("comb", 2, "int", args[1]); - goto exit; - } k = args[1]; return_value = math_comb_impl(module, n, k); exit: return return_value; } -/*[clinic end generated code: output=00aa76356759617a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6709521e5e1d90ec input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 007a8801429c56..bea4607b9be1ee 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -3001,10 +3001,11 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) /*[clinic input] math.comb - n: object(subclass_of='&PyLong_Type') - k: object(subclass_of='&PyLong_Type') + n: object + k: object + / -Number of ways to choose *k* items from *n* items without repetition and without order. +Number of ways to choose k items from n items without repetition and without order. Also called the binomial coefficient. It is mathematically equal to the expression n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in @@ -3017,103 +3018,109 @@ Raises ValueError if the arguments are negative or if k > n. static PyObject * math_comb_impl(PyObject *module, PyObject *n, PyObject *k) -/*[clinic end generated code: output=bd2cec8d854f3493 input=565f340f98efb5b5]*/ +/*[clinic end generated code: output=bd2cec8d854f3493 input=2f336ac9ec8242f9]*/ { - PyObject *val = NULL, - *temp_obj1 = NULL, - *temp_obj2 = NULL, - *dump_var = NULL; + PyObject *result = NULL, *factor = NULL, *temp; int overflow, cmp; - long long i, terms; + long long i, factors; - cmp = PyObject_RichCompareBool(n, k, Py_LT); - if (cmp < 0) { - goto fail_comb; + n = PyNumber_Index(n); + if (n == NULL) { + return NULL; } - else if (cmp > 0) { - PyErr_Format(PyExc_ValueError, - "n must be an integer greater than or equal to k"); - goto fail_comb; + k = PyNumber_Index(k); + if (k == NULL) { + Py_DECREF(n); + return NULL; } - /* b = min(b, a - b) */ - dump_var = PyNumber_Subtract(n, k); - if (dump_var == NULL) { - goto fail_comb; + if (Py_SIZE(n) < 0) { + PyErr_SetString(PyExc_ValueError, + "n must be a non-negative integer"); + goto error; } - cmp = PyObject_RichCompareBool(k, dump_var, Py_GT); - if (cmp < 0) { - goto fail_comb; + /* k = min(k, n - k) */ + temp = PyNumber_Subtract(n, k); + if (temp == NULL) { + goto error; } - else if (cmp > 0) { - k = dump_var; - dump_var = NULL; + if (Py_SIZE(temp) < 0) { + Py_DECREF(temp); + PyErr_SetString(PyExc_ValueError, + "k must be an integer less than or equal to n"); + goto error; + } + cmp = PyObject_RichCompareBool(k, temp, Py_GT); + if (cmp > 0) { + Py_SETREF(k, temp); } else { - Py_DECREF(dump_var); - dump_var = NULL; + Py_DECREF(temp); + if (cmp < 0) { + goto error; + } } - terms = PyLong_AsLongLongAndOverflow(k, &overflow); - if (terms < 0 && PyErr_Occurred()) { - goto fail_comb; - } - else if (overflow > 0) { + factors = PyLong_AsLongLongAndOverflow(k, &overflow); + if (overflow > 0) { PyErr_Format(PyExc_OverflowError, - "minimum(n - k, k) must not exceed %lld", + "min(n - k, k) must not exceed %lld", LLONG_MAX); - goto fail_comb; + goto error; } - else if (overflow < 0 || terms < 0) { - PyErr_Format(PyExc_ValueError, - "k must be a positive integer"); - goto fail_comb; + else if (overflow < 0 || factors < 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + } + goto error; } - if (terms == 0) { - return PyNumber_Long(_PyLong_One); + if (factors == 0) { + result = PyLong_FromLong(1); + goto done; } - val = PyNumber_Long(n); - for (i = 1; i < terms; ++i) { - temp_obj1 = PyLong_FromSsize_t(i); - if (temp_obj1 == NULL) { - goto fail_comb; - } - temp_obj2 = PyNumber_Subtract(n, temp_obj1); - if (temp_obj2 == NULL) { - goto fail_comb; + result = n; + Py_INCREF(result); + if (factors == 1) { + goto done; + } + + factor = n; + Py_INCREF(factor); + for (i = 1; i < factors; ++i) { + Py_SETREF(factor, PyNumber_Subtract(factor, _PyLong_One)); + if (factor == NULL) { + goto error; } - dump_var = val; - val = PyNumber_Multiply(val, temp_obj2); - if (val == NULL) { - goto fail_comb; + Py_SETREF(result, PyNumber_Multiply(result, factor)); + if (result == NULL) { + goto error; } - Py_DECREF(dump_var); - dump_var = NULL; - Py_DECREF(temp_obj2); - temp_obj2 = PyLong_FromUnsignedLongLong((unsigned long long)(i + 1)); - if (temp_obj2 == NULL) { - goto fail_comb; + + temp = PyLong_FromUnsignedLongLong((unsigned long long)i + 1); + if (temp == NULL) { + goto error; } - dump_var = val; - val = PyNumber_FloorDivide(val, temp_obj2); - if (val == NULL) { - goto fail_comb; + Py_SETREF(result, PyNumber_FloorDivide(result, temp)); + Py_DECREF(temp); + if (result == NULL) { + goto error; } - Py_DECREF(dump_var); - Py_DECREF(temp_obj1); - Py_DECREF(temp_obj2); } + Py_DECREF(factor); - return val; - -fail_comb: - Py_XDECREF(val); - Py_XDECREF(dump_var); - Py_XDECREF(temp_obj1); - Py_XDECREF(temp_obj2); +done: + Py_DECREF(n); + Py_DECREF(k); + return result; +error: + Py_XDECREF(factor); + Py_XDECREF(result); + Py_DECREF(n); + Py_DECREF(k); return NULL; } From 56624a99a916fd27152d5b23364303acc0d707de Mon Sep 17 00:00:00 2001 From: Evan Date: Sun, 2 Jun 2019 05:09:22 +1000 Subject: [PATCH 246/441] bpo-28595: Allow shlex whitespace_split with punctuation_chars (GH-2071) --- Doc/library/shlex.rst | 35 +++++++++++++++++++++----------- Lib/shlex.py | 3 ++- Lib/test/test_shlex.py | 46 +++++++++++++++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index 8c5b0239d1f08b..a8421fdb7008ce 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -225,7 +225,8 @@ variables which either control lexical analysis or can be used for debugging: appear in filename specifications and command line parameters, will also be included in this attribute, and any characters which appear in ``punctuation_chars`` will be removed from ``wordchars`` if they are present - there. + there. If :attr:`whitespace_split` is set to ``True``, this will have no + effect. .. attribute:: shlex.whitespace @@ -258,11 +259,13 @@ variables which either control lexical analysis or can be used for debugging: If ``True``, tokens will only be split in whitespaces. This is useful, for example, for parsing command lines with :class:`~shlex.shlex`, getting - tokens in a similar way to shell arguments. If this attribute is ``True``, - :attr:`punctuation_chars` will have no effect, and splitting will happen - only on whitespaces. When using :attr:`punctuation_chars`, which is - intended to provide parsing closer to that implemented by shells, it is - advisable to leave ``whitespace_split`` as ``False`` (the default value). + tokens in a similar way to shell arguments. When used in combination with + :attr:`punctuation_chars`, tokens will be split on whitespace in addition to + those characters. + + .. versionchanged:: 3.8 + The :attr:`punctuation_chars` attribute was made compatible with the + :attr:`whitespace_split` attribute. .. attribute:: shlex.infile @@ -398,12 +401,15 @@ otherwise. To illustrate, you can see the difference in the following snippet: >>> import shlex >>> text = "a && b; c && d || e; f >'abc'; (def \"ghi\")" - >>> list(shlex.shlex(text)) - ['a', '&', '&', 'b', ';', 'c', '&', '&', 'd', '|', '|', 'e', ';', 'f', '>', - "'abc'", ';', '(', 'def', '"ghi"', ')'] - >>> list(shlex.shlex(text, punctuation_chars=True)) - ['a', '&&', 'b', ';', 'c', '&&', 'd', '||', 'e', ';', 'f', '>', "'abc'", - ';', '(', 'def', '"ghi"', ')'] + >>> s = shlex.shlex(text, posix=True) + >>> s.whitespace_split = True + >>> list(s) + ['a', '&&', 'b;', 'c', '&&', 'd', '||', 'e;', 'f', '>abc;', '(def', 'ghi)'] + >>> s = shlex.shlex(text, posix=True, punctuation_chars=True) + >>> s.whitespace_split = True + >>> list(s) + ['a', '&&', 'b', ';', 'c', '&&', 'd', '||', 'e', ';', 'f', '>', 'abc', ';', + '(', 'def', 'ghi', ')'] Of course, tokens will be returned which are not valid for shells, and you'll need to implement your own error checks on the returned tokens. @@ -428,6 +434,11 @@ which characters constitute punctuation. For example:: >>> list(s) ['~/a', '&&', 'b-c', '--color=auto', '||', 'd', '*.py?'] + However, to match the shell as closely as possible, it is recommended to + always use ``posix`` and :attr:`~shlex.whitespace_split` when using + :attr:`~shlex.punctuation_chars`, which will negate + :attr:`~shlex.wordchars` entirely. + For best effect, ``punctuation_chars`` should be set in conjunction with ``posix=True``. (Note that ``posix=False`` is the default for :class:`~shlex.shlex`.) diff --git a/Lib/shlex.py b/Lib/shlex.py index fb1130d4eac207..edea077948608a 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -246,7 +246,8 @@ def read_token(self): escapedstate = 'a' self.state = nextchar elif (nextchar in self.wordchars or nextchar in self.quotes - or self.whitespace_split): + or (self.whitespace_split and + nextchar not in self.punctuation_chars)): self.token += nextchar else: if self.punctuation_chars: diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index a432610d3af460..376c5e88d3819d 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -1,4 +1,5 @@ import io +import itertools import shlex import string import unittest @@ -183,10 +184,12 @@ def testSyntaxSplitAmpersandAndPipe(self): src = ['echo hi %s echo bye' % delimiter, 'echo hi%secho bye' % delimiter] ref = ['echo', 'hi', delimiter, 'echo', 'bye'] - for ss in src: + for ss, ws in itertools.product(src, (False, True)): s = shlex.shlex(ss, punctuation_chars=True) + s.whitespace_split = ws result = list(s) - self.assertEqual(ref, result, "While splitting '%s'" % ss) + self.assertEqual(ref, result, + "While splitting '%s' [ws=%s]" % (ss, ws)) def testSyntaxSplitSemicolon(self): """Test handling of syntax splitting of ;""" @@ -197,10 +200,12 @@ def testSyntaxSplitSemicolon(self): 'echo hi%s echo bye' % delimiter, 'echo hi%secho bye' % delimiter] ref = ['echo', 'hi', delimiter, 'echo', 'bye'] - for ss in src: + for ss, ws in itertools.product(src, (False, True)): s = shlex.shlex(ss, punctuation_chars=True) + s.whitespace_split = ws result = list(s) - self.assertEqual(ref, result, "While splitting '%s'" % ss) + self.assertEqual(ref, result, + "While splitting '%s' [ws=%s]" % (ss, ws)) def testSyntaxSplitRedirect(self): """Test handling of syntax splitting of >""" @@ -211,10 +216,11 @@ def testSyntaxSplitRedirect(self): 'echo hi%s out' % delimiter, 'echo hi%sout' % delimiter] ref = ['echo', 'hi', delimiter, 'out'] - for ss in src: + for ss, ws in itertools.product(src, (False, True)): s = shlex.shlex(ss, punctuation_chars=True) result = list(s) - self.assertEqual(ref, result, "While splitting '%s'" % ss) + self.assertEqual(ref, result, + "While splitting '%s' [ws=%s]" % (ss, ws)) def testSyntaxSplitParen(self): """Test handling of syntax splitting of ()""" @@ -222,18 +228,25 @@ def testSyntaxSplitParen(self): src = ['( echo hi )', '(echo hi)'] ref = ['(', 'echo', 'hi', ')'] - for ss in src: + for ss, ws in itertools.product(src, (False, True)): s = shlex.shlex(ss, punctuation_chars=True) + s.whitespace_split = ws result = list(s) - self.assertEqual(ref, result, "While splitting '%s'" % ss) + self.assertEqual(ref, result, + "While splitting '%s' [ws=%s]" % (ss, ws)) def testSyntaxSplitCustom(self): """Test handling of syntax splitting with custom chars""" + ss = "~/a&&b-c --color=auto||d *.py?" ref = ['~/a', '&', '&', 'b-c', '--color=auto', '||', 'd', '*.py?'] - ss = "~/a && b-c --color=auto || d *.py?" s = shlex.shlex(ss, punctuation_chars="|") result = list(s) - self.assertEqual(ref, result, "While splitting '%s'" % ss) + self.assertEqual(ref, result, "While splitting '%s' [ws=False]" % ss) + ref = ['~/a&&b-c', '--color=auto', '||', 'd', '*.py?'] + s = shlex.shlex(ss, punctuation_chars="|") + s.whitespace_split = True + result = list(s) + self.assertEqual(ref, result, "While splitting '%s' [ws=True]" % ss) def testTokenTypes(self): """Test that tokens are split with types as expected.""" @@ -293,6 +306,19 @@ def testEmptyStringHandling(self): s = shlex.shlex("'')abc", punctuation_chars=True) self.assertEqual(list(s), expected) + def testUnicodeHandling(self): + """Test punctuation_chars and whitespace_split handle unicode.""" + ss = "\u2119\u01b4\u2602\u210c\u00f8\u1f24" + # Should be parsed as one complete token (whitespace_split=True). + ref = ['\u2119\u01b4\u2602\u210c\u00f8\u1f24'] + s = shlex.shlex(ss, punctuation_chars=True) + s.whitespace_split = True + self.assertEqual(list(s), ref) + # Without whitespace_split, uses wordchars and splits on all. + ref = ['\u2119', '\u01b4', '\u2602', '\u210c', '\u00f8', '\u1f24'] + s = shlex.shlex(ss, punctuation_chars=True) + self.assertEqual(list(s), ref) + def testQuote(self): safeunquoted = string.ascii_letters + string.digits + '@%_-+=:,./' unicode_sample = '\xe9\xe0\xdf' # e + acute accent, a + grave, sharp s From faa2948654d15a859bc4317e00730ff213295764 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 1 Jun 2019 21:49:03 +0200 Subject: [PATCH 247/441] Clean up and reduce visual clutter in the makeunicode.py script. (GH-7558) --- Tools/unicode/makeunicodedata.py | 538 ++++++++++++++++--------------- 1 file changed, 275 insertions(+), 263 deletions(-) diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 5418eec588c825..5b9427acd39003 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -31,6 +31,7 @@ import zipfile from textwrap import dedent +from functools import partial SCRIPT = sys.argv[0] VERSION = "3.3" @@ -106,11 +107,11 @@ ('2CEB0', '2EBE0'), ] + def maketables(trace=0): print("--- Reading", UNICODE_DATA % "", "...") - version = "" unicode = UnicodeData(UNIDATA_VERSION) print(len(list(filter(None, unicode.table))), "characters") @@ -125,6 +126,7 @@ def maketables(trace=0): makeunicodedata(unicode, trace) makeunicodetype(unicode, trace) + # -------------------------------------------------------------------- # unicode character properties @@ -258,124 +260,125 @@ def makeunicodedata(unicode, trace): print("--- Writing", FILE, "...") - fp = open(FILE, "w") - print("/* this file was generated by %s %s */" % (SCRIPT, VERSION), file=fp) - print(file=fp) - print('#define UNIDATA_VERSION "%s"' % UNIDATA_VERSION, file=fp) - print("/* a list of unique database records */", file=fp) - print("const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = {", file=fp) - for item in table: - print(" {%d, %d, %d, %d, %d, %d}," % item, file=fp) - print("};", file=fp) - print(file=fp) - - print("/* Reindexing of NFC first characters. */", file=fp) - print("#define TOTAL_FIRST",total_first, file=fp) - print("#define TOTAL_LAST",total_last, file=fp) - print("struct reindex{int start;short count,index;};", file=fp) - print("static struct reindex nfc_first[] = {", file=fp) - for start,end in comp_first_ranges: - print(" { %d, %d, %d}," % (start,end-start,comp_first[start]), file=fp) - print(" {0,0,0}", file=fp) - print("};\n", file=fp) - print("static struct reindex nfc_last[] = {", file=fp) - for start,end in comp_last_ranges: - print(" { %d, %d, %d}," % (start,end-start,comp_last[start]), file=fp) - print(" {0,0,0}", file=fp) - print("};\n", file=fp) - - # FIXME: the following tables could be made static, and - # the support code moved into unicodedatabase.c - - print("/* string literals */", file=fp) - print("const char *_PyUnicode_CategoryNames[] = {", file=fp) - for name in CATEGORY_NAMES: - print(" \"%s\"," % name, file=fp) - print(" NULL", file=fp) - print("};", file=fp) - - print("const char *_PyUnicode_BidirectionalNames[] = {", file=fp) - for name in BIDIRECTIONAL_NAMES: - print(" \"%s\"," % name, file=fp) - print(" NULL", file=fp) - print("};", file=fp) - - print("const char *_PyUnicode_EastAsianWidthNames[] = {", file=fp) - for name in EASTASIANWIDTH_NAMES: - print(" \"%s\"," % name, file=fp) - print(" NULL", file=fp) - print("};", file=fp) - - print("static const char *decomp_prefix[] = {", file=fp) - for name in decomp_prefix: - print(" \"%s\"," % name, file=fp) - print(" NULL", file=fp) - print("};", file=fp) - - # split record index table - index1, index2, shift = splitbins(index, trace) - - print("/* index tables for the database records */", file=fp) - print("#define SHIFT", shift, file=fp) - Array("index1", index1).dump(fp, trace) - Array("index2", index2).dump(fp, trace) - - # split decomposition index table - index1, index2, shift = splitbins(decomp_index, trace) - - print("/* decomposition data */", file=fp) - Array("decomp_data", decomp_data).dump(fp, trace) - - print("/* index tables for the decomposition data */", file=fp) - print("#define DECOMP_SHIFT", shift, file=fp) - Array("decomp_index1", index1).dump(fp, trace) - Array("decomp_index2", index2).dump(fp, trace) - - index, index2, shift = splitbins(comp_data, trace) - print("/* NFC pairs */", file=fp) - print("#define COMP_SHIFT", shift, file=fp) - Array("comp_index", index).dump(fp, trace) - Array("comp_data", index2).dump(fp, trace) - - # Generate delta tables for old versions - for version, table, normalization in unicode.changed: - cversion = version.replace(".","_") - records = [table[0]] - cache = {table[0]:0} - index = [0] * len(table) - for i, record in enumerate(table): - try: - index[i] = cache[record] - except KeyError: - index[i] = cache[record] = len(records) - records.append(record) + with open(FILE, "w") as fp: + fprint = partial(print, file=fp) + + fprint("/* this file was generated by %s %s */" % (SCRIPT, VERSION)) + fprint() + fprint('#define UNIDATA_VERSION "%s"' % UNIDATA_VERSION) + fprint("/* a list of unique database records */") + fprint("const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = {") + for item in table: + fprint(" {%d, %d, %d, %d, %d, %d}," % item) + fprint("};") + fprint() + + fprint("/* Reindexing of NFC first characters. */") + fprint("#define TOTAL_FIRST",total_first) + fprint("#define TOTAL_LAST",total_last) + fprint("struct reindex{int start;short count,index;};") + fprint("static struct reindex nfc_first[] = {") + for start,end in comp_first_ranges: + fprint(" { %d, %d, %d}," % (start,end-start,comp_first[start])) + fprint(" {0,0,0}") + fprint("};\n") + fprint("static struct reindex nfc_last[] = {") + for start,end in comp_last_ranges: + fprint(" { %d, %d, %d}," % (start,end-start,comp_last[start])) + fprint(" {0,0,0}") + fprint("};\n") + + # FIXME: the following tables could be made static, and + # the support code moved into unicodedatabase.c + + fprint("/* string literals */") + fprint("const char *_PyUnicode_CategoryNames[] = {") + for name in CATEGORY_NAMES: + fprint(" \"%s\"," % name) + fprint(" NULL") + fprint("};") + + fprint("const char *_PyUnicode_BidirectionalNames[] = {") + for name in BIDIRECTIONAL_NAMES: + fprint(" \"%s\"," % name) + fprint(" NULL") + fprint("};") + + fprint("const char *_PyUnicode_EastAsianWidthNames[] = {") + for name in EASTASIANWIDTH_NAMES: + fprint(" \"%s\"," % name) + fprint(" NULL") + fprint("};") + + fprint("static const char *decomp_prefix[] = {") + for name in decomp_prefix: + fprint(" \"%s\"," % name) + fprint(" NULL") + fprint("};") + + # split record index table index1, index2, shift = splitbins(index, trace) - print("static const change_record change_records_%s[] = {" % cversion, file=fp) - for record in records: - print(" { %s }," % ", ".join(map(str,record)), file=fp) - print("};", file=fp) - Array("changes_%s_index" % cversion, index1).dump(fp, trace) - Array("changes_%s_data" % cversion, index2).dump(fp, trace) - print("static const change_record* get_change_%s(Py_UCS4 n)" % cversion, file=fp) - print("{", file=fp) - print(" int index;", file=fp) - print(" if (n >= 0x110000) index = 0;", file=fp) - print(" else {", file=fp) - print(" index = changes_%s_index[n>>%d];" % (cversion, shift), file=fp) - print(" index = changes_%s_data[(index<<%d)+(n & %d)];" % \ - (cversion, shift, ((1<= 0x110000) index = 0;") + fprint(" else {") + fprint(" index = changes_%s_index[n>>%d];" % (cversion, shift)) + fprint(" index = changes_%s_data[(index<<%d)+(n & %d)];" % \ + (cversion, shift, ((1<name phrasebook */", file=fp) - print("#define phrasebook_shift", shift, file=fp) - print("#define phrasebook_short", short, file=fp) - - Array("phrasebook", phrasebook).dump(fp, trace) - Array("phrasebook_offset1", offset1).dump(fp, trace) - Array("phrasebook_offset2", offset2).dump(fp, trace) - - print("/* name->code dictionary */", file=fp) - codehash.dump(fp, trace) - - print(file=fp) - print('static const unsigned int aliases_start = %#x;' % - NAME_ALIASES_START, file=fp) - print('static const unsigned int aliases_end = %#x;' % - (NAME_ALIASES_START + len(unicode.aliases)), file=fp) - - print('static const unsigned int name_aliases[] = {', file=fp) - for name, codepoint in unicode.aliases: - print(' 0x%04X,' % codepoint, file=fp) - print('};', file=fp) - - # In Unicode 6.0.0, the sequences contain at most 4 BMP chars, - # so we are using Py_UCS2 seq[4]. This needs to be updated if longer - # sequences or sequences with non-BMP chars are added. - # unicodedata_lookup should be adapted too. - print(dedent(""" - typedef struct NamedSequence { - int seqlen; - Py_UCS2 seq[4]; - } named_sequence; - """), file=fp) - - print('static const unsigned int named_sequences_start = %#x;' % - NAMED_SEQUENCES_START, file=fp) - print('static const unsigned int named_sequences_end = %#x;' % - (NAMED_SEQUENCES_START + len(unicode.named_sequences)), file=fp) - - print('static const named_sequence named_sequences[] = {', file=fp) - for name, sequence in unicode.named_sequences: - seq_str = ', '.join('0x%04X' % cp for cp in sequence) - print(' {%d, {%s}},' % (len(sequence), seq_str), file=fp) - print('};', file=fp) - - fp.close() + with open(FILE, "w") as fp: + fprint = partial(print, file=fp) + + fprint("/* this file was generated by %s %s */" % (SCRIPT, VERSION)) + fprint() + fprint("#define NAME_MAXLEN", 256) + fprint() + fprint("/* lexicon */") + Array("lexicon", lexicon).dump(fp, trace) + Array("lexicon_offset", lexicon_offset).dump(fp, trace) + + # split decomposition index table + offset1, offset2, shift = splitbins(phrasebook_offset, trace) + + fprint("/* code->name phrasebook */") + fprint("#define phrasebook_shift", shift) + fprint("#define phrasebook_short", short) + + Array("phrasebook", phrasebook).dump(fp, trace) + Array("phrasebook_offset1", offset1).dump(fp, trace) + Array("phrasebook_offset2", offset2).dump(fp, trace) + + fprint("/* name->code dictionary */") + codehash.dump(fp, trace) + + fprint() + fprint('static const unsigned int aliases_start = %#x;' % + NAME_ALIASES_START) + fprint('static const unsigned int aliases_end = %#x;' % + (NAME_ALIASES_START + len(unicode.aliases))) + + fprint('static const unsigned int name_aliases[] = {') + for name, codepoint in unicode.aliases: + fprint(' 0x%04X,' % codepoint) + fprint('};') + + # In Unicode 6.0.0, the sequences contain at most 4 BMP chars, + # so we are using Py_UCS2 seq[4]. This needs to be updated if longer + # sequences or sequences with non-BMP chars are added. + # unicodedata_lookup should be adapted too. + fprint(dedent(""" + typedef struct NamedSequence { + int seqlen; + Py_UCS2 seq[4]; + } named_sequence; + """)) + + fprint('static const unsigned int named_sequences_start = %#x;' % + NAMED_SEQUENCES_START) + fprint('static const unsigned int named_sequences_end = %#x;' % + (NAMED_SEQUENCES_START + len(unicode.named_sequences))) + + fprint('static const named_sequence named_sequences[] = {') + for name, sequence in unicode.named_sequences: + seq_str = ', '.join('0x%04X' % cp for cp in sequence) + fprint(' {%d, {%s}},' % (len(sequence), seq_str)) + fprint('};') def merge_old_version(version, new, old): @@ -882,6 +885,7 @@ class Difference(Exception):pass numeric_changes)), normalization_changes)) + def open_data(template, version): local = template % ('-'+version,) if not os.path.exists(local): @@ -898,6 +902,7 @@ def open_data(template, version): # Unihan.zip return open(local, 'rb') + # -------------------------------------------------------------------- # the following support code is taken from the unidb utilities # Copyright (c) 1999-2000 by Secret Labs AB @@ -1150,6 +1155,7 @@ def uselatin1(self): # restrict character range to ISO Latin 1 self.chars = list(range(256)) + # hash table tools # this is a straight-forward reimplementation of Python's built-in @@ -1165,6 +1171,7 @@ def myhash(s, magic): h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff return h + SIZES = [ (4,3), (8,3), (16,3), (32,5), (64,3), (128,3), (256,29), (512,17), (1024,9), (2048,5), (4096,83), (8192,27), (16384,43), (32768,3), @@ -1172,6 +1179,7 @@ def myhash(s, magic): (2097152,5), (4194304,3), (8388608,33), (16777216,27) ] + class Hash: def __init__(self, name, data, magic): # turn a (key, value) list into a static hash table structure @@ -1202,7 +1210,7 @@ def __init__(self, name, data, magic): if v is None: table[i] = value continue - incr = (h ^ (h >> 3)) & mask; + incr = (h ^ (h >> 3)) & mask if not incr: incr = mask while 1: @@ -1236,6 +1244,7 @@ def dump(self, file, trace): file.write("#define %s_size %d\n" % (self.name, self.size)) file.write("#define %s_poly %d\n" % (self.name, self.poly)) + # stuff to deal with arrays of unsigned integers class Array: @@ -1270,6 +1279,7 @@ def dump(self, file, trace=0): file.write(s.rstrip() + "\n") file.write("};\n\n") + def getsize(data): # return smallest possible integer size for the given array maxdata = max(data) @@ -1280,6 +1290,7 @@ def getsize(data): else: return 4 + def splitbins(t, trace=0): """t, trace=0 -> (t1, t2, shift). Split a table to save space. @@ -1299,8 +1310,8 @@ def splitbins(t, trace=0): def dump(t1, t2, shift, bytes): print("%d+%d bins at shift %d; %d bytes" % ( len(t1), len(t2), shift, bytes), file=sys.stderr) - print("Size of original table:", len(t)*getsize(t), \ - "bytes", file=sys.stderr) + print("Size of original table:", len(t)*getsize(t), "bytes", + file=sys.stderr) n = len(t)-1 # last valid index maxshift = 0 # the most we can shift n and still have something left if n > 0: @@ -1341,5 +1352,6 @@ def dump(t1, t2, shift, bytes): assert t[i] == t2[(t1[i >> shift] << shift) + (i & mask)] return best + if __name__ == "__main__": maketables(1) From 938d9a0167f7fa4ed109484d269902021d274c64 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 1 Jun 2019 21:02:08 +0100 Subject: [PATCH 248/441] Fix compiler warnings in the pystrehex module (GH-13730) --- Python/pystrhex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/pystrhex.c b/Python/pystrhex.c index 695a3c394e9b06..5dc7c9613796e0 100644 --- a/Python/pystrhex.c +++ b/Python/pystrhex.c @@ -11,11 +11,11 @@ static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, PyObject *retval; Py_UCS1* retbuf; Py_ssize_t i, j, resultlen = 0; - Py_UCS1 sep_char; + Py_UCS1 sep_char = 0; unsigned int abs_bytes_per_sep; if (sep) { - Py_ssize_t seplen = PyObject_Length(sep); + Py_ssize_t seplen = PyObject_Length((PyObject*)sep); if (seplen < 0) { return NULL; } From 3b57f50efc16c65df96914ec53bc8d3dc28e18b6 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 1 Jun 2019 21:18:48 +0100 Subject: [PATCH 249/441] bpo-36842: Pass positional only parameters to code_new audit hook (GH-13707) --- Doc/c-api/code.rst | 2 +- Objects/codeobject.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 92baa4c7df5cc1..48428109e6f2fe 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -45,7 +45,7 @@ bound into a function. The first parameter (*argcount*) now represents the total number of positional arguments, including positional-only. - .. audit-event:: code.__new__ "code filename name argcount kwonlyargcount nlocals stacksize flags" + .. audit-event:: code.__new__ "code filename name argcount posonlyargcount kwonlyargcount nlocals stacksize flags" .. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index bf68e54f42ec1c..233307562a5537 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -390,9 +390,9 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) &PyTuple_Type, &cellvars)) return NULL; - if (PySys_Audit("code.__new__", "OOOiiiii", - code, filename, name, argcount, kwonlyargcount, - nlocals, stacksize, flags) < 0) { + if (PySys_Audit("code.__new__", "OOOiiiiii", + code, filename, name, argcount, posonlyargcount, + kwonlyargcount, nlocals, stacksize, flags) < 0) { goto cleanup; } From e5f6207ba6cb510d9370519ba869296be01787be Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Sun, 2 Jun 2019 01:32:18 +0500 Subject: [PATCH 250/441] bpo-34303: Micro-optimizations in functools.reduce() (GH-8598) --- .../Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst | 2 ++ Modules/_functoolsmodule.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst diff --git a/Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst b/Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst new file mode 100644 index 00000000000000..94c1299e5956b0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst @@ -0,0 +1,2 @@ +Performance of :func:`functools.reduce` is slightly improved. Patch by +Sergey Fedoseev. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index aca5bad23f585b..a101363bf02a07 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -626,10 +626,13 @@ functools_reduce(PyObject *self, PyObject *args) if (result == NULL) result = op2; else { - PyTuple_SetItem(args, 0, result); - PyTuple_SetItem(args, 1, op2); - if ((result = PyEval_CallObject(func, args)) == NULL) + /* Update the args tuple in-place */ + assert(args->ob_refcnt == 1); + Py_XSETREF(_PyTuple_ITEMS(args)[0], result); + Py_XSETREF(_PyTuple_ITEMS(args)[1], op2); + if ((result = PyObject_Call(func, args, NULL)) == NULL) { goto Fail; + } } } From 1a4d9ffa1aecd7e750195f2be06d3d16c7a3a88f Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Sat, 1 Jun 2019 17:03:22 -0400 Subject: [PATCH 251/441] bpo-32411: IDLE: Remove line number sort in browser.py (#5011) Insertion in line order makes sorting keys by line order unneeded. --- Lib/idlelib/NEWS.txt | 2 ++ Lib/idlelib/browser.py | 7 +++-- Lib/idlelib/idle_test/test_browser.py | 28 +++++++++---------- .../2017-12-25-18-48-50.bpo-32411.vNwDhe.rst | 2 ++ 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index e1bc009ae93332..b260d4e5ef1bd8 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,8 @@ Released on 2019-10-20? ====================================== +bpo-32411: Stop sorting dict created with desired line order. + bpo-37038: Make idlelib.run runnable; add test clause. bpo-36958: Print any argument other than None or int passed to diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py index 234883fe860599..e5b0bc53c66240 100644 --- a/Lib/idlelib/browser.py +++ b/Lib/idlelib/browser.py @@ -29,9 +29,10 @@ def transform_children(child_dict, modname=None): The dictionary maps names to pyclbr information objects. Filter out imported objects. Augment class names with bases. - Sort objects by line number. + The insertion order of the dictonary is assumed to have been in line + number order, so sorting is not necessary. - The current tree only calls this once per child_dic as it saves + The current tree only calls this once per child_dict as it saves TreeItems once created. A future tree and tests might violate this, so a check prevents multiple in-place augmentations. """ @@ -51,7 +52,7 @@ def transform_children(child_dict, modname=None): supers.append(sname) obj.name += '({})'.format(', '.join(supers)) obs.append(obj) - return sorted(obs, key=lambda o: o.lineno) + return obs class ModuleBrowser: diff --git a/Lib/idlelib/idle_test/test_browser.py b/Lib/idlelib/idle_test/test_browser.py index dfbab6dd6b5e5b..25d6dc6630364b 100644 --- a/Lib/idlelib/idle_test/test_browser.py +++ b/Lib/idlelib/idle_test/test_browser.py @@ -61,16 +61,16 @@ def test_close(self): # Nested tree same as in test_pyclbr.py except for supers on C0. C1. mb = pyclbr module, fname = 'test', 'test.py' -f0 = mb.Function(module, 'f0', fname, 1) -f1 = mb._nest_function(f0, 'f1', 2) -f2 = mb._nest_function(f1, 'f2', 3) -c1 = mb._nest_class(f0, 'c1', 5) -C0 = mb.Class(module, 'C0', ['base'], fname, 6) -F1 = mb._nest_function(C0, 'F1', 8) -C1 = mb._nest_class(C0, 'C1', 11, ['']) -C2 = mb._nest_class(C1, 'C2', 12) -F3 = mb._nest_function(C2, 'F3', 14) -mock_pyclbr_tree = {'f0': f0, 'C0': C0} +C0 = mb.Class(module, 'C0', ['base'], fname, 1) +F1 = mb._nest_function(C0, 'F1', 3) +C1 = mb._nest_class(C0, 'C1', 6, ['']) +C2 = mb._nest_class(C1, 'C2', 7) +F3 = mb._nest_function(C2, 'F3', 9) +f0 = mb.Function(module, 'f0', fname, 11) +f1 = mb._nest_function(f0, 'f1', 12) +f2 = mb._nest_function(f1, 'f2', 13) +c1 = mb._nest_class(f0, 'c1', 15) +mock_pyclbr_tree = {'C0': C0, 'f0': f0} # Adjust C0.name, C1.name so tests do not depend on order. browser.transform_children(mock_pyclbr_tree, 'test') # C0(base) @@ -87,12 +87,12 @@ def test_transform_module_children(self): transform = browser.transform_children # Parameter matches tree module. tcl = list(transform(mock_pyclbr_tree, 'test')) - eq(tcl, [f0, C0]) - eq(tcl[0].name, 'f0') - eq(tcl[1].name, 'C0(base)') + eq(tcl, [C0, f0]) + eq(tcl[0].name, 'C0(base)') + eq(tcl[1].name, 'f0') # Check that second call does not change suffix. tcl = list(transform(mock_pyclbr_tree, 'test')) - eq(tcl[1].name, 'C0(base)') + eq(tcl[0].name, 'C0(base)') # Nothing to traverse if parameter name isn't same as tree module. tcl = list(transform(mock_pyclbr_tree, 'different name')) eq(tcl, []) diff --git a/Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst b/Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst new file mode 100644 index 00000000000000..a5522012923a50 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst @@ -0,0 +1,2 @@ +In browser.py, remove extraneous sorting by line number since dictionary was +created in line number order. From bdbad71b9def0b86433de12cecca022eee91bd9f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 2 Jun 2019 00:05:48 +0300 Subject: [PATCH 252/441] bpo-20092. Use __index__ in constructors of int, float and complex. (GH-13108) --- Doc/c-api/complex.rst | 8 ++- Doc/c-api/float.rst | 4 ++ Doc/library/functions.rst | 21 +++++- Doc/reference/datamodel.rst | 8 +-- Doc/whatsnew/3.8.rst | 11 +++- Lib/test/test_cmath.py | 7 +- Lib/test/test_complex.py | 18 +++++ Lib/test/test_float.py | 15 +++++ Lib/test/test_getargs2.py | 6 ++ Lib/test/test_index.py | 2 +- Lib/test/test_int.py | 66 +++++++++++++++++-- .../2019-05-31-11-55-49.bpo-20092.KIMjBW.rst | 4 ++ Objects/abstract.c | 19 ++++++ Objects/complexobject.c | 6 +- Objects/floatobject.c | 9 +++ 15 files changed, 181 insertions(+), 23 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst index 675bd013e892f5..06dbb2572725ee 100644 --- a/Doc/c-api/complex.rst +++ b/Doc/c-api/complex.rst @@ -129,4 +129,10 @@ Complex Numbers as Python Objects If *op* is not a Python complex number object but has a :meth:`__complex__` method, this method will first be called to convert *op* to a Python complex - number object. Upon failure, this method returns ``-1.0`` as a real value. + number object. If ``__complex__()`` is not defined then it falls back to + :meth:`__float__`. If ``__float__()`` is not defined then it falls back + to :meth:`__index__`. Upon failure, this method returns ``-1.0`` as a real + value. + + .. versionchanged:: 3.8 + Use :meth:`__index__` if available. diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index 8a996422ce48f8..057ff522516a3a 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -47,9 +47,13 @@ Floating Point Objects Return a C :c:type:`double` representation of the contents of *pyfloat*. If *pyfloat* is not a Python floating point object but has a :meth:`__float__` method, this method will first be called to convert *pyfloat* into a float. + If ``__float__()`` is not defined then it falls back to :meth:`__index__`. This method returns ``-1.0`` upon failure, so one should call :c:func:`PyErr_Occurred` to check for errors. + .. versionchanged:: 3.8 + Use :meth:`__index__` if available. + .. c:function:: double PyFloat_AS_DOUBLE(PyObject *pyfloat) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 425a985320fcfb..d5c9f18c79b7ab 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -318,6 +318,11 @@ are always available. They are listed here in alphabetical order. :class:`int` and :class:`float`. If both arguments are omitted, returns ``0j``. + For a general Python object ``x``, ``complex(x)`` delegates to + ``x.__complex__()``. If ``__complex__()`` is not defined then it falls back + to :meth:`__float__`. If ``__float__()`` is not defined then it falls back + to :meth:`__index__`. + .. note:: When converting from a string, the string must not contain whitespace @@ -330,6 +335,10 @@ are always available. They are listed here in alphabetical order. .. versionchanged:: 3.6 Grouping digits with underscores as in code literals is allowed. + .. versionchanged:: 3.8 + Falls back to :meth:`__index__` if :meth:`__complex__` and + :meth:`__float__` are not defined. + .. function:: delattr(object, name) @@ -584,7 +593,8 @@ are always available. They are listed here in alphabetical order. float, an :exc:`OverflowError` will be raised. For a general Python object ``x``, ``float(x)`` delegates to - ``x.__float__()``. + ``x.__float__()``. If ``__float__()`` is not defined then it falls back + to :meth:`__index__`. If no argument is given, ``0.0`` is returned. @@ -609,6 +619,9 @@ are always available. They are listed here in alphabetical order. .. versionchanged:: 3.7 *x* is now a positional-only parameter. + .. versionchanged:: 3.8 + Falls back to :meth:`__index__` if :meth:`__float__` is not defined. + .. index:: single: __format__ @@ -780,7 +793,8 @@ are always available. They are listed here in alphabetical order. Return an integer object constructed from a number or string *x*, or return ``0`` if no arguments are given. If *x* defines :meth:`__int__`, - ``int(x)`` returns ``x.__int__()``. If *x* defines :meth:`__trunc__`, + ``int(x)`` returns ``x.__int__()``. If *x* defines :meth:`__index__`, + it returns ``x.__index__()``. If *x* defines :meth:`__trunc__`, it returns ``x.__trunc__()``. For floating point numbers, this truncates towards zero. @@ -812,6 +826,9 @@ are always available. They are listed here in alphabetical order. .. versionchanged:: 3.7 *x* is now a positional-only parameter. + .. versionchanged:: 3.8 + Falls back to :meth:`__index__` if :meth:`__int__` is not defined. + .. function:: isinstance(object, classinfo) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 44017d8a55df52..fa47bf1c1619b5 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2394,11 +2394,9 @@ left undefined. functions). Presence of this method indicates that the numeric object is an integer type. Must return an integer. - .. note:: - - In order to have a coherent integer type class, when :meth:`__index__` is - defined :meth:`__int__` should also be defined, and both should return - the same value. + If :meth:`__int__`, :meth:`__float__` and :meth:`__complex__` are not + defined then corresponding built-in functions :func:`int`, :func:`float` + and :func:`complex` fall back to :meth:`__index__`. .. method:: object.__round__(self, [,ndigits]) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 4c5a9bb0cdb909..591b4548837264 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -250,6 +250,12 @@ Other Language Changes compatible with the existing :meth:`float.as_integer_ratio` method. (Contributed by Lisa Roach in :issue:`33073`.) +* Constructors of :class:`int`, :class:`float` and :class:`complex` will now + use the :meth:`~object.__index__` special method, if available and the + corresponding method :meth:`~object.__int__`, :meth:`~object.__float__` + or :meth:`~object.__complex__` is not available. + (Contributed by Serhiy Storchaka in :issue:`20092`.) + * Added support of ``\N{name}`` escapes in :mod:`regular expressions `. (Contributed by Jonathan Eunice and Serhiy Storchaka in :issue:`30688`.) @@ -868,7 +874,10 @@ Build and C API Changes ``__index__()`` method (like :class:`~decimal.Decimal` and :class:`~fractions.Fraction`). :c:func:`PyNumber_Check` will now return ``1`` for objects implementing ``__index__()``. - (Contributed by Serhiy Storchaka in :issue:`36048`.) + :c:func:`PyNumber_Long`, :c:func:`PyNumber_Float` and + :c:func:`PyFloat_AsDouble` also now use the ``__index__()`` method if + available. + (Contributed by Serhiy Storchaka in :issue:`36048` and :issue:`20092`.) * Heap-allocated type objects will now increase their reference count in :c:func:`PyObject_Init` (and its parallel macro ``PyObject_INIT``) diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index 43a074b4b66353..a00185f43dbf8d 100644 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -220,12 +220,11 @@ class NeitherComplexNorFloat(object): pass class NeitherComplexNorFloatOS: pass - class MyInt(object): + class Index: def __int__(self): return 2 def __index__(self): return 2 - class MyIntOS: + class MyInt: def __int__(self): return 2 - def __index__(self): return 2 # other possible combinations of __float__ and __complex__ # that should work @@ -255,6 +254,7 @@ def __float__(self): self.assertEqual(f(FloatAndComplexOS()), f(cx_arg)) self.assertEqual(f(JustFloat()), f(flt_arg)) self.assertEqual(f(JustFloatOS()), f(flt_arg)) + self.assertEqual(f(Index()), f(int(Index()))) # TypeError should be raised for classes not providing # either __complex__ or __float__, even if they provide # __int__ or __index__. An old-style class @@ -263,7 +263,6 @@ def __float__(self): self.assertRaises(TypeError, f, NeitherComplexNorFloat()) self.assertRaises(TypeError, f, MyInt()) self.assertRaises(Exception, f, NeitherComplexNorFloatOS()) - self.assertRaises(Exception, f, MyIntOS()) # non-complex return value from __complex__ -> TypeError for bad_complex in non_complexes: self.assertRaises(TypeError, f, MyComplex(bad_complex)) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 21c6eaed60540c..fe1e566562de49 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -368,6 +368,24 @@ def __float__(self): self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) self.assertRaises(TypeError, complex, float2(None)) + class MyIndex: + def __init__(self, value): + self.value = value + def __index__(self): + return self.value + + self.assertAlmostEqual(complex(MyIndex(42)), 42.0+0.0j) + self.assertAlmostEqual(complex(123, MyIndex(42)), 123.0+42.0j) + self.assertRaises(OverflowError, complex, MyIndex(2**2000)) + self.assertRaises(OverflowError, complex, 123, MyIndex(2**2000)) + + class MyInt: + def __int__(self): + return 42 + + self.assertRaises(TypeError, complex, MyInt()) + self.assertRaises(TypeError, complex, 123, MyInt()) + class complex0(complex): """Test usage of __complex__() when inheriting from 'complex'""" def __complex__(self): diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 5278d716de234d..b656582538e875 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -223,6 +223,21 @@ def __float__(self): with self.assertWarns(DeprecationWarning): self.assertIs(type(FloatSubclass(F())), FloatSubclass) + class MyIndex: + def __init__(self, value): + self.value = value + def __index__(self): + return self.value + + self.assertEqual(float(MyIndex(42)), 42.0) + self.assertRaises(OverflowError, float, MyIndex(2**2000)) + + class MyInt: + def __int__(self): + return 42 + + self.assertRaises(TypeError, float, MyInt()) + def test_keyword_args(self): with self.assertRaisesRegex(TypeError, 'keyword argument'): float(x='3.14') diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py index 07e2d151379182..1a73fa4615806d 100644 --- a/Lib/test/test_getargs2.py +++ b/Lib/test/test_getargs2.py @@ -457,6 +457,8 @@ def test_f(self): with self.assertWarns(DeprecationWarning): self.assertEqual(getargs_f(BadFloat2()), 4.25) self.assertEqual(getargs_f(BadFloat3(7.5)), 7.5) + self.assertEqual(getargs_f(Index()), 99.0) + self.assertRaises(TypeError, getargs_f, Int()) for x in (FLT_MIN, -FLT_MIN, FLT_MAX, -FLT_MAX, INF, -INF): self.assertEqual(getargs_f(x), x) @@ -489,6 +491,8 @@ def test_d(self): with self.assertWarns(DeprecationWarning): self.assertEqual(getargs_d(BadFloat2()), 4.25) self.assertEqual(getargs_d(BadFloat3(7.5)), 7.5) + self.assertEqual(getargs_d(Index()), 99.0) + self.assertRaises(TypeError, getargs_d, Int()) for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF): self.assertEqual(getargs_d(x), x) @@ -511,6 +515,8 @@ def test_D(self): with self.assertWarns(DeprecationWarning): self.assertEqual(getargs_D(BadComplex2()), 4.25+0.5j) self.assertEqual(getargs_D(BadComplex3(7.5+0.25j)), 7.5+0.25j) + self.assertEqual(getargs_D(Index()), 99.0+0j) + self.assertRaises(TypeError, getargs_D, Int()) for x in (DBL_MIN, -DBL_MIN, DBL_MAX, -DBL_MAX, INF, -INF): c = complex(x, 1.0) diff --git a/Lib/test/test_index.py b/Lib/test/test_index.py index a2ac32132e2343..cbdc56c801a4bd 100644 --- a/Lib/test/test_index.py +++ b/Lib/test/test_index.py @@ -60,7 +60,7 @@ def test_int_subclass_with_index(self): # subclasses. See issue #17576. class MyInt(int): def __index__(self): - return int(self) + 1 + return int(str(self)) + 1 my_int = MyInt(7) direct_index = my_int.__index__() diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index 307ca36bb4faf4..6fdf52ef23f65f 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -378,15 +378,23 @@ def __trunc__(self): int(ExceptionalTrunc()) for trunc_result_base in (object, Classic): - class Integral(trunc_result_base): - def __int__(self): + class Index(trunc_result_base): + def __index__(self): return 42 class TruncReturnsNonInt(base): def __trunc__(self): - return Integral() - with self.assertWarns(DeprecationWarning): - self.assertEqual(int(TruncReturnsNonInt()), 42) + return Index() + self.assertEqual(int(TruncReturnsNonInt()), 42) + + class Intable(trunc_result_base): + def __int__(self): + return 42 + + class TruncReturnsNonIndex(base): + def __trunc__(self): + return Intable() + self.assertEqual(int(TruncReturnsNonInt()), 42) class NonIntegral(trunc_result_base): def __trunc__(self): @@ -418,6 +426,21 @@ def __trunc__(self): with self.assertRaises(TypeError): int(TruncReturnsBadInt()) + def test_int_subclass_with_index(self): + class MyIndex(int): + def __index__(self): + return 42 + + class BadIndex(int): + def __index__(self): + return 42.0 + + my_int = MyIndex(7) + self.assertEqual(my_int, 7) + self.assertEqual(int(my_int), 7) + + self.assertEqual(int(BadIndex()), 0) + def test_int_subclass_with_int(self): class MyInt(int): def __int__(self): @@ -431,9 +454,19 @@ def __int__(self): self.assertEqual(my_int, 7) self.assertEqual(int(my_int), 42) - self.assertRaises(TypeError, int, BadInt()) + my_int = BadInt(7) + self.assertEqual(my_int, 7) + self.assertRaises(TypeError, int, my_int) def test_int_returns_int_subclass(self): + class BadIndex: + def __index__(self): + return True + + class BadIndex2(int): + def __index__(self): + return True + class BadInt: def __int__(self): return True @@ -442,6 +475,10 @@ class BadInt2(int): def __int__(self): return True + class TruncReturnsBadIndex: + def __trunc__(self): + return BadIndex() + class TruncReturnsBadInt: def __trunc__(self): return BadInt() @@ -450,6 +487,17 @@ class TruncReturnsIntSubclass: def __trunc__(self): return True + bad_int = BadIndex() + with self.assertWarns(DeprecationWarning): + n = int(bad_int) + self.assertEqual(n, 1) + self.assertIs(type(n), int) + + bad_int = BadIndex2() + n = int(bad_int) + self.assertEqual(n, 0) + self.assertIs(type(n), int) + bad_int = BadInt() with self.assertWarns(DeprecationWarning): n = int(bad_int) @@ -462,6 +510,12 @@ def __trunc__(self): self.assertEqual(n, 1) self.assertIs(type(n), int) + bad_int = TruncReturnsBadIndex() + with self.assertWarns(DeprecationWarning): + n = int(bad_int) + self.assertEqual(n, 1) + self.assertIs(type(n), int) + bad_int = TruncReturnsBadInt() with self.assertWarns(DeprecationWarning): n = int(bad_int) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst new file mode 100644 index 00000000000000..7536dc33c9f196 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst @@ -0,0 +1,4 @@ +Constructors of :class:`int`, :class:`float` and :class:`complex` will now +use the :meth:`~object.__index__` special method, if available and the +corresponding method :meth:`~object.__int__`, :meth:`~object.__float__` +or :meth:`~object.__complex__` is not available. diff --git a/Objects/abstract.c b/Objects/abstract.c index 68d06edfa60080..77d09143aa0764 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1373,6 +1373,13 @@ PyNumber_Long(PyObject *o) } return result; } + if (m && m->nb_index) { + result = _PyLong_FromNbIndexOrNbInt(o); + if (result != NULL && !PyLong_CheckExact(result)) { + Py_SETREF(result, _PyLong_Copy((PyLongObject *)result)); + } + return result; + } trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__); if (trunc_func) { result = _PyObject_CallNoArg(trunc_func); @@ -1480,6 +1487,18 @@ PyNumber_Float(PyObject *o) Py_DECREF(res); return PyFloat_FromDouble(val); } + if (m && m->nb_index) { + PyObject *res = PyNumber_Index(o); + if (!res) { + return NULL; + } + double val = PyLong_AsDouble(res); + Py_DECREF(res); + if (val == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(val); + } if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */ return PyFloat_FromDouble(PyFloat_AS_DOUBLE(o)); } diff --git a/Objects/complexobject.c b/Objects/complexobject.c index a5f95186d62575..f78c0fdf78def4 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -984,7 +984,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } nbr = r->ob_type->tp_as_number; - if (nbr == NULL || nbr->nb_float == NULL) { + if (nbr == NULL || (nbr->nb_float == NULL && nbr->nb_index == NULL)) { PyErr_Format(PyExc_TypeError, "complex() first argument must be a string or a number, " "not '%.200s'", @@ -996,7 +996,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } if (i != NULL) { nbi = i->ob_type->tp_as_number; - if (nbi == NULL || nbi->nb_float == NULL) { + if (nbi == NULL || (nbi->nb_float == NULL && nbi->nb_index == NULL)) { PyErr_Format(PyExc_TypeError, "complex() second argument must be a number, " "not '%.200s'", @@ -1052,7 +1052,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) /* The "imag" part really is entirely imaginary, and contributes nothing in the real direction. Just treat it as a double. */ - tmp = (*nbi->nb_float)(i); + tmp = PyNumber_Float(i); if (tmp == NULL) return NULL; ci.real = PyFloat_AsDouble(tmp); diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 2bf7061d4f62c5..15cbe5c9d8bae5 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -246,6 +246,15 @@ PyFloat_AsDouble(PyObject *op) nb = Py_TYPE(op)->tp_as_number; if (nb == NULL || nb->nb_float == NULL) { + if (nb && nb->nb_index) { + PyObject *res = PyNumber_Index(op); + if (!res) { + return -1; + } + double val = PyLong_AsDouble(res); + Py_DECREF(res); + return val; + } PyErr_Format(PyExc_TypeError, "must be real number, not %.50s", op->ob_type->tp_name); return -1; From 36dcaab7fde5d2e54cdeff5b705b5adcb27726dd Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Sat, 1 Jun 2019 15:07:46 -0600 Subject: [PATCH 253/441] Fix the error handling in bytesio_sizeof(). (GH-10459) bytesio_sizeof() must check if an error has occurred in _PySys_GetSizeOf(). --- Modules/_io/bytesio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 32427e44de5b1c..19e1ed8441e3f3 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -943,8 +943,13 @@ bytesio_sizeof(bytesio *self, void *unused) Py_ssize_t res; res = _PyObject_SIZE(Py_TYPE(self)); - if (self->buf && !SHARED_BUF(self)) - res += _PySys_GetSizeOf(self->buf); + if (self->buf && !SHARED_BUF(self)) { + Py_ssize_t s = _PySys_GetSizeOf(self->buf); + if (s == -1) { + return NULL; + } + res += s; + } return PyLong_FromSsize_t(res); } From 218e47b61862470477922e9aba1a23fd3dab18ae Mon Sep 17 00:00:00 2001 From: Marco Buttu Date: Sat, 1 Jun 2019 23:11:48 +0200 Subject: [PATCH 254/441] bpo-29414: Change 'the for statement is such an iterator' in Tutorial (GH-273) --- Doc/tutorial/controlflow.rst | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 81a28a6e53257f..79111f8518d9bb 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -139,18 +139,24 @@ but in fact it isn't. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn't really make the list, thus saving space. -We say such an object is *iterable*, that is, suitable as a target for +We say such an object is :term:`iterable`, that is, suitable as a target for functions and constructs that expect something from which they can -obtain successive items until the supply is exhausted. We have seen that -the :keyword:`for` statement is such an *iterator*. The function :func:`list` -is another; it creates lists from iterables:: +obtain successive items until the supply is exhausted. We have seen that +the :keyword:`for` statement is such a construct, while an example of function +that takes an iterable is :func:`sum`:: + >>> sum(range(4)) # 0 + 1 + 2 + 3 + 6 - >>> list(range(5)) - [0, 1, 2, 3, 4] +Later we will see more functions that return iterables and take iterables as +arguments. Lastly, maybe you are curious about how to get a list from a range. +Here is the solution:: -Later we will see more functions that return iterables and take iterables as argument. + >>> list(range(4)) + [0, 1, 2, 3] +In chapter :ref:`tut-structures`, we will discuss in more detail about +:func:`list`. .. _tut-break: @@ -161,7 +167,7 @@ The :keyword:`break` statement, like in C, breaks out of the innermost enclosing :keyword:`for` or :keyword:`while` loop. Loop statements may have an :keyword:`!else` clause; it is executed when the loop -terminates through exhaustion of the list (with :keyword:`for`) or when the +terminates through exhaustion of the iterable (with :keyword:`for`) or when the condition becomes false (with :keyword:`while`), but not when the loop is terminated by a :keyword:`break` statement. This is exemplified by the following loop, which searches for prime numbers:: @@ -188,8 +194,8 @@ following loop, which searches for prime numbers:: the :keyword:`for` loop, **not** the :keyword:`if` statement.) When used with a loop, the ``else`` clause has more in common with the -``else`` clause of a :keyword:`try` statement than it does that of -:keyword:`if` statements: a :keyword:`!try` statement's ``else`` clause runs +``else`` clause of a :keyword:`try` statement than it does with that of +:keyword:`if` statements: a :keyword:`try` statement's ``else`` clause runs when no exception occurs, and a loop's ``else`` clause runs when no ``break`` occurs. For more on the :keyword:`!try` statement and exceptions, see :ref:`tut-handling`. From 6a150bcaeb190d1731b38ab9c7a5d1a352847ddc Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Sat, 1 Jun 2019 15:39:46 -0600 Subject: [PATCH 255/441] bpo-33608: Factor out a private, per-interpreter _Py_AddPendingCall(). (gh-13714) --- Include/internal/pycore_ceval.h | 13 +- Include/internal/pycore_pystate.h | 12 +- Lib/test/test_capi.py | 2 +- .../2018-09-15-12-13-46.bpo-33608.avmvVP.rst | 5 + Modules/_testcapimodule.c | 1 + Modules/signalmodule.c | 12 +- Python/ceval.c | 336 +++++++++++------- Python/ceval_gil.h | 28 +- Python/pylifecycle.c | 29 +- Python/pystate.c | 68 ++-- 10 files changed, 320 insertions(+), 186 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 37170ed438f8bb..d44afdf4fa46a5 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -12,19 +12,22 @@ extern "C" { #include "pycore_pystate.h" #include "pythread.h" -PyAPI_FUNC(void) _Py_FinishPendingCalls(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *); PyAPI_FUNC(void) _PyEval_FiniThreads( - struct _ceval_runtime_state *ceval); + struct _ceval_runtime_state *); PyAPI_FUNC(void) _PyEval_SignalReceived( - struct _ceval_runtime_state *ceval); + struct _ceval_runtime_state *); PyAPI_FUNC(int) _PyEval_AddPendingCall( PyThreadState *tstate, - struct _ceval_runtime_state *ceval, + struct _ceval_runtime_state *, + struct _ceval_interpreter_state *, + unsigned long thread_id, int (*func)(void *), void *arg); +PyAPI_FUNC(void) _PyEval_FinishPendingCalls(PyInterpreterState *); PyAPI_FUNC(void) _PyEval_SignalAsyncExc( - struct _ceval_runtime_state *ceval); + struct _ceval_runtime_state *, + struct _ceval_interpreter_state *); PyAPI_FUNC(void) _PyEval_ReInitThreads( _PyRuntimeState *runtime); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 520a74b8a61fde..aca5533022e322 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -25,7 +25,7 @@ struct pyruntimestate; /* ceval state */ -struct _pending_calls { +struct _ceval_pending_calls { int finishing; PyThread_type_lock lock; /* Request for running pending calls. */ @@ -36,6 +36,7 @@ struct _pending_calls { int async_exc; #define NPENDINGCALLS 32 struct { + unsigned long thread_id; int (*func)(void *); void *arg; } calls[NPENDINGCALLS]; @@ -53,15 +54,21 @@ struct _ceval_runtime_state { int tracing_possible; /* This single variable consolidates all requests to break out of the fast path in the eval loop. */ + // XXX This can move to _ceval_interpreter_state once all parts + // from COMPUTE_EVAL_BREAKER have moved under PyInterpreterState. _Py_atomic_int eval_breaker; /* Request for dropping the GIL */ _Py_atomic_int gil_drop_request; - struct _pending_calls pending; /* Request for checking signals. */ _Py_atomic_int signals_pending; struct _gil_runtime_state gil; }; +struct _ceval_interpreter_state { + struct _ceval_pending_calls pending; +}; + + /* interpreter state */ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); @@ -136,6 +143,7 @@ struct _is { uint64_t tstate_next_unique_id; + struct _ceval_interpreter_state ceval; struct _warnings_runtime_state warnings; PyObject *audit_hooks; diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 4dd78bb9a2fd5f..fabc821e5c3ad8 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -431,7 +431,7 @@ def pendingcalls_wait(self, l, n, context = None): def test_pendingcalls_threaded(self): #do every callback on a separate thread - n = 32 #total callbacks + n = 32 #total callbacks (see NPENDINGCALLS in pycore_ceval.h) threads = [] class foo(object):pass context = foo() diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst new file mode 100644 index 00000000000000..73a01a1f46bdc1 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst @@ -0,0 +1,5 @@ +We added a new internal _Py_AddPendingCall() that operates relative to the +provided interpreter. This allows us to use the existing implementation to +ask another interpreter to do work that cannot be done in the current +interpreter, like decref an object the other interpreter owns. The existing +Py_AddPendingCall() only operates relative to the main interpreter. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b42f41cc8d8fd7..bf20e81a4ce888 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2677,6 +2677,7 @@ pending_threadfunc(PyObject *self, PyObject *arg) Py_INCREF(callable); Py_BEGIN_ALLOW_THREADS + /* XXX Use the internal _Py_AddPendingCall(). */ r = Py_AddPendingCall(&_pending_callback, callable); Py_END_ALLOW_THREADS diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 7698984ff3afe1..1964646da2522d 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -21,6 +21,7 @@ #include #endif #endif +#include "internal/pycore_pystate.h" #ifdef HAVE_SIGNAL_H #include @@ -259,6 +260,7 @@ trip_signal(int sig_num) /* Notify ceval.c */ _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = runtime->interpreters.main; _PyEval_SignalReceived(&runtime->ceval); /* And then write to the wakeup fd *after* setting all the globals and @@ -299,7 +301,10 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(tstate, &runtime->ceval, + _PyEval_AddPendingCall(tstate, + &runtime->ceval, + &interp->ceval, + runtime->main_thread, report_wakeup_send_error, (void *)(intptr_t) last_error); } @@ -318,7 +323,10 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(tstate, &runtime->ceval, + _PyEval_AddPendingCall(tstate, + &runtime->ceval, + &interp->ceval, + runtime->main_thread, report_wakeup_write_error, (void *)(intptr_t)errno); } diff --git a/Python/ceval.c b/Python/ceval.c index d9a71e942153ee..a092a235564136 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -101,66 +101,64 @@ static long dxp[256]; #endif #endif -#define GIL_REQUEST _Py_atomic_load_relaxed(&ceval->gil_drop_request) - /* This can set eval_breaker to 0 even though gil_drop_request became 1. We believe this is all right because the eval loop will release the GIL eventually anyway. */ -#define COMPUTE_EVAL_BREAKER(ceval) \ +#define COMPUTE_EVAL_BREAKER(ceval_r, ceval_i) \ _Py_atomic_store_relaxed( \ - &(ceval)->eval_breaker, \ - GIL_REQUEST | \ - _Py_atomic_load_relaxed(&(ceval)->signals_pending) | \ - _Py_atomic_load_relaxed(&(ceval)->pending.calls_to_do) | \ - (ceval)->pending.async_exc) + &(ceval_r)->eval_breaker, \ + _Py_atomic_load_relaxed(&(ceval_r)->gil_drop_request) | \ + _Py_atomic_load_relaxed(&(ceval_r)->signals_pending) | \ + _Py_atomic_load_relaxed(&(ceval_i)->pending.calls_to_do) | \ + (ceval_i)->pending.async_exc) -#define SET_GIL_DROP_REQUEST(ceval) \ +#define SET_GIL_DROP_REQUEST(ceval_r) \ do { \ - _Py_atomic_store_relaxed(&(ceval)->gil_drop_request, 1); \ - _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + _Py_atomic_store_relaxed(&(ceval_r)->gil_drop_request, 1); \ + _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ } while (0) -#define RESET_GIL_DROP_REQUEST(ceval) \ +#define RESET_GIL_DROP_REQUEST(ceval_r, ceval_i) \ do { \ - _Py_atomic_store_relaxed(&(ceval)->gil_drop_request, 0); \ - COMPUTE_EVAL_BREAKER(ceval); \ + _Py_atomic_store_relaxed(&(ceval_r)->gil_drop_request, 0); \ + COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ } while (0) /* Pending calls are only modified under pending_lock */ -#define SIGNAL_PENDING_CALLS(ceval) \ +#define SIGNAL_PENDING_CALLS(ceval_r, ceval_i) \ do { \ - _Py_atomic_store_relaxed(&(ceval)->pending.calls_to_do, 1); \ - _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + _Py_atomic_store_relaxed(&(ceval_i)->pending.calls_to_do, 1); \ + _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ } while (0) -#define UNSIGNAL_PENDING_CALLS(ceval) \ +#define UNSIGNAL_PENDING_CALLS(ceval_r, ceval_i) \ do { \ - _Py_atomic_store_relaxed(&(ceval)->pending.calls_to_do, 0); \ - COMPUTE_EVAL_BREAKER(ceval); \ + _Py_atomic_store_relaxed(&(ceval_i)->pending.calls_to_do, 0); \ + COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ } while (0) -#define SIGNAL_PENDING_SIGNALS(ceval) \ +#define SIGNAL_PENDING_SIGNALS(ceval_r) \ do { \ - _Py_atomic_store_relaxed(&(ceval)->signals_pending, 1); \ - _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + _Py_atomic_store_relaxed(&(ceval_r)->signals_pending, 1); \ + _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ } while (0) -#define UNSIGNAL_PENDING_SIGNALS(ceval) \ +#define UNSIGNAL_PENDING_SIGNALS(ceval_r, ceval_i) \ do { \ - _Py_atomic_store_relaxed(&(ceval)->signals_pending, 0); \ - COMPUTE_EVAL_BREAKER(ceval); \ + _Py_atomic_store_relaxed(&(ceval_r)->signals_pending, 0); \ + COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ } while (0) -#define SIGNAL_ASYNC_EXC(ceval) \ +#define SIGNAL_ASYNC_EXC(ceval_r, ceval_i) \ do { \ - (ceval)->pending.async_exc = 1; \ - _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ + (ceval_i)->pending.async_exc = 1; \ + _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ } while (0) -#define UNSIGNAL_ASYNC_EXC(ceval) \ +#define UNSIGNAL_ASYNC_EXC(ceval_r, ceval_i) \ do { \ - (ceval)->pending.async_exc = 0; \ - COMPUTE_EVAL_BREAKER(ceval); \ + (ceval_i)->pending.async_exc = 0; \ + COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ } while (0) @@ -180,8 +178,8 @@ void PyEval_InitThreads(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _gil_runtime_state *gil = &ceval->gil; + struct _ceval_runtime_state *ceval_r = &runtime->ceval; + struct _gil_runtime_state *gil = &ceval_r->gil; if (gil_created(gil)) { return; } @@ -189,19 +187,15 @@ PyEval_InitThreads(void) PyThread_init_thread(); create_gil(gil); PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - take_gil(ceval, tstate); + take_gil(ceval_r, tstate); - struct _pending_calls *pending = &ceval->pending; - pending->lock = PyThread_allocate_lock(); - if (pending->lock == NULL) { - Py_FatalError("Can't initialize threads for pending calls"); - } + // The pending calls mutex is initialized in PyInterpreterState_New(). } void -_PyEval_FiniThreads(struct _ceval_runtime_state *ceval) +_PyEval_FiniThreads(struct _ceval_runtime_state *ceval_r) { - struct _gil_runtime_state *gil = &ceval->gil; + struct _gil_runtime_state *gil = &ceval_r->gil; if (!gil_created(gil)) { return; } @@ -209,20 +203,24 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval) destroy_gil(gil); assert(!gil_created(gil)); - struct _pending_calls *pending = &ceval->pending; - if (pending->lock != NULL) { - PyThread_free_lock(pending->lock); - pending->lock = NULL; - } + // The pending calls mutex is freed in PyInterpreterState_Delete(). } static inline void exit_thread_if_finalizing(PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; - /* _Py_Finalizing is protected by the GIL */ + PyInterpreterState *interp = tstate->interp; + // Stop if thread/interpreter inalization already stated. + if (interp == NULL) { + return; + } + _PyRuntimeState *runtime = interp->runtime; + if (runtime == NULL) { + return; + } + // Don't exit if the main thread (i.e. of the main interpreter). if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { - drop_gil(&runtime->ceval, tstate); + drop_gil(&runtime->ceval, &interp->ceval, tstate); PyThread_exit_thread(); } } @@ -231,12 +229,12 @@ void PyEval_AcquireLock(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_runtime_state *ceval_r = &runtime->ceval; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); if (tstate == NULL) { Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); } - take_gil(ceval, tstate); + take_gil(ceval_r, tstate); exit_thread_if_finalizing(tstate); } @@ -244,12 +242,21 @@ void PyEval_ReleaseLock(void) { _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); /* This function must succeed when the current thread state is NULL. We therefore avoid PyThreadState_Get() which dumps a fatal error in debug mode. */ - drop_gil(&runtime->ceval, tstate); + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + // Fall back to the main interpreter if there is not active Python + // thread. This only affects the eval_breaker. + PyInterpreterState *interp = runtime->interpreters.main; + if (tstate != NULL) { + interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("PyEval_ReleaseLock: NULL interpreter state"); + } + } + drop_gil(&runtime->ceval, &interp->ceval, tstate); } void @@ -258,14 +265,19 @@ PyEval_AcquireThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_AcquireThread: NULL new thread state"); } - assert(tstate->interp != NULL); - - _PyRuntimeState *runtime = tstate->interp->runtime; - struct _ceval_runtime_state *ceval = &runtime->ceval; + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("PyEval_AcquireThread: NULL interpreter state"); + } + _PyRuntimeState *runtime = interp->runtime; + if (runtime == NULL) { + Py_FatalError("PyEval_AcquireThread: NULL runtime state"); + } + struct _ceval_runtime_state *ceval_r = &runtime->ceval; /* Check someone has called PyEval_InitThreads() to create the lock */ - assert(gil_created(&ceval->gil)); - take_gil(ceval, tstate); + assert(gil_created(&ceval_r->gil)); + take_gil(ceval_r, tstate); exit_thread_if_finalizing(tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); @@ -278,14 +290,20 @@ PyEval_ReleaseThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_ReleaseThread: NULL thread state"); } - assert(tstate->interp != NULL); + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("PyEval_ReleaseThread: NULL interpreter state"); + } + _PyRuntimeState *runtime = interp->runtime; + if (runtime == NULL) { + Py_FatalError("PyEval_ReleaseThread: NULL runtime state"); + } - _PyRuntimeState *runtime = tstate->interp->runtime; PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (new_tstate != tstate) { Py_FatalError("PyEval_ReleaseThread: wrong thread state"); } - drop_gil(&runtime->ceval, tstate); + drop_gil(&runtime->ceval, &interp->ceval, tstate); } /* This function is called from PyOS_AfterFork_Child to destroy all threads @@ -296,15 +314,17 @@ PyEval_ReleaseThread(PyThreadState *tstate) void _PyEval_ReInitThreads(_PyRuntimeState *runtime) { - struct _ceval_runtime_state *ceval = &runtime->ceval; - if (!gil_created(&ceval->gil)) { + struct _ceval_runtime_state *ceval_r = &runtime->ceval; + if (!gil_created(&ceval_r->gil)) { return; } - recreate_gil(&ceval->gil); + recreate_gil(&ceval_r->gil); PyThreadState *current_tstate = _PyRuntimeState_GetThreadState(runtime); - take_gil(ceval, current_tstate); + take_gil(ceval_r, current_tstate); - struct _pending_calls *pending = &ceval->pending; + // Only the main interpreter remains, so ignore the rest. + PyInterpreterState *interp = _PyRuntime.interpreters.main; + struct _ceval_pending_calls *pending = &interp->ceval.pending; pending->lock = PyThread_allocate_lock(); if (pending->lock == NULL) { Py_FatalError("Can't initialize threads for pending calls"); @@ -318,22 +338,28 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) raised. */ void -_PyEval_SignalAsyncExc(struct _ceval_runtime_state *ceval) +_PyEval_SignalAsyncExc(struct _ceval_runtime_state *ceval_r, + struct _ceval_interpreter_state *ceval_i) { - SIGNAL_ASYNC_EXC(ceval); + SIGNAL_ASYNC_EXC(ceval_r, ceval_i); } PyThreadState * PyEval_SaveThread(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_runtime_state *ceval_r = &runtime->ceval; PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (tstate == NULL) { Py_FatalError("PyEval_SaveThread: NULL tstate"); } - assert(gil_created(&ceval->gil)); - drop_gil(ceval, tstate); + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("PyEval_SaveThread: NULL interpreter state"); + } + + assert(gil_created(&ceval_r->gil)); + drop_gil(ceval_r, &interp->ceval, tstate); return tstate; } @@ -343,14 +369,20 @@ PyEval_RestoreThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_RestoreThread: NULL tstate"); } - assert(tstate->interp != NULL); + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("PyEval_RestoreThread: NULL interpreter state"); + } + _PyRuntimeState *runtime = interp->runtime; + if (runtime == NULL) { + Py_FatalError("PyEval_RestoreThread: NULL runtime state"); + } + struct _ceval_runtime_state *ceval_r = &runtime->ceval; - _PyRuntimeState *runtime = tstate->interp->runtime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - assert(gil_created(&ceval->gil)); + assert(gil_created(&ceval_r->gil)); int err = errno; - take_gil(ceval, tstate); + take_gil(ceval_r, tstate); exit_thread_if_finalizing(tstate); errno = err; @@ -381,17 +413,17 @@ PyEval_RestoreThread(PyThreadState *tstate) */ void -_PyEval_SignalReceived(struct _ceval_runtime_state *ceval) +_PyEval_SignalReceived(struct _ceval_runtime_state *ceval_r) { /* bpo-30703: Function called when the C signal handler of Python gets a signal. We cannot queue a callback using Py_AddPendingCall() since that function is not async-signal-safe. */ - SIGNAL_PENDING_SIGNALS(ceval); + SIGNAL_PENDING_SIGNALS(ceval_r); } /* Push one item onto the queue while holding the lock. */ static int -_push_pending_call(struct _pending_calls *pending, +_push_pending_call(struct _ceval_pending_calls *pending, unsigned long thread_id, int (*func)(void *), void *arg) { int i = pending->last; @@ -399,6 +431,7 @@ _push_pending_call(struct _pending_calls *pending, if (j == pending->first) { return -1; /* Queue full */ } + pending->calls[i].thread_id = thread_id; pending->calls[i].func = func; pending->calls[i].arg = arg; pending->last = j; @@ -407,7 +440,7 @@ _push_pending_call(struct _pending_calls *pending, /* Pop one item off the queue while holding the lock. */ static void -_pop_pending_call(struct _pending_calls *pending, +_pop_pending_call(struct _ceval_pending_calls *pending, unsigned long *thread_id, int (**func)(void *), void **arg) { int i = pending->first; @@ -417,6 +450,7 @@ _pop_pending_call(struct _pending_calls *pending, *func = pending->calls[i].func; *arg = pending->calls[i].arg; + *thread_id = pending->calls[i].thread_id; pending->first = (i + 1) % NPENDINGCALLS; } @@ -427,10 +461,12 @@ _pop_pending_call(struct _pending_calls *pending, int _PyEval_AddPendingCall(PyThreadState *tstate, - struct _ceval_runtime_state *ceval, + struct _ceval_runtime_state *ceval_r, + struct _ceval_interpreter_state *ceval_i, + unsigned long thread_id, int (*func)(void *), void *arg) { - struct _pending_calls *pending = &ceval->pending; + struct _ceval_pending_calls *pending = &ceval_i->pending; PyThread_acquire_lock(pending->lock, WAIT_LOCK); if (pending->finishing) { @@ -445,20 +481,27 @@ _PyEval_AddPendingCall(PyThreadState *tstate, _PyErr_Restore(tstate, exc, val, tb); return -1; } - int result = _push_pending_call(pending, func, arg); + int result = _push_pending_call(pending, thread_id, func, arg); + + /* signal loop */ + SIGNAL_PENDING_CALLS(ceval_r, ceval_i); PyThread_release_lock(pending->lock); - /* signal main loop */ - SIGNAL_PENDING_CALLS(ceval); return result; } +/* Py_AddPendingCall() is a simple wrapper for the sake + of backward-compatibility. */ int Py_AddPendingCall(int (*func)(void *), void *arg) { _PyRuntimeState *runtime = &_PyRuntime; + PyInterpreterState *interp = runtime->interpreters.main; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - return _PyEval_AddPendingCall(tstate, &runtime->ceval, func, arg); + return _PyEval_AddPendingCall(tstate, + &runtime->ceval, &interp->ceval, + runtime->main_thread, + func, arg); } static int @@ -479,47 +522,69 @@ handle_signals(_PyRuntimeState *runtime) return 0; } - struct _ceval_runtime_state *ceval = &runtime->ceval; - UNSIGNAL_PENDING_SIGNALS(ceval); + struct _ceval_runtime_state *ceval_r = &runtime->ceval; + struct _ceval_interpreter_state *ceval_i = &interp->ceval; + UNSIGNAL_PENDING_SIGNALS(ceval_r, ceval_i); if (_PyErr_CheckSignals() < 0) { - SIGNAL_PENDING_SIGNALS(ceval); /* We're not done yet */ + SIGNAL_PENDING_SIGNALS(ceval_r); /* We're not done yet */ return -1; } return 0; } static int -make_pending_calls(_PyRuntimeState *runtime) +make_pending_calls(PyInterpreterState *interp) { - static int busy = 0; - - /* only service pending calls on main thread */ - if (PyThread_get_thread_ident() != runtime->main_thread) { - return 0; + if (interp == NULL) { + Py_FatalError("make_pending_calls: NULL interpreter state"); + } + _PyRuntimeState *runtime = interp->runtime; + if (runtime == NULL) { + Py_FatalError("make_pending_calls: NULL runtime state"); + } + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + if (tstate == NULL) { + Py_FatalError("make_pending_calls: NULL thread state"); } + if (tstate->interp == NULL || tstate->interp != interp) { + Py_FatalError("make_pending_calls: thread state mismatch"); + } + static int busy = 0; /* don't perform recursive pending calls */ if (busy) { return 0; } busy = 1; - struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_runtime_state *ceval_r = &runtime->ceval; + struct _ceval_interpreter_state *ceval_i = &interp->ceval; /* unsignal before starting to call callbacks, so that any callback added in-between re-signals */ - UNSIGNAL_PENDING_CALLS(ceval); + UNSIGNAL_PENDING_CALLS(ceval_r, ceval_i); int res = 0; /* perform a bounded number of calls, in case of recursion */ - struct _pending_calls *pending = &ceval->pending; + struct _ceval_pending_calls *pending = &ceval_i->pending; + unsigned long thread_id = 0; for (int i=0; ilock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); + _pop_pending_call(pending, &thread_id, &func, &arg); PyThread_release_lock(pending->lock); + if (thread_id && PyThread_get_thread_ident() != thread_id) { + // Thread mismatch, so move it to the end of the list + // and start over. + _PyEval_AddPendingCall(tstate, + &runtime->ceval, &interp->ceval, + thread_id, + func, arg); + goto error; + } + /* having released the lock, perform the callback */ if (func == NULL) { break; @@ -535,17 +600,16 @@ make_pending_calls(_PyRuntimeState *runtime) error: busy = 0; - SIGNAL_PENDING_CALLS(ceval); + SIGNAL_PENDING_CALLS(ceval_r, ceval_i); return res; } void -_Py_FinishPendingCalls(_PyRuntimeState *runtime) +_PyEval_FinishPendingCalls(PyInterpreterState *interp) { assert(PyGILState_Check()); - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - struct _pending_calls *pending = &runtime->ceval.pending; + struct _ceval_pending_calls *pending = &interp->ceval.pending; PyThread_acquire_lock(pending->lock, WAIT_LOCK); pending->finishing = 1; @@ -555,12 +619,19 @@ _Py_FinishPendingCalls(_PyRuntimeState *runtime) return; } - if (make_pending_calls(runtime) < 0) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - PyErr_BadInternalCall(); - _PyErr_ChainExceptions(exc, val, tb); - _PyErr_Print(tstate); + if (make_pending_calls(interp) < 0) { + _PyRuntimeState *runtime = interp->runtime; + if (runtime == NULL) { + runtime = &_PyRuntime; + } + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + if (tstate != NULL) { + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + PyErr_BadInternalCall(); + _PyErr_ChainExceptions(exc, val, tb); + _PyErr_Print(tstate); + } } } @@ -579,7 +650,8 @@ Py_MakePendingCalls(void) return res; } - res = make_pending_calls(runtime); + PyInterpreterState *interp = _PyRuntime.interpreters.main; + res = make_pending_calls(interp); if (res != 0) { return res; } @@ -596,11 +668,11 @@ Py_MakePendingCalls(void) int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; void -_PyEval_Initialize(struct _ceval_runtime_state *state) +_PyEval_Initialize(struct _ceval_runtime_state *ceval_r) { - state->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; + ceval_r->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; - _gil_initialize(&state->gil); + _gil_initialize(&ceval_r->gil); } int @@ -612,9 +684,9 @@ Py_GetRecursionLimit(void) void Py_SetRecursionLimit(int new_limit) { - struct _ceval_runtime_state *ceval = &_PyRuntime.ceval; - ceval->recursion_limit = new_limit; - _Py_CheckRecursionLimit = ceval->recursion_limit; + struct _ceval_runtime_state *ceval_r = &_PyRuntime.ceval; + ceval_r->recursion_limit = new_limit; + _Py_CheckRecursionLimit = ceval_r->recursion_limit; } /* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() @@ -663,7 +735,7 @@ _Py_CheckRecursiveCall(const char *where) static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); -#define _Py_TracingPossible(ceval) ((ceval)->tracing_possible) +#define _Py_TracingPossible(ceval_r) ((ceval_r)->tracing_possible) PyObject * @@ -709,8 +781,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *retval = NULL; /* Return value */ _PyRuntimeState * const runtime = &_PyRuntime; PyThreadState * const tstate = _PyRuntimeState_GetThreadState(runtime); - struct _ceval_runtime_state * const ceval = &runtime->ceval; - _Py_atomic_int * const eval_breaker = &ceval->eval_breaker; + PyInterpreterState * const interp = tstate->interp; + struct _ceval_runtime_state * const ceval_r = &runtime->ceval; + struct _ceval_interpreter_state * const ceval_i = &interp->ceval; + _Py_atomic_int * const eval_breaker = &ceval_r->eval_breaker; PyCodeObject *co; /* when tracing we set things up so that @@ -797,7 +871,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) #ifdef LLTRACE #define FAST_DISPATCH() \ { \ - if (!lltrace && !_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \ + if (!lltrace && !_Py_TracingPossible(ceval_r) && !PyDTrace_LINE_ENABLED()) { \ f->f_lasti = INSTR_OFFSET(); \ NEXTOPARG(); \ goto *opcode_targets[opcode]; \ @@ -807,7 +881,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) #else #define FAST_DISPATCH() \ { \ - if (!_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \ + if (!_Py_TracingPossible(ceval_r) && !PyDTrace_LINE_ENABLED()) { \ f->f_lasti = INSTR_OFFSET(); \ NEXTOPARG(); \ goto *opcode_targets[opcode]; \ @@ -1122,27 +1196,27 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) goto fast_next_opcode; } - if (_Py_atomic_load_relaxed(&ceval->signals_pending)) { + if (_Py_atomic_load_relaxed(&ceval_r->signals_pending)) { if (handle_signals(runtime) != 0) { goto error; } } - if (_Py_atomic_load_relaxed(&ceval->pending.calls_to_do)) { - if (make_pending_calls(runtime) != 0) { + if (_Py_atomic_load_relaxed(&ceval_i->pending.calls_to_do)) { + if (make_pending_calls(interp) != 0) { goto error; } } - if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { + if (_Py_atomic_load_relaxed(&ceval_r->gil_drop_request)) { /* Give another thread a chance */ if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { Py_FatalError("ceval: tstate mix-up"); } - drop_gil(ceval, tstate); + drop_gil(ceval_r, ceval_i, tstate); /* Other threads may run now */ - take_gil(ceval, tstate); + take_gil(ceval_r, tstate); /* Check if we should make a quick exit. */ exit_thread_if_finalizing(tstate); @@ -1155,7 +1229,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (tstate->async_exc != NULL) { PyObject *exc = tstate->async_exc; tstate->async_exc = NULL; - UNSIGNAL_ASYNC_EXC(ceval); + UNSIGNAL_ASYNC_EXC(ceval_r, ceval_i); _PyErr_SetNone(tstate, exc); Py_DECREF(exc); goto error; @@ -1170,7 +1244,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* line-by-line tracing support */ - if (_Py_TracingPossible(ceval) && + if (_Py_TracingPossible(ceval_r) && tstate->c_tracefunc != NULL && !tstate->tracing) { int err; /* see maybe_call_line_trace diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h index 34d48c990c4479..b44d0abad36b13 100644 --- a/Python/ceval_gil.h +++ b/Python/ceval_gil.h @@ -141,9 +141,11 @@ static void recreate_gil(struct _gil_runtime_state *gil) } static void -drop_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) +drop_gil(struct _ceval_runtime_state *ceval_r, + struct _ceval_interpreter_state *ceval_i, + PyThreadState *tstate) { - struct _gil_runtime_state *gil = &ceval->gil; + struct _gil_runtime_state *gil = &ceval_r->gil; if (!_Py_atomic_load_relaxed(&gil->locked)) { Py_FatalError("drop_gil: GIL is not locked"); } @@ -163,12 +165,12 @@ drop_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) MUTEX_UNLOCK(gil->mutex); #ifdef FORCE_SWITCHING - if (_Py_atomic_load_relaxed(&ceval->gil_drop_request) && tstate != NULL) { + if (_Py_atomic_load_relaxed(&ceval_r->gil_drop_request) && tstate != NULL) { MUTEX_LOCK(gil->switch_mutex); /* Not switched yet => wait */ if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) { - RESET_GIL_DROP_REQUEST(ceval); + RESET_GIL_DROP_REQUEST(ceval_r, ceval_i); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take the GIL and drop it again, and reset the condition @@ -181,13 +183,19 @@ drop_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) } static void -take_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) +take_gil(struct _ceval_runtime_state *ceval_r, + PyThreadState *tstate) { if (tstate == NULL) { Py_FatalError("take_gil: NULL tstate"); } + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("take_gil: NULL interp"); + } + struct _ceval_interpreter_state *ceval_i = &interp->ceval; - struct _gil_runtime_state *gil = &ceval->gil; + struct _gil_runtime_state *gil = &ceval_r->gil; int err = errno; MUTEX_LOCK(gil->mutex); @@ -210,7 +218,7 @@ take_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) _Py_atomic_load_relaxed(&gil->locked) && gil->switch_number == saved_switchnum) { - SET_GIL_DROP_REQUEST(ceval); + SET_GIL_DROP_REQUEST(ceval_r); } } _ready: @@ -232,11 +240,11 @@ take_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) COND_SIGNAL(gil->switch_cond); MUTEX_UNLOCK(gil->switch_mutex); #endif - if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { - RESET_GIL_DROP_REQUEST(ceval); + if (_Py_atomic_load_relaxed(&ceval_r->gil_drop_request)) { + RESET_GIL_DROP_REQUEST(ceval_r, ceval_i); } if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(ceval); + _PyEval_SignalAsyncExc(ceval_r, ceval_i); } MUTEX_UNLOCK(gil->mutex); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 6590ef8e9a27a0..3de5528811ae16 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1147,15 +1147,31 @@ Py_FinalizeEx(void) return status; } + /* Get current thread state and interpreter pointer */ + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = tstate->interp; + // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(); // Make any remaining pending calls. - _Py_FinishPendingCalls(runtime); - - /* Get current thread state and interpreter pointer */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - PyInterpreterState *interp = tstate->interp; + /* XXX For the moment we are going to ignore lingering pending calls. + * We've seen sporadic on some of the buildbots during finalization + * with the changes for per-interpreter pending calls (see bpo-33608), + * meaning the previous _PyEval_FinishPendincCalls() call here is + * a trigger, if not responsible. + * + * Ignoring pending calls at this point in the runtime lifecycle + * is okay (for now) for the following reasons: + * + * * pending calls are still not a widely-used feature + * * this only affects runtime finalization, where the process is + * likely to end soon anyway (except for some embdding cases) + * + * See bpo-37127 about resolving the problem. Ultimately the call + * here should be re-enabled. + */ + //_PyEval_FinishPendingCalls(interp); /* The interpreter is still entirely intact at this point, and the * exit funcs may be relying on that. In particular, if some thread @@ -1580,6 +1596,9 @@ Py_EndInterpreter(PyThreadState *tstate) // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(); + // Make any remaining pending calls. + _PyEval_FinishPendingCalls(interp); + call_py_exitfuncs(interp); if (tstate != interp->tstate_head || tstate->next != NULL) diff --git a/Python/pystate.c b/Python/pystate.c index 2b7db0e48debe9..a9f3389a0d833e 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -218,6 +218,13 @@ PyInterpreterState_New(void) return NULL; } + interp->ceval.pending.lock = PyThread_allocate_lock(); + if (interp->ceval.pending.lock == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "failed to create interpreter ceval pending mutex"); + return NULL; + } + interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN #if HAVE_DECL_RTLD_NOW @@ -345,6 +352,10 @@ PyInterpreterState_Delete(PyInterpreterState *interp) if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } + if (interp->ceval.pending.lock != NULL) { + PyThread_free_lock(interp->ceval.pending.lock); + interp->ceval.pending.lock = NULL; + } PyMem_RawFree(interp); } @@ -1014,7 +1025,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) p->async_exc = exc; HEAD_UNLOCK(runtime); Py_XDECREF(old_exc); - _PyEval_SignalAsyncExc(&runtime->ceval); + _PyEval_SignalAsyncExc(&runtime->ceval, &interp->ceval); return 1; } } @@ -1444,7 +1455,7 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) return 0; } -static void +static int _release_xidata(void *arg) { _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; @@ -1452,42 +1463,21 @@ _release_xidata(void *arg) data->free(data->data); } Py_XDECREF(data->obj); -} - -static void -_call_in_interpreter(struct _gilstate_runtime_state *gilstate, - PyInterpreterState *interp, - void (*func)(void *), void *arg) -{ - /* We would use Py_AddPendingCall() if it weren't specific to the - * main interpreter (see bpo-33608). In the meantime we take a - * naive approach. - */ - PyThreadState *save_tstate = NULL; - if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) { - // XXX Using the "head" thread isn't strictly correct. - PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); - // XXX Possible GILState issues? - save_tstate = _PyThreadState_Swap(gilstate, tstate); - } - - func(arg); - - // Switch back. - if (save_tstate != NULL) { - _PyThreadState_Swap(gilstate, save_tstate); - } + PyMem_Free(data); + return 0; } void _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) { + _PyRuntimeState *runtime = &_PyRuntime; + if (data->data == NULL && data->obj == NULL) { // Nothing to release! return; } - // Switch to the original interpreter. + // Get the original interpreter. PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); if (interp == NULL) { // The intepreter was already destroyed. @@ -1496,10 +1486,28 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) } return; } + // XXX There's an ever-so-slight race here... + if (interp->finalizing) { + // XXX Someone leaked some memory... + return; + } // "Release" the data and/or the object. - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - _call_in_interpreter(gilstate, interp, _release_xidata, data); + _PyCrossInterpreterData *copied = PyMem_Malloc(sizeof(_PyCrossInterpreterData)); + if (copied == NULL) { + PyErr_SetString(PyExc_MemoryError, + "Not enough memory to preserve cross-interpreter data"); + PyErr_Print(); + return; + } + memcpy(copied, data, sizeof(_PyCrossInterpreterData)); + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + int res = _PyEval_AddPendingCall(tstate, + &runtime->ceval, &interp->ceval, + 0, _release_xidata, copied); + if (res != 0) { + // XXX Queue full or couldn't get lock. Try again somehow? + } } PyObject * From b7fade4f87e0d37d1686a4e8596141e55ecef099 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 1 Jun 2019 15:01:46 -0700 Subject: [PATCH 256/441] Put math.comb() docs is correct place alphabetically (GH-13734) --- Doc/library/math.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 206b06edd2a206..8c6837050319c6 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -36,6 +36,21 @@ Number-theoretic and representation functions :class:`~numbers.Integral` value. +.. function:: comb(n, k) + + Return the number of ways to choose *k* items from *n* items without repetition + and without order. + + Also called the binomial coefficient. It is mathematically equal to the expression + ``n! / (k! (n - k)!)``. It is equivalent to the coefficient of the *k*-th term in the + polynomial expansion of the expression ``(1 + x) ** n``. + + Raises :exc:`TypeError` if the arguments not integers. + Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*. + + .. versionadded:: 3.8 + + .. function:: copysign(x, y) Return a float with the magnitude (absolute value) of *x* but the sign of @@ -232,21 +247,6 @@ Number-theoretic and representation functions :meth:`x.__trunc__() `. -.. function:: comb(n, k) - - Return the number of ways to choose *k* items from *n* items without repetition - and without order. - - Also called the binomial coefficient. It is mathematically equal to the expression - ``n! / (k! (n - k)!)``. It is equivalent to the coefficient of the *k*-th term in the - polynomial expansion of the expression ``(1 + x) ** n``. - - Raises :exc:`TypeError` if the arguments not integers. - Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*. - - .. versionadded:: 3.8 - - Note that :func:`frexp` and :func:`modf` have a different call/return pattern than their C equivalents: they take a single argument and return a pair of values, rather than returning their second return value through an 'output From b7daabd711274a009e70556020efeae502a85f0b Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 1 Jun 2019 17:13:26 -0700 Subject: [PATCH 257/441] Improve version added references in `typing` module docs (GH-13457) --- Doc/library/typing.rst | 22 +++++++++++++++---- .../2019-05-20-22-21-17.bpo-36984.IjZlmS.rst | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 2575a995817d73..1a766c29a57a53 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -637,7 +637,7 @@ The module defines the following classes, functions and decorators: A generic version of :class:`collections.abc.Collection` - .. versionadded:: 3.6 + .. versionadded:: 3.6.0 .. class:: AbstractSet(Sized, Collection[T_co]) @@ -681,6 +681,7 @@ The module defines the following classes, functions and decorators: A generic version of :class:`collections.deque`. + .. versionadded:: 3.5.4 .. versionadded:: 3.6.1 .. class:: List(list, MutableSequence[T]) @@ -730,6 +731,8 @@ The module defines the following classes, functions and decorators: A generic version of :class:`collections.abc.Awaitable`. + .. versionadded:: 3.5.2 + .. class:: Coroutine(Awaitable[V_co], Generic[T_co T_contra, V_co]) A generic version of :class:`collections.abc.Coroutine`. @@ -743,25 +746,33 @@ The module defines the following classes, functions and decorators: async def bar() -> None: x = await c # type: int + .. versionadded:: 3.5.3 + .. class:: AsyncIterable(Generic[T_co]) A generic version of :class:`collections.abc.AsyncIterable`. + .. versionadded:: 3.5.2 + .. class:: AsyncIterator(AsyncIterable[T_co]) A generic version of :class:`collections.abc.AsyncIterator`. + .. versionadded:: 3.5.2 + .. class:: ContextManager(Generic[T_co]) A generic version of :class:`contextlib.AbstractContextManager`. - .. versionadded:: 3.6 + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.0 .. class:: AsyncContextManager(Generic[T_co]) A generic version of :class:`contextlib.AbstractAsyncContextManager`. - .. versionadded:: 3.6 + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.2 .. class:: Dict(dict, MutableMapping[KT, VT]) @@ -790,12 +801,14 @@ The module defines the following classes, functions and decorators: A generic version of :class:`collections.Counter`. + .. versionadded:: 3.5.4 .. versionadded:: 3.6.1 .. class:: ChainMap(collections.ChainMap, MutableMapping[KT, VT]) A generic version of :class:`collections.ChainMap`. + .. versionadded:: 3.5.4 .. versionadded:: 3.6.1 .. class:: Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]) @@ -860,7 +873,7 @@ The module defines the following classes, functions and decorators: yield start start = await increment(start) - .. versionadded:: 3.5.4 + .. versionadded:: 3.6.1 .. class:: Text @@ -1166,6 +1179,7 @@ The module defines the following classes, functions and decorators: raise RuntimeError('no way') .. versionadded:: 3.5.4 + .. versionadded:: 3.6.2 .. data:: Union diff --git a/Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst b/Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst new file mode 100644 index 00000000000000..b26eeadb924aa9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst @@ -0,0 +1 @@ +Improve version added references in ``typing`` module - by Anthony Sottile. From d71f3170ac9c850f6d1f9bffaa628dc473df5e75 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 2 Jun 2019 09:03:59 +0300 Subject: [PATCH 258/441] Add more tests for preserving identity in marshal. (GH-13736) --- Lib/test/test_marshal.py | 69 +++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index a3bd350c77b95b..ace1593999d4eb 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -383,10 +383,7 @@ def CollectObjectIDs(ids, obj): return len(ids) class InstancingTestCase(unittest.TestCase, HelperMixin): - intobj = 123321 - floatobj = 1.2345 - strobj = "abcde"*3 - dictobj = {"hello":floatobj, "goodbye":floatobj, floatobj:"hello"} + keys = (123, 1.2345, 'abc', (123, 'abc'), frozenset({123, 'abc'})) def helper3(self, rsample, recursive=False, simple=False): #we have two instances @@ -394,11 +391,12 @@ def helper3(self, rsample, recursive=False, simple=False): n0 = CollectObjectIDs(set(), sample) - s3 = marshal.dumps(sample, 3) - n3 = CollectObjectIDs(set(), marshal.loads(s3)) + for v in range(3, marshal.version + 1): + s3 = marshal.dumps(sample, v) + n3 = CollectObjectIDs(set(), marshal.loads(s3)) - #same number of instances generated - self.assertEqual(n3, n0) + #same number of instances generated + self.assertEqual(n3, n0) if not recursive: #can compare with version 2 @@ -414,20 +412,54 @@ def helper3(self, rsample, recursive=False, simple=False): self.assertGreaterEqual(len(s2), len(s3)) def testInt(self): - self.helper(self.intobj) - self.helper3(self.intobj, simple=True) + intobj = 123321 + self.helper(intobj) + self.helper3(intobj, simple=True) def testFloat(self): - self.helper(self.floatobj) - self.helper3(self.floatobj) + floatobj = 1.2345 + self.helper(floatobj) + self.helper3(floatobj) def testStr(self): - self.helper(self.strobj) - self.helper3(self.strobj) + strobj = "abcde"*3 + self.helper(strobj) + self.helper3(strobj) + + def testBytes(self): + bytesobj = b"abcde"*3 + self.helper(bytesobj) + self.helper3(bytesobj) + + def testList(self): + for obj in self.keys: + listobj = [obj, obj] + self.helper(listobj) + self.helper3(listobj) + + def testTuple(self): + for obj in self.keys: + tupleobj = (obj, obj) + self.helper(tupleobj) + self.helper3(tupleobj) + + def testSet(self): + for obj in self.keys: + setobj = {(obj, 1), (obj, 2)} + self.helper(setobj) + self.helper3(setobj) + + def testFrozenSet(self): + for obj in self.keys: + frozensetobj = frozenset({(obj, 1), (obj, 2)}) + self.helper(frozensetobj) + self.helper3(frozensetobj) def testDict(self): - self.helper(self.dictobj) - self.helper3(self.dictobj) + for obj in self.keys: + dictobj = {"hello": obj, "goodbye": obj, obj: "hello"} + self.helper(dictobj) + self.helper3(dictobj) def testModule(self): with open(__file__, "rb") as f: @@ -438,10 +470,11 @@ def testModule(self): self.helper3(code) def testRecursion(self): - d = dict(self.dictobj) + obj = 1.2345 + d = {"hello": obj, "goodbye": obj, obj: "hello"} d["self"] = d self.helper3(d, recursive=True) - l = [self.dictobj] + l = [obj, obj] l.append(l) self.helper3(l, recursive=True) From 5ae299ac78abb628803ab7dee0997364547f5cc8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 2 Jun 2019 11:16:49 +0300 Subject: [PATCH 259/441] bpo-37128: Add math.perm(). (GH-13731) --- Doc/library/math.rst | 13 ++ Lib/test/test_math.py | 66 ++++++++- .../2019-06-01-22-54-03.bpo-37128.oGXBWN.rst | 1 + Modules/clinic/mathmodule.c.h | 37 ++++- Modules/mathmodule.c | 130 +++++++++++++++++- 5 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 8c6837050319c6..c5a77f1fab9fd6 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -207,6 +207,19 @@ Number-theoretic and representation functions of *x* and are floats. +.. function:: perm(n, k) + + Return the number of ways to choose *k* items from *n* items + without repetition and with order. + + It is mathematically equal to the expression ``n! / (n - k)!``. + + Raises :exc:`TypeError` if the arguments not integers. + Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*. + + .. versionadded:: 3.8 + + .. function:: prod(iterable, *, start=1) Calculate the product of all the elements in the input *iterable*. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index e27092eefd6ed7..96e0cf2fe67197 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -240,6 +240,9 @@ def result_check(expected, got, ulp_tol=5, abs_tol=0.0): else: return None +class IntSubclass(int): + pass + # Class providing an __index__ method. class MyIndexable(object): def __init__(self, value): @@ -1862,6 +1865,64 @@ def test_fractions(self): self.assertAllClose(fraction_examples, rel_tol=1e-8) self.assertAllNotClose(fraction_examples, rel_tol=1e-9) + def testPerm(self): + perm = math.perm + factorial = math.factorial + # Test if factorial defintion is satisfied + for n in range(100): + for k in range(n + 1): + self.assertEqual(perm(n, k), + factorial(n) // factorial(n - k)) + + # Test for Pascal's identity + for n in range(1, 100): + for k in range(1, n): + self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k)) + + # Test corner cases + for n in range(1, 100): + self.assertEqual(perm(n, 0), 1) + self.assertEqual(perm(n, 1), n) + self.assertEqual(perm(n, n), factorial(n)) + + # Raises TypeError if any argument is non-integer or argument count is + # not 2 + self.assertRaises(TypeError, perm, 10, 1.0) + self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0)) + self.assertRaises(TypeError, perm, 10, "1") + self.assertRaises(TypeError, perm, 10.0, 1) + self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1) + self.assertRaises(TypeError, perm, "10", 1) + + self.assertRaises(TypeError, perm, 10) + self.assertRaises(TypeError, perm, 10, 1, 3) + self.assertRaises(TypeError, perm) + + # Raises Value error if not k or n are negative numbers + self.assertRaises(ValueError, perm, -1, 1) + self.assertRaises(ValueError, perm, -2**1000, 1) + self.assertRaises(ValueError, perm, 1, -1) + self.assertRaises(ValueError, perm, 1, -2**1000) + + # Raises value error if k is greater than n + self.assertRaises(ValueError, perm, 1, 2) + self.assertRaises(ValueError, perm, 1, 2**1000) + + n = 2**1000 + self.assertEqual(perm(n, 0), 1) + self.assertEqual(perm(n, 1), n) + self.assertEqual(perm(n, 2), n * (n-1)) + self.assertRaises((OverflowError, MemoryError), perm, n, n) + + for n, k in (True, True), (True, False), (False, False): + self.assertEqual(perm(n, k), 1) + self.assertIs(type(perm(n, k)), int) + self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20) + self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20) + for k in range(3): + self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int) + self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int) + def testComb(self): comb = math.comb factorial = math.factorial @@ -1925,8 +1986,11 @@ def testComb(self): for n, k in (True, True), (True, False), (False, False): self.assertEqual(comb(n, k), 1) self.assertIs(type(comb(n, k)), int) + self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10) self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10) - self.assertIs(type(comb(MyIndexable(5), MyIndexable(2))), int) + for k in range(3): + self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int) + self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int) def test_main(): diff --git a/Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst b/Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst new file mode 100644 index 00000000000000..f1b825890231d9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst @@ -0,0 +1 @@ +Added :func:`math.perm`. diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 92ec4bec9bf17d..0efe5cc409ceb1 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -638,6 +638,41 @@ math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k return return_value; } +PyDoc_STRVAR(math_perm__doc__, +"perm($module, n, k, /)\n" +"--\n" +"\n" +"Number of ways to choose k items from n items without repetition and with order.\n" +"\n" +"It is mathematically equal to the expression n! / (n - k)!.\n" +"\n" +"Raises TypeError if the arguments are not integers.\n" +"Raises ValueError if the arguments are negative or if k > n."); + +#define MATH_PERM_METHODDEF \ + {"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__}, + +static PyObject * +math_perm_impl(PyObject *module, PyObject *n, PyObject *k); + +static PyObject * +math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *n; + PyObject *k; + + if (!_PyArg_CheckPositional("perm", nargs, 2, 2)) { + goto exit; + } + n = args[0]; + k = args[1]; + return_value = math_perm_impl(module, n, k); + +exit: + return return_value; +} + PyDoc_STRVAR(math_comb__doc__, "comb($module, n, k, /)\n" "--\n" @@ -674,4 +709,4 @@ math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=6709521e5e1d90ec input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a82b0e705b6d0ec0 input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index bea4607b9be1ee..6e1099321c5495 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2998,6 +2998,120 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) } +/*[clinic input] +math.perm + + n: object + k: object + / + +Number of ways to choose k items from n items without repetition and with order. + +It is mathematically equal to the expression n! / (n - k)!. + +Raises TypeError if the arguments are not integers. +Raises ValueError if the arguments are negative or if k > n. +[clinic start generated code]*/ + +static PyObject * +math_perm_impl(PyObject *module, PyObject *n, PyObject *k) +/*[clinic end generated code: output=e021a25469653e23 input=f71ee4f6ff26be24]*/ +{ + PyObject *result = NULL, *factor = NULL; + int overflow, cmp; + long long i, factors; + + n = PyNumber_Index(n); + if (n == NULL) { + return NULL; + } + if (!PyLong_CheckExact(n)) { + Py_SETREF(n, _PyLong_Copy((PyLongObject *)n)); + if (n == NULL) { + return NULL; + } + } + k = PyNumber_Index(k); + if (k == NULL) { + Py_DECREF(n); + return NULL; + } + if (!PyLong_CheckExact(k)) { + Py_SETREF(k, _PyLong_Copy((PyLongObject *)k)); + if (k == NULL) { + Py_DECREF(n); + return NULL; + } + } + + if (Py_SIZE(n) < 0) { + PyErr_SetString(PyExc_ValueError, + "n must be a non-negative integer"); + goto error; + } + cmp = PyObject_RichCompareBool(n, k, Py_LT); + if (cmp != 0) { + if (cmp > 0) { + PyErr_SetString(PyExc_ValueError, + "k must be an integer less than or equal to n"); + } + goto error; + } + + factors = PyLong_AsLongLongAndOverflow(k, &overflow); + if (overflow > 0) { + PyErr_Format(PyExc_OverflowError, + "k must not exceed %lld", + LLONG_MAX); + goto error; + } + else if (overflow < 0 || factors < 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + } + goto error; + } + + if (factors == 0) { + result = PyLong_FromLong(1); + goto done; + } + + result = n; + Py_INCREF(result); + if (factors == 1) { + goto done; + } + + factor = n; + Py_INCREF(factor); + for (i = 1; i < factors; ++i) { + Py_SETREF(factor, PyNumber_Subtract(factor, _PyLong_One)); + if (factor == NULL) { + goto error; + } + Py_SETREF(result, PyNumber_Multiply(result, factor)); + if (result == NULL) { + goto error; + } + } + Py_DECREF(factor); + +done: + Py_DECREF(n); + Py_DECREF(k); + return result; + +error: + Py_XDECREF(factor); + Py_XDECREF(result); + Py_DECREF(n); + Py_DECREF(k); + return NULL; +} + + /*[clinic input] math.comb @@ -3028,11 +3142,24 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) if (n == NULL) { return NULL; } + if (!PyLong_CheckExact(n)) { + Py_SETREF(n, _PyLong_Copy((PyLongObject *)n)); + if (n == NULL) { + return NULL; + } + } k = PyNumber_Index(k); if (k == NULL) { Py_DECREF(n); return NULL; } + if (!PyLong_CheckExact(k)) { + Py_SETREF(k, _PyLong_Copy((PyLongObject *)k)); + if (k == NULL) { + Py_DECREF(n); + return NULL; + } + } if (Py_SIZE(n) < 0) { PyErr_SetString(PyExc_ValueError, @@ -3050,7 +3177,7 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) "k must be an integer less than or equal to n"); goto error; } - cmp = PyObject_RichCompareBool(k, temp, Py_GT); + cmp = PyObject_RichCompareBool(temp, k, Py_LT); if (cmp > 0) { Py_SETREF(k, temp); } @@ -3174,6 +3301,7 @@ static PyMethodDef math_methods[] = { {"tanh", math_tanh, METH_O, math_tanh_doc}, MATH_TRUNC_METHODDEF MATH_PROD_METHODDEF + MATH_PERM_METHODDEF MATH_COMB_METHODDEF {NULL, NULL} /* sentinel */ }; From c52996785a45d4693857ea219e040777a14584f8 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 2 Jun 2019 10:24:06 +0100 Subject: [PATCH 260/441] bpo-36027: Extend three-argument pow to negative second argument (GH-13266) --- Doc/library/functions.rst | 21 ++- Doc/whatsnew/3.8.rst | 6 + Lib/test/test_builtin.py | 3 +- Lib/test/test_pow.py | 26 ++++ .../2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst | 3 + Objects/longobject.c | 130 ++++++++++++++++-- 6 files changed, 173 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index d5c9f18c79b7ab..415a65b4946f08 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1277,9 +1277,24 @@ are always available. They are listed here in alphabetical order. operands, the result has the same type as the operands (after coercion) unless the second argument is negative; in that case, all arguments are converted to float and a float result is delivered. For example, ``10**2`` - returns ``100``, but ``10**-2`` returns ``0.01``. If the second argument is - negative, the third argument must be omitted. If *z* is present, *x* and *y* - must be of integer types, and *y* must be non-negative. + returns ``100``, but ``10**-2`` returns ``0.01``. + + For :class:`int` operands *x* and *y*, if *z* is present, *z* must also be + of integer type and *z* must be nonzero. If *z* is present and *y* is + negative, *x* must be relatively prime to *z*. In that case, ``pow(inv_x, + -y, z)`` is returned, where *inv_x* is an inverse to *x* modulo *z*. + + Here's an example of computing an inverse for ``38`` modulo ``97``:: + + >>> pow(38, -1, 97) + 23 + >>> 23 * 38 % 97 == 1 + True + + .. versionchanged:: 3.8 + For :class:`int` operands, the three-argument form of ``pow`` now allows + the second argument to be negative, permitting computation of modular + inverses. .. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 591b4548837264..74d0079a53db86 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -304,6 +304,12 @@ Other Language Changes * Added new ``replace()`` method to the code type (:class:`types.CodeType`). (Contributed by Victor Stinner in :issue:`37032`.) +* For integers, the three-argument form of the :func:`pow` function now permits + the exponent to be negative in the case where the base is relatively prime to + the modulus. It then computes a modular inverse to the base when the exponent + is ``-1``, and a suitable power of that inverse for other negative exponents. + (Contributed by Mark Dickinson in :issue:`36027`.) + New Modules =========== diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index e32fb75d81912d..b536cec064878f 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1195,7 +1195,8 @@ def test_pow(self): self.assertAlmostEqual(pow(-1, 0.5), 1j) self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j) - self.assertRaises(ValueError, pow, -1, -2, 3) + # See test_pow for additional tests for three-argument pow. + self.assertEqual(pow(-1, -2, 3), 1) self.assertRaises(ValueError, pow, 1, 2, 0) self.assertRaises(TypeError, pow) diff --git a/Lib/test/test_pow.py b/Lib/test/test_pow.py index cac1ae5ea2d8bc..660ff80bbf522f 100644 --- a/Lib/test/test_pow.py +++ b/Lib/test/test_pow.py @@ -1,3 +1,4 @@ +import math import unittest class PowTest(unittest.TestCase): @@ -119,5 +120,30 @@ def test_bug705231(self): eq(pow(a, -fiveto), expected) eq(expected, 1.0) # else we didn't push fiveto to evenness + def test_negative_exponent(self): + for a in range(-50, 50): + for m in range(-50, 50): + with self.subTest(a=a, m=m): + if m != 0 and math.gcd(a, m) == 1: + # Exponent -1 should give an inverse, with the + # same sign as m. + inv = pow(a, -1, m) + self.assertEqual(inv, inv % m) + self.assertEqual((inv * a - 1) % m, 0) + + # Larger exponents + self.assertEqual(pow(a, -2, m), pow(inv, 2, m)) + self.assertEqual(pow(a, -3, m), pow(inv, 3, m)) + self.assertEqual(pow(a, -1001, m), pow(inv, 1001, m)) + + else: + with self.assertRaises(ValueError): + pow(a, -1, m) + with self.assertRaises(ValueError): + pow(a, -2, m) + with self.assertRaises(ValueError): + pow(a, -1001, m) + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst new file mode 100644 index 00000000000000..866309cddc682f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst @@ -0,0 +1,3 @@ +Allow computation of modular inverses via three-argument ``pow``: the second +argument is now permitted to be negative in the case where the first and +third arguments are relatively prime. diff --git a/Objects/longobject.c b/Objects/longobject.c index 5d2b595621f3d8..49f1420bf64f98 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4174,6 +4174,98 @@ long_divmod(PyObject *a, PyObject *b) return z; } + +/* Compute an inverse to a modulo n, or raise ValueError if a is not + invertible modulo n. Assumes n is positive. The inverse returned + is whatever falls out of the extended Euclidean algorithm: it may + be either positive or negative, but will be smaller than n in + absolute value. + + Pure Python equivalent for long_invmod: + + def invmod(a, n): + b, c = 1, 0 + while n: + q, r = divmod(a, n) + a, b, c, n = n, c, b - q*c, r + + # at this point a is the gcd of the original inputs + if a == 1: + return b + raise ValueError("Not invertible") +*/ + +static PyLongObject * +long_invmod(PyLongObject *a, PyLongObject *n) +{ + PyLongObject *b, *c; + + /* Should only ever be called for positive n */ + assert(Py_SIZE(n) > 0); + + b = (PyLongObject *)PyLong_FromLong(1L); + if (b == NULL) { + return NULL; + } + c = (PyLongObject *)PyLong_FromLong(0L); + if (c == NULL) { + Py_DECREF(b); + return NULL; + } + Py_INCREF(a); + Py_INCREF(n); + + /* references now owned: a, b, c, n */ + while (Py_SIZE(n) != 0) { + PyLongObject *q, *r, *s, *t; + + if (l_divmod(a, n, &q, &r) == -1) { + goto Error; + } + Py_DECREF(a); + a = n; + n = r; + t = (PyLongObject *)long_mul(q, c); + Py_DECREF(q); + if (t == NULL) { + goto Error; + } + s = (PyLongObject *)long_sub(b, t); + Py_DECREF(t); + if (s == NULL) { + goto Error; + } + Py_DECREF(b); + b = c; + c = s; + } + /* references now owned: a, b, c, n */ + + Py_DECREF(c); + Py_DECREF(n); + if (long_compare(a, _PyLong_One)) { + /* a != 1; we don't have an inverse. */ + Py_DECREF(a); + Py_DECREF(b); + PyErr_SetString(PyExc_ValueError, + "base is not invertible for the given modulus"); + return NULL; + } + else { + /* a == 1; b gives an inverse modulo n */ + Py_DECREF(a); + return b; + } + + Error: + Py_DECREF(a); + Py_DECREF(b); + Py_DECREF(c); + Py_DECREF(n); + return NULL; +} + + /* pow(v, w, x) */ static PyObject * long_pow(PyObject *v, PyObject *w, PyObject *x) @@ -4207,20 +4299,14 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) Py_RETURN_NOTIMPLEMENTED; } - if (Py_SIZE(b) < 0) { /* if exponent is negative */ - if (c) { - PyErr_SetString(PyExc_ValueError, "pow() 2nd argument " - "cannot be negative when 3rd argument specified"); - goto Error; - } - else { - /* else return a float. This works because we know + if (Py_SIZE(b) < 0 && c == NULL) { + /* if exponent is negative and there's no modulus: + return a float. This works because we know that this calls float_pow() which converts its arguments to double. */ - Py_DECREF(a); - Py_DECREF(b); - return PyFloat_Type.tp_as_number->nb_power(v, w, x); - } + Py_DECREF(a); + Py_DECREF(b); + return PyFloat_Type.tp_as_number->nb_power(v, w, x); } if (c) { @@ -4255,6 +4341,26 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) goto Done; } + /* if exponent is negative, negate the exponent and + replace the base with a modular inverse */ + if (Py_SIZE(b) < 0) { + temp = (PyLongObject *)_PyLong_Copy(b); + if (temp == NULL) + goto Error; + Py_DECREF(b); + b = temp; + temp = NULL; + _PyLong_Negate(&b); + if (b == NULL) + goto Error; + + temp = long_invmod(a, c); + if (temp == NULL) + goto Error; + Py_DECREF(a); + a = temp; + } + /* Reduce base by modulus in some cases: 1. If base < 0. Forcing the base non-negative makes things easier. 2. If base is obviously larger than the modulus. The "small From 13ed07998ad93dbdd94991ba0451b9b559f07972 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 2 Jun 2019 13:56:38 +0300 Subject: [PATCH 261/441] bpo-35621: Support running subprocesses in asyncio when loop is executed in non-main thread (#13630) --- Lib/asyncio/unix_events.py | 240 ++++++++++++++++-- Lib/test/test_asyncio/test_subprocess.py | 40 ++- Lib/test/test_asyncio/test_unix_events.py | 34 +-- .../2019-05-28-19-03-46.bpo-35621.Abc1lf.rst | 2 + 4 files changed, 262 insertions(+), 54 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 28128d2977df64..6714542e4e3361 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -2,6 +2,7 @@ import errno import io +import itertools import os import selectors import signal @@ -29,7 +30,9 @@ __all__ = ( 'SelectorEventLoop', 'AbstractChildWatcher', 'SafeChildWatcher', - 'FastChildWatcher', 'DefaultEventLoopPolicy', + 'FastChildWatcher', + 'MultiLoopChildWatcher', 'ThreadedChildWatcher', + 'DefaultEventLoopPolicy', ) @@ -184,6 +187,13 @@ async def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): with events.get_child_watcher() as watcher: + if not watcher.is_active(): + # Check early. + # Raising exception before process creation + # prevents subprocess execution if the watcher + # is not ready to handle it. + raise RuntimeError("asyncio.get_child_watcher() is not activated, " + "subproccess support is not installed.") waiter = self.create_future() transp = _UnixSubprocessTransport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, @@ -838,6 +848,15 @@ def close(self): """ raise NotImplementedError() + def is_active(self): + """Watcher status. + + Return True if the watcher is installed and ready to handle process exit + notifications. + + """ + raise NotImplementedError() + def __enter__(self): """Enter the watcher's context and allow starting new processes @@ -849,6 +868,20 @@ def __exit__(self, a, b, c): raise NotImplementedError() +def _compute_returncode(status): + if os.WIFSIGNALED(status): + # The child process died because of a signal. + return -os.WTERMSIG(status) + elif os.WIFEXITED(status): + # The child process exited (e.g sys.exit()). + return os.WEXITSTATUS(status) + else: + # The child exited, but we don't understand its status. + # This shouldn't happen, but if it does, let's just + # return that status; perhaps that helps debug it. + return status + + class BaseChildWatcher(AbstractChildWatcher): def __init__(self): @@ -858,6 +891,9 @@ def __init__(self): def close(self): self.attach_loop(None) + def is_active(self): + return self._loop is not None and self._loop.is_running() + def _do_waitpid(self, expected_pid): raise NotImplementedError() @@ -898,19 +934,6 @@ def _sig_chld(self): 'exception': exc, }) - def _compute_returncode(self, status): - if os.WIFSIGNALED(status): - # The child process died because of a signal. - return -os.WTERMSIG(status) - elif os.WIFEXITED(status): - # The child process exited (e.g sys.exit()). - return os.WEXITSTATUS(status) - else: - # The child exited, but we don't understand its status. - # This shouldn't happen, but if it does, let's just - # return that status; perhaps that helps debug it. - return status - class SafeChildWatcher(BaseChildWatcher): """'Safe' child watcher implementation. @@ -934,11 +957,6 @@ def __exit__(self, a, b, c): pass def add_child_handler(self, pid, callback, *args): - if self._loop is None: - raise RuntimeError( - "Cannot add child handler, " - "the child watcher does not have a loop attached") - self._callbacks[pid] = (callback, args) # Prevent a race condition in case the child is already terminated. @@ -974,7 +992,7 @@ def _do_waitpid(self, expected_pid): # The child process is still alive. return - returncode = self._compute_returncode(status) + returncode = _compute_returncode(status) if self._loop.get_debug(): logger.debug('process %s exited with returncode %s', expected_pid, returncode) @@ -1035,11 +1053,6 @@ def __exit__(self, a, b, c): def add_child_handler(self, pid, callback, *args): assert self._forks, "Must use the context manager" - if self._loop is None: - raise RuntimeError( - "Cannot add child handler, " - "the child watcher does not have a loop attached") - with self._lock: try: returncode = self._zombies.pop(pid) @@ -1072,7 +1085,7 @@ def _do_waitpid_all(self): # A child process is still alive. return - returncode = self._compute_returncode(status) + returncode = _compute_returncode(status) with self._lock: try: @@ -1101,6 +1114,177 @@ def _do_waitpid_all(self): callback(pid, returncode, *args) +class MultiLoopChildWatcher(AbstractChildWatcher): + # The class keeps compatibility with AbstractChildWatcher ABC + # To achieve this it has empty attach_loop() method + # and doesn't accept explicit loop argument + # for add_child_handler()/remove_child_handler() + # but retrieves the current loop by get_running_loop() + + def __init__(self): + self._callbacks = {} + self._saved_sighandler = None + + def is_active(self): + return self._saved_sighandler is not None + + def close(self): + self._callbacks.clear() + if self._saved_sighandler is not None: + handler = signal.getsignal(signal.SIGCHLD) + if handler != self._sig_chld: + logger.warning("SIGCHLD handler was changed by outside code") + else: + signal.signal(signal.SIGCHLD, self._saved_sighandler) + self._saved_sighandler = None + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + def add_child_handler(self, pid, callback, *args): + loop = events.get_running_loop() + self._callbacks[pid] = (loop, callback, args) + + # Prevent a race condition in case the child is already terminated. + self._do_waitpid(pid) + + def remove_child_handler(self, pid): + try: + del self._callbacks[pid] + return True + except KeyError: + return False + + def attach_loop(self, loop): + # Don't save the loop but initialize itself if called first time + # The reason to do it here is that attach_loop() is called from + # unix policy only for the main thread. + # Main thread is required for subscription on SIGCHLD signal + if self._saved_sighandler is None: + self._saved_sighandler = signal.signal(signal.SIGCHLD, self._sig_chld) + if self._saved_sighandler is None: + logger.warning("Previous SIGCHLD handler was set by non-Python code, " + "restore to default handler on watcher close.") + self._saved_sighandler = signal.SIG_DFL + + # Set SA_RESTART to limit EINTR occurrences. + signal.siginterrupt(signal.SIGCHLD, False) + + def _do_waitpid_all(self): + for pid in list(self._callbacks): + self._do_waitpid(pid) + + def _do_waitpid(self, expected_pid): + assert expected_pid > 0 + + try: + pid, status = os.waitpid(expected_pid, os.WNOHANG) + except ChildProcessError: + # The child process is already reaped + # (may happen if waitpid() is called elsewhere). + pid = expected_pid + returncode = 255 + logger.warning( + "Unknown child process pid %d, will report returncode 255", + pid) + debug_log = False + else: + if pid == 0: + # The child process is still alive. + return + + returncode = _compute_returncode(status) + debug_log = True + try: + loop, callback, args = self._callbacks.pop(pid) + except KeyError: # pragma: no cover + # May happen if .remove_child_handler() is called + # after os.waitpid() returns. + logger.warning("Child watcher got an unexpected pid: %r", + pid, exc_info=True) + else: + if loop.is_closed(): + logger.warning("Loop %r that handles pid %r is closed", loop, pid) + else: + if debug_log and loop.get_debug(): + logger.debug('process %s exited with returncode %s', + expected_pid, returncode) + loop.call_soon_threadsafe(callback, pid, returncode, *args) + + def _sig_chld(self, signum, frame): + try: + self._do_waitpid_all() + except (SystemExit, KeyboardInterrupt): + raise + except BaseException: + logger.warning('Unknown exception in SIGCHLD handler', exc_info=True) + + +class ThreadedChildWatcher(AbstractChildWatcher): + # The watcher uses a thread per process + # for waiting for the process finish. + # It doesn't require subscription on POSIX signal + + def __init__(self): + self._pid_counter = itertools.count(0) + + def is_active(self): + return True + + def close(self): + pass + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + def add_child_handler(self, pid, callback, *args): + loop = events.get_running_loop() + thread = threading.Thread(target=self._do_waitpid, + name=f"waitpid-{next(self._pid_counter)}", + args=(loop, pid, callback, args), + daemon=True) + thread.start() + + def remove_child_handler(self, pid): + # asyncio never calls remove_child_handler() !!! + # The method is no-op but is implemented because + # abstract base classe requires it + return True + + def attach_loop(self, loop): + pass + + def _do_waitpid(self, loop, expected_pid, callback, args): + assert expected_pid > 0 + + try: + pid, status = os.waitpid(expected_pid, 0) + except ChildProcessError: + # The child process is already reaped + # (may happen if waitpid() is called elsewhere). + pid = expected_pid + returncode = 255 + logger.warning( + "Unknown child process pid %d, will report returncode 255", + pid) + else: + returncode = _compute_returncode(status) + if loop.get_debug(): + logger.debug('process %s exited with returncode %s', + expected_pid, returncode) + + if loop.is_closed(): + logger.warning("Loop %r that handles pid %r is closed", loop, pid) + else: + loop.call_soon_threadsafe(callback, pid, returncode, *args) + + class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): """UNIX event loop policy with a watcher for child processes.""" _loop_factory = _UnixSelectorEventLoop @@ -1112,7 +1296,7 @@ def __init__(self): def _init_watcher(self): with events._lock: if self._watcher is None: # pragma: no branch - self._watcher = SafeChildWatcher() + self._watcher = ThreadedChildWatcher() if isinstance(threading.current_thread(), threading._MainThread): self._watcher.attach_loop(self._local._loop) @@ -1134,7 +1318,7 @@ def set_event_loop(self, loop): def get_child_watcher(self): """Get the watcher for child processes. - If not yet set, a SafeChildWatcher object is automatically created. + If not yet set, a ThreadedChildWatcher object is automatically created. """ if self._watcher is None: self._init_watcher() diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 7d72e6cde4e7a8..582e1720246033 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -633,6 +633,7 @@ async def execute(): self.assertIsNone(self.loop.run_until_complete(execute())) + if sys.platform != 'win32': # Unix class SubprocessWatcherMixin(SubprocessMixin): @@ -648,7 +649,24 @@ def setUp(self): watcher = self.Watcher() watcher.attach_loop(self.loop) policy.set_child_watcher(watcher) - self.addCleanup(policy.set_child_watcher, None) + + def tearDown(self): + super().setUp() + policy = asyncio.get_event_loop_policy() + watcher = policy.get_child_watcher() + policy.set_child_watcher(None) + watcher.attach_loop(None) + watcher.close() + + class SubprocessThreadedWatcherTests(SubprocessWatcherMixin, + test_utils.TestCase): + + Watcher = unix_events.ThreadedChildWatcher + + class SubprocessMultiLoopWatcherTests(SubprocessWatcherMixin, + test_utils.TestCase): + + Watcher = unix_events.MultiLoopChildWatcher class SubprocessSafeWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): @@ -670,5 +688,25 @@ def setUp(self): self.set_event_loop(self.loop) +class GenericWatcherTests: + + def test_create_subprocess_fails_with_inactive_watcher(self): + + async def execute(): + watcher = mock.create_authspec(asyncio.AbstractChildWatcher) + watcher.is_active.return_value = False + asyncio.set_child_watcher(watcher) + + with self.assertRaises(RuntimeError): + await subprocess.create_subprocess_exec( + support.FakePath(sys.executable), '-c', 'pass') + + watcher.add_child_handler.assert_not_called() + + self.assertIsNone(self.loop.run_until_complete(execute())) + + + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index ac84304ec99da6..f7f992fcea49f9 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1082,6 +1082,8 @@ def test_not_implemented(self): NotImplementedError, watcher.attach_loop, f) self.assertRaises( NotImplementedError, watcher.close) + self.assertRaises( + NotImplementedError, watcher.is_active) self.assertRaises( NotImplementedError, watcher.__enter__) self.assertRaises( @@ -1784,15 +1786,6 @@ def test_close(self, m): if isinstance(self.watcher, asyncio.FastChildWatcher): self.assertFalse(self.watcher._zombies) - @waitpid_mocks - def test_add_child_handler_with_no_loop_attached(self, m): - callback = mock.Mock() - with self.create_watcher() as watcher: - with self.assertRaisesRegex( - RuntimeError, - 'the child watcher does not have a loop attached'): - watcher.add_child_handler(100, callback) - class SafeChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): @@ -1809,17 +1802,16 @@ class PolicyTests(unittest.TestCase): def create_policy(self): return asyncio.DefaultEventLoopPolicy() - def test_get_child_watcher(self): + def test_get_default_child_watcher(self): policy = self.create_policy() self.assertIsNone(policy._watcher) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, asyncio.SafeChildWatcher) + self.assertIsInstance(watcher, asyncio.ThreadedChildWatcher) self.assertIs(policy._watcher, watcher) self.assertIs(watcher, policy.get_child_watcher()) - self.assertIsNone(watcher._loop) def test_get_child_watcher_after_set(self): policy = self.create_policy() @@ -1829,18 +1821,6 @@ def test_get_child_watcher_after_set(self): self.assertIs(policy._watcher, watcher) self.assertIs(watcher, policy.get_child_watcher()) - def test_get_child_watcher_with_mainloop_existing(self): - policy = self.create_policy() - loop = policy.get_event_loop() - - self.assertIsNone(policy._watcher) - watcher = policy.get_child_watcher() - - self.assertIsInstance(watcher, asyncio.SafeChildWatcher) - self.assertIs(watcher._loop, loop) - - loop.close() - def test_get_child_watcher_thread(self): def f(): @@ -1865,7 +1845,11 @@ def test_child_watcher_replace_mainloop_existing(self): policy = self.create_policy() loop = policy.get_event_loop() - watcher = policy.get_child_watcher() + # Explicitly setup SafeChildWatcher, + # default ThreadedChildWatcher has no _loop property + watcher = asyncio.SafeChildWatcher() + policy.set_child_watcher(watcher) + watcher.attach_loop(loop) self.assertIs(watcher._loop, loop) diff --git a/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst b/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst new file mode 100644 index 00000000000000..c492e1de6d5c42 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst @@ -0,0 +1,2 @@ +Support running asyncio subprocesses when execution event loop in a thread +on UNIX. From 7ffcf848df214135abeea7f6c6faa4135fd0928f Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sun, 2 Jun 2019 15:45:13 +0100 Subject: [PATCH 262/441] bpo-37126: Allow structseq objects to be tracked by the GC (GH-13729) --- .../2019-06-01-20-03-13.bpo-37126.tP6lL4.rst | 2 ++ Objects/structseq.c | 20 +++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst new file mode 100644 index 00000000000000..069b064dfa615d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst @@ -0,0 +1,2 @@ +All structseq objects are now tracked by the garbage collector. Patch by +Pablo Galindo. diff --git a/Objects/structseq.c b/Objects/structseq.c index a5046c42cbc32d..3d857f734be8a3 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_tupleobject.h" +#include "pycore_object.h" #include "structmember.h" static const char visible_length_key[] = "n_sequence_fields"; @@ -59,6 +60,18 @@ PyStructSequence_GetItem(PyObject* op, Py_ssize_t i) return PyStructSequence_GET_ITEM(op, i); } + +static int +structseq_traverse(PyStructSequence *obj, visitproc visit, void *arg) +{ + Py_ssize_t i, size; + size = REAL_SIZE(obj); + for (i = 0; i < size; ++i) { + Py_VISIT(obj->ob_item[i]); + } + return 0; +} + static void structseq_dealloc(PyStructSequence *obj) { @@ -166,6 +179,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) } Py_DECREF(arg); + _PyObject_GC_TRACK(res); return (PyObject*) res; } @@ -388,6 +402,7 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) type->tp_methods = structseq_methods; type->tp_new = structseq_new; type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC; + type->tp_traverse = (traverseproc) structseq_traverse; n_members = count_members(desc, &n_unnamed_members); members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); @@ -426,7 +441,7 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) PyMemberDef *members; PyObject *bases; PyTypeObject *type; - PyType_Slot slots[7]; + PyType_Slot slots[8]; PyType_Spec spec; Py_ssize_t n_members, n_unnamed_members; @@ -446,7 +461,8 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) slots[3] = (PyType_Slot){Py_tp_methods, structseq_methods}; slots[4] = (PyType_Slot){Py_tp_new, structseq_new}; slots[5] = (PyType_Slot){Py_tp_members, members}; - slots[6] = (PyType_Slot){0, 0}; + slots[6] = (PyType_Slot){Py_tp_traverse, (traverseproc)structseq_traverse}; + slots[7] = (PyType_Slot){0, 0}; /* Initialize Spec */ /* The name in this PyType_Spec is statically allocated so it is */ From 5df4025f42b30aca72f441899b361f748c304c57 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Sun, 2 Jun 2019 18:58:10 +0200 Subject: [PATCH 263/441] Add description to the command line help of the argument clinic (GH-8518) --- Tools/clinic/clinic.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index cb2ded4649dce2..9880b395133995 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -4900,7 +4900,14 @@ def main(argv): sys.exit("Error: clinic.py requires Python 3.3 or greater.") import argparse - cmdline = argparse.ArgumentParser() + cmdline = argparse.ArgumentParser( + description="""Preprocessor for CPython C files. + +The purpose of the Argument Clinic is automating all the boilerplate involved +with writing argument parsing code for builtins and providing introspection +signatures ("docstrings") for CPython builtins. + +For more information see https://docs.python.org/3/howto/clinic.html""") cmdline.add_argument("-f", "--force", action='store_true') cmdline.add_argument("-o", "--output", type=str) cmdline.add_argument("-v", "--verbose", action='store_true') From 6bdc4dee01788599808c7858e2fe9fdd72cf6792 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Sun, 2 Jun 2019 14:56:47 -0400 Subject: [PATCH 264/441] bpo-35610: IDLE - Replace .context_use_ps1 with .prompt_last_line (GH-11307) Changes in bpo- 31858 made the less informative 'context_use_ps1' redundant. --- Lib/idlelib/NEWS.txt | 3 +++ Lib/idlelib/editor.py | 7 +------ Lib/idlelib/hyperparser.py | 2 +- Lib/idlelib/idle_test/test_autocomplete.py | 2 +- Lib/idlelib/idle_test/test_hyperparser.py | 6 +++--- Lib/idlelib/idle_test/test_parenmatch.py | 2 +- Lib/idlelib/pyshell.py | 2 +- .../next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst | 2 ++ 8 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index b260d4e5ef1bd8..982af77672517c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2019-10-20? ====================================== +bpo-35610: Replace now redundant editor.context_use_ps1 with +.prompt_last_line. This finishes change started in bpo-31858. + bpo-32411: Stop sorting dict created with desired line order. bpo-37038: Make idlelib.run runnable; add test clause. diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 83260329640e1a..89b7239a96ea0e 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -228,10 +228,6 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.indentwidth = self.tabwidth self.set_notabs_indentwidth() - # If context_use_ps1 is true, parsing searches back for a ps1 line; - # else searches for a popular (if, def, ...) Python stmt. - self.context_use_ps1 = False - # When searching backwards for a reliable place to begin parsing, # first start num_context_lines[0] lines back, then # num_context_lines[1] lines back if that didn't work, and so on. @@ -1337,14 +1333,13 @@ def newline_and_indent_event(self, event): # open/close first need to find the last stmt lno = index2line(text.index('insert')) y = pyparse.Parser(self.indentwidth, self.tabwidth) - if not self.context_use_ps1: + if not self.prompt_last_line: for context in self.num_context_lines: startat = max(lno - context, 1) startatindex = repr(startat) + ".0" rawtext = text.get(startatindex, "insert") y.set_code(rawtext) bod = y.find_good_parse_start( - self.context_use_ps1, self._build_char_in_string_func(startatindex)) if bod is not None or startat == 1: break diff --git a/Lib/idlelib/hyperparser.py b/Lib/idlelib/hyperparser.py index 7e7e0ae8024754..77baca782b3fdc 100644 --- a/Lib/idlelib/hyperparser.py +++ b/Lib/idlelib/hyperparser.py @@ -35,7 +35,7 @@ def index2line(index): return int(float(index)) lno = index2line(text.index(index)) - if not editwin.context_use_ps1: + if not editwin.prompt_last_line: for context in editwin.num_context_lines: startat = max(lno - context, 1) startatindex = repr(startat) + ".0" diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py index 398cb359e0931f..6181b29ec250cc 100644 --- a/Lib/idlelib/idle_test/test_autocomplete.py +++ b/Lib/idlelib/idle_test/test_autocomplete.py @@ -19,7 +19,7 @@ def __init__(self, root, text): self.text = text self.indentwidth = 8 self.tabwidth = 8 - self.context_use_ps1 = True + self.prompt_last_line = '>>>' # Currently not used by autocomplete. class AutoCompleteTest(unittest.TestCase): diff --git a/Lib/idlelib/idle_test/test_hyperparser.py b/Lib/idlelib/idle_test/test_hyperparser.py index 8dbfc63779d380..343843c4166e97 100644 --- a/Lib/idlelib/idle_test/test_hyperparser.py +++ b/Lib/idlelib/idle_test/test_hyperparser.py @@ -11,7 +11,7 @@ def __init__(self, text): self.text = text self.indentwidth = 8 self.tabwidth = 8 - self.context_use_ps1 = True + self.prompt_last_line = '>>>' self.num_context_lines = 50, 500, 1000 _build_char_in_string_func = EditorWindow._build_char_in_string_func @@ -53,7 +53,7 @@ def setUp(self): def tearDown(self): self.text.delete('1.0', 'end') - self.editwin.context_use_ps1 = True + self.editwin.prompt_last_line = '>>>' def get_parser(self, index): """ @@ -71,7 +71,7 @@ def test_init(self): self.assertIn('precedes', str(ve.exception)) # test without ps1 - self.editwin.context_use_ps1 = False + self.editwin.prompt_last_line = '' # number of lines lesser than 50 p = self.get_parser('end') diff --git a/Lib/idlelib/idle_test/test_parenmatch.py b/Lib/idlelib/idle_test/test_parenmatch.py index f58819abf11211..4a41d8433d5483 100644 --- a/Lib/idlelib/idle_test/test_parenmatch.py +++ b/Lib/idlelib/idle_test/test_parenmatch.py @@ -17,7 +17,7 @@ def __init__(self, text): self.text = text self.indentwidth = 8 self.tabwidth = 8 - self.context_use_ps1 = True + self.prompt_last_line = '>>>' # Currently not used by parenmatch. class ParenMatchTest(unittest.TestCase): diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 2de42658b01cb8..6e0707d68bb6ed 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -881,7 +881,7 @@ def __init__(self, flist=None): self.usetabs = True # indentwidth must be 8 when using tabs. See note in EditorWindow: self.indentwidth = 8 - self.context_use_ps1 = True + self.sys_ps1 = sys.ps1 if hasattr(sys, 'ps1') else '>>> ' self.prompt_last_line = self.sys_ps1.split('\n')[-1] self.prompt = self.sys_ps1 # Changes when debug active diff --git a/Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst b/Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst new file mode 100644 index 00000000000000..0042ab70497a3b --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst @@ -0,0 +1,2 @@ +Replace now redundant .context_use_ps1 with .prompt_last_line. This finishes +change started in bpo-31858. From c0295dba259accc4b247beb22a0b2cc2f31d9850 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sun, 2 Jun 2019 21:36:21 +0100 Subject: [PATCH 265/441] bpo-37124: Fix reference leak in test_msilib (GH-13750) --- Lib/test/test_msilib.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_msilib.py b/Lib/test/test_msilib.py index fa0be581613de3..f9bd0da7498e91 100644 --- a/Lib/test/test_msilib.py +++ b/Lib/test/test_msilib.py @@ -87,6 +87,7 @@ def test_directory_start_component_keyfile(self): db, db_path = init_database() self.addCleanup(unlink, db_path) self.addCleanup(db.Close) + self.addCleanup(msilib._directories.clear) feature = msilib.Feature(db, 0, 'Feature', 'A feature', 'Python') cab = msilib.CAB('CAB') dir = msilib.Directory(db, cab, None, TESTFN, 'TARGETDIR', From 3caf4de6f05f68c3a175f4d8ce870d7a0016622a Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sun, 2 Jun 2019 21:52:49 +0100 Subject: [PATCH 266/441] Call PyObject_GC_UnTrack in structseq dealloc (GH-13751) --- Objects/structseq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/structseq.c b/Objects/structseq.c index 3d857f734be8a3..2c25e1646a2a67 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -77,6 +77,7 @@ structseq_dealloc(PyStructSequence *obj) { Py_ssize_t i, size; PyTypeObject *tp; + PyObject_GC_UnTrack(obj); tp = (PyTypeObject *) Py_TYPE(obj); size = REAL_SIZE(obj); From aca273e2401ca3151e15e984f400233b7f255e15 Mon Sep 17 00:00:00 2001 From: Michele Angrisano Date: Sun, 2 Jun 2019 23:01:49 +0200 Subject: [PATCH 267/441] bpo-37014: Update docstring and Documentation of fileinput.FileInput(). (GH-13545) * bpo-37014: Update docstring and Documentation of fileinput.FileInput() * Explain the behavior of fileinput.FileInput() when reading stdin. * Update blurb. * bpo-37014: Fix typo in the docstring and documentation. --- Doc/library/fileinput.rst | 5 +++-- Lib/fileinput.py | 6 +++--- Misc/ACKS | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 14be492f55a67f..f5e5280a136399 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -23,8 +23,9 @@ The typical use is:: This iterates over the lines of all files listed in ``sys.argv[1:]``, defaulting to ``sys.stdin`` if the list is empty. If a filename is ``'-'``, it is also -replaced by ``sys.stdin``. To specify an alternative list of filenames, pass it -as the first argument to :func:`.input`. A single file name is also allowed. +replaced by ``sys.stdin`` and the optional arguments *mode* and *openhook* +are ignored. To specify an alternative list of filenames, pass it as the +first argument to :func:`.input`. A single file name is also allowed. All files are opened in text mode by default, but you can override this by specifying the *mode* parameter in the call to :func:`.input` or diff --git a/Lib/fileinput.py b/Lib/fileinput.py index d868e74cd5e969..c1b0ec9a8ed084 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -8,9 +8,9 @@ This iterates over the lines of all files listed in sys.argv[1:], defaulting to sys.stdin if the list is empty. If a filename is '-' it -is also replaced by sys.stdin. To specify an alternative list of -filenames, pass it as the argument to input(). A single file name is -also allowed. +is also replaced by sys.stdin and the optional arguments mode and +openhook are ignored. To specify an alternative list of filenames, +pass it as the argument to input(). A single file name is also allowed. Functions filename(), lineno() return the filename and cumulative line number of the line that has just been read; filelineno() returns its diff --git a/Misc/ACKS b/Misc/ACKS index 5c23df8c589922..082fa567f23aa6 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -55,6 +55,7 @@ Juancarlo Añez Chris Angelico Jérémy Anger Jon Anglin +Michele Angrisano Ankur Ankan Heidi Annexstad Ramchandra Apte From cdce0574d03005e27b843fc110c54c99c7a76412 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 2 Jun 2019 23:08:41 +0200 Subject: [PATCH 268/441] bpo-36829: test_threading: Fix a ref cycle (GH-13752) --- Lib/test/test_threading.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 8c8cc128b0513b..6ac4ea9623de0d 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -1140,7 +1140,11 @@ def test_excepthook_thread_None(self): raise ValueError("bug") except Exception as exc: args = threading.ExceptHookArgs([*sys.exc_info(), None]) - threading.excepthook(args) + try: + threading.excepthook(args) + finally: + # Explicitly break a reference cycle + args = None stderr = stderr.getvalue().strip() self.assertIn(f'Exception in thread {threading.get_ident()}:\n', stderr) From 64e2c64f7f0111c52834155becc0c6134f9d8750 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Sun, 2 Jun 2019 23:11:24 +0200 Subject: [PATCH 269/441] test_gdb.test_pycfunction: test more calling conventions (GH-13668) As the code paths for various METH_* conventions are diverging due to optimizations, we should check they continue to be covered by GDB integration. --- Lib/test/test_gdb.py | 55 +++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 3127e69ca9ba1d..f57e348b6c144c 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -867,27 +867,40 @@ def test_gc(self): # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround def test_pycfunction(self): 'Verify that "py-bt" displays invocations of PyCFunction instances' - # Tested function must not be defined with METH_NOARGS or METH_O, - # otherwise call_function() doesn't call PyCFunction_Call() - cmd = ('from time import gmtime\n' - 'def foo():\n' - ' gmtime(1)\n' - 'def bar():\n' - ' foo()\n' - 'bar()\n') - # Verify with "py-bt": - gdb_output = self.get_stack_trace(cmd, - breakpoint='time_gmtime', - cmds_after_breakpoint=['bt', 'py-bt'], - ) - self.assertIn(' Date: Sun, 2 Jun 2019 23:34:12 +0200 Subject: [PATCH 270/441] bpo-19184: Update the documentation of dis module. (GH-13652) * bpo-19184: Update the documentation of dis module * Explain the behavior of the number of arguments of RAISE_VARGARGS opcode. * bpo-19184: Update blurb. * bpo-19184: Fix typo in the dis Documentation. * bpo-19184: Address review comments and improve the doc * bpo-19184: Remove news file. --- Doc/library/dis.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 060d4bb6997a4d..15e707ae49f85f 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1113,9 +1113,13 @@ All of the following opcodes use their arguments. .. opcode:: RAISE_VARARGS (argc) - Raises an exception. *argc* indicates the number of arguments to the raise - statement, ranging from 0 to 3. The handler will find the traceback as TOS2, - the parameter as TOS1, and the exception as TOS. + Raises an exception using one of the 3 forms of the ``raise`` statement, + depending on the value of *argc*: + + * 0: ``raise`` (re-raise previous exception) + * 1: ``raise TOS`` (raise exception instance or type at ``TOS``) + * 2: ``raise TOS1 from TOS`` (raise exception instance or type at ``TOS1`` + with ``__cause__`` set to ``TOS``) .. opcode:: CALL_FUNCTION (argc) From fb9423fd0a85f06affb8c3a8f25dd598a649aa42 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Sun, 2 Jun 2019 23:52:20 +0200 Subject: [PATCH 271/441] bpo-36974: Make tp_call=PyVectorcall_Call work for inherited types (GH-13699) When inheriting a heap subclass from a vectorcall class that sets `.tp_call=PyVectorcall_Call` (as recommended in PEP 590), the subclass does not inherit `_Py_TPFLAGS_HAVE_VECTORCALL`, and thus `PyVectorcall_Call` does not work for it. This attempts to solve the issue by: * always inheriting `tp_vectorcall_offset` unless `tp_call` is overridden in the subclass * inheriting _Py_TPFLAGS_HAVE_VECTORCALL for static types, unless `tp_call` is overridden * making `PyVectorcall_Call` ignore `_Py_TPFLAGS_HAVE_VECTORCALL` This means it'll be ever more important to only call `PyVectorcall_Call` on classes that support vectorcall. In `PyVectorcall_Call`'s intended role as `tp_call` filler, that's not a problem. --- Lib/test/test_capi.py | 30 +++++++++++++++++++++++++----- Modules/_testcapimodule.c | 2 +- Objects/call.c | 12 +++++++++++- Objects/typeobject.c | 24 ++++++++++++++---------- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index fabc821e5c3ad8..88bda057ed6a67 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -515,9 +515,10 @@ def test_vectorcall_override(self): def test_vectorcall(self): # Test a bunch of different ways to call objects: - # 1. normal call - # 2. vectorcall using _PyObject_Vectorcall() - # 3. vectorcall using PyVectorcall_Call() + # 1. vectorcall using PyVectorcall_Call() + # (only for objects that support vectorcall directly) + # 2. normal call + # 3. vectorcall using _PyObject_Vectorcall() # 4. call as bound method # 5. call using functools.partial @@ -541,6 +542,27 @@ def vectorcall(func, args, kwargs): kwnames = tuple(kwargs) return pyobject_vectorcall(func, args, kwnames) + for (func, args, kwargs, expected) in calls: + with self.subTest(str(func)): + if not kwargs: + self.assertEqual(expected, pyvectorcall_call(func, args)) + self.assertEqual(expected, pyvectorcall_call(func, args, kwargs)) + + # Add derived classes (which do not support vectorcall directly, + # but do support all other ways of calling). + + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + pass + + class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase): + def __call__(self, n): + return 'new' + + calls += [ + (MethodDescriptorHeap(), (0,), {}, True), + (MethodDescriptorOverridden(), (0,), {}, 'new'), + ] + for (func, args, kwargs, expected) in calls: with self.subTest(str(func)): args1 = args[1:] @@ -549,12 +571,10 @@ def vectorcall(func, args, kwargs): if not kwargs: self.assertEqual(expected, func(*args)) self.assertEqual(expected, pyobject_vectorcall(func, args, None)) - self.assertEqual(expected, pyvectorcall_call(func, args)) self.assertEqual(expected, meth(*args1)) self.assertEqual(expected, wrapped(*args)) self.assertEqual(expected, func(*args, **kwargs)) self.assertEqual(expected, vectorcall(func, args, kwargs)) - self.assertEqual(expected, pyvectorcall_call(func, args, kwargs)) self.assertEqual(expected, meth(*args1, **kwargs)) self.assertEqual(expected, wrapped(*args, **kwargs)) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index bf20e81a4ce888..eed34c9802c341 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5854,7 +5854,7 @@ MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, static PyObject * MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) { - MethodDescriptorObject *op = PyObject_New(MethodDescriptorObject, type); + MethodDescriptorObject *op = type->tp_alloc(type, 0); op->vectorcall = MethodDescriptor_vectorcall; return (PyObject *)op; } diff --git a/Objects/call.c b/Objects/call.c index c0d14567e43037..578e1b3ab61933 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -173,12 +173,22 @@ _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs PyObject * PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) { - vectorcallfunc func = _PyVectorcall_Function(callable); + /* get vectorcallfunc as in _PyVectorcall_Function, but without + * the _Py_TPFLAGS_HAVE_VECTORCALL check */ + Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; + if ((offset <= 0) || (!Py_TYPE(callable)->tp_call)) { + PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", + Py_TYPE(callable)->tp_name); + return NULL; + } + vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset); if (func == NULL) { PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", Py_TYPE(callable)->tp_name); return NULL; } + + /* Convert arguments & call */ PyObject *const *args; Py_ssize_t nargs = PyTuple_GET_SIZE(tuple); PyObject *kwnames; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b6d925c1442e78..76e06aa31d641a 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5145,17 +5145,21 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) } COPYSLOT(tp_repr); /* tp_hash see tp_richcompare */ - COPYSLOT(tp_call); - /* Inherit tp_vectorcall_offset and _Py_TPFLAGS_HAVE_VECTORCALL if tp_call - * was inherited, but only for extension types */ - if ((base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && - !(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && - !(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && - base->tp_call && - type->tp_call == base->tp_call) { - type->tp_vectorcall_offset = base->tp_vectorcall_offset; - type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; + /* Inherit tp_vectorcall_offset only if tp_call is not overridden */ + if (!type->tp_call) { + COPYSLOT(tp_vectorcall_offset); + } + /* Inherit_Py_TPFLAGS_HAVE_VECTORCALL for non-heap types + * if tp_call is not overridden */ + if (!type->tp_call && + (base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && + !(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) && + !(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + { + type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL; + } + COPYSLOT(tp_call); } COPYSLOT(tp_str); { From c6789d6c85a290a35f3839efb52a3d34536dcebe Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 3 Jun 2019 01:45:54 +0300 Subject: [PATCH 272/441] bpo-35621: Fix tests when SafeChildWatcher is expected instead of ThreadedChildWatcher (GH-13754) https://bugs.python.org/issue35621 --- Lib/test/test_asyncio/test_unix_events.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index f7f992fcea49f9..462a8b3c785917 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1836,6 +1836,7 @@ def f(): policy.get_event_loop().close() policy = self.create_policy() + policy.set_child_watcher(asyncio.SafeChildWatcher()) th = threading.Thread(target=f) th.start() From e584cbff1ea78e700cf9943d50467e3b58301ccc Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 3 Jun 2019 01:08:14 +0200 Subject: [PATCH 273/441] bpo-36027 bpo-36974: Fix "incompatible pointer type" compiler warnings (GH-13758) --- Modules/_testcapimodule.c | 2 +- Objects/longobject.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index eed34c9802c341..40e0826ce1263a 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5854,7 +5854,7 @@ MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, static PyObject * MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) { - MethodDescriptorObject *op = type->tp_alloc(type, 0); + MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0); op->vectorcall = MethodDescriptor_vectorcall; return (PyObject *)op; } diff --git a/Objects/longobject.c b/Objects/longobject.c index 49f1420bf64f98..858e256ac0b417 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4243,7 +4243,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) Py_DECREF(c); Py_DECREF(n); - if (long_compare(a, _PyLong_One)) { + if (long_compare(a, (PyObject *)_PyLong_One)) { /* a != 1; we don't have an inverse. */ Py_DECREF(a); Py_DECREF(b); From 0d70227e419ab78c44d81b4ea6ae8aaf769470e6 Mon Sep 17 00:00:00 2001 From: Xtreak Date: Mon, 3 Jun 2019 04:42:33 +0530 Subject: [PATCH 274/441] Fix typos in docs and docstrings (GH-13745) --- Doc/library/dis.rst | 2 +- Doc/using/windows.rst | 2 +- Doc/whatsnew/3.8.rst | 2 +- Lib/asyncio/unix_events.py | 2 +- Lib/bdb.py | 2 +- Lib/distutils/ccompiler.py | 2 +- Lib/email/_header_value_parser.py | 2 +- Lib/encodings/__init__.py | 2 +- Lib/lib2to3/fixes/fix_metaclass.py | 2 +- Lib/pstats.py | 4 ++-- Lib/pyclbr.py | 2 +- Lib/ssl.py | 2 +- Lib/turtle.py | 2 +- Lib/turtledemo/paint.py | 2 +- Lib/zipfile.py | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 15e707ae49f85f..2a3ffb5e827119 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -708,7 +708,7 @@ iterations of the loop. Cleans up the value stack and the block stack. If *preserve_tos* is not ``0`` TOS first is popped from the stack and pushed on the stack after - perfoming other stack operations: + performing other stack operations: * If TOS is ``NULL`` or an integer (pushed by :opcode:`BEGIN_FINALLY` or :opcode:`CALL_FINALLY`) it is popped from the stack. diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index a1b25ffd25f08a..462e4c2b6c63d5 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -815,7 +815,7 @@ Customizing default Python versions In some cases, a version qualifier can be included in a command to dictate which version of Python will be used by the command. A version qualifier starts with a major version number and can optionally be followed by a period -('.') and a minor version specifier. Furthermore it is possible to specifiy +('.') and a minor version specifier. Furthermore it is possible to specify if a 32 or 64 bit implementation shall be requested by adding "-32" or "-64". For example, a shebang line of ``#!python`` has no version qualifier, while diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 74d0079a53db86..e9c9c814c69a19 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1286,7 +1286,7 @@ Changes in the C API (Contributed by Zackery Spytz in :issue:`33407`.) * The interpreter does not pretend to support binary compatibility of - extension types accross feature releases, anymore. A :c:type:`PyTypeObject` + extension types across feature releases, anymore. A :c:type:`PyTypeObject` exported by a third-party extension module is supposed to have all the slots expected in the current Python version, including :c:member:`~PyTypeObject.tp_finalize` (:const:`Py_TPFLAGS_HAVE_FINALIZE` diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 6714542e4e3361..b943845d9363c6 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -193,7 +193,7 @@ async def _make_subprocess_transport(self, protocol, args, shell, # prevents subprocess execution if the watcher # is not ready to handle it. raise RuntimeError("asyncio.get_child_watcher() is not activated, " - "subproccess support is not installed.") + "subprocess support is not installed.") waiter = self.create_future() transp = _UnixSubprocessTransport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, diff --git a/Lib/bdb.py b/Lib/bdb.py index 69174364c46aef..96e7d18d718df9 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -384,7 +384,7 @@ def set_break(self, filename, lineno, temporary=False, cond=None, return None def _prune_breaks(self, filename, lineno): - """Prune breakpoints for filname:lineno. + """Prune breakpoints for filename:lineno. A list of breakpoints is maintained in the Bdb instance and in the Breakpoint class. If a breakpoint in the Bdb instance no diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py index b71d1d39bcda87..1a411ed1113224 100644 --- a/Lib/distutils/ccompiler.py +++ b/Lib/distutils/ccompiler.py @@ -545,7 +545,7 @@ def compile(self, sources, output_dir=None, macros=None, 'extra_preargs' and 'extra_postargs' are implementation- dependent. On platforms that have the notion of a command-line (e.g. Unix, DOS/Windows), they are most likely lists of strings: extra - command-line arguments to prepand/append to the compiler command + command-line arguments to prepend/append to the compiler command line. On other platforms, consult the implementation class documentation. In any event, they are intended as an escape hatch for those occasions when the abstract compiler framework doesn't diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 649f1539fa02ab..14cc00c61e0771 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -2385,7 +2385,7 @@ def parse_mime_parameters(value): the formal RFC grammar, but it is more convenient for us for the set of parameters to be treated as its own TokenList. - This is 'parse' routine because it consumes the reminaing value, but it + This is 'parse' routine because it consumes the remaining value, but it would never be called to parse a full header. Instead it is called to parse everything after the non-parameter value of a specific MIME header. diff --git a/Lib/encodings/__init__.py b/Lib/encodings/__init__.py index d737d5339dce0d..ddd5afdcf2dab0 100644 --- a/Lib/encodings/__init__.py +++ b/Lib/encodings/__init__.py @@ -12,7 +12,7 @@ * getregentry() -> codecs.CodecInfo object The getregentry() API must return a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader - atttributes which adhere to the Python Codec Interface Standard. + attributes which adhere to the Python Codec Interface Standard. In addition, a module may optionally also define the following APIs which are then used by the package's codec search function: diff --git a/Lib/lib2to3/fixes/fix_metaclass.py b/Lib/lib2to3/fixes/fix_metaclass.py index 8e34463bd8ab7e..d1cd10d327587c 100644 --- a/Lib/lib2to3/fixes/fix_metaclass.py +++ b/Lib/lib2to3/fixes/fix_metaclass.py @@ -1,6 +1,6 @@ """Fixer for __metaclass__ = X -> (metaclass=X) methods. - The various forms of classef (inherits nothing, inherits once, inherints + The various forms of classef (inherits nothing, inherits once, inherits many) don't parse the same in the CST so we look at ALL classes for a __metaclass__ and if we find one normalize the inherits to all be an arglist. diff --git a/Lib/pstats.py b/Lib/pstats.py index b7649ebc6f1c65..4b419a8ecdb6c7 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -632,12 +632,12 @@ def do_EOF(self, line): print("", file=self.stream) return 1 def help_EOF(self): - print("Leave the profile brower.", file=self.stream) + print("Leave the profile browser.", file=self.stream) def do_quit(self, line): return 1 def help_quit(self): - print("Leave the profile brower.", file=self.stream) + print("Leave the profile browser.", file=self.stream) def do_read(self, line): if line: diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py index 8fd0523b7e3b96..99a17343fb61fd 100644 --- a/Lib/pyclbr.py +++ b/Lib/pyclbr.py @@ -50,7 +50,7 @@ class _Object: - "Informaton about Python class or function." + "Information about Python class or function." def __init__(self, module, name, file, lineno, parent): self.module = module self.name = name diff --git a/Lib/ssl.py b/Lib/ssl.py index f5fa6aeec2d21b..4afa46e5da5cd5 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -862,7 +862,7 @@ def server_side(self): @property def server_hostname(self): """The currently set server hostname (for SNI), or ``None`` if no - server hostame is set.""" + server hostname is set.""" return self._sslobj.server_hostname def read(self, len=1024, buffer=None): diff --git a/Lib/turtle.py b/Lib/turtle.py index 044d91cf6d837e..ee67a351b54f19 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -833,7 +833,7 @@ def numinput(self, title, prompt, default=None, minval=None, maxval=None): Arguments: title is the title of the dialog window, prompt is a text mostly describing what numerical information to input. default: default value - minval: minimum value for imput + minval: minimum value for input maxval: maximum value for input The number input must be in the range minval .. maxval if these are diff --git a/Lib/turtledemo/paint.py b/Lib/turtledemo/paint.py index dde16912dfed8a..fc6852a20082f5 100755 --- a/Lib/turtledemo/paint.py +++ b/Lib/turtledemo/paint.py @@ -7,7 +7,7 @@ - left mouse button moves turtle - middle mouse button changes color -- right mouse button toogles betweem pen up +- right mouse button toggles between pen up (no line drawn when the turtle moves) and pen down (line is drawn). If pen up follows at least two pen-down moves, the polygon that diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 5496f6eb18678b..62f2fd27d3ce6f 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -2163,7 +2163,7 @@ class Path: >>> (b / 'missing.txt').exists() False - Coersion to string: + Coercion to string: >>> str(c) 'abcde.zip/b/c.txt' From 7f4ae1b2cc60cb69938e7c88793b9e9a2dd36d93 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 3 Jun 2019 01:31:12 +0200 Subject: [PATCH 275/441] bpo-37012: Clean up special cases in PyType_FromSpecWithBases slot assignments (GH-13496) The main slot assignment loop is now if-else if ladder, making the control flow clearer. Based on suggestion by Victor Stinner in: https://github.com/python/cpython/pull/10304/#issuecomment-491123026 --- Objects/typeobject.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 76e06aa31d641a..beb0ddd8240014 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2941,14 +2941,13 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); goto fail; } - if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) + else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) { /* Processed above */ continue; - *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; - - /* need to make a copy of the docstring slot, which usually - points to a static string literal */ - if (slot->slot == Py_tp_doc) { + } + else if (slot->slot == Py_tp_doc) { + /* For the docstring slot, which usually points to a static string + literal, we need to make a copy */ const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); size_t len = strlen(old_doc)+1; char *tp_doc = PyObject_MALLOC(len); @@ -2960,13 +2959,16 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) memcpy(tp_doc, old_doc, len); type->tp_doc = tp_doc; } - - /* Move the slots to the heap type itself */ - if (slot->slot == Py_tp_members) { + else if (slot->slot == Py_tp_members) { + /* Move the slots to the heap type itself */ size_t len = Py_TYPE(type)->tp_itemsize * nmembers; memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len); type->tp_members = PyHeapType_GET_MEMBERS(res); } + else { + /* Copy other slots directly */ + *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; + } } if (type->tp_dealloc == NULL) { /* It's a heap type, so needs the heap types' dealloc. From 3cf7ea1272fbc921a89acdbe40ca152813028cb5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Jun 2019 01:35:37 +0200 Subject: [PATCH 276/441] bpo-37100: Fix test_coroutines with -Werror (GH-13756) test_coroutines: test_unawaited_warning_when_module_broken() now uses support.check_warnings() to catch expected RuntimeWarning. --- Lib/test/test_coroutines.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 0e7eb3a1af47eb..b406b1c3ebf846 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2250,7 +2250,8 @@ async def corofn(): try: warnings._warn_unawaited_coroutine = lambda coro: 1/0 with support.catch_unraisable_exception() as cm, \ - support.captured_stderr() as stream: + support.check_warnings((r'coroutine .* was never awaited', + RuntimeWarning)): # only store repr() to avoid keeping the coroutine alive coro = corofn() coro_repr = repr(coro) @@ -2261,13 +2262,12 @@ async def corofn(): self.assertEqual(repr(cm.unraisable.object), coro_repr) self.assertEqual(cm.unraisable.exc_type, ZeroDivisionError) - self.assertIn("was never awaited", stream.getvalue()) del warnings._warn_unawaited_coroutine - with support.captured_stderr() as stream: + with support.check_warnings((r'coroutine .* was never awaited', + RuntimeWarning)): corofn() support.gc_collect() - self.assertIn("was never awaited", stream.getvalue()) finally: warnings._warn_unawaited_coroutine = orig_wuc From 82eac26a73107ded733110cf11e59e95f41c197e Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Mon, 3 Jun 2019 00:41:00 +0100 Subject: [PATCH 277/441] Update the annotated assignment docs (GH-13757) --- Doc/reference/simple_stmts.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index af7c0caff62797..9c0430da1fb2a4 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -329,7 +329,8 @@ Annotated assignment statements statement, of a variable or attribute annotation and an optional assignment statement: .. productionlist:: - annotated_assignment_stmt: `augtarget` ":" `expression` ["=" `expression`] + annotated_assignment_stmt: `augtarget` ":" `expression` + : ["=" (`expression_list` | `yield_expression`)] The difference from normal :ref:`assignment` is that only single target and only single right hand side value is allowed. @@ -366,6 +367,11 @@ target, then the interpreter evaluates the target except for the last syntax for type annotations that can be used in static analysis tools and IDEs. +.. versionchanged:: 3.8 + Now annotated assignments allow same expressions in the right hand side as + the augmented assignments. Previously, some expressions (like un-parenthesized + tuple expressions) caused a syntax error. + .. _assert: From 9e3e06e582accec82eb29cf665c3b4c7d84d2eb0 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 3 Jun 2019 01:43:13 +0200 Subject: [PATCH 278/441] bpo-36974: document PEP 590 (GH-13450) --- Doc/c-api/object.rst | 77 +++++++++ Doc/c-api/typeobj.rst | 321 +++++++++++++++++++++++--------------- Doc/includes/typestruct.h | 2 +- Doc/whatsnew/3.8.rst | 16 ++ 4 files changed, 293 insertions(+), 123 deletions(-) diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index ffc35241e7a4d7..ce0d05942f4e79 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -335,6 +335,83 @@ Object Protocol *NULL* on failure. +.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) + + Call a callable Python object *callable*, using + :c:data:`vectorcall ` if possible. + + *args* is a C array with the positional arguments. + + *nargsf* is the number of positional arguments plus optionally the flag + :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` (see below). + To get actual number of arguments, use + :c:func:`PyVectorcall_NARGS(nargsf) `. + + *kwnames* can be either NULL (no keyword arguments) or a tuple of keyword + names. In the latter case, the values of the keyword arguments are stored + in *args* after the positional arguments. + The number of keyword arguments does not influence *nargsf*. + + *kwnames* must contain only objects of type ``str`` (not a subclass), + and all keys must be unique. + + Return the result of the call on success, or *NULL* on failure. + + This uses the vectorcall protocol if the callable supports it; + otherwise, the arguments are converted to use + :c:member:`~PyTypeObject.tp_call`. + + .. note:: + + This function is provisional and expected to become public in Python 3.9, + with a different name and, possibly, changed semantics. + If you use the function, plan for updating your code for Python 3.9. + + .. versionadded:: 3.8 + +.. c:var:: PY_VECTORCALL_ARGUMENTS_OFFSET + + If set in a vectorcall *nargsf* argument, the callee is allowed to + temporarily change ``args[-1]``. In other words, *args* points to + argument 1 (not 0) in the allocated vector. + The callee must restore the value of ``args[-1]`` before returning. + + Whenever they can do so cheaply (without additional allocation), callers + are encouraged to use :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`. + Doing so will allow callables such as bound methods to make their onward + calls (which include a prepended *self* argument) cheaply. + + .. versionadded:: 3.8 + +.. c:function:: Py_ssize_t PyVectorcall_NARGS(size_t nargsf) + + Given a vectorcall *nargsf* argument, return the actual number of + arguments. + Currently equivalent to ``nargsf & ~PY_VECTORCALL_ARGUMENTS_OFFSET``. + + .. versionadded:: 3.8 + +.. c:function:: PyObject* _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwdict) + + Same as :c:func:`_PyObject_Vectorcall` except that the keyword arguments + are passed as a dictionary in *kwdict*. This may be *NULL* if there + are no keyword arguments. + + For callables supporting :c:data:`vectorcall `, + the arguments are internally converted to the vectorcall convention. + Therefore, this function adds some overhead compared to + :c:func:`_PyObject_Vectorcall`. + It should only be used if the caller already has a dictionary ready to use. + + .. note:: + + This function is provisional and expected to become public in Python 3.9, + with a different name and, possibly, changed semantics. + If you use the function, plan for updating your code for Python 3.9. + + .. versionadded:: 3.8 + + .. c:function:: Py_hash_t PyObject_Hash(PyObject *o) .. index:: builtin: hash diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index e2f8f54be79ae8..83fcc5abed7079 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -36,115 +36,115 @@ Quick Reference .. table:: :widths: 18,18,18,1,1,1,1 - +---------------------------------------------+-----------------------------------+-------------------+---------------+ - | PyTypeObject Slot [#slots]_ | :ref:`Type ` | special | Info [#cols]_ | - | | | methods/attrs +---+---+---+---+ - | | | | O | T | D | I | - +=============================================+===================================+===================+===+===+===+===+ - | :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | (:c:member:`~PyTypeObject.tp_print`) | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G | - | | | __getattr__ | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | (:c:member:`~PyTypeObject.tp_setattr`) | :c:type:`setattrfunc` | __setattr__, | | | | G | - | | | __delattr__ | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_as_async` | :c:type:`PyAsyncMethods` * | :ref:`sub-slots` | | | | % | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_repr` | :c:type:`reprfunc` | __repr__ | X | X | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_as_number` | :c:type:`PyNumberMethods` * | :ref:`sub-slots` | | | | % | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_as_sequence` | :c:type:`PySequenceMethods` * | :ref:`sub-slots` | | | | % | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_as_mapping` | :c:type:`PyMappingMethods` * | :ref:`sub-slots` | | | | % | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_hash` | :c:type:`hashfunc` | __hash__ | X | | | G | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_call` | :c:type:`ternaryfunc` | __call__ | | X | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_str` | :c:type:`reprfunc` | __str__ | X | | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_getattro` | :c:type:`getattrofunc` | __getattribute__, | X | X | | G | - | | | __getattr__ | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_setattro` | :c:type:`setattrofunc` | __setattr__, | X | X | | G | - | | | __delattr__ | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_as_buffer` | :c:type:`PyBufferProcs` * | | | | | % | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_flags` | unsigned long | | X | X | | ? | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_doc` | const char * | __doc__ | X | X | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_traverse` | :c:type:`traverseproc` | | | X | | G | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_clear` | :c:type:`inquiry` | | | X | | G | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_richcompare` | :c:type:`richcmpfunc` | __lt__, | X | | | G | - | | | __le__, | | | | | - | | | __eq__, | | | | | - | | | __ne__, | | | | | - | | | __gt__, | | | | | - | | | __ge__ | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_iternext` | :c:type:`iternextfunc` | __next__ | | | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_methods` | :c:type:`PyMethodDef` [] | | X | X | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_members` | :c:type:`PyMemberDef` [] | | | X | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_getset` | :c:type:`PyGetSetDef` [] | | X | X | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_base` | :c:type:`PyTypeObject` * | __base__ | | | X | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_dict` | :c:type:`PyObject` * | __dict__ | | | ? | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_descr_get` | :c:type:`descrgetfunc` | __get__ | | | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X | - | | | __delete__ | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_alloc` | :c:type:`allocfunc` | | X | | ? | ? | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_new` | :c:type:`newfunc` | __new__ | X | X | ? | ? | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_free` | :c:type:`freefunc` | | X | X | ? | ? | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_is_gc` | :c:type:`inquiry` | | | X | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | <:c:member:`~PyTypeObject.tp_bases`> | :c:type:`PyObject` * | __bases__ | | | ~ | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | <:c:member:`~PyTypeObject.tp_mro`> | :c:type:`PyObject` * | __mro__ | | | ~ | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | (:c:member:`~PyTypeObject.tp_del`) | :c:type:`destructor` | | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_version_tag`] | unsigned int | | | | | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_finalize` | :c:type:`destructor` | __del__ | | | | X | - +---------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + +------------------------------------------------+-----------------------------------+-------------------+---------------+ + | PyTypeObject Slot [#slots]_ | :ref:`Type ` | special | Info [#cols]_ | + | | | methods/attrs +---+---+---+---+ + | | | | O | T | D | I | + +================================================+===================================+===================+===+===+===+===+ + | :c:member:`~PyTypeObject.tp_name` | const char * | __name__ | X | X | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_basicsize` | Py_ssize_t | | X | X | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_itemsize` | Py_ssize_t | | | X | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_dealloc` | :c:type:`destructor` | | X | X | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_vectorcall_offset` | Py_ssize_t | | | | | ? | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | (:c:member:`~PyTypeObject.tp_getattr`) | :c:type:`getattrfunc` | __getattribute__, | | | | G | + | | | __getattr__ | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | (:c:member:`~PyTypeObject.tp_setattr`) | :c:type:`setattrfunc` | __setattr__, | | | | G | + | | | __delattr__ | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_async` | :c:type:`PyAsyncMethods` * | :ref:`sub-slots` | | | | % | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_repr` | :c:type:`reprfunc` | __repr__ | X | X | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_number` | :c:type:`PyNumberMethods` * | :ref:`sub-slots` | | | | % | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_sequence` | :c:type:`PySequenceMethods` * | :ref:`sub-slots` | | | | % | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_mapping` | :c:type:`PyMappingMethods` * | :ref:`sub-slots` | | | | % | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_hash` | :c:type:`hashfunc` | __hash__ | X | | | G | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_call` | :c:type:`ternaryfunc` | __call__ | | X | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_str` | :c:type:`reprfunc` | __str__ | X | | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_getattro` | :c:type:`getattrofunc` | __getattribute__, | X | X | | G | + | | | __getattr__ | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_setattro` | :c:type:`setattrofunc` | __setattr__, | X | X | | G | + | | | __delattr__ | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_as_buffer` | :c:type:`PyBufferProcs` * | | | | | % | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_flags` | unsigned long | | X | X | | ? | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_doc` | const char * | __doc__ | X | X | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_traverse` | :c:type:`traverseproc` | | | X | | G | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_clear` | :c:type:`inquiry` | | | X | | G | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_richcompare` | :c:type:`richcmpfunc` | __lt__, | X | | | G | + | | | __le__, | | | | | + | | | __eq__, | | | | | + | | | __ne__, | | | | | + | | | __gt__, | | | | | + | | | __ge__ | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_weaklistoffset` | Py_ssize_t | | | X | | ? | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_iternext` | :c:type:`iternextfunc` | __next__ | | | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_methods` | :c:type:`PyMethodDef` [] | | X | X | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_members` | :c:type:`PyMemberDef` [] | | | X | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_getset` | :c:type:`PyGetSetDef` [] | | X | X | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_base` | :c:type:`PyTypeObject` * | __base__ | | | X | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_dict` | :c:type:`PyObject` * | __dict__ | | | ? | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_descr_get` | :c:type:`descrgetfunc` | __get__ | | | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X | + | | | __delete__ | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_dictoffset` | Py_ssize_t | | | X | | ? | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_alloc` | :c:type:`allocfunc` | | X | | ? | ? | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_new` | :c:type:`newfunc` | __new__ | X | X | ? | ? | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_free` | :c:type:`freefunc` | | X | X | ? | ? | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_is_gc` | :c:type:`inquiry` | | | X | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | <:c:member:`~PyTypeObject.tp_bases`> | :c:type:`PyObject` * | __bases__ | | | ~ | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | <:c:member:`~PyTypeObject.tp_mro`> | :c:type:`PyObject` * | __mro__ | | | ~ | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | (:c:member:`~PyTypeObject.tp_del`) | :c:type:`destructor` | | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_version_tag`] | unsigned int | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | :c:member:`~PyTypeObject.tp_finalize` | :c:type:`destructor` | __del__ | | | | X | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ If :const:`COUNT_ALLOCS` is defined then the following (internal-only) fields exist as well: @@ -364,12 +364,6 @@ slot typedefs +-----------------------------+-----------------------------+----------------------+ | :c:type:`reprfunc` | :c:type:`PyObject` * | :c:type:`PyObject` * | +-----------------------------+-----------------------------+----------------------+ -| :c:type:`printfunc` | .. line-block:: | int | -| | | | -| | :c:type:`PyObject` * | | -| | FILE * | | -| | int | | -+-----------------------------+-----------------------------+----------------------+ | :c:type:`getattrfunc` | .. line-block:: | :c:type:`PyObject` * | | | | | | | :c:type:`PyObject` * | | @@ -675,9 +669,66 @@ and :c:type:`PyType_Type` effectively act as defaults.) This field is inherited by subtypes. -.. c:member:: printfunc PyTypeObject.tp_print +.. c:member:: Py_ssize_t PyTypeObject.tp_vectorcall_offset + + An optional offset to a per-instance function that implements calling + the object using the *vectorcall* protocol, a more efficient alternative + of the simpler :c:member:`~PyTypeObject.tp_call`. + + This field is only used if the flag :const:`_Py_TPFLAGS_HAVE_VECTORCALL` + is set. If so, this must be a positive integer containing the offset in the + instance of a :c:type:`vectorcallfunc` pointer. + The signature is the same as for :c:func:`_PyObject_Vectorcall`:: + + PyObject *vectorcallfunc(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) + + The *vectorcallfunc* pointer may be zero, in which case the instance behaves + as if :const:`_Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance + falls back to :c:member:`~PyTypeObject.tp_call`. + + Any class that sets ``_Py_TPFLAGS_HAVE_VECTORCALL`` must also set + :c:member:`~PyTypeObject.tp_call` and make sure its behaviour is consistent + with the *vectorcallfunc* function. + This can be done by setting *tp_call* to ``PyVectorcall_Call``: + + .. c:function:: PyObject *PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict) + + Call *callable*'s *vectorcallfunc* with positional and keyword + arguments given in a tuple and dict, respectively. + + This function is intended to be used in the ``tp_call`` slot. + It does not fall back to ``tp_call`` and it currently does not check the + ``_Py_TPFLAGS_HAVE_VECTORCALL`` flag. + To call an object, use one of the :c:func:`PyObject_Call ` + functions instead. + + .. note:: + + It is not recommended for :ref:`heap types ` to implement + the vectorcall protocol. + When a user sets ``__call__`` in Python code, only ``tp_call`` is updated, + possibly making it inconsistent with the vectorcall function. + + .. note:: + + The semantics of the ``tp_vectorcall_offset`` slot are provisional and + expected to be finalized in Python 3.9. + If you use vectorcall, plan for updating your code for Python 3.9. + + .. versionchanged:: 3.8 + + This slot was used for print formatting in Python 2.x. + In Python 3.0 to 3.7, it was reserved and named ``tp_print``. - Reserved slot, formerly used for print formatting in Python 2.x. + **Inheritance:** + + This field is inherited by subtypes together with + :c:member:`~PyTypeObject.tp_call`: a subtype inherits + :c:member:`~PyTypeObject.tp_vectorcall_offset` from its base type when + the subtype’s :c:member:`~PyTypeObject.tp_call` is NULL. + + Note that `heap types`_ (including subclasses defined in Python) do not + inherit the :const:`_Py_TPFLAGS_HAVE_VECTORCALL` flag. .. c:member:: getattrfunc PyTypeObject.tp_getattr @@ -1104,6 +1155,28 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:member:`~PyTypeObject.tp_finalize` slot is always present in the type structure. + .. data:: _Py_TPFLAGS_HAVE_VECTORCALL + + This bit is set when the class implements the vectorcall protocol. + See :c:member:`~PyTypeObject.tp_vectorcall_offset` for details. + + **Inheritance:** + + This bit is set on *static* subtypes if ``tp_flags`` is not overridden: + a subtype inherits ``_Py_TPFLAGS_HAVE_VECTORCALL`` from its base type + when the subtype’s :c:member:`~PyTypeObject.tp_call` is NULL + and the subtype's ``Py_TPFLAGS_HEAPTYPE`` is not set. + + `Heap types`_ do not inherit ``_Py_TPFLAGS_HAVE_VECTORCALL``. + + .. note:: + + This flag is provisional and expected to become public in Python 3.9, + with a different name and, possibly, changed semantics. + If you use vectorcall, plan for updating your code for Python 3.9. + + .. versionadded:: 3.8 + .. c:member:: const char* PyTypeObject.tp_doc @@ -2286,6 +2359,14 @@ Slot Type typedefs .. c:type:: void (*destructor)(PyObject *) +.. c:type:: PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames) + + See :c:member:`~PyTypeObject.tp_vectorcall_offset`. + + Arguments to ``vectorcallfunc`` are the same as for :c:func:`_PyObject_Vectorcall`. + + .. versionadded:: 3.8 + .. c:type:: void (*freefunc)(void *) See :c:member:`~PyTypeObject.tp_free`. @@ -2302,10 +2383,6 @@ Slot Type typedefs See :c:member:`~PyTypeObject.tp_repr`. -.. c:type:: int (*printfunc)(PyObject *, FILE *, int) - - This is hidden if :const:`PY_LIMITED_API` is set. - .. c:type:: PyObject *(*getattrfunc)(PyObject *self, char *attr) Return the value of the named attribute for the object. @@ -2409,7 +2486,7 @@ with a more verbose initializer:: sizeof(MyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)myobj_dealloc, /* tp_dealloc */ - 0, /* tp_print */ + 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_as_async */ diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h index 9f47899a198e01..9ada03cfc4a4cb 100644 --- a/Doc/includes/typestruct.h +++ b/Doc/includes/typestruct.h @@ -6,7 +6,7 @@ typedef struct _typeobject { /* Methods to implement standard operations */ destructor tp_dealloc; - printfunc tp_print; + Py_ssize_t tp_vectorcall_offset; getattrfunc tp_getattr; setattrfunc tp_setattr; PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index e9c9c814c69a19..9474a2f4aafe6d 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -238,6 +238,22 @@ See :pep:`587` for a full description. (Contributed by Victor Stinner in :issue:`36763`.) +Vectorcall: a fast calling protocol for CPython +----------------------------------------------- + +The "vectorcall" protocol is added to the Python/C API. +It is meant to formalize existing optimizations which were already done +for various classes. +Any extension type implementing a callable can use this protocol. + +This is currently provisional, +the aim is to make it fully public in Python 3.9. + +See :pep:`590` for a full description. + +(Contributed by Jeroen Demeyer and Mark Shannon in :issue:`36974`.) + + Other Language Changes ====================== From be718c33f06b3496faa61142df24fb071fd5d1f1 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Mon, 3 Jun 2019 01:57:22 +0200 Subject: [PATCH 279/441] bpo-36974: add some assertions for PEP 590 (GH-13682) --- Objects/typeobject.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index beb0ddd8240014..006df8d1f090d5 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -5233,6 +5233,20 @@ PyType_Ready(PyTypeObject *type) _PyObject_ASSERT((PyObject *)type, (type->tp_flags & Py_TPFLAGS_READYING) == 0); + /* Consistency checks for PEP 590: + * - Py_TPFLAGS_METHOD_DESCRIPTOR requires tp_descr_get + * - _Py_TPFLAGS_HAVE_VECTORCALL requires tp_call and + * tp_vectorcall_offset > 0 + * To avoid mistakes, we require this before inheriting. + */ + if (type->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) { + _PyObject_ASSERT((PyObject *)type, type->tp_descr_get != NULL); + } + if (type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) { + _PyObject_ASSERT((PyObject *)type, type->tp_vectorcall_offset > 0); + _PyObject_ASSERT((PyObject *)type, type->tp_call != NULL); + } + type->tp_flags |= Py_TPFLAGS_READYING; #ifdef Py_TRACE_REFS From 1e375c6269e9de4f3d05d4aa6d6d74e00f522d63 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 3 Jun 2019 02:28:29 +0200 Subject: [PATCH 280/441] bpo-36027: Really fix "incompatible pointer type" compiler warning (GH-13761) Apologies for the earlier hasty attempt. --- Objects/longobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 858e256ac0b417..a1103f697c7379 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4243,7 +4243,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) Py_DECREF(c); Py_DECREF(n); - if (long_compare(a, (PyObject *)_PyLong_One)) { + if (long_compare(a, (PyLongObject *)_PyLong_One)) { /* a != 1; we don't have an inverse. */ Py_DECREF(a); Py_DECREF(b); From 13136e83a637a9f1cfbada7e93097005296659b4 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Sun, 2 Jun 2019 17:43:22 -0700 Subject: [PATCH 281/441] bpo-36896: Clarify that some types constructors are unstable (GH-13271) --- Doc/library/types.rst | 3 +++ .../Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst diff --git a/Doc/library/types.rst b/Doc/library/types.rst index e629c2935f27f4..a21fb44dda5dec 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -98,6 +98,9 @@ the types that arise only incidentally during processing such as the Typical use of these names is for :func:`isinstance` or :func:`issubclass` checks. + +If you instantiate any of these types, note that signatures may vary between Python versions. + Standard names are defined for the following types: .. data:: FunctionType diff --git a/Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst b/Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst new file mode 100644 index 00000000000000..d75fccad6c0ff1 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst @@ -0,0 +1,2 @@ +Clarify that some types have unstable constructor signature between Python +versions. From 0025350294959594e7f57aef4fc9579c77a0ed1c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Jun 2019 03:51:43 +0200 Subject: [PATCH 282/441] bpo-37069: tests use catch_unraisable_exception() (GH-13762) Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl and test_yield_from to use support.catch_unraisable_exception() rather than support.captured_stderr(). test_thread: remove test_save_exception_state_on_error() which is now updated. test_unraisable_exception() checks that sys.unraisablehook() is called to handle _thread.start_new_thread() exception. test_cprofile now rely on unittest for test discovery: replace support.run_unittest() with unittest.main(). --- Lib/test/test_coroutines.py | 12 +++++-- Lib/test/test_cprofile.py | 32 +++++++------------ Lib/test/test_generators.py | 18 ++++++----- Lib/test/test_raise.py | 5 ++- Lib/test/test_ssl.py | 32 +++++++++++-------- Lib/test/test_thread.py | 21 ------------ Lib/test/test_yield_from.py | 6 ++-- .../2019-06-03-02-30-36.bpo-37069.rVtdLk.rst | 3 ++ 8 files changed, 60 insertions(+), 69 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index b406b1c3ebf846..208b5c2ccf5cd2 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2032,11 +2032,17 @@ async def func(): pass def test_fatal_coro_warning(self): # Issue 27811 async def func(): pass - with warnings.catch_warnings(), support.captured_stderr() as stderr: + with warnings.catch_warnings(), \ + support.catch_unraisable_exception() as cm: warnings.filterwarnings("error") - func() + coro = func() + # only store repr() to avoid keeping the coroutine alive + coro_repr = repr(coro) + coro = None support.gc_collect() - self.assertIn("was never awaited", stderr.getvalue()) + + self.assertIn("was never awaited", str(cm.unraisable.exc_value)) + self.assertEqual(repr(cm.unraisable.object), coro_repr) def test_for_assign_raising_stop_async_iteration(self): class BadTarget: diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index efcf6bc9280372..5c70037f39a2db 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -1,13 +1,13 @@ """Test suite for the cProfile module.""" import sys -from test.support import run_unittest, TESTFN, unlink import unittest # rip off all interesting stuff from test_profile import cProfile from test.test_profile import ProfileTest, regenerate_expected_output from test.support.script_helper import assert_python_failure, assert_python_ok +from test import support class CProfileTest(ProfileTest): @@ -18,24 +18,18 @@ class CProfileTest(ProfileTest): def get_expected_output(self): return _ProfileOutput - # Issue 3895. def test_bad_counter_during_dealloc(self): + # bpo-3895 import _lsprof - # Must use a file as StringIO doesn't trigger the bug. - orig_stderr = sys.stderr - try: - with open(TESTFN, 'w') as file: - sys.stderr = file - try: - obj = _lsprof.Profiler(lambda: int) - obj.enable() - obj = _lsprof.Profiler(1) - obj.disable() - obj.clear() - finally: - sys.stderr = orig_stderr - finally: - unlink(TESTFN) + + with support.catch_unraisable_exception() as cm: + obj = _lsprof.Profiler(lambda: int) + obj.enable() + obj = _lsprof.Profiler(1) + obj.disable() + obj.clear() + + self.assertEqual(cm.unraisable.exc_type, TypeError) def test_profile_enable_disable(self): prof = self.profilerclass() @@ -70,12 +64,10 @@ def test_sort(self): self.assertGreater(rc, 0) self.assertIn(b"option -s: invalid choice: 'demo'", err) -def test_main(): - run_unittest(CProfileTest, TestCommandLine) def main(): if '-r' not in sys.argv: - test_main() + unittest.main() else: regenerate_expected_output(__file__, CProfileTest) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 7f1472fa03ac30..a34e4ec2eda73a 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -2051,15 +2051,17 @@ def printsolution(self, x): Our ill-behaved code should be invoked during GC: ->>> import sys, io ->>> old, sys.stderr = sys.stderr, io.StringIO() ->>> g = f() ->>> next(g) ->>> del g ->>> "RuntimeError: generator ignored GeneratorExit" in sys.stderr.getvalue() +>>> with support.catch_unraisable_exception() as cm: +... g = f() +... next(g) +... del g +... +... cm.unraisable.exc_type == RuntimeError +... "generator ignored GeneratorExit" in str(cm.unraisable.exc_value) +... cm.unraisable.exc_traceback is not None +True +True True ->>> sys.stderr = old - And errors thrown during closing should propagate: diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index c1ef154a9a9f03..57da0e15a756b6 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -459,9 +459,12 @@ def f(): self.assertNotEqual(e.__context__, None) self.assertIsInstance(e.__context__, AttributeError) - with support.captured_output("stderr"): + with support.catch_unraisable_exception() as cm: f() + self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type) + + class TestRemovedFunctionality(unittest.TestCase): def test_tuples(self): try: diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index f368906c8a94f9..a72d7913218128 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -4051,13 +4051,15 @@ def cb_raising(ssl_sock, server_name, initial_context): 1/0 server_context.set_servername_callback(cb_raising) - with self.assertRaises(ssl.SSLError) as cm, \ - support.captured_stderr() as stderr: - stats = server_params_test(client_context, server_context, - chatty=False, - sni_name='supermessage') - self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE') - self.assertIn("ZeroDivisionError", stderr.getvalue()) + with support.catch_unraisable_exception() as catch: + with self.assertRaises(ssl.SSLError) as cm: + stats = server_params_test(client_context, server_context, + chatty=False, + sni_name='supermessage') + + self.assertEqual(cm.exception.reason, + 'SSLV3_ALERT_HANDSHAKE_FAILURE') + self.assertEqual(catch.unraisable.exc_type, ZeroDivisionError) @needs_sni def test_sni_callback_wrong_return_type(self): @@ -4069,13 +4071,15 @@ def cb_wrong_return_type(ssl_sock, server_name, initial_context): return "foo" server_context.set_servername_callback(cb_wrong_return_type) - with self.assertRaises(ssl.SSLError) as cm, \ - support.captured_stderr() as stderr: - stats = server_params_test(client_context, server_context, - chatty=False, - sni_name='supermessage') - self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR') - self.assertIn("TypeError", stderr.getvalue()) + with support.catch_unraisable_exception() as catch: + with self.assertRaises(ssl.SSLError) as cm: + stats = server_params_test(client_context, server_context, + chatty=False, + sni_name='supermessage') + + + self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR') + self.assertEqual(catch.unraisable.exc_type, TypeError) def test_shared_ciphers(self): client_context, server_context, hostname = testing_context() diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index f946f7bc839928..9f4801f47e3aaa 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -133,27 +133,6 @@ def task(): time.sleep(POLL_SLEEP) self.assertEqual(thread._count(), orig) - def test_save_exception_state_on_error(self): - # See issue #14474 - def task(): - started.release() - raise SyntaxError - def mywrite(self, *args): - try: - raise ValueError - except ValueError: - pass - real_write(self, *args) - started = thread.allocate_lock() - with support.captured_output("stderr") as stderr: - real_write = stderr.write - stderr.write = mywrite - started.acquire() - with support.wait_threads_exit(): - thread.start_new_thread(task, ()) - started.acquire() - self.assertIn("Traceback", stderr.getvalue()) - def test_unraisable_exception(self): def task(): started.release() diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py index ce21c3df814037..4735ef4bee3b36 100644 --- a/Lib/test/test_yield_from.py +++ b/Lib/test/test_yield_from.py @@ -11,6 +11,7 @@ import inspect from test.support import captured_stderr, disable_gc, gc_collect +from test import support class TestPEP380Operation(unittest.TestCase): """ @@ -562,11 +563,12 @@ def g(): self.assertEqual(next(gi), 1) gi.throw(AttributeError) - with captured_stderr() as output: + with support.catch_unraisable_exception() as cm: gi = g() self.assertEqual(next(gi), 1) gi.close() - self.assertIn('ZeroDivisionError', output.getvalue()) + + self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type) def test_exception_in_initial_next_call(self): """ diff --git a/Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst b/Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst new file mode 100644 index 00000000000000..566ff5150d5f95 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst @@ -0,0 +1,3 @@ +Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl +and test_yield_from to use :func:`test.support.catch_unraisable_exception` +rather than :func:`test.support.captured_stderr`. From 01ee12ba35a333e8a6a25c4153c4a21838e9585c Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Sun, 2 Jun 2019 23:14:48 -0300 Subject: [PATCH 283/441] bpo-33569 Preserve type information with dataclasses.InitVar (GH-8927) --- Lib/dataclasses.py | 13 ++++++++++--- Lib/test/test_dataclasses.py | 6 ++++++ .../2018-08-28-03-00-12.bpo-33569.45YlGG.rst | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 75113f123b3af1..b035cbb809f848 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -201,10 +201,16 @@ def __repr__(self): class _InitVarMeta(type): def __getitem__(self, params): - return self + return InitVar(params) class InitVar(metaclass=_InitVarMeta): - pass + __slots__ = ('type', ) + + def __init__(self, type): + self.type = type + + def __repr__(self): + return f'dataclasses.InitVar[{self.type.__name__}]' # Instances of Field are only ever created from within this module, @@ -586,7 +592,8 @@ def _is_classvar(a_type, typing): def _is_initvar(a_type, dataclasses): # The module we're checking against is the module we're # currently in (dataclasses.py). - return a_type is dataclasses.InitVar + return (a_type is dataclasses.InitVar + or type(a_type) is dataclasses.InitVar) def _is_type(annotation, cls, a_module, a_type, is_type_predicate): diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 867210688f5737..53e8443c2adf17 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -1097,6 +1097,12 @@ def __post_init__(self, init_param): c = C(init_param=10) self.assertEqual(c.x, 20) + def test_init_var_preserve_type(self): + self.assertEqual(InitVar[int].type, int) + + # Make sure the repr is correct. + self.assertEqual(repr(InitVar[int]), 'dataclasses.InitVar[int]') + def test_init_var_inheritance(self): # Note that this deliberately tests that a dataclass need not # have a __post_init__ function if it has an InitVar field. diff --git a/Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst b/Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst new file mode 100644 index 00000000000000..adafa2803ae399 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst @@ -0,0 +1 @@ +dataclasses.InitVar: Exposes the type used to create the init var. From d337169156933eaf732566bf29eb968549ada5e8 Mon Sep 17 00:00:00 2001 From: cclauss Date: Mon, 3 Jun 2019 05:19:44 +0200 Subject: [PATCH 284/441] Fix variable name copy/paste error in build-installer.py (GH-13038) --- Mac/BuildScript/build-installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index fb43da5478f728..60e28fee055d9c 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1540,7 +1540,7 @@ def buildDMG(): print(" -- retrying hdiutil create") time.sleep(5) else: - raise RuntimeError("command failed: %s"%(commandline,)) + raise RuntimeError("command failed: %s"%(cmd,)) if not os.path.exists(os.path.join(WORKDIR, "mnt")): os.mkdir(os.path.join(WORKDIR, "mnt")) From cba9f84725353455b0995bd47d0fa8cb1724464b Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sun, 2 Jun 2019 21:07:43 -0700 Subject: [PATCH 285/441] bpo-36546: Add design notes to aid future discussions (GH-13769) --- Lib/statistics.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Lib/statistics.py b/Lib/statistics.py index 19db8e82801013..012845b8d2ef4c 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -564,6 +564,45 @@ def multimode(data): maxcount, mode_items = next(groupby(counts, key=itemgetter(1)), (0, [])) return list(map(itemgetter(0), mode_items)) +# Notes on methods for computing quantiles +# ---------------------------------------- +# +# There is no one perfect way to compute quantiles. Here we offer +# two methods that serve common needs. Most other packages +# surveyed offered at least one or both of these two, making them +# "standard" in the sense of "widely-adopted and reproducible". +# They are also easy to explain, easy to compute manually, and have +# straight-forward interpretations that aren't surprising. + +# The default method is known as "R6", "PERCENTILE.EXC", or "expected +# value of rank order statistics". The alternative method is known as +# "R7", "PERCENTILE.INC", or "mode of rank order statistics". + +# For sample data where there is a positive probability for values +# beyond the range of the data, the R6 exclusive method is a +# reasonable choice. Consider a random sample of nine values from a +# population with a uniform distribution from 0.0 to 100.0. The +# distribution of the third ranked sample point is described by +# betavariate(alpha=3, beta=7) which has mode=0.250, median=0.286, and +# mean=0.300. Only the latter (which corresponds with R6) gives the +# desired cut point with 30% of the population falling below that +# value, making it comparable to a result from an inv_cdf() function. + +# For describing population data where the end points are known to +# be included in the data, the R7 inclusive method is a reasonable +# choice. Instead of the mean, it uses the mode of the beta +# distribution for the interior points. Per Hyndman & Fan, "One nice +# property is that the vertices of Q7(p) divide the range into n - 1 +# intervals, and exactly 100p% of the intervals lie to the left of +# Q7(p) and 100(1 - p)% of the intervals lie to the right of Q7(p)." + +# If the need arises, we could add method="median" for a median +# unbiased, distribution-free alternative. Also if needed, the +# distribution-free approaches could be augmented by adding +# method='normal'. However, for now, the position is that fewer +# options make for easier choices and that external packages can be +# used for anything more advanced. + def quantiles(dist, *, n=4, method='exclusive'): '''Divide *dist* into *n* continuous intervals with equal probability. From d9677f36fe486e86bb86f2cd59cb7fc3804bdac1 Mon Sep 17 00:00:00 2001 From: Xtreak Date: Mon, 3 Jun 2019 09:51:15 +0530 Subject: [PATCH 286/441] IDLE: Fix typos in docs and comments (GH-13749) --- Lib/idlelib/config.py | 2 +- Lib/idlelib/configdialog.py | 2 +- Lib/idlelib/delegator.py | 2 +- Lib/idlelib/editor.py | 2 +- Lib/idlelib/idle_test/htest.py | 2 +- Lib/idlelib/idle_test/mock_tk.py | 2 +- Lib/idlelib/idle_test/test_pyparse.py | 2 +- Lib/idlelib/search.py | 2 +- Lib/idlelib/searchbase.py | 2 +- Lib/idlelib/squeezer.py | 2 +- Lib/idlelib/undo.py | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index aa94d6535be6bb..12113c19c08672 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -12,7 +12,7 @@ there are separate dicts for default and user values. Each has config-type keys 'main', 'extensions', 'highlight', and 'keys'. The value for each key is a ConfigParser instance that maps section and item -to values. For 'main' and 'extenstons', user values override +to values. For 'main' and 'extensions', user values override default values. For 'highlight' and 'keys', user sections augment the default sections (and must, therefore, have distinct names). diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 4aaec1321f7d68..807ff60413d1b0 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -199,7 +199,7 @@ def destroy(self): def help(self): """Create textview for config dialog help. - Attrbutes accessed: + Attributes accessed: note Methods: diff --git a/Lib/idlelib/delegator.py b/Lib/idlelib/delegator.py index dc2a1aaeeab74e..55c95da8532f47 100644 --- a/Lib/idlelib/delegator.py +++ b/Lib/idlelib/delegator.py @@ -14,7 +14,7 @@ def __getattr__(self, name): def resetcache(self): "Removes added attributes while leaving original attributes." - # Function is really about resetting delagator dict + # Function is really about resetting delegator dict # to original state. Cache is just a means for key in self.__cache: try: diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 89b7239a96ea0e..a6674728cd9374 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -315,7 +315,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.CodeContext(self).toggle_code_context_event) def _filename_to_unicode(self, filename): - """Return filename as BMP unicode so diplayable in Tk.""" + """Return filename as BMP unicode so displayable in Tk.""" # Decode bytes to unicode. if isinstance(filename, bytes): try: diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py index 429081f7ef25a8..6e3398ed0bc8db 100644 --- a/Lib/idlelib/idle_test/htest.py +++ b/Lib/idlelib/idle_test/htest.py @@ -12,7 +12,7 @@ The first parameter of X must be 'parent'. When called, the parent argument will be the root window. X must create a child Toplevel window (or subclass thereof). The Toplevel may be a test widget or -dialog, in which case the callable is the corresonding class. Or the +dialog, in which case the callable is the corresponding class. Or the Toplevel may contain the widget to be tested or set up a context in which a test widget is invoked. In this latter case, the callable is a wrapper function that sets up the Toplevel and other objects. Wrapper diff --git a/Lib/idlelib/idle_test/mock_tk.py b/Lib/idlelib/idle_test/mock_tk.py index a54f51f1949c08..576f7d5d609e4d 100644 --- a/Lib/idlelib/idle_test/mock_tk.py +++ b/Lib/idlelib/idle_test/mock_tk.py @@ -37,7 +37,7 @@ class Mbox_func: """Generic mock for messagebox functions, which all have the same signature. Instead of displaying a message box, the mock's call method saves the - arguments as instance attributes, which test functions can then examime. + arguments as instance attributes, which test functions can then examine. The test can set the result returned to ask function """ def __init__(self, result=None): diff --git a/Lib/idlelib/idle_test/test_pyparse.py b/Lib/idlelib/idle_test/test_pyparse.py index 0534301b36102f..479b84a216b02c 100644 --- a/Lib/idlelib/idle_test/test_pyparse.py +++ b/Lib/idlelib/idle_test/test_pyparse.py @@ -160,7 +160,7 @@ def test_study1(self): TestInfo('\n def function1(self, a,\n', [0, 1, 2], BRACKET), TestInfo('())\n', [0, 1], NONE), # Extra closer. TestInfo(')(\n', [0, 1], BRACKET), # Extra closer. - # For the mismatched example, it doesn't look like contination. + # For the mismatched example, it doesn't look like continuation. TestInfo('{)(]\n', [0, 1], NONE), # Mismatched. ) diff --git a/Lib/idlelib/search.py b/Lib/idlelib/search.py index 5bbe9d6b5dc8a1..b35f3b59c3d2e8 100644 --- a/Lib/idlelib/search.py +++ b/Lib/idlelib/search.py @@ -80,7 +80,7 @@ def find_again(self, text): If no search was previously run, open a new search dialog. In this case, no search is done. - If a seach was previously run, the search dialog won't be + If a search was previously run, the search dialog won't be shown and the options from the previous search (including the search pattern) will be used to find the next occurrence of the pattern. Next is relative based on direction. diff --git a/Lib/idlelib/searchbase.py b/Lib/idlelib/searchbase.py index 74ba8538512b9d..4ed94f186b048d 100644 --- a/Lib/idlelib/searchbase.py +++ b/Lib/idlelib/searchbase.py @@ -36,7 +36,7 @@ def __init__(self, root, engine): text (Text searched): set in open(), only used in subclasses(). ent (ry): created in make_entry() called from create_entry(). row (of grid): 0 in create_widgets(), +1 in make_entry/frame(). - default_command: set in subclasses, used in create_widgers(). + default_command: set in subclasses, used in create_widgets(). title (of dialog): class attribute, override in subclasses. icon (of dialog): ditto, use unclear if cannot minimize dialog. diff --git a/Lib/idlelib/squeezer.py b/Lib/idlelib/squeezer.py index 869498d753a2cd..032401f2abc738 100644 --- a/Lib/idlelib/squeezer.py +++ b/Lib/idlelib/squeezer.py @@ -6,7 +6,7 @@ completely unusable. This extension will automatically replace long texts with a small button. -Double-cliking this button will remove it and insert the original text instead. +Double-clicking this button will remove it and insert the original text instead. Middle-clicking will copy the text to the clipboard. Right-clicking will open the text in a separate viewing window. diff --git a/Lib/idlelib/undo.py b/Lib/idlelib/undo.py index f048994b7d15c3..85ecffecb4cbcb 100644 --- a/Lib/idlelib/undo.py +++ b/Lib/idlelib/undo.py @@ -2,7 +2,7 @@ from idlelib.delegator import Delegator -# tkintter import not needed because module does not create widgets, +# tkinter import not needed because module does not create widgets, # although many methods operate on text widget arguments. #$ event <> From 8565f6b6db0fa9f65449b532a5056a98bad3dc37 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Mon, 3 Jun 2019 08:34:20 +0100 Subject: [PATCH 287/441] bpo-35814: Allow unpacking in r.h.s of annotated assignment expressions (GH-13760) --- Grammar/Grammar | 2 +- Lib/test/test_grammar.py | 4 ++++ .../2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst | 2 ++ Python/ast.c | 2 +- Python/graminit.c | 2 +- 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst diff --git a/Grammar/Grammar b/Grammar/Grammar index 0cacfb648e9abb..21f7e1a89115b2 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -84,7 +84,7 @@ small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt) expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) | [('=' (yield_expr|testlist_star_expr))+ [TYPE_COMMENT]] ) -annassign: ':' test ['=' (yield_expr|testlist)] +annassign: ':' test ['=' (yield_expr|testlist_star_expr)] testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 2a3b71fac4a5a0..78d94593c7f322 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -454,6 +454,10 @@ def test_var_annot_rhs(self): exec(stmt, ns) self.assertEqual(list(ns['f']()), [None]) + ns = {"a": 1, 'b': (2, 3, 4), "c":5, "Tuple": typing.Tuple} + exec('x: Tuple[int, ...] = a,*b,c', ns) + self.assertEqual(ns['x'], (1, 2, 3, 4, 5)) + def test_funcdef(self): ### [decorators] 'def' NAME parameters ['->' test] ':' suite ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst new file mode 100644 index 00000000000000..2b9f00a6d9e7cf --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst @@ -0,0 +1,2 @@ +Allow unpacking in the right hand side of annotated assignments. In +particular, ``t: Tuple[int, ...] = x, y, *z`` is now allowed. diff --git a/Python/ast.c b/Python/ast.c index b77552274d2443..df9242977e3f21 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -3398,7 +3398,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) } else { ch = CHILD(ann, 3); - if (TYPE(ch) == testlist) { + if (TYPE(ch) == testlist_star_expr) { expr3 = ast_for_testlist(c, ch); } else { diff --git a/Python/graminit.c b/Python/graminit.c index 0587b1c0fc105d..7c40ce933c1d61 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -742,7 +742,7 @@ static const arc arcs_17_2[2] = { {0, 2}, }; static const arc arcs_17_3[2] = { - {47, 4}, + {81, 4}, {84, 4}, }; static const arc arcs_17_4[1] = { From 0288dd6a5192074fcd5aa0db5d3513c3880209ca Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Mon, 3 Jun 2019 06:34:48 -0400 Subject: [PATCH 288/441] bpo-36231: Support building on macOS without /usr/include (GH-13773) --- .../2019-06-03-05-49-49.bpo-36231.RfmW_p.rst | 3 ++ setup.py | 52 ++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst diff --git a/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst b/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst new file mode 100644 index 00000000000000..c82e54c12c89fe --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst @@ -0,0 +1,3 @@ +Support building Python on macOS without /usr/include installed. As of macOS +10.14, system header files are only available within an SDK provided by +either the Command Line Tools or the Xcode app. diff --git a/setup.py b/setup.py index 7852c2dfa27e08..598f5819f8f34e 100644 --- a/setup.py +++ b/setup.py @@ -125,19 +125,57 @@ def sysroot_paths(make_vars, subdirs): break return dirs +MACOS_SDK_ROOT = None def macosx_sdk_root(): + """Return the directory of the current macOS SDK. + + If no SDK was explicitly configured, call the compiler to find which + include files paths are being searched by default. Use '/' if the + compiler is searching /usr/include (meaning system header files are + installed) or use the root of an SDK if that is being searched. + (The SDK may be supplied via Xcode or via the Command Line Tools). + The SDK paths used by Apple-supplied tool chains depend on the + setting of various variables; see the xcrun man page for more info. """ - Return the directory of the current OSX SDK, - or '/' if no SDK was specified. - """ + global MACOS_SDK_ROOT + + # If already called, return cached result. + if MACOS_SDK_ROOT: + return MACOS_SDK_ROOT + cflags = sysconfig.get_config_var('CFLAGS') m = re.search(r'-isysroot\s+(\S+)', cflags) - if m is None: - sysroot = '/' + if m is not None: + MACOS_SDK_ROOT = m.group(1) else: - sysroot = m.group(1) - return sysroot + MACOS_SDK_ROOT = '/' + cc = sysconfig.get_config_var('CC') + tmpfile = '/tmp/setup_sdk_root.%d' % os.getpid() + try: + os.unlink(tmpfile) + except: + pass + ret = os.system('%s -E -v - %s 1>/dev/null' % (cc, tmpfile)) + in_incdirs = False + try: + if ret >> 8 == 0: + with open(tmpfile) as fp: + for line in fp.readlines(): + if line.startswith("#include <...>"): + in_incdirs = True + elif line.startswith("End of search list"): + in_incdirs = False + elif in_incdirs: + line = line.strip() + if line == '/usr/include': + MACOS_SDK_ROOT = '/' + elif line.endswith(".sdk/usr/include"): + MACOS_SDK_ROOT = line[:-12] + finally: + os.unlink(tmpfile) + + return MACOS_SDK_ROOT def is_macosx_sdk_path(path): From 29ec4228106ed5f970d1c3666614f4a51bad192c Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Mon, 3 Jun 2019 08:00:25 -0400 Subject: [PATCH 289/441] Pin macOS installer Sphinx to v2.0.1 (GH-13774) --- Mac/BuildScript/build-installer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index 60e28fee055d9c..2c606b9df67452 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1058,6 +1058,7 @@ def buildPythonDocs(): runCommand('make clean') # Create virtual environment for docs builds with blurb and sphinx runCommand('make venv') + runCommand('venv/bin/python3 -m pip install -U Sphinx==2.0.1') runCommand('make html PYTHON=venv/bin/python') os.chdir(curDir) if not os.path.exists(docdir): From 91234a16367b56ca03ee289f7c03a34d4cfec4c8 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 3 Jun 2019 21:30:58 +0900 Subject: [PATCH 290/441] bpo-26219: per opcode cache for LOAD_GLOBAL (GH-12884) This patch implements per opcode cache mechanism, and use it in only LOAD_GLOBAL opcode. Based on Yury's opcache3.patch in bpo-26219. --- Doc/whatsnew/3.8.rst | 4 + Include/code.h | 17 +++ Include/internal/pycore_ceval.h | 3 + Include/internal/pycore_code.h | 27 ++++ Lib/test/test_dict_version.py | 6 +- Makefile.pre.in | 1 + .../2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst | 3 + Objects/codeobject.c | 65 ++++++++ Objects/dictobject.c | 25 +-- PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 + Python/ceval.c | 143 +++++++++++++++++- Python/pylifecycle.c | 3 + 13 files changed, 285 insertions(+), 16 deletions(-) create mode 100644 Include/internal/pycore_code.h create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 9474a2f4aafe6d..da97a728509992 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -860,6 +860,10 @@ Optimizations methods up to 20--50%. (Contributed by Serhiy Storchaka in :issue:`23867`, :issue:`35582` and :issue:`36127`.) +* ``LOAD_GLOBAL`` instruction now uses new "per opcode cache" mechanism. + It is about 40% faster now. (Contributed by Yury Selivanov and Inada Naoki in + :issue:`26219`.) + Build and C API Changes ======================= diff --git a/Include/code.h b/Include/code.h index 933de97d078282..b79d977394e026 100644 --- a/Include/code.h +++ b/Include/code.h @@ -17,6 +17,8 @@ typedef uint16_t _Py_CODEUNIT; # define _Py_OPARG(word) ((word) >> 8) #endif +typedef struct _PyOpcache _PyOpcache; + /* Bytecode object */ typedef struct { PyObject_HEAD @@ -49,6 +51,21 @@ typedef struct { Type is a void* to keep the format private in codeobject.c to force people to go through the proper APIs. */ void *co_extra; + + /* Per opcodes just-in-time cache + * + * To reduce cache size, we use indirect mapping from opcode index to + * cache object: + * cache = co_opcache[co_opcache_map[next_instr - first_instr] - 1] + */ + + // co_opcache_map is indexed by (next_instr - first_instr). + // * 0 means there is no cache for this opcode. + // * n > 0 means there is cache in co_opcache[n-1]. + unsigned char *co_opcache_map; + _PyOpcache *co_opcache; + int co_opcache_flag; // used to determine when create a cache. + unsigned char co_opcache_size; // length of co_opcache. } PyCodeObject; /* Masks for co_flags above */ diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index d44afdf4fa46a5..2c6df9a9af9e3b 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -31,6 +31,9 @@ PyAPI_FUNC(void) _PyEval_SignalAsyncExc( PyAPI_FUNC(void) _PyEval_ReInitThreads( _PyRuntimeState *runtime); +/* Private function */ +void _PyEval_Fini(void); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h new file mode 100644 index 00000000000000..88956f109b4f79 --- /dev/null +++ b/Include/internal/pycore_code.h @@ -0,0 +1,27 @@ +#ifndef Py_INTERNAL_CODE_H +#define Py_INTERNAL_CODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject *ptr; /* Cached pointer (borrowed reference) */ + uint64_t globals_ver; /* ma_version of global dict */ + uint64_t builtins_ver; /* ma_version of builtin dict */ +} _PyOpcache_LoadGlobal; + +struct _PyOpcache { + union { + _PyOpcache_LoadGlobal lg; + } u; + char optimized; +}; + +/* Private API */ +int _PyCode_InitOpcache(PyCodeObject *co); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CODE_H */ diff --git a/Lib/test/test_dict_version.py b/Lib/test/test_dict_version.py index 5671f9fc7c2265..cb79e7434c29d4 100644 --- a/Lib/test/test_dict_version.py +++ b/Lib/test/test_dict_version.py @@ -80,14 +80,14 @@ def test_setitem_same_value(self): # setting a key to the same value with dict.__setitem__ # must change the version - self.check_version_changed(d, d.__setitem__, 'key', value) + self.check_version_dont_change(d, d.__setitem__, 'key', value) # setting a key to the same value with dict.update # must change the version - self.check_version_changed(d, d.update, key=value) + self.check_version_dont_change(d, d.update, key=value) d2 = self.new_dict(key=value) - self.check_version_changed(d, d.update, d2) + self.check_version_dont_change(d, d.update, d2) def test_setitem_equal(self): class AlwaysEqual: diff --git a/Makefile.pre.in b/Makefile.pre.in index 0bf5df4b68e57b..a0bc9c1f1cc897 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1070,6 +1070,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_atomic.h \ $(srcdir)/Include/internal/pycore_ceval.h \ + $(srcdir)/Include/internal/pycore_code.h \ $(srcdir)/Include/internal/pycore_condvar.h \ $(srcdir)/Include/internal/pycore_context.h \ $(srcdir)/Include/internal/pycore_fileutils.h \ diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst new file mode 100644 index 00000000000000..a4ee7b580bc899 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst @@ -0,0 +1,3 @@ +Implemented per opcode cache mechanism and ``LOAD_GLOBAL`` instruction use +it. ``LOAD_GLOBAL`` is now about 40% faster. Contributed by Yury Selivanov, +and Inada Naoki. diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 233307562a5537..0d9e5d16e76815 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -2,7 +2,9 @@ #include "Python.h" #include "code.h" +#include "opcode.h" #include "structmember.h" +#include "pycore_code.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" #include "clinic/codeobject.c.h" @@ -233,9 +235,56 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, co->co_zombieframe = NULL; co->co_weakreflist = NULL; co->co_extra = NULL; + + co->co_opcache_map = NULL; + co->co_opcache = NULL; + co->co_opcache_flag = 0; + co->co_opcache_size = 0; return co; } +int +_PyCode_InitOpcache(PyCodeObject *co) +{ + Py_ssize_t co_size = PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT); + co->co_opcache_map = (unsigned char *)PyMem_Calloc(co_size, 1); + if (co->co_opcache_map == NULL) { + return -1; + } + + _Py_CODEUNIT *opcodes = (_Py_CODEUNIT*)PyBytes_AS_STRING(co->co_code); + Py_ssize_t opts = 0; + + for (Py_ssize_t i = 0; i < co_size;) { + unsigned char opcode = _Py_OPCODE(opcodes[i]); + i++; // 'i' is now aligned to (next_instr - first_instr) + + // TODO: LOAD_METHOD, LOAD_ATTR + if (opcode == LOAD_GLOBAL) { + co->co_opcache_map[i] = ++opts; + if (opts > 254) { + break; + } + } + } + + if (opts) { + co->co_opcache = (_PyOpcache *)PyMem_Calloc(opts, sizeof(_PyOpcache)); + if (co->co_opcache == NULL) { + PyMem_FREE(co->co_opcache_map); + return -1; + } + } + else { + PyMem_FREE(co->co_opcache_map); + co->co_opcache_map = NULL; + co->co_opcache = NULL; + } + + co->co_opcache_size = opts; + return 0; +} + PyCodeObject * PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) { @@ -458,6 +507,15 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) static void code_dealloc(PyCodeObject *co) { + if (co->co_opcache != NULL) { + PyMem_FREE(co->co_opcache); + } + if (co->co_opcache_map != NULL) { + PyMem_FREE(co->co_opcache_map); + } + co->co_opcache_flag = 0; + co->co_opcache_size = 0; + if (co->co_extra != NULL) { PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); _PyCodeObjectExtra *co_extra = co->co_extra; @@ -504,6 +562,13 @@ code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) res += sizeof(_PyCodeObjectExtra) + (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]); } + if (co->co_opcache != NULL) { + assert(co->co_opcache_map != NULL); + // co_opcache_map + res += PyBytes_GET_SIZE(co->co_code) / sizeof(_Py_CODEUNIT); + // co_opcache + res += co->co_opcache_size * sizeof(_PyOpcache); + } return PyLong_FromSsize_t(res); } diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 2b04b0b679651a..0cc14437500699 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1080,20 +1080,21 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) return 0; } - if (_PyDict_HasSplitTable(mp)) { - mp->ma_values[ix] = value; - if (old_value == NULL) { - /* pending state */ - assert(ix == mp->ma_used); - mp->ma_used++; + if (old_value != value) { + if (_PyDict_HasSplitTable(mp)) { + mp->ma_values[ix] = value; + if (old_value == NULL) { + /* pending state */ + assert(ix == mp->ma_used); + mp->ma_used++; + } } + else { + assert(old_value != NULL); + DK_ENTRIES(mp->ma_keys)[ix].me_value = value; + } + mp->ma_version_tag = DICT_NEXT_VERSION(); } - else { - assert(old_value != NULL); - DK_ENTRIES(mp->ma_keys)[ix].me_value = value; - } - - mp->ma_version_tag = DICT_NEXT_VERSION(); Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ ASSERT_CONSISTENT(mp); Py_DECREF(key); diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 329f9feb2bdf02..89625da944e1ab 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -158,6 +158,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index d80d05fb15a0cf..63ab88b4a01ddc 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -177,6 +177,9 @@ Include + + Include + Include diff --git a/Python/ceval.c b/Python/ceval.c index a092a235564136..411ba3d73c5f2e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -11,6 +11,7 @@ #include "Python.h" #include "pycore_ceval.h" +#include "pycore_code.h" #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" @@ -101,6 +102,20 @@ static long dxp[256]; #endif #endif +/* per opcode cache */ +#define OPCACHE_MIN_RUNS 1024 /* create opcache when code executed this time */ +#define OPCACHE_STATS 0 /* Enable stats */ + +#if OPCACHE_STATS +static size_t opcache_code_objects = 0; +static size_t opcache_code_objects_extra_mem = 0; + +static size_t opcache_global_opts = 0; +static size_t opcache_global_hits = 0; +static size_t opcache_global_misses = 0; +#endif + + /* This can set eval_breaker to 0 even though gil_drop_request became 1. We believe this is all right because the eval loop will release the GIL eventually anyway. */ @@ -225,6 +240,35 @@ exit_thread_if_finalizing(PyThreadState *tstate) } } +void +_PyEval_Fini(void) +{ +#if OPCACHE_STATS + fprintf(stderr, "-- Opcode cache number of objects = %zd\n", + opcache_code_objects); + + fprintf(stderr, "-- Opcode cache total extra mem = %zd\n", + opcache_code_objects_extra_mem); + + fprintf(stderr, "\n"); + + fprintf(stderr, "-- Opcode cache LOAD_GLOBAL hits = %zd (%d%%)\n", + opcache_global_hits, + (int) (100.0 * opcache_global_hits / + (opcache_global_hits + opcache_global_misses))); + + fprintf(stderr, "-- Opcode cache LOAD_GLOBAL misses = %zd (%d%%)\n", + opcache_global_misses, + (int) (100.0 * opcache_global_misses / + (opcache_global_hits + opcache_global_misses))); + + fprintf(stderr, "-- Opcode cache LOAD_GLOBAL opts = %zd\n", + opcache_global_opts); + + fprintf(stderr, "\n"); +#endif +} + void PyEval_AcquireLock(void) { @@ -799,6 +843,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) const _Py_CODEUNIT *first_instr; PyObject *names; PyObject *consts; + _PyOpcache *co_opcache; #ifdef LLTRACE _Py_IDENTIFIER(__ltrace__); @@ -1061,6 +1106,49 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) Py_XDECREF(traceback); \ } while(0) + /* macros for opcode cache */ +#define OPCACHE_CHECK() \ + do { \ + co_opcache = NULL; \ + if (co->co_opcache != NULL) { \ + unsigned char co_opt_offset = \ + co->co_opcache_map[next_instr - first_instr]; \ + if (co_opt_offset > 0) { \ + assert(co_opt_offset <= co->co_opcache_size); \ + co_opcache = &co->co_opcache[co_opt_offset - 1]; \ + assert(co_opcache != NULL); \ + if (co_opcache->optimized < 0) { \ + co_opcache = NULL; \ + } \ + } \ + } \ + } while (0) + +#if OPCACHE_STATS + +#define OPCACHE_STAT_GLOBAL_HIT() \ + do { \ + if (co->co_opcache != NULL) opcache_global_hits++; \ + } while (0) + +#define OPCACHE_STAT_GLOBAL_MISS() \ + do { \ + if (co->co_opcache != NULL) opcache_global_misses++; \ + } while (0) + +#define OPCACHE_STAT_GLOBAL_OPT() \ + do { \ + if (co->co_opcache != NULL) opcache_global_opts++; \ + } while (0) + +#else /* OPCACHE_STATS */ + +#define OPCACHE_STAT_GLOBAL_HIT() +#define OPCACHE_STAT_GLOBAL_MISS() +#define OPCACHE_STAT_GLOBAL_OPT() + +#endif + /* Start of code */ /* push frame */ @@ -1142,6 +1230,20 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */ f->f_executing = 1; + if (co->co_opcache_flag < OPCACHE_MIN_RUNS) { + co->co_opcache_flag++; + if (co->co_opcache_flag == OPCACHE_MIN_RUNS) { + if (_PyCode_InitOpcache(co) < 0) { + return NULL; + } +#if OPCACHE_STATS + opcache_code_objects_extra_mem += + PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT) + + sizeof(_PyOpcache) * co->co_opcache_size; + opcache_code_objects++; +#endif + } + } #ifdef LLTRACE lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL; @@ -2451,11 +2553,30 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } case TARGET(LOAD_GLOBAL): { - PyObject *name = GETITEM(names, oparg); + PyObject *name; PyObject *v; if (PyDict_CheckExact(f->f_globals) && PyDict_CheckExact(f->f_builtins)) { + OPCACHE_CHECK(); + if (co_opcache != NULL && co_opcache->optimized > 0) { + _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg; + + if (lg->globals_ver == + ((PyDictObject *)f->f_globals)->ma_version_tag + && lg->builtins_ver == + ((PyDictObject *)f->f_builtins)->ma_version_tag) + { + PyObject *ptr = lg->ptr; + OPCACHE_STAT_GLOBAL_HIT(); + assert(ptr != NULL); + Py_INCREF(ptr); + PUSH(ptr); + DISPATCH(); + } + } + + name = GETITEM(names, oparg); v = _PyDict_LoadGlobal((PyDictObject *)f->f_globals, (PyDictObject *)f->f_builtins, name); @@ -2468,12 +2589,32 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) } goto error; } + + if (co_opcache != NULL) { + _PyOpcache_LoadGlobal *lg = &co_opcache->u.lg; + + if (co_opcache->optimized == 0) { + /* Wasn't optimized before. */ + OPCACHE_STAT_GLOBAL_OPT(); + } else { + OPCACHE_STAT_GLOBAL_MISS(); + } + + co_opcache->optimized = 1; + lg->globals_ver = + ((PyDictObject *)f->f_globals)->ma_version_tag; + lg->builtins_ver = + ((PyDictObject *)f->f_builtins)->ma_version_tag; + lg->ptr = v; /* borrowed */ + } + Py_INCREF(v); } else { /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ + name = GETITEM(names, oparg); v = PyObject_GetItem(f->f_globals, name); if (v == NULL) { if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 3de5528811ae16..fc7e5510b2cdc8 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1242,6 +1242,9 @@ Py_FinalizeEx(void) /* Destroy all modules */ PyImport_Cleanup(); + /* Print debug stats if any */ + _PyEval_Fini(); + /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ if (flush_std_files() < 0) { status = -1; From 395420e2a35937fa9777fc3c8b0086629db95e27 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 3 Jun 2019 22:34:15 +0900 Subject: [PATCH 291/441] bpo-26219: remove unused code (GH-13775) This code was for deoptimization, which is removed from PR-12884. --- Python/ceval.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 411ba3d73c5f2e..cb0275c4183d2a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1117,9 +1117,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) assert(co_opt_offset <= co->co_opcache_size); \ co_opcache = &co->co_opcache[co_opt_offset - 1]; \ assert(co_opcache != NULL); \ - if (co_opcache->optimized < 0) { \ - co_opcache = NULL; \ - } \ } \ } \ } while (0) From 01ae897efddb31f622999abf4479b2f0fd2f37ff Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Jun 2019 16:28:01 +0200 Subject: [PATCH 292/441] Add credits to What's New in Python 3.8 (GH-13776) * Credit myself and others. * Complete asyncio changes. --- Doc/whatsnew/3.8.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index da97a728509992..f060f4b3f7c40f 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -341,6 +341,15 @@ asyncio ------- On Windows, the default event loop is now :class:`~asyncio.ProactorEventLoop`. +(Contributed by Victor Stinner in :issue:`34687`.) + +:class:`~asyncio.ProactorEventLoop` now also supports UDP. +(Contributed by Adam Meily and Andrew Svetlov in :issue:`29883`.) + +:class:`~asyncio.ProactorEventLoop` can now be interrupted by +:exc:`KeyboardInterrupt` ("CTRL+C"). +(Contributed by Vladimir Matveev in :issue:`23057`.) + builtins -------- @@ -672,6 +681,7 @@ how "unraisable exceptions" are handled. It is called when an exception has occurred but there is no way for Python to handle it. For example, when a destructor raises an exception or during garbage collection (:func:`gc.collect`). +(Contributed by Victor Stinner in :issue:`36829`.) tarfile @@ -740,7 +750,7 @@ unicodedata unittest -------- -* XXX Added :class:`AsyncMock` to support an asynchronous version of :class:`Mock`. +* Added :class:`AsyncMock` to support an asynchronous version of :class:`Mock`. Appropriate new assert functions for testing have been added as well. (Contributed by Lisa Roach in :issue:`26467`). @@ -801,6 +811,8 @@ Optimizations are not set; * the *executable* path contains a directory. + (Contributed by Joannah Nanjekye and Victor Stinner in :issue:`35537`.) + * :func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, :func:`shutil.copytree` and :func:`shutil.move` use platform-specific "fast-copy" syscalls on Linux and macOS in order to copy the file @@ -1006,10 +1018,12 @@ The following features and APIs have been removed from Python 3.8: * The function :func:`platform.popen` has been removed, it was deprecated since Python 3.3: use :func:`os.popen` instead. + (Contributed by Victor Stinner in :issue:`35345`.) * The function :func:`time.clock` has been removed, it was deprecated since Python 3.3: use :func:`time.perf_counter` or :func:`time.process_time` instead, depending on your requirements, to have a well defined behavior. + (Contributed by Matthias Bussonnier in :issue:`36895`.) * The ``pyvenv`` script has been removed in favor of ``python3.8 -m venv`` to help eliminate confusion as to what Python interpreter the ``pyvenv`` @@ -1100,12 +1114,14 @@ Changes in the Python API Emulation, Popen constructor using :func:`os.posix_spawn` no longer raise an exception on errors like missing program, but the child process fails with a non-zero :attr:`~Popen.returncode`. + (Contributed by Joannah Nanjekye and Victor Stinner in :issue:`35537`.) * The :meth:`imap.IMAP4.logout` method no longer ignores silently arbitrary exceptions. * The function :func:`platform.popen` has been removed, it was deprecated since Python 3.3: use :func:`os.popen` instead. + (Contributed by Victor Stinner in :issue:`35345`.) * The :func:`statistics.mode` function no longer raises an exception when given multimodal data. Instead, it returns the first mode @@ -1232,6 +1248,7 @@ Changes in the C API ``RTLD_LOCAL``, it was already not possible to load C extensions which were not linked to ``libpython``, like C extensions of the standard library built by the ``*shared*`` section of ``Modules/Setup``. + (Contributed by Victor Stinner in :issue:`21536`.) * Use of ``#`` variants of formats in parsing or building value (e.g. :c:func:`PyArg_ParseTuple`, :c:func:`Py_BuildValue`, :c:func:`PyObject_CallFunction`, From 141da44bb45bc182886303fce92cbbae5631cb4c Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Mon, 3 Jun 2019 17:17:03 +0200 Subject: [PATCH 293/441] Doc fix: duplicate object description of email.message (GH-13742) --- Doc/library/email.compat32-message.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index f02b35b910a0cf..09ea64a5a01aae 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -6,6 +6,7 @@ .. module:: email.message :synopsis: The base class representing email messages in a fashion backward compatible with Python 3.2 + :noindex: The :class:`Message` class is very similar to the From 0b9956e9162d8723c2a30ff316ecc25e54459fb1 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 3 Jun 2019 16:43:33 +0100 Subject: [PATCH 294/441] bpo-37087: Adding native ID support for OpenBSD (GH-13654) --- Doc/library/_thread.rst | 2 +- Doc/library/threading.rst | 4 ++-- Include/pythread.h | 2 +- .../2019-05-30-17-33-55.bpo-37087.vElenE.rst | 1 + Python/thread_pthread.h | 5 +++++ 5 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 48d36e85c9e5ab..26568dcbf8f532 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -106,7 +106,7 @@ This module defines the following constants and functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD. .. versionadded:: 3.8 diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index ffe6d04258aa9e..7fb9ac9979e42f 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -82,7 +82,7 @@ This module defines the following functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD. .. versionadded:: 3.8 @@ -355,7 +355,7 @@ since it is impossible to detect the termination of alien threads. system-wide) from the time the thread is created until the thread has been terminated. - .. availability:: Windows, FreeBSD, Linux, macOS. + .. availability:: Require :func:`get_native_id` function. .. versionadded:: 3.8 diff --git a/Include/pythread.h b/Include/pythread.h index c0f1eb9789b352..84b79c87642575 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -26,7 +26,7 @@ PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); -#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(_WIN32) +#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_WIN32) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); #endif diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst new file mode 100644 index 00000000000000..a45330fed999f9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst @@ -0,0 +1 @@ +Add native thread ID (TID) support to OpenBSD. \ No newline at end of file diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index f57a1e7bb78baf..740b521b944621 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -16,6 +16,8 @@ # include /* syscall(SYS_gettid) */ #elif defined(__FreeBSD__) # include /* pthread_getthreadid_np() */ +#elif defined(__OpenBSD__) +# include /* getthrid() */ #endif /* The POSIX spec requires that use of pthread_attr_setstacksize @@ -323,6 +325,9 @@ PyThread_get_thread_native_id(void) #elif defined(__FreeBSD__) int native_id; native_id = pthread_getthreadid_np(); +#elif defined(__OpenBSD__) + pid_t native_id; + native_id = getthrid(); #endif return (unsigned long) native_id; } From 49a7e347976c9b39149ac7505b11ad6e9e2bdeec Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Jun 2019 17:49:04 +0200 Subject: [PATCH 295/441] bpo-37137: Fix test_asyncio: use TestCase.set_event_loop() (GH-13779) Replace asyncio.set_event_loop() with TestCase.set_event_loop() of test_asyncio.utils: this method calls TestCase.close_loop() which waits until the executor completes, to avoid leaking dangling threads. Inherit from test_asyncio.utils.TestCase rather than unittest.TestCase. --- Lib/test/test_asyncio/test_tasks.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 74ce25908a3308..22a49077d5e7f1 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2775,7 +2775,7 @@ def test__unregister_task_not_registered(self): self.assertEqual(asyncio.all_tasks(loop), set()) -class PyIntrospectionTests(unittest.TestCase, BaseTaskIntrospectionTests): +class PyIntrospectionTests(test_utils.TestCase, BaseTaskIntrospectionTests): _register_task = staticmethod(tasks._py_register_task) _unregister_task = staticmethod(tasks._py_unregister_task) _enter_task = staticmethod(tasks._py_enter_task) @@ -2784,7 +2784,7 @@ class PyIntrospectionTests(unittest.TestCase, BaseTaskIntrospectionTests): @unittest.skipUnless(hasattr(tasks, '_c_register_task'), 'requires the C _asyncio module') -class CIntrospectionTests(unittest.TestCase, BaseTaskIntrospectionTests): +class CIntrospectionTests(test_utils.TestCase, BaseTaskIntrospectionTests): if hasattr(tasks, '_c_register_task'): _register_task = staticmethod(tasks._c_register_task) _unregister_task = staticmethod(tasks._c_unregister_task) @@ -2799,12 +2799,7 @@ class BaseCurrentLoopTests: def setUp(self): super().setUp() self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(self.loop) - - def tearDown(self): - self.loop.close() - asyncio.set_event_loop(None) - super().tearDown() + self.set_event_loop(self.loop) def new_task(self, coro): raise NotImplementedError @@ -2828,7 +2823,7 @@ async def coro(): self.assertIsNone(asyncio.current_task(loop=self.loop)) -class PyCurrentLoopTests(BaseCurrentLoopTests, unittest.TestCase): +class PyCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase): def new_task(self, coro): return tasks._PyTask(coro, loop=self.loop) @@ -2836,7 +2831,7 @@ def new_task(self, coro): @unittest.skipUnless(hasattr(tasks, '_CTask'), 'requires the C _asyncio module') -class CCurrentLoopTests(BaseCurrentLoopTests, unittest.TestCase): +class CCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase): def new_task(self, coro): return getattr(tasks, '_CTask')(coro, loop=self.loop) @@ -3245,7 +3240,7 @@ class SleepTests(test_utils.TestCase): def setUp(self): super().setUp() self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(None) + self.set_event_loop(self.loop) def tearDown(self): self.loop.close() @@ -3279,7 +3274,7 @@ class WaitTests(test_utils.TestCase): def setUp(self): super().setUp() self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(None) + self.set_event_loop(self.loop) def tearDown(self): self.loop.close() @@ -3306,7 +3301,7 @@ class CompatibilityTests(test_utils.TestCase): def setUp(self): super().setUp() self.loop = asyncio.new_event_loop() - asyncio.set_event_loop(None) + self.set_event_loop(self.loop) def tearDown(self): self.loop.close() From e225bebc1409bcf68db74a35ed3c31222883bf8f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Jun 2019 18:14:24 +0200 Subject: [PATCH 296/441] Revert "bpo-33608: Factor out a private, per-interpreter _Py_AddPendingCall(). (gh-13714)" (GH-13780) This reverts commit 6a150bcaeb190d1731b38ab9c7a5d1a352847ddc. --- Include/internal/pycore_ceval.h | 13 +- Include/internal/pycore_pystate.h | 12 +- Lib/test/test_capi.py | 2 +- .../2018-09-15-12-13-46.bpo-33608.avmvVP.rst | 5 - Modules/_testcapimodule.c | 1 - Modules/signalmodule.c | 12 +- Python/ceval.c | 335 +++++++----------- Python/ceval_gil.h | 28 +- Python/pylifecycle.c | 29 +- Python/pystate.c | 68 ++-- 10 files changed, 185 insertions(+), 320 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 2c6df9a9af9e3b..4c1c0e2439eea4 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -12,22 +12,19 @@ extern "C" { #include "pycore_pystate.h" #include "pythread.h" +PyAPI_FUNC(void) _Py_FinishPendingCalls(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyEval_Initialize(struct _ceval_runtime_state *); PyAPI_FUNC(void) _PyEval_FiniThreads( - struct _ceval_runtime_state *); + struct _ceval_runtime_state *ceval); PyAPI_FUNC(void) _PyEval_SignalReceived( - struct _ceval_runtime_state *); + struct _ceval_runtime_state *ceval); PyAPI_FUNC(int) _PyEval_AddPendingCall( PyThreadState *tstate, - struct _ceval_runtime_state *, - struct _ceval_interpreter_state *, - unsigned long thread_id, + struct _ceval_runtime_state *ceval, int (*func)(void *), void *arg); -PyAPI_FUNC(void) _PyEval_FinishPendingCalls(PyInterpreterState *); PyAPI_FUNC(void) _PyEval_SignalAsyncExc( - struct _ceval_runtime_state *, - struct _ceval_interpreter_state *); + struct _ceval_runtime_state *ceval); PyAPI_FUNC(void) _PyEval_ReInitThreads( _PyRuntimeState *runtime); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index aca5533022e322..520a74b8a61fde 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -25,7 +25,7 @@ struct pyruntimestate; /* ceval state */ -struct _ceval_pending_calls { +struct _pending_calls { int finishing; PyThread_type_lock lock; /* Request for running pending calls. */ @@ -36,7 +36,6 @@ struct _ceval_pending_calls { int async_exc; #define NPENDINGCALLS 32 struct { - unsigned long thread_id; int (*func)(void *); void *arg; } calls[NPENDINGCALLS]; @@ -54,21 +53,15 @@ struct _ceval_runtime_state { int tracing_possible; /* This single variable consolidates all requests to break out of the fast path in the eval loop. */ - // XXX This can move to _ceval_interpreter_state once all parts - // from COMPUTE_EVAL_BREAKER have moved under PyInterpreterState. _Py_atomic_int eval_breaker; /* Request for dropping the GIL */ _Py_atomic_int gil_drop_request; + struct _pending_calls pending; /* Request for checking signals. */ _Py_atomic_int signals_pending; struct _gil_runtime_state gil; }; -struct _ceval_interpreter_state { - struct _ceval_pending_calls pending; -}; - - /* interpreter state */ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); @@ -143,7 +136,6 @@ struct _is { uint64_t tstate_next_unique_id; - struct _ceval_interpreter_state ceval; struct _warnings_runtime_state warnings; PyObject *audit_hooks; diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 88bda057ed6a67..43d7a08da944a9 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -431,7 +431,7 @@ def pendingcalls_wait(self, l, n, context = None): def test_pendingcalls_threaded(self): #do every callback on a separate thread - n = 32 #total callbacks (see NPENDINGCALLS in pycore_ceval.h) + n = 32 #total callbacks threads = [] class foo(object):pass context = foo() diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst b/Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst deleted file mode 100644 index 73a01a1f46bdc1..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-09-15-12-13-46.bpo-33608.avmvVP.rst +++ /dev/null @@ -1,5 +0,0 @@ -We added a new internal _Py_AddPendingCall() that operates relative to the -provided interpreter. This allows us to use the existing implementation to -ask another interpreter to do work that cannot be done in the current -interpreter, like decref an object the other interpreter owns. The existing -Py_AddPendingCall() only operates relative to the main interpreter. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 40e0826ce1263a..f059b4df11b734 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2677,7 +2677,6 @@ pending_threadfunc(PyObject *self, PyObject *arg) Py_INCREF(callable); Py_BEGIN_ALLOW_THREADS - /* XXX Use the internal _Py_AddPendingCall(). */ r = Py_AddPendingCall(&_pending_callback, callable); Py_END_ALLOW_THREADS diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 1964646da2522d..7698984ff3afe1 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -21,7 +21,6 @@ #include #endif #endif -#include "internal/pycore_pystate.h" #ifdef HAVE_SIGNAL_H #include @@ -260,7 +259,6 @@ trip_signal(int sig_num) /* Notify ceval.c */ _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - PyInterpreterState *interp = runtime->interpreters.main; _PyEval_SignalReceived(&runtime->ceval); /* And then write to the wakeup fd *after* setting all the globals and @@ -301,10 +299,7 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(tstate, - &runtime->ceval, - &interp->ceval, - runtime->main_thread, + _PyEval_AddPendingCall(tstate, &runtime->ceval, report_wakeup_send_error, (void *)(intptr_t) last_error); } @@ -323,10 +318,7 @@ trip_signal(int sig_num) { /* Py_AddPendingCall() isn't signal-safe, but we still use it for this exceptional case. */ - _PyEval_AddPendingCall(tstate, - &runtime->ceval, - &interp->ceval, - runtime->main_thread, + _PyEval_AddPendingCall(tstate, &runtime->ceval, report_wakeup_write_error, (void *)(intptr_t)errno); } diff --git a/Python/ceval.c b/Python/ceval.c index cb0275c4183d2a..0a4af915d6ffe0 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -115,65 +115,66 @@ static size_t opcache_global_hits = 0; static size_t opcache_global_misses = 0; #endif +#define GIL_REQUEST _Py_atomic_load_relaxed(&ceval->gil_drop_request) /* This can set eval_breaker to 0 even though gil_drop_request became 1. We believe this is all right because the eval loop will release the GIL eventually anyway. */ -#define COMPUTE_EVAL_BREAKER(ceval_r, ceval_i) \ +#define COMPUTE_EVAL_BREAKER(ceval) \ _Py_atomic_store_relaxed( \ - &(ceval_r)->eval_breaker, \ - _Py_atomic_load_relaxed(&(ceval_r)->gil_drop_request) | \ - _Py_atomic_load_relaxed(&(ceval_r)->signals_pending) | \ - _Py_atomic_load_relaxed(&(ceval_i)->pending.calls_to_do) | \ - (ceval_i)->pending.async_exc) + &(ceval)->eval_breaker, \ + GIL_REQUEST | \ + _Py_atomic_load_relaxed(&(ceval)->signals_pending) | \ + _Py_atomic_load_relaxed(&(ceval)->pending.calls_to_do) | \ + (ceval)->pending.async_exc) -#define SET_GIL_DROP_REQUEST(ceval_r) \ +#define SET_GIL_DROP_REQUEST(ceval) \ do { \ - _Py_atomic_store_relaxed(&(ceval_r)->gil_drop_request, 1); \ - _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ + _Py_atomic_store_relaxed(&(ceval)->gil_drop_request, 1); \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ } while (0) -#define RESET_GIL_DROP_REQUEST(ceval_r, ceval_i) \ +#define RESET_GIL_DROP_REQUEST(ceval) \ do { \ - _Py_atomic_store_relaxed(&(ceval_r)->gil_drop_request, 0); \ - COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ + _Py_atomic_store_relaxed(&(ceval)->gil_drop_request, 0); \ + COMPUTE_EVAL_BREAKER(ceval); \ } while (0) /* Pending calls are only modified under pending_lock */ -#define SIGNAL_PENDING_CALLS(ceval_r, ceval_i) \ +#define SIGNAL_PENDING_CALLS(ceval) \ do { \ - _Py_atomic_store_relaxed(&(ceval_i)->pending.calls_to_do, 1); \ - _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ + _Py_atomic_store_relaxed(&(ceval)->pending.calls_to_do, 1); \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ } while (0) -#define UNSIGNAL_PENDING_CALLS(ceval_r, ceval_i) \ +#define UNSIGNAL_PENDING_CALLS(ceval) \ do { \ - _Py_atomic_store_relaxed(&(ceval_i)->pending.calls_to_do, 0); \ - COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ + _Py_atomic_store_relaxed(&(ceval)->pending.calls_to_do, 0); \ + COMPUTE_EVAL_BREAKER(ceval); \ } while (0) -#define SIGNAL_PENDING_SIGNALS(ceval_r) \ +#define SIGNAL_PENDING_SIGNALS(ceval) \ do { \ - _Py_atomic_store_relaxed(&(ceval_r)->signals_pending, 1); \ - _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ + _Py_atomic_store_relaxed(&(ceval)->signals_pending, 1); \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ } while (0) -#define UNSIGNAL_PENDING_SIGNALS(ceval_r, ceval_i) \ +#define UNSIGNAL_PENDING_SIGNALS(ceval) \ do { \ - _Py_atomic_store_relaxed(&(ceval_r)->signals_pending, 0); \ - COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ + _Py_atomic_store_relaxed(&(ceval)->signals_pending, 0); \ + COMPUTE_EVAL_BREAKER(ceval); \ } while (0) -#define SIGNAL_ASYNC_EXC(ceval_r, ceval_i) \ +#define SIGNAL_ASYNC_EXC(ceval) \ do { \ - (ceval_i)->pending.async_exc = 1; \ - _Py_atomic_store_relaxed(&(ceval_r)->eval_breaker, 1); \ + (ceval)->pending.async_exc = 1; \ + _Py_atomic_store_relaxed(&(ceval)->eval_breaker, 1); \ } while (0) -#define UNSIGNAL_ASYNC_EXC(ceval_r, ceval_i) \ +#define UNSIGNAL_ASYNC_EXC(ceval) \ do { \ - (ceval_i)->pending.async_exc = 0; \ - COMPUTE_EVAL_BREAKER(ceval_r, ceval_i); \ + (ceval)->pending.async_exc = 0; \ + COMPUTE_EVAL_BREAKER(ceval); \ } while (0) @@ -193,8 +194,8 @@ void PyEval_InitThreads(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval_r = &runtime->ceval; - struct _gil_runtime_state *gil = &ceval_r->gil; + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _gil_runtime_state *gil = &ceval->gil; if (gil_created(gil)) { return; } @@ -202,15 +203,19 @@ PyEval_InitThreads(void) PyThread_init_thread(); create_gil(gil); PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - take_gil(ceval_r, tstate); + take_gil(ceval, tstate); - // The pending calls mutex is initialized in PyInterpreterState_New(). + struct _pending_calls *pending = &ceval->pending; + pending->lock = PyThread_allocate_lock(); + if (pending->lock == NULL) { + Py_FatalError("Can't initialize threads for pending calls"); + } } void -_PyEval_FiniThreads(struct _ceval_runtime_state *ceval_r) +_PyEval_FiniThreads(struct _ceval_runtime_state *ceval) { - struct _gil_runtime_state *gil = &ceval_r->gil; + struct _gil_runtime_state *gil = &ceval->gil; if (!gil_created(gil)) { return; } @@ -218,24 +223,20 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval_r) destroy_gil(gil); assert(!gil_created(gil)); - // The pending calls mutex is freed in PyInterpreterState_Delete(). + struct _pending_calls *pending = &ceval->pending; + if (pending->lock != NULL) { + PyThread_free_lock(pending->lock); + pending->lock = NULL; + } } static inline void exit_thread_if_finalizing(PyThreadState *tstate) { - PyInterpreterState *interp = tstate->interp; - // Stop if thread/interpreter inalization already stated. - if (interp == NULL) { - return; - } - _PyRuntimeState *runtime = interp->runtime; - if (runtime == NULL) { - return; - } - // Don't exit if the main thread (i.e. of the main interpreter). + _PyRuntimeState *runtime = tstate->interp->runtime; + /* _Py_Finalizing is protected by the GIL */ if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { - drop_gil(&runtime->ceval, &interp->ceval, tstate); + drop_gil(&runtime->ceval, tstate); PyThread_exit_thread(); } } @@ -273,12 +274,12 @@ void PyEval_AcquireLock(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval_r = &runtime->ceval; + struct _ceval_runtime_state *ceval = &runtime->ceval; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); if (tstate == NULL) { Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); } - take_gil(ceval_r, tstate); + take_gil(ceval, tstate); exit_thread_if_finalizing(tstate); } @@ -286,21 +287,12 @@ void PyEval_ReleaseLock(void) { _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); /* This function must succeed when the current thread state is NULL. We therefore avoid PyThreadState_Get() which dumps a fatal error in debug mode. */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - // Fall back to the main interpreter if there is not active Python - // thread. This only affects the eval_breaker. - PyInterpreterState *interp = runtime->interpreters.main; - if (tstate != NULL) { - interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("PyEval_ReleaseLock: NULL interpreter state"); - } - } - drop_gil(&runtime->ceval, &interp->ceval, tstate); + drop_gil(&runtime->ceval, tstate); } void @@ -309,19 +301,14 @@ PyEval_AcquireThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_AcquireThread: NULL new thread state"); } - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("PyEval_AcquireThread: NULL interpreter state"); - } - _PyRuntimeState *runtime = interp->runtime; - if (runtime == NULL) { - Py_FatalError("PyEval_AcquireThread: NULL runtime state"); - } - struct _ceval_runtime_state *ceval_r = &runtime->ceval; + assert(tstate->interp != NULL); + + _PyRuntimeState *runtime = tstate->interp->runtime; + struct _ceval_runtime_state *ceval = &runtime->ceval; /* Check someone has called PyEval_InitThreads() to create the lock */ - assert(gil_created(&ceval_r->gil)); - take_gil(ceval_r, tstate); + assert(gil_created(&ceval->gil)); + take_gil(ceval, tstate); exit_thread_if_finalizing(tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); @@ -334,20 +321,14 @@ PyEval_ReleaseThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_ReleaseThread: NULL thread state"); } - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("PyEval_ReleaseThread: NULL interpreter state"); - } - _PyRuntimeState *runtime = interp->runtime; - if (runtime == NULL) { - Py_FatalError("PyEval_ReleaseThread: NULL runtime state"); - } + assert(tstate->interp != NULL); + _PyRuntimeState *runtime = tstate->interp->runtime; PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (new_tstate != tstate) { Py_FatalError("PyEval_ReleaseThread: wrong thread state"); } - drop_gil(&runtime->ceval, &interp->ceval, tstate); + drop_gil(&runtime->ceval, tstate); } /* This function is called from PyOS_AfterFork_Child to destroy all threads @@ -358,17 +339,15 @@ PyEval_ReleaseThread(PyThreadState *tstate) void _PyEval_ReInitThreads(_PyRuntimeState *runtime) { - struct _ceval_runtime_state *ceval_r = &runtime->ceval; - if (!gil_created(&ceval_r->gil)) { + struct _ceval_runtime_state *ceval = &runtime->ceval; + if (!gil_created(&ceval->gil)) { return; } - recreate_gil(&ceval_r->gil); + recreate_gil(&ceval->gil); PyThreadState *current_tstate = _PyRuntimeState_GetThreadState(runtime); - take_gil(ceval_r, current_tstate); + take_gil(ceval, current_tstate); - // Only the main interpreter remains, so ignore the rest. - PyInterpreterState *interp = _PyRuntime.interpreters.main; - struct _ceval_pending_calls *pending = &interp->ceval.pending; + struct _pending_calls *pending = &ceval->pending; pending->lock = PyThread_allocate_lock(); if (pending->lock == NULL) { Py_FatalError("Can't initialize threads for pending calls"); @@ -382,28 +361,22 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) raised. */ void -_PyEval_SignalAsyncExc(struct _ceval_runtime_state *ceval_r, - struct _ceval_interpreter_state *ceval_i) +_PyEval_SignalAsyncExc(struct _ceval_runtime_state *ceval) { - SIGNAL_ASYNC_EXC(ceval_r, ceval_i); + SIGNAL_ASYNC_EXC(ceval); } PyThreadState * PyEval_SaveThread(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval_r = &runtime->ceval; + struct _ceval_runtime_state *ceval = &runtime->ceval; PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (tstate == NULL) { Py_FatalError("PyEval_SaveThread: NULL tstate"); } - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("PyEval_SaveThread: NULL interpreter state"); - } - - assert(gil_created(&ceval_r->gil)); - drop_gil(ceval_r, &interp->ceval, tstate); + assert(gil_created(&ceval->gil)); + drop_gil(ceval, tstate); return tstate; } @@ -413,20 +386,14 @@ PyEval_RestoreThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_RestoreThread: NULL tstate"); } - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("PyEval_RestoreThread: NULL interpreter state"); - } - _PyRuntimeState *runtime = interp->runtime; - if (runtime == NULL) { - Py_FatalError("PyEval_RestoreThread: NULL runtime state"); - } - struct _ceval_runtime_state *ceval_r = &runtime->ceval; + assert(tstate->interp != NULL); - assert(gil_created(&ceval_r->gil)); + _PyRuntimeState *runtime = tstate->interp->runtime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + assert(gil_created(&ceval->gil)); int err = errno; - take_gil(ceval_r, tstate); + take_gil(ceval, tstate); exit_thread_if_finalizing(tstate); errno = err; @@ -457,17 +424,17 @@ PyEval_RestoreThread(PyThreadState *tstate) */ void -_PyEval_SignalReceived(struct _ceval_runtime_state *ceval_r) +_PyEval_SignalReceived(struct _ceval_runtime_state *ceval) { /* bpo-30703: Function called when the C signal handler of Python gets a signal. We cannot queue a callback using Py_AddPendingCall() since that function is not async-signal-safe. */ - SIGNAL_PENDING_SIGNALS(ceval_r); + SIGNAL_PENDING_SIGNALS(ceval); } /* Push one item onto the queue while holding the lock. */ static int -_push_pending_call(struct _ceval_pending_calls *pending, unsigned long thread_id, +_push_pending_call(struct _pending_calls *pending, int (*func)(void *), void *arg) { int i = pending->last; @@ -475,7 +442,6 @@ _push_pending_call(struct _ceval_pending_calls *pending, unsigned long thread_id if (j == pending->first) { return -1; /* Queue full */ } - pending->calls[i].thread_id = thread_id; pending->calls[i].func = func; pending->calls[i].arg = arg; pending->last = j; @@ -484,7 +450,7 @@ _push_pending_call(struct _ceval_pending_calls *pending, unsigned long thread_id /* Pop one item off the queue while holding the lock. */ static void -_pop_pending_call(struct _ceval_pending_calls *pending, unsigned long *thread_id, +_pop_pending_call(struct _pending_calls *pending, int (**func)(void *), void **arg) { int i = pending->first; @@ -494,7 +460,6 @@ _pop_pending_call(struct _ceval_pending_calls *pending, unsigned long *thread_id *func = pending->calls[i].func; *arg = pending->calls[i].arg; - *thread_id = pending->calls[i].thread_id; pending->first = (i + 1) % NPENDINGCALLS; } @@ -505,12 +470,10 @@ _pop_pending_call(struct _ceval_pending_calls *pending, unsigned long *thread_id int _PyEval_AddPendingCall(PyThreadState *tstate, - struct _ceval_runtime_state *ceval_r, - struct _ceval_interpreter_state *ceval_i, - unsigned long thread_id, + struct _ceval_runtime_state *ceval, int (*func)(void *), void *arg) { - struct _ceval_pending_calls *pending = &ceval_i->pending; + struct _pending_calls *pending = &ceval->pending; PyThread_acquire_lock(pending->lock, WAIT_LOCK); if (pending->finishing) { @@ -525,27 +488,20 @@ _PyEval_AddPendingCall(PyThreadState *tstate, _PyErr_Restore(tstate, exc, val, tb); return -1; } - int result = _push_pending_call(pending, thread_id, func, arg); - - /* signal loop */ - SIGNAL_PENDING_CALLS(ceval_r, ceval_i); + int result = _push_pending_call(pending, func, arg); PyThread_release_lock(pending->lock); + /* signal main loop */ + SIGNAL_PENDING_CALLS(ceval); return result; } -/* Py_AddPendingCall() is a simple wrapper for the sake - of backward-compatibility. */ int Py_AddPendingCall(int (*func)(void *), void *arg) { _PyRuntimeState *runtime = &_PyRuntime; - PyInterpreterState *interp = runtime->interpreters.main; PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - return _PyEval_AddPendingCall(tstate, - &runtime->ceval, &interp->ceval, - runtime->main_thread, - func, arg); + return _PyEval_AddPendingCall(tstate, &runtime->ceval, func, arg); } static int @@ -566,69 +522,47 @@ handle_signals(_PyRuntimeState *runtime) return 0; } - struct _ceval_runtime_state *ceval_r = &runtime->ceval; - struct _ceval_interpreter_state *ceval_i = &interp->ceval; - UNSIGNAL_PENDING_SIGNALS(ceval_r, ceval_i); + struct _ceval_runtime_state *ceval = &runtime->ceval; + UNSIGNAL_PENDING_SIGNALS(ceval); if (_PyErr_CheckSignals() < 0) { - SIGNAL_PENDING_SIGNALS(ceval_r); /* We're not done yet */ + SIGNAL_PENDING_SIGNALS(ceval); /* We're not done yet */ return -1; } return 0; } static int -make_pending_calls(PyInterpreterState *interp) +make_pending_calls(_PyRuntimeState *runtime) { - if (interp == NULL) { - Py_FatalError("make_pending_calls: NULL interpreter state"); - } - _PyRuntimeState *runtime = interp->runtime; - if (runtime == NULL) { - Py_FatalError("make_pending_calls: NULL runtime state"); - } - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - if (tstate == NULL) { - Py_FatalError("make_pending_calls: NULL thread state"); - } - if (tstate->interp == NULL || tstate->interp != interp) { - Py_FatalError("make_pending_calls: thread state mismatch"); - } static int busy = 0; + /* only service pending calls on main thread */ + if (PyThread_get_thread_ident() != runtime->main_thread) { + return 0; + } + /* don't perform recursive pending calls */ if (busy) { return 0; } busy = 1; - struct _ceval_runtime_state *ceval_r = &runtime->ceval; - struct _ceval_interpreter_state *ceval_i = &interp->ceval; + struct _ceval_runtime_state *ceval = &runtime->ceval; /* unsignal before starting to call callbacks, so that any callback added in-between re-signals */ - UNSIGNAL_PENDING_CALLS(ceval_r, ceval_i); + UNSIGNAL_PENDING_CALLS(ceval); int res = 0; /* perform a bounded number of calls, in case of recursion */ - struct _ceval_pending_calls *pending = &ceval_i->pending; - unsigned long thread_id = 0; + struct _pending_calls *pending = &ceval->pending; for (int i=0; ilock, WAIT_LOCK); - _pop_pending_call(pending, &thread_id, &func, &arg); + _pop_pending_call(pending, &func, &arg); PyThread_release_lock(pending->lock); - if (thread_id && PyThread_get_thread_ident() != thread_id) { - // Thread mismatch, so move it to the end of the list - // and start over. - _PyEval_AddPendingCall(tstate, - &runtime->ceval, &interp->ceval, - thread_id, - func, arg); - goto error; - } - /* having released the lock, perform the callback */ if (func == NULL) { break; @@ -644,16 +578,17 @@ make_pending_calls(PyInterpreterState *interp) error: busy = 0; - SIGNAL_PENDING_CALLS(ceval_r, ceval_i); + SIGNAL_PENDING_CALLS(ceval); return res; } void -_PyEval_FinishPendingCalls(PyInterpreterState *interp) +_Py_FinishPendingCalls(_PyRuntimeState *runtime) { assert(PyGILState_Check()); - struct _ceval_pending_calls *pending = &interp->ceval.pending; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + struct _pending_calls *pending = &runtime->ceval.pending; PyThread_acquire_lock(pending->lock, WAIT_LOCK); pending->finishing = 1; @@ -663,19 +598,12 @@ _PyEval_FinishPendingCalls(PyInterpreterState *interp) return; } - if (make_pending_calls(interp) < 0) { - _PyRuntimeState *runtime = interp->runtime; - if (runtime == NULL) { - runtime = &_PyRuntime; - } - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - if (tstate != NULL) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - PyErr_BadInternalCall(); - _PyErr_ChainExceptions(exc, val, tb); - _PyErr_Print(tstate); - } + if (make_pending_calls(runtime) < 0) { + PyObject *exc, *val, *tb; + _PyErr_Fetch(tstate, &exc, &val, &tb); + PyErr_BadInternalCall(); + _PyErr_ChainExceptions(exc, val, tb); + _PyErr_Print(tstate); } } @@ -694,8 +622,7 @@ Py_MakePendingCalls(void) return res; } - PyInterpreterState *interp = _PyRuntime.interpreters.main; - res = make_pending_calls(interp); + res = make_pending_calls(runtime); if (res != 0) { return res; } @@ -712,11 +639,11 @@ Py_MakePendingCalls(void) int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; void -_PyEval_Initialize(struct _ceval_runtime_state *ceval_r) +_PyEval_Initialize(struct _ceval_runtime_state *state) { - ceval_r->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; + state->recursion_limit = Py_DEFAULT_RECURSION_LIMIT; _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; - _gil_initialize(&ceval_r->gil); + _gil_initialize(&state->gil); } int @@ -728,9 +655,9 @@ Py_GetRecursionLimit(void) void Py_SetRecursionLimit(int new_limit) { - struct _ceval_runtime_state *ceval_r = &_PyRuntime.ceval; - ceval_r->recursion_limit = new_limit; - _Py_CheckRecursionLimit = ceval_r->recursion_limit; + struct _ceval_runtime_state *ceval = &_PyRuntime.ceval; + ceval->recursion_limit = new_limit; + _Py_CheckRecursionLimit = ceval->recursion_limit; } /* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall() @@ -779,7 +706,7 @@ _Py_CheckRecursiveCall(const char *where) static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); -#define _Py_TracingPossible(ceval_r) ((ceval_r)->tracing_possible) +#define _Py_TracingPossible(ceval) ((ceval)->tracing_possible) PyObject * @@ -825,10 +752,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PyObject *retval = NULL; /* Return value */ _PyRuntimeState * const runtime = &_PyRuntime; PyThreadState * const tstate = _PyRuntimeState_GetThreadState(runtime); - PyInterpreterState * const interp = tstate->interp; - struct _ceval_runtime_state * const ceval_r = &runtime->ceval; - struct _ceval_interpreter_state * const ceval_i = &interp->ceval; - _Py_atomic_int * const eval_breaker = &ceval_r->eval_breaker; + struct _ceval_runtime_state * const ceval = &runtime->ceval; + _Py_atomic_int * const eval_breaker = &ceval->eval_breaker; PyCodeObject *co; /* when tracing we set things up so that @@ -916,7 +841,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) #ifdef LLTRACE #define FAST_DISPATCH() \ { \ - if (!lltrace && !_Py_TracingPossible(ceval_r) && !PyDTrace_LINE_ENABLED()) { \ + if (!lltrace && !_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \ f->f_lasti = INSTR_OFFSET(); \ NEXTOPARG(); \ goto *opcode_targets[opcode]; \ @@ -926,7 +851,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) #else #define FAST_DISPATCH() \ { \ - if (!_Py_TracingPossible(ceval_r) && !PyDTrace_LINE_ENABLED()) { \ + if (!_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \ f->f_lasti = INSTR_OFFSET(); \ NEXTOPARG(); \ goto *opcode_targets[opcode]; \ @@ -1295,27 +1220,27 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) goto fast_next_opcode; } - if (_Py_atomic_load_relaxed(&ceval_r->signals_pending)) { + if (_Py_atomic_load_relaxed(&ceval->signals_pending)) { if (handle_signals(runtime) != 0) { goto error; } } - if (_Py_atomic_load_relaxed(&ceval_i->pending.calls_to_do)) { - if (make_pending_calls(interp) != 0) { + if (_Py_atomic_load_relaxed(&ceval->pending.calls_to_do)) { + if (make_pending_calls(runtime) != 0) { goto error; } } - if (_Py_atomic_load_relaxed(&ceval_r->gil_drop_request)) { + if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { /* Give another thread a chance */ if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { Py_FatalError("ceval: tstate mix-up"); } - drop_gil(ceval_r, ceval_i, tstate); + drop_gil(ceval, tstate); /* Other threads may run now */ - take_gil(ceval_r, tstate); + take_gil(ceval, tstate); /* Check if we should make a quick exit. */ exit_thread_if_finalizing(tstate); @@ -1328,7 +1253,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) if (tstate->async_exc != NULL) { PyObject *exc = tstate->async_exc; tstate->async_exc = NULL; - UNSIGNAL_ASYNC_EXC(ceval_r, ceval_i); + UNSIGNAL_ASYNC_EXC(ceval); _PyErr_SetNone(tstate, exc); Py_DECREF(exc); goto error; @@ -1343,7 +1268,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) /* line-by-line tracing support */ - if (_Py_TracingPossible(ceval_r) && + if (_Py_TracingPossible(ceval) && tstate->c_tracefunc != NULL && !tstate->tracing) { int err; /* see maybe_call_line_trace diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h index b44d0abad36b13..34d48c990c4479 100644 --- a/Python/ceval_gil.h +++ b/Python/ceval_gil.h @@ -141,11 +141,9 @@ static void recreate_gil(struct _gil_runtime_state *gil) } static void -drop_gil(struct _ceval_runtime_state *ceval_r, - struct _ceval_interpreter_state *ceval_i, - PyThreadState *tstate) +drop_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) { - struct _gil_runtime_state *gil = &ceval_r->gil; + struct _gil_runtime_state *gil = &ceval->gil; if (!_Py_atomic_load_relaxed(&gil->locked)) { Py_FatalError("drop_gil: GIL is not locked"); } @@ -165,12 +163,12 @@ drop_gil(struct _ceval_runtime_state *ceval_r, MUTEX_UNLOCK(gil->mutex); #ifdef FORCE_SWITCHING - if (_Py_atomic_load_relaxed(&ceval_r->gil_drop_request) && tstate != NULL) { + if (_Py_atomic_load_relaxed(&ceval->gil_drop_request) && tstate != NULL) { MUTEX_LOCK(gil->switch_mutex); /* Not switched yet => wait */ if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) { - RESET_GIL_DROP_REQUEST(ceval_r, ceval_i); + RESET_GIL_DROP_REQUEST(ceval); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take the GIL and drop it again, and reset the condition @@ -183,19 +181,13 @@ drop_gil(struct _ceval_runtime_state *ceval_r, } static void -take_gil(struct _ceval_runtime_state *ceval_r, - PyThreadState *tstate) +take_gil(struct _ceval_runtime_state *ceval, PyThreadState *tstate) { if (tstate == NULL) { Py_FatalError("take_gil: NULL tstate"); } - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("take_gil: NULL interp"); - } - struct _ceval_interpreter_state *ceval_i = &interp->ceval; - struct _gil_runtime_state *gil = &ceval_r->gil; + struct _gil_runtime_state *gil = &ceval->gil; int err = errno; MUTEX_LOCK(gil->mutex); @@ -218,7 +210,7 @@ take_gil(struct _ceval_runtime_state *ceval_r, _Py_atomic_load_relaxed(&gil->locked) && gil->switch_number == saved_switchnum) { - SET_GIL_DROP_REQUEST(ceval_r); + SET_GIL_DROP_REQUEST(ceval); } } _ready: @@ -240,11 +232,11 @@ take_gil(struct _ceval_runtime_state *ceval_r, COND_SIGNAL(gil->switch_cond); MUTEX_UNLOCK(gil->switch_mutex); #endif - if (_Py_atomic_load_relaxed(&ceval_r->gil_drop_request)) { - RESET_GIL_DROP_REQUEST(ceval_r, ceval_i); + if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { + RESET_GIL_DROP_REQUEST(ceval); } if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(ceval_r, ceval_i); + _PyEval_SignalAsyncExc(ceval); } MUTEX_UNLOCK(gil->mutex); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index fc7e5510b2cdc8..fca2ee65519104 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1147,31 +1147,15 @@ Py_FinalizeEx(void) return status; } - /* Get current thread state and interpreter pointer */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - PyInterpreterState *interp = tstate->interp; - // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(); // Make any remaining pending calls. - /* XXX For the moment we are going to ignore lingering pending calls. - * We've seen sporadic on some of the buildbots during finalization - * with the changes for per-interpreter pending calls (see bpo-33608), - * meaning the previous _PyEval_FinishPendincCalls() call here is - * a trigger, if not responsible. - * - * Ignoring pending calls at this point in the runtime lifecycle - * is okay (for now) for the following reasons: - * - * * pending calls are still not a widely-used feature - * * this only affects runtime finalization, where the process is - * likely to end soon anyway (except for some embdding cases) - * - * See bpo-37127 about resolving the problem. Ultimately the call - * here should be re-enabled. - */ - //_PyEval_FinishPendingCalls(interp); + _Py_FinishPendingCalls(runtime); + + /* Get current thread state and interpreter pointer */ + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyInterpreterState *interp = tstate->interp; /* The interpreter is still entirely intact at this point, and the * exit funcs may be relying on that. In particular, if some thread @@ -1599,9 +1583,6 @@ Py_EndInterpreter(PyThreadState *tstate) // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(); - // Make any remaining pending calls. - _PyEval_FinishPendingCalls(interp); - call_py_exitfuncs(interp); if (tstate != interp->tstate_head || tstate->next != NULL) diff --git a/Python/pystate.c b/Python/pystate.c index a9f3389a0d833e..2b7db0e48debe9 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -218,13 +218,6 @@ PyInterpreterState_New(void) return NULL; } - interp->ceval.pending.lock = PyThread_allocate_lock(); - if (interp->ceval.pending.lock == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "failed to create interpreter ceval pending mutex"); - return NULL; - } - interp->eval_frame = _PyEval_EvalFrameDefault; #ifdef HAVE_DLOPEN #if HAVE_DECL_RTLD_NOW @@ -352,10 +345,6 @@ PyInterpreterState_Delete(PyInterpreterState *interp) if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } - if (interp->ceval.pending.lock != NULL) { - PyThread_free_lock(interp->ceval.pending.lock); - interp->ceval.pending.lock = NULL; - } PyMem_RawFree(interp); } @@ -1025,7 +1014,7 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) p->async_exc = exc; HEAD_UNLOCK(runtime); Py_XDECREF(old_exc); - _PyEval_SignalAsyncExc(&runtime->ceval, &interp->ceval); + _PyEval_SignalAsyncExc(&runtime->ceval); return 1; } } @@ -1455,7 +1444,7 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) return 0; } -static int +static void _release_xidata(void *arg) { _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; @@ -1463,21 +1452,42 @@ _release_xidata(void *arg) data->free(data->data); } Py_XDECREF(data->obj); - PyMem_Free(data); - return 0; +} + +static void +_call_in_interpreter(struct _gilstate_runtime_state *gilstate, + PyInterpreterState *interp, + void (*func)(void *), void *arg) +{ + /* We would use Py_AddPendingCall() if it weren't specific to the + * main interpreter (see bpo-33608). In the meantime we take a + * naive approach. + */ + PyThreadState *save_tstate = NULL; + if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) { + // XXX Using the "head" thread isn't strictly correct. + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); + // XXX Possible GILState issues? + save_tstate = _PyThreadState_Swap(gilstate, tstate); + } + + func(arg); + + // Switch back. + if (save_tstate != NULL) { + _PyThreadState_Swap(gilstate, save_tstate); + } } void _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) { - _PyRuntimeState *runtime = &_PyRuntime; - if (data->data == NULL && data->obj == NULL) { // Nothing to release! return; } - // Get the original interpreter. + // Switch to the original interpreter. PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); if (interp == NULL) { // The intepreter was already destroyed. @@ -1486,28 +1496,10 @@ _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) } return; } - // XXX There's an ever-so-slight race here... - if (interp->finalizing) { - // XXX Someone leaked some memory... - return; - } // "Release" the data and/or the object. - _PyCrossInterpreterData *copied = PyMem_Malloc(sizeof(_PyCrossInterpreterData)); - if (copied == NULL) { - PyErr_SetString(PyExc_MemoryError, - "Not enough memory to preserve cross-interpreter data"); - PyErr_Print(); - return; - } - memcpy(copied, data, sizeof(_PyCrossInterpreterData)); - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - int res = _PyEval_AddPendingCall(tstate, - &runtime->ceval, &interp->ceval, - 0, _release_xidata, copied); - if (res != 0) { - // XXX Queue full or couldn't get lock. Try again somehow? - } + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; + _call_in_interpreter(gilstate, interp, _release_xidata, data); } PyObject * From 06651ee418b5e4e013195d6b702763a1220706a7 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 3 Jun 2019 20:10:19 +0200 Subject: [PATCH 297/441] bpo-37081: Test with OpenSSL 1.1.1c (GH-13631) Signed-off-by: Christian Heimes --- .azure-pipelines/ci.yml | 4 ++-- .azure-pipelines/pr.yml | 4 ++-- .travis.yml | 2 +- .../next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst | 1 + Tools/ssl/multissltests.py | 6 +++--- 5 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 1576599379c489..fcfac85ed9c442 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -59,7 +59,7 @@ jobs: variables: testRunTitle: '$(build.sourceBranchName)-linux' testRunPlatform: linux - openssl_version: 1.1.1b + openssl_version: 1.1.1c steps: - template: ./posix-steps.yml @@ -116,7 +116,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.1b + openssl_version: 1.1.1c steps: - template: ./posix-steps.yml diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml index 0bd7921bcbefcc..2486f88a63fb15 100644 --- a/.azure-pipelines/pr.yml +++ b/.azure-pipelines/pr.yml @@ -59,7 +59,7 @@ jobs: variables: testRunTitle: '$(system.pullRequest.TargetBranch)-linux' testRunPlatform: linux - openssl_version: 1.1.0j + openssl_version: 1.1.1c steps: - template: ./posix-steps.yml @@ -116,7 +116,7 @@ jobs: variables: testRunTitle: '$(Build.SourceBranchName)-linux-coverage' testRunPlatform: linux-coverage - openssl_version: 1.1.0j + openssl_version: 1.1.1c steps: - template: ./posix-steps.yml diff --git a/.travis.yml b/.travis.yml index c1efe24b646bb5..02de997750abc8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ cache: env: global: - - OPENSSL=1.1.0i + - OPENSSL=1.1.1c - OPENSSL_DIR="$HOME/multissl/openssl/${OPENSSL}" - PATH="${OPENSSL_DIR}/bin:$PATH" # Use -O3 because we don't use debugger on Travis-CI diff --git a/Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst b/Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst new file mode 100644 index 00000000000000..df5b8f2482d351 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst @@ -0,0 +1 @@ +Test with OpenSSL 1.1.1c diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 759f5f4a3e7872..07bd9b016d97f8 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -45,9 +45,9 @@ ] OPENSSL_RECENT_VERSIONS = [ - "1.0.2p", - "1.1.0i", - "1.1.1", + "1.0.2s", + "1.1.0k", + "1.1.1c", ] LIBRESSL_OLD_VERSIONS = [ From e35d1ba9eab07a59b98b700c5e18ceb13b2561a6 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 3 Jun 2019 20:40:15 +0200 Subject: [PATCH 298/441] bpo-34271: Fix compatibility with 1.0.2 (GH-13728) Fix various compatibility issues with LibreSSL and OpenSSL 1.0.2 introduced by bpo-34271. Signed-off-by: Christian Heimes --- Lib/ssl.py | 6 ++--- Lib/test/test_ssl.py | 48 ++++++------------------------------- Modules/_ssl/debughelpers.c | 11 ++++++++- Tools/ssl/multissltests.py | 3 ++- 4 files changed, 22 insertions(+), 46 deletions(-) diff --git a/Lib/ssl.py b/Lib/ssl.py index 4afa46e5da5cd5..61bd775f759b09 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -658,12 +658,12 @@ def _msg_callback(self, callback): def inner(conn, direction, version, content_type, msg_type, data): try: version = TLSVersion(version) - except TypeError: + except ValueError: pass try: content_type = _TLSContentType(content_type) - except TypeError: + except ValueError: pass if content_type == _TLSContentType.HEADER: @@ -674,7 +674,7 @@ def inner(conn, direction, version, content_type, msg_type, data): msg_enum = _TLSMessageType try: msg_type = msg_enum(msg_type) - except TypeError: + except ValueError: pass return callback(conn, direction, version, diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index a72d7913218128..455a12ea7f2f0c 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -3703,7 +3703,7 @@ def test_min_max_version(self): # client 1.0, server 1.2 (mismatch) server_context.minimum_version = ssl.TLSVersion.TLSv1_2 server_context.maximum_version = ssl.TLSVersion.TLSv1_2 - client_context.minimum_version = ssl.TLSVersion.TLSv1 + client_context.maximum_version = ssl.TLSVersion.TLSv1 client_context.maximum_version = ssl.TLSVersion.TLSv1 with ThreadedEchoServer(context=server_context) as server: with client_context.wrap_socket(socket.socket(), @@ -4529,50 +4529,16 @@ def msg_cb(conn, direction, version, content_type, msg_type, data): server_hostname=hostname) as s: s.connect((HOST, server.port)) - self.assertEqual(msg, [ - ("write", TLSVersion.TLSv1, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.CLIENT_HELLO), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.SERVER_HELLO), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.CERTIFICATE), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), + self.assertIn( ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, _TLSMessageType.SERVER_KEY_EXCHANGE), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.SERVER_DONE), - ("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.CLIENT_KEY_EXCHANGE), - ("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.FINISHED), + msg + ) + self.assertIn( ("write", TLSVersion.TLSv1_2, _TLSContentType.CHANGE_CIPHER_SPEC, _TLSMessageType.CHANGE_CIPHER_SPEC), - ("write", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("write", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.FINISHED), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.NEWSESSION_TICKET), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.FINISHED), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HEADER, - _TLSMessageType.CERTIFICATE_STATUS), - ("read", TLSVersion.TLSv1_2, _TLSContentType.HANDSHAKE, - _TLSMessageType.FINISHED), - ]) + msg + ) def test_main(verbose=False): diff --git a/Modules/_ssl/debughelpers.c b/Modules/_ssl/debughelpers.c index 53b96674932805..858b3d7955c9cf 100644 --- a/Modules/_ssl/debughelpers.c +++ b/Modules/_ssl/debughelpers.c @@ -1,5 +1,12 @@ /* Debug helpers */ +#ifndef SSL3_MT_CHANGE_CIPHER_SPEC +/* Dummy message type for handling CCS like a normal handshake message + * not defined in OpenSSL 1.0.2 + */ +#define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 +#endif + static void _PySSL_msg_callback(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) @@ -41,11 +48,13 @@ _PySSL_msg_callback(int write_p, int version, int content_type, case SSL3_RT_HANDSHAKE: msg_type = (int)cbuf[0]; break; +#ifdef SSL3_RT_HEADER case SSL3_RT_HEADER: /* frame header encodes version in bytes 1..2 */ version = cbuf[1] << 8 | cbuf[2]; msg_type = (int)cbuf[0]; break; +#endif #ifdef SSL3_RT_INNER_CONTENT_TYPE case SSL3_RT_INNER_CONTENT_TYPE: msg_type = (int)cbuf[0]; @@ -210,4 +219,4 @@ _PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { return 0; } -#endif \ No newline at end of file +#endif diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 07bd9b016d97f8..7fda4df55a678b 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -51,10 +51,11 @@ ] LIBRESSL_OLD_VERSIONS = [ + "2.9.2", ] LIBRESSL_RECENT_VERSIONS = [ - "2.7.4", + "2.8.3", ] # store files in ../multissl From 47eb2234061524562a4b484e3a395f4fdd6c1b76 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 3 Jun 2019 20:51:27 +0200 Subject: [PATCH 299/441] bpo-36868: Fix what's new for SSLContext.hostname_checks_common_name (GH-13248) What's new now mentions SSLContext.hostname_checks_common_name instead of SSLContext.host_flags. https://bugs.python.org/issue36868 --- Doc/whatsnew/3.7.rst | 5 ++--- .../Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 93d3e62b75d227..fc867ac15a5fe2 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -1307,7 +1307,7 @@ including failing the host name check now raises :exc:`~ssl.SSLCertVerificationError` and aborts the handshake with a proper TLS Alert message. The new exception contains additional information. Host name validation can be customized with -:attr:`SSLContext.host_flags `. +:attr:`SSLContext.hostname_checks_common_name `. (Contributed by Christian Heimes in :issue:`31399`.) .. note:: @@ -1320,8 +1320,7 @@ The ``ssl`` module no longer sends IP addresses in SNI TLS extension. (Contributed by Christian Heimes in :issue:`32185`.) :func:`~ssl.match_hostname` no longer supports partial wildcards like -``www*.example.org``. :attr:`SSLContext.host_flags ` -has partial wildcard matching disabled by default. +``www*.example.org``. (Contributed by Mandeep Singh in :issue:`23033` and Christian Heimes in :issue:`31399`.) diff --git a/Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst b/Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst new file mode 100644 index 00000000000000..ad9ed5baf167e6 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst @@ -0,0 +1,2 @@ +What's new now mentions SSLContext.hostname_checks_common_name instead of +SSLContext.host_flags. From 78c7d527799dacca91b9ed67057cb996efe526b0 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 3 Jun 2019 21:00:10 +0200 Subject: [PATCH 300/441] bpo-37120: Add SSLContext.num_tickets (GH-13719) Signed-off-by: Christian Heimes --- Doc/library/ssl.rst | 13 +++++++ Lib/test/test_ssl.py | 18 +++++++++ .../2019-06-01-09-03-32.bpo-37120.FOKQLU.rst | 1 + Modules/_ssl.c | 37 +++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index be09f38f7dfa0b..279af5728913d9 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -1959,6 +1959,19 @@ to speed up repeated connections from the same clients. .. versionadded:: 3.7 +.. attribute:: SSLContext.num_tickets + + Control the number of TLS 1.3 session tickets of a + :attr:`TLS_PROTOCOL_SERVER` context. The setting has no impact on TLS + 1.0 to 1.2 connections. + + .. note:: + + This attribute is not available unless the ssl module is compiled + with OpenSSL 1.1.1 or newer. + + .. versionadded:: 3.8 + .. attribute:: SSLContext.options An integer representing the set of SSL options enabled on this context. diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 455a12ea7f2f0c..7ba8156eef5da8 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -1634,6 +1634,24 @@ class MySSLObject(ssl.SSLObject): obj = ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO()) self.assertIsInstance(obj, MySSLObject) + @unittest.skipUnless(IS_OPENSSL_1_1_1, "Test requires OpenSSL 1.1.1") + def test_num_tickest(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + self.assertEqual(ctx.num_tickets, 2) + ctx.num_tickets = 1 + self.assertEqual(ctx.num_tickets, 1) + ctx.num_tickets = 0 + self.assertEqual(ctx.num_tickets, 0) + with self.assertRaises(ValueError): + ctx.num_tickets = -1 + with self.assertRaises(TypeError): + ctx.num_tickets = None + + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + self.assertEqual(ctx.num_tickets, 2) + with self.assertRaises(ValueError): + ctx.num_tickets = 1 + class SSLErrorTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst b/Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst new file mode 100644 index 00000000000000..6bea492e6a5555 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst @@ -0,0 +1 @@ +Add SSLContext.num_tickets to control the number of TLSv1.3 session tickets. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index f40127d3d932bb..2331c58ad77d5a 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3617,6 +3617,39 @@ set_maximum_version(PySSLContext *self, PyObject *arg, void *c) } #endif /* SSL_CTRL_GET_MAX_PROTO_VERSION */ +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) +static PyObject * +get_num_tickets(PySSLContext *self, void *c) +{ + return PyLong_FromLong(SSL_CTX_get_num_tickets(self->ctx)); +} + +static int +set_num_tickets(PySSLContext *self, PyObject *arg, void *c) +{ + long num; + if (!PyArg_Parse(arg, "l", &num)) + return -1; + if (num < 0) { + PyErr_SetString(PyExc_ValueError, "value must be non-negative"); + return -1; + } + if (self->protocol != PY_SSL_VERSION_TLS_SERVER) { + PyErr_SetString(PyExc_ValueError, + "SSLContext is not a server context."); + return -1; + } + if (SSL_CTX_set_num_tickets(self->ctx, num) != 1) { + PyErr_SetString(PyExc_ValueError, "failed to set num tickets."); + return -1; + } + return 0; +} + +PyDoc_STRVAR(PySSLContext_num_tickets_doc, +"Control the number of TLSv1.3 session tickets"); +#endif /* OpenSSL 1.1.1 */ + static PyObject * get_options(PySSLContext *self, void *c) { @@ -4654,6 +4687,10 @@ static PyGetSetDef context_getsetlist[] = { (setter) _PySSLContext_set_msg_callback, NULL}, {"sni_callback", (getter) get_sni_callback, (setter) set_sni_callback, PySSLContext_sni_callback_doc}, +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) + {"num_tickets", (getter) get_num_tickets, + (setter) set_num_tickets, PySSLContext_num_tickets_doc}, +#endif {"options", (getter) get_options, (setter) set_options, NULL}, {"post_handshake_auth", (getter) get_post_handshake_auth, From 0f0a30f4da4b529e0f7df857b9f575b231b32758 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Jun 2019 23:31:04 +0200 Subject: [PATCH 301/441] bpo-34037, asyncio: add BaseEventLoop.wait_executor_on_close (GH-13786) Add BaseEventLoop.wait_executor_on_close attribute: true by default. loop.close() now waits for the default executor to finish by default. Set loop.wait_executor_on_close attribute to False to not wait for the executor. --- Doc/library/asyncio-eventloop.rst | 10 ++++++++-- Lib/asyncio/base_events.py | 4 +++- .../Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst | 4 ++++ 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 8673f84e96382e..f75ca9a966b6d5 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -140,12 +140,18 @@ Running and stopping the loop The loop must not be running when this function is called. Any pending callbacks will be discarded. - This method clears all queues and shuts down the executor, but does - not wait for the executor to finish. + This method clears all queues and shuts down the default executor. By + default, it waits for the default executor to finish. Set + *loop.wait_executor_on_close* to ``False`` to not wait for the executor. This method is idempotent and irreversible. No other methods should be called after the event loop is closed. + .. versionchanged:: 3.8 + The method now waits for the default executor to finish by default. + Added *loop.wait_executor_on_close* attribute. + + .. coroutinemethod:: loop.shutdown_asyncgens() Schedule all currently open :term:`asynchronous generator` objects to diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index e0025397fa8a85..b1a7f88f41165a 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -380,6 +380,8 @@ async def wait_closed(self): class BaseEventLoop(events.AbstractEventLoop): def __init__(self): + # If true, close() waits for the default executor to finish + self.wait_executor_on_close = True self._timer_cancelled_count = 0 self._closed = False self._stopping = False @@ -635,7 +637,7 @@ def close(self): executor = self._default_executor if executor is not None: self._default_executor = None - executor.shutdown(wait=False) + executor.shutdown(wait=self.wait_executor_on_close) def is_closed(self): """Returns True if the event loop was closed.""" diff --git a/Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst b/Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst new file mode 100644 index 00000000000000..fb2f7a5fa36e32 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst @@ -0,0 +1,4 @@ +:mod:`asyncio`: ``loop.close()`` now waits for the default executor to +finish by default. Set ``loop.wait_executor_on_close`` attribute to +``False`` to opt-in for Python 3.7 behavior (not wait for the executor to +finish). From eddef861b49f1635222a9e1771231c34a807debf Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 4 Jun 2019 07:38:10 +0900 Subject: [PATCH 302/441] bpo-37146: disable opcache when Py_DEBUG is defined (GH-13787) --with-pydebug is commonly used to find memory leaks. But opcache makes it harder. So disable opcache when Py_DEBUG is defined. --- Python/ceval.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Python/ceval.c b/Python/ceval.c index 0a4af915d6ffe0..2590ce6575a1dc 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -103,7 +103,14 @@ static long dxp[256]; #endif /* per opcode cache */ +#ifdef Py_DEBUG +// --with-pydebug is used to find memory leak. opcache makes it harder. +// So we disable opcache when Py_DEBUG is defined. +// See bpo-37146 +#define OPCACHE_MIN_RUNS 0 /* disable opcache */ +#else #define OPCACHE_MIN_RUNS 1024 /* create opcache when code executed this time */ +#endif #define OPCACHE_STATS 0 /* Enable stats */ #if OPCACHE_STATS From 9535aff9421f0a5639f6e4c4bb0f07a743ea8dba Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Tue, 4 Jun 2019 03:09:19 +0300 Subject: [PATCH 303/441] Revert "bpo-35621: Support running subprocesses in asyncio when loop is executed in non-main thread (#13630)" (GH-13793) https://bugs.python.org/issue35621 --- Lib/asyncio/unix_events.py | 240 ++---------------- Lib/test/test_asyncio/test_subprocess.py | 40 +-- Lib/test/test_asyncio/test_unix_events.py | 34 ++- .../2019-05-28-19-03-46.bpo-35621.Abc1lf.rst | 2 - 4 files changed, 54 insertions(+), 262 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index b943845d9363c6..28128d2977df64 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -2,7 +2,6 @@ import errno import io -import itertools import os import selectors import signal @@ -30,9 +29,7 @@ __all__ = ( 'SelectorEventLoop', 'AbstractChildWatcher', 'SafeChildWatcher', - 'FastChildWatcher', - 'MultiLoopChildWatcher', 'ThreadedChildWatcher', - 'DefaultEventLoopPolicy', + 'FastChildWatcher', 'DefaultEventLoopPolicy', ) @@ -187,13 +184,6 @@ async def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): with events.get_child_watcher() as watcher: - if not watcher.is_active(): - # Check early. - # Raising exception before process creation - # prevents subprocess execution if the watcher - # is not ready to handle it. - raise RuntimeError("asyncio.get_child_watcher() is not activated, " - "subprocess support is not installed.") waiter = self.create_future() transp = _UnixSubprocessTransport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, @@ -848,15 +838,6 @@ def close(self): """ raise NotImplementedError() - def is_active(self): - """Watcher status. - - Return True if the watcher is installed and ready to handle process exit - notifications. - - """ - raise NotImplementedError() - def __enter__(self): """Enter the watcher's context and allow starting new processes @@ -868,20 +849,6 @@ def __exit__(self, a, b, c): raise NotImplementedError() -def _compute_returncode(status): - if os.WIFSIGNALED(status): - # The child process died because of a signal. - return -os.WTERMSIG(status) - elif os.WIFEXITED(status): - # The child process exited (e.g sys.exit()). - return os.WEXITSTATUS(status) - else: - # The child exited, but we don't understand its status. - # This shouldn't happen, but if it does, let's just - # return that status; perhaps that helps debug it. - return status - - class BaseChildWatcher(AbstractChildWatcher): def __init__(self): @@ -891,9 +858,6 @@ def __init__(self): def close(self): self.attach_loop(None) - def is_active(self): - return self._loop is not None and self._loop.is_running() - def _do_waitpid(self, expected_pid): raise NotImplementedError() @@ -934,6 +898,19 @@ def _sig_chld(self): 'exception': exc, }) + def _compute_returncode(self, status): + if os.WIFSIGNALED(status): + # The child process died because of a signal. + return -os.WTERMSIG(status) + elif os.WIFEXITED(status): + # The child process exited (e.g sys.exit()). + return os.WEXITSTATUS(status) + else: + # The child exited, but we don't understand its status. + # This shouldn't happen, but if it does, let's just + # return that status; perhaps that helps debug it. + return status + class SafeChildWatcher(BaseChildWatcher): """'Safe' child watcher implementation. @@ -957,6 +934,11 @@ def __exit__(self, a, b, c): pass def add_child_handler(self, pid, callback, *args): + if self._loop is None: + raise RuntimeError( + "Cannot add child handler, " + "the child watcher does not have a loop attached") + self._callbacks[pid] = (callback, args) # Prevent a race condition in case the child is already terminated. @@ -992,7 +974,7 @@ def _do_waitpid(self, expected_pid): # The child process is still alive. return - returncode = _compute_returncode(status) + returncode = self._compute_returncode(status) if self._loop.get_debug(): logger.debug('process %s exited with returncode %s', expected_pid, returncode) @@ -1053,6 +1035,11 @@ def __exit__(self, a, b, c): def add_child_handler(self, pid, callback, *args): assert self._forks, "Must use the context manager" + if self._loop is None: + raise RuntimeError( + "Cannot add child handler, " + "the child watcher does not have a loop attached") + with self._lock: try: returncode = self._zombies.pop(pid) @@ -1085,7 +1072,7 @@ def _do_waitpid_all(self): # A child process is still alive. return - returncode = _compute_returncode(status) + returncode = self._compute_returncode(status) with self._lock: try: @@ -1114,177 +1101,6 @@ def _do_waitpid_all(self): callback(pid, returncode, *args) -class MultiLoopChildWatcher(AbstractChildWatcher): - # The class keeps compatibility with AbstractChildWatcher ABC - # To achieve this it has empty attach_loop() method - # and doesn't accept explicit loop argument - # for add_child_handler()/remove_child_handler() - # but retrieves the current loop by get_running_loop() - - def __init__(self): - self._callbacks = {} - self._saved_sighandler = None - - def is_active(self): - return self._saved_sighandler is not None - - def close(self): - self._callbacks.clear() - if self._saved_sighandler is not None: - handler = signal.getsignal(signal.SIGCHLD) - if handler != self._sig_chld: - logger.warning("SIGCHLD handler was changed by outside code") - else: - signal.signal(signal.SIGCHLD, self._saved_sighandler) - self._saved_sighandler = None - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - pass - - def add_child_handler(self, pid, callback, *args): - loop = events.get_running_loop() - self._callbacks[pid] = (loop, callback, args) - - # Prevent a race condition in case the child is already terminated. - self._do_waitpid(pid) - - def remove_child_handler(self, pid): - try: - del self._callbacks[pid] - return True - except KeyError: - return False - - def attach_loop(self, loop): - # Don't save the loop but initialize itself if called first time - # The reason to do it here is that attach_loop() is called from - # unix policy only for the main thread. - # Main thread is required for subscription on SIGCHLD signal - if self._saved_sighandler is None: - self._saved_sighandler = signal.signal(signal.SIGCHLD, self._sig_chld) - if self._saved_sighandler is None: - logger.warning("Previous SIGCHLD handler was set by non-Python code, " - "restore to default handler on watcher close.") - self._saved_sighandler = signal.SIG_DFL - - # Set SA_RESTART to limit EINTR occurrences. - signal.siginterrupt(signal.SIGCHLD, False) - - def _do_waitpid_all(self): - for pid in list(self._callbacks): - self._do_waitpid(pid) - - def _do_waitpid(self, expected_pid): - assert expected_pid > 0 - - try: - pid, status = os.waitpid(expected_pid, os.WNOHANG) - except ChildProcessError: - # The child process is already reaped - # (may happen if waitpid() is called elsewhere). - pid = expected_pid - returncode = 255 - logger.warning( - "Unknown child process pid %d, will report returncode 255", - pid) - debug_log = False - else: - if pid == 0: - # The child process is still alive. - return - - returncode = _compute_returncode(status) - debug_log = True - try: - loop, callback, args = self._callbacks.pop(pid) - except KeyError: # pragma: no cover - # May happen if .remove_child_handler() is called - # after os.waitpid() returns. - logger.warning("Child watcher got an unexpected pid: %r", - pid, exc_info=True) - else: - if loop.is_closed(): - logger.warning("Loop %r that handles pid %r is closed", loop, pid) - else: - if debug_log and loop.get_debug(): - logger.debug('process %s exited with returncode %s', - expected_pid, returncode) - loop.call_soon_threadsafe(callback, pid, returncode, *args) - - def _sig_chld(self, signum, frame): - try: - self._do_waitpid_all() - except (SystemExit, KeyboardInterrupt): - raise - except BaseException: - logger.warning('Unknown exception in SIGCHLD handler', exc_info=True) - - -class ThreadedChildWatcher(AbstractChildWatcher): - # The watcher uses a thread per process - # for waiting for the process finish. - # It doesn't require subscription on POSIX signal - - def __init__(self): - self._pid_counter = itertools.count(0) - - def is_active(self): - return True - - def close(self): - pass - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - pass - - def add_child_handler(self, pid, callback, *args): - loop = events.get_running_loop() - thread = threading.Thread(target=self._do_waitpid, - name=f"waitpid-{next(self._pid_counter)}", - args=(loop, pid, callback, args), - daemon=True) - thread.start() - - def remove_child_handler(self, pid): - # asyncio never calls remove_child_handler() !!! - # The method is no-op but is implemented because - # abstract base classe requires it - return True - - def attach_loop(self, loop): - pass - - def _do_waitpid(self, loop, expected_pid, callback, args): - assert expected_pid > 0 - - try: - pid, status = os.waitpid(expected_pid, 0) - except ChildProcessError: - # The child process is already reaped - # (may happen if waitpid() is called elsewhere). - pid = expected_pid - returncode = 255 - logger.warning( - "Unknown child process pid %d, will report returncode 255", - pid) - else: - returncode = _compute_returncode(status) - if loop.get_debug(): - logger.debug('process %s exited with returncode %s', - expected_pid, returncode) - - if loop.is_closed(): - logger.warning("Loop %r that handles pid %r is closed", loop, pid) - else: - loop.call_soon_threadsafe(callback, pid, returncode, *args) - - class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): """UNIX event loop policy with a watcher for child processes.""" _loop_factory = _UnixSelectorEventLoop @@ -1296,7 +1112,7 @@ def __init__(self): def _init_watcher(self): with events._lock: if self._watcher is None: # pragma: no branch - self._watcher = ThreadedChildWatcher() + self._watcher = SafeChildWatcher() if isinstance(threading.current_thread(), threading._MainThread): self._watcher.attach_loop(self._local._loop) @@ -1318,7 +1134,7 @@ def set_event_loop(self, loop): def get_child_watcher(self): """Get the watcher for child processes. - If not yet set, a ThreadedChildWatcher object is automatically created. + If not yet set, a SafeChildWatcher object is automatically created. """ if self._watcher is None: self._init_watcher() diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 582e1720246033..7d72e6cde4e7a8 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -633,7 +633,6 @@ async def execute(): self.assertIsNone(self.loop.run_until_complete(execute())) - if sys.platform != 'win32': # Unix class SubprocessWatcherMixin(SubprocessMixin): @@ -649,24 +648,7 @@ def setUp(self): watcher = self.Watcher() watcher.attach_loop(self.loop) policy.set_child_watcher(watcher) - - def tearDown(self): - super().setUp() - policy = asyncio.get_event_loop_policy() - watcher = policy.get_child_watcher() - policy.set_child_watcher(None) - watcher.attach_loop(None) - watcher.close() - - class SubprocessThreadedWatcherTests(SubprocessWatcherMixin, - test_utils.TestCase): - - Watcher = unix_events.ThreadedChildWatcher - - class SubprocessMultiLoopWatcherTests(SubprocessWatcherMixin, - test_utils.TestCase): - - Watcher = unix_events.MultiLoopChildWatcher + self.addCleanup(policy.set_child_watcher, None) class SubprocessSafeWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): @@ -688,25 +670,5 @@ def setUp(self): self.set_event_loop(self.loop) -class GenericWatcherTests: - - def test_create_subprocess_fails_with_inactive_watcher(self): - - async def execute(): - watcher = mock.create_authspec(asyncio.AbstractChildWatcher) - watcher.is_active.return_value = False - asyncio.set_child_watcher(watcher) - - with self.assertRaises(RuntimeError): - await subprocess.create_subprocess_exec( - support.FakePath(sys.executable), '-c', 'pass') - - watcher.add_child_handler.assert_not_called() - - self.assertIsNone(self.loop.run_until_complete(execute())) - - - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 462a8b3c785917..5c610cdd67ba49 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1082,8 +1082,6 @@ def test_not_implemented(self): NotImplementedError, watcher.attach_loop, f) self.assertRaises( NotImplementedError, watcher.close) - self.assertRaises( - NotImplementedError, watcher.is_active) self.assertRaises( NotImplementedError, watcher.__enter__) self.assertRaises( @@ -1786,6 +1784,15 @@ def test_close(self, m): if isinstance(self.watcher, asyncio.FastChildWatcher): self.assertFalse(self.watcher._zombies) + @waitpid_mocks + def test_add_child_handler_with_no_loop_attached(self, m): + callback = mock.Mock() + with self.create_watcher() as watcher: + with self.assertRaisesRegex( + RuntimeError, + 'the child watcher does not have a loop attached'): + watcher.add_child_handler(100, callback) + class SafeChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): @@ -1802,16 +1809,17 @@ class PolicyTests(unittest.TestCase): def create_policy(self): return asyncio.DefaultEventLoopPolicy() - def test_get_default_child_watcher(self): + def test_get_child_watcher(self): policy = self.create_policy() self.assertIsNone(policy._watcher) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, asyncio.ThreadedChildWatcher) + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIs(policy._watcher, watcher) self.assertIs(watcher, policy.get_child_watcher()) + self.assertIsNone(watcher._loop) def test_get_child_watcher_after_set(self): policy = self.create_policy() @@ -1821,6 +1829,18 @@ def test_get_child_watcher_after_set(self): self.assertIs(policy._watcher, watcher) self.assertIs(watcher, policy.get_child_watcher()) + def test_get_child_watcher_with_mainloop_existing(self): + policy = self.create_policy() + loop = policy.get_event_loop() + + self.assertIsNone(policy._watcher) + watcher = policy.get_child_watcher() + + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) + self.assertIs(watcher._loop, loop) + + loop.close() + def test_get_child_watcher_thread(self): def f(): @@ -1846,11 +1866,7 @@ def test_child_watcher_replace_mainloop_existing(self): policy = self.create_policy() loop = policy.get_event_loop() - # Explicitly setup SafeChildWatcher, - # default ThreadedChildWatcher has no _loop property - watcher = asyncio.SafeChildWatcher() - policy.set_child_watcher(watcher) - watcher.attach_loop(loop) + watcher = policy.get_child_watcher() self.assertIs(watcher._loop, loop) diff --git a/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst b/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst deleted file mode 100644 index c492e1de6d5c42..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-19-03-46.bpo-35621.Abc1lf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Support running asyncio subprocesses when execution event loop in a thread -on UNIX. From 0fd2c300c2a85b3b227a907b2a39ef79fa86d850 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Jun 2019 03:15:09 +0200 Subject: [PATCH 304/441] Revert "bpo-36818: Add PyInterpreterState.runtime field. (gh-13129)" (GH-13795) This reverts commit 396e0a8d9dc65453cb9d53500d0a620602656cfe. --- Include/cpython/pystate.h | 6 +- Include/internal/pycore_object.h | 7 +- Include/internal/pycore_pylifecycle.h | 10 ++- Include/internal/pycore_pystate.h | 12 +-- .../2019-05-06-14-46-48.bpo-36818.5UDDLj.rst | 1 - Modules/_threadmodule.c | 2 +- Python/ceval.c | 26 +++--- Python/import.c | 3 +- Python/pylifecycle.c | 15 ++-- Python/pystate.c | 89 ++++++++++--------- Python/sysmodule.c | 31 ++++--- 11 files changed, 103 insertions(+), 99 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 74e7fc96bec900..94b0809cd4f015 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -110,9 +110,9 @@ struct _ts { * if the thread holds the last reference to the lock, decref'ing the * lock will delete the lock, and that may trigger arbitrary Python code * if there's a weakref, with a callback, to the lock. But by this time - * _PyRuntimeState.gilstate.tstate_current is already NULL, so only the - * simplest of C code can be allowed to run (in particular it must not be - * possible to release the GIL). + * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest + * of C code can be allowed to run (in particular it must not be possible to + * release the GIL). * So instead of holding the lock directly, the tstate holds a weakref to * the lock: that's the value of on_delete_data below. Decref'ing a * weakref is harmless. diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 1c5beb01f45823..81548f819198e3 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -19,10 +19,9 @@ PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); * NB: While the object is tracked by the collector, it must be safe to call the * ob_traverse method. * - * Internal note: _PyRuntimeState.gc.generation0->_gc_prev doesn't have - * any bit flags because it's not object header. So we don't use - * _PyGCHead_PREV() and _PyGCHead_SET_PREV() for it to avoid unnecessary - * bitwise operations. + * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags + * because it's not object header. So we don't use _PyGCHead_PREV() and + * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. * * The PyObject_GC_Track() function is the public version of this macro. */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index e30341710c20ae..8a692ea1649512 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -39,10 +39,13 @@ extern PyStatus _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(void); extern PyStatus _PySys_Create( + _PyRuntimeState *runtime, PyInterpreterState *interp, PyObject **sysmod_p); extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); -extern int _PySys_InitMain(PyInterpreterState *interp); +extern int _PySys_InitMain( + _PyRuntimeState *runtime, + PyInterpreterState *interp); extern PyStatus _PyImport_Init(PyInterpreterState *interp); extern PyStatus _PyExc_Init(void); extern PyStatus _PyErr_Init(void); @@ -83,7 +86,10 @@ extern void _PyHash_Fini(void); extern int _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); -extern void _PyGILState_Init(PyThreadState *tstate); +extern void _PyGILState_Init( + _PyRuntimeState *runtime, + PyInterpreterState *interp, + PyThreadState *tstate); extern void _PyGILState_Fini(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 520a74b8a61fde..3ab4009770c9a0 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -19,9 +19,6 @@ extern "C" { #include "pycore_pymem.h" #include "pycore_warnings.h" -// forward -struct pyruntimestate; - /* ceval state */ @@ -71,7 +68,6 @@ struct _is { struct _is *next; struct _ts *tstate_head; - struct pyruntimestate *runtime; int64_t id; int64_t id_refcount; @@ -300,8 +296,12 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); /* Other */ -PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *tstate); -PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_Init( + _PyRuntimeState *runtime, + PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_DeleteExcept( + _PyRuntimeState *runtime, + PyThreadState *tstate); PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( struct _gilstate_runtime_state *gilstate, diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst deleted file mode 100644 index bb6c56a628e955..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst +++ /dev/null @@ -1 +0,0 @@ -Add PyInterpreterState.runtime (and use it). diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 099afd86d05505..d5e40ef999e3d5 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -996,7 +996,7 @@ t_bootstrap(void *boot_raw) tstate = boot->tstate; tstate->thread_id = PyThread_get_thread_ident(); - _PyThreadState_Init(tstate); + _PyThreadState_Init(&_PyRuntime, tstate); PyEval_AcquireThread(tstate); tstate->interp->num_threads++; res = PyObject_Call(boot->func, boot->args, boot->keyw); diff --git a/Python/ceval.c b/Python/ceval.c index 2590ce6575a1dc..7063647d584f65 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -238,9 +238,8 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval) } static inline void -exit_thread_if_finalizing(PyThreadState *tstate) +exit_thread_if_finalizing(_PyRuntimeState *runtime, PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; /* _Py_Finalizing is protected by the GIL */ if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { drop_gil(&runtime->ceval, tstate); @@ -287,7 +286,7 @@ PyEval_AcquireLock(void) Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); } take_gil(ceval, tstate); - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); } void @@ -308,15 +307,14 @@ PyEval_AcquireThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_AcquireThread: NULL new thread state"); } - assert(tstate->interp != NULL); - _PyRuntimeState *runtime = tstate->interp->runtime; + _PyRuntimeState *runtime = &_PyRuntime; struct _ceval_runtime_state *ceval = &runtime->ceval; /* Check someone has called PyEval_InitThreads() to create the lock */ assert(gil_created(&ceval->gil)); take_gil(ceval, tstate); - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); } @@ -328,9 +326,8 @@ PyEval_ReleaseThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_ReleaseThread: NULL thread state"); } - assert(tstate->interp != NULL); - _PyRuntimeState *runtime = tstate->interp->runtime; + _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (new_tstate != tstate) { Py_FatalError("PyEval_ReleaseThread: wrong thread state"); @@ -361,7 +358,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) } /* Destroy all threads except the current one */ - _PyThreadState_DeleteExcept(current_tstate); + _PyThreadState_DeleteExcept(runtime, current_tstate); } /* This function is used to signal that async exceptions are waiting to be @@ -390,18 +387,17 @@ PyEval_SaveThread(void) void PyEval_RestoreThread(PyThreadState *tstate) { + _PyRuntimeState *runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + if (tstate == NULL) { Py_FatalError("PyEval_RestoreThread: NULL tstate"); } - assert(tstate->interp != NULL); - - _PyRuntimeState *runtime = tstate->interp->runtime; - struct _ceval_runtime_state *ceval = &runtime->ceval; assert(gil_created(&ceval->gil)); int err = errno; take_gil(ceval, tstate); - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); errno = err; _PyThreadState_Swap(&runtime->gilstate, tstate); @@ -1250,7 +1246,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) take_gil(ceval, tstate); /* Check if we should make a quick exit. */ - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("ceval: orphan tstate"); diff --git a/Python/import.c b/Python/import.c index 68d1f4003abcee..ab7db6bc17f6b1 100644 --- a/Python/import.c +++ b/Python/import.c @@ -541,8 +541,7 @@ PyImport_Cleanup(void) _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings machinery. */ - _PyRuntimeState *runtime = interp->runtime; - _PyGC_DumpShutdownStats(runtime); + _PyGC_DumpShutdownStats(&_PyRuntime); /* Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index fca2ee65519104..751c4d6d1d631c 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -545,7 +545,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, _PyEval_FiniThreads(&runtime->ceval); /* Auto-thread-state API */ - _PyGILState_Init(tstate); + _PyGILState_Init(runtime, interp, tstate); /* Create the GIL */ PyEval_InitThreads(); @@ -683,7 +683,7 @@ pyinit_config(_PyRuntimeState *runtime, } PyObject *sysmod; - status = _PySys_Create(interp, &sysmod); + status = _PySys_Create(runtime, interp, &sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -892,9 +892,8 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * non-zero return code. */ static PyStatus -pyinit_main(PyInterpreterState *interp) +pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; if (!runtime->core_initialized) { return _PyStatus_ERR("runtime core not initialized"); } @@ -920,7 +919,7 @@ pyinit_main(PyInterpreterState *interp) return _PyStatus_ERR("can't initialize time"); } - if (_PySys_InitMain(interp) < 0) { + if (_PySys_InitMain(runtime, interp) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } @@ -1000,7 +999,7 @@ _Py_InitializeMain(void) _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - return pyinit_main(interp); + return pyinit_main(runtime, interp); } @@ -1027,7 +1026,7 @@ Py_InitializeFromConfig(const PyConfig *config) config = &interp->config; if (config->_init_main) { - status = pyinit_main(interp); + status = pyinit_main(runtime, interp); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1457,7 +1456,7 @@ new_interpreter(PyThreadState **tstate_p) } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); - if (_PySys_InitMain(interp) < 0) { + if (_PySys_InitMain(runtime, interp) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } } diff --git a/Python/pystate.c b/Python/pystate.c index 2b7db0e48debe9..833e0fb30dcb26 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -39,6 +39,7 @@ extern "C" { /* Forward declarations */ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); +static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate); static PyStatus @@ -191,8 +192,6 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) PyInterpreterState * PyInterpreterState_New(void) { - _PyRuntimeState *runtime = &_PyRuntime; - if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) { return NULL; } @@ -203,9 +202,6 @@ PyInterpreterState_New(void) } memset(interp, 0, sizeof(*interp)); - - interp->runtime = runtime; - interp->id_refcount = -1; interp->check_interval = 100; @@ -227,6 +223,7 @@ PyInterpreterState_New(void) #endif #endif + _PyRuntimeState *runtime = &_PyRuntime; struct pyinterpreters *interpreters = &runtime->interpreters; HEAD_LOCK(runtime); @@ -260,11 +257,9 @@ PyInterpreterState_New(void) } -void -PyInterpreterState_Clear(PyInterpreterState *interp) +static void +_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; - if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) { PyErr_Clear(); } @@ -302,25 +297,31 @@ PyInterpreterState_Clear(PyInterpreterState *interp) // objects have been cleaned up at the point. } +void +PyInterpreterState_Clear(PyInterpreterState *interp) +{ + _PyInterpreterState_Clear(&_PyRuntime, interp); +} + static void -zapthreads(PyInterpreterState *interp) +zapthreads(_PyRuntimeState *runtime, PyInterpreterState *interp) { - PyThreadState *ts; + PyThreadState *p; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ - while ((ts = interp->tstate_head) != NULL) { - PyThreadState_Delete(ts); + while ((p = interp->tstate_head) != NULL) { + _PyThreadState_Delete(runtime, p); } } -void -PyInterpreterState_Delete(PyInterpreterState *interp) +static void +_PyInterpreterState_Delete(_PyRuntimeState *runtime, + PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; struct pyinterpreters *interpreters = &runtime->interpreters; - zapthreads(interp); + zapthreads(runtime, interp); HEAD_LOCK(runtime); PyInterpreterState **p; for (p = &interpreters->head; ; p = &(*p)->next) { @@ -349,6 +350,13 @@ PyInterpreterState_Delete(PyInterpreterState *interp) } +void +PyInterpreterState_Delete(PyInterpreterState *interp) +{ + _PyInterpreterState_Delete(&_PyRuntime, interp); +} + + /* * Delete all interpreter states except the main interpreter. If there * is a current interpreter state, it *must* be the main interpreter. @@ -375,8 +383,8 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) continue; } - PyInterpreterState_Clear(interp); // XXX must activate? - zapthreads(interp); + _PyInterpreterState_Clear(runtime, interp); // XXX must activate? + zapthreads(runtime, interp); if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } @@ -489,8 +497,7 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) if (interp->id_mutex == NULL) { return; } - _PyRuntimeState *runtime = interp->runtime; - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); interp->id_refcount -= 1; @@ -552,7 +559,7 @@ threadstate_getframe(PyThreadState *self) static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { - _PyRuntimeState *runtime = interp->runtime; + _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (tstate == NULL) { return NULL; @@ -608,7 +615,7 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->id = ++interp->tstate_next_unique_id; if (init) { - _PyThreadState_Init(tstate); + _PyThreadState_Init(runtime, tstate); } HEAD_LOCK(runtime); @@ -635,9 +642,8 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) } void -_PyThreadState_Init(PyThreadState *tstate) +_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; _PyGILState_NoteThreadState(&runtime->gilstate, tstate); } @@ -802,7 +808,7 @@ PyThreadState_Clear(PyThreadState *tstate) /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(PyThreadState *tstate) +tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) { if (tstate == NULL) { Py_FatalError("PyThreadState_Delete: NULL tstate"); @@ -811,7 +817,6 @@ tstate_delete_common(PyThreadState *tstate) if (interp == NULL) { Py_FatalError("PyThreadState_Delete: NULL interp"); } - _PyRuntimeState *runtime = interp->runtime; HEAD_LOCK(runtime); if (tstate->prev) tstate->prev->next = tstate->next; @@ -827,10 +832,9 @@ tstate_delete_common(PyThreadState *tstate) } -void -PyThreadState_Delete(PyThreadState *tstate) +static void +_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; struct _gilstate_runtime_state *gilstate = &runtime->gilstate; if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { Py_FatalError("PyThreadState_Delete: tstate is still current"); @@ -840,7 +844,14 @@ PyThreadState_Delete(PyThreadState *tstate) { PyThread_tss_set(&gilstate->autoTSSkey, NULL); } - tstate_delete_common(tstate); + tstate_delete_common(runtime, tstate); +} + + +void +PyThreadState_Delete(PyThreadState *tstate) +{ + _PyThreadState_Delete(&_PyRuntime, tstate); } @@ -852,7 +863,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - tstate_delete_common(tstate); + tstate_delete_common(runtime, tstate); if (gilstate->autoInterpreterState && PyThread_tss_get(&gilstate->autoTSSkey) == tstate) { @@ -877,10 +888,9 @@ PyThreadState_DeleteCurrent() * be kept in those other interpreteres. */ void -_PyThreadState_DeleteExcept(PyThreadState *tstate) +_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) { PyInterpreterState *interp = tstate->interp; - _PyRuntimeState *runtime = interp->runtime; PyThreadState *p, *next, *garbage; HEAD_LOCK(runtime); /* Remove all thread states, except tstate, from the linked list of @@ -1119,9 +1129,8 @@ _PyThread_CurrentFrames(void) static int PyThreadState_IsCurrent(PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; /* Must be the tstate for this thread */ - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; assert(_PyGILState_GetThisThreadState(gilstate) == tstate); return tstate == _PyRuntimeGILState_GetThreadState(gilstate); } @@ -1130,14 +1139,12 @@ PyThreadState_IsCurrent(PyThreadState *tstate) Py_Initialize/Py_FinalizeEx */ void -_PyGILState_Init(PyThreadState *tstate) +_PyGILState_Init(_PyRuntimeState *runtime, + PyInterpreterState *interp, PyThreadState *tstate) { /* must init with valid states */ - assert(tstate != NULL); - PyInterpreterState *interp = tstate->interp; assert(interp != NULL); - _PyRuntimeState *runtime = interp->runtime; - assert(runtime != NULL); + assert(tstate != NULL); struct _gilstate_runtime_state *gilstate = &runtime->gilstate; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 97bff94d8b4196..12b1bd7711d5b8 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -120,9 +120,8 @@ should_audit(void) if (!ts) { return 0; } - PyInterpreterState *is = ts->interp; - _PyRuntimeState *runtime = is->runtime; - return runtime->audit_hook_head + PyInterpreterState *is = ts ? ts->interp : NULL; + return _PyRuntime.audit_hook_head || (is && is->audit_hooks) || PyDTrace_AUDIT_ENABLED(); } @@ -281,8 +280,8 @@ void _PySys_ClearAuditHooks(void) { PySys_Audit("cpython._PySys_ClearAuditHooks", NULL); PyErr_Clear(); - _Py_AuditHookEntry *e = runtime->audit_hook_head, *n; - runtime->audit_hook_head = NULL; + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n; + _PyRuntime.audit_hook_head = NULL; while (e) { n = e->next; PyMem_RawFree(e); @@ -293,7 +292,6 @@ void _PySys_ClearAuditHooks(void) { int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) { - _PyRuntimeState *runtime = &_PyRuntime; /* Invoke existing audit hooks to allow them an opportunity to abort. */ /* Cannot invoke hooks until we are initialized */ if (Py_IsInitialized()) { @@ -307,10 +305,10 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) } } - _Py_AuditHookEntry *e = runtime->audit_hook_head; + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; if (!e) { e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); - runtime->audit_hook_head = e; + _PyRuntime.audit_hook_head = e; } else { while (e->next) e = e->next; @@ -2415,9 +2413,8 @@ static PyStructSequence_Desc flags_desc = { }; static PyObject* -make_flags(PyInterpreterState *interp) +make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; int pos = 0; PyObject *seq; const PyPreConfig *preconfig = &runtime->preconfig; @@ -2636,7 +2633,8 @@ static struct PyModuleDef sysmodule = { } while (0) static PyStatus -_PySys_InitCore(PyInterpreterState *interp, PyObject *sysdict) +_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject *sysdict) { PyObject *version_info; int res; @@ -2730,7 +2728,7 @@ _PySys_InitCore(PyInterpreterState *interp, PyObject *sysdict) } } /* Set flags to their default values (updated by _PySys_InitMain()) */ - SET_SYS_FROM_STRING("flags", make_flags(interp)); + SET_SYS_FROM_STRING("flags", make_flags(runtime, interp)); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -2851,7 +2849,7 @@ sys_create_xoptions_dict(const PyConfig *config) int -_PySys_InitMain(PyInterpreterState *interp) +_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) { PyObject *sysdict = interp->sysdict; const PyConfig *config = &interp->config; @@ -2905,7 +2903,7 @@ _PySys_InitMain(PyInterpreterState *interp) #undef SET_SYS_FROM_WSTR /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(interp)); + SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp)); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; @@ -2972,7 +2970,8 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict) /* Create sys module without all attributes: _PySys_InitMain() should be called later to add remaining attributes. */ PyStatus -_PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p) +_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject **sysmod_p) { PyObject *modules = PyDict_New(); if (modules == NULL) { @@ -3001,7 +3000,7 @@ _PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p) return status; } - status = _PySys_InitCore(interp, sysdict); + status = _PySys_InitCore(runtime, interp, sysdict); if (_PyStatus_EXCEPTION(status)) { return status; } From 963eb0f4738456455b9bef7eb531b46805415208 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 4 Jun 2019 01:23:06 -0700 Subject: [PATCH 305/441] bpo-35431: Drop the k <= n requirement (GH-13798) --- Doc/library/math.rst | 20 ++++++++++++-------- Lib/test/test_math.py | 12 ++++++------ Modules/clinic/mathmodule.c.h | 22 +++++++++++++--------- Modules/mathmodule.c | 33 ++++++++++++++++++--------------- 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index c5a77f1fab9fd6..4a157897245298 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -41,12 +41,15 @@ Number-theoretic and representation functions Return the number of ways to choose *k* items from *n* items without repetition and without order. - Also called the binomial coefficient. It is mathematically equal to the expression - ``n! / (k! (n - k)!)``. It is equivalent to the coefficient of the *k*-th term in the - polynomial expansion of the expression ``(1 + x) ** n``. + Evaluates to ``n! / (k! * (n - k)!)`` when ``k <= n`` and evaluates + to zero when ``k > n``. - Raises :exc:`TypeError` if the arguments not integers. - Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*. + Also called the binomial coefficient because it is equivalent + to the coefficient of k-th term in polynomial expansion of the + expression ``(1 + x) ** n``. + + Raises :exc:`TypeError` if either of the arguments not integers. + Raises :exc:`ValueError` if either of the arguments are negative. .. versionadded:: 3.8 @@ -212,10 +215,11 @@ Number-theoretic and representation functions Return the number of ways to choose *k* items from *n* items without repetition and with order. - It is mathematically equal to the expression ``n! / (n - k)!``. + Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates + to zero when ``k > n``. - Raises :exc:`TypeError` if the arguments not integers. - Raises :exc:`ValueError` if the arguments are negative or if *k* > *n*. + Raises :exc:`TypeError` if either of the arguments not integers. + Raises :exc:`ValueError` if either of the arguments are negative. .. versionadded:: 3.8 diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 96e0cf2fe67197..86e3923af6d074 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1904,9 +1904,9 @@ def testPerm(self): self.assertRaises(ValueError, perm, 1, -1) self.assertRaises(ValueError, perm, 1, -2**1000) - # Raises value error if k is greater than n - self.assertRaises(ValueError, perm, 1, 2) - self.assertRaises(ValueError, perm, 1, 2**1000) + # Returns zero if k is greater than n + self.assertEqual(perm(1, 2), 0) + self.assertEqual(perm(1, 2**1000), 0) n = 2**1000 self.assertEqual(perm(n, 0), 1) @@ -1970,9 +1970,9 @@ def testComb(self): self.assertRaises(ValueError, comb, 1, -1) self.assertRaises(ValueError, comb, 1, -2**1000) - # Raises value error if k is greater than n - self.assertRaises(ValueError, comb, 1, 2) - self.assertRaises(ValueError, comb, 1, 2**1000) + # Returns zero if k is greater than n + self.assertEqual(comb(1, 2), 0) + self.assertEqual(comb(1, 2**1000), 0) n = 2**1000 self.assertEqual(comb(n, 0), 1) diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 0efe5cc409ceb1..cdf4305641b7d9 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -644,10 +644,11 @@ PyDoc_STRVAR(math_perm__doc__, "\n" "Number of ways to choose k items from n items without repetition and with order.\n" "\n" -"It is mathematically equal to the expression n! / (n - k)!.\n" +"Evaluates to n! / (n - k)! when k <= n and evaluates\n" +"to zero when k > n.\n" "\n" -"Raises TypeError if the arguments are not integers.\n" -"Raises ValueError if the arguments are negative or if k > n."); +"Raises TypeError if either of the arguments are not integers.\n" +"Raises ValueError if either of the arguments are negative."); #define MATH_PERM_METHODDEF \ {"perm", (PyCFunction)(void(*)(void))math_perm, METH_FASTCALL, math_perm__doc__}, @@ -679,12 +680,15 @@ PyDoc_STRVAR(math_comb__doc__, "\n" "Number of ways to choose k items from n items without repetition and without order.\n" "\n" -"Also called the binomial coefficient. It is mathematically equal to the expression\n" -"n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in\n" -"polynomial expansion of the expression (1 + x)**n.\n" +"Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n" +"to zero when k > n.\n" "\n" -"Raises TypeError if the arguments are not integers.\n" -"Raises ValueError if the arguments are negative or if k > n."); +"Also called the binomial coefficient because it is equivalent\n" +"to the coefficient of k-th term in polynomial expansion of the\n" +"expression (1 + x)**n.\n" +"\n" +"Raises TypeError if either of the arguments are not integers.\n" +"Raises ValueError if either of the arguments are negative."); #define MATH_COMB_METHODDEF \ {"comb", (PyCFunction)(void(*)(void))math_comb, METH_FASTCALL, math_comb__doc__}, @@ -709,4 +713,4 @@ math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=a82b0e705b6d0ec0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5004266613284dcc input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 6e1099321c5495..9a9a8159ced407 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -3007,15 +3007,16 @@ math.perm Number of ways to choose k items from n items without repetition and with order. -It is mathematically equal to the expression n! / (n - k)!. +Evaluates to n! / (n - k)! when k <= n and evaluates +to zero when k > n. -Raises TypeError if the arguments are not integers. -Raises ValueError if the arguments are negative or if k > n. +Raises TypeError if either of the arguments are not integers. +Raises ValueError if either of the arguments are negative. [clinic start generated code]*/ static PyObject * math_perm_impl(PyObject *module, PyObject *n, PyObject *k) -/*[clinic end generated code: output=e021a25469653e23 input=f71ee4f6ff26be24]*/ +/*[clinic end generated code: output=e021a25469653e23 input=b2e7729d9a1949cf]*/ { PyObject *result = NULL, *factor = NULL; int overflow, cmp; @@ -3052,8 +3053,8 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) cmp = PyObject_RichCompareBool(n, k, Py_LT); if (cmp != 0) { if (cmp > 0) { - PyErr_SetString(PyExc_ValueError, - "k must be an integer less than or equal to n"); + result = PyLong_FromLong(0); + goto done; } goto error; } @@ -3121,18 +3122,21 @@ math.comb Number of ways to choose k items from n items without repetition and without order. -Also called the binomial coefficient. It is mathematically equal to the expression -n! / (k! * (n - k)!). It is equivalent to the coefficient of k-th term in -polynomial expansion of the expression (1 + x)**n. +Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates +to zero when k > n. + +Also called the binomial coefficient because it is equivalent +to the coefficient of k-th term in polynomial expansion of the +expression (1 + x)**n. -Raises TypeError if the arguments are not integers. -Raises ValueError if the arguments are negative or if k > n. +Raises TypeError if either of the arguments are not integers. +Raises ValueError if either of the arguments are negative. [clinic start generated code]*/ static PyObject * math_comb_impl(PyObject *module, PyObject *n, PyObject *k) -/*[clinic end generated code: output=bd2cec8d854f3493 input=2f336ac9ec8242f9]*/ +/*[clinic end generated code: output=bd2cec8d854f3493 input=9a05315af2518709]*/ { PyObject *result = NULL, *factor = NULL, *temp; int overflow, cmp; @@ -3173,9 +3177,8 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) } if (Py_SIZE(temp) < 0) { Py_DECREF(temp); - PyErr_SetString(PyExc_ValueError, - "k must be an integer less than or equal to n"); - goto error; + result = PyLong_FromLong(0); + goto done; } cmp = PyObject_RichCompareBool(temp, k, Py_LT); if (cmp > 0) { From 4cdbc452ce308bb55523e53963cabdc988e3f44b Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 4 Jun 2019 11:26:20 +0100 Subject: [PATCH 306/441] bpo-37148: Fix asyncio test that check for warning when running the test suite with huntleaks (GH-13800) --- Lib/test/test_asyncio/test_streams.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index df3d7e7dfa455c..c1b9dc95ee621f 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -1229,10 +1229,14 @@ def test_eof_feed_when_closing_writer(self): self.assertEqual(messages, []) def test_stream_reader_create_warning(self): + with contextlib.suppress(AttributeError): + del asyncio.StreamReader with self.assertWarns(DeprecationWarning): asyncio.StreamReader def test_stream_writer_create_warning(self): + with contextlib.suppress(AttributeError): + del asyncio.StreamWriter with self.assertWarns(DeprecationWarning): asyncio.StreamWriter From 8bcf2629a2e27267edba98fd3b5ed274b25aeb2d Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Tue, 4 Jun 2019 11:37:46 +0100 Subject: [PATCH 307/441] More updates to the annotated assignments docs (GH-13794) --- Doc/reference/simple_stmts.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index 9c0430da1fb2a4..0a043a90050c4e 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -330,10 +330,9 @@ statement, of a variable or attribute annotation and an optional assignment stat .. productionlist:: annotated_assignment_stmt: `augtarget` ":" `expression` - : ["=" (`expression_list` | `yield_expression`)] + : ["=" (`starred_expression` | `yield_expression`)] -The difference from normal :ref:`assignment` is that only single target and -only single right hand side value is allowed. +The difference from normal :ref:`assignment` is that only single target is allowed. For simple names as assignment targets, if in class or module scope, the annotations are evaluated and stored in a special class or module @@ -369,7 +368,7 @@ target, then the interpreter evaluates the target except for the last .. versionchanged:: 3.8 Now annotated assignments allow same expressions in the right hand side as - the augmented assignments. Previously, some expressions (like un-parenthesized + the regular assignments. Previously, some expressions (like un-parenthesized tuple expressions) caused a syntax error. From 8f4bbb5d627e07a5508099e84796cecaeb9e32ab Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 4 Jun 2019 03:40:23 -0700 Subject: [PATCH 308/441] Fix grammar (GH-13801) --- Doc/library/math.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 4a157897245298..28ed5d21f03adb 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -48,7 +48,7 @@ Number-theoretic and representation functions to the coefficient of k-th term in polynomial expansion of the expression ``(1 + x) ** n``. - Raises :exc:`TypeError` if either of the arguments not integers. + Raises :exc:`TypeError` if either of the arguments are not integers. Raises :exc:`ValueError` if either of the arguments are negative. .. versionadded:: 3.8 @@ -218,7 +218,7 @@ Number-theoretic and representation functions Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates to zero when ``k > n``. - Raises :exc:`TypeError` if either of the arguments not integers. + Raises :exc:`TypeError` if either of the arguments are not integers. Raises :exc:`ValueError` if either of the arguments are negative. .. versionadded:: 3.8 From 7f9a2ae78051877f4d966119e2fcd27ec77eda1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 4 Jun 2019 13:03:20 +0200 Subject: [PATCH 309/441] Revert "bpo-34037, asyncio: add BaseEventLoop.wait_executor_on_close (GH-13786)" (#13802) This reverts commit 0f0a30f4da4b529e0f7df857b9f575b231b32758. --- Doc/library/asyncio-eventloop.rst | 10 ++-------- Lib/asyncio/base_events.py | 4 +--- .../Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst | 4 ---- 3 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index f75ca9a966b6d5..8673f84e96382e 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -140,18 +140,12 @@ Running and stopping the loop The loop must not be running when this function is called. Any pending callbacks will be discarded. - This method clears all queues and shuts down the default executor. By - default, it waits for the default executor to finish. Set - *loop.wait_executor_on_close* to ``False`` to not wait for the executor. + This method clears all queues and shuts down the executor, but does + not wait for the executor to finish. This method is idempotent and irreversible. No other methods should be called after the event loop is closed. - .. versionchanged:: 3.8 - The method now waits for the default executor to finish by default. - Added *loop.wait_executor_on_close* attribute. - - .. coroutinemethod:: loop.shutdown_asyncgens() Schedule all currently open :term:`asynchronous generator` objects to diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index b1a7f88f41165a..e0025397fa8a85 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -380,8 +380,6 @@ async def wait_closed(self): class BaseEventLoop(events.AbstractEventLoop): def __init__(self): - # If true, close() waits for the default executor to finish - self.wait_executor_on_close = True self._timer_cancelled_count = 0 self._closed = False self._stopping = False @@ -637,7 +635,7 @@ def close(self): executor = self._default_executor if executor is not None: self._default_executor = None - executor.shutdown(wait=self.wait_executor_on_close) + executor.shutdown(wait=False) def is_closed(self): """Returns True if the event loop was closed.""" diff --git a/Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst b/Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst deleted file mode 100644 index fb2f7a5fa36e32..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-03-22-54-15.bpo-34037.fKNAbH.rst +++ /dev/null @@ -1,4 +0,0 @@ -:mod:`asyncio`: ``loop.close()`` now waits for the default executor to -finish by default. Set ``loop.wait_executor_on_close`` attribute to -``False`` to opt-in for Python 3.7 behavior (not wait for the executor to -finish). From 35890abb8da7848919d70790f73fa091d7f98769 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Tue, 4 Jun 2019 14:37:10 +0300 Subject: [PATCH 310/441] Make StreamServer.close() tests more robust (GH-13790) --- Lib/test/test_asyncio/test_streams.py | 48 +++++++++++++++++++++------ 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index c1b9dc95ee621f..e484746432af50 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -1507,10 +1507,14 @@ async def test(): def test_stream_server_abort(self): server_stream_aborted = False - fut = self.loop.create_future() + fut1 = self.loop.create_future() + fut2 = self.loop.create_future() async def handle_client(stream): - await fut + data = await stream.readexactly(4) + self.assertEqual(b'data', data) + fut1.set_result(None) + await fut2 self.assertEqual(b'', await stream.readline()) nonlocal server_stream_aborted server_stream_aborted = True @@ -1518,7 +1522,8 @@ async def handle_client(stream): async def client(srv): addr = srv.sockets[0].getsockname() stream = await asyncio.connect(*addr) - fut.set_result(None) + await stream.write(b'data') + await fut2 self.assertEqual(b'', await stream.readline()) await stream.close() @@ -1526,7 +1531,8 @@ async def test(): async with asyncio.StreamServer(handle_client, '127.0.0.1', 0) as server: await server.start_serving() task = asyncio.create_task(client(server)) - await fut + await fut1 + fut2.set_result(None) await server.abort() await task @@ -1534,21 +1540,31 @@ async def test(): self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) self.loop.run_until_complete(test()) self.assertEqual(messages, []) - self.assertTrue(fut.done()) + self.assertTrue(fut1.done()) + self.assertTrue(fut2.done()) self.assertTrue(server_stream_aborted) def test_stream_shutdown_hung_task(self): fut1 = self.loop.create_future() fut2 = self.loop.create_future() + cancelled = self.loop.create_future() async def handle_client(stream): - while True: - await asyncio.sleep(0.01) + data = await stream.readexactly(4) + self.assertEqual(b'data', data) + fut1.set_result(None) + await fut2 + try: + while True: + await asyncio.sleep(0.01) + except asyncio.CancelledError: + cancelled.set_result(None) + raise async def client(srv): addr = srv.sockets[0].getsockname() stream = await asyncio.connect(*addr) - fut1.set_result(None) + await stream.write(b'data') await fut2 self.assertEqual(b'', await stream.readline()) await stream.close() @@ -1561,9 +1577,10 @@ async def test(): await server.start_serving() task = asyncio.create_task(client(server)) await fut1 - await server.close() fut2.set_result(None) + await server.close() await task + await cancelled messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) @@ -1571,21 +1588,28 @@ async def test(): self.assertEqual(messages, []) self.assertTrue(fut1.done()) self.assertTrue(fut2.done()) + self.assertTrue(cancelled.done()) def test_stream_shutdown_hung_task_prevents_cancellation(self): fut1 = self.loop.create_future() fut2 = self.loop.create_future() + cancelled = self.loop.create_future() do_handle_client = True async def handle_client(stream): + data = await stream.readexactly(4) + self.assertEqual(b'data', data) + fut1.set_result(None) + await fut2 while do_handle_client: with contextlib.suppress(asyncio.CancelledError): await asyncio.sleep(0.01) + cancelled.set_result(None) async def client(srv): addr = srv.sockets[0].getsockname() stream = await asyncio.connect(*addr) - fut1.set_result(None) + await stream.write(b'data') await fut2 self.assertEqual(b'', await stream.readline()) await stream.close() @@ -1598,11 +1622,12 @@ async def test(): await server.start_serving() task = asyncio.create_task(client(server)) await fut1 + fut2.set_result(None) await server.close() nonlocal do_handle_client do_handle_client = False - fut2.set_result(None) await task + await cancelled messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) @@ -1612,6 +1637,7 @@ async def test(): " Date: Tue, 4 Jun 2019 16:44:44 +0300 Subject: [PATCH 311/441] bpo-37142: Make asyncio stream tests more robust again (GH-13804) Make test_stream_server_close() implementation following test_stream_server_abort(). Add explicit timeout for tests that can hang. --- Lib/test/test_asyncio/test_streams.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index e484746432af50..74e385524dd54b 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -1475,10 +1475,14 @@ async def test(): def test_stream_server_close(self): server_stream_aborted = False - fut = self.loop.create_future() + fut1 = self.loop.create_future() + fut2 = self.loop.create_future() async def handle_client(stream): - await fut + data = await stream.readexactly(4) + self.assertEqual(b'data', data) + fut1.set_result(None) + await fut2 self.assertEqual(b'', await stream.readline()) nonlocal server_stream_aborted server_stream_aborted = True @@ -1486,7 +1490,8 @@ async def handle_client(stream): async def client(srv): addr = srv.sockets[0].getsockname() stream = await asyncio.connect(*addr) - fut.set_result(None) + await stream.write(b'data') + await fut2 self.assertEqual(b'', await stream.readline()) await stream.close() @@ -1494,15 +1499,17 @@ async def test(): async with asyncio.StreamServer(handle_client, '127.0.0.1', 0) as server: await server.start_serving() task = asyncio.create_task(client(server)) - await fut + await fut1 + fut2.set_result(None) await server.close() await task messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) - self.loop.run_until_complete(test()) + self.loop.run_until_complete(asyncio.wait_for(test(), 60.0)) self.assertEqual(messages, []) - self.assertTrue(fut.done()) + self.assertTrue(fut1.done()) + self.assertTrue(fut2.done()) self.assertTrue(server_stream_aborted) def test_stream_server_abort(self): @@ -1538,7 +1545,7 @@ async def test(): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) - self.loop.run_until_complete(test()) + self.loop.run_until_complete(asyncio.wait_for(test(), 60.0)) self.assertEqual(messages, []) self.assertTrue(fut1.done()) self.assertTrue(fut2.done()) @@ -1584,7 +1591,7 @@ async def test(): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) - self.loop.run_until_complete(test()) + self.loop.run_until_complete(asyncio.wait_for(test(), 60.0)) self.assertEqual(messages, []) self.assertTrue(fut1.done()) self.assertTrue(fut2.done()) @@ -1631,7 +1638,7 @@ async def test(): messages = [] self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) - self.loop.run_until_complete(test()) + self.loop.run_until_complete(asyncio.wait_for(test(), 60.0)) self.assertEqual(1, len(messages)) self.assertRegex(messages[0]['message'], " Date: Tue, 4 Jun 2019 17:08:24 +0200 Subject: [PATCH 312/441] bpo-26219: Fix compiler warning in _PyCode_InitOpcache() (GH-13809) Fix this MSVC warning: objects\codeobject.c(264): warning C4244: '=': conversion from 'Py_ssize_t' to 'unsigned char', possible loss of data --- Objects/codeobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 0d9e5d16e76815..63ce4793597a13 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -261,7 +261,8 @@ _PyCode_InitOpcache(PyCodeObject *co) // TODO: LOAD_METHOD, LOAD_ATTR if (opcode == LOAD_GLOBAL) { - co->co_opcache_map[i] = ++opts; + opts++; + co->co_opcache_map[i] = (unsigned char)opts; if (opts > 254) { break; } From ca612a9728b83472d9d286bbea74972d426ed344 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Jun 2019 17:09:10 +0200 Subject: [PATCH 313/441] bpo-36778: Remove outdated comment from CodePageTest (GH-13807) CP65001Test has been removed. --- Lib/test/test_codecs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 47df88cedaafa7..d98f178384abf1 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -2870,7 +2870,6 @@ def decode_to_bytes(*args, **kwds): @unittest.skipUnless(sys.platform == 'win32', 'code pages are specific to Windows') class CodePageTest(unittest.TestCase): - # CP_UTF8 is already tested by CP65001Test CP_UTF8 = 65001 def test_invalid_code_page(self): From f0b5ae4567637b24035ecda93a3240efc96b6dd9 Mon Sep 17 00:00:00 2001 From: Mario Corchero Date: Tue, 4 Jun 2019 16:18:11 +0100 Subject: [PATCH 314/441] bpo-30699: Improve example on datetime tzinfo instances (GH-4290) * Improve example on tzinfo instances Move from GMTX to TZX when naming the classes, as GMT1 might be rather confusing as seen in the reported issue. In addition, move to UTC over GMT and improve the tzname implementation. * Simplify datetime with tzinfo example Move the example in the documentation to just use timezone.utc and a user defined Kabul timezone rather than having two user defined timezones with DST. Kabul timezone is still interesting as it changes its offset but not based on DST. This is more accurate as the previous example was missing information about the fold attribute. Additionally, implementing the fold attribute was rather complex and probably not relevant enough for the section "datetime with tzinfo". --- Doc/library/datetime.rst | 111 +++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 51 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 3c45e56b5f4fef..fb41aeeb5bed03 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -1365,56 +1365,64 @@ Examples of working with datetime objects: Using datetime with tzinfo: - >>> from datetime import timedelta, datetime, tzinfo - >>> class GMT1(tzinfo): + >>> from datetime import timedelta, datetime, tzinfo, timezone + >>> class KabulTz(tzinfo): + ... # Kabul used +4 until 1945, when they moved to +4:30 + ... UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc) ... def utcoffset(self, dt): - ... return timedelta(hours=1) + self.dst(dt) - ... def dst(self, dt): - ... # DST starts last Sunday in March - ... d = datetime(dt.year, 4, 1) # ends last Sunday in October - ... self.dston = d - timedelta(days=d.weekday() + 1) - ... d = datetime(dt.year, 11, 1) - ... self.dstoff = d - timedelta(days=d.weekday() + 1) - ... if self.dston <= dt.replace(tzinfo=None) < self.dstoff: - ... return timedelta(hours=1) + ... if dt.year < 1945: + ... return timedelta(hours=4) + ... elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30): + ... # If dt falls in the imaginary range, use fold to decide how + ... # to resolve. See PEP495 + ... return timedelta(hours=4, minutes=(30 if dt.fold else 0)) ... else: - ... return timedelta(0) - ... def tzname(self,dt): - ... return "GMT +1" + ... return timedelta(hours=4, minutes=30) + ... + ... def fromutc(self, dt): + ... # A custom implementation is required for fromutc as + ... # the input to this function is a datetime with utc values + ... # but with a tzinfo set to self + ... # See datetime.astimezone or fromtimestamp + ... + ... # Follow same validations as in datetime.tzinfo + ... if not isinstance(dt, datetime): + ... raise TypeError("fromutc() requires a datetime argument") + ... if dt.tzinfo is not self: + ... raise ValueError("dt.tzinfo is not self") + ... + ... if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE: + ... return dt + timedelta(hours=4, minutes=30) + ... else: + ... return dt + timedelta(hours=4) ... - >>> class GMT2(tzinfo): - ... def utcoffset(self, dt): - ... return timedelta(hours=2) + self.dst(dt) ... def dst(self, dt): - ... d = datetime(dt.year, 4, 1) - ... self.dston = d - timedelta(days=d.weekday() + 1) - ... d = datetime(dt.year, 11, 1) - ... self.dstoff = d - timedelta(days=d.weekday() + 1) - ... if self.dston <= dt.replace(tzinfo=None) < self.dstoff: - ... return timedelta(hours=1) + ... return timedelta(0) + ... + ... def tzname(self, dt): + ... if dt >= self.UTC_MOVE_DATE: + ... return "+04:30" ... else: - ... return timedelta(0) - ... def tzname(self,dt): - ... return "GMT +2" + ... return "+04" ... - >>> gmt1 = GMT1() - >>> # Daylight Saving Time - >>> dt1 = datetime(2006, 11, 21, 16, 30, tzinfo=gmt1) - >>> dt1.dst() - datetime.timedelta(0) - >>> dt1.utcoffset() - datetime.timedelta(seconds=3600) - >>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=gmt1) - >>> dt2.dst() - datetime.timedelta(seconds=3600) - >>> dt2.utcoffset() - datetime.timedelta(seconds=7200) + ... def __repr__(self): + ... return f"{self.__class__.__name__}()" + ... + >>> tz1 = KabulTz() + >>> # Datetime before the change + >>> dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1) + >>> print(dt1.utcoffset()) + 4:00:00 + >>> # Datetime after the change + >>> dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1) + >>> print(dt2.utcoffset()) + 4:30:00 >>> # Convert datetime to another time zone - >>> dt3 = dt2.astimezone(GMT2()) - >>> dt3 # doctest: +ELLIPSIS - datetime.datetime(2006, 6, 14, 14, 0, tzinfo=) - >>> dt2 # doctest: +ELLIPSIS - datetime.datetime(2006, 6, 14, 13, 0, tzinfo=) + >>> dt3 = dt2.astimezone(timezone.utc) + >>> dt3 + datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc) + >>> dt2 + datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz()) >>> dt2.utctimetuple() == dt3.utctimetuple() True @@ -1656,26 +1664,27 @@ Instance methods: Example: >>> from datetime import time, tzinfo, timedelta - >>> class GMT1(tzinfo): + >>> class TZ1(tzinfo): ... def utcoffset(self, dt): ... return timedelta(hours=1) ... def dst(self, dt): ... return timedelta(0) ... def tzname(self,dt): - ... return "Europe/Prague" + ... return "+01:00" + ... def __repr__(self): + ... return f"{self.__class__.__name__}()" ... - >>> t = time(12, 10, 30, tzinfo=GMT1()) - >>> t # doctest: +ELLIPSIS - datetime.time(12, 10, 30, tzinfo=) - >>> gmt = GMT1() + >>> t = time(12, 10, 30, tzinfo=TZ1()) + >>> t + datetime.time(12, 10, 30, tzinfo=TZ1()) >>> t.isoformat() '12:10:30+01:00' >>> t.dst() datetime.timedelta(0) >>> t.tzname() - 'Europe/Prague' + '+01:00' >>> t.strftime("%H:%M:%S %Z") - '12:10:30 Europe/Prague' + '12:10:30 +01:00' >>> 'The {} is {:%H:%M}.'.format("time", t) 'The time is 12:10.' From 800d78637034d77c099d49c4fe99e1fe773da700 Mon Sep 17 00:00:00 2001 From: Boris Feld Date: Tue, 4 Jun 2019 17:20:18 +0200 Subject: [PATCH 315/441] Fix extraneous whitespace in QueueListener.prepare (GH-13803) --- Lib/logging/handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index a913d27389ab59..34ff7a056ef547 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1437,7 +1437,7 @@ def start(self): t.daemon = True t.start() - def prepare(self , record): + def prepare(self, record): """ Prepare a record for handling. From 8d0ef0b5edeae52960c7ed05ae8a12388324f87e Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Tue, 4 Jun 2019 08:55:30 -0700 Subject: [PATCH 316/441] bpo-36742: Corrects fix to handle decomposition in usernames (#13812) --- Lib/test/test_urlparse.py | 11 ++++++----- Lib/urllib/parse.py | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 43447656376472..4ae6ed33858ce2 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1018,11 +1018,12 @@ def test_urlsplit_normalization(self): urllib.parse.urlsplit('http://\u30d5\u309a\ufe1380') for scheme in ["http", "https", "ftp"]: - for c in denorm_chars: - url = "{}://netloc{}false.netloc/path".format(scheme, c) - with self.subTest(url=url, char='{:04X}'.format(ord(c))): - with self.assertRaises(ValueError): - urllib.parse.urlsplit(url) + for netloc in ["netloc{}false.netloc", "n{}user@netloc"]: + for c in denorm_chars: + url = "{}://{}/path".format(scheme, netloc.format(c)) + with self.subTest(url=url, char='{:04X}'.format(ord(c))): + with self.assertRaises(ValueError): + urllib.parse.urlsplit(url) class Utility_Tests(unittest.TestCase): """Testcase to test the various utility functions in the urllib.""" diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index daefb2025b14ea..b6608783a89471 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -402,9 +402,9 @@ def _checknetloc(netloc): # looking for characters like \u2100 that expand to 'a/c' # IDNA uses NFKC equivalence, so normalize for this check import unicodedata - n = netloc.rpartition('@')[2] # ignore anything to the left of '@' - n = n.replace(':', '') # ignore characters already included - n = n.replace('#', '') # but not the surrounding text + n = netloc.replace('@', '') # ignore characters already included + n = n.replace(':', '') # but not the surrounding text + n = n.replace('#', '') n = n.replace('?', '') netloc2 = unicodedata.normalize('NFKC', n) if n == netloc2: From bc6469f79ca13217b784fb47da7ec83484a3debe Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Jun 2019 19:03:13 +0200 Subject: [PATCH 317/441] bpo-37153: test_venv.test_mutiprocessing() calls pool.terminate() (GH-13816) test_venv.test_mutiprocessing() now explicitly calls pool.terminate() to wait until the pool completes. --- Lib/test/test_venv.py | 6 ++++-- .../next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 278c68699d8e60..24d3a69b1878b5 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -325,8 +325,10 @@ def test_multiprocessing(self): envpy = os.path.join(os.path.realpath(self.env_dir), self.bindir, self.exe) out, err = check_output([envpy, '-c', - 'from multiprocessing import Pool; ' + - 'print(Pool(1).apply_async("Python".lower).get(3))']) + 'from multiprocessing import Pool; ' + 'pool = Pool(1); ' + 'print(pool.apply_async("Python".lower).get(3)); ' + 'pool.terminate()']) self.assertEqual(out.strip(), "python".encode()) @requireVenvCreate diff --git a/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst b/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst new file mode 100644 index 00000000000000..138a22f6acc249 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-06-04-18-30-39.bpo-37153.711INB.rst @@ -0,0 +1,2 @@ +``test_venv.test_mutiprocessing()`` now explicitly calls +``pool.terminate()`` to wait until the pool completes. From 46d88a113142b26c01c95c93846a89318ba87ffc Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Tue, 4 Jun 2019 13:41:34 -0400 Subject: [PATCH 318/441] bpo-35805: Add parser for Message-ID email header. (GH-13397) * bpo-35805: Add parser for Message-ID header. This parser is based on the definition of Identification Fields from RFC 5322 Sec 3.6.4. This should also prevent folding of Message-ID header using RFC 2047 encoded words and hence fix bpo-35805. * Prevent folding of non-ascii message-id headers. * Add fold method to MsgID token to prevent folding. --- Doc/library/email.headerregistry.rst | 33 +++-- Lib/email/_header_value_parser.py | 137 ++++++++++++++++-- Lib/email/headerregistry.py | 13 ++ .../test_email/test__header_value_parser.py | 72 +++++++++ Lib/test/test_email/test_headerregistry.py | 28 ++++ .../2019-05-17-15-11-08.bpo-35805.E4YwYz.rst | 2 + 6 files changed, 257 insertions(+), 28 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst diff --git a/Doc/library/email.headerregistry.rst b/Doc/library/email.headerregistry.rst index c3ce90c2d6d952..9376da2b8d39ce 100644 --- a/Doc/library/email.headerregistry.rst +++ b/Doc/library/email.headerregistry.rst @@ -321,19 +321,26 @@ variant, :attr:`~.BaseHeader.max_count` is set to 1. The default mappings are: - :subject: UniqueUnstructuredHeader - :date: UniqueDateHeader - :resent-date: DateHeader - :orig-date: UniqueDateHeader - :sender: UniqueSingleAddressHeader - :resent-sender: SingleAddressHeader - :to: UniqueAddressHeader - :resent-to: AddressHeader - :cc: UniqueAddressHeader - :resent-cc: AddressHeader - :from: UniqueAddressHeader - :resent-from: AddressHeader - :reply-to: UniqueAddressHeader + :subject: UniqueUnstructuredHeader + :date: UniqueDateHeader + :resent-date: DateHeader + :orig-date: UniqueDateHeader + :sender: UniqueSingleAddressHeader + :resent-sender: SingleAddressHeader + :to: UniqueAddressHeader + :resent-to: AddressHeader + :cc: UniqueAddressHeader + :resent-cc: AddressHeader + :bcc: UniqueAddressHeader + :resent-bcc: AddressHeader + :from: UniqueAddressHeader + :resent-from: AddressHeader + :reply-to: UniqueAddressHeader + :mime-version: MIMEVersionHeader + :content-type: ContentTypeHeader + :content-disposition: ContentDispositionHeader + :content-transfer-encoding: ContentTransferEncodingHeader + :message-id: MessageIDHeader ``HeaderRegistry`` has the following methods: diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 14cc00c61e0771..34969ab5915119 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -179,37 +179,30 @@ def comments(self): class UnstructuredTokenList(TokenList): - token_type = 'unstructured' class Phrase(TokenList): - token_type = 'phrase' class Word(TokenList): - token_type = 'word' class CFWSList(WhiteSpaceTokenList): - token_type = 'cfws' class Atom(TokenList): - token_type = 'atom' class Token(TokenList): - token_type = 'token' encode_as_ew = False class EncodedWord(TokenList): - token_type = 'encoded-word' cte = None charset = None @@ -496,16 +489,19 @@ def domain(self): class DotAtom(TokenList): - token_type = 'dot-atom' class DotAtomText(TokenList): - token_type = 'dot-atom-text' as_ew_allowed = True +class NoFoldLiteral(TokenList): + token_type = 'no-fold-literal' + as_ew_allowed = False + + class AddrSpec(TokenList): token_type = 'addr-spec' @@ -809,7 +805,6 @@ def params(self): class ContentType(ParameterizedHeaderValue): - token_type = 'content-type' as_ew_allowed = False maintype = 'text' @@ -817,27 +812,35 @@ class ContentType(ParameterizedHeaderValue): class ContentDisposition(ParameterizedHeaderValue): - token_type = 'content-disposition' as_ew_allowed = False content_disposition = None class ContentTransferEncoding(TokenList): - token_type = 'content-transfer-encoding' as_ew_allowed = False cte = '7bit' class HeaderLabel(TokenList): - token_type = 'header-label' as_ew_allowed = False -class Header(TokenList): +class MsgID(TokenList): + token_type = 'msg-id' + as_ew_allowed = False + + def fold(self, policy): + # message-id tokens may not be folded. + return str(self) + policy.linesep + +class MessageID(MsgID): + token_type = 'message-id' + +class Header(TokenList): token_type = 'header' @@ -1583,7 +1586,7 @@ def get_addr_spec(value): addr_spec.append(token) if not value or value[0] != '@': addr_spec.defects.append(errors.InvalidHeaderDefect( - "add-spec local part with no domain")) + "addr-spec local part with no domain")) return addr_spec, value addr_spec.append(ValueTerminal('@', 'address-at-symbol')) token, value = get_domain(value[1:]) @@ -1968,6 +1971,110 @@ def get_address_list(value): value = value[1:] return address_list, value + +def get_no_fold_literal(value): + """ no-fold-literal = "[" *dtext "]" + """ + no_fold_literal = NoFoldLiteral() + if not value: + raise errors.HeaderParseError( + "expected no-fold-literal but found '{}'".format(value)) + if value[0] != '[': + raise errors.HeaderParseError( + "expected '[' at the start of no-fold-literal " + "but found '{}'".format(value)) + no_fold_literal.append(ValueTerminal('[', 'no-fold-literal-start')) + value = value[1:] + token, value = get_dtext(value) + no_fold_literal.append(token) + if not value or value[0] != ']': + raise errors.HeaderParseError( + "expected ']' at the end of no-fold-literal " + "but found '{}'".format(value)) + no_fold_literal.append(ValueTerminal(']', 'no-fold-literal-end')) + return no_fold_literal, value[1:] + +def get_msg_id(value): + """msg-id = [CFWS] "<" id-left '@' id-right ">" [CFWS] + id-left = dot-atom-text / obs-id-left + id-right = dot-atom-text / no-fold-literal / obs-id-right + no-fold-literal = "[" *dtext "]" + """ + msg_id = MsgID() + if value[0] in CFWS_LEADER: + token, value = get_cfws(value) + msg_id.append(token) + if not value or value[0] != '<': + raise errors.HeaderParseError( + "expected msg-id but found '{}'".format(value)) + msg_id.append(ValueTerminal('<', 'msg-id-start')) + value = value[1:] + # Parse id-left. + try: + token, value = get_dot_atom_text(value) + except errors.HeaderParseError: + try: + # obs-id-left is same as local-part of add-spec. + token, value = get_obs_local_part(value) + msg_id.defects.append(errors.ObsoleteHeaderDefect( + "obsolete id-left in msg-id")) + except errors.HeaderParseError: + raise errors.HeaderParseError( + "expected dot-atom-text or obs-id-left" + " but found '{}'".format(value)) + msg_id.append(token) + if not value or value[0] != '@': + msg_id.defects.append(errors.InvalidHeaderDefect( + "msg-id with no id-right")) + # Even though there is no id-right, if the local part + # ends with `>` let's just parse it too and return + # along with the defect. + if value and value[0] == '>': + msg_id.append(ValueTerminal('>', 'msg-id-end')) + value = value[1:] + return msg_id, value + msg_id.append(ValueTerminal('@', 'address-at-symbol')) + value = value[1:] + # Parse id-right. + try: + token, value = get_dot_atom_text(value) + except errors.HeaderParseError: + try: + token, value = get_no_fold_literal(value) + except errors.HeaderParseError as e: + try: + token, value = get_domain(value) + msg_id.defects.append(errors.ObsoleteHeaderDefect( + "obsolete id-right in msg-id")) + except errors.HeaderParseError: + raise errors.HeaderParseError( + "expected dot-atom-text, no-fold-literal or obs-id-right" + " but found '{}'".format(value)) + msg_id.append(token) + if value and value[0] == '>': + value = value[1:] + else: + msg_id.defects.append(errors.InvalidHeaderDefect( + "missing trailing '>' on msg-id")) + msg_id.append(ValueTerminal('>', 'msg-id-end')) + if value and value[0] in CFWS_LEADER: + token, value = get_cfws(value) + msg_id.append(token) + return msg_id, value + + +def parse_message_id(value): + """message-id = "Message-ID:" msg-id CRLF + """ + message_id = MessageID() + try: + token, value = get_msg_id(value) + except errors.HeaderParseError: + message_id.defects.append(errors.InvalidHeaderDefect( + "Expected msg-id but found {!r}".format(value))) + message_id.append(token) + return message_id + # # XXX: As I begin to add additional header parsers, I'm realizing we probably # have two level of parser routines: the get_XXX methods that get a token in diff --git a/Lib/email/headerregistry.py b/Lib/email/headerregistry.py index 00652049f2fa2f..452c6ad5084692 100644 --- a/Lib/email/headerregistry.py +++ b/Lib/email/headerregistry.py @@ -520,6 +520,18 @@ def cte(self): return self._cte +class MessageIDHeader: + + max_count = 1 + value_parser = staticmethod(parser.parse_message_id) + + @classmethod + def parse(cls, value, kwds): + kwds['parse_tree'] = parse_tree = cls.value_parser(value) + kwds['decoded'] = str(parse_tree) + kwds['defects'].extend(parse_tree.all_defects) + + # The header factory # _default_header_map = { @@ -542,6 +554,7 @@ def cte(self): 'content-type': ContentTypeHeader, 'content-disposition': ContentDispositionHeader, 'content-transfer-encoding': ContentTransferEncodingHeader, + 'message-id': MessageIDHeader, } class HeaderRegistry: diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 676732bb3d0261..12da3cffb84c88 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -2494,6 +2494,78 @@ def test_invalid_content_transfer_encoding(self): ";foo", ";foo", ";foo", [errors.InvalidHeaderDefect]*3 ) + # get_msg_id + + def test_get_msg_id_valid(self): + msg_id = self._test_get_x( + parser.get_msg_id, + "", + "", + "", + [], + '', + ) + self.assertEqual(msg_id.token_type, 'msg-id') + + def test_get_msg_id_obsolete_local(self): + msg_id = self._test_get_x( + parser.get_msg_id, + '<"simeple.local"@example.com>', + '<"simeple.local"@example.com>', + '', + [errors.ObsoleteHeaderDefect], + '', + ) + self.assertEqual(msg_id.token_type, 'msg-id') + + def test_get_msg_id_non_folding_literal_domain(self): + msg_id = self._test_get_x( + parser.get_msg_id, + "", + "", + "", + [], + "", + ) + self.assertEqual(msg_id.token_type, 'msg-id') + + + def test_get_msg_id_obsolete_domain_part(self): + msg_id = self._test_get_x( + parser.get_msg_id, + "", + "", + "", + [errors.ObsoleteHeaderDefect], + "" + ) + + def test_get_msg_id_no_id_right_part(self): + msg_id = self._test_get_x( + parser.get_msg_id, + "", + "", + "", + [errors.InvalidHeaderDefect], + "" + ) + self.assertEqual(msg_id.token_type, 'msg-id') + + def test_get_msg_id_no_angle_start(self): + with self.assertRaises(errors.HeaderParseError): + parser.get_msg_id("msgwithnoankle") + + def test_get_msg_id_no_angle_end(self): + msg_id = self._test_get_x( + parser.get_msg_id, + "", + "", + [errors.InvalidHeaderDefect], + "" + ) + self.assertEqual(msg_id.token_type, 'msg-id') + @parameterize class Test_parse_mime_parameters(TestParserMixin, TestEmailBase): diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index d1007099f666c9..75505460aba89e 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -1648,6 +1648,34 @@ def test_fold_overlong_words_using_RFC2047(self): 'xxxxxxxxxxxxxxxxxxxx=3D=3D-xxx-xx-xx?=\n' ' =?utf-8?q?=3E?=\n') + def test_message_id_header_is_not_folded(self): + h = self.make_header( + 'Message-ID', + '') + self.assertEqual( + h.fold(policy=policy.default.clone(max_line_length=20)), + 'Message-ID: \n') + + # Test message-id isn't folded when id-right is no-fold-literal. + h = self.make_header( + 'Message-ID', + '') + self.assertEqual( + h.fold(policy=policy.default.clone(max_line_length=20)), + 'Message-ID: \n') + + # Test message-id isn't folded when id-right is non-ascii characters. + h = self.make_header('Message-ID', '<ईमेल@wők.com>') + self.assertEqual( + h.fold(policy=policy.default.clone(max_line_length=30)), + 'Message-ID: <ईमेल@wők.com>\n') + + # Test message-id is folded without breaking the msg-id token into + # encoded words, *even* if they don't fit into max_line_length. + h = self.make_header('Message-ID', '<ईमेलfromMessage@wők.com>') + self.assertEqual( + h.fold(policy=policy.default.clone(max_line_length=20)), + 'Message-ID:\n <ईमेलfromMessage@wők.com>\n') if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst b/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst new file mode 100644 index 00000000000000..2d8c8b3222d099 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-17-15-11-08.bpo-35805.E4YwYz.rst @@ -0,0 +1,2 @@ +Add parser for Message-ID header and add it to default HeaderRegistry. This +should prevent folding of Message-ID using RFC 2048 encoded words. From 3b5deb0116abf2c94690d48af41b109bc8a4d559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 4 Jun 2019 19:44:34 +0200 Subject: [PATCH 319/441] Python 3.8.0b1 --- Doc/tools/extensions/pyspecific.py | 2 +- Include/patchlevel.h | 6 +- Lib/pydoc_data/topics.py | 154 +- Misc/NEWS.d/3.8.0b1.rst | 2052 +++++++++++++++++ .../2019-05-03-21-08-06.bpo-36786.gOLFbD.rst | 1 - .../2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst | 16 - .../2019-05-11-03-56-23.bpo-36728.FR-dMP.rst | 2 - .../2019-05-15-10-46-55.bpo-36922.J3EFK_.rst | 3 - .../2019-05-17-19-23-24.bpo-36763.TswmDy.rst | 3 - .../2019-05-22-15-24-08.bpo-36974.TkySRe.rst | 2 - .../2019-05-22-17-33-52.bpo-37107.8BVPR-.rst | 4 - .../2019-05-24-07-11-08.bpo-36379.8zgoKe.rst | 2 - .../2019-05-27-12-25-25.bpo-36763.bHCA9j.rst | 1 - .../2017-10-24-17-26-58.bpo-31862.5Gea8L.rst | 2 - .../2017-12-21-20-37-40.bpo-32388.6w-i5t.rst | 1 - .../2018-05-30-23-43-03.bpo-26826.NkRzjb.rst | 1 - .../2018-07-04-16-57-59.bpo-20602.sDLElw.rst | 2 - .../2019-02-13-16-47-19.bpo-35983.bNxsXv.rst | 3 - .../2019-02-22-14-30-19.bpo-36035.-6dy1y.rst | 1 - .../2019-02-22-23-03-20.bpo-36084.86Eh4X.rst | 1 - .../2019-02-24-12-44-46.bpo-36045.RO20OV.rst | 1 - .../2019-04-10-18-12-11.bpo-36594.fbnJAc.rst | 2 - .../2019-04-13-16-14-16.bpo-36601.mIgS7t.rst | 2 - .../2019-04-16-11-52-21.bpo-27987.n2_DcQ.rst | 3 - .../2019-04-29-03-27-22.bpo-24048.vXxUDQ.rst | 1 - .../2019-05-02-11-48-08.bpo-36774.ZqbJ1J.rst | 7 - .../2019-05-04-16-15-33.bpo-36793.Izog4Z.rst | 3 - .../2019-05-07-12-18-11.bpo-36737.XAo6LY.rst | 2 - .../2019-05-07-15-49-17.bpo-27639.b1Ah87.rst | 2 - .../2019-05-07-16-50-12.bpo-36842.NYww_N.rst | 1 - .../2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst | 1 - .../2019-05-08-11-42-06.bpo-36851.J7DiCW.rst | 2 - .../2019-05-08-16-36-51.bpo-28866.qCv_bj.rst | 2 - .../2019-05-08-20-42-40.bpo-36861.72mvZM.rst | 1 - .../2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst | 3 - .../2019-05-15-01-29-29.bpo-1875.9oxXFX.rst | 3 - .../2019-05-15-14-01-09.bpo-36826.GLrO3W.rst | 1 - .../2019-05-16-23-53-45.bpo-36946.qjxr0Y.rst | 1 - .../2019-05-17-12-28-24.bpo-36907.rk7kgp.rst | 2 - .../2019-05-17-18-34-30.bpo-2180.aBqHeW.rst | 1 - .../2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst | 3 - .../2019-05-22-11-16-16.bpo-36878.QwLa3P.rst | 2 - .../2019-05-22-23-01-29.bpo-36829.MfOcUg.rst | 4 - .../2019-05-23-04-19-13.bpo-37007.d1SOtF.rst | 2 - .../2019-05-24-12-38-40.bpo-37032.T8rSH8.rst | 1 - .../2019-05-25-08-18-01.bpo-26836.rplYWW.rst | 1 - .../2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst | 4 - .../2019-05-27-14-46-24.bpo-37050.7MyZGg.rst | 4 - .../2019-05-27-18-00-19.bpo-26423.RgUOE8.rst | 2 - .../2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst | 1 - .../2019-05-28-18-18-55.bpo-37072.1Hewl3.rst | 1 - .../2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst | 3 - .../2019-05-30-17-33-55.bpo-37087.vElenE.rst | 1 - .../2019-05-31-11-55-49.bpo-20092.KIMjBW.rst | 4 - .../2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst | 5 - .../2019-06-01-20-03-13.bpo-37126.tP6lL4.rst | 2 - .../2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst | 2 - .../2017-12-08-20-30-37.bpo-20285.cfnp0J.rst | 3 - .../2018-04-08-19-09-22.bpo-25735.idVQBD.rst | 1 - .../2018-05-13-10-36-37.bpo-33482.jalAaQ.rst | 1 - .../2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst | 1 - .../2018-10-07-03-04-57.bpo-32995.TXN9ur.rst | 1 - .../2019-01-09-17-56-35.bpo-35397.ZMreIz.rst | 2 - .../2019-02-21-18-13-50.bpo-22865.6hg6J8.rst | 1 - .../2019-05-05-07-58-50.bpo-36797.W1X4On.rst | 3 - .../2019-05-07-02-30-51.bpo-36783.gpC8E2.rst | 2 - .../2019-05-08-13-17-44.bpo-35924.lqbNpW.rst | 2 - .../2019-05-11-17-42-15.bpo-36868.yioL0R.rst | 2 - .../2019-05-20-22-21-17.bpo-36984.IjZlmS.rst | 1 - .../2019-05-27-17-28-58.bpo-36686.Zot4sx.rst | 6 - .../2019-05-31-10-46-36.bpo-36896.wkXTW9.rst | 2 - .../2017-12-25-18-48-50.bpo-32411.vNwDhe.rst | 2 - .../2019-05-05-16-27-53.bpo-13102.AGNWYJ.rst | 1 - .../2019-05-19-22-02-22.bpo-36958.DZUC6G.rst | 2 - .../2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst | 1 - .../2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst | 2 - .../2016-07-27-11-06-43.bpo-23395.MuCEX9.rst | 2 - .../2017-10-21-12-07-56.bpo-31829.6IhP-O.rst | 3 - .../2017-10-24-00-42-14.bpo-27141.zbAgSs.rst | 3 - .../2017-12-13-17-49-56.bpo-32299.eqAPWs.rst | 2 - .../2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst | 1 - .../2018-03-08-16-15-00.bpo-22102.th33uD.rst | 2 - .../2018-03-20-20-57-00.bpo-32941.9FU0gL.rst | 2 - .../2018-03-22-19-13-19.bpo-33123._Y5ooE.rst | 2 - .../2018-03-27-13-28-16.bpo-31961.GjLoYu.rst | 6 - .../2018-04-04-14-54-30.bpo-24882.urybpa.rst | 1 - .../2018-05-30-01-05-50.bpo-31922.fobsXJ.rst | 3 - .../2018-06-10-17-48-07.bpo-22454.qeiy_X.rst | 2 - .../2018-07-13-20-17-17.bpo-33361.dx2NVn.rst | 2 - .../2018-08-03-09-47-20.bpo-34303.tOE2HP.rst | 2 - .../2018-08-18-14-47-00.bpo-34424.wAlRuS.rst | 2 - .../2018-08-28-03-00-12.bpo-33569.45YlGG.rst | 1 - .../2018-09-13-20-33-24.bpo-26467.cahAk3.rst | 2 - .../2018-10-21-17-39-32.bpo-34271.P15VLM.rst | 3 - .../2018-11-04-16-39-46.bpo-26660.RdXz8a.rst | 4 - .../2019-01-02-19-48-23.bpo-35431.FhG6QA.rst | 4 - .../2019-01-11-17-09-15.bpo-31855.PlhfsX.rst | 2 - .../2019-01-18-16-23-00.bpo-35721.d8djAJ.rst | 3 - .../2019-02-15-17-18-50.bpo-35125.h0xk0f.rst | 1 - .../2019-03-01-17-59-39.bpo-31904.38djdk.rst | 1 - .../2019-03-04-01-28-33.bpo-26707.QY4kRZ.rst | 1 - .../2019-03-09-23-51-27.bpo-36239.BHJ3Ln.rst | 1 - .../2019-03-13-10-57-41.bpo-27497.JDmIe_.rst | 3 - .../2019-03-18-14-25-36.bpo-31904.ds3d67.rst | 1 - .../2019-03-21-16-00-00.bpo-36368.zsRT1.rst | 2 - .../2019-03-22-22-40-00.bpo-35900.oiee0o.rst | 2 - .../2019-03-27-15-09-00.bpo-35900.fh56UU.rst | 3 - .../2019-04-02-19-23-12.bpo-35252.VooTVv.rst | 1 - .../2019-04-06-00-55-09.bpo-36533.kzMyRH.rst | 6 - .../2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst | 2 - .../2019-04-07-14-30-10.bpo-36548.CJQiYw.rst | 1 - .../2019-04-22-22-55-29.bpo-29183.MILvsk.rst | 3 - .../2019-04-26-22-13-26.bpo-22640.p3rheW.rst | 2 - .../2019-04-27-02-54-23.bpo-8138.osBRGI.rst | 2 - .../2019-04-29-15-18-13.bpo-36748.YBKWps.rst | 3 - .../2019-04-30-04-34-53.bpo-6584.Hzp9-P.rst | 1 - .../2019-05-01-20-41-53.bpo-36772.fV2K0F.rst | 2 - .../2019-05-03-20-47-55.bpo-36785.PQLnPq.rst | 1 - .../2019-05-05-09-45-44.bpo-36801.XrlFFs.rst | 1 - .../2019-05-05-10-12-23.bpo-36802.HYMc8P.rst | 2 - .../2019-05-05-16-14-38.bpo-36806.rAzF-x.rst | 2 - .../2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst | 2 - .../2019-05-06-19-17-04.bpo-26903.4payXb.rst | 1 - .../2019-05-06-22-34-47.bpo-33110.rSJSCh.rst | 1 - .../2019-05-06-23-13-26.bpo-36814.dSeMz_.rst | 1 - .../2019-05-07-15-00-45.bpo-36832.TExgqb.rst | 1 - .../2019-05-08-12-51-37.bpo-36829.8enFMA.rst | 5 - .../2019-05-09-08-35-18.bpo-24538.WK8Y-k.rst | 3 - .../2019-05-09-12-38-40.bpo-30262.Tu74ak.rst | 2 - .../2019-05-09-18-12-55.bpo-36867.FuwVTi.rst | 1 - .../2019-05-10-01-06-36.bpo-36778.GRqeiS.rst | 2 - .../2019-05-10-22-00-06.bpo-36878.iigeqk.rst | 4 - .../2019-05-11-02-30-45.bpo-34632.8MXa7T.rst | 1 - .../2019-05-11-14-50-59.bpo-36887.XD3f22.rst | 1 - .../2019-05-11-16-21-29.bpo-35545.FcvJvP.rst | 2 - .../2019-05-12-14-49-13.bpo-36895.ZZuuY7.rst | 2 - .../2019-05-13-05-49-15.bpo-23896.8TtUKo.rst | 2 - .../2019-05-13-13-02-43.bpo-36867.Qh-6mX.rst | 1 - .../2019-05-14-05-38-22.bpo-23378.R25teI.rst | 1 - .../2019-05-14-07-57-02.bpo-36845._GtFFf.rst | 2 - .../2019-05-14-12-25-44.bpo-36889.MChPqP.rst | 6 - .../2019-05-14-15-39-34.bpo-36916._GPsTt.rst | 2 - .../2019-05-14-21-39-52.bpo-25652.xLw42k.rst | 1 - .../2019-05-15-21-35-23.bpo-36921.kA1306.rst | 1 - .../2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst | 2 - .../2019-05-16-23-40-36.bpo-24564.lIwV_7.rst | 3 - .../2019-05-17-11-44-21.bpo-33524.8y_xUU.rst | 3 - .../2019-05-17-21-42-58.bpo-36948.vnUDvk.rst | 2 - .../2019-05-19-06-54-26.bpo-36949.jBlG9F.rst | 1 - .../2019-05-20-08-54-41.bpo-36952.I_glok.rst | 5 - .../2019-05-20-11-01-28.bpo-36952.MgZi7-.rst | 4 - .../2019-05-20-14-47-55.bpo-32972.LoeUNh.rst | 1 - .../2019-05-20-17-08-26.bpo-36972.3l3SGc.rst | 1 - .../2019-05-20-20-41-30.bpo-36983.hz-fLr.rst | 2 - .../2019-05-20-23-31-20.bpo-36969.JkZORP.rst | 2 - .../2019-05-21-12-31-21.bpo-36969.u7cxu7.rst | 2 - .../2019-05-22-02-25-31.bpo-27737.7bgKpa.rst | 2 - .../2019-05-22-15-26-08.bpo-37008.WPbv31.rst | 2 - .../2019-05-22-22-55-18.bpo-36996.XQx08d.rst | 1 - ...2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst | 3 - .../2019-05-23-17-37-22.bpo-32528.sGnkcl.rst | 8 - .../2019-05-23-18-46-56.bpo-37027.iH4eut.rst | 2 - .../2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst | 1 - .../2019-05-23-21-10-57.bpo-37001.DoLvTK.rst | 2 - .../2019-05-24-18-16-07.bpo-37035.HFbJVT.rst | 5 - .../2019-05-25-18-36-50.bpo-37045.suHdVJ.rst | 1 - .../2019-05-25-19-12-53.bpo-37046.iuhQQj.rst | 1 - .../2019-05-25-19-48-42.bpo-37049.an2LXJ.rst | 1 - .../2019-05-26-01-20-06.bpo-37047.K9epi8.rst | 3 - .../2019-05-26-10-16-55.bpo-36933.4w3eP9.rst | 2 - .../2019-05-26-19-05-24.bpo-37058.jmRu_g.rst | 1 - .../2019-05-28-01-06-44.bpo-37054.sLULGQ.rst | 3 - .../2019-05-28-01-17-42.bpo-33725.fFZoDG.rst | 2 - .../2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst | 3 - .../2019-05-28-19-14-29.bpo-35279.PX7yl9.rst | 3 - .../2019-05-28-23-17-35.bpo-35246.oXT21d.rst | 1 - .../2019-05-30-13-30-46.bpo-36999.EjY_L2.rst | 2 - .../2019-05-30-16-16-47.bpo-12639.TQFOR4.rst | 2 - .../2019-05-30-21-25-14.bpo-29262.LdIzun.rst | 1 - .../2019-05-31-11-33-11.bpo-26835.xGbUX0.rst | 1 - .../2019-05-31-15-53-34.bpo-12202.nobzc9.rst | 2 - .../2019-06-01-09-03-32.bpo-37120.FOKQLU.rst | 1 - .../2019-06-01-22-54-03.bpo-37128.oGXBWN.rst | 1 - .../2018-03-30-12-26-47.bpo-33164.aO29Cx.rst | 1 - .../2019-02-24-18-48-16.bpo-33529.wpNNBD.rst | 2 - .../2019-05-21-23-20-18.bpo-35907.NC_zNK.rst | 3 - .../2019-03-23-13-58-49.bpo-36342.q6Quiq.rst | 1 - .../2019-05-04-21-25-19.bpo-36782.h3oPIb.rst | 1 - .../2019-05-06-18-29-54.bpo-35925.gwQPuC.rst | 1 - .../2019-05-08-15-55-46.bpo-36816.WBKRGZ.rst | 1 - .../2019-05-10-01-50-30.bpo-36719.O84ZWv.rst | 3 - .../2019-05-14-14-12-24.bpo-36915.58b7pH.rst | 3 - .../2019-05-22-12-57-15.bpo-36829.e9mRWC.rst | 2 - .../2019-05-28-17-48-22.bpo-37081.qxB-1l.rst | 1 - .../2019-05-30-10-57-39.bpo-37098.SfXt1M.rst | 1 - .../2019-06-03-02-30-36.bpo-37069.rVtdLk.rst | 3 - .../2019-05-26-16-47-06.bpo-37053.-EYRuz.rst | 1 - .../2018-08-28-17-23-49.bpo-33407.ARG0W_.rst | 1 - .../2018-09-15-11-36-55.bpo-29883.HErerE.rst | 2 - .../2019-03-01-16-43-45.bpo-35926.mLszHo.rst | 1 - .../2019-05-20-20-26-36.bpo-36965.KsfI-N.rst | 1 - .../2019-06-03-05-49-49.bpo-36231.RfmW_p.rst | 3 - README.rst | 4 +- 203 files changed, 2142 insertions(+), 500 deletions(-) create mode 100644 Misc/NEWS.d/3.8.0b1.rst delete mode 100644 Misc/NEWS.d/next/Build/2019-05-03-21-08-06.bpo-36786.gOLFbD.rst delete mode 100644 Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst delete mode 100644 Misc/NEWS.d/next/C API/2019-05-11-03-56-23.bpo-36728.FR-dMP.rst delete mode 100644 Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst delete mode 100644 Misc/NEWS.d/next/C API/2019-05-17-19-23-24.bpo-36763.TswmDy.rst delete mode 100644 Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst delete mode 100644 Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst delete mode 100644 Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst delete mode 100644 Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-13-16-47-19.bpo-35983.bNxsXv.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-04-10-18-12-11.bpo-36594.fbnJAc.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-04-13-16-14-16.bpo-36601.mIgS7t.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-04-16-11-52-21.bpo-27987.n2_DcQ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-04-29-03-27-22.bpo-24048.vXxUDQ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-02-11-48-08.bpo-36774.ZqbJ1J.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-04-16-15-33.bpo-36793.Izog4Z.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-07-12-18-11.bpo-36737.XAo6LY.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-07-15-49-17.bpo-27639.b1Ah87.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-08-11-42-06.bpo-36851.J7DiCW.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-08-20-42-40.bpo-36861.72mvZM.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-15-01-29-29.bpo-1875.9oxXFX.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-16-23-53-45.bpo-36946.qjxr0Y.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2018-10-07-03-04-57.bpo-32995.TXN9ur.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-05-05-07-58-50.bpo-36797.W1X4On.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-05-07-02-30-51.bpo-36783.gpC8E2.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-05-08-13-17-44.bpo-35924.lqbNpW.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst delete mode 100644 Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2019-05-05-16-27-53.bpo-13102.AGNWYJ.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst delete mode 100644 Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst delete mode 100644 Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst delete mode 100644 Misc/NEWS.d/next/Library/2017-10-21-12-07-56.bpo-31829.6IhP-O.rst delete mode 100644 Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst delete mode 100644 Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-05-30-01-05-50.bpo-31922.fobsXJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-08-18-14-47-00.bpo-34424.wAlRuS.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst delete mode 100644 Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-01-11-17-09-15.bpo-31855.PlhfsX.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-02-15-17-18-50.bpo-35125.h0xk0f.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-04-01-28-33.bpo-26707.QY4kRZ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-09-23-51-27.bpo-36239.BHJ3Ln.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-13-10-57-41.bpo-27497.JDmIe_.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-21-16-00-00.bpo-36368.zsRT1.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-22-22-40-00.bpo-35900.oiee0o.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-03-27-15-09-00.bpo-35900.fh56UU.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-06-00-55-09.bpo-36533.kzMyRH.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-29-15-18-13.bpo-36748.YBKWps.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-04-30-04-34-53.bpo-6584.Hzp9-P.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-03-20-47-55.bpo-36785.PQLnPq.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-05-09-45-44.bpo-36801.XrlFFs.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-05-10-12-23.bpo-36802.HYMc8P.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-05-16-14-38.bpo-36806.rAzF-x.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-06-19-17-04.bpo-26903.4payXb.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-06-23-13-26.bpo-36814.dSeMz_.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-07-15-00-45.bpo-36832.TExgqb.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-09-08-35-18.bpo-24538.WK8Y-k.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-09-12-38-40.bpo-30262.Tu74ak.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-09-18-12-55.bpo-36867.FuwVTi.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-10-01-06-36.bpo-36778.GRqeiS.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-10-22-00-06.bpo-36878.iigeqk.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-11-16-21-29.bpo-35545.FcvJvP.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-12-14-49-13.bpo-36895.ZZuuY7.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-13-13-02-43.bpo-36867.Qh-6mX.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-14-07-57-02.bpo-36845._GtFFf.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-15-21-35-23.bpo-36921.kA1306.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-17-11-44-21.bpo-33524.8y_xUU.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst delete mode 100644 Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst delete mode 100644 Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst delete mode 100644 Misc/NEWS.d/next/Security/2019-02-24-18-48-16.bpo-33529.wpNNBD.rst delete mode 100644 Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-08-15-55-46.bpo-36816.WBKRGZ.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-10-01-50-30.bpo-36719.O84ZWv.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-14-14-12-24.bpo-36915.58b7pH.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst delete mode 100644 Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst delete mode 100644 Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst delete mode 100644 Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst delete mode 100644 Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst delete mode 100644 Misc/NEWS.d/next/Windows/2019-03-01-16-43-45.bpo-35926.mLszHo.rst delete mode 100644 Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst delete mode 100644 Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index f79b25048a5a64..8bf7eb699c4e72 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -36,7 +36,7 @@ ISSUE_URI = 'https://bugs.python.org/issue%s' -SOURCE_URI = 'https://github.com/python/cpython/tree/master/%s' +SOURCE_URI = 'https://github.com/python/cpython/tree/3.8/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body diff --git a/Include/patchlevel.h b/Include/patchlevel.h index da787f27cc88a7..881558bb44f612 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -19,11 +19,11 @@ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 8 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 4 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.8.0a4+" +#define PY_VERSION "3.8.0b1" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 3361c6b5568a4d..1fb19f241ac31c 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Wed May 29 01:18:52 2019 +# Autogenerated by Sphinx on Tue Jun 4 19:40:37 2019 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -357,12 +357,13 @@ 'a variable or attribute annotation and an optional assignment\n' 'statement:\n' '\n' - ' annotated_assignment_stmt ::= augtarget ":" expression ["=" ' - 'expression]\n' + ' annotated_assignment_stmt ::= augtarget ":" expression\n' + ' ["=" (starred_expression | ' + 'yield_expression)]\n' '\n' 'The difference from normal Assignment statements is that only ' 'single\n' - 'target and only single right hand side value is allowed.\n' + 'target is allowed.\n' '\n' 'For simple names as assignment targets, if in class or module ' 'scope,\n' @@ -409,7 +410,14 @@ 'standard\n' ' syntax for type annotations that can be used in static ' 'analysis\n' - ' tools and IDEs.\n', + ' tools and IDEs.\n' + '\n' + 'Changed in version 3.8: Now annotated assignments allow same\n' + 'expressions in the right hand side as the regular ' + 'assignments.\n' + 'Previously, some expressions (like un-parenthesized tuple ' + 'expressions)\n' + 'caused a syntax error.\n', 'async': 'Coroutines\n' '**********\n' '\n' @@ -2026,21 +2034,22 @@ '\n' 'For user-defined classes which do not define "__contains__()" ' 'but do\n' - 'define "__iter__()", "x in y" is "True" if some value "z" ' - 'with "x ==\n' - 'z" is produced while iterating over "y". If an exception is ' - 'raised\n' - 'during the iteration, it is as if "in" raised that ' - 'exception.\n' + 'define "__iter__()", "x in y" is "True" if some value "z", ' + 'for which\n' + 'the expression "x is z or x == z" is true, is produced while ' + 'iterating\n' + 'over "y". If an exception is raised during the iteration, it ' + 'is as if\n' + '"in" raised that exception.\n' '\n' 'Lastly, the old-style iteration protocol is tried: if a class ' 'defines\n' '"__getitem__()", "x in y" is "True" if and only if there is a ' 'non-\n' - 'negative integer index *i* such that "x == y[i]", and all ' - 'lower\n' - 'integer indices do not raise "IndexError" exception. (If any ' - 'other\n' + 'negative integer index *i* such that "x is y[i] or x == ' + 'y[i]", and no\n' + 'lower integer index raises the "IndexError" exception. (If ' + 'any other\n' 'exception is raised, it is as if "in" raised that ' 'exception).\n' '\n' @@ -5081,7 +5090,7 @@ 'Meaning ' '|\n' ' ' - '|===========|============================================================|\n' + '+===========+============================================================+\n' ' | "\'<\'" | Forces the field to be left-aligned ' 'within the available |\n' ' | | space (this is the default for most ' @@ -5130,7 +5139,7 @@ 'Meaning ' '|\n' ' ' - '|===========|============================================================|\n' + '+===========+============================================================+\n' ' | "\'+\'" | indicates that a sign should be used for ' 'both positive as |\n' ' | | well as negative ' @@ -5234,7 +5243,7 @@ 'Meaning ' '|\n' ' ' - '|===========|============================================================|\n' + '+===========+============================================================+\n' ' | "\'s\'" | String format. This is the default type ' 'for strings and |\n' ' | | may be ' @@ -5254,7 +5263,7 @@ 'Meaning ' '|\n' ' ' - '|===========|============================================================|\n' + '+===========+============================================================+\n' ' | "\'b\'" | Binary format. Outputs the number in ' 'base 2. |\n' ' ' @@ -5316,7 +5325,7 @@ 'Meaning ' '|\n' ' ' - '|===========|============================================================|\n' + '+===========+============================================================+\n' ' | "\'e\'" | Exponent notation. Prints the number in ' 'scientific |\n' ' | | notation using the letter ‘e’ to indicate ' @@ -6334,14 +6343,16 @@ '"False" otherwise.\n' '\n' 'For user-defined classes which do not define "__contains__()" but do\n' - 'define "__iter__()", "x in y" is "True" if some value "z" with "x ==\n' - 'z" is produced while iterating over "y". If an exception is raised\n' - 'during the iteration, it is as if "in" raised that exception.\n' + 'define "__iter__()", "x in y" is "True" if some value "z", for which\n' + 'the expression "x is z or x == z" is true, is produced while ' + 'iterating\n' + 'over "y". If an exception is raised during the iteration, it is as if\n' + '"in" raised that exception.\n' '\n' 'Lastly, the old-style iteration protocol is tried: if a class defines\n' '"__getitem__()", "x in y" is "True" if and only if there is a non-\n' - 'negative integer index *i* such that "x == y[i]", and all lower\n' - 'integer indices do not raise "IndexError" exception. (If any other\n' + 'negative integer index *i* such that "x is y[i] or x == y[i]", and no\n' + 'lower integer index raises the "IndexError" exception. (If any other\n' 'exception is raised, it is as if "in" raised that exception).\n' '\n' 'The operator "not in" is defined to have the inverse truth value of\n' @@ -6850,11 +6861,11 @@ 'numeric\n' ' object is an integer type. Must return an integer.\n' '\n' - ' Note: In order to have a coherent integer type class, ' - 'when\n' - ' "__index__()" is defined "__int__()" should also be ' - 'defined, and\n' - ' both should return the same value.\n' + ' If "__int__()", "__float__()" and "__complex__()" are ' + 'not defined\n' + ' then corresponding built-in functions "int()", "float()" ' + 'and\n' + ' "complex()" fall back to "__index__()".\n' '\n' 'object.__round__(self[, ndigits])\n' 'object.__trunc__(self)\n' @@ -7025,7 +7036,7 @@ '+-------------------------------------------------+---------------------------------------+\n' '| Operator | ' 'Description |\n' - '|=================================================|=======================================|\n' + '+=================================================+=======================================+\n' '| "lambda" | ' 'Lambda expression |\n' '+-------------------------------------------------+---------------------------------------+\n' @@ -8716,7 +8727,7 @@ ' in:\n' '\n' ' class Philosopher:\n' - ' def __init_subclass__(cls, default_name, ' + ' def __init_subclass__(cls, /, default_name, ' '**kwargs):\n' ' super().__init_subclass__(**kwargs)\n' ' cls.default_name = default_name\n' @@ -9469,11 +9480,11 @@ 'numeric\n' ' object is an integer type. Must return an integer.\n' '\n' - ' Note: In order to have a coherent integer type class, ' - 'when\n' - ' "__index__()" is defined "__int__()" should also be ' - 'defined, and\n' - ' both should return the same value.\n' + ' If "__int__()", "__float__()" and "__complex__()" are not ' + 'defined\n' + ' then corresponding built-in functions "int()", "float()" ' + 'and\n' + ' "complex()" fall back to "__index__()".\n' '\n' 'object.__round__(self[, ndigits])\n' 'object.__trunc__(self)\n' @@ -10269,7 +10280,7 @@ ' | Representation | ' 'Description |\n' ' ' - '|=========================|===============================|\n' + '+=========================+===============================+\n' ' | "\\n" | Line ' 'Feed |\n' ' ' @@ -10608,7 +10619,7 @@ '+-------------------+-----------------------------------+---------+\n' '| Escape Sequence | Meaning | Notes ' '|\n' - '|===================|===================================|=========|\n' + '+===================+===================================+=========+\n' '| "\\newline" | Backslash and newline ignored ' '| |\n' '+-------------------+-----------------------------------+---------+\n' @@ -10654,7 +10665,7 @@ '+-------------------+-----------------------------------+---------+\n' '| Escape Sequence | Meaning | Notes ' '|\n' - '|===================|===================================|=========|\n' + '+===================+===================================+=========+\n' '| "\\N{name}" | Character named *name* in the | ' '(4) |\n' '| | Unicode database | ' @@ -11292,7 +11303,7 @@ ' | Attribute | Meaning ' '| |\n' ' ' - '|===========================|=================================|=============|\n' + '+===========================+=================================+=============+\n' ' | "__doc__" | The function’s documentation ' '| Writable |\n' ' | | string, or "None" if ' @@ -11769,33 +11780,36 @@ '\n' ' Special read-only attributes: "co_name" gives the function ' 'name;\n' - ' "co_argcount" is the number of positional arguments ' - '(including\n' - ' arguments with default values); "co_nlocals" is the number ' - 'of\n' - ' local variables used by the function (including arguments);\n' - ' "co_varnames" is a tuple containing the names of the local\n' - ' variables (starting with the argument names); "co_cellvars" ' - 'is a\n' - ' tuple containing the names of local variables that are\n' - ' referenced by nested functions; "co_freevars" is a tuple\n' - ' containing the names of free variables; "co_code" is a ' - 'string\n' - ' representing the sequence of bytecode instructions; ' - '"co_consts"\n' - ' is a tuple containing the literals used by the bytecode;\n' - ' "co_names" is a tuple containing the names used by the ' - 'bytecode;\n' - ' "co_filename" is the filename from which the code was ' - 'compiled;\n' - ' "co_firstlineno" is the first line number of the function;\n' - ' "co_lnotab" is a string encoding the mapping from bytecode\n' - ' offsets to line numbers (for details see the source code of ' + ' "co_argcount" is the total number of positional arguments\n' + ' (including positional-only arguments and arguments with ' + 'default\n' + ' values); "co_posonlyargcount" is the number of ' + 'positional-only\n' + ' arguments (including arguments with default values);\n' + ' "co_kwonlyargcount" is the number of keyword-only arguments\n' + ' (including arguments with default values); "co_nlocals" is ' + 'the\n' + ' number of local variables used by the function (including\n' + ' arguments); "co_varnames" is a tuple containing the names of ' + 'the\n' + ' local variables (starting with the argument names);\n' + ' "co_cellvars" is a tuple containing the names of local ' + 'variables\n' + ' that are referenced by nested functions; "co_freevars" is a\n' + ' tuple containing the names of free variables; "co_code" is a\n' + ' string representing the sequence of bytecode instructions;\n' + ' "co_consts" is a tuple containing the literals used by the\n' + ' bytecode; "co_names" is a tuple containing the names used by ' 'the\n' - ' interpreter); "co_stacksize" is the required stack size\n' - ' (including local variables); "co_flags" is an integer ' - 'encoding a\n' - ' number of flags for the interpreter.\n' + ' bytecode; "co_filename" is the filename from which the code ' + 'was\n' + ' compiled; "co_firstlineno" is the first line number of the\n' + ' function; "co_lnotab" is a string encoding the mapping from\n' + ' bytecode offsets to line numbers (for details see the source\n' + ' code of the interpreter); "co_stacksize" is the required ' + 'stack\n' + ' size (including local variables); "co_flags" is an integer\n' + ' encoding a number of flags for the interpreter.\n' '\n' ' The following flag bits are defined for "co_flags": bit ' '"0x04"\n' @@ -12563,7 +12577,7 @@ '+----------------------------+----------------------------------+------------+\n' '| Operation | Result ' '| Notes |\n' - '|============================|==================================|============|\n' + '+============================+==================================+============+\n' '| "x in s" | "True" if an item of *s* is ' '| (1) |\n' '| | equal to *x*, else "False" ' @@ -12792,7 +12806,7 @@ '+--------------------------------+----------------------------------+-----------------------+\n' '| Operation | ' 'Result | Notes |\n' - '|================================|==================================|=======================|\n' + '+================================+==================================+=======================+\n' '| "s[i] = x" | item *i* of *s* is replaced ' 'by | |\n' '| | ' @@ -13254,7 +13268,7 @@ '| Operation | ' 'Result | Notes ' '|\n' - '|================================|==================================|=======================|\n' + '+================================+==================================+=======================+\n' '| "s[i] = x" | item *i* of *s* is ' 'replaced by | |\n' '| | ' diff --git a/Misc/NEWS.d/3.8.0b1.rst b/Misc/NEWS.d/3.8.0b1.rst new file mode 100644 index 00000000000000..d083983642e7a0 --- /dev/null +++ b/Misc/NEWS.d/3.8.0b1.rst @@ -0,0 +1,2052 @@ +.. bpo: 35907 +.. date: 2019-05-21-23-20-18 +.. nonce: NC_zNK +.. release date: 2019-06-04 +.. section: Security + +CVE-2019-9948: Avoid file reading by disallowing ``local-file://`` and +``local_file://`` URL schemes in ``URLopener().open()`` and +``URLopener().retrieve()`` of :mod:`urllib.request`. + +.. + +.. bpo: 33529 +.. date: 2019-02-24-18-48-16 +.. nonce: wpNNBD +.. section: Security + +Prevent fold function used in email header encoding from entering infinite +loop when there are too many non-ASCII characters in a header. + +.. + +.. bpo: 33164 +.. date: 2018-03-30-12-26-47 +.. nonce: aO29Cx +.. section: Security + +Updated blake2 implementation which uses secure memset implementation +provided by platform. + +.. + +.. bpo: 35814 +.. date: 2019-06-03-00-51-02 +.. nonce: Cf7sGY +.. section: Core and Builtins + +Allow unpacking in the right hand side of annotated assignments. In +particular, ``t: Tuple[int, ...] = x, y, *z`` is now allowed. + +.. + +.. bpo: 37126 +.. date: 2019-06-01-20-03-13 +.. nonce: tP6lL4 +.. section: Core and Builtins + +All structseq objects are now tracked by the garbage collector. Patch by +Pablo Galindo. + +.. + +.. bpo: 37122 +.. date: 2019-06-01-16-53-41 +.. nonce: dZ3-NY +.. section: Core and Builtins + +Make the *co_argcount* attribute of code objects represent the total number +of positional arguments (including positional-only arguments). The value of +*co_posonlyargcount* can be used to distinguish which arguments are +positional only, and the difference (*co_argcount* - *co_posonlyargcount*) +is the number of positional-or-keyword arguments. Patch by Pablo Galindo. + +.. + +.. bpo: 20092 +.. date: 2019-05-31-11-55-49 +.. nonce: KIMjBW +.. section: Core and Builtins + +Constructors of :class:`int`, :class:`float` and :class:`complex` will now +use the :meth:`~object.__index__` special method, if available and the +corresponding method :meth:`~object.__int__`, :meth:`~object.__float__` or +:meth:`~object.__complex__` is not available. + +.. + +.. bpo: 37087 +.. date: 2019-05-30-17-33-55 +.. nonce: vElenE +.. section: Core and Builtins + +Add native thread ID (TID) support to OpenBSD. + +.. + +.. bpo: 26219 +.. date: 2019-05-29-22-03-09 +.. nonce: Ovf1Qs +.. section: Core and Builtins + +Implemented per opcode cache mechanism and ``LOAD_GLOBAL`` instruction use +it. ``LOAD_GLOBAL`` is now about 40% faster. Contributed by Yury Selivanov, +and Inada Naoki. + +.. + +.. bpo: 37072 +.. date: 2019-05-28-18-18-55 +.. nonce: 1Hewl3 +.. section: Core and Builtins + +Fix crash in PyAST_FromNodeObject() when flags is NULL. + +.. + +.. bpo: 37029 +.. date: 2019-05-28-17-02-46 +.. nonce: MxpgfJ +.. section: Core and Builtins + +Freeing a great many small objects could take time quadratic in the number +of arenas, due to using linear search to keep ``obmalloc.c``'s list of +usable arenas sorted by order of number of free memory pools. This is +accomplished without search now, leaving the worst-case time linear in the +number of arenas. For programs where this quite visibly matters (typically +with more than 100 thousand small objects alive simultaneously), this can +greatly reduce the time needed to release their memory. + +.. + +.. bpo: 26423 +.. date: 2019-05-27-18-00-19 +.. nonce: RgUOE8 +.. section: Core and Builtins + +Fix possible overflow in ``wrap_lenfunc()`` when ``sizeof(long) < +sizeof(Py_ssize_t)`` (e.g., 64-bit Windows). + +.. + +.. bpo: 37050 +.. date: 2019-05-27-14-46-24 +.. nonce: 7MyZGg +.. section: Core and Builtins + +Improve the AST for "debug" f-strings, which use '=' to print out the source +of the expression being evaluated. Delete expr_text from the FormattedValue +node, and instead use a Constant string node (possibly merged with adjacent +constant expressions inside the f-string). + +.. + +.. bpo: 22385 +.. date: 2019-05-25-17-18-26 +.. nonce: VeVvhJ +.. section: Core and Builtins + +The `bytes.hex`, `bytearray.hex`, and `memoryview.hex` methods as well as +the `binascii.hexlify` and `b2a_hex` functions now have the ability to +include an optional separator between hex bytes. This functionality was +inspired by MicroPython's hexlify implementation. + +.. + +.. bpo: 26836 +.. date: 2019-05-25-08-18-01 +.. nonce: rplYWW +.. section: Core and Builtins + +Add :func:`os.memfd_create`. + +.. + +.. bpo: 37032 +.. date: 2019-05-24-12-38-40 +.. nonce: T8rSH8 +.. section: Core and Builtins + +Added new ``replace()`` method to the code type (:class:`types.CodeType`). + +.. + +.. bpo: 37007 +.. date: 2019-05-23-04-19-13 +.. nonce: d1SOtF +.. section: Core and Builtins + +Implement :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, +and :func:`socket.if_indextoname()` on Windows. + +.. + +.. bpo: 36829 +.. date: 2019-05-22-23-01-29 +.. nonce: MfOcUg +.. section: Core and Builtins + +:c:func:`PyErr_WriteUnraisable` now creates a traceback object if there is +no current traceback. Moreover, call :c:func:`PyErr_NormalizeException` and +:c:func:`PyException_SetTraceback` to normalize the exception value. Ignore +any error. + +.. + +.. bpo: 36878 +.. date: 2019-05-22-11-16-16 +.. nonce: QwLa3P +.. section: Core and Builtins + +Only accept text after `# type: ignore` if the first character is ASCII. +This is to disallow things like `# type: ignoreé`. + +.. + +.. bpo: 36878 +.. date: 2019-05-21-16-21-22 +.. nonce: EFRHZ3 +.. section: Core and Builtins + +Store text appearing after a `# type: ignore` comment in the AST. For +example a type ignore like `# type: ignore[E1000]` will have the string +`"[E1000]"` stored in its AST node. + +.. + +.. bpo: 2180 +.. date: 2019-05-17-18-34-30 +.. nonce: aBqHeW +.. section: Core and Builtins + +Treat line continuation at EOF as a ``SyntaxError`` by Anthony Sottile. + +.. + +.. bpo: 36907 +.. date: 2019-05-17-12-28-24 +.. nonce: rk7kgp +.. section: Core and Builtins + +Fix a crash when calling a C function with a keyword dict (``f(**kwargs)``) +and changing the dict ``kwargs`` while that function is running. + +.. + +.. bpo: 36946 +.. date: 2019-05-16-23-53-45 +.. nonce: qjxr0Y +.. section: Core and Builtins + +Fix possible signed integer overflow when handling slices. + +.. + +.. bpo: 36826 +.. date: 2019-05-15-14-01-09 +.. nonce: GLrO3W +.. section: Core and Builtins + +Add NamedExpression kind support to ast_unparse.c + +.. + +.. bpo: 1875 +.. date: 2019-05-15-01-29-29 +.. nonce: 9oxXFX +.. section: Core and Builtins + +A :exc:`SyntaxError` is now raised if a code blocks that will be optimized +away (e.g. if conditions that are always false) contains syntax errors. +Patch by Pablo Galindo. + +.. + +.. bpo: 36027 +.. date: 2019-05-12-18-46-50 +.. nonce: Q4YatQ +.. section: Core and Builtins + +Allow computation of modular inverses via three-argument ``pow``: the second +argument is now permitted to be negative in the case where the first and +third arguments are relatively prime. + +.. + +.. bpo: 36861 +.. date: 2019-05-08-20-42-40 +.. nonce: 72mvZM +.. section: Core and Builtins + +Update the Unicode database to version 12.1.0. + +.. + +.. bpo: 28866 +.. date: 2019-05-08-16-36-51 +.. nonce: qCv_bj +.. section: Core and Builtins + +Avoid caching attributes of classes which type defines mro() to avoid a hard +cache invalidation problem. + +.. + +.. bpo: 36851 +.. date: 2019-05-08-11-42-06 +.. nonce: J7DiCW +.. section: Core and Builtins + +The ``FrameType`` stack is now correctly cleaned up if the execution ends +with a return and the stack is not empty. + +.. + +.. bpo: 34616 +.. date: 2019-05-07-17-12-37 +.. nonce: 0Y0_9r +.. section: Core and Builtins + +The ``compile()`` builtin functions now support the +``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag, which allow to compile sources +that contains top-level ``await``, ``async with`` or ``async for``. This is +useful to evaluate async-code from with an already async functions; for +example in a custom REPL. + +.. + +.. bpo: 36842 +.. date: 2019-05-07-16-50-12 +.. nonce: NYww_N +.. section: Core and Builtins + +Implement PEP 578, adding sys.audit, io.open_code and related APIs. + +.. + +.. bpo: 27639 +.. date: 2019-05-07-15-49-17 +.. nonce: b1Ah87 +.. section: Core and Builtins + +Correct return type for UserList slicing operations. Patch by Michael +Blahay, Erick Cervantes, and vaultah + +.. + +.. bpo: 36737 +.. date: 2019-05-07-12-18-11 +.. nonce: XAo6LY +.. section: Core and Builtins + +Move PyRuntimeState.warnings into per-interpreter state (via "module +state"). + +.. + +.. bpo: 36793 +.. date: 2019-05-04-16-15-33 +.. nonce: Izog4Z +.. section: Core and Builtins + +Removed ``__str__`` implementations from builtin types :class:`bool`, +:class:`int`, :class:`float`, :class:`complex` and few classes from the +standard library. They now inherit ``__str__()`` from :class:`object`. + +.. + +.. bpo: 36774 +.. date: 2019-05-02-11-48-08 +.. nonce: ZqbJ1J +.. section: Core and Builtins + +Add a ``=`` feature f-strings for debugging. This can precede ``!s``, +``!r``, or ``!a``. It produces the text of the expression, followed by an +equal sign, followed by the repr of the value of the expression. So +``f'{3*9+15=}'`` would be equal to the string ``'3*9+15=42'``. If ``=`` is +specified, the default conversion is set to ``!r``, unless a format spec is +given, in which case the formatting behavior is unchanged, and __format__ +will be used. + +.. + +.. bpo: 24048 +.. date: 2019-04-29-03-27-22 +.. nonce: vXxUDQ +.. section: Core and Builtins + +Save the live exception during import.c's ``remove_module()``. + +.. + +.. bpo: 27987 +.. date: 2019-04-16-11-52-21 +.. nonce: n2_DcQ +.. section: Core and Builtins + +pymalloc returns memory blocks aligned by 16 bytes, instead of 8 bytes, on +64-bit platforms to conform x86-64 ABI. Recent compilers assume this +alignment more often. Patch by Inada Naoki. + +.. + +.. bpo: 36601 +.. date: 2019-04-13-16-14-16 +.. nonce: mIgS7t +.. section: Core and Builtins + +A long-since-meaningless check for ``getpid() == main_pid`` was removed from +Python's internal C signal handler. + +.. + +.. bpo: 36594 +.. date: 2019-04-10-18-12-11 +.. nonce: fbnJAc +.. section: Core and Builtins + +Fix incorrect use of ``%p`` in format strings. Patch by Zackery Spytz. + +.. + +.. bpo: 36045 +.. date: 2019-02-24-12-44-46 +.. nonce: RO20OV +.. section: Core and Builtins + +builtins.help() now prefixes `async` for async functions + +.. + +.. bpo: 36084 +.. date: 2019-02-22-23-03-20 +.. nonce: 86Eh4X +.. section: Core and Builtins + +Add native thread ID (TID) to threading.Thread objects (supported platforms: +Windows, FreeBSD, Linux, macOS) + +.. + +.. bpo: 36035 +.. date: 2019-02-22-14-30-19 +.. nonce: -6dy1y +.. section: Core and Builtins + +Added fix for broken symlinks in combination with pathlib + +.. + +.. bpo: 35983 +.. date: 2019-02-13-16-47-19 +.. nonce: bNxsXv +.. section: Core and Builtins + +Added new trashcan macros to deal with a double deallocation that could +occur when the `tp_dealloc` of a subclass calls the `tp_dealloc` of a base +class and that base class uses the trashcan mechanism. Patch by Jeroen +Demeyer. + +.. + +.. bpo: 20602 +.. date: 2018-07-04-16-57-59 +.. nonce: sDLElw +.. section: Core and Builtins + +Do not clear :data:`sys.flags` and :data:`sys.float_info` during shutdown. +Patch by Zackery Spytz. + +.. + +.. bpo: 26826 +.. date: 2018-05-30-23-43-03 +.. nonce: NkRzjb +.. section: Core and Builtins + +Expose :func:`copy_file_range` as a low level API in the :mod:`os` module. + +.. + +.. bpo: 32388 +.. date: 2017-12-21-20-37-40 +.. nonce: 6w-i5t +.. section: Core and Builtins + +Remove cross-version binary compatibility requirement in tp_flags. + +.. + +.. bpo: 31862 +.. date: 2017-10-24-17-26-58 +.. nonce: 5Gea8L +.. section: Core and Builtins + +Port binascii to PEP 489 multiphase initialization. Patch by Marcel Plch. + +.. + +.. bpo: 37128 +.. date: 2019-06-01-22-54-03 +.. nonce: oGXBWN +.. section: Library + +Added :func:`math.perm`. + +.. + +.. bpo: 37120 +.. date: 2019-06-01-09-03-32 +.. nonce: FOKQLU +.. section: Library + +Add SSLContext.num_tickets to control the number of TLSv1.3 session tickets. + +.. + +.. bpo: 12202 +.. date: 2019-05-31-15-53-34 +.. nonce: nobzc9 +.. section: Library + +Fix the error handling in :meth:`msilib.SummaryInformation.GetProperty`. +Patch by Zackery Spytz. + +.. + +.. bpo: 26835 +.. date: 2019-05-31-11-33-11 +.. nonce: xGbUX0 +.. section: Library + +The fcntl module now contains file sealing constants for sealing of memfds. + +.. + +.. bpo: 29262 +.. date: 2019-05-30-21-25-14 +.. nonce: LdIzun +.. section: Library + +Add ``get_origin()`` and ``get_args()`` introspection helpers to ``typing`` +module. + +.. + +.. bpo: 12639 +.. date: 2019-05-30-16-16-47 +.. nonce: TQFOR4 +.. section: Library + +:meth:`msilib.Directory.start_component()` no longer fails if *keyfile* is +not ``None``. + +.. + +.. bpo: 36999 +.. date: 2019-05-30-13-30-46 +.. nonce: EjY_L2 +.. section: Library + +Add the ``asyncio.Task.get_coro()`` method to publicly expose the tasks's +coroutine object. + +.. + +.. bpo: 35246 +.. date: 2019-05-28-23-17-35 +.. nonce: oXT21d +.. section: Library + +Make :func:`asyncio.create_subprocess_exec` accept path-like arguments. + +.. + +.. bpo: 35279 +.. date: 2019-05-28-19-14-29 +.. nonce: PX7yl9 +.. section: Library + +Change default *max_workers* of ``ThreadPoolExecutor`` from ``cpu_count() * +5`` to ``min(32, cpu_count() + 4))``. Previous value was unreasonably large +on many cores machines. + +.. + +.. bpo: 37076 +.. date: 2019-05-28-12-17-10 +.. nonce: Bk2xOs +.. section: Library + +:func:`_thread.start_new_thread` now logs uncaught exception raised by the +function using :func:`sys.unraisablehook`, rather than +:func:`sys.excepthook`, so the hook gets access to the function which raised +the exception. + +.. + +.. bpo: 33725 +.. date: 2019-05-28-01-17-42 +.. nonce: fFZoDG +.. section: Library + +On macOS, the :mod:`multiprocessing` module now uses *spawn* start method by +default. + +.. + +.. bpo: 37054 +.. date: 2019-05-28-01-06-44 +.. nonce: sLULGQ +.. section: Library + +Fix destructor :class:`_pyio.BytesIO` and :class:`_pyio.TextIOWrapper`: +initialize their ``_buffer`` attribute as soon as possible (in the class +body), because it's used by ``__del__()`` which calls ``close()``. + +.. + +.. bpo: 37058 +.. date: 2019-05-26-19-05-24 +.. nonce: jmRu_g +.. section: Library + +PEP 544: Add ``Protocol`` and ``@runtime_checkable`` to the ``typing`` +module. + +.. + +.. bpo: 36933 +.. date: 2019-05-26-10-16-55 +.. nonce: 4w3eP9 +.. section: Library + +The functions ``sys.set_coroutine_wrapper`` and +``sys.get_coroutine_wrapper`` that were deprecated and marked for removal in +3.8 have been removed. + +.. + +.. bpo: 37047 +.. date: 2019-05-26-01-20-06 +.. nonce: K9epi8 +.. section: Library + +Handle late binding and attribute access in :class:`unittest.mock.AsyncMock` +setup for autospeccing. Document newly implemented async methods in +:class:`unittest.mock.MagicMock`. + +.. + +.. bpo: 37049 +.. date: 2019-05-25-19-48-42 +.. nonce: an2LXJ +.. section: Library + +PEP 589: Add ``TypedDict`` to the ``typing`` module. + +.. + +.. bpo: 37046 +.. date: 2019-05-25-19-12-53 +.. nonce: iuhQQj +.. section: Library + +PEP 586: Add ``Literal`` to the ``typing`` module. + +.. + +.. bpo: 37045 +.. date: 2019-05-25-18-36-50 +.. nonce: suHdVJ +.. section: Library + +PEP 591: Add ``Final`` qualifier and ``@final`` decorator to the ``typing`` +module. + +.. + +.. bpo: 37035 +.. date: 2019-05-24-18-16-07 +.. nonce: HFbJVT +.. section: Library + +Don't log OSError based exceptions if a fatal error has occurred in asyncio +transport. Peer can generate almost any OSError, user cannot avoid these +exceptions by fixing own code. Errors are still propagated to user code, +it's just logging them is pointless and pollute asyncio logs. + +.. + +.. bpo: 37001 +.. date: 2019-05-23-21-10-57 +.. nonce: DoLvTK +.. section: Library + +:func:`symtable.symtable` now accepts the same input types for source code +as the built-in :func:`compile` function. Patch by Dino Viehland. + +.. + +.. bpo: 37028 +.. date: 2019-05-23-18-57-34 +.. nonce: Vse6Pj +.. section: Library + +Implement asyncio REPL + +.. + +.. bpo: 37027 +.. date: 2019-05-23-18-46-56 +.. nonce: iH4eut +.. section: Library + +Return safe to use proxy socket object from +transport.get_extra_info('socket') + +.. + +.. bpo: 32528 +.. date: 2019-05-23-17-37-22 +.. nonce: sGnkcl +.. section: Library + +Make asyncio.CancelledError a BaseException. + +This will address the common mistake many asyncio users make: an "except +Exception" clause breaking Tasks cancellation. + +In addition to this change, we stop inheriting asyncio.TimeoutError and +asyncio.InvalidStateError from their concurrent.futures.* counterparts. +There's no point for these exceptions to share the inheritance chain. + +.. + +.. bpo: 1230540 +.. date: 2019-05-23-01-48-39 +.. nonce: oKTNEQ +.. section: Library + +Add a new :func:`threading.excepthook` function which handles uncaught +:meth:`threading.Thread.run` exception. It can be overridden to control how +uncaught :meth:`threading.Thread.run` exceptions are handled. + +.. + +.. bpo: 36996 +.. date: 2019-05-22-22-55-18 +.. nonce: XQx08d +.. section: Library + +Handle :func:`unittest.mock.patch` used as a decorator on async functions. + +.. + +.. bpo: 37008 +.. date: 2019-05-22-15-26-08 +.. nonce: WPbv31 +.. section: Library + +Add support for calling :func:`next` with the mock resulting from +:func:`unittest.mock.mock_open` + +.. + +.. bpo: 27737 +.. date: 2019-05-22-02-25-31 +.. nonce: 7bgKpa +.. section: Library + +Allow whitespace only header encoding in ``email.header`` - by Batuhan +Taskaya + +.. + +.. bpo: 36969 +.. date: 2019-05-21-12-31-21 +.. nonce: u7cxu7 +.. section: Library + +PDB command `args` now display positional only arguments. Patch contributed +by Rémi Lapeyre. + +.. + +.. bpo: 36969 +.. date: 2019-05-20-23-31-20 +.. nonce: JkZORP +.. section: Library + +PDB command `args` now display keyword only arguments. Patch contributed by +Rémi Lapeyre. + +.. + +.. bpo: 36983 +.. date: 2019-05-20-20-41-30 +.. nonce: hz-fLr +.. section: Library + +Add missing names to ``typing.__all__``: ``ChainMap``, ``ForwardRef``, +``OrderedDict`` - by Anthony Sottile. + +.. + +.. bpo: 36972 +.. date: 2019-05-20-17-08-26 +.. nonce: 3l3SGc +.. section: Library + +Add SupportsIndex protocol to the typing module to allow type checking to +detect classes that can be passed to `hex()`, `oct()` and `bin()`. + +.. + +.. bpo: 32972 +.. date: 2019-05-20-14-47-55 +.. nonce: LoeUNh +.. section: Library + +Implement ``unittest.AsyncTestCase`` to help testing asyncio-based code. + +.. + +.. bpo: 36952 +.. date: 2019-05-20-11-01-28 +.. nonce: MgZi7- +.. section: Library + +:func:`fileinput.input` and :class:`fileinput.FileInput` **bufsize** +argument has been removed (was deprecated and ignored since Python 3.6), and +as a result the **mode** and **openhook** arguments have been made +keyword-only. + +.. + +.. bpo: 36952 +.. date: 2019-05-20-08-54-41 +.. nonce: I_glok +.. section: Library + +Starting with Python 3.3, importing ABCs from :mod:`collections` is +deprecated, and import should be done from :mod:`collections.abc`. Still +being able to import from :mod:`collections` was marked for removal in 3.8, +but has been delayed to 3.9; documentation and ``DeprecationWarning`` +clarified. + +.. + +.. bpo: 36949 +.. date: 2019-05-19-06-54-26 +.. nonce: jBlG9F +.. section: Library + +Implement __repr__ for WeakSet objects. + +.. + +.. bpo: 36948 +.. date: 2019-05-17-21-42-58 +.. nonce: vnUDvk +.. section: Library + +Fix :exc:`NameError` in :meth:`urllib.request.URLopener.retrieve`. Patch by +Karthikeyan Singaravelan. + +.. + +.. bpo: 33524 +.. date: 2019-05-17-11-44-21 +.. nonce: 8y_xUU +.. section: Library + +Fix the folding of email header when the max_line_length is 0 or None and +the header contains non-ascii characters. Contributed by Licht Takeuchi +(@Licht-T). + +.. + +.. bpo: 24564 +.. date: 2019-05-16-23-40-36 +.. nonce: lIwV_7 +.. section: Library + +:func:`shutil.copystat` now ignores :const:`errno.EINVAL` on +:func:`os.setxattr` which may occur when copying files on filesystems +without extended attributes support. + +Original patch by Giampaolo Rodola, updated by Ying Wang. + +.. + +.. bpo: 36888 +.. date: 2019-05-16-18-02-08 +.. nonce: -H2Dkm +.. section: Library + +Python child processes can now access the status of their parent process +using multiprocessing.process.parent_process + +.. + +.. bpo: 36921 +.. date: 2019-05-15-21-35-23 +.. nonce: kA1306 +.. section: Library + +Deprecate ``@coroutine`` for sake of ``async def``. + +.. + +.. bpo: 25652 +.. date: 2019-05-14-21-39-52 +.. nonce: xLw42k +.. section: Library + +Fix bug in ``__rmod__`` of ``UserString`` - by Batuhan Taskaya. + +.. + +.. bpo: 36916 +.. date: 2019-05-14-15-39-34 +.. nonce: _GPsTt +.. section: Library + +Remove a message about an unhandled exception in a task when writer.write() +is used without await and writer.drain() fails with an exception. + +.. + +.. bpo: 36889 +.. date: 2019-05-14-12-25-44 +.. nonce: MChPqP +.. section: Library + +Introduce :class:`asyncio.Stream` class that merges +:class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter` +functionality. :class:`asyncio.Stream` can work in readonly, writeonly and +readwrite modes. Provide :func:`asyncio.connect`, +:func:`asyncio.connect_unix`, :func:`asyncio.connect_read_pipe` and +:func:`asyncio.connect_write_pipe` factories to open :class:`asyncio.Stream` +connections. Provide :class:`asyncio.StreamServer` and +:class:`UnixStreamServer` to serve servers with asyncio.Stream API. Modify +:func:`asyncio.create_subprocess_shell` and +:func:`asyncio.create_subprocess_exec` to use :class:`asyncio.Stream` +instead of deprecated :class:`StreamReader` and :class:`StreamWriter`. +Deprecate :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter`. +Deprecate usage of private classes, e.g. :class:`asyncio.FlowControlMixing` +and :class:`asyncio.StreamReaderProtocol` outside of asyncio package. + +.. + +.. bpo: 36845 +.. date: 2019-05-14-07-57-02 +.. nonce: _GtFFf +.. section: Library + +Added validation of integer prefixes to the construction of IP networks and +interfaces in the ipaddress module. + +.. + +.. bpo: 23378 +.. date: 2019-05-14-05-38-22 +.. nonce: R25teI +.. section: Library + +Add an extend action to argparser. + +.. + +.. bpo: 36867 +.. date: 2019-05-13-13-02-43 +.. nonce: Qh-6mX +.. section: Library + +Fix a bug making a SharedMemoryManager instance and its parent process use +two separate resource_tracker processes. + +.. + +.. bpo: 23896 +.. date: 2019-05-13-05-49-15 +.. nonce: 8TtUKo +.. section: Library + +Adds a grammar to lib2to3.pygram that contains exec as a function not as +statement. + +.. + +.. bpo: 36895 +.. date: 2019-05-12-14-49-13 +.. nonce: ZZuuY7 +.. section: Library + +The function ``time.clock()`` was deprecated in 3.3 in favor of +``time.perf_counter()`` and marked for removal in 3.8, it has removed. + +.. + +.. bpo: 35545 +.. date: 2019-05-11-16-21-29 +.. nonce: FcvJvP +.. section: Library + +Fix asyncio discarding IPv6 scopes when ensuring hostname resolutions +internally + +.. + +.. bpo: 36887 +.. date: 2019-05-11-14-50-59 +.. nonce: XD3f22 +.. section: Library + +Add new function :func:`math.isqrt` to compute integer square roots. + +.. + +.. bpo: 34632 +.. date: 2019-05-11-02-30-45 +.. nonce: 8MXa7T +.. section: Library + +Introduce the ``importlib.metadata`` module with (provisional) support for +reading metadata from third-party packages. + +.. + +.. bpo: 36878 +.. date: 2019-05-10-22-00-06 +.. nonce: iigeqk +.. section: Library + +When using `type_comments=True` in `ast.parse`, treat `# type: ignore` +followed by a non-alphanumeric character and then arbitrary text as a type +ignore, instead of requiring nothing but whitespace or another comment. This +is to permit formations such as `# type: ignore[E1000]`. + +.. + +.. bpo: 36778 +.. date: 2019-05-10-01-06-36 +.. nonce: GRqeiS +.. section: Library + +``cp65001`` encoding (Windows code page 65001) becomes an alias to ``utf_8`` +encoding. + +.. + +.. bpo: 36867 +.. date: 2019-05-09-18-12-55 +.. nonce: FuwVTi +.. section: Library + +The multiprocessing.resource_tracker replaces the +multiprocessing.semaphore_tracker module. Other than semaphores, +resource_tracker also tracks shared_memory segments. + +.. + +.. bpo: 30262 +.. date: 2019-05-09-12-38-40 +.. nonce: Tu74ak +.. section: Library + +The ``Cache`` and ``Statement`` objects of the :mod:`sqlite3` module are not +exposed to the user. Patch by Aviv Palivoda. + +.. + +.. bpo: 24538 +.. date: 2019-05-09-08-35-18 +.. nonce: WK8Y-k +.. section: Library + +In `shutil.copystat()`, first copy extended file attributes and then file +permissions, since extended attributes can only be set on the destination +while it is still writeable. + +.. + +.. bpo: 36829 +.. date: 2019-05-08-12-51-37 +.. nonce: 8enFMA +.. section: Library + +Add new :func:`sys.unraisablehook` function which can be overridden to +control how "unraisable exceptions" are handled. It is called when an +exception has occurred but there is no way for Python to handle it. For +example, when a destructor raises an exception or during garbage collection +(:func:`gc.collect`). + +.. + +.. bpo: 36832 +.. date: 2019-05-07-15-00-45 +.. nonce: TExgqb +.. section: Library + +Introducing ``zipfile.Path``, a pathlib-compatible wrapper for traversing +zip files. + +.. + +.. bpo: 36814 +.. date: 2019-05-06-23-13-26 +.. nonce: dSeMz_ +.. section: Library + +Fix an issue where os.posix_spawnp() would incorrectly raise a TypeError +when file_actions is None. + +.. + +.. bpo: 33110 +.. date: 2019-05-06-22-34-47 +.. nonce: rSJSCh +.. section: Library + +Handle exceptions raised by functions added by concurrent.futures +add_done_callback correctly when the Future has already completed. + +.. + +.. bpo: 26903 +.. date: 2019-05-06-19-17-04 +.. nonce: 4payXb +.. section: Library + +Limit `max_workers` in `ProcessPoolExecutor` to 61 to work around a +WaitForMultipleObjects limitation. + +.. + +.. bpo: 36813 +.. date: 2019-05-06-18-28-38 +.. nonce: NXD0KZ +.. section: Library + +Fix :class:`~logging.handlers.QueueListener` to call ``queue.task_done()`` +upon stopping. Patch by Bar Harel. + +.. + +.. bpo: 36806 +.. date: 2019-05-05-16-14-38 +.. nonce: rAzF-x +.. section: Library + +Forbid creation of asyncio stream objects like StreamReader, StreamWriter, +Process, and their protocols outside of asyncio package. + +.. + +.. bpo: 36802 +.. date: 2019-05-05-10-12-23 +.. nonce: HYMc8P +.. section: Library + +Provide both sync and async calls for StreamWriter.write() and +StreamWriter.close() + +.. + +.. bpo: 36801 +.. date: 2019-05-05-09-45-44 +.. nonce: XrlFFs +.. section: Library + +Properly handle SSL connection closing in asyncio StreamWriter.drain() call. + +.. + +.. bpo: 36785 +.. date: 2019-05-03-20-47-55 +.. nonce: PQLnPq +.. section: Library + +Implement PEP 574 (pickle protocol 5 with out-of-band buffers). + +.. + +.. bpo: 36772 +.. date: 2019-05-01-20-41-53 +.. nonce: fV2K0F +.. section: Library + +functools.lru_cache() can now be used as a straight decorator in addition to +its existing usage as a function that returns a decorator. + +.. + +.. bpo: 6584 +.. date: 2019-04-30-04-34-53 +.. nonce: Hzp9-P +.. section: Library + +Add a :exc:`~gzip.BadGzipFile` exception to the :mod:`gzip` module. + +.. + +.. bpo: 36748 +.. date: 2019-04-29-15-18-13 +.. nonce: YBKWps +.. section: Library + +Optimized write buffering in C implementation of ``TextIOWrapper``. Writing +ASCII string to ``TextIOWrapper`` with ascii, latin1, or utf-8 encoding is +about 20% faster. Patch by Inada Naoki. + +.. + +.. bpo: 8138 +.. date: 2019-04-27-02-54-23 +.. nonce: osBRGI +.. section: Library + +Don't mark ``wsgiref.simple_server.SimpleServer`` as multi-threaded since +``wsgiref.simple_server.WSGIServer`` is single-threaded. + +.. + +.. bpo: 22640 +.. date: 2019-04-26-22-13-26 +.. nonce: p3rheW +.. section: Library + +:func:`py_compile.compile` now supports silent mode. Patch by Joannah +Nanjekye + +.. + +.. bpo: 29183 +.. date: 2019-04-22-22-55-29 +.. nonce: MILvsk +.. section: Library + +Fix double exceptions in :class:`wsgiref.handlers.BaseHandler` by calling +its :meth:`~wsgiref.handlers.BaseHandler.close` method only when no +exception is raised. + +.. + +.. bpo: 36548 +.. date: 2019-04-07-14-30-10 +.. nonce: CJQiYw +.. section: Library + +Improved the repr of regular expression flags. + +.. + +.. bpo: 36542 +.. date: 2019-04-06-12-36-09 +.. nonce: Q0qyYV +.. section: Library + +The signature of Python functions can now be overridden by specifying the +``__text_signature__`` attribute. + +.. + +.. bpo: 36533 +.. date: 2019-04-06-00-55-09 +.. nonce: kzMyRH +.. section: Library + +Reinitialize logging.Handler locks in forked child processes instead of +attempting to acquire them all in the parent before forking only to be +released in the child process. The acquire/release pattern was leading to +deadlocks in code that has implemented any form of chained logging handlers +that depend upon one another as the lock acquision order cannot be +guaranteed. + +.. + +.. bpo: 35252 +.. date: 2019-04-02-19-23-12 +.. nonce: VooTVv +.. section: Library + +Throw a TypeError instead of an AssertionError when using an invalid type +annotation with singledispatch. + +.. + +.. bpo: 35900 +.. date: 2019-03-27-15-09-00 +.. nonce: fh56UU +.. section: Library + +Allow reduction methods to return a 6-item tuple where the 6th item +specifies a custom state-setting method that's called instead of the regular +``__setstate__`` method. + +.. + +.. bpo: 35900 +.. date: 2019-03-22-22-40-00 +.. nonce: oiee0o +.. section: Library + +enable custom reduction callback registration for functions and classes in +_pickle.c, using the new Pickler's attribute ``reducer_override`` + +.. + +.. bpo: 36368 +.. date: 2019-03-21-16-00-00 +.. nonce: zsRT1 +.. section: Library + +Fix a bug crashing SharedMemoryManager instances in interactive sessions +after a ctrl-c (KeyboardInterrupt) was sent + +.. + +.. bpo: 31904 +.. date: 2019-03-18-14-25-36 +.. nonce: ds3d67 +.. section: Library + +Fix mmap fail for VxWorks + +.. + +.. bpo: 27497 +.. date: 2019-03-13-10-57-41 +.. nonce: JDmIe_ +.. section: Library + +:meth:`csv.DictWriter.writeheader` now returns the return value of the +underlying :meth:`csv.Writer.writerow` method. Patch contributed by Ashish +Nitin Patil. + +.. + +.. bpo: 36239 +.. date: 2019-03-09-23-51-27 +.. nonce: BHJ3Ln +.. section: Library + +Parsing .mo files now ignores comments starting and ending with #-#-#-#-#. + +.. + +.. bpo: 26707 +.. date: 2019-03-04-01-28-33 +.. nonce: QY4kRZ +.. section: Library + +Enable plistlib to read and write binary plist files that were created as a +KeyedArchive file. Specifically, this allows the plistlib to process 0x80 +tokens as UID objects. + +.. + +.. bpo: 31904 +.. date: 2019-03-01-17-59-39 +.. nonce: 38djdk +.. section: Library + +Add posix module support for VxWorks. + +.. + +.. bpo: 35125 +.. date: 2019-02-15-17-18-50 +.. nonce: h0xk0f +.. section: Library + +Asyncio: Remove inner callback on outer cancellation in shield + +.. + +.. bpo: 35721 +.. date: 2019-01-18-16-23-00 +.. nonce: d8djAJ +.. section: Library + +Fix :meth:`asyncio.SelectorEventLoop.subprocess_exec()` leaks file +descriptors if ``Popen`` fails and called with ``stdin=subprocess.PIPE``. +Patch by Niklas Fiekas. + +.. + +.. bpo: 31855 +.. date: 2019-01-11-17-09-15 +.. nonce: PlhfsX +.. section: Library + +:func:`unittest.mock.mock_open` results now respects the argument of +read([size]). Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 35431 +.. date: 2019-01-02-19-48-23 +.. nonce: FhG6QA +.. section: Library + +Implement :func:`math.comb` that returns binomial coefficient, that computes +the number of ways to choose k items from n items without repetition and +without order. Patch by Yash Aggarwal and Keller Fuchs. + +.. + +.. bpo: 26660 +.. date: 2018-11-04-16-39-46 +.. nonce: RdXz8a +.. section: Library + +Fixed permission errors in :class:`~tempfile.TemporaryDirectory` clean up. +Previously ``TemporaryDirectory.cleanup()`` failed when non-writeable or +non-searchable files or directories were created inside a temporary +directory. + +.. + +.. bpo: 34271 +.. date: 2018-10-21-17-39-32 +.. nonce: P15VLM +.. section: Library + +Add debugging helpers to ssl module. It's now possible to dump key material +and to trace TLS protocol. The default and stdlib contexts also support +SSLKEYLOGFILE env var. + +.. + +.. bpo: 26467 +.. date: 2018-09-13-20-33-24 +.. nonce: cahAk3 +.. section: Library + +Added AsyncMock to support using unittest to mock asyncio coroutines. Patch +by Lisa Roach. + +.. + +.. bpo: 33569 +.. date: 2018-08-28-03-00-12 +.. nonce: 45YlGG +.. section: Library + +dataclasses.InitVar: Exposes the type used to create the init var. + +.. + +.. bpo: 34424 +.. date: 2018-08-18-14-47-00 +.. nonce: wAlRuS +.. section: Library + +Fix serialization of messages containing encoded strings when the +policy.linesep is set to a multi-character string. Patch by Jens Troeger. + +.. + +.. bpo: 34303 +.. date: 2018-08-03-09-47-20 +.. nonce: tOE2HP +.. section: Library + +Performance of :func:`functools.reduce` is slightly improved. Patch by +Sergey Fedoseev. + +.. + +.. bpo: 33361 +.. date: 2018-07-13-20-17-17 +.. nonce: dx2NVn +.. section: Library + +Fix a bug in :class:`codecs.StreamRecoder` where seeking might leave old +data in a buffer and break subsequent read calls. Patch by Ammar Askar. + +.. + +.. bpo: 22454 +.. date: 2018-06-10-17-48-07 +.. nonce: qeiy_X +.. section: Library + +The :mod:`shlex` module now exposes :func:`shlex.join`, the inverse of +:func:`shlex.split`. Patch by Bo Bayles. + +.. + +.. bpo: 31922 +.. date: 2018-05-30-01-05-50 +.. nonce: fobsXJ +.. section: Library + +:meth:`asyncio.AbstractEventLoop.create_datagram_endpoint`: Do not connect +UDP socket when broadcast is allowed. This allows to receive replies after a +UDP broadcast. + +.. + +.. bpo: 24882 +.. date: 2018-04-04-14-54-30 +.. nonce: urybpa +.. section: Library + +Change ThreadPoolExecutor to use existing idle threads before spinning up +new ones. + +.. + +.. bpo: 31961 +.. date: 2018-03-27-13-28-16 +.. nonce: GjLoYu +.. section: Library + +Added support for bytes and path-like objects in :func:`subprocess.Popen` on +Windows. The *args* parameter now accepts a :term:`path-like object` if +*shell* is ``False`` and a sequence containing bytes and path-like objects. +The *executable* parameter now accepts a bytes and :term:`path-like object`. +The *cwd* parameter now accepts a bytes object. Based on patch by Anders +Lorentsen. + +.. + +.. bpo: 33123 +.. date: 2018-03-22-19-13-19 +.. nonce: _Y5ooE +.. section: Library + +:class:`pathlib.Path.unlink` now accepts a *missing_ok* parameter to avoid a +:exc:`FileNotFoundError` from being raised. Patch by Robert Buchholz. + +.. + +.. bpo: 32941 +.. date: 2018-03-20-20-57-00 +.. nonce: 9FU0gL +.. section: Library + +Allow :class:`mmap.mmap` objects to access the madvise() system call +(through :meth:`mmap.mmap.madvise`). + +.. + +.. bpo: 22102 +.. date: 2018-03-08-16-15-00 +.. nonce: th33uD +.. section: Library + +Added support for ZIP files with disks set to 0. Such files are commonly +created by builtin tools on Windows when use ZIP64 extension. Patch by +Francisco Facioni. + +.. + +.. bpo: 32515 +.. date: 2018-01-07-21-04-50 +.. nonce: D8_Wcb +.. section: Library + +trace.py can now run modules via python3 -m trace -t --module module_name + +.. + +.. bpo: 32299 +.. date: 2017-12-13-17-49-56 +.. nonce: eqAPWs +.. section: Library + +Changed :func:`unittest.mock.patch.dict` to return the patched dictionary +when used as context manager. Patch by Vadim Tsander. + +.. + +.. bpo: 27141 +.. date: 2017-10-24-00-42-14 +.. nonce: zbAgSs +.. section: Library + +Added a ``__copy__()`` to ``collections.UserList`` and +``collections.UserDict`` in order to correctly implement shallow copying of +the objects. Patch by Bar Harel. + +.. + +.. bpo: 31829 +.. date: 2017-10-21-12-07-56 +.. nonce: 6IhP-O +.. section: Library + +``\r``, ``\0`` and ``\x1a`` (end-of-file on Windows) are now escaped in +protocol 0 pickles of Unicode strings. This allows to load them without loss +from files open in text mode in Python 2. + +.. + +.. bpo: 23395 +.. date: 2016-07-27-11-06-43 +.. nonce: MuCEX9 +.. section: Library + +``_thread.interrupt_main()`` now avoids setting the Python error status if +the ``SIGINT`` signal is ignored or not handled by Python. + +.. + +.. bpo: 36896 +.. date: 2019-05-31-10-46-36 +.. nonce: wkXTW9 +.. section: Documentation + +Clarify that some types have unstable constructor signature between Python +versions. + +.. + +.. bpo: 36686 +.. date: 2019-05-27-17-28-58 +.. nonce: Zot4sx +.. section: Documentation + +Improve documentation of the stdin, stdout, and stderr arguments of of the +``asyncio.subprocess_exec`` function to specficy which values are supported. +Also mention that decoding as text is not supported. + +Add a few tests to verify that the various values passed to the std* +arguments actually work. + +.. + +.. bpo: 36984 +.. date: 2019-05-20-22-21-17 +.. nonce: IjZlmS +.. section: Documentation + +Improve version added references in ``typing`` module - by Anthony Sottile. + +.. + +.. bpo: 36868 +.. date: 2019-05-11-17-42-15 +.. nonce: yioL0R +.. section: Documentation + +What's new now mentions SSLContext.hostname_checks_common_name instead of +SSLContext.host_flags. + +.. + +.. bpo: 35924 +.. date: 2019-05-08-13-17-44 +.. nonce: lqbNpW +.. section: Documentation + +Add a note to the ``curses.addstr()`` documentation to warn that multiline +strings can cause segfaults because of an ncurses bug. + +.. + +.. bpo: 36783 +.. date: 2019-05-07-02-30-51 +.. nonce: gpC8E2 +.. section: Documentation + +Added C API Documentation for Time_FromTimeAndFold and +PyDateTime_FromDateAndTimeAndFold as per PEP 495. Patch by Edison Abahurire. + +.. + +.. bpo: 36797 +.. date: 2019-05-05-07-58-50 +.. nonce: W1X4On +.. section: Documentation + +More of the legacy distutils documentation has been either pruned, or else +more clearly marked as being retained solely until the setuptools +documentation covers it independently. + +.. + +.. bpo: 22865 +.. date: 2019-02-21-18-13-50 +.. nonce: 6hg6J8 +.. section: Documentation + +Add detail to the documentation on the `pty.spawn` function. + +.. + +.. bpo: 35397 +.. date: 2019-01-09-17-56-35 +.. nonce: ZMreIz +.. section: Documentation + +Remove deprecation and document urllib.parse.unwrap(). Patch contributed by +Rémi Lapeyre. + +.. + +.. bpo: 32995 +.. date: 2018-10-07-03-04-57 +.. nonce: TXN9ur +.. section: Documentation + +Added the context variable in glossary. + +.. + +.. bpo: 33519 +.. date: 2018-05-17-21-02-00 +.. nonce: Q7s2FB +.. section: Documentation + +Clarify that `copy()` is not part of the `MutableSequence` ABC. + +.. + +.. bpo: 33482 +.. date: 2018-05-13-10-36-37 +.. nonce: jalAaQ +.. section: Documentation + +Make `codecs.StreamRecoder.writelines` take a list of bytes. + +.. + +.. bpo: 25735 +.. date: 2018-04-08-19-09-22 +.. nonce: idVQBD +.. section: Documentation + +Added documentation for func factorial to indicate that returns integer +values + +.. + +.. bpo: 20285 +.. date: 2017-12-08-20-30-37 +.. nonce: cfnp0J +.. section: Documentation + +Expand object.__doc__ (docstring) to make it clearer. Modify pydoc.py so +that help(object) lists object methods (for other classes, help omits +methods of the object base class.) + +.. + +.. bpo: 37069 +.. date: 2019-06-03-02-30-36 +.. nonce: rVtdLk +.. section: Tests + +Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl +and test_yield_from to use :func:`test.support.catch_unraisable_exception` +rather than :func:`test.support.captured_stderr`. + +.. + +.. bpo: 37098 +.. date: 2019-05-30-10-57-39 +.. nonce: SfXt1M +.. section: Tests + +Fix test_memfd_create on older Linux Kernels. + +.. + +.. bpo: 37081 +.. date: 2019-05-28-17-48-22 +.. nonce: qxB-1l +.. section: Tests + +Test with OpenSSL 1.1.1c + +.. + +.. bpo: 36829 +.. date: 2019-05-22-12-57-15 +.. nonce: e9mRWC +.. section: Tests + +Add :func:`test.support.catch_unraisable_exception`: context manager +catching unraisable exception using :func:`sys.unraisablehook`. + +.. + +.. bpo: 36915 +.. date: 2019-05-14-14-12-24 +.. nonce: 58b7pH +.. section: Tests + +The main regrtest process now always removes all temporary directories of +worker processes even if they crash or if they are killed on +KeyboardInterrupt (CTRL+c). + +.. + +.. bpo: 36719 +.. date: 2019-05-10-01-50-30 +.. nonce: O84ZWv +.. section: Tests + +"python3 -m test -jN ..." now continues the execution of next tests when a +worker process crash (CHILD_ERROR state). Previously, the test suite stopped +immediately. Use --failfast to stop at the first error. + +.. + +.. bpo: 36816 +.. date: 2019-05-08-15-55-46 +.. nonce: WBKRGZ +.. section: Tests + +Update Lib/test/selfsigned_pythontestdotnet.pem to match +self-signed.pythontest.net's new TLS certificate. + +.. + +.. bpo: 35925 +.. date: 2019-05-06-18-29-54 +.. nonce: gwQPuC +.. section: Tests + +Skip httplib and nntplib networking tests when they would otherwise fail due +to a modern OS or distro with a default OpenSSL policy of rejecting +connections to servers with weak certificates. + +.. + +.. bpo: 36782 +.. date: 2019-05-04-21-25-19 +.. nonce: h3oPIb +.. section: Tests + +Add tests for several C API functions in the :mod:`datetime` module. Patch +by Edison Abahurire. + +.. + +.. bpo: 36342 +.. date: 2019-03-23-13-58-49 +.. nonce: q6Quiq +.. section: Tests + +Fix test_multiprocessing in test_venv if platform lacks functioning +sem_open. + +.. + +.. bpo: 36721 +.. date: 2019-05-22-16-19-18 +.. nonce: 9aRwfZ +.. section: Build + +To embed Python into an application, a new ``--embed`` option must be passed +to ``python3-config --libs --embed`` to get ``-lpython3.8`` (link the +application to libpython). To support both 3.8 and older, try +``python3-config --libs --embed`` first and fallback to ``python3-config +--libs`` (without ``--embed``) if the previous command fails. + +Add a pkg-config ``python-3.8-embed`` module to embed Python into an +application: ``pkg-config python-3.8-embed --libs`` includes +``-lpython3.8``. To support both 3.8 and older, try ``pkg-config +python-X.Y-embed --libs`` first and fallback to ``pkg-config python-X.Y +--libs`` (without ``--embed``) if the previous command fails (replace +``X.Y`` with the Python version). + +On the other hand, ``pkg-config python3.8 --libs`` no longer contains +``-lpython3.8``. C extensions must not be linked to libpython (except on +Android, case handled by the script); this change is backward incompatible +on purpose. + +.. + +.. bpo: 36786 +.. date: 2019-05-03-21-08-06 +.. nonce: gOLFbD +.. section: Build + +"make install" now runs compileall in parallel. + +.. + +.. bpo: 36965 +.. date: 2019-05-20-20-26-36 +.. nonce: KsfI-N +.. section: Windows + +include of STATUS_CONTROL_C_EXIT without depending on MSC compiler + +.. + +.. bpo: 35926 +.. date: 2019-03-01-16-43-45 +.. nonce: mLszHo +.. section: Windows + +Update to OpenSSL 1.1.1b for Windows. + +.. + +.. bpo: 29883 +.. date: 2018-09-15-11-36-55 +.. nonce: HErerE +.. section: Windows + +Add Windows support for UDP transports for the Proactor Event Loop. Patch by +Adam Meily. + +.. + +.. bpo: 33407 +.. date: 2018-08-28-17-23-49 +.. nonce: ARG0W_ +.. section: Windows + +The :c:macro:`Py_DEPRECATED()` macro has been implemented for MSVC. + +.. + +.. bpo: 36231 +.. date: 2019-06-03-05-49-49 +.. nonce: RfmW_p +.. section: macOS + +Support building Python on macOS without /usr/include installed. As of macOS +10.14, system header files are only available within an SDK provided by +either the Command Line Tools or the Xcode app. + +.. + +.. bpo: 35610 +.. date: 2019-06-02-14-10-52 +.. nonce: 0w_v6Y +.. section: IDLE + +Replace now redundant .context_use_ps1 with .prompt_last_line. This finishes +change started in bpo-31858. + +.. + +.. bpo: 37038 +.. date: 2019-05-24-18-57-57 +.. nonce: AJ3RwQ +.. section: IDLE + +Make idlelib.run runnable; add test clause. + +.. + +.. bpo: 36958 +.. date: 2019-05-19-22-02-22 +.. nonce: DZUC6G +.. section: IDLE + +Print any argument other than None or int passed to SystemExit or +sys.exit(). + +.. + +.. bpo: 13102 +.. date: 2019-05-05-16-27-53 +.. nonce: AGNWYJ +.. section: IDLE + +When saving a file, call os.fsync() so bits are flushed to e.g. USB drive. + +.. + +.. bpo: 32411 +.. date: 2017-12-25-18-48-50 +.. nonce: vNwDhe +.. section: IDLE + +In browser.py, remove extraneous sorting by line number since dictionary was +created in line number order. + +.. + +.. bpo: 37053 +.. date: 2019-05-26-16-47-06 +.. nonce: -EYRuz +.. section: Tools/Demos + +Handle strings like u"bar" correctly in Tools/parser/unparse.py. Patch by +Chih-Hsuan Yen. + +.. + +.. bpo: 36763 +.. date: 2019-05-27-12-25-25 +.. nonce: bHCA9j +.. section: C API + +Implement the :pep:`587` "Python Initialization Configuration". + +.. + +.. bpo: 36379 +.. date: 2019-05-24-07-11-08 +.. nonce: 8zgoKe +.. section: C API + +Fix crashes when attempting to use the *modulo* parameter when ``__ipow__`` +is implemented in C. + +.. + +.. bpo: 37107 +.. date: 2019-05-22-17-33-52 +.. nonce: 8BVPR- +.. section: C API + +Update :c:func:`PyObject_CallMethodObjArgs` and +``_PyObject_CallMethodIdObjArgs`` to use ``_PyObject_GetMethod`` to avoid +creating a bound method object in many cases. Patch by Michael J. Sullivan. + +.. + +.. bpo: 36974 +.. date: 2019-05-22-15-24-08 +.. nonce: TkySRe +.. section: C API + +Implement :pep:`590`: Vectorcall: a fast calling protocol for CPython. This +is a new protocol to optimize calls of custom callable objects. + +.. + +.. bpo: 36763 +.. date: 2019-05-17-19-23-24 +.. nonce: TswmDy +.. section: C API + +``Py_Main()`` now returns the exitcode rather than calling +``Py_Exit(exitcode)`` when calling ``PyErr_Print()`` if the current +exception type is ``SystemExit``. + +.. + +.. bpo: 36922 +.. date: 2019-05-15-10-46-55 +.. nonce: J3EFK_ +.. section: C API + +Add new type flag ``Py_TPFLAGS_METHOD_DESCRIPTOR`` for objects behaving like +unbound methods. These are objects supporting the optimization given by the +``LOAD_METHOD``/``CALL_METHOD`` opcodes. See PEP 590. + +.. + +.. bpo: 36728 +.. date: 2019-05-11-03-56-23 +.. nonce: FR-dMP +.. section: C API + +The :c:func:`PyEval_ReInitThreads` function has been removed from the C API. +It should not be called explicitly: use :c:func:`PyOS_AfterFork_Child` +instead. diff --git a/Misc/NEWS.d/next/Build/2019-05-03-21-08-06.bpo-36786.gOLFbD.rst b/Misc/NEWS.d/next/Build/2019-05-03-21-08-06.bpo-36786.gOLFbD.rst deleted file mode 100644 index 0fcda434a799cd..00000000000000 --- a/Misc/NEWS.d/next/Build/2019-05-03-21-08-06.bpo-36786.gOLFbD.rst +++ /dev/null @@ -1 +0,0 @@ -"make install" now runs compileall in parallel. diff --git a/Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst b/Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst deleted file mode 100644 index 1c266586a33b76..00000000000000 --- a/Misc/NEWS.d/next/Build/2019-05-22-16-19-18.bpo-36721.9aRwfZ.rst +++ /dev/null @@ -1,16 +0,0 @@ -To embed Python into an application, a new ``--embed`` option must be passed to -``python3-config --libs --embed`` to get ``-lpython3.8`` (link the application -to libpython). To support both 3.8 and older, try ``python3-config --libs ---embed`` first and fallback to ``python3-config --libs`` (without ``--embed``) -if the previous command fails. - -Add a pkg-config ``python-3.8-embed`` module to embed Python into an -application: ``pkg-config python-3.8-embed --libs`` includes ``-lpython3.8``. -To support both 3.8 and older, try ``pkg-config python-X.Y-embed --libs`` first -and fallback to ``pkg-config python-X.Y --libs`` (without ``--embed``) if the -previous command fails (replace ``X.Y`` with the Python version). - -On the other hand, ``pkg-config python3.8 --libs`` no longer contains -``-lpython3.8``. C extensions must not be linked to libpython (except on -Android, case handled by the script); this change is backward incompatible on -purpose. diff --git a/Misc/NEWS.d/next/C API/2019-05-11-03-56-23.bpo-36728.FR-dMP.rst b/Misc/NEWS.d/next/C API/2019-05-11-03-56-23.bpo-36728.FR-dMP.rst deleted file mode 100644 index c691cc412c2194..00000000000000 --- a/Misc/NEWS.d/next/C API/2019-05-11-03-56-23.bpo-36728.FR-dMP.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :c:func:`PyEval_ReInitThreads` function has been removed from the C API. -It should not be called explicitly: use :c:func:`PyOS_AfterFork_Child` instead. diff --git a/Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst b/Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst deleted file mode 100644 index 8eee208f905b5f..00000000000000 --- a/Misc/NEWS.d/next/C API/2019-05-15-10-46-55.bpo-36922.J3EFK_.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add new type flag ``Py_TPFLAGS_METHOD_DESCRIPTOR`` for objects behaving like -unbound methods. These are objects supporting the optimization given by the -``LOAD_METHOD``/``CALL_METHOD`` opcodes. See PEP 590. diff --git a/Misc/NEWS.d/next/C API/2019-05-17-19-23-24.bpo-36763.TswmDy.rst b/Misc/NEWS.d/next/C API/2019-05-17-19-23-24.bpo-36763.TswmDy.rst deleted file mode 100644 index 29c016600dbf1a..00000000000000 --- a/Misc/NEWS.d/next/C API/2019-05-17-19-23-24.bpo-36763.TswmDy.rst +++ /dev/null @@ -1,3 +0,0 @@ -``Py_Main()`` now returns the exitcode rather than calling -``Py_Exit(exitcode)`` when calling ``PyErr_Print()`` if the current -exception type is ``SystemExit``. diff --git a/Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst b/Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst deleted file mode 100644 index c51c2e2419d1fa..00000000000000 --- a/Misc/NEWS.d/next/C API/2019-05-22-15-24-08.bpo-36974.TkySRe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement :pep:`590`: Vectorcall: a fast calling protocol for CPython. -This is a new protocol to optimize calls of custom callable objects. diff --git a/Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst b/Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst deleted file mode 100644 index 4a9e58f7155483..00000000000000 --- a/Misc/NEWS.d/next/C API/2019-05-22-17-33-52.bpo-37107.8BVPR-.rst +++ /dev/null @@ -1,4 +0,0 @@ -Update :c:func:`PyObject_CallMethodObjArgs` and ``_PyObject_CallMethodIdObjArgs`` -to use ``_PyObject_GetMethod`` to avoid creating a bound method object in many -cases. -Patch by Michael J. Sullivan. diff --git a/Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst b/Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst deleted file mode 100644 index 6a699b2084e4a3..00000000000000 --- a/Misc/NEWS.d/next/C API/2019-05-24-07-11-08.bpo-36379.8zgoKe.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix crashes when attempting to use the *modulo* parameter when ``__ipow__`` -is implemented in C. diff --git a/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst b/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst deleted file mode 100644 index fc5a48107cfd30..00000000000000 --- a/Misc/NEWS.d/next/C API/2019-05-27-12-25-25.bpo-36763.bHCA9j.rst +++ /dev/null @@ -1 +0,0 @@ -Implement the :pep:`587` "Python Initialization Configuration". diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst deleted file mode 100644 index 0e80cdc6924fcb..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-10-24-17-26-58.bpo-31862.5Gea8L.rst +++ /dev/null @@ -1,2 +0,0 @@ -Port binascii to PEP 489 multiphase initialization. -Patch by Marcel Plch. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst deleted file mode 100644 index 60615d47f60d4d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst +++ /dev/null @@ -1 +0,0 @@ -Remove cross-version binary compatibility requirement in tp_flags. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst deleted file mode 100644 index 27d7f82a672db4..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-05-30-23-43-03.bpo-26826.NkRzjb.rst +++ /dev/null @@ -1 +0,0 @@ -Expose :func:`copy_file_range` as a low level API in the :mod:`os` module. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst deleted file mode 100644 index ab37a020d8036f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-07-04-16-57-59.bpo-20602.sDLElw.rst +++ /dev/null @@ -1,2 +0,0 @@ -Do not clear :data:`sys.flags` and :data:`sys.float_info` during shutdown. -Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-13-16-47-19.bpo-35983.bNxsXv.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-13-16-47-19.bpo-35983.bNxsXv.rst deleted file mode 100644 index 1138df635dbbdc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-13-16-47-19.bpo-35983.bNxsXv.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added new trashcan macros to deal with a double deallocation that could occur -when the `tp_dealloc` of a subclass calls the `tp_dealloc` of a base class -and that base class uses the trashcan mechanism. Patch by Jeroen Demeyer. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst deleted file mode 100644 index 1e4f7ac71f3395..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-14-30-19.bpo-36035.-6dy1y.rst +++ /dev/null @@ -1 +0,0 @@ -Added fix for broken symlinks in combination with pathlib \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst deleted file mode 100644 index fb28a6fec77a5d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-22-23-03-20.bpo-36084.86Eh4X.rst +++ /dev/null @@ -1 +0,0 @@ -Add native thread ID (TID) to threading.Thread objects (supported platforms: Windows, FreeBSD, Linux, macOS) \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst deleted file mode 100644 index 7cab3ea8409d1b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-02-24-12-44-46.bpo-36045.RO20OV.rst +++ /dev/null @@ -1 +0,0 @@ -builtins.help() now prefixes `async` for async functions diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-04-10-18-12-11.bpo-36594.fbnJAc.rst b/Misc/NEWS.d/next/Core and Builtins/2019-04-10-18-12-11.bpo-36594.fbnJAc.rst deleted file mode 100644 index 7ca5dd998d9882..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-04-10-18-12-11.bpo-36594.fbnJAc.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix incorrect use of ``%p`` in format strings. -Patch by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-04-13-16-14-16.bpo-36601.mIgS7t.rst b/Misc/NEWS.d/next/Core and Builtins/2019-04-13-16-14-16.bpo-36601.mIgS7t.rst deleted file mode 100644 index 0159aae65d750a..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-04-13-16-14-16.bpo-36601.mIgS7t.rst +++ /dev/null @@ -1,2 +0,0 @@ -A long-since-meaningless check for ``getpid() == main_pid`` was removed -from Python's internal C signal handler. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-04-16-11-52-21.bpo-27987.n2_DcQ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-04-16-11-52-21.bpo-27987.n2_DcQ.rst deleted file mode 100644 index b0f32a5c6c3f41..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-04-16-11-52-21.bpo-27987.n2_DcQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -pymalloc returns memory blocks aligned by 16 bytes, instead of 8 bytes, on -64-bit platforms to conform x86-64 ABI. Recent compilers assume this alignment -more often. Patch by Inada Naoki. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-04-29-03-27-22.bpo-24048.vXxUDQ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-04-29-03-27-22.bpo-24048.vXxUDQ.rst deleted file mode 100644 index 27c86a47f4b925..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-04-29-03-27-22.bpo-24048.vXxUDQ.rst +++ /dev/null @@ -1 +0,0 @@ -Save the live exception during import.c's ``remove_module()``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-02-11-48-08.bpo-36774.ZqbJ1J.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-02-11-48-08.bpo-36774.ZqbJ1J.rst deleted file mode 100644 index b73547c84a7dea..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-02-11-48-08.bpo-36774.ZqbJ1J.rst +++ /dev/null @@ -1,7 +0,0 @@ -Add a ``=`` feature f-strings for debugging. This can precede ``!s``, -``!r``, or ``!a``. It produces the text of the expression, followed by -an equal sign, followed by the repr of the value of the expression. So -``f'{3*9+15=}'`` would be equal to the string ``'3*9+15=42'``. If -``=`` is specified, the default conversion is set to ``!r``, unless a -format spec is given, in which case the formatting behavior is -unchanged, and __format__ will be used. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-04-16-15-33.bpo-36793.Izog4Z.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-04-16-15-33.bpo-36793.Izog4Z.rst deleted file mode 100644 index 6c79f97dacac90..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-04-16-15-33.bpo-36793.Izog4Z.rst +++ /dev/null @@ -1,3 +0,0 @@ -Removed ``__str__`` implementations from builtin types :class:`bool`, -:class:`int`, :class:`float`, :class:`complex` and few classes from the -standard library. They now inherit ``__str__()`` from :class:`object`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-12-18-11.bpo-36737.XAo6LY.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-12-18-11.bpo-36737.XAo6LY.rst deleted file mode 100644 index 7a2c647dbff31e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-12-18-11.bpo-36737.XAo6LY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Move PyRuntimeState.warnings into per-interpreter state (via "module -state"). diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-15-49-17.bpo-27639.b1Ah87.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-15-49-17.bpo-27639.b1Ah87.rst deleted file mode 100644 index ae5b915969d3b5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-15-49-17.bpo-27639.b1Ah87.rst +++ /dev/null @@ -1,2 +0,0 @@ -Correct return type for UserList slicing operations. Patch by Michael Blahay, -Erick Cervantes, and vaultah diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst deleted file mode 100644 index 5e23d31a24855f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-16-50-12.bpo-36842.NYww_N.rst +++ /dev/null @@ -1 +0,0 @@ -Implement PEP 578, adding sys.audit, io.open_code and related APIs. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst deleted file mode 100644 index c264d21bd01610..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-07-17-12-37.bpo-34616.0Y0_9r.rst +++ /dev/null @@ -1 +0,0 @@ -The ``compile()`` builtin functions now support the ``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag, which allow to compile sources that contains top-level ``await``, ``async with`` or ``async for``. This is useful to evaluate async-code from with an already async functions; for example in a custom REPL. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-08-11-42-06.bpo-36851.J7DiCW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-08-11-42-06.bpo-36851.J7DiCW.rst deleted file mode 100644 index 9973e4ee71614c..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-08-11-42-06.bpo-36851.J7DiCW.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``FrameType`` stack is now correctly cleaned up if the execution ends -with a return and the stack is not empty. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst deleted file mode 100644 index 69017293649cd5..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-08-16-36-51.bpo-28866.qCv_bj.rst +++ /dev/null @@ -1,2 +0,0 @@ -Avoid caching attributes of classes which type defines mro() to avoid a hard -cache invalidation problem. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-08-20-42-40.bpo-36861.72mvZM.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-08-20-42-40.bpo-36861.72mvZM.rst deleted file mode 100644 index 79c339a779e8f0..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-08-20-42-40.bpo-36861.72mvZM.rst +++ /dev/null @@ -1 +0,0 @@ -Update the Unicode database to version 12.1.0. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst deleted file mode 100644 index 866309cddc682f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-12-18-46-50.bpo-36027.Q4YatQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Allow computation of modular inverses via three-argument ``pow``: the second -argument is now permitted to be negative in the case where the first and -third arguments are relatively prime. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-15-01-29-29.bpo-1875.9oxXFX.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-15-01-29-29.bpo-1875.9oxXFX.rst deleted file mode 100644 index 8f095ed9f16b12..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-15-01-29-29.bpo-1875.9oxXFX.rst +++ /dev/null @@ -1,3 +0,0 @@ -A :exc:`SyntaxError` is now raised if a code blocks that will be optimized -away (e.g. if conditions that are always false) contains syntax errors. -Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst deleted file mode 100644 index 5a1b51999f26fc..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-15-14-01-09.bpo-36826.GLrO3W.rst +++ /dev/null @@ -1 +0,0 @@ -Add NamedExpression kind support to ast_unparse.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-16-23-53-45.bpo-36946.qjxr0Y.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-16-23-53-45.bpo-36946.qjxr0Y.rst deleted file mode 100644 index aa5de80a294381..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-16-23-53-45.bpo-36946.qjxr0Y.rst +++ /dev/null @@ -1 +0,0 @@ -Fix possible signed integer overflow when handling slices. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst deleted file mode 100644 index ae502e83ef6843..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-17-12-28-24.bpo-36907.rk7kgp.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a crash when calling a C function with a keyword dict (``f(**kwargs)``) -and changing the dict ``kwargs`` while that function is running. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst deleted file mode 100644 index a2207c17aea0a8..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-17-18-34-30.bpo-2180.aBqHeW.rst +++ /dev/null @@ -1 +0,0 @@ -Treat line continuation at EOF as a ``SyntaxError`` by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst deleted file mode 100644 index 00c8b904ac2a41..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-21-16-21-22.bpo-36878.EFRHZ3.rst +++ /dev/null @@ -1,3 +0,0 @@ -Store text appearing after a `# type: ignore` comment in the AST. For -example a type ignore like `# type: ignore[E1000]` will have the string -`"[E1000]"` stored in its AST node. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst deleted file mode 100644 index 2d9f014119db8d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-22-11-16-16.bpo-36878.QwLa3P.rst +++ /dev/null @@ -1,2 +0,0 @@ -Only accept text after `# type: ignore` if the first character is ASCII. -This is to disallow things like `# type: ignoreé`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst deleted file mode 100644 index 957a4857e408f3..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-22-23-01-29.bpo-36829.MfOcUg.rst +++ /dev/null @@ -1,4 +0,0 @@ -:c:func:`PyErr_WriteUnraisable` now creates a traceback object if there is -no current traceback. Moreover, call :c:func:`PyErr_NormalizeException` and -:c:func:`PyException_SetTraceback` to normalize the exception value. Ignore any -error. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst deleted file mode 100644 index ac344a57c83d93..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-23-04-19-13.bpo-37007.d1SOtF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, and -:func:`socket.if_indextoname()` on Windows. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst deleted file mode 100644 index 7e31a84eb4688b..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-24-12-38-40.bpo-37032.T8rSH8.rst +++ /dev/null @@ -1 +0,0 @@ -Added new ``replace()`` method to the code type (:class:`types.CodeType`). diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst deleted file mode 100644 index bbf63ec82ca6cd..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-08-18-01.bpo-26836.rplYWW.rst +++ /dev/null @@ -1 +0,0 @@ -Add :func:`os.memfd_create`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst deleted file mode 100644 index e10690b3a560d7..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-25-17-18-26.bpo-22385.VeVvhJ.rst +++ /dev/null @@ -1,4 +0,0 @@ -The `bytes.hex`, `bytearray.hex`, and `memoryview.hex` methods as well as -the `binascii.hexlify` and `b2a_hex` functions now have the ability to -include an optional separator between hex bytes. This functionality was -inspired by MicroPython's hexlify implementation. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst deleted file mode 100644 index 0667c8ebd14898..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-27-14-46-24.bpo-37050.7MyZGg.rst +++ /dev/null @@ -1,4 +0,0 @@ -Improve the AST for "debug" f-strings, which use '=' to print out the source -of the expression being evaluated. Delete expr_text from the FormattedValue -node, and instead use a Constant string node (possibly merged with adjacent -constant expressions inside the f-string). diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst deleted file mode 100644 index 6bf2031a338488..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-27-18-00-19.bpo-26423.RgUOE8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix possible overflow in ``wrap_lenfunc()`` when -``sizeof(long) < sizeof(Py_ssize_t)`` (e.g., 64-bit Windows). diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst deleted file mode 100644 index c18f5d23eaa26f..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-17-02-46.bpo-37029.MxpgfJ.rst +++ /dev/null @@ -1 +0,0 @@ -Freeing a great many small objects could take time quadratic in the number of arenas, due to using linear search to keep ``obmalloc.c``'s list of usable arenas sorted by order of number of free memory pools. This is accomplished without search now, leaving the worst-case time linear in the number of arenas. For programs where this quite visibly matters (typically with more than 100 thousand small objects alive simultaneously), this can greatly reduce the time needed to release their memory. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst deleted file mode 100644 index 15bcc5ed2bb0ca..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-18-18-55.bpo-37072.1Hewl3.rst +++ /dev/null @@ -1 +0,0 @@ -Fix crash in PyAST_FromNodeObject() when flags is NULL. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst deleted file mode 100644 index a4ee7b580bc899..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-29-22-03-09.bpo-26219.Ovf1Qs.rst +++ /dev/null @@ -1,3 +0,0 @@ -Implemented per opcode cache mechanism and ``LOAD_GLOBAL`` instruction use -it. ``LOAD_GLOBAL`` is now about 40% faster. Contributed by Yury Selivanov, -and Inada Naoki. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst deleted file mode 100644 index a45330fed999f9..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-30-17-33-55.bpo-37087.vElenE.rst +++ /dev/null @@ -1 +0,0 @@ -Add native thread ID (TID) support to OpenBSD. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst deleted file mode 100644 index 7536dc33c9f196..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-31-11-55-49.bpo-20092.KIMjBW.rst +++ /dev/null @@ -1,4 +0,0 @@ -Constructors of :class:`int`, :class:`float` and :class:`complex` will now -use the :meth:`~object.__index__` special method, if available and the -corresponding method :meth:`~object.__int__`, :meth:`~object.__float__` -or :meth:`~object.__complex__` is not available. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst deleted file mode 100644 index b9584b50e61d95..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-01-16-53-41.bpo-37122.dZ3-NY.rst +++ /dev/null @@ -1,5 +0,0 @@ -Make the *co_argcount* attribute of code objects represent the total number -of positional arguments (including positional-only arguments). The value of -*co_posonlyargcount* can be used to distinguish which arguments are -positional only, and the difference (*co_argcount* - *co_posonlyargcount*) -is the number of positional-or-keyword arguments. Patch by Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst deleted file mode 100644 index 069b064dfa615d..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-01-20-03-13.bpo-37126.tP6lL4.rst +++ /dev/null @@ -1,2 +0,0 @@ -All structseq objects are now tracked by the garbage collector. Patch by -Pablo Galindo. diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst deleted file mode 100644 index 2b9f00a6d9e7cf..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-06-03-00-51-02.bpo-35814.Cf7sGY.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow unpacking in the right hand side of annotated assignments. In -particular, ``t: Tuple[int, ...] = x, y, *z`` is now allowed. diff --git a/Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst b/Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst deleted file mode 100644 index ebe0c3f95e45ab..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2017-12-08-20-30-37.bpo-20285.cfnp0J.rst +++ /dev/null @@ -1,3 +0,0 @@ -Expand object.__doc__ (docstring) to make it clearer. -Modify pydoc.py so that help(object) lists object methods -(for other classes, help omits methods of the object base class.) diff --git a/Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst b/Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst deleted file mode 100644 index 8d22cf69e170c8..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-04-08-19-09-22.bpo-25735.idVQBD.rst +++ /dev/null @@ -1 +0,0 @@ -Added documentation for func factorial to indicate that returns integer values diff --git a/Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst b/Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst deleted file mode 100644 index bda5be87723d45..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-05-13-10-36-37.bpo-33482.jalAaQ.rst +++ /dev/null @@ -1 +0,0 @@ -Make `codecs.StreamRecoder.writelines` take a list of bytes. diff --git a/Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst b/Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst deleted file mode 100644 index 0ee6c0d5f8eae7..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-05-17-21-02-00.bpo-33519.Q7s2FB.rst +++ /dev/null @@ -1 +0,0 @@ -Clarify that `copy()` is not part of the `MutableSequence` ABC. diff --git a/Misc/NEWS.d/next/Documentation/2018-10-07-03-04-57.bpo-32995.TXN9ur.rst b/Misc/NEWS.d/next/Documentation/2018-10-07-03-04-57.bpo-32995.TXN9ur.rst deleted file mode 100644 index 1df5eeaa965ac3..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2018-10-07-03-04-57.bpo-32995.TXN9ur.rst +++ /dev/null @@ -1 +0,0 @@ -Added the context variable in glossary. diff --git a/Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst b/Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst deleted file mode 100644 index 6dc7d3aebb1a44..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-01-09-17-56-35.bpo-35397.ZMreIz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove deprecation and document urllib.parse.unwrap(). Patch contributed by -Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst b/Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst deleted file mode 100644 index 67a4ed26bede37..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-02-21-18-13-50.bpo-22865.6hg6J8.rst +++ /dev/null @@ -1 +0,0 @@ -Add detail to the documentation on the `pty.spawn` function. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-05-05-07-58-50.bpo-36797.W1X4On.rst b/Misc/NEWS.d/next/Documentation/2019-05-05-07-58-50.bpo-36797.W1X4On.rst deleted file mode 100644 index 5ca55556c887e2..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-05-07-58-50.bpo-36797.W1X4On.rst +++ /dev/null @@ -1,3 +0,0 @@ -More of the legacy distutils documentation has been either pruned, or else -more clearly marked as being retained solely until the setuptools -documentation covers it independently. diff --git a/Misc/NEWS.d/next/Documentation/2019-05-07-02-30-51.bpo-36783.gpC8E2.rst b/Misc/NEWS.d/next/Documentation/2019-05-07-02-30-51.bpo-36783.gpC8E2.rst deleted file mode 100644 index d3cbf4f6e13e88..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-07-02-30-51.bpo-36783.gpC8E2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added C API Documentation for Time_FromTimeAndFold and PyDateTime_FromDateAndTimeAndFold as per PEP 495. -Patch by Edison Abahurire. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Documentation/2019-05-08-13-17-44.bpo-35924.lqbNpW.rst b/Misc/NEWS.d/next/Documentation/2019-05-08-13-17-44.bpo-35924.lqbNpW.rst deleted file mode 100644 index a88778f85cce7d..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-08-13-17-44.bpo-35924.lqbNpW.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add a note to the ``curses.addstr()`` documentation to warn that multiline -strings can cause segfaults because of an ncurses bug. diff --git a/Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst b/Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst deleted file mode 100644 index ad9ed5baf167e6..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-11-17-42-15.bpo-36868.yioL0R.rst +++ /dev/null @@ -1,2 +0,0 @@ -What's new now mentions SSLContext.hostname_checks_common_name instead of -SSLContext.host_flags. diff --git a/Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst b/Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst deleted file mode 100644 index b26eeadb924aa9..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-20-22-21-17.bpo-36984.IjZlmS.rst +++ /dev/null @@ -1 +0,0 @@ -Improve version added references in ``typing`` module - by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst b/Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst deleted file mode 100644 index 2ea42adf131735..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-27-17-28-58.bpo-36686.Zot4sx.rst +++ /dev/null @@ -1,6 +0,0 @@ -Improve documentation of the stdin, stdout, and stderr arguments of of the -``asyncio.subprocess_exec`` function to specficy which values are supported. -Also mention that decoding as text is not supported. - -Add a few tests to verify that the various values passed to the std* -arguments actually work. diff --git a/Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst b/Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst deleted file mode 100644 index d75fccad6c0ff1..00000000000000 --- a/Misc/NEWS.d/next/Documentation/2019-05-31-10-46-36.bpo-36896.wkXTW9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Clarify that some types have unstable constructor signature between Python -versions. diff --git a/Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst b/Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst deleted file mode 100644 index a5522012923a50..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2017-12-25-18-48-50.bpo-32411.vNwDhe.rst +++ /dev/null @@ -1,2 +0,0 @@ -In browser.py, remove extraneous sorting by line number since dictionary was -created in line number order. diff --git a/Misc/NEWS.d/next/IDLE/2019-05-05-16-27-53.bpo-13102.AGNWYJ.rst b/Misc/NEWS.d/next/IDLE/2019-05-05-16-27-53.bpo-13102.AGNWYJ.rst deleted file mode 100644 index 2a905bf0eecfd2..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-05-05-16-27-53.bpo-13102.AGNWYJ.rst +++ /dev/null @@ -1 +0,0 @@ -When saving a file, call os.fsync() so bits are flushed to e.g. USB drive. diff --git a/Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst b/Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst deleted file mode 100644 index c5a675d6781ae9..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-05-19-22-02-22.bpo-36958.DZUC6G.rst +++ /dev/null @@ -1,2 +0,0 @@ -Print any argument other than None or int passed to SystemExit or -sys.exit(). diff --git a/Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst b/Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst deleted file mode 100644 index 762e9f1e43749d..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-05-24-18-57-57.bpo-37038.AJ3RwQ.rst +++ /dev/null @@ -1 +0,0 @@ -Make idlelib.run runnable; add test clause. diff --git a/Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst b/Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst deleted file mode 100644 index 0042ab70497a3b..00000000000000 --- a/Misc/NEWS.d/next/IDLE/2019-06-02-14-10-52.bpo-35610.0w_v6Y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Replace now redundant .context_use_ps1 with .prompt_last_line. This finishes -change started in bpo-31858. diff --git a/Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst b/Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst deleted file mode 100644 index ec95320ab411fd..00000000000000 --- a/Misc/NEWS.d/next/Library/2016-07-27-11-06-43.bpo-23395.MuCEX9.rst +++ /dev/null @@ -1,2 +0,0 @@ -``_thread.interrupt_main()`` now avoids setting the Python error status -if the ``SIGINT`` signal is ignored or not handled by Python. diff --git a/Misc/NEWS.d/next/Library/2017-10-21-12-07-56.bpo-31829.6IhP-O.rst b/Misc/NEWS.d/next/Library/2017-10-21-12-07-56.bpo-31829.6IhP-O.rst deleted file mode 100644 index aefb8aec16fd11..00000000000000 --- a/Misc/NEWS.d/next/Library/2017-10-21-12-07-56.bpo-31829.6IhP-O.rst +++ /dev/null @@ -1,3 +0,0 @@ -``\r``, ``\0`` and ``\x1a`` (end-of-file on Windows) are now escaped in -protocol 0 pickles of Unicode strings. This allows to load them without loss -from files open in text mode in Python 2. diff --git a/Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst b/Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst deleted file mode 100644 index 76c2abbf82d689..00000000000000 --- a/Misc/NEWS.d/next/Library/2017-10-24-00-42-14.bpo-27141.zbAgSs.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added a ``__copy__()`` to ``collections.UserList`` and -``collections.UserDict`` in order to correctly implement shallow copying of -the objects. Patch by Bar Harel. diff --git a/Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst b/Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst deleted file mode 100644 index 4e1afa9a43eac5..00000000000000 --- a/Misc/NEWS.d/next/Library/2017-12-13-17-49-56.bpo-32299.eqAPWs.rst +++ /dev/null @@ -1,2 +0,0 @@ -Changed :func:`unittest.mock.patch.dict` to return the patched -dictionary when used as context manager. Patch by Vadim Tsander. diff --git a/Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst b/Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst deleted file mode 100644 index ad585b3ab5edfb..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-01-07-21-04-50.bpo-32515.D8_Wcb.rst +++ /dev/null @@ -1 +0,0 @@ -trace.py can now run modules via python3 -m trace -t --module module_name diff --git a/Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst b/Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst deleted file mode 100644 index ad690f57c52384..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-08-16-15-00.bpo-22102.th33uD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added support for ZIP files with disks set to 0. Such files are commonly created by builtin tools on Windows when use ZIP64 extension. -Patch by Francisco Facioni. diff --git a/Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst b/Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst deleted file mode 100644 index f7668aecda6b50..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-20-20-57-00.bpo-32941.9FU0gL.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow :class:`mmap.mmap` objects to access the madvise() system call -(through :meth:`mmap.mmap.madvise`). diff --git a/Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst b/Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst deleted file mode 100644 index 8803ca84313122..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-22-19-13-19.bpo-33123._Y5ooE.rst +++ /dev/null @@ -1,2 +0,0 @@ -:class:`pathlib.Path.unlink` now accepts a *missing_ok* parameter to avoid a -:exc:`FileNotFoundError` from being raised. Patch by Robert Buchholz. diff --git a/Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst b/Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst deleted file mode 100644 index a38db6790f47ec..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-03-27-13-28-16.bpo-31961.GjLoYu.rst +++ /dev/null @@ -1,6 +0,0 @@ -Added support for bytes and path-like objects in :func:`subprocess.Popen` -on Windows. The *args* parameter now accepts a :term:`path-like object` if -*shell* is ``False`` and a sequence containing bytes and path-like objects. -The *executable* parameter now accepts a bytes and :term:`path-like object`. -The *cwd* parameter now accepts a bytes object. -Based on patch by Anders Lorentsen. diff --git a/Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst b/Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst deleted file mode 100644 index 8c418824a99d96..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-04-04-14-54-30.bpo-24882.urybpa.rst +++ /dev/null @@ -1 +0,0 @@ -Change ThreadPoolExecutor to use existing idle threads before spinning up new ones. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2018-05-30-01-05-50.bpo-31922.fobsXJ.rst b/Misc/NEWS.d/next/Library/2018-05-30-01-05-50.bpo-31922.fobsXJ.rst deleted file mode 100644 index df3881bffaaa38..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-05-30-01-05-50.bpo-31922.fobsXJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -:meth:`asyncio.AbstractEventLoop.create_datagram_endpoint`: -Do not connect UDP socket when broadcast is allowed. -This allows to receive replies after a UDP broadcast. diff --git a/Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst b/Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst deleted file mode 100644 index 2f30e5c893cfb4..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-06-10-17-48-07.bpo-22454.qeiy_X.rst +++ /dev/null @@ -1,2 +0,0 @@ -The :mod:`shlex` module now exposes :func:`shlex.join`, the inverse of -:func:`shlex.split`. Patch by Bo Bayles. diff --git a/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst b/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst deleted file mode 100644 index 2b71095984a09e..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug in :class:`codecs.StreamRecoder` where seeking might leave old data in a -buffer and break subsequent read calls. Patch by Ammar Askar. diff --git a/Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst b/Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst deleted file mode 100644 index 94c1299e5956b0..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-08-03-09-47-20.bpo-34303.tOE2HP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Performance of :func:`functools.reduce` is slightly improved. Patch by -Sergey Fedoseev. diff --git a/Misc/NEWS.d/next/Library/2018-08-18-14-47-00.bpo-34424.wAlRuS.rst b/Misc/NEWS.d/next/Library/2018-08-18-14-47-00.bpo-34424.wAlRuS.rst deleted file mode 100644 index 2b384cd5513fca..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-08-18-14-47-00.bpo-34424.wAlRuS.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix serialization of messages containing encoded strings when the -policy.linesep is set to a multi-character string. Patch by Jens Troeger. diff --git a/Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst b/Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst deleted file mode 100644 index adafa2803ae399..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-08-28-03-00-12.bpo-33569.45YlGG.rst +++ /dev/null @@ -1 +0,0 @@ -dataclasses.InitVar: Exposes the type used to create the init var. diff --git a/Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst b/Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst deleted file mode 100644 index 4cf3f2ae7ef7e6..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-09-13-20-33-24.bpo-26467.cahAk3.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added AsyncMock to support using unittest to mock asyncio coroutines. -Patch by Lisa Roach. diff --git a/Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst b/Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst deleted file mode 100644 index 344388f7f2287f..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-10-21-17-39-32.bpo-34271.P15VLM.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add debugging helpers to ssl module. It's now possible to dump key material -and to trace TLS protocol. The default and stdlib contexts also support -SSLKEYLOGFILE env var. diff --git a/Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst b/Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst deleted file mode 100644 index 4448bf6b0164d0..00000000000000 --- a/Misc/NEWS.d/next/Library/2018-11-04-16-39-46.bpo-26660.RdXz8a.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fixed permission errors in :class:`~tempfile.TemporaryDirectory` clean up. -Previously ``TemporaryDirectory.cleanup()`` failed when non-writeable or -non-searchable files or directories were created inside a temporary -directory. diff --git a/Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst b/Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst deleted file mode 100644 index 34687bdb8a251f..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-01-02-19-48-23.bpo-35431.FhG6QA.rst +++ /dev/null @@ -1,4 +0,0 @@ -Implement :func:`math.comb` that returns binomial coefficient, that computes -the number of ways to choose k items from n items without repetition and -without order. -Patch by Yash Aggarwal and Keller Fuchs. diff --git a/Misc/NEWS.d/next/Library/2019-01-11-17-09-15.bpo-31855.PlhfsX.rst b/Misc/NEWS.d/next/Library/2019-01-11-17-09-15.bpo-31855.PlhfsX.rst deleted file mode 100644 index 0da9c4997e1aa1..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-01-11-17-09-15.bpo-31855.PlhfsX.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`unittest.mock.mock_open` results now respects the argument of read([size]). -Patch contributed by Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst b/Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst deleted file mode 100644 index 5af4b1b8999419..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-01-18-16-23-00.bpo-35721.d8djAJ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix :meth:`asyncio.SelectorEventLoop.subprocess_exec()` leaks file descriptors -if ``Popen`` fails and called with ``stdin=subprocess.PIPE``. -Patch by Niklas Fiekas. diff --git a/Misc/NEWS.d/next/Library/2019-02-15-17-18-50.bpo-35125.h0xk0f.rst b/Misc/NEWS.d/next/Library/2019-02-15-17-18-50.bpo-35125.h0xk0f.rst deleted file mode 100644 index 2e28a25d2415a2..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-02-15-17-18-50.bpo-35125.h0xk0f.rst +++ /dev/null @@ -1 +0,0 @@ -Asyncio: Remove inner callback on outer cancellation in shield diff --git a/Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst b/Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst deleted file mode 100644 index 319c0a319f8c34..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-01-17-59-39.bpo-31904.38djdk.rst +++ /dev/null @@ -1 +0,0 @@ -Add posix module support for VxWorks. diff --git a/Misc/NEWS.d/next/Library/2019-03-04-01-28-33.bpo-26707.QY4kRZ.rst b/Misc/NEWS.d/next/Library/2019-03-04-01-28-33.bpo-26707.QY4kRZ.rst deleted file mode 100644 index ab76540c9eec64..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-04-01-28-33.bpo-26707.QY4kRZ.rst +++ /dev/null @@ -1 +0,0 @@ -Enable plistlib to read and write binary plist files that were created as a KeyedArchive file. Specifically, this allows the plistlib to process 0x80 tokens as UID objects. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-03-09-23-51-27.bpo-36239.BHJ3Ln.rst b/Misc/NEWS.d/next/Library/2019-03-09-23-51-27.bpo-36239.BHJ3Ln.rst deleted file mode 100644 index 3a742029151378..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-09-23-51-27.bpo-36239.BHJ3Ln.rst +++ /dev/null @@ -1 +0,0 @@ -Parsing .mo files now ignores comments starting and ending with #-#-#-#-#. diff --git a/Misc/NEWS.d/next/Library/2019-03-13-10-57-41.bpo-27497.JDmIe_.rst b/Misc/NEWS.d/next/Library/2019-03-13-10-57-41.bpo-27497.JDmIe_.rst deleted file mode 100644 index f6da1143681af3..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-13-10-57-41.bpo-27497.JDmIe_.rst +++ /dev/null @@ -1,3 +0,0 @@ -:meth:`csv.DictWriter.writeheader` now returns the return value of the -underlying :meth:`csv.Writer.writerow` method. Patch contributed by Ashish -Nitin Patil. diff --git a/Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst b/Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst deleted file mode 100644 index fd82fe086f068f..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-18-14-25-36.bpo-31904.ds3d67.rst +++ /dev/null @@ -1 +0,0 @@ -Fix mmap fail for VxWorks diff --git a/Misc/NEWS.d/next/Library/2019-03-21-16-00-00.bpo-36368.zsRT1.rst b/Misc/NEWS.d/next/Library/2019-03-21-16-00-00.bpo-36368.zsRT1.rst deleted file mode 100644 index d8426827cedf04..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-21-16-00-00.bpo-36368.zsRT1.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix a bug crashing SharedMemoryManager instances in interactive sessions after -a ctrl-c (KeyboardInterrupt) was sent diff --git a/Misc/NEWS.d/next/Library/2019-03-22-22-40-00.bpo-35900.oiee0o.rst b/Misc/NEWS.d/next/Library/2019-03-22-22-40-00.bpo-35900.oiee0o.rst deleted file mode 100644 index 641572649694ae..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-22-22-40-00.bpo-35900.oiee0o.rst +++ /dev/null @@ -1,2 +0,0 @@ -enable custom reduction callback registration for functions and classes in -_pickle.c, using the new Pickler's attribute ``reducer_override`` diff --git a/Misc/NEWS.d/next/Library/2019-03-27-15-09-00.bpo-35900.fh56UU.rst b/Misc/NEWS.d/next/Library/2019-03-27-15-09-00.bpo-35900.fh56UU.rst deleted file mode 100644 index 7f3a0675cdab94..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-03-27-15-09-00.bpo-35900.fh56UU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Allow reduction methods to return a 6-item tuple where the 6th item specifies a -custom state-setting method that's called instead of the regular -``__setstate__`` method. diff --git a/Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst b/Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst deleted file mode 100644 index c8f3e7d5f5fb18..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-02-19-23-12.bpo-35252.VooTVv.rst +++ /dev/null @@ -1 +0,0 @@ -Throw a TypeError instead of an AssertionError when using an invalid type annotation with singledispatch. diff --git a/Misc/NEWS.d/next/Library/2019-04-06-00-55-09.bpo-36533.kzMyRH.rst b/Misc/NEWS.d/next/Library/2019-04-06-00-55-09.bpo-36533.kzMyRH.rst deleted file mode 100644 index 15c4222d48374d..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-06-00-55-09.bpo-36533.kzMyRH.rst +++ /dev/null @@ -1,6 +0,0 @@ -Reinitialize logging.Handler locks in forked child processes instead of -attempting to acquire them all in the parent before forking only to be -released in the child process. The acquire/release pattern was leading to -deadlocks in code that has implemented any form of chained logging handlers -that depend upon one another as the lock acquision order cannot be -guaranteed. diff --git a/Misc/NEWS.d/next/Library/2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst b/Misc/NEWS.d/next/Library/2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst deleted file mode 100644 index 8374776e61eb8e..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-06-12-36-09.bpo-36542.Q0qyYV.rst +++ /dev/null @@ -1,2 +0,0 @@ -The signature of Python functions can now be overridden by specifying the -``__text_signature__`` attribute. diff --git a/Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst b/Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst deleted file mode 100644 index e72bb91174048e..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-07-14-30-10.bpo-36548.CJQiYw.rst +++ /dev/null @@ -1 +0,0 @@ -Improved the repr of regular expression flags. diff --git a/Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst b/Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst deleted file mode 100644 index 1d19f191eeded5..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-22-22-55-29.bpo-29183.MILvsk.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix double exceptions in :class:`wsgiref.handlers.BaseHandler` by calling -its :meth:`~wsgiref.handlers.BaseHandler.close` method only when no -exception is raised. diff --git a/Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst b/Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst deleted file mode 100644 index 8ac6be92044317..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-26-22-13-26.bpo-22640.p3rheW.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`py_compile.compile` now supports silent mode. -Patch by Joannah Nanjekye \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst b/Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst deleted file mode 100644 index e94d0a68d465ed..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-27-02-54-23.bpo-8138.osBRGI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Don't mark ``wsgiref.simple_server.SimpleServer`` as multi-threaded since -``wsgiref.simple_server.WSGIServer`` is single-threaded. diff --git a/Misc/NEWS.d/next/Library/2019-04-29-15-18-13.bpo-36748.YBKWps.rst b/Misc/NEWS.d/next/Library/2019-04-29-15-18-13.bpo-36748.YBKWps.rst deleted file mode 100644 index 0eacc3c99cd9f0..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-29-15-18-13.bpo-36748.YBKWps.rst +++ /dev/null @@ -1,3 +0,0 @@ -Optimized write buffering in C implementation of ``TextIOWrapper``. Writing -ASCII string to ``TextIOWrapper`` with ascii, latin1, or utf-8 encoding is -about 20% faster. Patch by Inada Naoki. diff --git a/Misc/NEWS.d/next/Library/2019-04-30-04-34-53.bpo-6584.Hzp9-P.rst b/Misc/NEWS.d/next/Library/2019-04-30-04-34-53.bpo-6584.Hzp9-P.rst deleted file mode 100644 index 3a0943800b00e2..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-04-30-04-34-53.bpo-6584.Hzp9-P.rst +++ /dev/null @@ -1 +0,0 @@ -Add a :exc:`~gzip.BadGzipFile` exception to the :mod:`gzip` module. diff --git a/Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst b/Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst deleted file mode 100644 index 00b8a684f9a7ac..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-01-20-41-53.bpo-36772.fV2K0F.rst +++ /dev/null @@ -1,2 +0,0 @@ -functools.lru_cache() can now be used as a straight decorator in -addition to its existing usage as a function that returns a decorator. diff --git a/Misc/NEWS.d/next/Library/2019-05-03-20-47-55.bpo-36785.PQLnPq.rst b/Misc/NEWS.d/next/Library/2019-05-03-20-47-55.bpo-36785.PQLnPq.rst deleted file mode 100644 index 0a86054bbe869c..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-03-20-47-55.bpo-36785.PQLnPq.rst +++ /dev/null @@ -1 +0,0 @@ -Implement PEP 574 (pickle protocol 5 with out-of-band buffers). diff --git a/Misc/NEWS.d/next/Library/2019-05-05-09-45-44.bpo-36801.XrlFFs.rst b/Misc/NEWS.d/next/Library/2019-05-05-09-45-44.bpo-36801.XrlFFs.rst deleted file mode 100644 index 43e51fe5ca94d5..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-05-09-45-44.bpo-36801.XrlFFs.rst +++ /dev/null @@ -1 +0,0 @@ -Properly handle SSL connection closing in asyncio StreamWriter.drain() call. diff --git a/Misc/NEWS.d/next/Library/2019-05-05-10-12-23.bpo-36802.HYMc8P.rst b/Misc/NEWS.d/next/Library/2019-05-05-10-12-23.bpo-36802.HYMc8P.rst deleted file mode 100644 index f59863b7b7a837..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-05-10-12-23.bpo-36802.HYMc8P.rst +++ /dev/null @@ -1,2 +0,0 @@ -Provide both sync and async calls for StreamWriter.write() and -StreamWriter.close() diff --git a/Misc/NEWS.d/next/Library/2019-05-05-16-14-38.bpo-36806.rAzF-x.rst b/Misc/NEWS.d/next/Library/2019-05-05-16-14-38.bpo-36806.rAzF-x.rst deleted file mode 100644 index 7e3ff6cf0e1442..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-05-16-14-38.bpo-36806.rAzF-x.rst +++ /dev/null @@ -1,2 +0,0 @@ -Forbid creation of asyncio stream objects like StreamReader, StreamWriter, -Process, and their protocols outside of asyncio package. diff --git a/Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst b/Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst deleted file mode 100644 index e89358aa40512d..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-06-18-28-38.bpo-36813.NXD0KZ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :class:`~logging.handlers.QueueListener` to call ``queue.task_done()`` -upon stopping. Patch by Bar Harel. diff --git a/Misc/NEWS.d/next/Library/2019-05-06-19-17-04.bpo-26903.4payXb.rst b/Misc/NEWS.d/next/Library/2019-05-06-19-17-04.bpo-26903.4payXb.rst deleted file mode 100644 index ec3aa05e907e95..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-06-19-17-04.bpo-26903.4payXb.rst +++ /dev/null @@ -1 +0,0 @@ -Limit `max_workers` in `ProcessPoolExecutor` to 61 to work around a WaitForMultipleObjects limitation. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst b/Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst deleted file mode 100644 index f1e2460c4927c8..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-06-22-34-47.bpo-33110.rSJSCh.rst +++ /dev/null @@ -1 +0,0 @@ -Handle exceptions raised by functions added by concurrent.futures add_done_callback correctly when the Future has already completed. diff --git a/Misc/NEWS.d/next/Library/2019-05-06-23-13-26.bpo-36814.dSeMz_.rst b/Misc/NEWS.d/next/Library/2019-05-06-23-13-26.bpo-36814.dSeMz_.rst deleted file mode 100644 index 3f40011b2650b7..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-06-23-13-26.bpo-36814.dSeMz_.rst +++ /dev/null @@ -1 +0,0 @@ -Fix an issue where os.posix_spawnp() would incorrectly raise a TypeError when file_actions is None. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-07-15-00-45.bpo-36832.TExgqb.rst b/Misc/NEWS.d/next/Library/2019-05-07-15-00-45.bpo-36832.TExgqb.rst deleted file mode 100644 index 23577d9b5a829f..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-07-15-00-45.bpo-36832.TExgqb.rst +++ /dev/null @@ -1 +0,0 @@ -Introducing ``zipfile.Path``, a pathlib-compatible wrapper for traversing zip files. diff --git a/Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst b/Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst deleted file mode 100644 index 0b04efcb7e2f0e..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-08-12-51-37.bpo-36829.8enFMA.rst +++ /dev/null @@ -1,5 +0,0 @@ -Add new :func:`sys.unraisablehook` function which can be overridden to -control how "unraisable exceptions" are handled. It is called when an -exception has occurred but there is no way for Python to handle it. For -example, when a destructor raises an exception or during garbage collection -(:func:`gc.collect`). diff --git a/Misc/NEWS.d/next/Library/2019-05-09-08-35-18.bpo-24538.WK8Y-k.rst b/Misc/NEWS.d/next/Library/2019-05-09-08-35-18.bpo-24538.WK8Y-k.rst deleted file mode 100644 index e799f931bcec56..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-09-08-35-18.bpo-24538.WK8Y-k.rst +++ /dev/null @@ -1,3 +0,0 @@ -In `shutil.copystat()`, first copy extended file attributes and then file -permissions, since extended attributes can only be set on the destination -while it is still writeable. diff --git a/Misc/NEWS.d/next/Library/2019-05-09-12-38-40.bpo-30262.Tu74ak.rst b/Misc/NEWS.d/next/Library/2019-05-09-12-38-40.bpo-30262.Tu74ak.rst deleted file mode 100644 index 059bd717837f57..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-09-12-38-40.bpo-30262.Tu74ak.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``Cache`` and ``Statement`` objects of the :mod:`sqlite3` module are not -exposed to the user. Patch by Aviv Palivoda. diff --git a/Misc/NEWS.d/next/Library/2019-05-09-18-12-55.bpo-36867.FuwVTi.rst b/Misc/NEWS.d/next/Library/2019-05-09-18-12-55.bpo-36867.FuwVTi.rst deleted file mode 100644 index 5eaf0a032cc3c2..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-09-18-12-55.bpo-36867.FuwVTi.rst +++ /dev/null @@ -1 +0,0 @@ -The multiprocessing.resource_tracker replaces the multiprocessing.semaphore_tracker module. Other than semaphores, resource_tracker also tracks shared_memory segments. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-10-01-06-36.bpo-36778.GRqeiS.rst b/Misc/NEWS.d/next/Library/2019-05-10-01-06-36.bpo-36778.GRqeiS.rst deleted file mode 100644 index 5e594a33447cd2..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-10-01-06-36.bpo-36778.GRqeiS.rst +++ /dev/null @@ -1,2 +0,0 @@ -``cp65001`` encoding (Windows code page 65001) becomes an alias to ``utf_8`` -encoding. diff --git a/Misc/NEWS.d/next/Library/2019-05-10-22-00-06.bpo-36878.iigeqk.rst b/Misc/NEWS.d/next/Library/2019-05-10-22-00-06.bpo-36878.iigeqk.rst deleted file mode 100644 index 20b44dcbf13fce..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-10-22-00-06.bpo-36878.iigeqk.rst +++ /dev/null @@ -1,4 +0,0 @@ -When using `type_comments=True` in `ast.parse`, treat `# type: ignore` followed by -a non-alphanumeric character and then arbitrary text as a type ignore, instead of -requiring nothing but whitespace or another comment. This is to permit formations -such as `# type: ignore[E1000]`. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst b/Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst deleted file mode 100644 index ab4433846d4f7f..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-11-02-30-45.bpo-34632.8MXa7T.rst +++ /dev/null @@ -1 +0,0 @@ -Introduce the ``importlib.metadata`` module with (provisional) support for reading metadata from third-party packages. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst b/Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst deleted file mode 100644 index fe2929cea85a9b..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-11-14-50-59.bpo-36887.XD3f22.rst +++ /dev/null @@ -1 +0,0 @@ -Add new function :func:`math.isqrt` to compute integer square roots. diff --git a/Misc/NEWS.d/next/Library/2019-05-11-16-21-29.bpo-35545.FcvJvP.rst b/Misc/NEWS.d/next/Library/2019-05-11-16-21-29.bpo-35545.FcvJvP.rst deleted file mode 100644 index f4349afefcd8e2..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-11-16-21-29.bpo-35545.FcvJvP.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix asyncio discarding IPv6 scopes when ensuring hostname resolutions -internally diff --git a/Misc/NEWS.d/next/Library/2019-05-12-14-49-13.bpo-36895.ZZuuY7.rst b/Misc/NEWS.d/next/Library/2019-05-12-14-49-13.bpo-36895.ZZuuY7.rst deleted file mode 100644 index f6708abfc860a6..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-12-14-49-13.bpo-36895.ZZuuY7.rst +++ /dev/null @@ -1,2 +0,0 @@ -The function ``time.clock()`` was deprecated in 3.3 in favor of -``time.perf_counter()`` and marked for removal in 3.8, it has removed. diff --git a/Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst b/Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst deleted file mode 100644 index 3c154822c9acdb..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-13-05-49-15.bpo-23896.8TtUKo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Adds a grammar to lib2to3.pygram that contains exec as a function not as -statement. diff --git a/Misc/NEWS.d/next/Library/2019-05-13-13-02-43.bpo-36867.Qh-6mX.rst b/Misc/NEWS.d/next/Library/2019-05-13-13-02-43.bpo-36867.Qh-6mX.rst deleted file mode 100644 index ce925d0594bb5d..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-13-13-02-43.bpo-36867.Qh-6mX.rst +++ /dev/null @@ -1 +0,0 @@ -Fix a bug making a SharedMemoryManager instance and its parent process use two separate resource_tracker processes. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst b/Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst deleted file mode 100644 index c7c3f174d637e4..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-14-05-38-22.bpo-23378.R25teI.rst +++ /dev/null @@ -1 +0,0 @@ -Add an extend action to argparser. diff --git a/Misc/NEWS.d/next/Library/2019-05-14-07-57-02.bpo-36845._GtFFf.rst b/Misc/NEWS.d/next/Library/2019-05-14-07-57-02.bpo-36845._GtFFf.rst deleted file mode 100644 index c819dce3a57c8e..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-14-07-57-02.bpo-36845._GtFFf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Added validation of integer prefixes to the construction of IP networks and -interfaces in the ipaddress module. diff --git a/Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst b/Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst deleted file mode 100644 index d08c0e287edfb4..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-14-12-25-44.bpo-36889.MChPqP.rst +++ /dev/null @@ -1,6 +0,0 @@ -Introduce :class:`asyncio.Stream` class that merges :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter` functionality. -:class:`asyncio.Stream` can work in readonly, writeonly and readwrite modes. -Provide :func:`asyncio.connect`, :func:`asyncio.connect_unix`, :func:`asyncio.connect_read_pipe` and :func:`asyncio.connect_write_pipe` factories to open :class:`asyncio.Stream` connections. Provide :class:`asyncio.StreamServer` and :class:`UnixStreamServer` to serve servers with asyncio.Stream API. -Modify :func:`asyncio.create_subprocess_shell` and :func:`asyncio.create_subprocess_exec` to use :class:`asyncio.Stream` instead of deprecated :class:`StreamReader` and :class:`StreamWriter`. -Deprecate :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter`. -Deprecate usage of private classes, e.g. :class:`asyncio.FlowControlMixing` and :class:`asyncio.StreamReaderProtocol` outside of asyncio package. diff --git a/Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst b/Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst deleted file mode 100644 index 8726bb241f23a2..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst +++ /dev/null @@ -1,2 +0,0 @@ -Remove a message about an unhandled exception in a task when writer.write() -is used without await and writer.drain() fails with an exception. diff --git a/Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst b/Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst deleted file mode 100644 index 421fccfe8c73a6..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-14-21-39-52.bpo-25652.xLw42k.rst +++ /dev/null @@ -1 +0,0 @@ -Fix bug in ``__rmod__`` of ``UserString`` - by Batuhan Taskaya. diff --git a/Misc/NEWS.d/next/Library/2019-05-15-21-35-23.bpo-36921.kA1306.rst b/Misc/NEWS.d/next/Library/2019-05-15-21-35-23.bpo-36921.kA1306.rst deleted file mode 100644 index b443b379d8f7ca..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-15-21-35-23.bpo-36921.kA1306.rst +++ /dev/null @@ -1 +0,0 @@ -Deprecate ``@coroutine`` for sake of ``async def``. diff --git a/Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst b/Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst deleted file mode 100644 index e7b54677280c9f..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-16-18-02-08.bpo-36888.-H2Dkm.rst +++ /dev/null @@ -1,2 +0,0 @@ -Python child processes can now access the status of their parent process -using multiprocessing.process.parent_process diff --git a/Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst b/Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst deleted file mode 100644 index 27cb6178b54e46..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-16-23-40-36.bpo-24564.lIwV_7.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`shutil.copystat` now ignores :const:`errno.EINVAL` on :func:`os.setxattr` which may occur when copying files on filesystems without extended attributes support. - -Original patch by Giampaolo Rodola, updated by Ying Wang. diff --git a/Misc/NEWS.d/next/Library/2019-05-17-11-44-21.bpo-33524.8y_xUU.rst b/Misc/NEWS.d/next/Library/2019-05-17-11-44-21.bpo-33524.8y_xUU.rst deleted file mode 100644 index bfeab7231bdb79..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-17-11-44-21.bpo-33524.8y_xUU.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix the folding of email header when the max_line_length is 0 or None and the -header contains non-ascii characters. Contributed by Licht Takeuchi -(@Licht-T). diff --git a/Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst b/Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst deleted file mode 100644 index c8cfa54067fd35..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-17-21-42-58.bpo-36948.vnUDvk.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix :exc:`NameError` in :meth:`urllib.request.URLopener.retrieve`. Patch by -Karthikeyan Singaravelan. diff --git a/Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst b/Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst deleted file mode 100644 index e4eeb4010a231d..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-19-06-54-26.bpo-36949.jBlG9F.rst +++ /dev/null @@ -1 +0,0 @@ -Implement __repr__ for WeakSet objects. diff --git a/Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst b/Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst deleted file mode 100644 index eeb4fd71e67bf5..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-20-08-54-41.bpo-36952.I_glok.rst +++ /dev/null @@ -1,5 +0,0 @@ -Starting with Python 3.3, importing ABCs from :mod:`collections` is -deprecated, and import should be done from :mod:`collections.abc`. Still -being able to import from :mod:`collections` was marked for removal in 3.8, -but has been delayed to 3.9; documentation and ``DeprecationWarning`` -clarified. diff --git a/Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst b/Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst deleted file mode 100644 index f5ce2aadf4a18c..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-20-11-01-28.bpo-36952.MgZi7-.rst +++ /dev/null @@ -1,4 +0,0 @@ -:func:`fileinput.input` and :class:`fileinput.FileInput` **bufsize** -argument has been removed (was deprecated and ignored since Python 3.6), -and as a result the **mode** and **openhook** arguments have been made -keyword-only. diff --git a/Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst b/Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst deleted file mode 100644 index c8c47cd7763554..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-20-14-47-55.bpo-32972.LoeUNh.rst +++ /dev/null @@ -1 +0,0 @@ -Implement ``unittest.AsyncTestCase`` to help testing asyncio-based code. diff --git a/Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst b/Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst deleted file mode 100644 index da650e8944dfc7..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-20-17-08-26.bpo-36972.3l3SGc.rst +++ /dev/null @@ -1 +0,0 @@ -Add SupportsIndex protocol to the typing module to allow type checking to detect classes that can be passed to `hex()`, `oct()` and `bin()`. diff --git a/Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst b/Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst deleted file mode 100644 index bd2d91ad9234e3..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-20-20-41-30.bpo-36983.hz-fLr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add missing names to ``typing.__all__``: ``ChainMap``, ``ForwardRef``, -``OrderedDict`` - by Anthony Sottile. diff --git a/Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst b/Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst deleted file mode 100644 index 9253ab92f1fb6e..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-20-23-31-20.bpo-36969.JkZORP.rst +++ /dev/null @@ -1,2 +0,0 @@ -PDB command `args` now display keyword only arguments. Patch contributed by -Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst b/Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst deleted file mode 100644 index 1823a4dcc2492b..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-21-12-31-21.bpo-36969.u7cxu7.rst +++ /dev/null @@ -1,2 +0,0 @@ -PDB command `args` now display positional only arguments. Patch contributed -by Rémi Lapeyre. diff --git a/Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst b/Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst deleted file mode 100644 index 02d0ef891becde..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-22-02-25-31.bpo-27737.7bgKpa.rst +++ /dev/null @@ -1,2 +0,0 @@ -Allow whitespace only header encoding in ``email.header`` - by Batuhan -Taskaya diff --git a/Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst b/Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst deleted file mode 100644 index 42747aead49a49..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-22-15-26-08.bpo-37008.WPbv31.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add support for calling :func:`next` with the mock resulting from -:func:`unittest.mock.mock_open` diff --git a/Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst b/Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst deleted file mode 100644 index 69d18d9713b4f7..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-22-22-55-18.bpo-36996.XQx08d.rst +++ /dev/null @@ -1 +0,0 @@ -Handle :func:`unittest.mock.patch` used as a decorator on async functions. diff --git a/Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst b/Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst deleted file mode 100644 index 250a64237d1822..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-23-01-48-39.bpo-1230540.oKTNEQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add a new :func:`threading.excepthook` function which handles uncaught -:meth:`threading.Thread.run` exception. It can be overridden to control how -uncaught :meth:`threading.Thread.run` exceptions are handled. diff --git a/Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst b/Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst deleted file mode 100644 index 375f426025d325..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-23-17-37-22.bpo-32528.sGnkcl.rst +++ /dev/null @@ -1,8 +0,0 @@ -Make asyncio.CancelledError a BaseException. - -This will address the common mistake many asyncio users make: an "except -Exception" clause breaking Tasks cancellation. - -In addition to this change, we stop inheriting asyncio.TimeoutError and -asyncio.InvalidStateError from their concurrent.futures.* counterparts. -There's no point for these exceptions to share the inheritance chain. diff --git a/Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst b/Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst deleted file mode 100644 index 60b513d6ea3aaf..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-23-18-46-56.bpo-37027.iH4eut.rst +++ /dev/null @@ -1,2 +0,0 @@ -Return safe to use proxy socket object from -transport.get_extra_info('socket') diff --git a/Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst b/Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst deleted file mode 100644 index d9db21fb6f3c96..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-23-18-57-34.bpo-37028.Vse6Pj.rst +++ /dev/null @@ -1 +0,0 @@ -Implement asyncio REPL diff --git a/Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst b/Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst deleted file mode 100644 index 5bcd7a9976c553..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-23-21-10-57.bpo-37001.DoLvTK.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`symtable.symtable` now accepts the same input types for source code as the -built-in :func:`compile` function. Patch by Dino Viehland. diff --git a/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst b/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst deleted file mode 100644 index 004ec2d1371401..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-24-18-16-07.bpo-37035.HFbJVT.rst +++ /dev/null @@ -1,5 +0,0 @@ -Don't log OSError based exceptions if a fatal error has occurred in asyncio -transport. Peer can generate almost any OSError, user cannot avoid these exceptions -by fixing own code. -Errors are still propagated to user code, it's just logging them -is pointless and pollute asyncio logs. diff --git a/Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst b/Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst deleted file mode 100644 index 001529ed6db43c..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-25-18-36-50.bpo-37045.suHdVJ.rst +++ /dev/null @@ -1 +0,0 @@ -PEP 591: Add ``Final`` qualifier and ``@final`` decorator to the ``typing`` module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst b/Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst deleted file mode 100644 index 9ec333b2d980f9..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-25-19-12-53.bpo-37046.iuhQQj.rst +++ /dev/null @@ -1 +0,0 @@ -PEP 586: Add ``Literal`` to the ``typing`` module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst b/Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst deleted file mode 100644 index e0ce4a708d9eb7..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-25-19-48-42.bpo-37049.an2LXJ.rst +++ /dev/null @@ -1 +0,0 @@ -PEP 589: Add ``TypedDict`` to the ``typing`` module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst b/Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst deleted file mode 100644 index ace5a3a4417895..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-26-01-20-06.bpo-37047.K9epi8.rst +++ /dev/null @@ -1,3 +0,0 @@ -Handle late binding and attribute access in :class:`unittest.mock.AsyncMock` -setup for autospeccing. Document newly implemented async methods in -:class:`unittest.mock.MagicMock`. diff --git a/Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst b/Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst deleted file mode 100644 index dc2be7a140cf78..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-26-10-16-55.bpo-36933.4w3eP9.rst +++ /dev/null @@ -1,2 +0,0 @@ -The functions ``sys.set_coroutine_wrapper`` and ``sys.get_coroutine_wrapper`` -that were deprecated and marked for removal in 3.8 have been removed. diff --git a/Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst b/Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst deleted file mode 100644 index 329b82c12adfb4..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-26-19-05-24.bpo-37058.jmRu_g.rst +++ /dev/null @@ -1 +0,0 @@ -PEP 544: Add ``Protocol`` and ``@runtime_checkable`` to the ``typing`` module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst b/Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst deleted file mode 100644 index 9a2433abd0d000..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-01-06-44.bpo-37054.sLULGQ.rst +++ /dev/null @@ -1,3 +0,0 @@ -Fix destructor :class:`_pyio.BytesIO` and :class:`_pyio.TextIOWrapper`: -initialize their ``_buffer`` attribute as soon as possible (in the class -body), because it's used by ``__del__()`` which calls ``close()``. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst b/Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst deleted file mode 100644 index 6f1665f6fab328..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-01-17-42.bpo-33725.fFZoDG.rst +++ /dev/null @@ -1,2 +0,0 @@ -On macOS, the :mod:`multiprocessing` module now uses *spawn* start method by -default. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst b/Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst deleted file mode 100644 index 2773675cb5ad71..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-12-17-10.bpo-37076.Bk2xOs.rst +++ /dev/null @@ -1,3 +0,0 @@ -:func:`_thread.start_new_thread` now logs uncaught exception raised by the -function using :func:`sys.unraisablehook`, rather than :func:`sys.excepthook`, -so the hook gets access to the function which raised the exception. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst b/Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst deleted file mode 100644 index 41ee5c2fe8bf38..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-19-14-29.bpo-35279.PX7yl9.rst +++ /dev/null @@ -1,3 +0,0 @@ -Change default *max_workers* of ``ThreadPoolExecutor`` from ``cpu_count() * -5`` to ``min(32, cpu_count() + 4))``. Previous value was unreasonably -large on many cores machines. diff --git a/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst b/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst deleted file mode 100644 index 39d4469cd10177..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-28-23-17-35.bpo-35246.oXT21d.rst +++ /dev/null @@ -1 +0,0 @@ -Make :func:`asyncio.create_subprocess_exec` accept path-like arguments. diff --git a/Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst b/Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst deleted file mode 100644 index 5c897fb4dbc745..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-30-13-30-46.bpo-36999.EjY_L2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add the ``asyncio.Task.get_coro()`` method to publicly expose the tasks's -coroutine object. diff --git a/Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst b/Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst deleted file mode 100644 index aade9121b4bbbd..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-30-16-16-47.bpo-12639.TQFOR4.rst +++ /dev/null @@ -1,2 +0,0 @@ -:meth:`msilib.Directory.start_component()` no longer fails if *keyfile* is -not ``None``. diff --git a/Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst b/Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst deleted file mode 100644 index e1154ef575a539..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-30-21-25-14.bpo-29262.LdIzun.rst +++ /dev/null @@ -1 +0,0 @@ -Add ``get_origin()`` and ``get_args()`` introspection helpers to ``typing`` module. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst b/Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst deleted file mode 100644 index 1c5ed97a7d190b..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-31-11-33-11.bpo-26835.xGbUX0.rst +++ /dev/null @@ -1 +0,0 @@ -The fcntl module now contains file sealing constants for sealing of memfds. diff --git a/Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst b/Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst deleted file mode 100644 index 1e561970445fa9..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-05-31-15-53-34.bpo-12202.nobzc9.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix the error handling in :meth:`msilib.SummaryInformation.GetProperty`. Patch -by Zackery Spytz. diff --git a/Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst b/Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst deleted file mode 100644 index 6bea492e6a5555..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-01-09-03-32.bpo-37120.FOKQLU.rst +++ /dev/null @@ -1 +0,0 @@ -Add SSLContext.num_tickets to control the number of TLSv1.3 session tickets. diff --git a/Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst b/Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst deleted file mode 100644 index f1b825890231d9..00000000000000 --- a/Misc/NEWS.d/next/Library/2019-06-01-22-54-03.bpo-37128.oGXBWN.rst +++ /dev/null @@ -1 +0,0 @@ -Added :func:`math.perm`. diff --git a/Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst b/Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst deleted file mode 100644 index 654494cb349815..00000000000000 --- a/Misc/NEWS.d/next/Security/2018-03-30-12-26-47.bpo-33164.aO29Cx.rst +++ /dev/null @@ -1 +0,0 @@ -Updated blake2 implementation which uses secure memset implementation provided by platform. diff --git a/Misc/NEWS.d/next/Security/2019-02-24-18-48-16.bpo-33529.wpNNBD.rst b/Misc/NEWS.d/next/Security/2019-02-24-18-48-16.bpo-33529.wpNNBD.rst deleted file mode 100644 index 84d16f5a56ae2b..00000000000000 --- a/Misc/NEWS.d/next/Security/2019-02-24-18-48-16.bpo-33529.wpNNBD.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent fold function used in email header encoding from entering infinite -loop when there are too many non-ASCII characters in a header. diff --git a/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst b/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst deleted file mode 100644 index 37b567a5b6f93b..00000000000000 --- a/Misc/NEWS.d/next/Security/2019-05-21-23-20-18.bpo-35907.NC_zNK.rst +++ /dev/null @@ -1,3 +0,0 @@ -CVE-2019-9948: Avoid file reading by disallowing ``local-file://`` and -``local_file://`` URL schemes in ``URLopener().open()`` and -``URLopener().retrieve()`` of :mod:`urllib.request`. diff --git a/Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst b/Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst deleted file mode 100644 index a7c92980fd77ee..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-03-23-13-58-49.bpo-36342.q6Quiq.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test_multiprocessing in test_venv if platform lacks functioning sem_open. diff --git a/Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst b/Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst deleted file mode 100644 index 222fb386ca7bca..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-04-21-25-19.bpo-36782.h3oPIb.rst +++ /dev/null @@ -1 +0,0 @@ -Add tests for several C API functions in the :mod:`datetime` module. Patch by Edison Abahurire. diff --git a/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst b/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst deleted file mode 100644 index ad8cc8fc61a07f..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-06-18-29-54.bpo-35925.gwQPuC.rst +++ /dev/null @@ -1 +0,0 @@ -Skip httplib and nntplib networking tests when they would otherwise fail due to a modern OS or distro with a default OpenSSL policy of rejecting connections to servers with weak certificates. diff --git a/Misc/NEWS.d/next/Tests/2019-05-08-15-55-46.bpo-36816.WBKRGZ.rst b/Misc/NEWS.d/next/Tests/2019-05-08-15-55-46.bpo-36816.WBKRGZ.rst deleted file mode 100644 index 420dfe8323663b..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-08-15-55-46.bpo-36816.WBKRGZ.rst +++ /dev/null @@ -1 +0,0 @@ -Update Lib/test/selfsigned_pythontestdotnet.pem to match self-signed.pythontest.net's new TLS certificate. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Tests/2019-05-10-01-50-30.bpo-36719.O84ZWv.rst b/Misc/NEWS.d/next/Tests/2019-05-10-01-50-30.bpo-36719.O84ZWv.rst deleted file mode 100644 index 9f60145975fe89..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-10-01-50-30.bpo-36719.O84ZWv.rst +++ /dev/null @@ -1,3 +0,0 @@ -"python3 -m test -jN ..." now continues the execution of next tests when a -worker process crash (CHILD_ERROR state). Previously, the test suite stopped -immediately. Use --failfast to stop at the first error. diff --git a/Misc/NEWS.d/next/Tests/2019-05-14-14-12-24.bpo-36915.58b7pH.rst b/Misc/NEWS.d/next/Tests/2019-05-14-14-12-24.bpo-36915.58b7pH.rst deleted file mode 100644 index 4eebfb4832510d..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-14-14-12-24.bpo-36915.58b7pH.rst +++ /dev/null @@ -1,3 +0,0 @@ -The main regrtest process now always removes all temporary directories of -worker processes even if they crash or if they are killed on -KeyboardInterrupt (CTRL+c). diff --git a/Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst b/Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst deleted file mode 100644 index 4ab342b8a2b364..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-22-12-57-15.bpo-36829.e9mRWC.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add :func:`test.support.catch_unraisable_exception`: context manager -catching unraisable exception using :func:`sys.unraisablehook`. diff --git a/Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst b/Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst deleted file mode 100644 index df5b8f2482d351..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-28-17-48-22.bpo-37081.qxB-1l.rst +++ /dev/null @@ -1 +0,0 @@ -Test with OpenSSL 1.1.1c diff --git a/Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst b/Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst deleted file mode 100644 index 84e06e71869f68..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-05-30-10-57-39.bpo-37098.SfXt1M.rst +++ /dev/null @@ -1 +0,0 @@ -Fix test_memfd_create on older Linux Kernels. diff --git a/Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst b/Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst deleted file mode 100644 index 566ff5150d5f95..00000000000000 --- a/Misc/NEWS.d/next/Tests/2019-06-03-02-30-36.bpo-37069.rVtdLk.rst +++ /dev/null @@ -1,3 +0,0 @@ -Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl -and test_yield_from to use :func:`test.support.catch_unraisable_exception` -rather than :func:`test.support.captured_stderr`. diff --git a/Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst b/Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst deleted file mode 100644 index 5320dc51f75036..00000000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2019-05-26-16-47-06.bpo-37053.-EYRuz.rst +++ /dev/null @@ -1 +0,0 @@ -Handle strings like u"bar" correctly in Tools/parser/unparse.py. Patch by Chih-Hsuan Yen. \ No newline at end of file diff --git a/Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst b/Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst deleted file mode 100644 index 47b1e0668b18b8..00000000000000 --- a/Misc/NEWS.d/next/Windows/2018-08-28-17-23-49.bpo-33407.ARG0W_.rst +++ /dev/null @@ -1 +0,0 @@ -The :c:macro:`Py_DEPRECATED()` macro has been implemented for MSVC. diff --git a/Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst b/Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst deleted file mode 100644 index b6d1375c775263..00000000000000 --- a/Misc/NEWS.d/next/Windows/2018-09-15-11-36-55.bpo-29883.HErerE.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add Windows support for UDP transports for the Proactor Event Loop. Patch by -Adam Meily. diff --git a/Misc/NEWS.d/next/Windows/2019-03-01-16-43-45.bpo-35926.mLszHo.rst b/Misc/NEWS.d/next/Windows/2019-03-01-16-43-45.bpo-35926.mLszHo.rst deleted file mode 100644 index 03249c6a168a0a..00000000000000 --- a/Misc/NEWS.d/next/Windows/2019-03-01-16-43-45.bpo-35926.mLszHo.rst +++ /dev/null @@ -1 +0,0 @@ -Update to OpenSSL 1.1.1b for Windows. diff --git a/Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst b/Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst deleted file mode 100644 index 2a531d2c14d9a2..00000000000000 --- a/Misc/NEWS.d/next/Windows/2019-05-20-20-26-36.bpo-36965.KsfI-N.rst +++ /dev/null @@ -1 +0,0 @@ -include of STATUS_CONTROL_C_EXIT without depending on MSC compiler diff --git a/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst b/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst deleted file mode 100644 index c82e54c12c89fe..00000000000000 --- a/Misc/NEWS.d/next/macOS/2019-06-03-05-49-49.bpo-36231.RfmW_p.rst +++ /dev/null @@ -1,3 +0,0 @@ -Support building Python on macOS without /usr/include installed. As of macOS -10.14, system header files are only available within an SDK provided by -either the Command Line Tools or the Xcode app. diff --git a/README.rst b/README.rst index 388543b8dcfc92..b0a0ce7ec287b6 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.8.0 alpha 4 -==================================== +This is Python version 3.8.0 beta 1 +=================================== .. image:: https://travis-ci.org/python/cpython.svg?branch=master :alt: CPython build status on Travis CI From aa79707262f893428665ef45b5e879129abca4aa Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Tue, 4 Jun 2019 14:00:47 -0400 Subject: [PATCH 320/441] bpo-30835: email: Fix AttributeError when parsing invalid CTE (GH-13598) * bpo-30835: email: Fix AttributeError when parsing invalid Content-Transfer-Encoding Parsing an email containing a multipart Content-Type, along with a Content-Transfer-Encoding containing an invalid (non-ASCII-decodable) byte will fail. email.feedparser.FeedParser._parsegen() gets the header and attempts to convert it to lowercase before comparing it with the accepted encodings, but as the header contains an invalid byte, it's returned as a Header object rather than a str. Cast the Content-Transfer-Encoding header to a str to avoid this. Found using the AFL fuzzer. Reported-by: Daniel Axtens Signed-off-by: Andrew Donnellan * Add email and NEWS entry for the bugfix. --- Lib/email/feedparser.py | 2 +- Lib/test/test_email/test_email.py | 9 +++++++++ .../Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index 7c07ca86457a2a..97d3f5144d606f 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -320,7 +320,7 @@ def _parsegen(self): self._cur.set_payload(EMPTYSTRING.join(lines)) return # Make sure a valid content type was specified per RFC 2045:6.4. - if (self._cur.get('content-transfer-encoding', '8bit').lower() + if (str(self._cur.get('content-transfer-encoding', '8bit')).lower() not in ('7bit', '8bit', 'binary')): defect = errors.InvalidMultipartContentTransferEncodingDefect() self.policy.handle_defect(self._cur, defect) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index dfb3be84384a8b..c29cc56203b1f7 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -1466,6 +1466,15 @@ def test_mangled_from_with_bad_bytes(self): g.flatten(msg) self.assertEqual(b.getvalue(), source + b'>From R\xc3\xb6lli\n') + def test_mutltipart_with_bad_bytes_in_cte(self): + # bpo30835 + source = textwrap.dedent("""\ + From: aperson@example.com + Content-Type: multipart/mixed; boundary="1" + Content-Transfer-Encoding: \xc8 + """).encode('utf-8') + msg = email.message_from_bytes(source) + # Test the basic MIMEAudio class class TestMIMEAudio(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst b/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst new file mode 100644 index 00000000000000..019321d6f1d722 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-27-15-29-46.bpo-30835.3FoaWH.rst @@ -0,0 +1,3 @@ +Fixed a bug in email parsing where a message with invalid bytes in +content-transfer-encoding of a multipart message can cause an AttributeError. +Patch by Andrew Donnellan. From 001d63cefaa9d84d6d59aa9db8bac66040c8f0ee Mon Sep 17 00:00:00 2001 From: Petter Strandmark Date: Tue, 4 Jun 2019 21:34:49 +0200 Subject: [PATCH 321/441] bpo-35047: Update whatsnew/3.8 for better mock error message (GH-13746) --- Doc/whatsnew/3.8.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index f060f4b3f7c40f..8456a17aedcc0d 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -760,6 +760,9 @@ unittest :meth:`~unittest.TestCase.setUpClass()`. (Contributed by Lisa Roach in :issue:`24412`.) +* Several mock assert functions now also print a list of actual calls upon + failure. (Contributed by Petter Strandmark in :issue:`35047`.) + venv ---- From 9ab2fb1c68a75115da92d51b8c40b74f60f88561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 4 Jun 2019 22:12:32 +0200 Subject: [PATCH 322/441] Bump to 3.9.0a0 --- Doc/tools/extensions/pyspecific.py | 2 +- Doc/tutorial/interpreter.rst | 8 +- Doc/tutorial/stdlib.rst | 2 +- Doc/tutorial/stdlib2.rst | 2 +- Include/patchlevel.h | 8 +- PC/pyconfig.h | 4 +- PC/python3.def | 1598 ++++++++++++++-------------- PCbuild/readme.txt | 2 +- README.rst | 14 +- configure | 20 +- configure.ac | 2 +- 11 files changed, 831 insertions(+), 831 deletions(-) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 8bf7eb699c4e72..f79b25048a5a64 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -36,7 +36,7 @@ ISSUE_URI = 'https://bugs.python.org/issue%s' -SOURCE_URI = 'https://github.com/python/cpython/tree/3.8/%s' +SOURCE_URI = 'https://github.com/python/cpython/tree/master/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index dddfd850cd29fb..87d2fefac7ef04 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -10,13 +10,13 @@ Using the Python Interpreter Invoking the Interpreter ======================== -The Python interpreter is usually installed as :file:`/usr/local/bin/python3.8` +The Python interpreter is usually installed as :file:`/usr/local/bin/python3.9` on those machines where it is available; putting :file:`/usr/local/bin` in your Unix shell's search path makes it possible to start it by typing the command: .. code-block:: text - python3.8 + python3.9 to the shell. [#]_ Since the choice of the directory where the interpreter lives is an installation option, other places are possible; check with your local @@ -98,8 +98,8 @@ before printing the first prompt: .. code-block:: shell-session - $ python3.8 - Python 3.8 (default, Sep 16 2015, 09:25:04) + $ python3.9 + Python 3.9 (default, June 4 2019, 09:25:04) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index 82261a6513489a..e030f8f19b48de 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -15,7 +15,7 @@ operating system:: >>> import os >>> os.getcwd() # Return the current working directory - 'C:\\Python38' + 'C:\\Python39' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # Run the command mkdir in the system shell 0 diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index d2ac57b8e4d3a7..299482856ff324 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -278,7 +278,7 @@ applications include caching objects that are expensive to create:: Traceback (most recent call last): File "", line 1, in d['primary'] # entry was automatically removed - File "C:/python38/lib/weakref.py", line 46, in __getitem__ + File "C:/python39/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary' diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 881558bb44f612..ad5599462a8bd2 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -17,13 +17,13 @@ /* Version parsed out into numeric values */ /*--start constants--*/ #define PY_MAJOR_VERSION 3 -#define PY_MINOR_VERSION 8 +#define PY_MINOR_VERSION 9 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA +#define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.8.0b1" +#define PY_VERSION "3.9.0a0" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/PC/pyconfig.h b/PC/pyconfig.h index a74ee98a753d88..122591276b4a7d 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -274,11 +274,11 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ file in their Makefile (other compilers are generally taken care of by distutils.) */ # if defined(_DEBUG) -# pragma comment(lib,"python38_d.lib") +# pragma comment(lib,"python39_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else -# pragma comment(lib,"python38.lib") +# pragma comment(lib,"python39.lib") # endif /* _DEBUG */ # endif /* _MSC_VER */ # endif /* Py_BUILD_CORE */ diff --git a/PC/python3.def b/PC/python3.def index e317864d0cd802..6844cf1f3b8e14 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -2,802 +2,802 @@ ; It is used when building python3dll.vcxproj LIBRARY "python3" EXPORTS - PyArg_Parse=python38.PyArg_Parse - PyArg_ParseTuple=python38.PyArg_ParseTuple - PyArg_ParseTupleAndKeywords=python38.PyArg_ParseTupleAndKeywords - PyArg_UnpackTuple=python38.PyArg_UnpackTuple - PyArg_VaParse=python38.PyArg_VaParse - PyArg_VaParseTupleAndKeywords=python38.PyArg_VaParseTupleAndKeywords - PyArg_ValidateKeywordArguments=python38.PyArg_ValidateKeywordArguments - PyBaseObject_Type=python38.PyBaseObject_Type DATA - PyBool_FromLong=python38.PyBool_FromLong - PyBool_Type=python38.PyBool_Type DATA - PyByteArrayIter_Type=python38.PyByteArrayIter_Type DATA - PyByteArray_AsString=python38.PyByteArray_AsString - PyByteArray_Concat=python38.PyByteArray_Concat - PyByteArray_FromObject=python38.PyByteArray_FromObject - PyByteArray_FromStringAndSize=python38.PyByteArray_FromStringAndSize - PyByteArray_Resize=python38.PyByteArray_Resize - PyByteArray_Size=python38.PyByteArray_Size - PyByteArray_Type=python38.PyByteArray_Type DATA - PyBytesIter_Type=python38.PyBytesIter_Type DATA - PyBytes_AsString=python38.PyBytes_AsString - PyBytes_AsStringAndSize=python38.PyBytes_AsStringAndSize - PyBytes_Concat=python38.PyBytes_Concat - PyBytes_ConcatAndDel=python38.PyBytes_ConcatAndDel - PyBytes_DecodeEscape=python38.PyBytes_DecodeEscape - PyBytes_FromFormat=python38.PyBytes_FromFormat - PyBytes_FromFormatV=python38.PyBytes_FromFormatV - PyBytes_FromObject=python38.PyBytes_FromObject - PyBytes_FromString=python38.PyBytes_FromString - PyBytes_FromStringAndSize=python38.PyBytes_FromStringAndSize - PyBytes_Repr=python38.PyBytes_Repr - PyBytes_Size=python38.PyBytes_Size - PyBytes_Type=python38.PyBytes_Type DATA - PyCFunction_Call=python38.PyCFunction_Call - PyCFunction_ClearFreeList=python38.PyCFunction_ClearFreeList - PyCFunction_GetFlags=python38.PyCFunction_GetFlags - PyCFunction_GetFunction=python38.PyCFunction_GetFunction - PyCFunction_GetSelf=python38.PyCFunction_GetSelf - PyCFunction_New=python38.PyCFunction_New - PyCFunction_NewEx=python38.PyCFunction_NewEx - PyCFunction_Type=python38.PyCFunction_Type DATA - PyCallIter_New=python38.PyCallIter_New - PyCallIter_Type=python38.PyCallIter_Type DATA - PyCallable_Check=python38.PyCallable_Check - PyCapsule_GetContext=python38.PyCapsule_GetContext - PyCapsule_GetDestructor=python38.PyCapsule_GetDestructor - PyCapsule_GetName=python38.PyCapsule_GetName - PyCapsule_GetPointer=python38.PyCapsule_GetPointer - PyCapsule_Import=python38.PyCapsule_Import - PyCapsule_IsValid=python38.PyCapsule_IsValid - PyCapsule_New=python38.PyCapsule_New - PyCapsule_SetContext=python38.PyCapsule_SetContext - PyCapsule_SetDestructor=python38.PyCapsule_SetDestructor - PyCapsule_SetName=python38.PyCapsule_SetName - PyCapsule_SetPointer=python38.PyCapsule_SetPointer - PyCapsule_Type=python38.PyCapsule_Type DATA - PyClassMethodDescr_Type=python38.PyClassMethodDescr_Type DATA - PyCodec_BackslashReplaceErrors=python38.PyCodec_BackslashReplaceErrors - PyCodec_Decode=python38.PyCodec_Decode - PyCodec_Decoder=python38.PyCodec_Decoder - PyCodec_Encode=python38.PyCodec_Encode - PyCodec_Encoder=python38.PyCodec_Encoder - PyCodec_IgnoreErrors=python38.PyCodec_IgnoreErrors - PyCodec_IncrementalDecoder=python38.PyCodec_IncrementalDecoder - PyCodec_IncrementalEncoder=python38.PyCodec_IncrementalEncoder - PyCodec_KnownEncoding=python38.PyCodec_KnownEncoding - PyCodec_LookupError=python38.PyCodec_LookupError - PyCodec_NameReplaceErrors=python38.PyCodec_NameReplaceErrors - PyCodec_Register=python38.PyCodec_Register - PyCodec_RegisterError=python38.PyCodec_RegisterError - PyCodec_ReplaceErrors=python38.PyCodec_ReplaceErrors - PyCodec_StreamReader=python38.PyCodec_StreamReader - PyCodec_StreamWriter=python38.PyCodec_StreamWriter - PyCodec_StrictErrors=python38.PyCodec_StrictErrors - PyCodec_XMLCharRefReplaceErrors=python38.PyCodec_XMLCharRefReplaceErrors - PyComplex_FromDoubles=python38.PyComplex_FromDoubles - PyComplex_ImagAsDouble=python38.PyComplex_ImagAsDouble - PyComplex_RealAsDouble=python38.PyComplex_RealAsDouble - PyComplex_Type=python38.PyComplex_Type DATA - PyDescr_NewClassMethod=python38.PyDescr_NewClassMethod - PyDescr_NewGetSet=python38.PyDescr_NewGetSet - PyDescr_NewMember=python38.PyDescr_NewMember - PyDescr_NewMethod=python38.PyDescr_NewMethod - PyDictItems_Type=python38.PyDictItems_Type DATA - PyDictIterItem_Type=python38.PyDictIterItem_Type DATA - PyDictIterKey_Type=python38.PyDictIterKey_Type DATA - PyDictIterValue_Type=python38.PyDictIterValue_Type DATA - PyDictKeys_Type=python38.PyDictKeys_Type DATA - PyDictProxy_New=python38.PyDictProxy_New - PyDictProxy_Type=python38.PyDictProxy_Type DATA - PyDictValues_Type=python38.PyDictValues_Type DATA - PyDict_Clear=python38.PyDict_Clear - PyDict_Contains=python38.PyDict_Contains - PyDict_Copy=python38.PyDict_Copy - PyDict_DelItem=python38.PyDict_DelItem - PyDict_DelItemString=python38.PyDict_DelItemString - PyDict_GetItem=python38.PyDict_GetItem - PyDict_GetItemString=python38.PyDict_GetItemString - PyDict_GetItemWithError=python38.PyDict_GetItemWithError - PyDict_Items=python38.PyDict_Items - PyDict_Keys=python38.PyDict_Keys - PyDict_Merge=python38.PyDict_Merge - PyDict_MergeFromSeq2=python38.PyDict_MergeFromSeq2 - PyDict_New=python38.PyDict_New - PyDict_Next=python38.PyDict_Next - PyDict_SetItem=python38.PyDict_SetItem - PyDict_SetItemString=python38.PyDict_SetItemString - PyDict_Size=python38.PyDict_Size - PyDict_Type=python38.PyDict_Type DATA - PyDict_Update=python38.PyDict_Update - PyDict_Values=python38.PyDict_Values - PyEllipsis_Type=python38.PyEllipsis_Type DATA - PyEnum_Type=python38.PyEnum_Type DATA - PyErr_BadArgument=python38.PyErr_BadArgument - PyErr_BadInternalCall=python38.PyErr_BadInternalCall - PyErr_CheckSignals=python38.PyErr_CheckSignals - PyErr_Clear=python38.PyErr_Clear - PyErr_Display=python38.PyErr_Display - PyErr_ExceptionMatches=python38.PyErr_ExceptionMatches - PyErr_Fetch=python38.PyErr_Fetch - PyErr_Format=python38.PyErr_Format - PyErr_FormatV=python38.PyErr_FormatV - PyErr_GetExcInfo=python38.PyErr_GetExcInfo - PyErr_GivenExceptionMatches=python38.PyErr_GivenExceptionMatches - PyErr_NewException=python38.PyErr_NewException - PyErr_NewExceptionWithDoc=python38.PyErr_NewExceptionWithDoc - PyErr_NoMemory=python38.PyErr_NoMemory - PyErr_NormalizeException=python38.PyErr_NormalizeException - PyErr_Occurred=python38.PyErr_Occurred - PyErr_Print=python38.PyErr_Print - PyErr_PrintEx=python38.PyErr_PrintEx - PyErr_ProgramText=python38.PyErr_ProgramText - PyErr_ResourceWarning=python38.PyErr_ResourceWarning - PyErr_Restore=python38.PyErr_Restore - PyErr_SetExcFromWindowsErr=python38.PyErr_SetExcFromWindowsErr - PyErr_SetExcFromWindowsErrWithFilename=python38.PyErr_SetExcFromWindowsErrWithFilename - PyErr_SetExcFromWindowsErrWithFilenameObject=python38.PyErr_SetExcFromWindowsErrWithFilenameObject - PyErr_SetExcFromWindowsErrWithFilenameObjects=python38.PyErr_SetExcFromWindowsErrWithFilenameObjects - PyErr_SetExcInfo=python38.PyErr_SetExcInfo - PyErr_SetFromErrno=python38.PyErr_SetFromErrno - PyErr_SetFromErrnoWithFilename=python38.PyErr_SetFromErrnoWithFilename - PyErr_SetFromErrnoWithFilenameObject=python38.PyErr_SetFromErrnoWithFilenameObject - PyErr_SetFromErrnoWithFilenameObjects=python38.PyErr_SetFromErrnoWithFilenameObjects - PyErr_SetFromWindowsErr=python38.PyErr_SetFromWindowsErr - PyErr_SetFromWindowsErrWithFilename=python38.PyErr_SetFromWindowsErrWithFilename - PyErr_SetImportError=python38.PyErr_SetImportError - PyErr_SetImportErrorSubclass=python38.PyErr_SetImportErrorSubclass - PyErr_SetInterrupt=python38.PyErr_SetInterrupt - PyErr_SetNone=python38.PyErr_SetNone - PyErr_SetObject=python38.PyErr_SetObject - PyErr_SetString=python38.PyErr_SetString - PyErr_SyntaxLocation=python38.PyErr_SyntaxLocation - PyErr_SyntaxLocationEx=python38.PyErr_SyntaxLocationEx - PyErr_WarnEx=python38.PyErr_WarnEx - PyErr_WarnExplicit=python38.PyErr_WarnExplicit - PyErr_WarnFormat=python38.PyErr_WarnFormat - PyErr_WriteUnraisable=python38.PyErr_WriteUnraisable - PyEval_AcquireLock=python38.PyEval_AcquireLock - PyEval_AcquireThread=python38.PyEval_AcquireThread - PyEval_CallFunction=python38.PyEval_CallFunction - PyEval_CallMethod=python38.PyEval_CallMethod - PyEval_CallObjectWithKeywords=python38.PyEval_CallObjectWithKeywords - PyEval_EvalCode=python38.PyEval_EvalCode - PyEval_EvalCodeEx=python38.PyEval_EvalCodeEx - PyEval_EvalFrame=python38.PyEval_EvalFrame - PyEval_EvalFrameEx=python38.PyEval_EvalFrameEx - PyEval_GetBuiltins=python38.PyEval_GetBuiltins - PyEval_GetCallStats=python38.PyEval_GetCallStats - PyEval_GetFrame=python38.PyEval_GetFrame - PyEval_GetFuncDesc=python38.PyEval_GetFuncDesc - PyEval_GetFuncName=python38.PyEval_GetFuncName - PyEval_GetGlobals=python38.PyEval_GetGlobals - PyEval_GetLocals=python38.PyEval_GetLocals - PyEval_InitThreads=python38.PyEval_InitThreads - PyEval_ReInitThreads=python38.PyEval_ReInitThreads - PyEval_ReleaseLock=python38.PyEval_ReleaseLock - PyEval_ReleaseThread=python38.PyEval_ReleaseThread - PyEval_RestoreThread=python38.PyEval_RestoreThread - PyEval_SaveThread=python38.PyEval_SaveThread - PyEval_ThreadsInitialized=python38.PyEval_ThreadsInitialized - PyExc_ArithmeticError=python38.PyExc_ArithmeticError DATA - PyExc_AssertionError=python38.PyExc_AssertionError DATA - PyExc_AttributeError=python38.PyExc_AttributeError DATA - PyExc_BaseException=python38.PyExc_BaseException DATA - PyExc_BlockingIOError=python38.PyExc_BlockingIOError DATA - PyExc_BrokenPipeError=python38.PyExc_BrokenPipeError DATA - PyExc_BufferError=python38.PyExc_BufferError DATA - PyExc_BytesWarning=python38.PyExc_BytesWarning DATA - PyExc_ChildProcessError=python38.PyExc_ChildProcessError DATA - PyExc_ConnectionAbortedError=python38.PyExc_ConnectionAbortedError DATA - PyExc_ConnectionError=python38.PyExc_ConnectionError DATA - PyExc_ConnectionRefusedError=python38.PyExc_ConnectionRefusedError DATA - PyExc_ConnectionResetError=python38.PyExc_ConnectionResetError DATA - PyExc_DeprecationWarning=python38.PyExc_DeprecationWarning DATA - PyExc_EOFError=python38.PyExc_EOFError DATA - PyExc_EnvironmentError=python38.PyExc_EnvironmentError DATA - PyExc_Exception=python38.PyExc_Exception DATA - PyExc_FileExistsError=python38.PyExc_FileExistsError DATA - PyExc_FileNotFoundError=python38.PyExc_FileNotFoundError DATA - PyExc_FloatingPointError=python38.PyExc_FloatingPointError DATA - PyExc_FutureWarning=python38.PyExc_FutureWarning DATA - PyExc_GeneratorExit=python38.PyExc_GeneratorExit DATA - PyExc_IOError=python38.PyExc_IOError DATA - PyExc_ImportError=python38.PyExc_ImportError DATA - PyExc_ImportWarning=python38.PyExc_ImportWarning DATA - PyExc_IndentationError=python38.PyExc_IndentationError DATA - PyExc_IndexError=python38.PyExc_IndexError DATA - PyExc_InterruptedError=python38.PyExc_InterruptedError DATA - PyExc_IsADirectoryError=python38.PyExc_IsADirectoryError DATA - PyExc_KeyError=python38.PyExc_KeyError DATA - PyExc_KeyboardInterrupt=python38.PyExc_KeyboardInterrupt DATA - PyExc_LookupError=python38.PyExc_LookupError DATA - PyExc_MemoryError=python38.PyExc_MemoryError DATA - PyExc_ModuleNotFoundError=python38.PyExc_ModuleNotFoundError DATA - PyExc_NameError=python38.PyExc_NameError DATA - PyExc_NotADirectoryError=python38.PyExc_NotADirectoryError DATA - PyExc_NotImplementedError=python38.PyExc_NotImplementedError DATA - PyExc_OSError=python38.PyExc_OSError DATA - PyExc_OverflowError=python38.PyExc_OverflowError DATA - PyExc_PendingDeprecationWarning=python38.PyExc_PendingDeprecationWarning DATA - PyExc_PermissionError=python38.PyExc_PermissionError DATA - PyExc_ProcessLookupError=python38.PyExc_ProcessLookupError DATA - PyExc_RecursionError=python38.PyExc_RecursionError DATA - PyExc_ReferenceError=python38.PyExc_ReferenceError DATA - PyExc_ResourceWarning=python38.PyExc_ResourceWarning DATA - PyExc_RuntimeError=python38.PyExc_RuntimeError DATA - PyExc_RuntimeWarning=python38.PyExc_RuntimeWarning DATA - PyExc_StopAsyncIteration=python38.PyExc_StopAsyncIteration DATA - PyExc_StopIteration=python38.PyExc_StopIteration DATA - PyExc_SyntaxError=python38.PyExc_SyntaxError DATA - PyExc_SyntaxWarning=python38.PyExc_SyntaxWarning DATA - PyExc_SystemError=python38.PyExc_SystemError DATA - PyExc_SystemExit=python38.PyExc_SystemExit DATA - PyExc_TabError=python38.PyExc_TabError DATA - PyExc_TargetScopeError=python38.PyExc_TargetScopeError DATA - PyExc_TimeoutError=python38.PyExc_TimeoutError DATA - PyExc_TypeError=python38.PyExc_TypeError DATA - PyExc_UnboundLocalError=python38.PyExc_UnboundLocalError DATA - PyExc_UnicodeDecodeError=python38.PyExc_UnicodeDecodeError DATA - PyExc_UnicodeEncodeError=python38.PyExc_UnicodeEncodeError DATA - PyExc_UnicodeError=python38.PyExc_UnicodeError DATA - PyExc_UnicodeTranslateError=python38.PyExc_UnicodeTranslateError DATA - PyExc_UnicodeWarning=python38.PyExc_UnicodeWarning DATA - PyExc_UserWarning=python38.PyExc_UserWarning DATA - PyExc_ValueError=python38.PyExc_ValueError DATA - PyExc_Warning=python38.PyExc_Warning DATA - PyExc_WindowsError=python38.PyExc_WindowsError DATA - PyExc_ZeroDivisionError=python38.PyExc_ZeroDivisionError DATA - PyExceptionClass_Name=python38.PyExceptionClass_Name - PyException_GetCause=python38.PyException_GetCause - PyException_GetContext=python38.PyException_GetContext - PyException_GetTraceback=python38.PyException_GetTraceback - PyException_SetCause=python38.PyException_SetCause - PyException_SetContext=python38.PyException_SetContext - PyException_SetTraceback=python38.PyException_SetTraceback - PyFile_FromFd=python38.PyFile_FromFd - PyFile_GetLine=python38.PyFile_GetLine - PyFile_WriteObject=python38.PyFile_WriteObject - PyFile_WriteString=python38.PyFile_WriteString - PyFilter_Type=python38.PyFilter_Type DATA - PyFloat_AsDouble=python38.PyFloat_AsDouble - PyFloat_FromDouble=python38.PyFloat_FromDouble - PyFloat_FromString=python38.PyFloat_FromString - PyFloat_GetInfo=python38.PyFloat_GetInfo - PyFloat_GetMax=python38.PyFloat_GetMax - PyFloat_GetMin=python38.PyFloat_GetMin - PyFloat_Type=python38.PyFloat_Type DATA - PyFrozenSet_New=python38.PyFrozenSet_New - PyFrozenSet_Type=python38.PyFrozenSet_Type DATA - PyGC_Collect=python38.PyGC_Collect - PyGILState_Ensure=python38.PyGILState_Ensure - PyGILState_GetThisThreadState=python38.PyGILState_GetThisThreadState - PyGILState_Release=python38.PyGILState_Release - PyGetSetDescr_Type=python38.PyGetSetDescr_Type DATA - PyImport_AddModule=python38.PyImport_AddModule - PyImport_AddModuleObject=python38.PyImport_AddModuleObject - PyImport_AppendInittab=python38.PyImport_AppendInittab - PyImport_Cleanup=python38.PyImport_Cleanup - PyImport_ExecCodeModule=python38.PyImport_ExecCodeModule - PyImport_ExecCodeModuleEx=python38.PyImport_ExecCodeModuleEx - PyImport_ExecCodeModuleObject=python38.PyImport_ExecCodeModuleObject - PyImport_ExecCodeModuleWithPathnames=python38.PyImport_ExecCodeModuleWithPathnames - PyImport_GetImporter=python38.PyImport_GetImporter - PyImport_GetMagicNumber=python38.PyImport_GetMagicNumber - PyImport_GetMagicTag=python38.PyImport_GetMagicTag - PyImport_GetModule=python38.PyImport_GetModule - PyImport_GetModuleDict=python38.PyImport_GetModuleDict - PyImport_Import=python38.PyImport_Import - PyImport_ImportFrozenModule=python38.PyImport_ImportFrozenModule - PyImport_ImportFrozenModuleObject=python38.PyImport_ImportFrozenModuleObject - PyImport_ImportModule=python38.PyImport_ImportModule - PyImport_ImportModuleLevel=python38.PyImport_ImportModuleLevel - PyImport_ImportModuleLevelObject=python38.PyImport_ImportModuleLevelObject - PyImport_ImportModuleNoBlock=python38.PyImport_ImportModuleNoBlock - PyImport_ReloadModule=python38.PyImport_ReloadModule - PyIndex_Check=python38.PyIndex_Check - PyInterpreterState_Clear=python38.PyInterpreterState_Clear - PyInterpreterState_Delete=python38.PyInterpreterState_Delete - PyInterpreterState_New=python38.PyInterpreterState_New - PyIter_Check=python38.PyIter_Check - PyIter_Next=python38.PyIter_Next - PyListIter_Type=python38.PyListIter_Type DATA - PyListRevIter_Type=python38.PyListRevIter_Type DATA - PyList_Append=python38.PyList_Append - PyList_AsTuple=python38.PyList_AsTuple - PyList_GetItem=python38.PyList_GetItem - PyList_GetSlice=python38.PyList_GetSlice - PyList_Insert=python38.PyList_Insert - PyList_New=python38.PyList_New - PyList_Reverse=python38.PyList_Reverse - PyList_SetItem=python38.PyList_SetItem - PyList_SetSlice=python38.PyList_SetSlice - PyList_Size=python38.PyList_Size - PyList_Sort=python38.PyList_Sort - PyList_Type=python38.PyList_Type DATA - PyLongRangeIter_Type=python38.PyLongRangeIter_Type DATA - PyLong_AsDouble=python38.PyLong_AsDouble - PyLong_AsLong=python38.PyLong_AsLong - PyLong_AsLongAndOverflow=python38.PyLong_AsLongAndOverflow - PyLong_AsLongLong=python38.PyLong_AsLongLong - PyLong_AsLongLongAndOverflow=python38.PyLong_AsLongLongAndOverflow - PyLong_AsSize_t=python38.PyLong_AsSize_t - PyLong_AsSsize_t=python38.PyLong_AsSsize_t - PyLong_AsUnsignedLong=python38.PyLong_AsUnsignedLong - PyLong_AsUnsignedLongLong=python38.PyLong_AsUnsignedLongLong - PyLong_AsUnsignedLongLongMask=python38.PyLong_AsUnsignedLongLongMask - PyLong_AsUnsignedLongMask=python38.PyLong_AsUnsignedLongMask - PyLong_AsVoidPtr=python38.PyLong_AsVoidPtr - PyLong_FromDouble=python38.PyLong_FromDouble - PyLong_FromLong=python38.PyLong_FromLong - PyLong_FromLongLong=python38.PyLong_FromLongLong - PyLong_FromSize_t=python38.PyLong_FromSize_t - PyLong_FromSsize_t=python38.PyLong_FromSsize_t - PyLong_FromString=python38.PyLong_FromString - PyLong_FromUnsignedLong=python38.PyLong_FromUnsignedLong - PyLong_FromUnsignedLongLong=python38.PyLong_FromUnsignedLongLong - PyLong_FromVoidPtr=python38.PyLong_FromVoidPtr - PyLong_GetInfo=python38.PyLong_GetInfo - PyLong_Type=python38.PyLong_Type DATA - PyMap_Type=python38.PyMap_Type DATA - PyMapping_Check=python38.PyMapping_Check - PyMapping_GetItemString=python38.PyMapping_GetItemString - PyMapping_HasKey=python38.PyMapping_HasKey - PyMapping_HasKeyString=python38.PyMapping_HasKeyString - PyMapping_Items=python38.PyMapping_Items - PyMapping_Keys=python38.PyMapping_Keys - PyMapping_Length=python38.PyMapping_Length - PyMapping_SetItemString=python38.PyMapping_SetItemString - PyMapping_Size=python38.PyMapping_Size - PyMapping_Values=python38.PyMapping_Values - PyMem_Calloc=python38.PyMem_Calloc - PyMem_Free=python38.PyMem_Free - PyMem_Malloc=python38.PyMem_Malloc - PyMem_Realloc=python38.PyMem_Realloc - PyMemberDescr_Type=python38.PyMemberDescr_Type DATA - PyMemoryView_FromMemory=python38.PyMemoryView_FromMemory - PyMemoryView_FromObject=python38.PyMemoryView_FromObject - PyMemoryView_GetContiguous=python38.PyMemoryView_GetContiguous - PyMemoryView_Type=python38.PyMemoryView_Type DATA - PyMethodDescr_Type=python38.PyMethodDescr_Type DATA - PyModuleDef_Init=python38.PyModuleDef_Init - PyModuleDef_Type=python38.PyModuleDef_Type DATA - PyModule_AddFunctions=python38.PyModule_AddFunctions - PyModule_AddIntConstant=python38.PyModule_AddIntConstant - PyModule_AddObject=python38.PyModule_AddObject - PyModule_AddStringConstant=python38.PyModule_AddStringConstant - PyModule_Create2=python38.PyModule_Create2 - PyModule_ExecDef=python38.PyModule_ExecDef - PyModule_FromDefAndSpec2=python38.PyModule_FromDefAndSpec2 - PyModule_GetDef=python38.PyModule_GetDef - PyModule_GetDict=python38.PyModule_GetDict - PyModule_GetFilename=python38.PyModule_GetFilename - PyModule_GetFilenameObject=python38.PyModule_GetFilenameObject - PyModule_GetName=python38.PyModule_GetName - PyModule_GetNameObject=python38.PyModule_GetNameObject - PyModule_GetState=python38.PyModule_GetState - PyModule_New=python38.PyModule_New - PyModule_NewObject=python38.PyModule_NewObject - PyModule_SetDocString=python38.PyModule_SetDocString - PyModule_Type=python38.PyModule_Type DATA - PyNullImporter_Type=python38.PyNullImporter_Type DATA - PyNumber_Absolute=python38.PyNumber_Absolute - PyNumber_Add=python38.PyNumber_Add - PyNumber_And=python38.PyNumber_And - PyNumber_AsSsize_t=python38.PyNumber_AsSsize_t - PyNumber_Check=python38.PyNumber_Check - PyNumber_Divmod=python38.PyNumber_Divmod - PyNumber_Float=python38.PyNumber_Float - PyNumber_FloorDivide=python38.PyNumber_FloorDivide - PyNumber_InPlaceAdd=python38.PyNumber_InPlaceAdd - PyNumber_InPlaceAnd=python38.PyNumber_InPlaceAnd - PyNumber_InPlaceFloorDivide=python38.PyNumber_InPlaceFloorDivide - PyNumber_InPlaceLshift=python38.PyNumber_InPlaceLshift - PyNumber_InPlaceMatrixMultiply=python38.PyNumber_InPlaceMatrixMultiply - PyNumber_InPlaceMultiply=python38.PyNumber_InPlaceMultiply - PyNumber_InPlaceOr=python38.PyNumber_InPlaceOr - PyNumber_InPlacePower=python38.PyNumber_InPlacePower - PyNumber_InPlaceRemainder=python38.PyNumber_InPlaceRemainder - PyNumber_InPlaceRshift=python38.PyNumber_InPlaceRshift - PyNumber_InPlaceSubtract=python38.PyNumber_InPlaceSubtract - PyNumber_InPlaceTrueDivide=python38.PyNumber_InPlaceTrueDivide - PyNumber_InPlaceXor=python38.PyNumber_InPlaceXor - PyNumber_Index=python38.PyNumber_Index - PyNumber_Invert=python38.PyNumber_Invert - PyNumber_Long=python38.PyNumber_Long - PyNumber_Lshift=python38.PyNumber_Lshift - PyNumber_MatrixMultiply=python38.PyNumber_MatrixMultiply - PyNumber_Multiply=python38.PyNumber_Multiply - PyNumber_Negative=python38.PyNumber_Negative - PyNumber_Or=python38.PyNumber_Or - PyNumber_Positive=python38.PyNumber_Positive - PyNumber_Power=python38.PyNumber_Power - PyNumber_Remainder=python38.PyNumber_Remainder - PyNumber_Rshift=python38.PyNumber_Rshift - PyNumber_Subtract=python38.PyNumber_Subtract - PyNumber_ToBase=python38.PyNumber_ToBase - PyNumber_TrueDivide=python38.PyNumber_TrueDivide - PyNumber_Xor=python38.PyNumber_Xor - PyODictItems_Type=python38.PyODictItems_Type DATA - PyODictIter_Type=python38.PyODictIter_Type DATA - PyODictKeys_Type=python38.PyODictKeys_Type DATA - PyODictValues_Type=python38.PyODictValues_Type DATA - PyODict_DelItem=python38.PyODict_DelItem - PyODict_New=python38.PyODict_New - PyODict_SetItem=python38.PyODict_SetItem - PyODict_Type=python38.PyODict_Type DATA - PyOS_AfterFork=python38.PyOS_AfterFork - PyOS_CheckStack=python38.PyOS_CheckStack - PyOS_FSPath=python38.PyOS_FSPath - PyOS_InitInterrupts=python38.PyOS_InitInterrupts - PyOS_InputHook=python38.PyOS_InputHook DATA - PyOS_InterruptOccurred=python38.PyOS_InterruptOccurred - PyOS_ReadlineFunctionPointer=python38.PyOS_ReadlineFunctionPointer DATA - PyOS_double_to_string=python38.PyOS_double_to_string - PyOS_getsig=python38.PyOS_getsig - PyOS_mystricmp=python38.PyOS_mystricmp - PyOS_mystrnicmp=python38.PyOS_mystrnicmp - PyOS_setsig=python38.PyOS_setsig - PyOS_snprintf=python38.PyOS_snprintf - PyOS_string_to_double=python38.PyOS_string_to_double - PyOS_strtol=python38.PyOS_strtol - PyOS_strtoul=python38.PyOS_strtoul - PyOS_vsnprintf=python38.PyOS_vsnprintf - PyObject_ASCII=python38.PyObject_ASCII - PyObject_AsCharBuffer=python38.PyObject_AsCharBuffer - PyObject_AsFileDescriptor=python38.PyObject_AsFileDescriptor - PyObject_AsReadBuffer=python38.PyObject_AsReadBuffer - PyObject_AsWriteBuffer=python38.PyObject_AsWriteBuffer - PyObject_Bytes=python38.PyObject_Bytes - PyObject_Call=python38.PyObject_Call - PyObject_CallFunction=python38.PyObject_CallFunction - PyObject_CallFunctionObjArgs=python38.PyObject_CallFunctionObjArgs - PyObject_CallMethod=python38.PyObject_CallMethod - PyObject_CallMethodObjArgs=python38.PyObject_CallMethodObjArgs - PyObject_CallObject=python38.PyObject_CallObject - PyObject_Calloc=python38.PyObject_Calloc - PyObject_CheckReadBuffer=python38.PyObject_CheckReadBuffer - PyObject_ClearWeakRefs=python38.PyObject_ClearWeakRefs - PyObject_DelItem=python38.PyObject_DelItem - PyObject_DelItemString=python38.PyObject_DelItemString - PyObject_Dir=python38.PyObject_Dir - PyObject_Format=python38.PyObject_Format - PyObject_Free=python38.PyObject_Free - PyObject_GC_Del=python38.PyObject_GC_Del - PyObject_GC_Track=python38.PyObject_GC_Track - PyObject_GC_UnTrack=python38.PyObject_GC_UnTrack - PyObject_GenericGetAttr=python38.PyObject_GenericGetAttr - PyObject_GenericSetAttr=python38.PyObject_GenericSetAttr - PyObject_GenericSetDict=python38.PyObject_GenericSetDict - PyObject_GetAttr=python38.PyObject_GetAttr - PyObject_GetAttrString=python38.PyObject_GetAttrString - PyObject_GetItem=python38.PyObject_GetItem - PyObject_GetIter=python38.PyObject_GetIter - PyObject_HasAttr=python38.PyObject_HasAttr - PyObject_HasAttrString=python38.PyObject_HasAttrString - PyObject_Hash=python38.PyObject_Hash - PyObject_HashNotImplemented=python38.PyObject_HashNotImplemented - PyObject_Init=python38.PyObject_Init - PyObject_InitVar=python38.PyObject_InitVar - PyObject_IsInstance=python38.PyObject_IsInstance - PyObject_IsSubclass=python38.PyObject_IsSubclass - PyObject_IsTrue=python38.PyObject_IsTrue - PyObject_Length=python38.PyObject_Length - PyObject_Malloc=python38.PyObject_Malloc - PyObject_Not=python38.PyObject_Not - PyObject_Realloc=python38.PyObject_Realloc - PyObject_Repr=python38.PyObject_Repr - PyObject_RichCompare=python38.PyObject_RichCompare - PyObject_RichCompareBool=python38.PyObject_RichCompareBool - PyObject_SelfIter=python38.PyObject_SelfIter - PyObject_SetAttr=python38.PyObject_SetAttr - PyObject_SetAttrString=python38.PyObject_SetAttrString - PyObject_SetItem=python38.PyObject_SetItem - PyObject_Size=python38.PyObject_Size - PyObject_Str=python38.PyObject_Str - PyObject_Type=python38.PyObject_Type - PyParser_SimpleParseFileFlags=python38.PyParser_SimpleParseFileFlags - PyParser_SimpleParseStringFlags=python38.PyParser_SimpleParseStringFlags - PyParser_SimpleParseStringFlagsFilename=python38.PyParser_SimpleParseStringFlagsFilename - PyProperty_Type=python38.PyProperty_Type DATA - PyRangeIter_Type=python38.PyRangeIter_Type DATA - PyRange_Type=python38.PyRange_Type DATA - PyReversed_Type=python38.PyReversed_Type DATA - PySeqIter_New=python38.PySeqIter_New - PySeqIter_Type=python38.PySeqIter_Type DATA - PySequence_Check=python38.PySequence_Check - PySequence_Concat=python38.PySequence_Concat - PySequence_Contains=python38.PySequence_Contains - PySequence_Count=python38.PySequence_Count - PySequence_DelItem=python38.PySequence_DelItem - PySequence_DelSlice=python38.PySequence_DelSlice - PySequence_Fast=python38.PySequence_Fast - PySequence_GetItem=python38.PySequence_GetItem - PySequence_GetSlice=python38.PySequence_GetSlice - PySequence_In=python38.PySequence_In - PySequence_InPlaceConcat=python38.PySequence_InPlaceConcat - PySequence_InPlaceRepeat=python38.PySequence_InPlaceRepeat - PySequence_Index=python38.PySequence_Index - PySequence_Length=python38.PySequence_Length - PySequence_List=python38.PySequence_List - PySequence_Repeat=python38.PySequence_Repeat - PySequence_SetItem=python38.PySequence_SetItem - PySequence_SetSlice=python38.PySequence_SetSlice - PySequence_Size=python38.PySequence_Size - PySequence_Tuple=python38.PySequence_Tuple - PySetIter_Type=python38.PySetIter_Type DATA - PySet_Add=python38.PySet_Add - PySet_Clear=python38.PySet_Clear - PySet_Contains=python38.PySet_Contains - PySet_Discard=python38.PySet_Discard - PySet_New=python38.PySet_New - PySet_Pop=python38.PySet_Pop - PySet_Size=python38.PySet_Size - PySet_Type=python38.PySet_Type DATA - PySlice_AdjustIndices=python38.PySlice_AdjustIndices - PySlice_GetIndices=python38.PySlice_GetIndices - PySlice_GetIndicesEx=python38.PySlice_GetIndicesEx - PySlice_New=python38.PySlice_New - PySlice_Type=python38.PySlice_Type DATA - PySlice_Unpack=python38.PySlice_Unpack - PySortWrapper_Type=python38.PySortWrapper_Type DATA - PyInterpreterState_GetID=python38.PyInterpreterState_GetID - PyState_AddModule=python38.PyState_AddModule - PyState_FindModule=python38.PyState_FindModule - PyState_RemoveModule=python38.PyState_RemoveModule - PyStructSequence_GetItem=python38.PyStructSequence_GetItem - PyStructSequence_New=python38.PyStructSequence_New - PyStructSequence_NewType=python38.PyStructSequence_NewType - PyStructSequence_SetItem=python38.PyStructSequence_SetItem - PySuper_Type=python38.PySuper_Type DATA - PySys_AddWarnOption=python38.PySys_AddWarnOption - PySys_AddWarnOptionUnicode=python38.PySys_AddWarnOptionUnicode - PySys_AddXOption=python38.PySys_AddXOption - PySys_FormatStderr=python38.PySys_FormatStderr - PySys_FormatStdout=python38.PySys_FormatStdout - PySys_GetObject=python38.PySys_GetObject - PySys_GetXOptions=python38.PySys_GetXOptions - PySys_HasWarnOptions=python38.PySys_HasWarnOptions - PySys_ResetWarnOptions=python38.PySys_ResetWarnOptions - PySys_SetArgv=python38.PySys_SetArgv - PySys_SetArgvEx=python38.PySys_SetArgvEx - PySys_SetObject=python38.PySys_SetObject - PySys_SetPath=python38.PySys_SetPath - PySys_WriteStderr=python38.PySys_WriteStderr - PySys_WriteStdout=python38.PySys_WriteStdout - PyThreadState_Clear=python38.PyThreadState_Clear - PyThreadState_Delete=python38.PyThreadState_Delete - PyThreadState_DeleteCurrent=python38.PyThreadState_DeleteCurrent - PyThreadState_Get=python38.PyThreadState_Get - PyThreadState_GetDict=python38.PyThreadState_GetDict - PyThreadState_New=python38.PyThreadState_New - PyThreadState_SetAsyncExc=python38.PyThreadState_SetAsyncExc - PyThreadState_Swap=python38.PyThreadState_Swap - PyThread_tss_alloc=python38.PyThread_tss_alloc - PyThread_tss_create=python38.PyThread_tss_create - PyThread_tss_delete=python38.PyThread_tss_delete - PyThread_tss_free=python38.PyThread_tss_free - PyThread_tss_get=python38.PyThread_tss_get - PyThread_tss_is_created=python38.PyThread_tss_is_created - PyThread_tss_set=python38.PyThread_tss_set - PyTraceBack_Here=python38.PyTraceBack_Here - PyTraceBack_Print=python38.PyTraceBack_Print - PyTraceBack_Type=python38.PyTraceBack_Type DATA - PyTupleIter_Type=python38.PyTupleIter_Type DATA - PyTuple_ClearFreeList=python38.PyTuple_ClearFreeList - PyTuple_GetItem=python38.PyTuple_GetItem - PyTuple_GetSlice=python38.PyTuple_GetSlice - PyTuple_New=python38.PyTuple_New - PyTuple_Pack=python38.PyTuple_Pack - PyTuple_SetItem=python38.PyTuple_SetItem - PyTuple_Size=python38.PyTuple_Size - PyTuple_Type=python38.PyTuple_Type DATA - PyType_ClearCache=python38.PyType_ClearCache - PyType_FromSpec=python38.PyType_FromSpec - PyType_FromSpecWithBases=python38.PyType_FromSpecWithBases - PyType_GenericAlloc=python38.PyType_GenericAlloc - PyType_GenericNew=python38.PyType_GenericNew - PyType_GetFlags=python38.PyType_GetFlags - PyType_GetSlot=python38.PyType_GetSlot - PyType_IsSubtype=python38.PyType_IsSubtype - PyType_Modified=python38.PyType_Modified - PyType_Ready=python38.PyType_Ready - PyType_Type=python38.PyType_Type DATA - PyUnicodeDecodeError_Create=python38.PyUnicodeDecodeError_Create - PyUnicodeDecodeError_GetEncoding=python38.PyUnicodeDecodeError_GetEncoding - PyUnicodeDecodeError_GetEnd=python38.PyUnicodeDecodeError_GetEnd - PyUnicodeDecodeError_GetObject=python38.PyUnicodeDecodeError_GetObject - PyUnicodeDecodeError_GetReason=python38.PyUnicodeDecodeError_GetReason - PyUnicodeDecodeError_GetStart=python38.PyUnicodeDecodeError_GetStart - PyUnicodeDecodeError_SetEnd=python38.PyUnicodeDecodeError_SetEnd - PyUnicodeDecodeError_SetReason=python38.PyUnicodeDecodeError_SetReason - PyUnicodeDecodeError_SetStart=python38.PyUnicodeDecodeError_SetStart - PyUnicodeEncodeError_GetEncoding=python38.PyUnicodeEncodeError_GetEncoding - PyUnicodeEncodeError_GetEnd=python38.PyUnicodeEncodeError_GetEnd - PyUnicodeEncodeError_GetObject=python38.PyUnicodeEncodeError_GetObject - PyUnicodeEncodeError_GetReason=python38.PyUnicodeEncodeError_GetReason - PyUnicodeEncodeError_GetStart=python38.PyUnicodeEncodeError_GetStart - PyUnicodeEncodeError_SetEnd=python38.PyUnicodeEncodeError_SetEnd - PyUnicodeEncodeError_SetReason=python38.PyUnicodeEncodeError_SetReason - PyUnicodeEncodeError_SetStart=python38.PyUnicodeEncodeError_SetStart - PyUnicodeIter_Type=python38.PyUnicodeIter_Type DATA - PyUnicodeTranslateError_GetEnd=python38.PyUnicodeTranslateError_GetEnd - PyUnicodeTranslateError_GetObject=python38.PyUnicodeTranslateError_GetObject - PyUnicodeTranslateError_GetReason=python38.PyUnicodeTranslateError_GetReason - PyUnicodeTranslateError_GetStart=python38.PyUnicodeTranslateError_GetStart - PyUnicodeTranslateError_SetEnd=python38.PyUnicodeTranslateError_SetEnd - PyUnicodeTranslateError_SetReason=python38.PyUnicodeTranslateError_SetReason - PyUnicodeTranslateError_SetStart=python38.PyUnicodeTranslateError_SetStart - PyUnicode_Append=python38.PyUnicode_Append - PyUnicode_AppendAndDel=python38.PyUnicode_AppendAndDel - PyUnicode_AsASCIIString=python38.PyUnicode_AsASCIIString - PyUnicode_AsCharmapString=python38.PyUnicode_AsCharmapString - PyUnicode_AsDecodedObject=python38.PyUnicode_AsDecodedObject - PyUnicode_AsDecodedUnicode=python38.PyUnicode_AsDecodedUnicode - PyUnicode_AsEncodedObject=python38.PyUnicode_AsEncodedObject - PyUnicode_AsEncodedString=python38.PyUnicode_AsEncodedString - PyUnicode_AsEncodedUnicode=python38.PyUnicode_AsEncodedUnicode - PyUnicode_AsLatin1String=python38.PyUnicode_AsLatin1String - PyUnicode_AsMBCSString=python38.PyUnicode_AsMBCSString - PyUnicode_AsRawUnicodeEscapeString=python38.PyUnicode_AsRawUnicodeEscapeString - PyUnicode_AsUCS4=python38.PyUnicode_AsUCS4 - PyUnicode_AsUCS4Copy=python38.PyUnicode_AsUCS4Copy - PyUnicode_AsUTF16String=python38.PyUnicode_AsUTF16String - PyUnicode_AsUTF32String=python38.PyUnicode_AsUTF32String - PyUnicode_AsUTF8String=python38.PyUnicode_AsUTF8String - PyUnicode_AsUnicodeEscapeString=python38.PyUnicode_AsUnicodeEscapeString - PyUnicode_AsWideChar=python38.PyUnicode_AsWideChar - PyUnicode_AsWideCharString=python38.PyUnicode_AsWideCharString - PyUnicode_BuildEncodingMap=python38.PyUnicode_BuildEncodingMap - PyUnicode_ClearFreeList=python38.PyUnicode_ClearFreeList - PyUnicode_Compare=python38.PyUnicode_Compare - PyUnicode_CompareWithASCIIString=python38.PyUnicode_CompareWithASCIIString - PyUnicode_Concat=python38.PyUnicode_Concat - PyUnicode_Contains=python38.PyUnicode_Contains - PyUnicode_Count=python38.PyUnicode_Count - PyUnicode_Decode=python38.PyUnicode_Decode - PyUnicode_DecodeASCII=python38.PyUnicode_DecodeASCII - PyUnicode_DecodeCharmap=python38.PyUnicode_DecodeCharmap - PyUnicode_DecodeCodePageStateful=python38.PyUnicode_DecodeCodePageStateful - PyUnicode_DecodeFSDefault=python38.PyUnicode_DecodeFSDefault - PyUnicode_DecodeFSDefaultAndSize=python38.PyUnicode_DecodeFSDefaultAndSize - PyUnicode_DecodeLatin1=python38.PyUnicode_DecodeLatin1 - PyUnicode_DecodeLocale=python38.PyUnicode_DecodeLocale - PyUnicode_DecodeLocaleAndSize=python38.PyUnicode_DecodeLocaleAndSize - PyUnicode_DecodeMBCS=python38.PyUnicode_DecodeMBCS - PyUnicode_DecodeMBCSStateful=python38.PyUnicode_DecodeMBCSStateful - PyUnicode_DecodeRawUnicodeEscape=python38.PyUnicode_DecodeRawUnicodeEscape - PyUnicode_DecodeUTF16=python38.PyUnicode_DecodeUTF16 - PyUnicode_DecodeUTF16Stateful=python38.PyUnicode_DecodeUTF16Stateful - PyUnicode_DecodeUTF32=python38.PyUnicode_DecodeUTF32 - PyUnicode_DecodeUTF32Stateful=python38.PyUnicode_DecodeUTF32Stateful - PyUnicode_DecodeUTF7=python38.PyUnicode_DecodeUTF7 - PyUnicode_DecodeUTF7Stateful=python38.PyUnicode_DecodeUTF7Stateful - PyUnicode_DecodeUTF8=python38.PyUnicode_DecodeUTF8 - PyUnicode_DecodeUTF8Stateful=python38.PyUnicode_DecodeUTF8Stateful - PyUnicode_DecodeUnicodeEscape=python38.PyUnicode_DecodeUnicodeEscape - PyUnicode_EncodeCodePage=python38.PyUnicode_EncodeCodePage - PyUnicode_EncodeFSDefault=python38.PyUnicode_EncodeFSDefault - PyUnicode_EncodeLocale=python38.PyUnicode_EncodeLocale - PyUnicode_FSConverter=python38.PyUnicode_FSConverter - PyUnicode_FSDecoder=python38.PyUnicode_FSDecoder - PyUnicode_Find=python38.PyUnicode_Find - PyUnicode_FindChar=python38.PyUnicode_FindChar - PyUnicode_Format=python38.PyUnicode_Format - PyUnicode_FromEncodedObject=python38.PyUnicode_FromEncodedObject - PyUnicode_FromFormat=python38.PyUnicode_FromFormat - PyUnicode_FromFormatV=python38.PyUnicode_FromFormatV - PyUnicode_FromObject=python38.PyUnicode_FromObject - PyUnicode_FromOrdinal=python38.PyUnicode_FromOrdinal - PyUnicode_FromString=python38.PyUnicode_FromString - PyUnicode_FromStringAndSize=python38.PyUnicode_FromStringAndSize - PyUnicode_FromWideChar=python38.PyUnicode_FromWideChar - PyUnicode_GetDefaultEncoding=python38.PyUnicode_GetDefaultEncoding - PyUnicode_GetLength=python38.PyUnicode_GetLength - PyUnicode_GetSize=python38.PyUnicode_GetSize - PyUnicode_InternFromString=python38.PyUnicode_InternFromString - PyUnicode_InternImmortal=python38.PyUnicode_InternImmortal - PyUnicode_InternInPlace=python38.PyUnicode_InternInPlace - PyUnicode_IsIdentifier=python38.PyUnicode_IsIdentifier - PyUnicode_Join=python38.PyUnicode_Join - PyUnicode_Partition=python38.PyUnicode_Partition - PyUnicode_RPartition=python38.PyUnicode_RPartition - PyUnicode_RSplit=python38.PyUnicode_RSplit - PyUnicode_ReadChar=python38.PyUnicode_ReadChar - PyUnicode_Replace=python38.PyUnicode_Replace - PyUnicode_Resize=python38.PyUnicode_Resize - PyUnicode_RichCompare=python38.PyUnicode_RichCompare - PyUnicode_Split=python38.PyUnicode_Split - PyUnicode_Splitlines=python38.PyUnicode_Splitlines - PyUnicode_Substring=python38.PyUnicode_Substring - PyUnicode_Tailmatch=python38.PyUnicode_Tailmatch - PyUnicode_Translate=python38.PyUnicode_Translate - PyUnicode_Type=python38.PyUnicode_Type DATA - PyUnicode_WriteChar=python38.PyUnicode_WriteChar - PyWeakref_GetObject=python38.PyWeakref_GetObject - PyWeakref_NewProxy=python38.PyWeakref_NewProxy - PyWeakref_NewRef=python38.PyWeakref_NewRef - PyWrapperDescr_Type=python38.PyWrapperDescr_Type DATA - PyWrapper_New=python38.PyWrapper_New - PyZip_Type=python38.PyZip_Type DATA - Py_AddPendingCall=python38.Py_AddPendingCall - Py_AtExit=python38.Py_AtExit - Py_BuildValue=python38.Py_BuildValue - Py_CompileString=python38.Py_CompileString - Py_DecRef=python38.Py_DecRef - Py_DecodeLocale=python38.Py_DecodeLocale - Py_EncodeLocale=python38.Py_EncodeLocale - Py_EndInterpreter=python38.Py_EndInterpreter - Py_Exit=python38.Py_Exit - Py_FatalError=python38.Py_FatalError - Py_FileSystemDefaultEncodeErrors=python38.Py_FileSystemDefaultEncodeErrors DATA - Py_FileSystemDefaultEncoding=python38.Py_FileSystemDefaultEncoding DATA - Py_Finalize=python38.Py_Finalize - Py_FinalizeEx=python38.Py_FinalizeEx - Py_GetBuildInfo=python38.Py_GetBuildInfo - Py_GetCompiler=python38.Py_GetCompiler - Py_GetCopyright=python38.Py_GetCopyright - Py_GetExecPrefix=python38.Py_GetExecPrefix - Py_GetPath=python38.Py_GetPath - Py_GetPlatform=python38.Py_GetPlatform - Py_GetPrefix=python38.Py_GetPrefix - Py_GetProgramFullPath=python38.Py_GetProgramFullPath - Py_GetProgramName=python38.Py_GetProgramName - Py_GetPythonHome=python38.Py_GetPythonHome - Py_GetRecursionLimit=python38.Py_GetRecursionLimit - Py_GetVersion=python38.Py_GetVersion - Py_HasFileSystemDefaultEncoding=python38.Py_HasFileSystemDefaultEncoding DATA - Py_IncRef=python38.Py_IncRef - Py_Initialize=python38.Py_Initialize - Py_InitializeEx=python38.Py_InitializeEx - Py_IsInitialized=python38.Py_IsInitialized - Py_Main=python38.Py_Main - Py_MakePendingCalls=python38.Py_MakePendingCalls - Py_NewInterpreter=python38.Py_NewInterpreter - Py_ReprEnter=python38.Py_ReprEnter - Py_ReprLeave=python38.Py_ReprLeave - Py_SetPath=python38.Py_SetPath - Py_SetProgramName=python38.Py_SetProgramName - Py_SetPythonHome=python38.Py_SetPythonHome - Py_SetRecursionLimit=python38.Py_SetRecursionLimit - Py_SymtableString=python38.Py_SymtableString - Py_UTF8Mode=python38.Py_UTF8Mode DATA - Py_VaBuildValue=python38.Py_VaBuildValue - _PyArg_ParseTupleAndKeywords_SizeT=python38._PyArg_ParseTupleAndKeywords_SizeT - _PyArg_ParseTuple_SizeT=python38._PyArg_ParseTuple_SizeT - _PyArg_Parse_SizeT=python38._PyArg_Parse_SizeT - _PyArg_VaParseTupleAndKeywords_SizeT=python38._PyArg_VaParseTupleAndKeywords_SizeT - _PyArg_VaParse_SizeT=python38._PyArg_VaParse_SizeT - _PyErr_BadInternalCall=python38._PyErr_BadInternalCall - _PyObject_CallFunction_SizeT=python38._PyObject_CallFunction_SizeT - _PyObject_CallMethod_SizeT=python38._PyObject_CallMethod_SizeT - _PyObject_GC_Malloc=python38._PyObject_GC_Malloc - _PyObject_GC_New=python38._PyObject_GC_New - _PyObject_GC_NewVar=python38._PyObject_GC_NewVar - _PyObject_GC_Resize=python38._PyObject_GC_Resize - _PyObject_New=python38._PyObject_New - _PyObject_NewVar=python38._PyObject_NewVar - _PyState_AddModule=python38._PyState_AddModule - _PyThreadState_Init=python38._PyThreadState_Init - _PyThreadState_Prealloc=python38._PyThreadState_Prealloc - _PyTrash_delete_later=python38._PyTrash_delete_later DATA - _PyTrash_delete_nesting=python38._PyTrash_delete_nesting DATA - _PyTrash_deposit_object=python38._PyTrash_deposit_object - _PyTrash_destroy_chain=python38._PyTrash_destroy_chain - _PyTrash_thread_deposit_object=python38._PyTrash_thread_deposit_object - _PyTrash_thread_destroy_chain=python38._PyTrash_thread_destroy_chain - _PyWeakref_CallableProxyType=python38._PyWeakref_CallableProxyType DATA - _PyWeakref_ProxyType=python38._PyWeakref_ProxyType DATA - _PyWeakref_RefType=python38._PyWeakref_RefType DATA - _Py_BuildValue_SizeT=python38._Py_BuildValue_SizeT - _Py_CheckRecursionLimit=python38._Py_CheckRecursionLimit DATA - _Py_CheckRecursiveCall=python38._Py_CheckRecursiveCall - _Py_Dealloc=python38._Py_Dealloc - _Py_EllipsisObject=python38._Py_EllipsisObject DATA - _Py_FalseStruct=python38._Py_FalseStruct DATA - _Py_NoneStruct=python38._Py_NoneStruct DATA - _Py_NotImplementedStruct=python38._Py_NotImplementedStruct DATA - _Py_SwappedOp=python38._Py_SwappedOp DATA - _Py_TrueStruct=python38._Py_TrueStruct DATA - _Py_VaBuildValue_SizeT=python38._Py_VaBuildValue_SizeT + PyArg_Parse=python39.PyArg_Parse + PyArg_ParseTuple=python39.PyArg_ParseTuple + PyArg_ParseTupleAndKeywords=python39.PyArg_ParseTupleAndKeywords + PyArg_UnpackTuple=python39.PyArg_UnpackTuple + PyArg_VaParse=python39.PyArg_VaParse + PyArg_VaParseTupleAndKeywords=python39.PyArg_VaParseTupleAndKeywords + PyArg_ValidateKeywordArguments=python39.PyArg_ValidateKeywordArguments + PyBaseObject_Type=python39.PyBaseObject_Type DATA + PyBool_FromLong=python39.PyBool_FromLong + PyBool_Type=python39.PyBool_Type DATA + PyByteArrayIter_Type=python39.PyByteArrayIter_Type DATA + PyByteArray_AsString=python39.PyByteArray_AsString + PyByteArray_Concat=python39.PyByteArray_Concat + PyByteArray_FromObject=python39.PyByteArray_FromObject + PyByteArray_FromStringAndSize=python39.PyByteArray_FromStringAndSize + PyByteArray_Resize=python39.PyByteArray_Resize + PyByteArray_Size=python39.PyByteArray_Size + PyByteArray_Type=python39.PyByteArray_Type DATA + PyBytesIter_Type=python39.PyBytesIter_Type DATA + PyBytes_AsString=python39.PyBytes_AsString + PyBytes_AsStringAndSize=python39.PyBytes_AsStringAndSize + PyBytes_Concat=python39.PyBytes_Concat + PyBytes_ConcatAndDel=python39.PyBytes_ConcatAndDel + PyBytes_DecodeEscape=python39.PyBytes_DecodeEscape + PyBytes_FromFormat=python39.PyBytes_FromFormat + PyBytes_FromFormatV=python39.PyBytes_FromFormatV + PyBytes_FromObject=python39.PyBytes_FromObject + PyBytes_FromString=python39.PyBytes_FromString + PyBytes_FromStringAndSize=python39.PyBytes_FromStringAndSize + PyBytes_Repr=python39.PyBytes_Repr + PyBytes_Size=python39.PyBytes_Size + PyBytes_Type=python39.PyBytes_Type DATA + PyCFunction_Call=python39.PyCFunction_Call + PyCFunction_ClearFreeList=python39.PyCFunction_ClearFreeList + PyCFunction_GetFlags=python39.PyCFunction_GetFlags + PyCFunction_GetFunction=python39.PyCFunction_GetFunction + PyCFunction_GetSelf=python39.PyCFunction_GetSelf + PyCFunction_New=python39.PyCFunction_New + PyCFunction_NewEx=python39.PyCFunction_NewEx + PyCFunction_Type=python39.PyCFunction_Type DATA + PyCallIter_New=python39.PyCallIter_New + PyCallIter_Type=python39.PyCallIter_Type DATA + PyCallable_Check=python39.PyCallable_Check + PyCapsule_GetContext=python39.PyCapsule_GetContext + PyCapsule_GetDestructor=python39.PyCapsule_GetDestructor + PyCapsule_GetName=python39.PyCapsule_GetName + PyCapsule_GetPointer=python39.PyCapsule_GetPointer + PyCapsule_Import=python39.PyCapsule_Import + PyCapsule_IsValid=python39.PyCapsule_IsValid + PyCapsule_New=python39.PyCapsule_New + PyCapsule_SetContext=python39.PyCapsule_SetContext + PyCapsule_SetDestructor=python39.PyCapsule_SetDestructor + PyCapsule_SetName=python39.PyCapsule_SetName + PyCapsule_SetPointer=python39.PyCapsule_SetPointer + PyCapsule_Type=python39.PyCapsule_Type DATA + PyClassMethodDescr_Type=python39.PyClassMethodDescr_Type DATA + PyCodec_BackslashReplaceErrors=python39.PyCodec_BackslashReplaceErrors + PyCodec_Decode=python39.PyCodec_Decode + PyCodec_Decoder=python39.PyCodec_Decoder + PyCodec_Encode=python39.PyCodec_Encode + PyCodec_Encoder=python39.PyCodec_Encoder + PyCodec_IgnoreErrors=python39.PyCodec_IgnoreErrors + PyCodec_IncrementalDecoder=python39.PyCodec_IncrementalDecoder + PyCodec_IncrementalEncoder=python39.PyCodec_IncrementalEncoder + PyCodec_KnownEncoding=python39.PyCodec_KnownEncoding + PyCodec_LookupError=python39.PyCodec_LookupError + PyCodec_NameReplaceErrors=python39.PyCodec_NameReplaceErrors + PyCodec_Register=python39.PyCodec_Register + PyCodec_RegisterError=python39.PyCodec_RegisterError + PyCodec_ReplaceErrors=python39.PyCodec_ReplaceErrors + PyCodec_StreamReader=python39.PyCodec_StreamReader + PyCodec_StreamWriter=python39.PyCodec_StreamWriter + PyCodec_StrictErrors=python39.PyCodec_StrictErrors + PyCodec_XMLCharRefReplaceErrors=python39.PyCodec_XMLCharRefReplaceErrors + PyComplex_FromDoubles=python39.PyComplex_FromDoubles + PyComplex_ImagAsDouble=python39.PyComplex_ImagAsDouble + PyComplex_RealAsDouble=python39.PyComplex_RealAsDouble + PyComplex_Type=python39.PyComplex_Type DATA + PyDescr_NewClassMethod=python39.PyDescr_NewClassMethod + PyDescr_NewGetSet=python39.PyDescr_NewGetSet + PyDescr_NewMember=python39.PyDescr_NewMember + PyDescr_NewMethod=python39.PyDescr_NewMethod + PyDictItems_Type=python39.PyDictItems_Type DATA + PyDictIterItem_Type=python39.PyDictIterItem_Type DATA + PyDictIterKey_Type=python39.PyDictIterKey_Type DATA + PyDictIterValue_Type=python39.PyDictIterValue_Type DATA + PyDictKeys_Type=python39.PyDictKeys_Type DATA + PyDictProxy_New=python39.PyDictProxy_New + PyDictProxy_Type=python39.PyDictProxy_Type DATA + PyDictValues_Type=python39.PyDictValues_Type DATA + PyDict_Clear=python39.PyDict_Clear + PyDict_Contains=python39.PyDict_Contains + PyDict_Copy=python39.PyDict_Copy + PyDict_DelItem=python39.PyDict_DelItem + PyDict_DelItemString=python39.PyDict_DelItemString + PyDict_GetItem=python39.PyDict_GetItem + PyDict_GetItemString=python39.PyDict_GetItemString + PyDict_GetItemWithError=python39.PyDict_GetItemWithError + PyDict_Items=python39.PyDict_Items + PyDict_Keys=python39.PyDict_Keys + PyDict_Merge=python39.PyDict_Merge + PyDict_MergeFromSeq2=python39.PyDict_MergeFromSeq2 + PyDict_New=python39.PyDict_New + PyDict_Next=python39.PyDict_Next + PyDict_SetItem=python39.PyDict_SetItem + PyDict_SetItemString=python39.PyDict_SetItemString + PyDict_Size=python39.PyDict_Size + PyDict_Type=python39.PyDict_Type DATA + PyDict_Update=python39.PyDict_Update + PyDict_Values=python39.PyDict_Values + PyEllipsis_Type=python39.PyEllipsis_Type DATA + PyEnum_Type=python39.PyEnum_Type DATA + PyErr_BadArgument=python39.PyErr_BadArgument + PyErr_BadInternalCall=python39.PyErr_BadInternalCall + PyErr_CheckSignals=python39.PyErr_CheckSignals + PyErr_Clear=python39.PyErr_Clear + PyErr_Display=python39.PyErr_Display + PyErr_ExceptionMatches=python39.PyErr_ExceptionMatches + PyErr_Fetch=python39.PyErr_Fetch + PyErr_Format=python39.PyErr_Format + PyErr_FormatV=python39.PyErr_FormatV + PyErr_GetExcInfo=python39.PyErr_GetExcInfo + PyErr_GivenExceptionMatches=python39.PyErr_GivenExceptionMatches + PyErr_NewException=python39.PyErr_NewException + PyErr_NewExceptionWithDoc=python39.PyErr_NewExceptionWithDoc + PyErr_NoMemory=python39.PyErr_NoMemory + PyErr_NormalizeException=python39.PyErr_NormalizeException + PyErr_Occurred=python39.PyErr_Occurred + PyErr_Print=python39.PyErr_Print + PyErr_PrintEx=python39.PyErr_PrintEx + PyErr_ProgramText=python39.PyErr_ProgramText + PyErr_ResourceWarning=python39.PyErr_ResourceWarning + PyErr_Restore=python39.PyErr_Restore + PyErr_SetExcFromWindowsErr=python39.PyErr_SetExcFromWindowsErr + PyErr_SetExcFromWindowsErrWithFilename=python39.PyErr_SetExcFromWindowsErrWithFilename + PyErr_SetExcFromWindowsErrWithFilenameObject=python39.PyErr_SetExcFromWindowsErrWithFilenameObject + PyErr_SetExcFromWindowsErrWithFilenameObjects=python39.PyErr_SetExcFromWindowsErrWithFilenameObjects + PyErr_SetExcInfo=python39.PyErr_SetExcInfo + PyErr_SetFromErrno=python39.PyErr_SetFromErrno + PyErr_SetFromErrnoWithFilename=python39.PyErr_SetFromErrnoWithFilename + PyErr_SetFromErrnoWithFilenameObject=python39.PyErr_SetFromErrnoWithFilenameObject + PyErr_SetFromErrnoWithFilenameObjects=python39.PyErr_SetFromErrnoWithFilenameObjects + PyErr_SetFromWindowsErr=python39.PyErr_SetFromWindowsErr + PyErr_SetFromWindowsErrWithFilename=python39.PyErr_SetFromWindowsErrWithFilename + PyErr_SetImportError=python39.PyErr_SetImportError + PyErr_SetImportErrorSubclass=python39.PyErr_SetImportErrorSubclass + PyErr_SetInterrupt=python39.PyErr_SetInterrupt + PyErr_SetNone=python39.PyErr_SetNone + PyErr_SetObject=python39.PyErr_SetObject + PyErr_SetString=python39.PyErr_SetString + PyErr_SyntaxLocation=python39.PyErr_SyntaxLocation + PyErr_SyntaxLocationEx=python39.PyErr_SyntaxLocationEx + PyErr_WarnEx=python39.PyErr_WarnEx + PyErr_WarnExplicit=python39.PyErr_WarnExplicit + PyErr_WarnFormat=python39.PyErr_WarnFormat + PyErr_WriteUnraisable=python39.PyErr_WriteUnraisable + PyEval_AcquireLock=python39.PyEval_AcquireLock + PyEval_AcquireThread=python39.PyEval_AcquireThread + PyEval_CallFunction=python39.PyEval_CallFunction + PyEval_CallMethod=python39.PyEval_CallMethod + PyEval_CallObjectWithKeywords=python39.PyEval_CallObjectWithKeywords + PyEval_EvalCode=python39.PyEval_EvalCode + PyEval_EvalCodeEx=python39.PyEval_EvalCodeEx + PyEval_EvalFrame=python39.PyEval_EvalFrame + PyEval_EvalFrameEx=python39.PyEval_EvalFrameEx + PyEval_GetBuiltins=python39.PyEval_GetBuiltins + PyEval_GetCallStats=python39.PyEval_GetCallStats + PyEval_GetFrame=python39.PyEval_GetFrame + PyEval_GetFuncDesc=python39.PyEval_GetFuncDesc + PyEval_GetFuncName=python39.PyEval_GetFuncName + PyEval_GetGlobals=python39.PyEval_GetGlobals + PyEval_GetLocals=python39.PyEval_GetLocals + PyEval_InitThreads=python39.PyEval_InitThreads + PyEval_ReInitThreads=python39.PyEval_ReInitThreads + PyEval_ReleaseLock=python39.PyEval_ReleaseLock + PyEval_ReleaseThread=python39.PyEval_ReleaseThread + PyEval_RestoreThread=python39.PyEval_RestoreThread + PyEval_SaveThread=python39.PyEval_SaveThread + PyEval_ThreadsInitialized=python39.PyEval_ThreadsInitialized + PyExc_ArithmeticError=python39.PyExc_ArithmeticError DATA + PyExc_AssertionError=python39.PyExc_AssertionError DATA + PyExc_AttributeError=python39.PyExc_AttributeError DATA + PyExc_BaseException=python39.PyExc_BaseException DATA + PyExc_BlockingIOError=python39.PyExc_BlockingIOError DATA + PyExc_BrokenPipeError=python39.PyExc_BrokenPipeError DATA + PyExc_BufferError=python39.PyExc_BufferError DATA + PyExc_BytesWarning=python39.PyExc_BytesWarning DATA + PyExc_ChildProcessError=python39.PyExc_ChildProcessError DATA + PyExc_ConnectionAbortedError=python39.PyExc_ConnectionAbortedError DATA + PyExc_ConnectionError=python39.PyExc_ConnectionError DATA + PyExc_ConnectionRefusedError=python39.PyExc_ConnectionRefusedError DATA + PyExc_ConnectionResetError=python39.PyExc_ConnectionResetError DATA + PyExc_DeprecationWarning=python39.PyExc_DeprecationWarning DATA + PyExc_EOFError=python39.PyExc_EOFError DATA + PyExc_EnvironmentError=python39.PyExc_EnvironmentError DATA + PyExc_Exception=python39.PyExc_Exception DATA + PyExc_FileExistsError=python39.PyExc_FileExistsError DATA + PyExc_FileNotFoundError=python39.PyExc_FileNotFoundError DATA + PyExc_FloatingPointError=python39.PyExc_FloatingPointError DATA + PyExc_FutureWarning=python39.PyExc_FutureWarning DATA + PyExc_GeneratorExit=python39.PyExc_GeneratorExit DATA + PyExc_IOError=python39.PyExc_IOError DATA + PyExc_ImportError=python39.PyExc_ImportError DATA + PyExc_ImportWarning=python39.PyExc_ImportWarning DATA + PyExc_IndentationError=python39.PyExc_IndentationError DATA + PyExc_IndexError=python39.PyExc_IndexError DATA + PyExc_InterruptedError=python39.PyExc_InterruptedError DATA + PyExc_IsADirectoryError=python39.PyExc_IsADirectoryError DATA + PyExc_KeyError=python39.PyExc_KeyError DATA + PyExc_KeyboardInterrupt=python39.PyExc_KeyboardInterrupt DATA + PyExc_LookupError=python39.PyExc_LookupError DATA + PyExc_MemoryError=python39.PyExc_MemoryError DATA + PyExc_ModuleNotFoundError=python39.PyExc_ModuleNotFoundError DATA + PyExc_NameError=python39.PyExc_NameError DATA + PyExc_NotADirectoryError=python39.PyExc_NotADirectoryError DATA + PyExc_NotImplementedError=python39.PyExc_NotImplementedError DATA + PyExc_OSError=python39.PyExc_OSError DATA + PyExc_OverflowError=python39.PyExc_OverflowError DATA + PyExc_PendingDeprecationWarning=python39.PyExc_PendingDeprecationWarning DATA + PyExc_PermissionError=python39.PyExc_PermissionError DATA + PyExc_ProcessLookupError=python39.PyExc_ProcessLookupError DATA + PyExc_RecursionError=python39.PyExc_RecursionError DATA + PyExc_ReferenceError=python39.PyExc_ReferenceError DATA + PyExc_ResourceWarning=python39.PyExc_ResourceWarning DATA + PyExc_RuntimeError=python39.PyExc_RuntimeError DATA + PyExc_RuntimeWarning=python39.PyExc_RuntimeWarning DATA + PyExc_StopAsyncIteration=python39.PyExc_StopAsyncIteration DATA + PyExc_StopIteration=python39.PyExc_StopIteration DATA + PyExc_SyntaxError=python39.PyExc_SyntaxError DATA + PyExc_SyntaxWarning=python39.PyExc_SyntaxWarning DATA + PyExc_SystemError=python39.PyExc_SystemError DATA + PyExc_SystemExit=python39.PyExc_SystemExit DATA + PyExc_TabError=python39.PyExc_TabError DATA + PyExc_TargetScopeError=python39.PyExc_TargetScopeError DATA + PyExc_TimeoutError=python39.PyExc_TimeoutError DATA + PyExc_TypeError=python39.PyExc_TypeError DATA + PyExc_UnboundLocalError=python39.PyExc_UnboundLocalError DATA + PyExc_UnicodeDecodeError=python39.PyExc_UnicodeDecodeError DATA + PyExc_UnicodeEncodeError=python39.PyExc_UnicodeEncodeError DATA + PyExc_UnicodeError=python39.PyExc_UnicodeError DATA + PyExc_UnicodeTranslateError=python39.PyExc_UnicodeTranslateError DATA + PyExc_UnicodeWarning=python39.PyExc_UnicodeWarning DATA + PyExc_UserWarning=python39.PyExc_UserWarning DATA + PyExc_ValueError=python39.PyExc_ValueError DATA + PyExc_Warning=python39.PyExc_Warning DATA + PyExc_WindowsError=python39.PyExc_WindowsError DATA + PyExc_ZeroDivisionError=python39.PyExc_ZeroDivisionError DATA + PyExceptionClass_Name=python39.PyExceptionClass_Name + PyException_GetCause=python39.PyException_GetCause + PyException_GetContext=python39.PyException_GetContext + PyException_GetTraceback=python39.PyException_GetTraceback + PyException_SetCause=python39.PyException_SetCause + PyException_SetContext=python39.PyException_SetContext + PyException_SetTraceback=python39.PyException_SetTraceback + PyFile_FromFd=python39.PyFile_FromFd + PyFile_GetLine=python39.PyFile_GetLine + PyFile_WriteObject=python39.PyFile_WriteObject + PyFile_WriteString=python39.PyFile_WriteString + PyFilter_Type=python39.PyFilter_Type DATA + PyFloat_AsDouble=python39.PyFloat_AsDouble + PyFloat_FromDouble=python39.PyFloat_FromDouble + PyFloat_FromString=python39.PyFloat_FromString + PyFloat_GetInfo=python39.PyFloat_GetInfo + PyFloat_GetMax=python39.PyFloat_GetMax + PyFloat_GetMin=python39.PyFloat_GetMin + PyFloat_Type=python39.PyFloat_Type DATA + PyFrozenSet_New=python39.PyFrozenSet_New + PyFrozenSet_Type=python39.PyFrozenSet_Type DATA + PyGC_Collect=python39.PyGC_Collect + PyGILState_Ensure=python39.PyGILState_Ensure + PyGILState_GetThisThreadState=python39.PyGILState_GetThisThreadState + PyGILState_Release=python39.PyGILState_Release + PyGetSetDescr_Type=python39.PyGetSetDescr_Type DATA + PyImport_AddModule=python39.PyImport_AddModule + PyImport_AddModuleObject=python39.PyImport_AddModuleObject + PyImport_AppendInittab=python39.PyImport_AppendInittab + PyImport_Cleanup=python39.PyImport_Cleanup + PyImport_ExecCodeModule=python39.PyImport_ExecCodeModule + PyImport_ExecCodeModuleEx=python39.PyImport_ExecCodeModuleEx + PyImport_ExecCodeModuleObject=python39.PyImport_ExecCodeModuleObject + PyImport_ExecCodeModuleWithPathnames=python39.PyImport_ExecCodeModuleWithPathnames + PyImport_GetImporter=python39.PyImport_GetImporter + PyImport_GetMagicNumber=python39.PyImport_GetMagicNumber + PyImport_GetMagicTag=python39.PyImport_GetMagicTag + PyImport_GetModule=python39.PyImport_GetModule + PyImport_GetModuleDict=python39.PyImport_GetModuleDict + PyImport_Import=python39.PyImport_Import + PyImport_ImportFrozenModule=python39.PyImport_ImportFrozenModule + PyImport_ImportFrozenModuleObject=python39.PyImport_ImportFrozenModuleObject + PyImport_ImportModule=python39.PyImport_ImportModule + PyImport_ImportModuleLevel=python39.PyImport_ImportModuleLevel + PyImport_ImportModuleLevelObject=python39.PyImport_ImportModuleLevelObject + PyImport_ImportModuleNoBlock=python39.PyImport_ImportModuleNoBlock + PyImport_ReloadModule=python39.PyImport_ReloadModule + PyIndex_Check=python39.PyIndex_Check + PyInterpreterState_Clear=python39.PyInterpreterState_Clear + PyInterpreterState_Delete=python39.PyInterpreterState_Delete + PyInterpreterState_New=python39.PyInterpreterState_New + PyIter_Check=python39.PyIter_Check + PyIter_Next=python39.PyIter_Next + PyListIter_Type=python39.PyListIter_Type DATA + PyListRevIter_Type=python39.PyListRevIter_Type DATA + PyList_Append=python39.PyList_Append + PyList_AsTuple=python39.PyList_AsTuple + PyList_GetItem=python39.PyList_GetItem + PyList_GetSlice=python39.PyList_GetSlice + PyList_Insert=python39.PyList_Insert + PyList_New=python39.PyList_New + PyList_Reverse=python39.PyList_Reverse + PyList_SetItem=python39.PyList_SetItem + PyList_SetSlice=python39.PyList_SetSlice + PyList_Size=python39.PyList_Size + PyList_Sort=python39.PyList_Sort + PyList_Type=python39.PyList_Type DATA + PyLongRangeIter_Type=python39.PyLongRangeIter_Type DATA + PyLong_AsDouble=python39.PyLong_AsDouble + PyLong_AsLong=python39.PyLong_AsLong + PyLong_AsLongAndOverflow=python39.PyLong_AsLongAndOverflow + PyLong_AsLongLong=python39.PyLong_AsLongLong + PyLong_AsLongLongAndOverflow=python39.PyLong_AsLongLongAndOverflow + PyLong_AsSize_t=python39.PyLong_AsSize_t + PyLong_AsSsize_t=python39.PyLong_AsSsize_t + PyLong_AsUnsignedLong=python39.PyLong_AsUnsignedLong + PyLong_AsUnsignedLongLong=python39.PyLong_AsUnsignedLongLong + PyLong_AsUnsignedLongLongMask=python39.PyLong_AsUnsignedLongLongMask + PyLong_AsUnsignedLongMask=python39.PyLong_AsUnsignedLongMask + PyLong_AsVoidPtr=python39.PyLong_AsVoidPtr + PyLong_FromDouble=python39.PyLong_FromDouble + PyLong_FromLong=python39.PyLong_FromLong + PyLong_FromLongLong=python39.PyLong_FromLongLong + PyLong_FromSize_t=python39.PyLong_FromSize_t + PyLong_FromSsize_t=python39.PyLong_FromSsize_t + PyLong_FromString=python39.PyLong_FromString + PyLong_FromUnsignedLong=python39.PyLong_FromUnsignedLong + PyLong_FromUnsignedLongLong=python39.PyLong_FromUnsignedLongLong + PyLong_FromVoidPtr=python39.PyLong_FromVoidPtr + PyLong_GetInfo=python39.PyLong_GetInfo + PyLong_Type=python39.PyLong_Type DATA + PyMap_Type=python39.PyMap_Type DATA + PyMapping_Check=python39.PyMapping_Check + PyMapping_GetItemString=python39.PyMapping_GetItemString + PyMapping_HasKey=python39.PyMapping_HasKey + PyMapping_HasKeyString=python39.PyMapping_HasKeyString + PyMapping_Items=python39.PyMapping_Items + PyMapping_Keys=python39.PyMapping_Keys + PyMapping_Length=python39.PyMapping_Length + PyMapping_SetItemString=python39.PyMapping_SetItemString + PyMapping_Size=python39.PyMapping_Size + PyMapping_Values=python39.PyMapping_Values + PyMem_Calloc=python39.PyMem_Calloc + PyMem_Free=python39.PyMem_Free + PyMem_Malloc=python39.PyMem_Malloc + PyMem_Realloc=python39.PyMem_Realloc + PyMemberDescr_Type=python39.PyMemberDescr_Type DATA + PyMemoryView_FromMemory=python39.PyMemoryView_FromMemory + PyMemoryView_FromObject=python39.PyMemoryView_FromObject + PyMemoryView_GetContiguous=python39.PyMemoryView_GetContiguous + PyMemoryView_Type=python39.PyMemoryView_Type DATA + PyMethodDescr_Type=python39.PyMethodDescr_Type DATA + PyModuleDef_Init=python39.PyModuleDef_Init + PyModuleDef_Type=python39.PyModuleDef_Type DATA + PyModule_AddFunctions=python39.PyModule_AddFunctions + PyModule_AddIntConstant=python39.PyModule_AddIntConstant + PyModule_AddObject=python39.PyModule_AddObject + PyModule_AddStringConstant=python39.PyModule_AddStringConstant + PyModule_Create2=python39.PyModule_Create2 + PyModule_ExecDef=python39.PyModule_ExecDef + PyModule_FromDefAndSpec2=python39.PyModule_FromDefAndSpec2 + PyModule_GetDef=python39.PyModule_GetDef + PyModule_GetDict=python39.PyModule_GetDict + PyModule_GetFilename=python39.PyModule_GetFilename + PyModule_GetFilenameObject=python39.PyModule_GetFilenameObject + PyModule_GetName=python39.PyModule_GetName + PyModule_GetNameObject=python39.PyModule_GetNameObject + PyModule_GetState=python39.PyModule_GetState + PyModule_New=python39.PyModule_New + PyModule_NewObject=python39.PyModule_NewObject + PyModule_SetDocString=python39.PyModule_SetDocString + PyModule_Type=python39.PyModule_Type DATA + PyNullImporter_Type=python39.PyNullImporter_Type DATA + PyNumber_Absolute=python39.PyNumber_Absolute + PyNumber_Add=python39.PyNumber_Add + PyNumber_And=python39.PyNumber_And + PyNumber_AsSsize_t=python39.PyNumber_AsSsize_t + PyNumber_Check=python39.PyNumber_Check + PyNumber_Divmod=python39.PyNumber_Divmod + PyNumber_Float=python39.PyNumber_Float + PyNumber_FloorDivide=python39.PyNumber_FloorDivide + PyNumber_InPlaceAdd=python39.PyNumber_InPlaceAdd + PyNumber_InPlaceAnd=python39.PyNumber_InPlaceAnd + PyNumber_InPlaceFloorDivide=python39.PyNumber_InPlaceFloorDivide + PyNumber_InPlaceLshift=python39.PyNumber_InPlaceLshift + PyNumber_InPlaceMatrixMultiply=python39.PyNumber_InPlaceMatrixMultiply + PyNumber_InPlaceMultiply=python39.PyNumber_InPlaceMultiply + PyNumber_InPlaceOr=python39.PyNumber_InPlaceOr + PyNumber_InPlacePower=python39.PyNumber_InPlacePower + PyNumber_InPlaceRemainder=python39.PyNumber_InPlaceRemainder + PyNumber_InPlaceRshift=python39.PyNumber_InPlaceRshift + PyNumber_InPlaceSubtract=python39.PyNumber_InPlaceSubtract + PyNumber_InPlaceTrueDivide=python39.PyNumber_InPlaceTrueDivide + PyNumber_InPlaceXor=python39.PyNumber_InPlaceXor + PyNumber_Index=python39.PyNumber_Index + PyNumber_Invert=python39.PyNumber_Invert + PyNumber_Long=python39.PyNumber_Long + PyNumber_Lshift=python39.PyNumber_Lshift + PyNumber_MatrixMultiply=python39.PyNumber_MatrixMultiply + PyNumber_Multiply=python39.PyNumber_Multiply + PyNumber_Negative=python39.PyNumber_Negative + PyNumber_Or=python39.PyNumber_Or + PyNumber_Positive=python39.PyNumber_Positive + PyNumber_Power=python39.PyNumber_Power + PyNumber_Remainder=python39.PyNumber_Remainder + PyNumber_Rshift=python39.PyNumber_Rshift + PyNumber_Subtract=python39.PyNumber_Subtract + PyNumber_ToBase=python39.PyNumber_ToBase + PyNumber_TrueDivide=python39.PyNumber_TrueDivide + PyNumber_Xor=python39.PyNumber_Xor + PyODictItems_Type=python39.PyODictItems_Type DATA + PyODictIter_Type=python39.PyODictIter_Type DATA + PyODictKeys_Type=python39.PyODictKeys_Type DATA + PyODictValues_Type=python39.PyODictValues_Type DATA + PyODict_DelItem=python39.PyODict_DelItem + PyODict_New=python39.PyODict_New + PyODict_SetItem=python39.PyODict_SetItem + PyODict_Type=python39.PyODict_Type DATA + PyOS_AfterFork=python39.PyOS_AfterFork + PyOS_CheckStack=python39.PyOS_CheckStack + PyOS_FSPath=python39.PyOS_FSPath + PyOS_InitInterrupts=python39.PyOS_InitInterrupts + PyOS_InputHook=python39.PyOS_InputHook DATA + PyOS_InterruptOccurred=python39.PyOS_InterruptOccurred + PyOS_ReadlineFunctionPointer=python39.PyOS_ReadlineFunctionPointer DATA + PyOS_double_to_string=python39.PyOS_double_to_string + PyOS_getsig=python39.PyOS_getsig + PyOS_mystricmp=python39.PyOS_mystricmp + PyOS_mystrnicmp=python39.PyOS_mystrnicmp + PyOS_setsig=python39.PyOS_setsig + PyOS_snprintf=python39.PyOS_snprintf + PyOS_string_to_double=python39.PyOS_string_to_double + PyOS_strtol=python39.PyOS_strtol + PyOS_strtoul=python39.PyOS_strtoul + PyOS_vsnprintf=python39.PyOS_vsnprintf + PyObject_ASCII=python39.PyObject_ASCII + PyObject_AsCharBuffer=python39.PyObject_AsCharBuffer + PyObject_AsFileDescriptor=python39.PyObject_AsFileDescriptor + PyObject_AsReadBuffer=python39.PyObject_AsReadBuffer + PyObject_AsWriteBuffer=python39.PyObject_AsWriteBuffer + PyObject_Bytes=python39.PyObject_Bytes + PyObject_Call=python39.PyObject_Call + PyObject_CallFunction=python39.PyObject_CallFunction + PyObject_CallFunctionObjArgs=python39.PyObject_CallFunctionObjArgs + PyObject_CallMethod=python39.PyObject_CallMethod + PyObject_CallMethodObjArgs=python39.PyObject_CallMethodObjArgs + PyObject_CallObject=python39.PyObject_CallObject + PyObject_Calloc=python39.PyObject_Calloc + PyObject_CheckReadBuffer=python39.PyObject_CheckReadBuffer + PyObject_ClearWeakRefs=python39.PyObject_ClearWeakRefs + PyObject_DelItem=python39.PyObject_DelItem + PyObject_DelItemString=python39.PyObject_DelItemString + PyObject_Dir=python39.PyObject_Dir + PyObject_Format=python39.PyObject_Format + PyObject_Free=python39.PyObject_Free + PyObject_GC_Del=python39.PyObject_GC_Del + PyObject_GC_Track=python39.PyObject_GC_Track + PyObject_GC_UnTrack=python39.PyObject_GC_UnTrack + PyObject_GenericGetAttr=python39.PyObject_GenericGetAttr + PyObject_GenericSetAttr=python39.PyObject_GenericSetAttr + PyObject_GenericSetDict=python39.PyObject_GenericSetDict + PyObject_GetAttr=python39.PyObject_GetAttr + PyObject_GetAttrString=python39.PyObject_GetAttrString + PyObject_GetItem=python39.PyObject_GetItem + PyObject_GetIter=python39.PyObject_GetIter + PyObject_HasAttr=python39.PyObject_HasAttr + PyObject_HasAttrString=python39.PyObject_HasAttrString + PyObject_Hash=python39.PyObject_Hash + PyObject_HashNotImplemented=python39.PyObject_HashNotImplemented + PyObject_Init=python39.PyObject_Init + PyObject_InitVar=python39.PyObject_InitVar + PyObject_IsInstance=python39.PyObject_IsInstance + PyObject_IsSubclass=python39.PyObject_IsSubclass + PyObject_IsTrue=python39.PyObject_IsTrue + PyObject_Length=python39.PyObject_Length + PyObject_Malloc=python39.PyObject_Malloc + PyObject_Not=python39.PyObject_Not + PyObject_Realloc=python39.PyObject_Realloc + PyObject_Repr=python39.PyObject_Repr + PyObject_RichCompare=python39.PyObject_RichCompare + PyObject_RichCompareBool=python39.PyObject_RichCompareBool + PyObject_SelfIter=python39.PyObject_SelfIter + PyObject_SetAttr=python39.PyObject_SetAttr + PyObject_SetAttrString=python39.PyObject_SetAttrString + PyObject_SetItem=python39.PyObject_SetItem + PyObject_Size=python39.PyObject_Size + PyObject_Str=python39.PyObject_Str + PyObject_Type=python39.PyObject_Type + PyParser_SimpleParseFileFlags=python39.PyParser_SimpleParseFileFlags + PyParser_SimpleParseStringFlags=python39.PyParser_SimpleParseStringFlags + PyParser_SimpleParseStringFlagsFilename=python39.PyParser_SimpleParseStringFlagsFilename + PyProperty_Type=python39.PyProperty_Type DATA + PyRangeIter_Type=python39.PyRangeIter_Type DATA + PyRange_Type=python39.PyRange_Type DATA + PyReversed_Type=python39.PyReversed_Type DATA + PySeqIter_New=python39.PySeqIter_New + PySeqIter_Type=python39.PySeqIter_Type DATA + PySequence_Check=python39.PySequence_Check + PySequence_Concat=python39.PySequence_Concat + PySequence_Contains=python39.PySequence_Contains + PySequence_Count=python39.PySequence_Count + PySequence_DelItem=python39.PySequence_DelItem + PySequence_DelSlice=python39.PySequence_DelSlice + PySequence_Fast=python39.PySequence_Fast + PySequence_GetItem=python39.PySequence_GetItem + PySequence_GetSlice=python39.PySequence_GetSlice + PySequence_In=python39.PySequence_In + PySequence_InPlaceConcat=python39.PySequence_InPlaceConcat + PySequence_InPlaceRepeat=python39.PySequence_InPlaceRepeat + PySequence_Index=python39.PySequence_Index + PySequence_Length=python39.PySequence_Length + PySequence_List=python39.PySequence_List + PySequence_Repeat=python39.PySequence_Repeat + PySequence_SetItem=python39.PySequence_SetItem + PySequence_SetSlice=python39.PySequence_SetSlice + PySequence_Size=python39.PySequence_Size + PySequence_Tuple=python39.PySequence_Tuple + PySetIter_Type=python39.PySetIter_Type DATA + PySet_Add=python39.PySet_Add + PySet_Clear=python39.PySet_Clear + PySet_Contains=python39.PySet_Contains + PySet_Discard=python39.PySet_Discard + PySet_New=python39.PySet_New + PySet_Pop=python39.PySet_Pop + PySet_Size=python39.PySet_Size + PySet_Type=python39.PySet_Type DATA + PySlice_AdjustIndices=python39.PySlice_AdjustIndices + PySlice_GetIndices=python39.PySlice_GetIndices + PySlice_GetIndicesEx=python39.PySlice_GetIndicesEx + PySlice_New=python39.PySlice_New + PySlice_Type=python39.PySlice_Type DATA + PySlice_Unpack=python39.PySlice_Unpack + PySortWrapper_Type=python39.PySortWrapper_Type DATA + PyInterpreterState_GetID=python39.PyInterpreterState_GetID + PyState_AddModule=python39.PyState_AddModule + PyState_FindModule=python39.PyState_FindModule + PyState_RemoveModule=python39.PyState_RemoveModule + PyStructSequence_GetItem=python39.PyStructSequence_GetItem + PyStructSequence_New=python39.PyStructSequence_New + PyStructSequence_NewType=python39.PyStructSequence_NewType + PyStructSequence_SetItem=python39.PyStructSequence_SetItem + PySuper_Type=python39.PySuper_Type DATA + PySys_AddWarnOption=python39.PySys_AddWarnOption + PySys_AddWarnOptionUnicode=python39.PySys_AddWarnOptionUnicode + PySys_AddXOption=python39.PySys_AddXOption + PySys_FormatStderr=python39.PySys_FormatStderr + PySys_FormatStdout=python39.PySys_FormatStdout + PySys_GetObject=python39.PySys_GetObject + PySys_GetXOptions=python39.PySys_GetXOptions + PySys_HasWarnOptions=python39.PySys_HasWarnOptions + PySys_ResetWarnOptions=python39.PySys_ResetWarnOptions + PySys_SetArgv=python39.PySys_SetArgv + PySys_SetArgvEx=python39.PySys_SetArgvEx + PySys_SetObject=python39.PySys_SetObject + PySys_SetPath=python39.PySys_SetPath + PySys_WriteStderr=python39.PySys_WriteStderr + PySys_WriteStdout=python39.PySys_WriteStdout + PyThreadState_Clear=python39.PyThreadState_Clear + PyThreadState_Delete=python39.PyThreadState_Delete + PyThreadState_DeleteCurrent=python39.PyThreadState_DeleteCurrent + PyThreadState_Get=python39.PyThreadState_Get + PyThreadState_GetDict=python39.PyThreadState_GetDict + PyThreadState_New=python39.PyThreadState_New + PyThreadState_SetAsyncExc=python39.PyThreadState_SetAsyncExc + PyThreadState_Swap=python39.PyThreadState_Swap + PyThread_tss_alloc=python39.PyThread_tss_alloc + PyThread_tss_create=python39.PyThread_tss_create + PyThread_tss_delete=python39.PyThread_tss_delete + PyThread_tss_free=python39.PyThread_tss_free + PyThread_tss_get=python39.PyThread_tss_get + PyThread_tss_is_created=python39.PyThread_tss_is_created + PyThread_tss_set=python39.PyThread_tss_set + PyTraceBack_Here=python39.PyTraceBack_Here + PyTraceBack_Print=python39.PyTraceBack_Print + PyTraceBack_Type=python39.PyTraceBack_Type DATA + PyTupleIter_Type=python39.PyTupleIter_Type DATA + PyTuple_ClearFreeList=python39.PyTuple_ClearFreeList + PyTuple_GetItem=python39.PyTuple_GetItem + PyTuple_GetSlice=python39.PyTuple_GetSlice + PyTuple_New=python39.PyTuple_New + PyTuple_Pack=python39.PyTuple_Pack + PyTuple_SetItem=python39.PyTuple_SetItem + PyTuple_Size=python39.PyTuple_Size + PyTuple_Type=python39.PyTuple_Type DATA + PyType_ClearCache=python39.PyType_ClearCache + PyType_FromSpec=python39.PyType_FromSpec + PyType_FromSpecWithBases=python39.PyType_FromSpecWithBases + PyType_GenericAlloc=python39.PyType_GenericAlloc + PyType_GenericNew=python39.PyType_GenericNew + PyType_GetFlags=python39.PyType_GetFlags + PyType_GetSlot=python39.PyType_GetSlot + PyType_IsSubtype=python39.PyType_IsSubtype + PyType_Modified=python39.PyType_Modified + PyType_Ready=python39.PyType_Ready + PyType_Type=python39.PyType_Type DATA + PyUnicodeDecodeError_Create=python39.PyUnicodeDecodeError_Create + PyUnicodeDecodeError_GetEncoding=python39.PyUnicodeDecodeError_GetEncoding + PyUnicodeDecodeError_GetEnd=python39.PyUnicodeDecodeError_GetEnd + PyUnicodeDecodeError_GetObject=python39.PyUnicodeDecodeError_GetObject + PyUnicodeDecodeError_GetReason=python39.PyUnicodeDecodeError_GetReason + PyUnicodeDecodeError_GetStart=python39.PyUnicodeDecodeError_GetStart + PyUnicodeDecodeError_SetEnd=python39.PyUnicodeDecodeError_SetEnd + PyUnicodeDecodeError_SetReason=python39.PyUnicodeDecodeError_SetReason + PyUnicodeDecodeError_SetStart=python39.PyUnicodeDecodeError_SetStart + PyUnicodeEncodeError_GetEncoding=python39.PyUnicodeEncodeError_GetEncoding + PyUnicodeEncodeError_GetEnd=python39.PyUnicodeEncodeError_GetEnd + PyUnicodeEncodeError_GetObject=python39.PyUnicodeEncodeError_GetObject + PyUnicodeEncodeError_GetReason=python39.PyUnicodeEncodeError_GetReason + PyUnicodeEncodeError_GetStart=python39.PyUnicodeEncodeError_GetStart + PyUnicodeEncodeError_SetEnd=python39.PyUnicodeEncodeError_SetEnd + PyUnicodeEncodeError_SetReason=python39.PyUnicodeEncodeError_SetReason + PyUnicodeEncodeError_SetStart=python39.PyUnicodeEncodeError_SetStart + PyUnicodeIter_Type=python39.PyUnicodeIter_Type DATA + PyUnicodeTranslateError_GetEnd=python39.PyUnicodeTranslateError_GetEnd + PyUnicodeTranslateError_GetObject=python39.PyUnicodeTranslateError_GetObject + PyUnicodeTranslateError_GetReason=python39.PyUnicodeTranslateError_GetReason + PyUnicodeTranslateError_GetStart=python39.PyUnicodeTranslateError_GetStart + PyUnicodeTranslateError_SetEnd=python39.PyUnicodeTranslateError_SetEnd + PyUnicodeTranslateError_SetReason=python39.PyUnicodeTranslateError_SetReason + PyUnicodeTranslateError_SetStart=python39.PyUnicodeTranslateError_SetStart + PyUnicode_Append=python39.PyUnicode_Append + PyUnicode_AppendAndDel=python39.PyUnicode_AppendAndDel + PyUnicode_AsASCIIString=python39.PyUnicode_AsASCIIString + PyUnicode_AsCharmapString=python39.PyUnicode_AsCharmapString + PyUnicode_AsDecodedObject=python39.PyUnicode_AsDecodedObject + PyUnicode_AsDecodedUnicode=python39.PyUnicode_AsDecodedUnicode + PyUnicode_AsEncodedObject=python39.PyUnicode_AsEncodedObject + PyUnicode_AsEncodedString=python39.PyUnicode_AsEncodedString + PyUnicode_AsEncodedUnicode=python39.PyUnicode_AsEncodedUnicode + PyUnicode_AsLatin1String=python39.PyUnicode_AsLatin1String + PyUnicode_AsMBCSString=python39.PyUnicode_AsMBCSString + PyUnicode_AsRawUnicodeEscapeString=python39.PyUnicode_AsRawUnicodeEscapeString + PyUnicode_AsUCS4=python39.PyUnicode_AsUCS4 + PyUnicode_AsUCS4Copy=python39.PyUnicode_AsUCS4Copy + PyUnicode_AsUTF16String=python39.PyUnicode_AsUTF16String + PyUnicode_AsUTF32String=python39.PyUnicode_AsUTF32String + PyUnicode_AsUTF8String=python39.PyUnicode_AsUTF8String + PyUnicode_AsUnicodeEscapeString=python39.PyUnicode_AsUnicodeEscapeString + PyUnicode_AsWideChar=python39.PyUnicode_AsWideChar + PyUnicode_AsWideCharString=python39.PyUnicode_AsWideCharString + PyUnicode_BuildEncodingMap=python39.PyUnicode_BuildEncodingMap + PyUnicode_ClearFreeList=python39.PyUnicode_ClearFreeList + PyUnicode_Compare=python39.PyUnicode_Compare + PyUnicode_CompareWithASCIIString=python39.PyUnicode_CompareWithASCIIString + PyUnicode_Concat=python39.PyUnicode_Concat + PyUnicode_Contains=python39.PyUnicode_Contains + PyUnicode_Count=python39.PyUnicode_Count + PyUnicode_Decode=python39.PyUnicode_Decode + PyUnicode_DecodeASCII=python39.PyUnicode_DecodeASCII + PyUnicode_DecodeCharmap=python39.PyUnicode_DecodeCharmap + PyUnicode_DecodeCodePageStateful=python39.PyUnicode_DecodeCodePageStateful + PyUnicode_DecodeFSDefault=python39.PyUnicode_DecodeFSDefault + PyUnicode_DecodeFSDefaultAndSize=python39.PyUnicode_DecodeFSDefaultAndSize + PyUnicode_DecodeLatin1=python39.PyUnicode_DecodeLatin1 + PyUnicode_DecodeLocale=python39.PyUnicode_DecodeLocale + PyUnicode_DecodeLocaleAndSize=python39.PyUnicode_DecodeLocaleAndSize + PyUnicode_DecodeMBCS=python39.PyUnicode_DecodeMBCS + PyUnicode_DecodeMBCSStateful=python39.PyUnicode_DecodeMBCSStateful + PyUnicode_DecodeRawUnicodeEscape=python39.PyUnicode_DecodeRawUnicodeEscape + PyUnicode_DecodeUTF16=python39.PyUnicode_DecodeUTF16 + PyUnicode_DecodeUTF16Stateful=python39.PyUnicode_DecodeUTF16Stateful + PyUnicode_DecodeUTF32=python39.PyUnicode_DecodeUTF32 + PyUnicode_DecodeUTF32Stateful=python39.PyUnicode_DecodeUTF32Stateful + PyUnicode_DecodeUTF7=python39.PyUnicode_DecodeUTF7 + PyUnicode_DecodeUTF7Stateful=python39.PyUnicode_DecodeUTF7Stateful + PyUnicode_DecodeUTF8=python39.PyUnicode_DecodeUTF8 + PyUnicode_DecodeUTF8Stateful=python39.PyUnicode_DecodeUTF8Stateful + PyUnicode_DecodeUnicodeEscape=python39.PyUnicode_DecodeUnicodeEscape + PyUnicode_EncodeCodePage=python39.PyUnicode_EncodeCodePage + PyUnicode_EncodeFSDefault=python39.PyUnicode_EncodeFSDefault + PyUnicode_EncodeLocale=python39.PyUnicode_EncodeLocale + PyUnicode_FSConverter=python39.PyUnicode_FSConverter + PyUnicode_FSDecoder=python39.PyUnicode_FSDecoder + PyUnicode_Find=python39.PyUnicode_Find + PyUnicode_FindChar=python39.PyUnicode_FindChar + PyUnicode_Format=python39.PyUnicode_Format + PyUnicode_FromEncodedObject=python39.PyUnicode_FromEncodedObject + PyUnicode_FromFormat=python39.PyUnicode_FromFormat + PyUnicode_FromFormatV=python39.PyUnicode_FromFormatV + PyUnicode_FromObject=python39.PyUnicode_FromObject + PyUnicode_FromOrdinal=python39.PyUnicode_FromOrdinal + PyUnicode_FromString=python39.PyUnicode_FromString + PyUnicode_FromStringAndSize=python39.PyUnicode_FromStringAndSize + PyUnicode_FromWideChar=python39.PyUnicode_FromWideChar + PyUnicode_GetDefaultEncoding=python39.PyUnicode_GetDefaultEncoding + PyUnicode_GetLength=python39.PyUnicode_GetLength + PyUnicode_GetSize=python39.PyUnicode_GetSize + PyUnicode_InternFromString=python39.PyUnicode_InternFromString + PyUnicode_InternImmortal=python39.PyUnicode_InternImmortal + PyUnicode_InternInPlace=python39.PyUnicode_InternInPlace + PyUnicode_IsIdentifier=python39.PyUnicode_IsIdentifier + PyUnicode_Join=python39.PyUnicode_Join + PyUnicode_Partition=python39.PyUnicode_Partition + PyUnicode_RPartition=python39.PyUnicode_RPartition + PyUnicode_RSplit=python39.PyUnicode_RSplit + PyUnicode_ReadChar=python39.PyUnicode_ReadChar + PyUnicode_Replace=python39.PyUnicode_Replace + PyUnicode_Resize=python39.PyUnicode_Resize + PyUnicode_RichCompare=python39.PyUnicode_RichCompare + PyUnicode_Split=python39.PyUnicode_Split + PyUnicode_Splitlines=python39.PyUnicode_Splitlines + PyUnicode_Substring=python39.PyUnicode_Substring + PyUnicode_Tailmatch=python39.PyUnicode_Tailmatch + PyUnicode_Translate=python39.PyUnicode_Translate + PyUnicode_Type=python39.PyUnicode_Type DATA + PyUnicode_WriteChar=python39.PyUnicode_WriteChar + PyWeakref_GetObject=python39.PyWeakref_GetObject + PyWeakref_NewProxy=python39.PyWeakref_NewProxy + PyWeakref_NewRef=python39.PyWeakref_NewRef + PyWrapperDescr_Type=python39.PyWrapperDescr_Type DATA + PyWrapper_New=python39.PyWrapper_New + PyZip_Type=python39.PyZip_Type DATA + Py_AddPendingCall=python39.Py_AddPendingCall + Py_AtExit=python39.Py_AtExit + Py_BuildValue=python39.Py_BuildValue + Py_CompileString=python39.Py_CompileString + Py_DecRef=python39.Py_DecRef + Py_DecodeLocale=python39.Py_DecodeLocale + Py_EncodeLocale=python39.Py_EncodeLocale + Py_EndInterpreter=python39.Py_EndInterpreter + Py_Exit=python39.Py_Exit + Py_FatalError=python39.Py_FatalError + Py_FileSystemDefaultEncodeErrors=python39.Py_FileSystemDefaultEncodeErrors DATA + Py_FileSystemDefaultEncoding=python39.Py_FileSystemDefaultEncoding DATA + Py_Finalize=python39.Py_Finalize + Py_FinalizeEx=python39.Py_FinalizeEx + Py_GetBuildInfo=python39.Py_GetBuildInfo + Py_GetCompiler=python39.Py_GetCompiler + Py_GetCopyright=python39.Py_GetCopyright + Py_GetExecPrefix=python39.Py_GetExecPrefix + Py_GetPath=python39.Py_GetPath + Py_GetPlatform=python39.Py_GetPlatform + Py_GetPrefix=python39.Py_GetPrefix + Py_GetProgramFullPath=python39.Py_GetProgramFullPath + Py_GetProgramName=python39.Py_GetProgramName + Py_GetPythonHome=python39.Py_GetPythonHome + Py_GetRecursionLimit=python39.Py_GetRecursionLimit + Py_GetVersion=python39.Py_GetVersion + Py_HasFileSystemDefaultEncoding=python39.Py_HasFileSystemDefaultEncoding DATA + Py_IncRef=python39.Py_IncRef + Py_Initialize=python39.Py_Initialize + Py_InitializeEx=python39.Py_InitializeEx + Py_IsInitialized=python39.Py_IsInitialized + Py_Main=python39.Py_Main + Py_MakePendingCalls=python39.Py_MakePendingCalls + Py_NewInterpreter=python39.Py_NewInterpreter + Py_ReprEnter=python39.Py_ReprEnter + Py_ReprLeave=python39.Py_ReprLeave + Py_SetPath=python39.Py_SetPath + Py_SetProgramName=python39.Py_SetProgramName + Py_SetPythonHome=python39.Py_SetPythonHome + Py_SetRecursionLimit=python39.Py_SetRecursionLimit + Py_SymtableString=python39.Py_SymtableString + Py_UTF8Mode=python39.Py_UTF8Mode DATA + Py_VaBuildValue=python39.Py_VaBuildValue + _PyArg_ParseTupleAndKeywords_SizeT=python39._PyArg_ParseTupleAndKeywords_SizeT + _PyArg_ParseTuple_SizeT=python39._PyArg_ParseTuple_SizeT + _PyArg_Parse_SizeT=python39._PyArg_Parse_SizeT + _PyArg_VaParseTupleAndKeywords_SizeT=python39._PyArg_VaParseTupleAndKeywords_SizeT + _PyArg_VaParse_SizeT=python39._PyArg_VaParse_SizeT + _PyErr_BadInternalCall=python39._PyErr_BadInternalCall + _PyObject_CallFunction_SizeT=python39._PyObject_CallFunction_SizeT + _PyObject_CallMethod_SizeT=python39._PyObject_CallMethod_SizeT + _PyObject_GC_Malloc=python39._PyObject_GC_Malloc + _PyObject_GC_New=python39._PyObject_GC_New + _PyObject_GC_NewVar=python39._PyObject_GC_NewVar + _PyObject_GC_Resize=python39._PyObject_GC_Resize + _PyObject_New=python39._PyObject_New + _PyObject_NewVar=python39._PyObject_NewVar + _PyState_AddModule=python39._PyState_AddModule + _PyThreadState_Init=python39._PyThreadState_Init + _PyThreadState_Prealloc=python39._PyThreadState_Prealloc + _PyTrash_delete_later=python39._PyTrash_delete_later DATA + _PyTrash_delete_nesting=python39._PyTrash_delete_nesting DATA + _PyTrash_deposit_object=python39._PyTrash_deposit_object + _PyTrash_destroy_chain=python39._PyTrash_destroy_chain + _PyTrash_thread_deposit_object=python39._PyTrash_thread_deposit_object + _PyTrash_thread_destroy_chain=python39._PyTrash_thread_destroy_chain + _PyWeakref_CallableProxyType=python39._PyWeakref_CallableProxyType DATA + _PyWeakref_ProxyType=python39._PyWeakref_ProxyType DATA + _PyWeakref_RefType=python39._PyWeakref_RefType DATA + _Py_BuildValue_SizeT=python39._Py_BuildValue_SizeT + _Py_CheckRecursionLimit=python39._Py_CheckRecursionLimit DATA + _Py_CheckRecursiveCall=python39._Py_CheckRecursiveCall + _Py_Dealloc=python39._Py_Dealloc + _Py_EllipsisObject=python39._Py_EllipsisObject DATA + _Py_FalseStruct=python39._Py_FalseStruct DATA + _Py_NoneStruct=python39._Py_NoneStruct DATA + _Py_NotImplementedStruct=python39._Py_NotImplementedStruct DATA + _Py_SwappedOp=python39._Py_SwappedOp DATA + _Py_TrueStruct=python39._Py_TrueStruct DATA + _Py_VaBuildValue_SizeT=python39._Py_VaBuildValue_SizeT diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index cf4aa4c917544d..312fa6a588a6ca 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -38,7 +38,7 @@ Debug Used to build Python with extra debugging capabilities, equivalent to using ./configure --with-pydebug on UNIX. All binaries built using this configuration have "_d" added to their name: - python38_d.dll, python_d.exe, parser_d.pyd, and so on. Both the + python39_d.dll, python_d.exe, parser_d.pyd, and so on. Both the build and rt (run test) batch files in this directory accept a -d option for debug builds. If you are building Python to help with development of CPython, you will most likely use this configuration. diff --git a/README.rst b/README.rst index b0a0ce7ec287b6..0f658531cbac29 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.8.0 beta 1 -=================================== +This is Python version 3.9.0 alpha 0 +==================================== .. image:: https://travis-ci.org/python/cpython.svg?branch=master :alt: CPython build status on Travis CI @@ -140,7 +140,7 @@ What's New ---------- We have a comprehensive overview of the changes in the `What's New in Python -3.8 `_ document. For a more +3.9 `_ document. For a more detailed change log, read `Misc/NEWS `_, but a full accounting of changes can only be gleaned from the `commit history @@ -153,7 +153,7 @@ entitled "Installing multiple versions". Documentation ------------- -`Documentation for Python 3.8 `_ is online, +`Documentation for Python 3.9 `_ is online, updated daily. It can also be downloaded in many formats for faster access. The documentation @@ -212,8 +212,8 @@ intend to install multiple versions using the same prefix you must decide which version (if any) is your "primary" version. Install that version using ``make install``. Install all other versions using ``make altinstall``. -For example, if you want to install Python 2.7, 3.6, and 3.8 with 3.8 being the -primary version, you would execute ``make install`` in your 3.8 build directory +For example, if you want to install Python 2.7, 3.6, and 3.9 with 3.9 being the +primary version, you would execute ``make install`` in your 3.9 build directory and ``make altinstall`` in the others. @@ -243,7 +243,7 @@ All current PEPs, as well as guidelines for submitting a new PEP, are listed at Release Schedule ---------------- -See :pep:`569` for Python 3.8 release details. +See :pep:`596` for Python 3.9 release details. Copyright and License Information diff --git a/configure b/configure index b606fc808c17c1..4b98fc6914e208 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for python 3.8. +# Generated by GNU Autoconf 2.69 for python 3.9. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='python' PACKAGE_TARNAME='python' -PACKAGE_VERSION='3.8' -PACKAGE_STRING='python 3.8' +PACKAGE_VERSION='3.9' +PACKAGE_STRING='python 3.9' PACKAGE_BUGREPORT='https://bugs.python.org/' PACKAGE_URL='' @@ -1399,7 +1399,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures python 3.8 to adapt to many kinds of systems. +\`configure' configures python 3.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1465,7 +1465,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of python 3.8:";; + short | recursive ) echo "Configuration of python 3.9:";; esac cat <<\_ACEOF @@ -1631,7 +1631,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -python configure 3.8 +python configure 3.9 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2340,7 +2340,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by python $as_me 3.8, which was +It was created by python $as_me 3.9, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2960,7 +2960,7 @@ rm confdefs.h mv confdefs.h.new confdefs.h -VERSION=3.8 +VERSION=3.9 # Version number of Python's own shared library file. @@ -17862,7 +17862,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by python $as_me 3.8, which was +This file was extended by python $as_me 3.9, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17924,7 +17924,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -python config.status 3.8 +python config.status 3.9 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 3d589ac2589167..e82ed1964729a0 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ dnl * Please run autoreconf to test your changes! * dnl *********************************************** # Set VERSION so we only need to edit in one place (i.e., here) -m4_define(PYTHON_VERSION, 3.8) +m4_define(PYTHON_VERSION, 3.9) AC_PREREQ([2.69]) From 750767f7c06994f58bf235a520bc76b62affb70b Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Tue, 4 Jun 2019 15:57:15 -0500 Subject: [PATCH 323/441] Bump version in AppVeyor config (#13822) --- .github/appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/appveyor.yml b/.github/appveyor.yml index e8012f69ee5b2e..8556cf8437e509 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.8build{build} +version: 3.9build{build} clone_depth: 5 branches: only: From 19a1e1eb86115db66c1faae5927f87e3a12692fc Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Tue, 4 Jun 2019 16:03:10 -0500 Subject: [PATCH 324/441] bpo-34282: Remove deprecated enum _convert method (GH-13823) --- Lib/enum.py | 6 ------ .../next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst diff --git a/Lib/enum.py b/Lib/enum.py index 6ef17c7f6dc846..403f747d22a4ea 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -464,12 +464,6 @@ def _convert_(cls, name, module, filter, source=None): module_globals[name] = cls return cls - def _convert(cls, *args, **kwargs): - import warnings - warnings.warn("_convert is deprecated and will be removed in 3.9, use " - "_convert_ instead.", DeprecationWarning, stacklevel=2) - return cls._convert_(*args, **kwargs) - @staticmethod def _get_mixins_(bases): """Returns the type for creating enum members, and the first inherited diff --git a/Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst b/Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst new file mode 100644 index 00000000000000..66c388e1d6ee10 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-04-15-39-14.bpo-34282.aAK54n.rst @@ -0,0 +1 @@ +Remove ``Enum._convert`` method, deprecated in 3.8. From 59e7bbcaa4d0d556591f774c5ea4869c41fa95b0 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Wed, 5 Jun 2019 01:15:33 +0200 Subject: [PATCH 325/441] Doc: Python 3.9 in sidebar and version switcher. (GH-13824) --- Doc/tools/static/switchers.js | 3 ++- Doc/tools/templates/indexsidebar.html | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/tools/static/switchers.js b/Doc/tools/static/switchers.js index 346b31494e60f9..fa298a76b0fe10 100644 --- a/Doc/tools/static/switchers.js +++ b/Doc/tools/static/switchers.js @@ -10,7 +10,8 @@ '(?:release/\\d.\\d[\\x\\d\\.]*)']; var all_versions = { - '3.8': 'dev (3.8)', + '3.9': 'dev (3.9)', + '3.8': 'pre (3.8)', '3.7': '3.7', '3.6': '3.6', '3.5': '3.5', diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html index 3666af92f0da47..4fd7423430ca81 100644 --- a/Doc/tools/templates/indexsidebar.html +++ b/Doc/tools/templates/indexsidebar.html @@ -2,7 +2,8 @@

    {% trans %}Download{% endtrans %}

    {% trans %}Download these documents{% endtrans %}

    {% trans %}Docs by version{% endtrans %}

      -
    • {% trans %}Python 3.8 (in development){% endtrans %}
    • +
    • {% trans %}Python 3.9 (in development){% endtrans %}
    • +
    • {% trans %}Python 3.8 (pre-release){% endtrans %}
    • {% trans %}Python 3.7 (stable){% endtrans %}
    • {% trans %}Python 3.6 (security-fixes){% endtrans %}
    • {% trans %}Python 3.5 (security-fixes){% endtrans %}
    • From 949fe976d5c62ae63ed505ecf729f815d0baccfc Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Tue, 4 Jun 2019 21:55:37 -0400 Subject: [PATCH 326/441] bpo-35763: Make IDLE calltip note about '/' less obtrusive (GH-13791) Add it to the end of the first line if there is room. Tests were reworked. --- Lib/idlelib/calltip.py | 8 +- Lib/idlelib/idle_test/test_calltip.py | 120 +++++++++--------- .../2019-06-04-20-36-24.bpo-35763.7XdoWz.rst | 2 + 3 files changed, 69 insertions(+), 61 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst diff --git a/Lib/idlelib/calltip.py b/Lib/idlelib/calltip.py index b013a7f6ec0fc9..a3dda2678bd4da 100644 --- a/Lib/idlelib/calltip.py +++ b/Lib/idlelib/calltip.py @@ -118,7 +118,7 @@ def get_entity(expression): _first_param = re.compile(r'(?<=\()\w*\,?\s*') _default_callable_argspec = "See source or doc" _invalid_method = "invalid method signature" -_argument_positional = "\n['/' marks preceding arguments as positional-only]\n" +_argument_positional = " # '/' marks preceding args as positional-only." def get_argspec(ob): '''Return a string describing the signature of a callable object, or ''. @@ -144,11 +144,11 @@ def get_argspec(ob): if msg.startswith(_invalid_method): return _invalid_method - if '/' in argspec: - """Using AC's positional argument should add the explain""" + if '/' in argspec and len(argspec) < _MAX_COLS - len(_argument_positional): + # Add explanation TODO remove after 3.7, before 3.9. argspec += _argument_positional if isinstance(fob, type) and argspec == '()': - """fob with no argument, use default callable argspec""" + # If fob has no argument, use default callable argspec. argspec = _default_callable_argspec lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT) diff --git a/Lib/idlelib/idle_test/test_calltip.py b/Lib/idlelib/idle_test/test_calltip.py index 833351bd799601..886959b17074f6 100644 --- a/Lib/idlelib/idle_test/test_calltip.py +++ b/Lib/idlelib/idle_test/test_calltip.py @@ -4,8 +4,7 @@ import unittest import textwrap import types - -default_tip = calltip._default_callable_argspec +import re # Test Class TC is used in multiple get_argspec test methods @@ -28,6 +27,7 @@ def t6(no, self): 'doc' t6.tip = "(no, self)" def __call__(self, ci): 'doc' __call__.tip = "(self, ci)" + def nd(self): pass # No doc. # attaching .tip to wrapped methods does not work @classmethod def cm(cls, a): 'doc' @@ -36,11 +36,12 @@ def sm(b): 'doc' tc = TC() -signature = calltip.get_argspec # 2.7 and 3.x use different functions +default_tip = calltip._default_callable_argspec +get_spec = calltip.get_argspec -class Get_signatureTest(unittest.TestCase): - # The signature function must return a string, even if blank. +class Get_argspecTest(unittest.TestCase): + # The get_spec function must return a string, even if blank. # Test a variety of objects to be sure that none cause it to raise # (quite aside from getting as correct an answer as possible). # The tests of builtins may break if inspect or the docstrings change, @@ -49,57 +50,59 @@ class Get_signatureTest(unittest.TestCase): def test_builtins(self): + def tiptest(obj, out): + self.assertEqual(get_spec(obj), out) + # Python class that inherits builtin methods class List(list): "List() doc" # Simulate builtin with no docstring for default tip test class SB: __call__ = None - def gtest(obj, out): - self.assertEqual(signature(obj), out) - if List.__doc__ is not None: - gtest(List, '(iterable=(), /)' + calltip._argument_positional - + '\n' + List.__doc__) - gtest(list.__new__, + tiptest(List, + f'(iterable=(), /){calltip._argument_positional}' + f'\n{List.__doc__}') + tiptest(list.__new__, '(*args, **kwargs)\n' 'Create and return a new object. ' 'See help(type) for accurate signature.') - gtest(list.__init__, + tiptest(list.__init__, '(self, /, *args, **kwargs)' + calltip._argument_positional + '\n' + 'Initialize self. See help(type(self)) for accurate signature.') append_doc = (calltip._argument_positional + "\nAppend object to the end of the list.") - gtest(list.append, '(self, object, /)' + append_doc) - gtest(List.append, '(self, object, /)' + append_doc) - gtest([].append, '(object, /)' + append_doc) + tiptest(list.append, '(self, object, /)' + append_doc) + tiptest(List.append, '(self, object, /)' + append_doc) + tiptest([].append, '(object, /)' + append_doc) + + tiptest(types.MethodType, "method(function, instance)") + tiptest(SB(), default_tip) - gtest(types.MethodType, "method(function, instance)") - gtest(SB(), default_tip) - import re p = re.compile('') - gtest(re.sub, '''\ + tiptest(re.sub, '''\ (pattern, repl, string, count=0, flags=0) Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the Match object and must return''') - gtest(p.sub, '''\ + tiptest(p.sub, '''\ (repl, string, count=0) Return the string obtained by replacing the leftmost \ non-overlapping occurrences o...''') def test_signature_wrap(self): if textwrap.TextWrapper.__doc__ is not None: - self.assertEqual(signature(textwrap.TextWrapper), '''\ + self.assertEqual(get_spec(textwrap.TextWrapper), '''\ (width=70, initial_indent='', subsequent_indent='', expand_tabs=True, replace_whitespace=True, fix_sentence_endings=False, break_long_words=True, drop_whitespace=True, break_on_hyphens=True, tabsize=8, *, max_lines=None, placeholder=' [...]')''') def test_properly_formated(self): + def foo(s='a'*100): pass @@ -112,35 +115,35 @@ def baz(s='a'*100, z='b'*100): indent = calltip._INDENT - str_foo = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\ - "aaaaaaaaaa')" - str_bar = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\ - "aaaaaaaaaa')\nHello Guido" - str_baz = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\ - "aaaaaaaaaa', z='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"\ - "bbbbbbbbbbbbbbbbb\n" + indent + "bbbbbbbbbbbbbbbbbbbbbb"\ - "bbbbbbbbbbbbbbbbbbbbbb')" - - self.assertEqual(calltip.get_argspec(foo), str_foo) - self.assertEqual(calltip.get_argspec(bar), str_bar) - self.assertEqual(calltip.get_argspec(baz), str_baz) + sfoo = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\ + "aaaaaaaaaa')" + sbar = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\ + "aaaaaaaaaa')\nHello Guido" + sbaz = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + indent + "aaaaaaaaa"\ + "aaaaaaaaaa', z='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"\ + "bbbbbbbbbbbbbbbbb\n" + indent + "bbbbbbbbbbbbbbbbbbbbbb"\ + "bbbbbbbbbbbbbbbbbbbbbb')" + + for func,doc in [(foo, sfoo), (bar, sbar), (baz, sbaz)]: + with self.subTest(func=func, doc=doc): + self.assertEqual(get_spec(func), doc) def test_docline_truncation(self): def f(): pass f.__doc__ = 'a'*300 - self.assertEqual(signature(f), '()\n' + 'a' * (calltip._MAX_COLS-3) + '...') + self.assertEqual(get_spec(f), f"()\n{'a'*(calltip._MAX_COLS-3) + '...'}") def test_multiline_docstring(self): # Test fewer lines than max. - self.assertEqual(signature(range), + self.assertEqual(get_spec(range), "range(stop) -> range object\n" "range(start, stop[, step]) -> range object") # Test max lines - self.assertEqual(signature(bytes), '''\ + self.assertEqual(get_spec(bytes), '''\ bytes(iterable_of_ints) -> bytes bytes(string, encoding[, errors]) -> bytes bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer @@ -150,7 +153,7 @@ def test_multiline_docstring(self): # Test more than max lines def f(): pass f.__doc__ = 'a\n' * 15 - self.assertEqual(signature(f), '()' + '\na' * calltip._MAX_LINES) + self.assertEqual(get_spec(f), '()' + '\na' * calltip._MAX_LINES) def test_functions(self): def t1(): 'doc' @@ -166,14 +169,16 @@ def t5(a, b=None, *args, **kw): 'doc' doc = '\ndoc' if t1.__doc__ is not None else '' for func in (t1, t2, t3, t4, t5, TC): - self.assertEqual(signature(func), func.tip + doc) + with self.subTest(func=func): + self.assertEqual(get_spec(func), func.tip + doc) def test_methods(self): doc = '\ndoc' if TC.__doc__ is not None else '' for meth in (TC.t1, TC.t2, TC.t3, TC.t4, TC.t5, TC.t6, TC.__call__): - self.assertEqual(signature(meth), meth.tip + doc) - self.assertEqual(signature(TC.cm), "(a)" + doc) - self.assertEqual(signature(TC.sm), "(b)" + doc) + with self.subTest(meth=meth): + self.assertEqual(get_spec(meth), meth.tip + doc) + self.assertEqual(get_spec(TC.cm), "(a)" + doc) + self.assertEqual(get_spec(TC.sm), "(b)" + doc) def test_bound_methods(self): # test that first parameter is correctly removed from argspec @@ -181,7 +186,8 @@ def test_bound_methods(self): for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), (tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),): - self.assertEqual(signature(meth), mtip + doc) + with self.subTest(meth=meth, mtip=mtip): + self.assertEqual(get_spec(meth), mtip + doc) def test_starred_parameter(self): # test that starred first parameter is *not* removed from argspec @@ -189,17 +195,18 @@ class C: def m1(*args): pass c = C() for meth, mtip in ((C.m1, '(*args)'), (c.m1, "(*args)"),): - self.assertEqual(signature(meth), mtip) + with self.subTest(meth=meth, mtip=mtip): + self.assertEqual(get_spec(meth), mtip) - def test_invalid_method_signature(self): + def test_invalid_method_get_spec(self): class C: def m2(**kwargs): pass class Test: def __call__(*, a): pass mtip = calltip._invalid_method - self.assertEqual(signature(C().m2), mtip) - self.assertEqual(signature(Test()), mtip) + self.assertEqual(get_spec(C().m2), mtip) + self.assertEqual(get_spec(Test()), mtip) def test_non_ascii_name(self): # test that re works to delete a first parameter name that @@ -208,12 +215,9 @@ def test_non_ascii_name(self): assert calltip._first_param.sub('', uni) == '(a)' def test_no_docstring(self): - def nd(s): - pass - TC.nd = nd - self.assertEqual(signature(nd), "(s)") - self.assertEqual(signature(TC.nd), "(s)") - self.assertEqual(signature(tc.nd), "()") + for meth, mtip in ((TC.nd, "(self)"), (tc.nd, "()")): + with self.subTest(meth=meth, mtip=mtip): + self.assertEqual(get_spec(meth), mtip) def test_attribute_exception(self): class NoCall: @@ -229,11 +233,13 @@ def __call__(self, ci): for meth, mtip in ((NoCall, default_tip), (CallA, default_tip), (NoCall(), ''), (CallA(), '(a, b, c)'), (CallB(), '(ci)')): - self.assertEqual(signature(meth), mtip) + with self.subTest(meth=meth, mtip=mtip): + self.assertEqual(get_spec(meth), mtip) def test_non_callables(self): for obj in (0, 0.0, '0', b'0', [], {}): - self.assertEqual(signature(obj), '') + with self.subTest(obj=obj): + self.assertEqual(get_spec(obj), '') class Get_entityTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst b/Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst new file mode 100644 index 00000000000000..c2b6594cc3506c --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-06-04-20-36-24.bpo-35763.7XdoWz.rst @@ -0,0 +1,2 @@ +Make calltip reminder about '/' meaning positional-only less obtrusive by +only adding it when there is room on the first line. From 6d64a8f49eb321116f585c4b036c81bb976d2d5c Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Wed, 5 Jun 2019 02:45:53 -0300 Subject: [PATCH 327/441] bpo-36373: Deprecate explicit loop parameter in all public asyncio APIs [streams] (GH-13671) This PR deprecate explicit loop parameters in all public asyncio APIs This issues is split to be easier to review. Second step: streams.py https://bugs.python.org/issue36373 --- Lib/asyncio/streams.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 480f1a3fdd74ed..f03441b6b11ded 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -175,6 +175,10 @@ async def open_connection(host=None, port=None, *, stacklevel=2) if loop is None: loop = events.get_event_loop() + else: + warnings.warn("The loop argument is deprecated since Python 3.8, " + "and scheduled for removal in Python 3.10.", + DeprecationWarning, stacklevel=2) reader = StreamReader(limit=limit, loop=loop) protocol = StreamReaderProtocol(reader, loop=loop, _asyncio_internal=True) transport, _ = await loop.create_connection( @@ -213,6 +217,10 @@ async def start_server(client_connected_cb, host=None, port=None, *, stacklevel=2) if loop is None: loop = events.get_event_loop() + else: + warnings.warn("The loop argument is deprecated since Python 3.8, " + "and scheduled for removal in Python 3.10.", + DeprecationWarning, stacklevel=2) def factory(): reader = StreamReader(limit=limit, loop=loop) @@ -414,6 +422,10 @@ async def open_unix_connection(path=None, *, stacklevel=2) if loop is None: loop = events.get_event_loop() + else: + warnings.warn("The loop argument is deprecated since Python 3.8, " + "and scheduled for removal in Python 3.10.", + DeprecationWarning, stacklevel=2) reader = StreamReader(limit=limit, loop=loop) protocol = StreamReaderProtocol(reader, loop=loop, _asyncio_internal=True) @@ -473,6 +485,10 @@ async def start_unix_server(client_connected_cb, path=None, *, stacklevel=2) if loop is None: loop = events.get_event_loop() + else: + warnings.warn("The loop argument is deprecated since Python 3.8, " + "and scheduled for removal in Python 3.10.", + DeprecationWarning, stacklevel=2) def factory(): reader = StreamReader(limit=limit, loop=loop) From d4cf099dff4720a25208b5fa247dc16d86b11ac3 Mon Sep 17 00:00:00 2001 From: Benjamin Yeh Date: Wed, 5 Jun 2019 02:08:04 -0700 Subject: [PATCH 328/441] Fix documentation (GH-13721) Based on the source code https://github.com/python/cpython/blob/4a686504eb2bbf69adf78077458508a7ba131667/Lib/multiprocessing/pool.py#L755 AsyncResult.successful() raises a ValueError, not an AssertionError. --- Doc/library/multiprocessing.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index a4771d3a84cd40..6c07124f97907a 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -2279,6 +2279,10 @@ with the :class:`Pool` class. Return whether the call completed without raising an exception. Will raise :exc:`AssertionError` if the result is not ready. + .. versionchanged:: 3.7 + If the result is not ready, :exc:`ValueError` is raised instead of + :exc:`AssertionError`. + The following example demonstrates the use of a pool:: from multiprocessing import Pool From 9aa78566fbeeb8cdaa669ad22f92cf63765f4135 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Wed, 5 Jun 2019 03:33:27 -0600 Subject: [PATCH 329/441] bpo-34767: Do not always create a collections.deque() in asyncio.Lock() (GH-13834) https://bugs.python.org/issue34767 --- Lib/asyncio/locks.py | 9 +++++++-- .../Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index d59eb8f210c7e1..1324eefb5ff460 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -158,7 +158,7 @@ class Lock(_ContextManagerMixin): """ def __init__(self, *, loop=None): - self._waiters = collections.deque() + self._waiters = None self._locked = False if loop is not None: self._loop = loop @@ -182,10 +182,13 @@ async def acquire(self): This method blocks until the lock is unlocked, then sets it to locked and returns True. """ - if not self._locked and all(w.cancelled() for w in self._waiters): + if (not self._locked and (self._waiters is None or + all(w.cancelled() for w in self._waiters))): self._locked = True return True + if self._waiters is None: + self._waiters = collections.deque() fut = self._loop.create_future() self._waiters.append(fut) @@ -224,6 +227,8 @@ def release(self): def _wake_up_first(self): """Wake up the first waiter if it isn't done.""" + if not self._waiters: + return try: fut = next(iter(self._waiters)) except StopIteration: diff --git a/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst b/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst new file mode 100644 index 00000000000000..b46bc44506f4a4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-04-23-44-52.bpo-34767.BpDShN.rst @@ -0,0 +1 @@ +Do not always create a :class:`collections.deque` in :class:`asyncio.Lock`. From ccf0efbb21f6bbf6efd5f8cb560fed11079ce1a2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Jun 2019 12:24:52 +0200 Subject: [PATCH 330/441] bpo-26836: Document os.memfd_create() name parameter (GH-13838) https://bugs.python.org/issue26836 --- Doc/library/os.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 107764ba4d539e..f0df35e9ddd540 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -3011,6 +3011,13 @@ features: (or a bitwise ORed combination of them). By default, the new file descriptor is :ref:`non-inheritable `. + The name supplied in *name* is used as a filename and will be displayed as + the target of the corresponding symbolic link in the directory + ``/proc/self/fd/``. The displayed name is always prefixed with ``memfd:`` + and serves only for debugging purposes. Names do not affect the behavior of + the file descriptor, and as such multiple files can have the same name + without any side effects. + .. availability:: Linux 3.17 or newer with glibc 2.27 or newer. .. versionadded:: 3.8 From 6c01ebcc0dfc6be22950fabb46bdc10dcb6202c9 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 5 Jun 2019 07:39:38 -0700 Subject: [PATCH 331/441] bpo-37158: Simplify and speed-up statistics.fmean() (GH-13832) --- Lib/statistics.py | 8 ++++---- .../next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst diff --git a/Lib/statistics.py b/Lib/statistics.py index 012845b8d2ef4c..5be70e5ebf4ebb 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -320,11 +320,11 @@ def fmean(data): except TypeError: # Handle iterators that do not define __len__(). n = 0 - def count(x): + def count(iterable): nonlocal n - n += 1 - return x - total = fsum(map(count, data)) + for n, x in enumerate(iterable, start=1): + yield x + total = fsum(count(data)) else: total = fsum(data) try: diff --git a/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst b/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst new file mode 100644 index 00000000000000..4a5ec4122f9433 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-04-22-25-38.bpo-37158.JKm15S.rst @@ -0,0 +1 @@ +Speed-up statistics.fmean() by switching from a function to a generator. From 142566c028720934325f0b7fe28680afd046e00f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 5 Jun 2019 18:22:31 +0300 Subject: [PATCH 332/441] [3.9] bpo-37116: Use PEP 570 syntax for positional-only parameters. (GH-12620) Turn deprecation warnings added in 3.8 into TypeError. --- Doc/library/bdb.rst | 2 +- Doc/library/concurrent.futures.rst | 2 +- Doc/library/contextlib.rst | 4 +-- Doc/library/curses.rst | 2 +- Doc/library/profile.rst | 2 +- Doc/library/trace.rst | 2 +- Doc/library/unittest.rst | 2 +- Doc/library/weakref.rst | 2 +- Lib/bdb.py | 18 +----------- Lib/cProfile.py | 18 +----------- Lib/collections/__init__.py | 18 +----------- Lib/concurrent/futures/_base.py | 16 +---------- Lib/concurrent/futures/process.py | 18 +----------- Lib/concurrent/futures/thread.py | 18 +----------- Lib/contextlib.py | 36 ++--------------------- Lib/curses/__init__.py | 14 +-------- Lib/functools.py | 19 +------------ Lib/multiprocessing/managers.py | 44 ++--------------------------- Lib/profile.py | 18 +----------- Lib/test/test_concurrent_futures.py | 5 ++-- Lib/test/test_contextlib.py | 4 +-- Lib/test/test_contextlib_async.py | 4 +-- Lib/test/test_functools.py | 4 +-- Lib/test/test_trace.py | 5 ++-- Lib/test/test_userdict.py | 9 +++--- Lib/test/test_weakref.py | 18 +++--------- Lib/trace.py | 18 +----------- Lib/unittest/case.py | 19 +------------ Lib/unittest/test/test_runner.py | 5 ++-- Lib/weakref.py | 29 +------------------ 30 files changed, 45 insertions(+), 330 deletions(-) diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst index 116ffcf88e3b69..7e4066cd436ad5 100644 --- a/Doc/library/bdb.rst +++ b/Doc/library/bdb.rst @@ -343,7 +343,7 @@ The :mod:`bdb` module also defines two classes: For backwards compatibility. Calls the :meth:`run` method. - .. method:: runcall(func, *args, **kwds) + .. method:: runcall(func, /, *args, **kwds) Debug a single function call, and return its result. diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index f2491dd24571be..34905c449d7f8b 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -28,7 +28,7 @@ Executor Objects An abstract class that provides methods to execute calls asynchronously. It should not be used directly, but through its concrete subclasses. - .. method:: submit(fn, *args, **kwargs) + .. method:: submit(fn, /, *args, **kwargs) Schedules the callable, *fn*, to be executed as ``fn(*args **kwargs)`` and returns a :class:`Future` object representing the execution of the diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 73b24e5f251a94..0aa4ad76523480 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -416,7 +416,7 @@ Functions and classes provided: The passed in object is returned from the function, allowing this method to be used as a function decorator. - .. method:: callback(callback, *args, **kwds) + .. method:: callback(callback, /, *args, **kwds) Accepts an arbitrary callback function and arguments and adds it to the callback stack. @@ -473,7 +473,7 @@ Functions and classes provided: Similar to :meth:`push` but expects either an asynchronous context manager or a coroutine function. - .. method:: push_async_callback(callback, *args, **kwds) + .. method:: push_async_callback(callback, /, *args, **kwds) Similar to :meth:`callback` but expects a coroutine function. diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 7d1e7538a292b3..c88d3520e988ff 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -656,7 +656,7 @@ The module :mod:`curses` defines the following functions: foreground color on the default background. -.. function:: wrapper(func, ...) +.. function:: wrapper(func, /, *args, **kwargs) Initialize curses and call another callable object, *func*, which should be the rest of your curses-using application. If the application raises an exception, diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index d8039fd28e0d8a..8d589d247b7747 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -309,7 +309,7 @@ functions: Profile the cmd via :func:`exec` with the specified global and local environment. - .. method:: runcall(func, *args, **kwargs) + .. method:: runcall(func, /, *args, **kwargs) Profile ``func(*args, **kwargs)`` diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index 85fec6830006c7..c2732d900bc138 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -166,7 +166,7 @@ Programmatic Interface environments. If not defined, *globals* and *locals* default to empty dictionaries. - .. method:: runfunc(func, *args, **kwds) + .. method:: runfunc(func, /, *args, **kwds) Call *func* with the given arguments under control of the :class:`Trace` object with the current tracing parameters. diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 5ec4b40856ae91..320d898fc8d4ca 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1427,7 +1427,7 @@ Test cases :class:`TextTestResult` in Python 3.2. - .. method:: addCleanup(function, *args, **kwargs) + .. method:: addCleanup(function, /, *args, **kwargs) Add a function to be called after :meth:`tearDown` to cleanup resources used during the test. Functions will be called in reverse order to the diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index a28d71060f3836..a5c4295ef1faf9 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -240,7 +240,7 @@ objects. .. versionadded:: 3.4 -.. class:: finalize(obj, func, *args, **kwargs) +.. class:: finalize(obj, func, /, *args, **kwargs) Return a callable finalizer object which will be called when *obj* is garbage collected. Unlike an ordinary weak reference, a finalizer diff --git a/Lib/bdb.py b/Lib/bdb.py index 96e7d18d718df9..fd34976a4d0bb0 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -618,26 +618,11 @@ def runctx(self, cmd, globals, locals): # This method is more useful to debug a single function call. - def runcall(*args, **kwds): + def runcall(self, func, /, *args, **kwds): """Debug a single function call. Return the result of the function call. """ - if len(args) >= 2: - self, func, *args = args - elif not args: - raise TypeError("descriptor 'runcall' of 'Bdb' object " - "needs an argument") - elif 'func' in kwds: - func = kwds.pop('func') - self, *args = args - import warnings - warnings.warn("Passing 'func' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('runcall expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - self.reset() sys.settrace(self.trace_dispatch) res = None @@ -649,7 +634,6 @@ def runcall(*args, **kwds): self.quitting = True sys.settrace(None) return res - runcall.__text_signature__ = '($self, func, /, *args, **kwds)' def set_trace(): diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 369d02e22e24aa..4f202038d61260 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -103,28 +103,12 @@ def runctx(self, cmd, globals, locals): return self # This method is more useful to profile a single function call. - def runcall(*args, **kw): - if len(args) >= 2: - self, func, *args = args - elif not args: - raise TypeError("descriptor 'runcall' of 'Profile' object " - "needs an argument") - elif 'func' in kw: - func = kw.pop('func') - self, *args = args - import warnings - warnings.warn("Passing 'func' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('runcall expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - + def runcall(self, func, /, *args, **kw): self.enable() try: return func(*args, **kw) finally: self.disable() - runcall.__text_signature__ = '($self, func, /, *args, **kw)' def __enter__(self): self.enable() diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index e9999e27d5f535..2264efe94a7d3c 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -971,28 +971,12 @@ def clear(self): class UserDict(_collections_abc.MutableMapping): # Start by filling-out the abstract methods - def __init__(*args, **kwargs): - if not args: - raise TypeError("descriptor '__init__' of 'UserDict' object " - "needs an argument") - self, *args = args - if len(args) > 1: - raise TypeError('expected at most 1 arguments, got %d' % len(args)) - if args: - dict = args[0] - elif 'dict' in kwargs: - dict = kwargs.pop('dict') - import warnings - warnings.warn("Passing 'dict' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - dict = None + def __init__(self, dict=None, /, **kwargs): self.data = {} if dict is not None: self.update(dict) if kwargs: self.update(kwargs) - __init__.__text_signature__ = '($self, dict=None, /, **kwargs)' def __len__(self): return len(self.data) def __getitem__(self, key): diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index 6001e3bdb81bb3..fd0acec55d0460 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -547,7 +547,7 @@ def set_exception(self, exception): class Executor(object): """This is an abstract base class for concrete asynchronous executors.""" - def submit(*args, **kwargs): + def submit(self, fn, /, *args, **kwargs): """Submits a callable to be executed with the given arguments. Schedules the callable to be executed as fn(*args, **kwargs) and returns @@ -556,21 +556,7 @@ def submit(*args, **kwargs): Returns: A Future representing the given call. """ - if len(args) >= 2: - pass - elif not args: - raise TypeError("descriptor 'submit' of 'Executor' object " - "needs an argument") - elif 'fn' in kwargs: - import warnings - warnings.warn("Passing 'fn' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('submit expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - raise NotImplementedError() - submit.__text_signature__ = '($self, fn, /, *args, **kwargs)' def map(self, fn, *iterables, timeout=None, chunksize=1): """Returns an iterator equivalent to map(fn, iter). diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index dd14eaec907d7b..cfdcd3ed7ea9df 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -608,22 +608,7 @@ def _adjust_process_count(self): p.start() self._processes[p.pid] = p - def submit(*args, **kwargs): - if len(args) >= 2: - self, fn, *args = args - elif not args: - raise TypeError("descriptor 'submit' of 'ProcessPoolExecutor' object " - "needs an argument") - elif 'fn' in kwargs: - fn = kwargs.pop('fn') - self, *args = args - import warnings - warnings.warn("Passing 'fn' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('submit expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - + def submit(self, fn, /, *args, **kwargs): with self._shutdown_lock: if self._broken: raise BrokenProcessPool(self._broken) @@ -644,7 +629,6 @@ def submit(*args, **kwargs): self._start_queue_management_thread() return f - submit.__text_signature__ = _base.Executor.submit.__text_signature__ submit.__doc__ = _base.Executor.submit.__doc__ def map(self, fn, *iterables, timeout=None, chunksize=1): diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 2426e94de91fcb..75d05a76be3f41 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -155,22 +155,7 @@ def __init__(self, max_workers=None, thread_name_prefix='', self._initializer = initializer self._initargs = initargs - def submit(*args, **kwargs): - if len(args) >= 2: - self, fn, *args = args - elif not args: - raise TypeError("descriptor 'submit' of 'ThreadPoolExecutor' object " - "needs an argument") - elif 'fn' in kwargs: - fn = kwargs.pop('fn') - self, *args = args - import warnings - warnings.warn("Passing 'fn' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('submit expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - + def submit(self, fn, /, *args, **kwargs): with self._shutdown_lock: if self._broken: raise BrokenThreadPool(self._broken) @@ -187,7 +172,6 @@ def submit(*args, **kwargs): self._work_queue.put(w) self._adjust_thread_count() return f - submit.__text_signature__ = _base.Executor.submit.__text_signature__ submit.__doc__ = _base.Executor.submit.__doc__ def _adjust_thread_count(self): diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 94dc2bfed06cd8..69c272831a55c2 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -426,26 +426,11 @@ def enter_context(self, cm): self._push_cm_exit(cm, _exit) return result - def callback(*args, **kwds): + def callback(self, callback, /, *args, **kwds): """Registers an arbitrary callback and arguments. Cannot suppress exceptions. """ - if len(args) >= 2: - self, callback, *args = args - elif not args: - raise TypeError("descriptor 'callback' of '_BaseExitStack' object " - "needs an argument") - elif 'callback' in kwds: - callback = kwds.pop('callback') - self, *args = args - import warnings - warnings.warn("Passing 'callback' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('callback expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - _exit_wrapper = self._create_cb_wrapper(callback, *args, **kwds) # We changed the signature, so using @wraps is not appropriate, but @@ -453,7 +438,6 @@ def callback(*args, **kwds): _exit_wrapper.__wrapped__ = callback self._push_exit_callback(_exit_wrapper) return callback # Allow use as a decorator - callback.__text_signature__ = '($self, callback, /, *args, **kwds)' def _push_cm_exit(self, cm, cm_exit): """Helper to correctly register callbacks to __exit__ methods.""" @@ -587,26 +571,11 @@ def push_async_exit(self, exit): self._push_async_cm_exit(exit, exit_method) return exit # Allow use as a decorator - def push_async_callback(*args, **kwds): + def push_async_callback(self, callback, /, *args, **kwds): """Registers an arbitrary coroutine function and arguments. Cannot suppress exceptions. """ - if len(args) >= 2: - self, callback, *args = args - elif not args: - raise TypeError("descriptor 'push_async_callback' of " - "'AsyncExitStack' object needs an argument") - elif 'callback' in kwds: - callback = kwds.pop('callback') - self, *args = args - import warnings - warnings.warn("Passing 'callback' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('push_async_callback expected at least 1 ' - 'positional argument, got %d' % (len(args)-1)) - _exit_wrapper = self._create_async_cb_wrapper(callback, *args, **kwds) # We changed the signature, so using @wraps is not appropriate, but @@ -614,7 +583,6 @@ def push_async_callback(*args, **kwds): _exit_wrapper.__wrapped__ = callback self._push_exit_callback(_exit_wrapper, False) return callback # Allow use as a decorator - push_async_callback.__text_signature__ = '($self, callback, /, *args, **kwds)' async def aclose(self): """Immediately unwind the context stack.""" diff --git a/Lib/curses/__init__.py b/Lib/curses/__init__.py index 24ff3ca93a8933..69270bfcd2b205 100644 --- a/Lib/curses/__init__.py +++ b/Lib/curses/__init__.py @@ -60,7 +60,7 @@ def start_color(): # raises an exception, wrapper() will restore the terminal to a sane state so # you can read the resulting traceback. -def wrapper(*args, **kwds): +def wrapper(func, /, *args, **kwds): """Wrapper function that initializes curses and calls another function, restoring normal keyboard/screen behavior on error. The callable object 'func' is then passed the main window 'stdscr' @@ -68,17 +68,6 @@ def wrapper(*args, **kwds): wrapper(). """ - if args: - func, *args = args - elif 'func' in kwds: - func = kwds.pop('func') - import warnings - warnings.warn("Passing 'func' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('wrapper expected at least 1 positional argument, ' - 'got %d' % len(args)) - try: # Initialize curses stdscr = initscr() @@ -110,4 +99,3 @@ def wrapper(*args, **kwds): echo() nocbreak() endwin() -wrapper.__text_signature__ = '(func, /, *args, **kwds)' diff --git a/Lib/functools.py b/Lib/functools.py index 64d120182bb07a..9495fbe56eba39 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -345,23 +345,7 @@ class partialmethod(object): callables as instance methods. """ - def __init__(*args, **keywords): - if len(args) >= 2: - self, func, *args = args - elif not args: - raise TypeError("descriptor '__init__' of partialmethod " - "needs an argument") - elif 'func' in keywords: - func = keywords.pop('func') - self, *args = args - import warnings - warnings.warn("Passing 'func' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError("type 'partialmethod' takes at least one argument, " - "got %d" % (len(args)-1)) - args = tuple(args) - + def __init__(self, func, /, *args, **keywords): if not callable(func) and not hasattr(func, "__get__"): raise TypeError("{!r} is not callable or a descriptor" .format(func)) @@ -379,7 +363,6 @@ def __init__(*args, **keywords): self.func = func self.args = args self.keywords = keywords - __init__.__text_signature__ = '($self, func, /, *args, **keywords)' def __repr__(self): args = ", ".join(map(repr, self.args)) diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 7e1818bb099685..75b5150f821b1c 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -360,36 +360,10 @@ def shutdown(self, c): finally: self.stop_event.set() - def create(*args, **kwds): + def create(self, c, typeid, /, *args, **kwds): ''' Create a new shared object and return its id ''' - if len(args) >= 3: - self, c, typeid, *args = args - elif not args: - raise TypeError("descriptor 'create' of 'Server' object " - "needs an argument") - else: - if 'typeid' not in kwds: - raise TypeError('create expected at least 2 positional ' - 'arguments, got %d' % (len(args)-1)) - typeid = kwds.pop('typeid') - if len(args) >= 2: - self, c, *args = args - import warnings - warnings.warn("Passing 'typeid' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - if 'c' not in kwds: - raise TypeError('create expected at least 2 positional ' - 'arguments, got %d' % (len(args)-1)) - c = kwds.pop('c') - self, *args = args - import warnings - warnings.warn("Passing 'c' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - args = tuple(args) - with self.mutex: callable, exposed, method_to_typeid, proxytype = \ self.registry[typeid] @@ -421,7 +395,6 @@ def create(*args, **kwds): self.incref(c, ident) return ident, tuple(exposed) - create.__text_signature__ = '($self, c, typeid, /, *args, **kwds)' def get_methods(self, c, token): ''' @@ -1293,26 +1266,15 @@ def __init__(self, *args, **kwargs): _SharedMemoryTracker(f"shmm_{self.address}_{getpid()}") util.debug(f"SharedMemoryServer started by pid {getpid()}") - def create(*args, **kwargs): + def create(self, c, typeid, /, *args, **kwargs): """Create a new distributed-shared object (not backed by a shared memory block) and return its id to be used in a Proxy Object.""" # Unless set up as a shared proxy, don't make shared_memory_context # a standard part of kwargs. This makes things easier for supplying # simple functions. - if len(args) >= 3: - typeod = args[2] - elif 'typeid' in kwargs: - typeid = kwargs['typeid'] - elif not args: - raise TypeError("descriptor 'create' of 'SharedMemoryServer' " - "object needs an argument") - else: - raise TypeError('create expected at least 2 positional ' - 'arguments, got %d' % (len(args)-1)) if hasattr(self.registry[typeid][-1], "_shared_memory_proxy"): kwargs['shared_memory_context'] = self.shared_memory_context - return Server.create(*args, **kwargs) - create.__text_signature__ = '($self, c, typeid, /, *args, **kwargs)' + return Server.create(self, c, typeid, *args, **kwargs) def shutdown(self, c): "Call unlink() on all tracked shared memory, terminate the Server." diff --git a/Lib/profile.py b/Lib/profile.py index 1346297c04a593..aad458dc951f41 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -425,29 +425,13 @@ def runctx(self, cmd, globals, locals): return self # This method is more useful to profile a single function call. - def runcall(*args, **kw): - if len(args) >= 2: - self, func, *args = args - elif not args: - raise TypeError("descriptor 'runcall' of 'Profile' object " - "needs an argument") - elif 'func' in kw: - func = kw.pop('func') - self, *args = args - import warnings - warnings.warn("Passing 'func' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('runcall expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - + def runcall(self, func, /, *args, **kw): self.set_cmd(repr(func)) sys.setprofile(self.dispatcher) try: return func(*args, **kw) finally: sys.setprofile(None) - runcall.__text_signature__ = '($self, func, /, *args, **kw)' #****************************************************************** diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index b27ae719482285..2497c2b5727528 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -668,9 +668,8 @@ def test_submit_keyword(self): self.assertEqual(16, future.result()) future = self.executor.submit(capture, 1, self=2, fn=3) self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) - with self.assertWarns(DeprecationWarning): - future = self.executor.submit(fn=capture, arg=1) - self.assertEqual(future.result(), ((), {'arg': 1})) + with self.assertRaises(TypeError): + self.executor.submit(fn=capture, arg=1) with self.assertRaises(TypeError): self.executor.submit(arg=1) diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index 188a29d9f9fd77..024f912647295a 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -603,9 +603,9 @@ def _exit(*args, **kwds): stack.callback(arg=1) with self.assertRaises(TypeError): self.exit_stack.callback(arg=2) - with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): stack.callback(callback=_exit, arg=3) - self.assertEqual(result, [((), {'arg': 3})]) + self.assertEqual(result, []) def test_push(self): exc_raised = ZeroDivisionError diff --git a/Lib/test/test_contextlib_async.py b/Lib/test/test_contextlib_async.py index 492b226a0d549b..43fb7fced1bfdb 100644 --- a/Lib/test/test_contextlib_async.py +++ b/Lib/test/test_contextlib_async.py @@ -358,9 +358,9 @@ async def _exit(*args, **kwds): stack.push_async_callback(arg=1) with self.assertRaises(TypeError): self.exit_stack.push_async_callback(arg=2) - with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): stack.push_async_callback(callback=_exit, arg=3) - self.assertEqual(result, [((), {'arg': 3})]) + self.assertEqual(result, []) @_async_test async def test_async_push(self): diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 8fee1c6afdd450..c300270d49e5ec 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -556,11 +556,9 @@ class B(object): with self.assertRaises(TypeError): class B: method = functools.partialmethod() - with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): class B: method = functools.partialmethod(func=capture, a=1) - b = B() - self.assertEqual(b.method(2, x=3), ((b, 2), {'a': 1, 'x': 3})) def test_repr(self): self.assertEqual(repr(vars(self.A)['both']), diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index 4bc21eae02ce10..912badb409d9bb 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -276,9 +276,8 @@ def test_simple_caller(self): def test_arg_errors(self): res = self.tracer.runfunc(traced_capturer, 1, 2, self=3, func=4) self.assertEqual(res, ((1, 2), {'self': 3, 'func': 4})) - with self.assertWarns(DeprecationWarning): - res = self.tracer.runfunc(func=traced_capturer, arg=1) - self.assertEqual(res, ((), {'arg': 1})) + with self.assertRaises(TypeError): + self.tracer.runfunc(func=traced_capturer, arg=1) with self.assertRaises(TypeError): self.tracer.runfunc() diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py index 662c7f641af228..483910aaa4620e 100644 --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -30,8 +30,8 @@ def test_all(self): self.assertEqual(collections.UserDict(one=1, two=2), d2) # item sequence constructor self.assertEqual(collections.UserDict([('one',1), ('two',2)]), d2) - with self.assertWarnsRegex(DeprecationWarning, "'dict'"): - self.assertEqual(collections.UserDict(dict=[('one',1), ('two',2)]), d2) + self.assertEqual(collections.UserDict(dict=[('one',1), ('two',2)]), + {'dict': [('one', 1), ('two', 2)]}) # both together self.assertEqual(collections.UserDict([('one',1), ('two',2)], two=3, three=5), d3) @@ -149,9 +149,8 @@ def test_init(self): [('dict', 42)]) self.assertEqual(list(collections.UserDict({}, dict=None).items()), [('dict', None)]) - with self.assertWarnsRegex(DeprecationWarning, "'dict'"): - self.assertEqual(list(collections.UserDict(dict={'a': 42}).items()), - [('a', 42)]) + self.assertEqual(list(collections.UserDict(dict={'a': 42}).items()), + [('dict', {'a': 42})]) self.assertRaises(TypeError, collections.UserDict, 42) self.assertRaises(TypeError, collections.UserDict, (), ()) self.assertRaises(TypeError, collections.UserDict.__init__) diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 6f15c03ac5292f..ce5bbfccd78789 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -1866,20 +1866,10 @@ def fin(*args, **kwargs): f() self.assertEqual(res, [((1, 2), {'func': 3, 'obj': 4})]) - res = [] - with self.assertWarns(DeprecationWarning): - f = weakref.finalize(a, func=fin, arg=1) - self.assertEqual(f.peek(), (a, fin, (), {'arg': 1})) - f() - self.assertEqual(res, [((), {'arg': 1})]) - - res = [] - with self.assertWarns(DeprecationWarning): - f = weakref.finalize(obj=a, func=fin, arg=1) - self.assertEqual(f.peek(), (a, fin, (), {'arg': 1})) - f() - self.assertEqual(res, [((), {'arg': 1})]) - + with self.assertRaises(TypeError): + weakref.finalize(a, func=fin, arg=1) + with self.assertRaises(TypeError): + weakref.finalize(obj=a, func=fin, arg=1) self.assertRaises(TypeError, weakref.finalize, a) self.assertRaises(TypeError, weakref.finalize) diff --git a/Lib/trace.py b/Lib/trace.py index 62325d3f238ad6..681c3f9d05f811 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -451,22 +451,7 @@ def runctx(self, cmd, globals=None, locals=None): sys.settrace(None) threading.settrace(None) - def runfunc(*args, **kw): - if len(args) >= 2: - self, func, *args = args - elif not args: - raise TypeError("descriptor 'runfunc' of 'Trace' object " - "needs an argument") - elif 'func' in kw: - func = kw.pop('func') - self, *args = args - import warnings - warnings.warn("Passing 'func' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('runfunc expected at least 1 positional argument, ' - 'got %d' % (len(args)-1)) - + def runfunc(self, func, /, *args, **kw): result = None if not self.donothing: sys.settrace(self.globaltrace) @@ -476,7 +461,6 @@ def runfunc(*args, **kw): if not self.donothing: sys.settrace(None) return result - runfunc.__text_signature__ = '($self, func, /, *args, **kw)' def file_module_function_of(self, frame): code = frame.f_code diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index b363c635100726..8afb84513590f4 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -463,30 +463,13 @@ def addTypeEqualityFunc(self, typeobj, function): """ self._type_equality_funcs[typeobj] = function - def addCleanup(*args, **kwargs): + def addCleanup(self, function, /, *args, **kwargs): """Add a function, with arguments, to be called when the test is completed. Functions added are called on a LIFO basis and are called after tearDown on test failure or success. Cleanup items are called even if setUp fails (unlike tearDown).""" - if len(args) >= 2: - self, function, *args = args - elif not args: - raise TypeError("descriptor 'addCleanup' of 'TestCase' object " - "needs an argument") - elif 'function' in kwargs: - function = kwargs.pop('function') - self, *args = args - import warnings - warnings.warn("Passing 'function' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - raise TypeError('addCleanup expected at least 1 positional ' - 'argument, got %d' % (len(args)-1)) - args = tuple(args) - self._cleanups.append((function, args, kwargs)) - addCleanup.__text_signature__ = '($self, function, /, *args, **kwargs)' @classmethod def addClassCleanup(cls, function, /, *args, **kwargs): diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py index 7d36340741f463..dd9a1b6d9aeddf 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/unittest/test/test_runner.py @@ -592,7 +592,7 @@ def cleanup(*args, **kwargs): class TestableTest(unittest.TestCase): def setUp(self2): self2.addCleanup(cleanup, 1, 2, function=3, self=4) - with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): self2.addCleanup(function=cleanup, arg='hello') def testNothing(self): pass @@ -603,8 +603,7 @@ def testNothing(self): unittest.TestCase.addCleanup(self=TestableTest(), function=cleanup) runTests(TestableTest) self.assertEqual(cleanups, - [((), {'arg': 'hello'}), - ((1, 2), {'function': 3, 'self': 4})]) + [((1, 2), {'function': 3, 'self': 4})]) def test_with_errors_in_addClassCleanup(self): ordering = [] diff --git a/Lib/weakref.py b/Lib/weakref.py index 8d71af653b7ec4..fa7559bb3dbf86 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -514,33 +514,7 @@ class finalize: class _Info: __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index") - def __init__(*args, **kwargs): - if len(args) >= 3: - self, obj, func, *args = args - elif not args: - raise TypeError("descriptor '__init__' of 'finalize' object " - "needs an argument") - else: - if 'func' not in kwargs: - raise TypeError('finalize expected at least 2 positional ' - 'arguments, got %d' % (len(args)-1)) - func = kwargs.pop('func') - if len(args) >= 2: - self, obj, *args = args - import warnings - warnings.warn("Passing 'func' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - else: - if 'obj' not in kwargs: - raise TypeError('finalize expected at least 2 positional ' - 'arguments, got %d' % (len(args)-1)) - obj = kwargs.pop('obj') - self, *args = args - import warnings - warnings.warn("Passing 'obj' as keyword argument is deprecated", - DeprecationWarning, stacklevel=2) - args = tuple(args) - + def __init__(self, obj, func, /, *args, **kwargs): if not self._registered_with_atexit: # We may register the exit function more than once because # of a thread race, but that is harmless @@ -556,7 +530,6 @@ def __init__(*args, **kwargs): info.index = next(self._index_iter) self._registry[self] = info finalize._dirty = True - __init__.__text_signature__ = '($self, obj, func, /, *args, **kwargs)' def __call__(self, _=None): """If alive then mark as dead and return func(*args, **kwargs); From 66c4f3f38b867d8329b28c032bb907fd1a2f22d2 Mon Sep 17 00:00:00 2001 From: Abhilash Raj Date: Wed, 5 Jun 2019 12:56:33 -0400 Subject: [PATCH 333/441] bpo-21315: Fix parsing of encoded words with missing leading ws. (#13425) * bpo-21315: Fix parsing of encoded words with missing leading ws. Because of missing leading whitespace, encoded word would get parsed as unstructured token. This patch fixes that by looking for encoded words when splitting tokens with whitespace. Missing trailing whitespace around encoded word now register a defect instead. Original patch suggestion by David R. Murray on bpo-21315. --- Lib/email/_header_value_parser.py | 21 ++++++++++++++++ .../test_email/test__header_value_parser.py | 24 +++++++++++++++++-- Lib/test/test_email/test_headerregistry.py | 3 ++- .../2019-05-19-10-48-46.bpo-21315.PgXVqF.rst | 4 ++++ 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rst diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 34969ab5915119..35d746aa50825a 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -96,6 +96,18 @@ def quote_string(value): return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"' +# Match a RFC 2047 word, looks like =?utf-8?q?someword?= +rfc2047_matcher = re.compile(r''' + =\? # literal =? + [^?]* # charset + \? # literal ? + [qQbB] # literal 'q' or 'b', case insensitive + \? # literal ? + .*? # encoded word + \?= # literal ?= +''', re.VERBOSE | re.MULTILINE) + + # # TokenList and its subclasses # @@ -1052,6 +1064,10 @@ def get_encoded_word(value): _validate_xtext(vtext) ew.append(vtext) text = ''.join(remainder) + # Encoded words should be followed by a WS + if value and value[0] not in WSP: + ew.defects.append(errors.InvalidHeaderDefect( + "missing trailing whitespace after encoded-word")) return ew, value def get_unstructured(value): @@ -1104,6 +1120,11 @@ def get_unstructured(value): unstructured.append(token) continue tok, *remainder = _wsp_splitter(value, 1) + # Split in the middle of an atom if there is a rfc2047 encoded word + # which does not have WSP on both sides. The defect will be registered + # the next time through the loop. + if rfc2047_matcher.search(tok): + tok, *remainder = value.partition('=?') vtext = ValueTerminal(tok, 'vtext') _validate_xtext(vtext) unstructured.append(vtext) diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 12da3cffb84c88..649923fa6c8667 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -118,7 +118,7 @@ def test_get_encoded_word_gets_first_even_if_no_space(self): '=?us-ascii?q?first?==?utf-8?q?second?=', 'first', 'first', - [], + [errors.InvalidHeaderDefect], '=?utf-8?q?second?=') def test_get_encoded_word_sets_extra_attributes(self): @@ -361,6 +361,25 @@ def test_get_unstructured_no_whitespace_between_ews(self): '=?utf-8?q?foo?==?utf-8?q?bar?=', 'foobar', 'foobar', + [errors.InvalidHeaderDefect, + errors.InvalidHeaderDefect], + '') + + def test_get_unstructured_ew_without_leading_whitespace(self): + self._test_get_x( + self._get_unst, + 'nowhitespace=?utf-8?q?somevalue?=', + 'nowhitespacesomevalue', + 'nowhitespacesomevalue', + [errors.InvalidHeaderDefect], + '') + + def test_get_unstructured_ew_without_trailing_whitespace(self): + self._test_get_x( + self._get_unst, + '=?utf-8?q?somevalue?=nowhitespace', + 'somevaluenowhitespace', + 'somevaluenowhitespace', [errors.InvalidHeaderDefect], '') @@ -546,7 +565,8 @@ def test_encoded_word_inside_quotes(self): '"=?utf-8?Q?not_really_valid?="', '"not really valid"', 'not really valid', - [errors.InvalidHeaderDefect], + [errors.InvalidHeaderDefect, + errors.InvalidHeaderDefect], '') # get_comment diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index 75505460aba89e..5d9b3576d30657 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -1180,7 +1180,8 @@ class TestAddressHeader(TestHeaderBase): 'rfc2047_atom_in_quoted_string_is_decoded': ('"=?utf-8?q?=C3=89ric?=" ', - [errors.InvalidHeaderDefect], + [errors.InvalidHeaderDefect, + errors.InvalidHeaderDefect], 'Éric ', 'Éric', 'foo@example.com', diff --git a/Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rst b/Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rst new file mode 100644 index 00000000000000..dd0dd7f72c0a3f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-19-10-48-46.bpo-21315.PgXVqF.rst @@ -0,0 +1,4 @@ +Email headers containing RFC2047 encoded words are parsed despite the missing +whitespace, and a defect registered. Also missing trailing whitespace after +encoded words is now registered as a defect. + From 1e77ab0a35cf95318bb4893f7253a30f73201163 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Jun 2019 21:59:33 +0200 Subject: [PATCH 334/441] bpo-33725, multiprocessing doc: rephase warning against fork on macOS (GH-13841) Co-Authored-By: Barry Warsaw --- Doc/library/multiprocessing.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 6c07124f97907a..d8182feab963a1 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -126,8 +126,9 @@ to start a process. These *start methods* are .. versionchanged:: 3.8 - On macOS, *spawn* start method is now the default: *fork* start method is no - longer reliable on macOS, see :issue:`33725`. + On macOS, the *spawn* start method is now the default. The *fork* start + method should be considered unsafe as it can lead to crashes of the + subprocess. See :issue:`33725`. .. versionchanged:: 3.4 *spawn* added on all unix platforms, and *forkserver* added for From 54edb04aa688c8247570b4f59b5145e3fa417576 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 5 Jun 2019 21:24:28 +0100 Subject: [PATCH 335/441] bpo-37134: Add PEP570 notation to the documentation (GH-13743) --- Doc/library/struct.rst | 2 +- Doc/library/zlib.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 1a0fd73c6758c7..a06d90344ba34e 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -70,7 +70,7 @@ The module defines the following exception and functions: size required by the format, as reflected by :func:`calcsize`. -.. function:: unpack_from(format, buffer, offset=0) +.. function:: unpack_from(format, /, buffer, offset=0) Unpack from *buffer* starting at position *offset*, according to the format string *format*. The result is a tuple even if it contains exactly one diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index aa61278e099ac6..339acfd0e5786f 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -47,7 +47,7 @@ The available exception and functions in this module are: platforms, use ``adler32(data) & 0xffffffff``. -.. function:: compress(data, level=-1) +.. function:: compress(data, /, level=-1) Compresses the bytes in *data*, returning a bytes object containing compressed data. *level* is an integer from ``0`` to ``9`` or ``-1`` controlling the level of compression; @@ -132,7 +132,7 @@ The available exception and functions in this module are: platforms, use ``crc32(data) & 0xffffffff``. -.. function:: decompress(data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE) +.. function:: decompress(data, /, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE) Decompresses the bytes in *data*, returning a bytes object containing the uncompressed data. The *wbits* parameter depends on From c4c15ed7a2c7c2a1983e88b89c244d121eb3e512 Mon Sep 17 00:00:00 2001 From: Ashwin Ramaswami Date: Wed, 5 Jun 2019 15:18:07 -0700 Subject: [PATCH 336/441] bpo-35551: encodings update (GH-11446) --- Doc/library/codecs.rst | 3 ++- Lib/encodings/aliases.py | 4 +--- .../2019-01-18-16-16-27.bpo-35551.oF5pbO.rst | 3 +++ 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-35551.oF5pbO.rst diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 2e9314e0fab793..5048621bf0ad14 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -1198,7 +1198,8 @@ particular, the following variants typically exist: +-----------------+--------------------------------+--------------------------------+ | mac_iceland | maciceland | Icelandic | +-----------------+--------------------------------+--------------------------------+ -| mac_latin2 | maclatin2, maccentraleurope | Central and Eastern Europe | +| mac_latin2 | maclatin2, maccentraleurope, | Central and Eastern Europe | +| | mac_centeuro | | +-----------------+--------------------------------+--------------------------------+ | mac_roman | macroman, macintosh | Western Europe | +-----------------+--------------------------------+--------------------------------+ diff --git a/Lib/encodings/aliases.py b/Lib/encodings/aliases.py index 5ef40a3438b969..8b621add1b1bad 100644 --- a/Lib/encodings/aliases.py +++ b/Lib/encodings/aliases.py @@ -448,6 +448,7 @@ # mac_latin2 codec 'maccentraleurope' : 'mac_latin2', + 'mac_centeuro' : 'mac_latin2', 'maclatin2' : 'mac_latin2', # mac_roman codec @@ -491,9 +492,6 @@ 'sjisx0213' : 'shift_jisx0213', 's_jisx0213' : 'shift_jisx0213', - # tactis codec - 'tis260' : 'tactis', - # tis_620 codec 'tis620' : 'tis_620', 'tis_620_0' : 'tis_620', diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-35551.oF5pbO.rst b/Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-35551.oF5pbO.rst new file mode 100644 index 00000000000000..bd7946e6d94771 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-01-18-16-16-27.bpo-35551.oF5pbO.rst @@ -0,0 +1,3 @@ +Updated encodings: +- Removed the "tis260" encoding, which was an alias for the nonexistent "tactis" codec. +- Added "mac_centeuro" as an alias for the mac_latin2 encoding. \ No newline at end of file From e985804207473796a1326585b3e1b9e18c764345 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 5 Jun 2019 16:05:25 -0700 Subject: [PATCH 337/441] bpo-37165: Convert _count_elements to the argument clinic (GH-13848) --- .../2019-06-05-11-48-19.bpo-37165.V_rwfE.rst | 1 + Modules/_collectionsmodule.c | 27 ++++++++------- Modules/clinic/_collectionsmodule.c.h | 33 ++++++++++++++++++- 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst diff --git a/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst b/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst new file mode 100644 index 00000000000000..5430a57ef54c57 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-05-11-48-19.bpo-37165.V_rwfE.rst @@ -0,0 +1 @@ +Converted _collections._count_elements to use the Argument Clinic. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index dacea3a0243914..45169ecd11af00 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -8,9 +8,10 @@ #endif /*[clinic input] +module _collections class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ee5ed5baabe35068]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a8ece4ccad7e30ac]*/ static PyTypeObject tuplegetter_type; #include "clinic/_collectionsmodule.c.h" @@ -2228,17 +2229,24 @@ static PyTypeObject defdict_type = { /* helper function for Counter *********************************************/ -PyDoc_STRVAR(_count_elements_doc, -"_count_elements(mapping, iterable) -> None\n\ -\n\ -Count elements in the iterable, updating the mapping"); +/*[clinic input] +_collections._count_elements + + mapping: object + iterable: object + / + +Count elements in the iterable, updating the mapping +[clinic start generated code]*/ static PyObject * -_count_elements(PyObject *self, PyObject *args) +_collections__count_elements_impl(PyObject *module, PyObject *mapping, + PyObject *iterable) +/*[clinic end generated code: output=7e0c1789636b3d8f input=e79fad04534a0b45]*/ { _Py_IDENTIFIER(get); _Py_IDENTIFIER(__setitem__); - PyObject *it, *iterable, *mapping, *oldval; + PyObject *it, *oldval; PyObject *newval = NULL; PyObject *key = NULL; PyObject *bound_get = NULL; @@ -2247,9 +2255,6 @@ _count_elements(PyObject *self, PyObject *args) PyObject *mapping_setitem; PyObject *dict_setitem; - if (!PyArg_UnpackTuple(args, "_count_elements", 2, 2, &mapping, &iterable)) - return NULL; - it = PyObject_GetIter(iterable); if (it == NULL) return NULL; @@ -2510,7 +2515,7 @@ PyDoc_STRVAR(module_doc, "); static struct PyMethodDef module_functions[] = { - {"_count_elements", _count_elements, METH_VARARGS, _count_elements_doc}, + _COLLECTIONS__COUNT_ELEMENTS_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/clinic/_collectionsmodule.c.h b/Modules/clinic/_collectionsmodule.c.h index ed3b1b50f9b582..c3ba1a6698571d 100644 --- a/Modules/clinic/_collectionsmodule.c.h +++ b/Modules/clinic/_collectionsmodule.c.h @@ -2,6 +2,37 @@ preserve [clinic start generated code]*/ +PyDoc_STRVAR(_collections__count_elements__doc__, +"_count_elements($module, mapping, iterable, /)\n" +"--\n" +"\n" +"Count elements in the iterable, updating the mapping"); + +#define _COLLECTIONS__COUNT_ELEMENTS_METHODDEF \ + {"_count_elements", (PyCFunction)(void(*)(void))_collections__count_elements, METH_FASTCALL, _collections__count_elements__doc__}, + +static PyObject * +_collections__count_elements_impl(PyObject *module, PyObject *mapping, + PyObject *iterable); + +static PyObject * +_collections__count_elements(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *mapping; + PyObject *iterable; + + if (!_PyArg_CheckPositional("_count_elements", nargs, 2, 2)) { + goto exit; + } + mapping = args[0]; + iterable = args[1]; + return_value = _collections__count_elements_impl(module, mapping, iterable); + +exit: + return return_value; +} + static PyObject * tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc); @@ -42,4 +73,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=51bd572577ca7111 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9d2bfcc9df5faf35 input=a9049054013a1b77]*/ From c4c421d619baf2ff2f7e09f55b7ae22b8f863c7b Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 6 Jun 2019 00:11:46 +0100 Subject: [PATCH 338/441] bpo-37134: Use PEP570 syntax for sum() (GH-13851) --- Doc/library/functions.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 415a65b4946f08..88977056723f2e 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1562,11 +1562,11 @@ are always available. They are listed here in alphabetical order. about strings, see :ref:`textseq`. -.. function:: sum(iterable[, start]) +.. function:: sum(iterable, /, start=0) Sums *start* and the items of an *iterable* from left to right and returns the - total. *start* defaults to ``0``. The *iterable*'s items are normally numbers, - and the start value is not allowed to be a string. + total. The *iterable*'s items are normally numbers, and the start value is not + allowed to be a string. For some use cases, there are good alternatives to :func:`sum`. The preferred, fast way to concatenate a sequence of strings is by calling From 4867eaa294c5f5fb360e111d54f3543d502b4f46 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Wed, 5 Jun 2019 19:40:19 -0700 Subject: [PATCH 339/441] Add importlib.metadata to what's new. (#13855) --- Doc/whatsnew/3.8.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 8456a17aedcc0d..bf75387d9517f3 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -330,7 +330,10 @@ Other Language Changes New Modules =========== -* None yet. +* The new :mod:`importlib.metadata` module provides (provisional) support for + reading metadata from third-party packages. For example, you can extract an + installed package's version number, list of entry points, and more. See + :issue:`34632` for additional details. Improved Modules From cb65202520e7959196a2df8215692de155bf0cc8 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Thu, 6 Jun 2019 14:38:52 +0900 Subject: [PATCH 340/441] bpo-35551: remove mac_centeuro encoding (GH-13856) It is alias to mac_latin2 now. --- Lib/encodings/mac_centeuro.py | 307 ---------------------------------- 1 file changed, 307 deletions(-) delete mode 100644 Lib/encodings/mac_centeuro.py diff --git a/Lib/encodings/mac_centeuro.py b/Lib/encodings/mac_centeuro.py deleted file mode 100644 index 5785a0ec12df42..00000000000000 --- a/Lib/encodings/mac_centeuro.py +++ /dev/null @@ -1,307 +0,0 @@ -""" Python Character Mapping Codec mac_centeuro generated from 'MAPPINGS/VENDORS/APPLE/CENTEURO.TXT' with gencodec.py. - -"""#" - -import codecs - -### Codec APIs - -class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - return codecs.charmap_encode(input,errors,encoding_table) - - def decode(self,input,errors='strict'): - return codecs.charmap_decode(input,errors,decoding_table) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, input, final=False): - return codecs.charmap_encode(input,self.errors,encoding_table)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, input, final=False): - return codecs.charmap_decode(input,self.errors,decoding_table)[0] - -class StreamWriter(Codec,codecs.StreamWriter): - pass - -class StreamReader(Codec,codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='mac-centeuro', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamreader=StreamReader, - streamwriter=StreamWriter, - ) - - -### Decoding Table - -decoding_table = ( - '\x00' # 0x00 -> CONTROL CHARACTER - '\x01' # 0x01 -> CONTROL CHARACTER - '\x02' # 0x02 -> CONTROL CHARACTER - '\x03' # 0x03 -> CONTROL CHARACTER - '\x04' # 0x04 -> CONTROL CHARACTER - '\x05' # 0x05 -> CONTROL CHARACTER - '\x06' # 0x06 -> CONTROL CHARACTER - '\x07' # 0x07 -> CONTROL CHARACTER - '\x08' # 0x08 -> CONTROL CHARACTER - '\t' # 0x09 -> CONTROL CHARACTER - '\n' # 0x0A -> CONTROL CHARACTER - '\x0b' # 0x0B -> CONTROL CHARACTER - '\x0c' # 0x0C -> CONTROL CHARACTER - '\r' # 0x0D -> CONTROL CHARACTER - '\x0e' # 0x0E -> CONTROL CHARACTER - '\x0f' # 0x0F -> CONTROL CHARACTER - '\x10' # 0x10 -> CONTROL CHARACTER - '\x11' # 0x11 -> CONTROL CHARACTER - '\x12' # 0x12 -> CONTROL CHARACTER - '\x13' # 0x13 -> CONTROL CHARACTER - '\x14' # 0x14 -> CONTROL CHARACTER - '\x15' # 0x15 -> CONTROL CHARACTER - '\x16' # 0x16 -> CONTROL CHARACTER - '\x17' # 0x17 -> CONTROL CHARACTER - '\x18' # 0x18 -> CONTROL CHARACTER - '\x19' # 0x19 -> CONTROL CHARACTER - '\x1a' # 0x1A -> CONTROL CHARACTER - '\x1b' # 0x1B -> CONTROL CHARACTER - '\x1c' # 0x1C -> CONTROL CHARACTER - '\x1d' # 0x1D -> CONTROL CHARACTER - '\x1e' # 0x1E -> CONTROL CHARACTER - '\x1f' # 0x1F -> CONTROL CHARACTER - ' ' # 0x20 -> SPACE - '!' # 0x21 -> EXCLAMATION MARK - '"' # 0x22 -> QUOTATION MARK - '#' # 0x23 -> NUMBER SIGN - '$' # 0x24 -> DOLLAR SIGN - '%' # 0x25 -> PERCENT SIGN - '&' # 0x26 -> AMPERSAND - "'" # 0x27 -> APOSTROPHE - '(' # 0x28 -> LEFT PARENTHESIS - ')' # 0x29 -> RIGHT PARENTHESIS - '*' # 0x2A -> ASTERISK - '+' # 0x2B -> PLUS SIGN - ',' # 0x2C -> COMMA - '-' # 0x2D -> HYPHEN-MINUS - '.' # 0x2E -> FULL STOP - '/' # 0x2F -> SOLIDUS - '0' # 0x30 -> DIGIT ZERO - '1' # 0x31 -> DIGIT ONE - '2' # 0x32 -> DIGIT TWO - '3' # 0x33 -> DIGIT THREE - '4' # 0x34 -> DIGIT FOUR - '5' # 0x35 -> DIGIT FIVE - '6' # 0x36 -> DIGIT SIX - '7' # 0x37 -> DIGIT SEVEN - '8' # 0x38 -> DIGIT EIGHT - '9' # 0x39 -> DIGIT NINE - ':' # 0x3A -> COLON - ';' # 0x3B -> SEMICOLON - '<' # 0x3C -> LESS-THAN SIGN - '=' # 0x3D -> EQUALS SIGN - '>' # 0x3E -> GREATER-THAN SIGN - '?' # 0x3F -> QUESTION MARK - '@' # 0x40 -> COMMERCIAL AT - 'A' # 0x41 -> LATIN CAPITAL LETTER A - 'B' # 0x42 -> LATIN CAPITAL LETTER B - 'C' # 0x43 -> LATIN CAPITAL LETTER C - 'D' # 0x44 -> LATIN CAPITAL LETTER D - 'E' # 0x45 -> LATIN CAPITAL LETTER E - 'F' # 0x46 -> LATIN CAPITAL LETTER F - 'G' # 0x47 -> LATIN CAPITAL LETTER G - 'H' # 0x48 -> LATIN CAPITAL LETTER H - 'I' # 0x49 -> LATIN CAPITAL LETTER I - 'J' # 0x4A -> LATIN CAPITAL LETTER J - 'K' # 0x4B -> LATIN CAPITAL LETTER K - 'L' # 0x4C -> LATIN CAPITAL LETTER L - 'M' # 0x4D -> LATIN CAPITAL LETTER M - 'N' # 0x4E -> LATIN CAPITAL LETTER N - 'O' # 0x4F -> LATIN CAPITAL LETTER O - 'P' # 0x50 -> LATIN CAPITAL LETTER P - 'Q' # 0x51 -> LATIN CAPITAL LETTER Q - 'R' # 0x52 -> LATIN CAPITAL LETTER R - 'S' # 0x53 -> LATIN CAPITAL LETTER S - 'T' # 0x54 -> LATIN CAPITAL LETTER T - 'U' # 0x55 -> LATIN CAPITAL LETTER U - 'V' # 0x56 -> LATIN CAPITAL LETTER V - 'W' # 0x57 -> LATIN CAPITAL LETTER W - 'X' # 0x58 -> LATIN CAPITAL LETTER X - 'Y' # 0x59 -> LATIN CAPITAL LETTER Y - 'Z' # 0x5A -> LATIN CAPITAL LETTER Z - '[' # 0x5B -> LEFT SQUARE BRACKET - '\\' # 0x5C -> REVERSE SOLIDUS - ']' # 0x5D -> RIGHT SQUARE BRACKET - '^' # 0x5E -> CIRCUMFLEX ACCENT - '_' # 0x5F -> LOW LINE - '`' # 0x60 -> GRAVE ACCENT - 'a' # 0x61 -> LATIN SMALL LETTER A - 'b' # 0x62 -> LATIN SMALL LETTER B - 'c' # 0x63 -> LATIN SMALL LETTER C - 'd' # 0x64 -> LATIN SMALL LETTER D - 'e' # 0x65 -> LATIN SMALL LETTER E - 'f' # 0x66 -> LATIN SMALL LETTER F - 'g' # 0x67 -> LATIN SMALL LETTER G - 'h' # 0x68 -> LATIN SMALL LETTER H - 'i' # 0x69 -> LATIN SMALL LETTER I - 'j' # 0x6A -> LATIN SMALL LETTER J - 'k' # 0x6B -> LATIN SMALL LETTER K - 'l' # 0x6C -> LATIN SMALL LETTER L - 'm' # 0x6D -> LATIN SMALL LETTER M - 'n' # 0x6E -> LATIN SMALL LETTER N - 'o' # 0x6F -> LATIN SMALL LETTER O - 'p' # 0x70 -> LATIN SMALL LETTER P - 'q' # 0x71 -> LATIN SMALL LETTER Q - 'r' # 0x72 -> LATIN SMALL LETTER R - 's' # 0x73 -> LATIN SMALL LETTER S - 't' # 0x74 -> LATIN SMALL LETTER T - 'u' # 0x75 -> LATIN SMALL LETTER U - 'v' # 0x76 -> LATIN SMALL LETTER V - 'w' # 0x77 -> LATIN SMALL LETTER W - 'x' # 0x78 -> LATIN SMALL LETTER X - 'y' # 0x79 -> LATIN SMALL LETTER Y - 'z' # 0x7A -> LATIN SMALL LETTER Z - '{' # 0x7B -> LEFT CURLY BRACKET - '|' # 0x7C -> VERTICAL LINE - '}' # 0x7D -> RIGHT CURLY BRACKET - '~' # 0x7E -> TILDE - '\x7f' # 0x7F -> CONTROL CHARACTER - '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS - '\u0100' # 0x81 -> LATIN CAPITAL LETTER A WITH MACRON - '\u0101' # 0x82 -> LATIN SMALL LETTER A WITH MACRON - '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE - '\u0104' # 0x84 -> LATIN CAPITAL LETTER A WITH OGONEK - '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS - '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS - '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE - '\u0105' # 0x88 -> LATIN SMALL LETTER A WITH OGONEK - '\u010c' # 0x89 -> LATIN CAPITAL LETTER C WITH CARON - '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS - '\u010d' # 0x8B -> LATIN SMALL LETTER C WITH CARON - '\u0106' # 0x8C -> LATIN CAPITAL LETTER C WITH ACUTE - '\u0107' # 0x8D -> LATIN SMALL LETTER C WITH ACUTE - '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE - '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE - '\u017a' # 0x90 -> LATIN SMALL LETTER Z WITH ACUTE - '\u010e' # 0x91 -> LATIN CAPITAL LETTER D WITH CARON - '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE - '\u010f' # 0x93 -> LATIN SMALL LETTER D WITH CARON - '\u0112' # 0x94 -> LATIN CAPITAL LETTER E WITH MACRON - '\u0113' # 0x95 -> LATIN SMALL LETTER E WITH MACRON - '\u0116' # 0x96 -> LATIN CAPITAL LETTER E WITH DOT ABOVE - '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE - '\u0117' # 0x98 -> LATIN SMALL LETTER E WITH DOT ABOVE - '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX - '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS - '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE - '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE - '\u011a' # 0x9D -> LATIN CAPITAL LETTER E WITH CARON - '\u011b' # 0x9E -> LATIN SMALL LETTER E WITH CARON - '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS - '\u2020' # 0xA0 -> DAGGER - '\xb0' # 0xA1 -> DEGREE SIGN - '\u0118' # 0xA2 -> LATIN CAPITAL LETTER E WITH OGONEK - '\xa3' # 0xA3 -> POUND SIGN - '\xa7' # 0xA4 -> SECTION SIGN - '\u2022' # 0xA5 -> BULLET - '\xb6' # 0xA6 -> PILCROW SIGN - '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S - '\xae' # 0xA8 -> REGISTERED SIGN - '\xa9' # 0xA9 -> COPYRIGHT SIGN - '\u2122' # 0xAA -> TRADE MARK SIGN - '\u0119' # 0xAB -> LATIN SMALL LETTER E WITH OGONEK - '\xa8' # 0xAC -> DIAERESIS - '\u2260' # 0xAD -> NOT EQUAL TO - '\u0123' # 0xAE -> LATIN SMALL LETTER G WITH CEDILLA - '\u012e' # 0xAF -> LATIN CAPITAL LETTER I WITH OGONEK - '\u012f' # 0xB0 -> LATIN SMALL LETTER I WITH OGONEK - '\u012a' # 0xB1 -> LATIN CAPITAL LETTER I WITH MACRON - '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO - '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO - '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON - '\u0136' # 0xB5 -> LATIN CAPITAL LETTER K WITH CEDILLA - '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL - '\u2211' # 0xB7 -> N-ARY SUMMATION - '\u0142' # 0xB8 -> LATIN SMALL LETTER L WITH STROKE - '\u013b' # 0xB9 -> LATIN CAPITAL LETTER L WITH CEDILLA - '\u013c' # 0xBA -> LATIN SMALL LETTER L WITH CEDILLA - '\u013d' # 0xBB -> LATIN CAPITAL LETTER L WITH CARON - '\u013e' # 0xBC -> LATIN SMALL LETTER L WITH CARON - '\u0139' # 0xBD -> LATIN CAPITAL LETTER L WITH ACUTE - '\u013a' # 0xBE -> LATIN SMALL LETTER L WITH ACUTE - '\u0145' # 0xBF -> LATIN CAPITAL LETTER N WITH CEDILLA - '\u0146' # 0xC0 -> LATIN SMALL LETTER N WITH CEDILLA - '\u0143' # 0xC1 -> LATIN CAPITAL LETTER N WITH ACUTE - '\xac' # 0xC2 -> NOT SIGN - '\u221a' # 0xC3 -> SQUARE ROOT - '\u0144' # 0xC4 -> LATIN SMALL LETTER N WITH ACUTE - '\u0147' # 0xC5 -> LATIN CAPITAL LETTER N WITH CARON - '\u2206' # 0xC6 -> INCREMENT - '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS - '\xa0' # 0xCA -> NO-BREAK SPACE - '\u0148' # 0xCB -> LATIN SMALL LETTER N WITH CARON - '\u0150' # 0xCC -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE - '\u0151' # 0xCE -> LATIN SMALL LETTER O WITH DOUBLE ACUTE - '\u014c' # 0xCF -> LATIN CAPITAL LETTER O WITH MACRON - '\u2013' # 0xD0 -> EN DASH - '\u2014' # 0xD1 -> EM DASH - '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK - '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK - '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK - '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK - '\xf7' # 0xD6 -> DIVISION SIGN - '\u25ca' # 0xD7 -> LOZENGE - '\u014d' # 0xD8 -> LATIN SMALL LETTER O WITH MACRON - '\u0154' # 0xD9 -> LATIN CAPITAL LETTER R WITH ACUTE - '\u0155' # 0xDA -> LATIN SMALL LETTER R WITH ACUTE - '\u0158' # 0xDB -> LATIN CAPITAL LETTER R WITH CARON - '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK - '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - '\u0159' # 0xDE -> LATIN SMALL LETTER R WITH CARON - '\u0156' # 0xDF -> LATIN CAPITAL LETTER R WITH CEDILLA - '\u0157' # 0xE0 -> LATIN SMALL LETTER R WITH CEDILLA - '\u0160' # 0xE1 -> LATIN CAPITAL LETTER S WITH CARON - '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK - '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK - '\u0161' # 0xE4 -> LATIN SMALL LETTER S WITH CARON - '\u015a' # 0xE5 -> LATIN CAPITAL LETTER S WITH ACUTE - '\u015b' # 0xE6 -> LATIN SMALL LETTER S WITH ACUTE - '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE - '\u0164' # 0xE8 -> LATIN CAPITAL LETTER T WITH CARON - '\u0165' # 0xE9 -> LATIN SMALL LETTER T WITH CARON - '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE - '\u017d' # 0xEB -> LATIN CAPITAL LETTER Z WITH CARON - '\u017e' # 0xEC -> LATIN SMALL LETTER Z WITH CARON - '\u016a' # 0xED -> LATIN CAPITAL LETTER U WITH MACRON - '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE - '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX - '\u016b' # 0xF0 -> LATIN SMALL LETTER U WITH MACRON - '\u016e' # 0xF1 -> LATIN CAPITAL LETTER U WITH RING ABOVE - '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE - '\u016f' # 0xF3 -> LATIN SMALL LETTER U WITH RING ABOVE - '\u0170' # 0xF4 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - '\u0171' # 0xF5 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE - '\u0172' # 0xF6 -> LATIN CAPITAL LETTER U WITH OGONEK - '\u0173' # 0xF7 -> LATIN SMALL LETTER U WITH OGONEK - '\xdd' # 0xF8 -> LATIN CAPITAL LETTER Y WITH ACUTE - '\xfd' # 0xF9 -> LATIN SMALL LETTER Y WITH ACUTE - '\u0137' # 0xFA -> LATIN SMALL LETTER K WITH CEDILLA - '\u017b' # 0xFB -> LATIN CAPITAL LETTER Z WITH DOT ABOVE - '\u0141' # 0xFC -> LATIN CAPITAL LETTER L WITH STROKE - '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE - '\u0122' # 0xFE -> LATIN CAPITAL LETTER G WITH CEDILLA - '\u02c7' # 0xFF -> CARON -) - -### Encoding table -encoding_table=codecs.charmap_build(decoding_table) From 6af230359e57122708247dac970e05e05529cde6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Walter=20D=C3=B6rwald?= Date: Thu, 6 Jun 2019 12:13:08 +0200 Subject: [PATCH 341/441] bpo-2661: Make mapping tests better usable for custom mapping classes. (GH-11157) In test_fromkeys() the derived test class now supports all arguments in its constructor so that the class to be tested can use its own constructor in its fromkeys() implementation. In test_mutatingiteration() the test fails as soon as iterating over a dictionary with one entry and adding new entries in the loop iterates more than once (to avoid endless loops in faulty implementations). https://bugs.python.org/issue2661 --- Lib/test/mapping_tests.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 53f29f605386ba..613206a0855aea 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -448,7 +448,7 @@ def __new__(cls): class Exc(Exception): pass class baddict1(self.type2test): - def __init__(self): + def __init__(self, *args, **kwargs): raise Exc() self.assertRaises(Exc, baddict1.fromkeys, [1]) @@ -595,12 +595,14 @@ def test_mutatingiteration(self): d = self._empty_mapping() d[1] = 1 try: + count = 0 for i in d: d[i+1] = 1 + if count >= 1: + self.fail("changing dict size during iteration doesn't raise Error") + count += 1 except RuntimeError: pass - else: - self.fail("changing dict size during iteration doesn't raise Error") def test_repr(self): d = self._empty_mapping() From 013a18a65167725f140c0395211050ae03501b12 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 6 Jun 2019 14:25:18 +0200 Subject: [PATCH 342/441] bpo-36763, _testembed: enable assert() in release mode (GH-13857) --- Programs/_testembed.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 3e1210e04d8245..9633f4610b5494 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1,10 +1,13 @@ -/* FIXME: PEP 587 makes these functions public */ #ifndef Py_BUILD_CORE_MODULE # define Py_BUILD_CORE_MODULE #endif +/* Always enable assertion (even in release mode) */ +#undef NDEBUG + #include -#include "pycore_initconfig.h" /* FIXME: PEP 587 makes these functions public */ +#include "pycore_initconfig.h" /* _PyConfig_InitCompatConfig() */ +#include "pycore_pystate.h" /* _PyRuntime */ #include #include "pythread.h" #include From e0c0c7e8c9f8153a54b92e43aa3d09e69a9fd0c0 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 6 Jun 2019 09:06:51 -0700 Subject: [PATCH 343/441] bpo-37156: Fix libssl DLL tag in MSI sources (GH-13866) --- Tools/msi/msi.props | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index 0fe822af93194b..5da901c0215a2f 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -87,15 +87,16 @@ PyArchExt=$(PyArchExt); PyTestExt=$(PyTestExt); OptionalFeatureName=$(OutputName); + ssltag=-1_1; $(DefineConstants);CRTRedist=$(CRTRedist); - $(DefineConstants);Suffix32=-32;ssltag=-1_1; + $(DefineConstants);Suffix32=-32; - $(DefineConstants);Suffix32=;ssltag=-1_1-x64; + $(DefineConstants);Suffix32=; From f6713e84afc5addcfa8477dbdf2c027787f711c0 Mon Sep 17 00:00:00 2001 From: websurfer5 <49998481+websurfer5@users.noreply.github.com> Date: Thu, 6 Jun 2019 12:53:27 -0700 Subject: [PATCH 344/441] bpo-36520: Email header folded incorrectly (#13608) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bpo-36520: reset the encoded word offset when starting a new line during an email header folding operation * 📜🤖 Added by blurb_it. * bpo-36520: add an additional test case, and provide descriptive comments for the test_folding_with_utf8_encoding_* tests * bpo-36520: fix whitespace issue * bpo-36520: changes per reviewer request -- remove extraneous backslashes; add whitespace between terminating quotes and line-continuation backslashes; use "bpo-" instead of "issue #" in comments --- Lib/email/_header_value_parser.py | 1 + Lib/test/test_email/test_message.py | 131 ++++++++++++++++++ .../2019-05-28-02-37-00.bpo-36520.W4tday.rst | 1 + 3 files changed, 133 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 35d746aa50825a..bb5ff8dc7e8034 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -2789,6 +2789,7 @@ def _refold_parse_tree(parse_tree, *, policy): newline = _steal_trailing_WSP_if_exists(lines) if newline or part.startswith_fws(): lines.append(newline + tstr) + last_ew = None continue if not hasattr(part, 'encode'): # It's not a terminal, try folding the subparts. diff --git a/Lib/test/test_email/test_message.py b/Lib/test/test_email/test_message.py index f3a57df9e9cfd0..5dc46e1b812c5d 100644 --- a/Lib/test/test_email/test_message.py +++ b/Lib/test/test_email/test_message.py @@ -784,6 +784,137 @@ def test_str_defaults_to_utf8(self): m['Subject'] = 'unicöde' self.assertEqual(str(m), 'Subject: unicöde\n\n') + def test_folding_with_utf8_encoding_1(self): + # bpo-36520 + # + # Fold a line that contains UTF-8 words before + # and after the whitespace fold point, where the + # line length limit is reached within an ASCII + # word. + + m = EmailMessage() + m['Subject'] = 'Hello Wörld! Hello Wörld! ' \ + 'Hello Wörld! Hello Wörld!Hello Wörld!' + self.assertEqual(bytes(m), + b'Subject: Hello =?utf-8?q?W=C3=B6rld!_Hello_W' + b'=C3=B6rld!_Hello_W=C3=B6rld!?=\n' + b' Hello =?utf-8?q?W=C3=B6rld!Hello_W=C3=B6rld!?=\n\n') + + + def test_folding_with_utf8_encoding_2(self): + # bpo-36520 + # + # Fold a line that contains UTF-8 words before + # and after the whitespace fold point, where the + # line length limit is reached at the end of an + # encoded word. + + m = EmailMessage() + m['Subject'] = 'Hello Wörld! Hello Wörld! ' \ + 'Hello Wörlds123! Hello Wörld!Hello Wörld!' + self.assertEqual(bytes(m), + b'Subject: Hello =?utf-8?q?W=C3=B6rld!_Hello_W' + b'=C3=B6rld!_Hello_W=C3=B6rlds123!?=\n' + b' Hello =?utf-8?q?W=C3=B6rld!Hello_W=C3=B6rld!?=\n\n') + + def test_folding_with_utf8_encoding_3(self): + # bpo-36520 + # + # Fold a line that contains UTF-8 words before + # and after the whitespace fold point, where the + # line length limit is reached at the end of the + # first word. + + m = EmailMessage() + m['Subject'] = 'Hello-Wörld!-Hello-Wörld!-Hello-Wörlds123! ' \ + 'Hello Wörld!Hello Wörld!' + self.assertEqual(bytes(m), \ + b'Subject: =?utf-8?q?Hello-W=C3=B6rld!-Hello-W' + b'=C3=B6rld!-Hello-W=C3=B6rlds123!?=\n' + b' Hello =?utf-8?q?W=C3=B6rld!Hello_W=C3=B6rld!?=\n\n') + + def test_folding_with_utf8_encoding_4(self): + # bpo-36520 + # + # Fold a line that contains UTF-8 words before + # and after the fold point, where the first + # word is UTF-8 and the fold point is within + # the word. + + m = EmailMessage() + m['Subject'] = 'Hello-Wörld!-Hello-Wörld!-Hello-Wörlds123!-Hello' \ + ' Wörld!Hello Wörld!' + self.assertEqual(bytes(m), + b'Subject: =?utf-8?q?Hello-W=C3=B6rld!-Hello-W' + b'=C3=B6rld!-Hello-W=C3=B6rlds123!?=\n' + b' =?utf-8?q?-Hello_W=C3=B6rld!Hello_W=C3=B6rld!?=\n\n') + + def test_folding_with_utf8_encoding_5(self): + # bpo-36520 + # + # Fold a line that contains a UTF-8 word after + # the fold point. + + m = EmailMessage() + m['Subject'] = '123456789 123456789 123456789 123456789 123456789' \ + ' 123456789 123456789 Hello Wörld!' + self.assertEqual(bytes(m), + b'Subject: 123456789 123456789 123456789 123456789' + b' 123456789 123456789 123456789\n' + b' Hello =?utf-8?q?W=C3=B6rld!?=\n\n') + + def test_folding_with_utf8_encoding_6(self): + # bpo-36520 + # + # Fold a line that contains a UTF-8 word before + # the fold point and ASCII words after + + m = EmailMessage() + m['Subject'] = '123456789 123456789 123456789 123456789 Hello Wörld!' \ + ' 123456789 123456789 123456789 123456789 123456789' \ + ' 123456789' + self.assertEqual(bytes(m), + b'Subject: 123456789 123456789 123456789 123456789' + b' Hello =?utf-8?q?W=C3=B6rld!?=\n 123456789 ' + b'123456789 123456789 123456789 123456789 ' + b'123456789\n\n') + + def test_folding_with_utf8_encoding_7(self): + # bpo-36520 + # + # Fold a line twice that contains UTF-8 words before + # and after the first fold point, and ASCII words + # after the second fold point. + + m = EmailMessage() + m['Subject'] = '123456789 123456789 Hello Wörld! Hello Wörld! ' \ + '123456789-123456789 123456789 Hello Wörld! 123456789' \ + ' 123456789' + self.assertEqual(bytes(m), + b'Subject: 123456789 123456789 Hello =?utf-8?q?' + b'W=C3=B6rld!_Hello_W=C3=B6rld!?=\n' + b' 123456789-123456789 123456789 Hello ' + b'=?utf-8?q?W=C3=B6rld!?= 123456789\n 123456789\n\n') + + def test_folding_with_utf8_encoding_8(self): + # bpo-36520 + # + # Fold a line twice that contains UTF-8 words before + # the first fold point, and ASCII words after the + # first fold point, and UTF-8 words after the second + # fold point. + + m = EmailMessage() + m['Subject'] = '123456789 123456789 Hello Wörld! Hello Wörld! ' \ + '123456789 123456789 123456789 123456789 123456789 ' \ + '123456789-123456789 123456789 Hello Wörld! 123456789' \ + ' 123456789' + self.assertEqual(bytes(m), + b'Subject: 123456789 123456789 Hello ' + b'=?utf-8?q?W=C3=B6rld!_Hello_W=C3=B6rld!?=\n 123456789 ' + b'123456789 123456789 123456789 123456789 ' + b'123456789-123456789\n 123456789 Hello ' + b'=?utf-8?q?W=C3=B6rld!?= 123456789 123456789\n\n') class TestMIMEPart(TestEmailMessageBase, TestEmailBase): # Doing the full test run here may seem a bit redundant, since the two diff --git a/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst b/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst new file mode 100644 index 00000000000000..8171bfe9e2df12 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-28-02-37-00.bpo-36520.W4tday.rst @@ -0,0 +1 @@ +Lengthy email headers with UTF-8 characters are now properly encoded when they are folded. Patch by Jeffrey Kintscher. From dc2476500d91082f0c907772c83a044bf49af279 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Thu, 6 Jun 2019 14:39:23 -0600 Subject: [PATCH 345/441] bpo-37170: Fix the cast on error in PyLong_AsUnsignedLongLongMask() (GH-13860) --- Doc/c-api/long.rst | 6 +++-- .../2019-06-06-08-47-04.bpo-37170.hO_fpM.rst | 1 + Modules/_testcapimodule.c | 22 +++++++++++++++++++ Objects/longobject.c | 4 ++-- 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 6be29f9cd32eaa..fdaefafe21ba09 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -288,7 +288,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. If the value of *obj* is out of range for an :c:type:`unsigned long`, return the reduction of that value modulo ``ULONG_MAX + 1``. - Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. + Returns ``(unsigned long)-1`` on error. Use :c:func:`PyErr_Occurred` to + disambiguate. .. versionchanged:: 3.8 Use :meth:`__index__` if available. @@ -307,7 +308,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. If the value of *obj* is out of range for an :c:type:`unsigned long long`, return the reduction of that value modulo ``PY_ULLONG_MAX + 1``. - Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. + Returns ``(unsigned long long)-1`` on error. Use :c:func:`PyErr_Occurred` + to disambiguate. .. versionchanged:: 3.8 Use :meth:`__index__` if available. diff --git a/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst b/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst new file mode 100644 index 00000000000000..7a35c9583d6912 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst @@ -0,0 +1 @@ +Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index f059b4df11b734..c1ae237f2e6cce 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -825,6 +825,26 @@ test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) return Py_None; } +static PyObject * +test_long_as_unsigned_long_long_mask(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL); + + if (res != (unsigned long long)-1 || !PyErr_Occurred()) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) didn't " + "complain"); + } + if (!PyErr_ExceptionMatches(PyExc_SystemError)) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) raised " + "something other than SystemError"); + } + PyErr_Clear(); + Py_RETURN_NONE; +} + /* Test the PyLong_AsDouble API. At present this just tests that non-integer arguments are handled correctly. */ @@ -5070,6 +5090,8 @@ static PyMethodDef TestMethods[] = { {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, {"test_long_as_double", test_long_as_double, METH_NOARGS}, {"test_long_as_size_t", test_long_as_size_t, METH_NOARGS}, + {"test_long_as_unsigned_long_long_mask", + test_long_as_unsigned_long_long_mask, METH_NOARGS}, {"test_long_numbits", test_long_numbits, METH_NOARGS}, {"test_k_code", test_k_code, METH_NOARGS}, {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, diff --git a/Objects/longobject.c b/Objects/longobject.c index a1103f697c7379..50ea2a4e54a4e4 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1376,7 +1376,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); - return (unsigned long) -1; + return (unsigned long long) -1; } v = (PyLongObject *)vv; switch(Py_SIZE(v)) { @@ -1404,7 +1404,7 @@ PyLong_AsUnsignedLongLongMask(PyObject *op) if (op == NULL) { PyErr_BadInternalCall(); - return (unsigned long)-1; + return (unsigned long long)-1; } if (PyLong_Check(op)) { From de76c07a8cd0216c3dce215e4d542e2f45aa022f Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 7 Jun 2019 00:38:41 +0100 Subject: [PATCH 346/441] bpo-37134: Add PEP570 notation to the signature of byte{array}.translate (GH-13874) --- Doc/library/stdtypes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index fcb0da74e158b0..35a17a18080996 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2736,8 +2736,8 @@ arbitrary binary data. The prefix(es) to search for may be any :term:`bytes-like object`. -.. method:: bytes.translate(table, delete=b'') - bytearray.translate(table, delete=b'') +.. method:: bytes.translate(table, /, delete=b'') + bytearray.translate(table, /, delete=b'') Return a copy of the bytes or bytearray object where all bytes occurring in the optional argument *delete* are removed, and the remaining bytes have From 554450fb4e95066e825bdb4a2d544a490daeebdc Mon Sep 17 00:00:00 2001 From: Tal Einat Date: Fri, 7 Jun 2019 08:54:40 +0300 Subject: [PATCH 347/441] bpo-37177: make IDLE's search dialogs transient (GH-13869) This avoids the search dialogs being hidden behind the editor window. --- Lib/idlelib/idle_test/test_searchbase.py | 11 ++++++----- Lib/idlelib/searchbase.py | 2 ++ .../IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst diff --git a/Lib/idlelib/idle_test/test_searchbase.py b/Lib/idlelib/idle_test/test_searchbase.py index 6dd4d79337371d..e08268fde25799 100644 --- a/Lib/idlelib/idle_test/test_searchbase.py +++ b/Lib/idlelib/idle_test/test_searchbase.py @@ -4,7 +4,7 @@ import unittest from test.support import requires -from tkinter import Tk +from tkinter import Text, Tk, Toplevel from tkinter.ttk import Frame from idlelib import searchengine as se from idlelib import searchbase as sdb @@ -47,14 +47,15 @@ def test_open_and_close(self): # open calls create_widgets, which needs default_command self.dialog.default_command = None - # Since text parameter of .open is not used in base class, - # pass dummy 'text' instead of tk.Text(). - self.dialog.open('text') + toplevel = Toplevel(self.root) + self.addCleanup(toplevel.destroy) + text = Text(toplevel) + self.dialog.open(text) self.assertEqual(self.dialog.top.state(), 'normal') self.dialog.close() self.assertEqual(self.dialog.top.state(), 'withdrawn') - self.dialog.open('text', searchphrase="hello") + self.dialog.open(text, searchphrase="hello") self.assertEqual(self.dialog.ent.get(), 'hello') self.dialog.close() diff --git a/Lib/idlelib/searchbase.py b/Lib/idlelib/searchbase.py index 4ed94f186b048d..6fba0b8e583f2b 100644 --- a/Lib/idlelib/searchbase.py +++ b/Lib/idlelib/searchbase.py @@ -54,6 +54,7 @@ def open(self, text, searchphrase=None): else: self.top.deiconify() self.top.tkraise() + self.top.transient(text.winfo_toplevel()) if searchphrase: self.ent.delete(0,"end") self.ent.insert("end",searchphrase) @@ -66,6 +67,7 @@ def close(self, event=None): "Put dialog away for later use." if self.top: self.top.grab_release() + self.top.transient('') self.top.withdraw() def create_widgets(self): diff --git a/Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst b/Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst new file mode 100644 index 00000000000000..74e48eef89a621 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-06-07-00-17-41.bpo-37177.voU6pQ.rst @@ -0,0 +1,2 @@ +Properly 'attach' search dialogs to their main window so that they behave +like other dialogs and do not get hidden behind their main window. From 0690c79c419b8d2bdfe7c5b6dca57b018f5a5a54 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Fri, 7 Jun 2019 01:13:26 -0700 Subject: [PATCH 348/441] bpo-37188: Fix a divide-by-zero in arrays of size-0 objects (#13881) --- Lib/ctypes/test/test_arrays.py | 15 +++++++++++++++ Modules/_ctypes/_ctypes.c | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py index 87ecbf04e7edbb..a3e6d76940e0a1 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/ctypes/test/test_arrays.py @@ -208,6 +208,21 @@ class T(Array): _type_ = c_int _length_ = 0 + def test_empty_element_struct(self): + class EmptyStruct(Structure): + _fields_ = [] + + obj = (EmptyStruct * 2)() # bpo37188: Floating point exception + assert sizeof(obj) == 0 + + def test_empty_element_array(self): + class EmptyArray(Array): + _type_ = c_int + _length_ = 0 + + obj = (EmptyArray * 2)() # bpo37188: Floating point exception + assert sizeof(obj) == 0 + def test_bpo36504_signed_int_overflow(self): # The overflow check in PyCArrayType_new() could cause signed integer # overflow. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index f7513a3d74c4bc..2201c4520ad048 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1518,7 +1518,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } itemsize = itemdict->size; - if (length > PY_SSIZE_T_MAX / itemsize) { + if (itemsize != 0 && length > PY_SSIZE_T_MAX / itemsize) { PyErr_SetString(PyExc_OverflowError, "array too large"); goto error; From 7f8a38a7c47823c17adab469fcb4f762f4e945b7 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Fri, 7 Jun 2019 05:08:20 -0400 Subject: [PATCH 349/441] IDLE: Standardize naming convention for DummyEditwin in tests (GH-13876) * Change from Dummy_Editwin to DummyEditwin to match other tests. --- Lib/idlelib/idle_test/test_autoexpand.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/idle_test/test_autoexpand.py b/Lib/idlelib/idle_test/test_autoexpand.py index e5f44c46871325..e734a8be714a2a 100644 --- a/Lib/idlelib/idle_test/test_autoexpand.py +++ b/Lib/idlelib/idle_test/test_autoexpand.py @@ -6,7 +6,7 @@ from tkinter import Text, Tk -class Dummy_Editwin: +class DummyEditwin: # AutoExpand.__init__ only needs .text def __init__(self, text): self.text = text @@ -18,7 +18,7 @@ def setUpClass(cls): requires('gui') cls.tk = Tk() cls.text = Text(cls.tk) - cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text)) + cls.auto_expand = AutoExpand(DummyEditwin(cls.text)) cls.auto_expand.bell = lambda: None # If mock_tk.Text._decode understood indexes 'insert' with suffixed 'linestart', From 307d4cb957b9d34fdbbb40730f738c61c2e49be9 Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Fri, 7 Jun 2019 11:18:34 +0200 Subject: [PATCH 350/441] Use assertEqual(). (#13883) --- Lib/ctypes/test/test_arrays.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py index a3e6d76940e0a1..14603b7049c92c 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/ctypes/test/test_arrays.py @@ -213,7 +213,7 @@ class EmptyStruct(Structure): _fields_ = [] obj = (EmptyStruct * 2)() # bpo37188: Floating point exception - assert sizeof(obj) == 0 + self.assertEqual(sizeof(obj), 0) def test_empty_element_array(self): class EmptyArray(Array): @@ -221,7 +221,7 @@ class EmptyArray(Array): _length_ = 0 obj = (EmptyArray * 2)() # bpo37188: Floating point exception - assert sizeof(obj) == 0 + self.assertEqual(sizeof(obj), 0) def test_bpo36504_signed_int_overflow(self): # The overflow check in PyCArrayType_new() could cause signed integer From 3f345c39255dc3823dd989d4e3c93b12d18c44e0 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 7 Jun 2019 12:20:24 +0200 Subject: [PATCH 351/441] bpo-37151: simplify classmethoddescr_call (GH-13340) --- Lib/test/test_descr.py | 4 ++-- Objects/descrobject.c | 44 +++++++++++++++--------------------------- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 6b018ccc56fa1d..301a2d2a0fd29c 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1613,8 +1613,8 @@ class SubSpam(spam.spamlist): pass spam_cm(spam.spamlist()) self.assertEqual( str(cm.exception), - "descriptor 'classmeth' requires a type " - "but received a 'xxsubtype.spamlist' instance") + "descriptor 'classmeth' for type 'xxsubtype.spamlist' " + "needs a type, not a 'xxsubtype.spamlist' as arg 2") with self.assertRaises(TypeError) as cm: spam_cm(list) diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 6c95a8726c4202..806c0af97e24b6 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -300,16 +300,19 @@ _PyMethodDescr_Vectorcall(PyObject *descrobj, return result; } +/* Instances of classmethod_descriptor are unlikely to be called directly. + For one, the analogous class "classmethod" (for Python classes) is not + callable. Second, users are not likely to access a classmethod_descriptor + directly, since it means pulling it from the class __dict__. + + This is just an excuse to say that this doesn't need to be optimized: + we implement this simply by calling __get__ and then calling the result. +*/ static PyObject * classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) { - Py_ssize_t argc; - PyObject *self, *result; - - /* Make sure that the first argument is acceptable as 'self' */ - assert(PyTuple_Check(args)); - argc = PyTuple_GET_SIZE(args); + Py_ssize_t argc = PyTuple_GET_SIZE(args); if (argc < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%V' of '%.100s' " @@ -318,30 +321,15 @@ classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyDescr_TYPE(descr)->tp_name); return NULL; } - self = PyTuple_GET_ITEM(args, 0); - if (!PyType_Check(self)) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' requires a type " - "but received a '%.100s' instance", - descr_name((PyDescrObject *)descr), "?", - self->ob_type->tp_name); - return NULL; - } - if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { - PyErr_Format(PyExc_TypeError, - "descriptor '%V' requires a subtype of '%.100s' " - "but received '%.100s'", - descr_name((PyDescrObject *)descr), "?", - PyDescr_TYPE(descr)->tp_name, - ((PyTypeObject*)self)->tp_name); + PyObject *self = PyTuple_GET_ITEM(args, 0); + PyObject *bound = classmethod_get(descr, NULL, self); + if (bound == NULL) { return NULL; } - - result = _PyMethodDef_RawFastCallDict(descr->d_method, self, - &_PyTuple_ITEMS(args)[1], argc - 1, - kwds); - result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); - return result; + PyObject *res = _PyObject_FastCallDict(bound, _PyTuple_ITEMS(args)+1, + argc-1, kwds); + Py_DECREF(bound); + return res; } Py_LOCAL_INLINE(PyObject *) From 3bf0f3ad2046ac674d8e8a2c074a5a8b3327797d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 7 Jun 2019 16:22:21 +0200 Subject: [PATCH 352/441] bpo-37169: Rewrite _PyObject_IsFreed() unit tests (GH-13888) Replace two Python function calls with a single one to ensure that no memory allocation is done between the invalid object is created and when _PyObject_IsFreed() is called. --- Lib/test/test_capi.py | 29 ++++++++++--------- .../2019-06-07-12-23-15.bpo-37169.yfXTFg.rst | 1 + Modules/_testcapimodule.c | 27 ++++++++--------- 3 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 43d7a08da944a9..6a20f479c53fb0 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -705,28 +705,29 @@ def test_pyobject_malloc_without_gil(self): code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' self.check_malloc_without_gil(code) - def check_pyobject_is_freed(self, func): - code = textwrap.dedent(''' + def check_pyobject_is_freed(self, func_name): + code = textwrap.dedent(f''' import gc, os, sys, _testcapi # Disable the GC to avoid crash on GC collection gc.disable() - obj = _testcapi.{func}() - error = (_testcapi.pyobject_is_freed(obj) == False) - # Exit immediately to avoid a crash while deallocating - # the invalid object - os._exit(int(error)) + try: + _testcapi.{func_name}() + # Exit immediately to avoid a crash while deallocating + # the invalid object + os._exit(0) + except _testcapi.error: + os._exit(1) ''') - code = code.format(func=func) assert_python_ok('-c', code, PYTHONMALLOC=self.PYTHONMALLOC) - def test_pyobject_is_freed_uninitialized(self): - self.check_pyobject_is_freed('pyobject_uninitialized') + def test_pyobject_uninitialized_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed') - def test_pyobject_is_freed_forbidden_bytes(self): - self.check_pyobject_is_freed('pyobject_forbidden_bytes') + def test_pyobject_forbidden_bytes_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed') - def test_pyobject_is_freed_free(self): - self.check_pyobject_is_freed('pyobject_freed') + def test_pyobject_freed_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_freed_is_freed') class PyMemMallocDebugTests(PyMemDebugTests): diff --git a/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst b/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst new file mode 100644 index 00000000000000..f2f0a8b8d8ea25 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-06-07-12-23-15.bpo-37169.yfXTFg.rst @@ -0,0 +1 @@ +Rewrite ``_PyObject_IsFreed()`` unit tests. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c1ae237f2e6cce..07aadea3e98395 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4489,15 +4489,17 @@ test_pymem_getallocatorsname(PyObject *self, PyObject *args) static PyObject* -pyobject_is_freed(PyObject *self, PyObject *op) +test_pyobject_is_freed(const char *test_name, PyObject *op) { - int res = _PyObject_IsFreed(op); - return PyBool_FromLong(res); + if (!_PyObject_IsFreed(op)) { + return raiseTestError(test_name, "object is not seen as freed"); + } + Py_RETURN_NONE; } static PyObject* -pyobject_uninitialized(PyObject *self, PyObject *args) +check_pyobject_uninitialized_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) { PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); if (op == NULL) { @@ -4506,12 +4508,12 @@ pyobject_uninitialized(PyObject *self, PyObject *args) /* Initialize reference count to avoid early crash in ceval or GC */ Py_REFCNT(op) = 1; /* object fields like ob_type are uninitialized! */ - return op; + return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); } static PyObject* -pyobject_forbidden_bytes(PyObject *self, PyObject *args) +check_pyobject_forbidden_bytes_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) { /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); @@ -4522,12 +4524,12 @@ pyobject_forbidden_bytes(PyObject *self, PyObject *args) Py_REFCNT(op) = 1; /* ob_type field is after the memory block: part of "forbidden bytes" when using debug hooks on memory allocatrs! */ - return op; + return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); } static PyObject* -pyobject_freed(PyObject *self, PyObject *args) +check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) { PyObject *op = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); if (op == NULL) { @@ -4537,7 +4539,7 @@ pyobject_freed(PyObject *self, PyObject *args) /* Reset reference count to avoid early crash in ceval or GC */ Py_REFCNT(op) = 1; /* object memory is freed! */ - return op; + return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); } @@ -5264,10 +5266,9 @@ static PyMethodDef TestMethods[] = { {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, - {"pyobject_is_freed", (PyCFunction)(void(*)(void))pyobject_is_freed, METH_O}, - {"pyobject_uninitialized", pyobject_uninitialized, METH_NOARGS}, - {"pyobject_forbidden_bytes", pyobject_forbidden_bytes, METH_NOARGS}, - {"pyobject_freed", pyobject_freed, METH_NOARGS}, + {"check_pyobject_uninitialized_is_freed", check_pyobject_uninitialized_is_freed, METH_NOARGS}, + {"check_pyobject_forbidden_bytes_is_freed", check_pyobject_forbidden_bytes_is_freed, METH_NOARGS}, + {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS}, {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, From 740a84de73ad8d02655de0a084036f4b7e49a01b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 7 Jun 2019 17:51:28 +0200 Subject: [PATCH 353/441] bpo-37191: Move TestPEP590 from test_capi to test_call (GH-13892) --- Lib/test/test_call.py | 123 ++++++++++++++++++++++++++++++++++++++++++ Lib/test/test_capi.py | 115 --------------------------------------- 2 files changed, 123 insertions(+), 115 deletions(-) diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 9f0a75b84a03c3..b4ab74903edbc2 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -475,5 +475,128 @@ def __index__(self): # called, which changes the keywords dict. compile("pass", "", "exec", x, **x.kwargs) + +Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11 +Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17 + + +def testfunction(self): + """some doc""" + return self + + +def testfunction_kw(self, *, kw): + """some doc""" + return self + + +class TestPEP590(unittest.TestCase): + + def test_method_descriptor_flag(self): + import functools + cached = functools.lru_cache(1)(testfunction) + + self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + + self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + + # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + pass + self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + + def test_vectorcall_flag(self): + self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + + # Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + pass + self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + + def test_vectorcall_override(self): + # Check that tp_call can correctly override vectorcall. + # MethodDescriptorNopGet implements tp_call but it inherits from + # MethodDescriptorBase, which implements vectorcall. Since + # MethodDescriptorNopGet returns the args tuple when called, we check + # additionally that no new tuple is created for this call. + args = tuple(range(5)) + f = _testcapi.MethodDescriptorNopGet() + self.assertIs(f(*args), args) + + def test_vectorcall(self): + # Test a bunch of different ways to call objects: + # 1. vectorcall using PyVectorcall_Call() + # (only for objects that support vectorcall directly) + # 2. normal call + # 3. vectorcall using _PyObject_Vectorcall() + # 4. call as bound method + # 5. call using functools.partial + + # A list of (function, args, kwargs, result) calls to test + calls = [(len, (range(42),), {}, 42), + (list.append, ([], 0), {}, None), + ([].append, (0,), {}, None), + (sum, ([36],), {"start":6}, 42), + (testfunction, (42,), {}, 42), + (testfunction_kw, (42,), {"kw":None}, 42), + (_testcapi.MethodDescriptorBase(), (0,), {}, True), + (_testcapi.MethodDescriptorDerived(), (0,), {}, True), + (_testcapi.MethodDescriptor2(), (0,), {}, False)] + + from _testcapi import pyobject_vectorcall, pyvectorcall_call + from types import MethodType + from functools import partial + + def vectorcall(func, args, kwargs): + args = *args, *kwargs.values() + kwnames = tuple(kwargs) + return pyobject_vectorcall(func, args, kwnames) + + for (func, args, kwargs, expected) in calls: + with self.subTest(str(func)): + if not kwargs: + self.assertEqual(expected, pyvectorcall_call(func, args)) + self.assertEqual(expected, pyvectorcall_call(func, args, kwargs)) + + # Add derived classes (which do not support vectorcall directly, + # but do support all other ways of calling). + + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + pass + + class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase): + def __call__(self, n): + return 'new' + + calls += [ + (MethodDescriptorHeap(), (0,), {}, True), + (MethodDescriptorOverridden(), (0,), {}, 'new'), + ] + + for (func, args, kwargs, expected) in calls: + with self.subTest(str(func)): + args1 = args[1:] + meth = MethodType(func, args[0]) + wrapped = partial(func) + if not kwargs: + self.assertEqual(expected, func(*args)) + self.assertEqual(expected, pyobject_vectorcall(func, args, None)) + self.assertEqual(expected, meth(*args1)) + self.assertEqual(expected, wrapped(*args)) + self.assertEqual(expected, func(*args, **kwargs)) + self.assertEqual(expected, vectorcall(func, args, kwargs)) + self.assertEqual(expected, meth(*args1, **kwargs)) + self.assertEqual(expected, wrapped(*args, **kwargs)) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 6a20f479c53fb0..45fabd599159e9 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -27,18 +27,11 @@ # Were we compiled --with-pydebug or with #define Py_DEBUG? Py_DEBUG = hasattr(sys, 'gettotalrefcount') -Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11 -Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17 - def testfunction(self): """some doc""" return self -def testfunction_kw(self, *, kw): - """some doc""" - return self - class InstanceMethod: id = _testcapi.instancemethod(id) @@ -471,114 +464,6 @@ def test_pendingcalls_non_threaded(self): self.pendingcalls_wait(l, n) -class TestPEP590(unittest.TestCase): - - def test_method_descriptor_flag(self): - import functools - cached = functools.lru_cache(1)(testfunction) - - self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - - self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - - # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR - class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): - pass - self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) - - def test_vectorcall_flag(self): - self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - - # Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL - class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): - pass - self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - - def test_vectorcall_override(self): - # Check that tp_call can correctly override vectorcall. - # MethodDescriptorNopGet implements tp_call but it inherits from - # MethodDescriptorBase, which implements vectorcall. Since - # MethodDescriptorNopGet returns the args tuple when called, we check - # additionally that no new tuple is created for this call. - args = tuple(range(5)) - f = _testcapi.MethodDescriptorNopGet() - self.assertIs(f(*args), args) - - def test_vectorcall(self): - # Test a bunch of different ways to call objects: - # 1. vectorcall using PyVectorcall_Call() - # (only for objects that support vectorcall directly) - # 2. normal call - # 3. vectorcall using _PyObject_Vectorcall() - # 4. call as bound method - # 5. call using functools.partial - - # A list of (function, args, kwargs, result) calls to test - calls = [(len, (range(42),), {}, 42), - (list.append, ([], 0), {}, None), - ([].append, (0,), {}, None), - (sum, ([36],), {"start":6}, 42), - (testfunction, (42,), {}, 42), - (testfunction_kw, (42,), {"kw":None}, 42), - (_testcapi.MethodDescriptorBase(), (0,), {}, True), - (_testcapi.MethodDescriptorDerived(), (0,), {}, True), - (_testcapi.MethodDescriptor2(), (0,), {}, False)] - - from _testcapi import pyobject_vectorcall, pyvectorcall_call - from types import MethodType - from functools import partial - - def vectorcall(func, args, kwargs): - args = *args, *kwargs.values() - kwnames = tuple(kwargs) - return pyobject_vectorcall(func, args, kwnames) - - for (func, args, kwargs, expected) in calls: - with self.subTest(str(func)): - if not kwargs: - self.assertEqual(expected, pyvectorcall_call(func, args)) - self.assertEqual(expected, pyvectorcall_call(func, args, kwargs)) - - # Add derived classes (which do not support vectorcall directly, - # but do support all other ways of calling). - - class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): - pass - - class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase): - def __call__(self, n): - return 'new' - - calls += [ - (MethodDescriptorHeap(), (0,), {}, True), - (MethodDescriptorOverridden(), (0,), {}, 'new'), - ] - - for (func, args, kwargs, expected) in calls: - with self.subTest(str(func)): - args1 = args[1:] - meth = MethodType(func, args[0]) - wrapped = partial(func) - if not kwargs: - self.assertEqual(expected, func(*args)) - self.assertEqual(expected, pyobject_vectorcall(func, args, None)) - self.assertEqual(expected, meth(*args1)) - self.assertEqual(expected, wrapped(*args)) - self.assertEqual(expected, func(*args, **kwargs)) - self.assertEqual(expected, vectorcall(func, args, kwargs)) - self.assertEqual(expected, meth(*args1, **kwargs)) - self.assertEqual(expected, wrapped(*args, **kwargs)) - - class SubinterpreterTest(unittest.TestCase): def test_subinterps(self): From e7e5039d6940e41839dcef0433262ff363408dad Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Fri, 7 Jun 2019 10:58:41 -0700 Subject: [PATCH 354/441] bpo-37181: Fix test_regrtest failures on Windows arm64 (GH-13872) --- Lib/test/test_regrtest.py | 8 ++++++-- PCbuild/rt.bat | 1 + Tools/buildbot/test.bat | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 9155522c273d88..b616e8974b9d2c 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -616,7 +616,9 @@ def test_tools_buildbot_test(self): # Tools\buildbot\test.bat script = os.path.join(ROOT_DIR, 'Tools', 'buildbot', 'test.bat') test_args = ['--testdir=%s' % self.tmptestdir] - if platform.architecture()[0] == '64bit': + if platform.machine() == 'ARM64': + test_args.append('-arm64') # ARM 64-bit build + elif platform.architecture()[0] == '64bit': test_args.append('-x64') # 64-bit build if not Py_DEBUG: test_args.append('+d') # Release build, use python.exe @@ -629,7 +631,9 @@ def test_pcbuild_rt(self): if not os.path.isfile(script): self.skipTest(f'File "{script}" does not exist') rt_args = ["-q"] # Quick, don't run tests twice - if platform.architecture()[0] == '64bit': + if platform.machine() == 'ARM64': + rt_args.append('-arm64') # ARM 64-bit build + elif platform.architecture()[0] == '64bit': rt_args.append('-x64') # 64-bit build if Py_DEBUG: rt_args.append('-d') # Debug build, use python_d.exe diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index e603de6d5174f8..59f757c0f5888a 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -39,6 +39,7 @@ if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts if "%1"=="-x64" (set prefix=%pcbuild%amd64) & shift & goto CheckOpts +if "%1"=="-arm64" (set prefix=%pcbuild%arm64) & shift & goto CheckOpts if "%1"=="-arm32" (set prefix=%pcbuild%arm32) & shift & goto CheckOpts if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index f430680f3d80cf..1566f46c534f75 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -9,6 +9,7 @@ set arm32_ssh= :CheckOpts if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-arm64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-arm32" (set rt_opts=%rt_opts% %1) & (set arm32_ssh=true) & shift & goto CheckOpts if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts @@ -17,7 +18,6 @@ if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts -echo on if "%arm32_ssh%"=="true" goto :Arm32Ssh call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% From 1f9531764cc0f8dbca1d8f429d162dc28282f4b4 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 7 Jun 2019 20:01:53 +0200 Subject: [PATCH 355/441] bpo-37138: fix undefined behaviour with memcpy() on NULL array (GH-13867) --- Objects/classobject.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Objects/classobject.c b/Objects/classobject.c index ffd3f875c0e7ba..2415ed14cb1506 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -71,7 +71,11 @@ method_vectorcall(PyObject *method, PyObject *const *args, } /* use borrowed references */ newargs[0] = self; - memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); + if (totalargs) { /* bpo-37138: if totalargs == 0, then args may be + * NULL and calling memcpy() with a NULL pointer + * is undefined behaviour. */ + memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); + } result = _PyObject_Vectorcall(func, newargs, nargs+1, kwnames); PyMem_Free(newargs); } From 03d5831a2d62c68654ec223168e574cd546efbf6 Mon Sep 17 00:00:00 2001 From: zygocephalus Date: Fri, 7 Jun 2019 23:08:36 +0300 Subject: [PATCH 356/441] bpo-37150: Throw ValueError if FileType class object was passed in add_argument (GH-13805) There is a possibility that someone (like me) accidentally will omit parentheses with `FileType` arguments after `FileType`, and parser will contain wrong file until someone will try to use it. Example: ```python parser = argparse.ArgumentParser() parser.add_argument('-x', type=argparse.FileType) ``` https://bugs.python.org/issue37150 --- Lib/argparse.py | 4 ++++ Lib/test/test_argparse.py | 18 ++++++++++++++++++ .../2019-06-04-14-44-41.bpo-37150.TTzHxj.rst | 1 + 3 files changed, 23 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index ef888f063b3286..9a67b41ae00ead 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1361,6 +1361,10 @@ def add_argument(self, *args, **kwargs): if not callable(type_func): raise ValueError('%r is not callable' % (type_func,)) + if type_func is FileType: + raise ValueError('%r is a FileType class object, instance of it' + ' must be passed' % (type_func,)) + # raise an error if the metavar does not match the type if hasattr(self, "_get_formatter"): try: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 9d68f40571fe6f..bcf2cc9b26a319 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1619,6 +1619,24 @@ def test_open_args(self): m.assert_called_with('foo', *args) +class TestFileTypeMissingInitialization(TestCase): + """ + Test that add_argument throws an error if FileType class + object was passed instead of instance of FileType + """ + + def test(self): + parser = argparse.ArgumentParser() + with self.assertRaises(ValueError) as cm: + parser.add_argument('-x', type=argparse.FileType) + + self.assertEqual( + '%r is a FileType class object, instance of it must be passed' + % (argparse.FileType,), + str(cm.exception) + ) + + class TestTypeCallable(ParserTestCase): """Test some callables as option/argument types""" diff --git a/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst b/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst new file mode 100644 index 00000000000000..c5be46e1e5d3f4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-04-14-44-41.bpo-37150.TTzHxj.rst @@ -0,0 +1 @@ +`argparse._ActionsContainer.add_argument` now throws error, if someone accidentally pass FileType class object instead of instance of FileType as `type` argument \ No newline at end of file From 65e5860fcc8ffe66f3c325d5484112f3b6540e8c Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Fri, 7 Jun 2019 14:23:39 -0700 Subject: [PATCH 357/441] cross port importlib-metadata PR #76 (#13903) https://gitlab.com/python-devs/importlib_metadata/merge_requests/76 --- Lib/importlib/metadata/__init__.py | 2 ++ .../data/example-21.12-py3-none-any.whl | Bin 1453 -> 1455 bytes .../data/example-21.12-py3.6.egg | Bin 1492 -> 1497 bytes Lib/test/test_importlib/test_zip.py | 2 ++ 4 files changed, 4 insertions(+) diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index a1abdd64815bff..944dbb5fdf7e86 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -89,6 +89,8 @@ def _from_config(cls, config): @classmethod def _from_text(cls, text): config = ConfigParser() + # case sensitive: https://stackoverflow.com/q/1611799/812183 + config.optionxform = str try: config.read_string(text) except AttributeError: # pragma: nocover diff --git a/Lib/test/test_importlib/data/example-21.12-py3-none-any.whl b/Lib/test/test_importlib/data/example-21.12-py3-none-any.whl index f92f7716e3e613a2a9703be785135fd8b35cfb1c..641ab07f7aadd5c3ffe199b1e397b84504444994 100644 GIT binary patch delta 652 zcmZ3>y`Gydz?+#xgn@y9gQ2SWxZgxRKbAQ_dh!OwtsEc*-_4_HlVushn6DXMoLt6e z#tRah;;VX48>q)|Vy2^d(OQo)x+gqCH-vh$Zdg+!Z2Wmg&_?cJMh1k*AUzY$cnX4O zn_o&7^cWc!E&{RK#9Zn6AXjJqAeYiJJByke7#J?x%V&HtLD`i{K*Z%>!HNrS))aAV zIuu$$6tI^s6T?yO8*3a9e zdGD^HRoJQ9#{y)to7Sy-zeXc<+qa&ruV0F6{lOaG&B!FejEFcX&4U$+z$gJ>VIYQq zC6hlgt3aZZmsNs!Nn_CDy^P9}y;*r=VbL1{R13ngFg-we$>iHCdI~6U4HVTtR?)bK yablj<5-dv^g_$PiNljkLA_>-v64^+aw=gDv)lFm-V>`tRk^lez?DZ)C delta 732 zcmZ3_y_TCVz?+#xgn@y9gCTc`j_*W1KcTNnb$tKFUAe3V6x9M^4Ti}VShOa;U=&jF zTI+E}_k?HYhR}vhYl?)8KkwMVfG_~0ak3(lCkKde$oyXPWLd^A<}1cmCYLdqv48|8 zCTs;8@6T)+ZOF*La2<%{K*mee2e~@?2f5Uq-Cfk=z~FH4p5*_OgCCA5vF0#sbI*(bG-m?4>+SK$z)0TVdi`|)DrvG*q z7oSuWU%K)_oKU;brbG4zFRl5sSVo2S!H%Cie}hC$U*Pe69_qh>tKPi3S5R}8kY>I9 zb+2uUEdU%8_~S2RTDlQQ4TIEOn|4=%p_OYoED+$YZj^wjk?9-LI$ujI2!Gj}%Em5r_qW7zUO!YEBklRgeeT>?fsputE_i0m8yC1weX9WAtQyRwb}GAXm)=iai5j VkXK<~N#okd6IkuoCW9WRD?m_gKmsUT`{1fw-CkoNl@cjdAgP>t5)1&l_D zUTZzh=$`Nl-4NQaX-$!^@#h^o7*I@^{DaXNtlx}DpZRC@>d6^Q{v054ZnE_3nY^FL zn#IU?kKE*cObfxP7BSm^>4(hrU|N~Q1I^Y77Atv>{<|rhL0n+BGBAh%X&6}2_-yh; z7FDqBpDfahDw9Q7736_7`$=gYtWX3h17Ts9av;5=F>G=Os}jOhb*y4cE0`vqWYQH2 U@MdKLDdhk{111KBK4uUP08S8I@&Et; diff --git a/Lib/test/test_importlib/test_zip.py b/Lib/test/test_importlib/test_zip.py index db39e190ea7ac9..bcf7cf3618d748 100644 --- a/Lib/test/test_importlib/test_zip.py +++ b/Lib/test/test_importlib/test_zip.py @@ -26,6 +26,8 @@ def test_zip_entry_points(self): scripts = dict(entry_points()['console_scripts']) entry_point = scripts['example'] self.assertEqual(entry_point.value, 'example:main') + entry_point = scripts['Example'] + self.assertEqual(entry_point.value, 'example:main') def test_missing_metadata(self): self.assertIsNone(distribution('example').read_text('does not exist')) From d407d2a7265f6102e51a1d62b3fd28b4f7a78d16 Mon Sep 17 00:00:00 2001 From: Philipp A Date: Sat, 8 Jun 2019 14:05:46 +0200 Subject: [PATCH 358/441] bpo-37173: Show passed class in inspect.getfile error (GH-13861) Currently, inspect.getfile(str) will report nonsense: ```pytb >>> inspect.getfile(str) TypeError: is a built-in class ``` This fixes that https://bugs.python.org/issue37173 --- Lib/inspect.py | 6 +++--- Lib/test/test_inspect.py | 18 ++++++++++++++++++ .../2019-06-08-11-33-48.bpo-37173.0e_8gS.rst | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-08-11-33-48.bpo-37173.0e_8gS.rst diff --git a/Lib/inspect.py b/Lib/inspect.py index 91d209dc64bc9f..99a580bd2f2350 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -659,9 +659,9 @@ def getfile(object): raise TypeError('{!r} is a built-in module'.format(object)) if isclass(object): if hasattr(object, '__module__'): - object = sys.modules.get(object.__module__) - if getattr(object, '__file__', None): - return object.__file__ + module = sys.modules.get(object.__module__) + if getattr(module, '__file__', None): + return module.__file__ raise TypeError('{!r} is a built-in class'.format(object)) if ismethod(object): object = object.__func__ diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 83a5f7ec1f5385..1cd4ea28939d8a 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -513,6 +513,24 @@ def test_getsourcefile(self): def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) + def test_getfile_builtin_module(self): + with self.assertRaises(TypeError) as e: + inspect.getfile(sys) + self.assertTrue(str(e.exception).startswith(' Date: Sat, 8 Jun 2019 07:43:16 -0700 Subject: [PATCH 359/441] bpo-29505: Fix interpreter in fuzzing targets to be relocatable (GH-13907) --- Modules/_xxtestfuzz/fuzzer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index b50eb651271043..54f816ebc93dae 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -88,6 +88,14 @@ static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* /* CPython generates a lot of leak warnings for whatever reason. */ int __lsan_is_turned_off(void) { return 1; } +wchar_t wide_program_name[NAME_MAX]; + +int LLVMFuzzerInitialize(int *argc, char ***argv) { + wchar_t* wide_program_name = Py_DecodeLocale(*argv[0], NULL); + Py_SetProgramName(wide_program_name); + return 0; +} + /* Fuzz test interface. This returns the bitwise or of all fuzz test's return values. From 8cc605acdda5aff250ab4c9b524a7560f90ca9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Sat, 8 Jun 2019 16:56:24 +0200 Subject: [PATCH 360/441] bpo-34886: Fix subprocess.run handling of exclusive arguments (GH-11727) Fix an unintended ValueError from :func:`subprocess.run` when checking for conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` args when they were explicitly provided but with `None` values within a passed in `**kwargs` dict rather than as passed directly by name. --- Lib/subprocess.py | 4 ++-- .../next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 9e36b9de6b349c..d34c57828b48ec 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -459,12 +459,12 @@ def run(*popenargs, The other arguments are the same as for the Popen constructor. """ if input is not None: - if 'stdin' in kwargs: + if kwargs.get('stdin') is not None: raise ValueError('stdin and input arguments may not both be used.') kwargs['stdin'] = PIPE if capture_output: - if ('stdout' in kwargs) or ('stderr' in kwargs): + if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None: raise ValueError('stdout and stderr arguments may not be used ' 'with capture_output.') kwargs['stdout'] = PIPE diff --git a/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst b/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst new file mode 100644 index 00000000000000..1b5fc37025212d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-08-16-03-19.bpo-34886.Ov-pc9.rst @@ -0,0 +1,5 @@ +Fix an unintended ValueError from :func:`subprocess.run` when checking for +conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` +args when they were explicitly provided but with `None` values within a +passed in `**kwargs` dict rather than as passed directly by name. Patch +contributed by Rémi Lapeyre. From e119b3d136bd94d880bce4b382096f6de3f38062 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 8 Jun 2019 08:58:11 -0700 Subject: [PATCH 361/441] bpo-37178: Allow a one argument form of math.perm() (GH-13905) --- Doc/library/math.rst | 5 ++++- Lib/test/test_math.py | 9 +++++++-- .../2019-06-07-17-11-34.bpo-37178.b1StSv.rst | 2 ++ .../2019-06-07-17-16-09.bpo-37178.Day_oB.rst | 2 ++ Modules/clinic/mathmodule.c.h | 15 +++++++++++---- Modules/mathmodule.c | 10 ++++++++-- 6 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst create mode 100644 Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 28ed5d21f03adb..ff937d27c6ce79 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -210,7 +210,7 @@ Number-theoretic and representation functions of *x* and are floats. -.. function:: perm(n, k) +.. function:: perm(n, k=None) Return the number of ways to choose *k* items from *n* items without repetition and with order. @@ -218,6 +218,9 @@ Number-theoretic and representation functions Evaluates to ``n! / (n - k)!`` when ``k <= n`` and evaluates to zero when ``k > n``. + If *k* is not specified or is None, then *k* defaults to *n* + and the function returns ``n!``. + Raises :exc:`TypeError` if either of the arguments are not integers. Raises :exc:`ValueError` if either of the arguments are negative. diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 86e3923af6d074..adefa07a404114 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1885,8 +1885,13 @@ def testPerm(self): self.assertEqual(perm(n, 1), n) self.assertEqual(perm(n, n), factorial(n)) + # Test one argument form + for n in range(20): + self.assertEqual(perm(n), factorial(n)) + self.assertEqual(perm(n, None), factorial(n)) + # Raises TypeError if any argument is non-integer or argument count is - # not 2 + # not 1 or 2 self.assertRaises(TypeError, perm, 10, 1.0) self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0)) self.assertRaises(TypeError, perm, 10, "1") @@ -1894,7 +1899,7 @@ def testPerm(self): self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1) self.assertRaises(TypeError, perm, "10", 1) - self.assertRaises(TypeError, perm, 10) + self.assertRaises(TypeError, perm) self.assertRaises(TypeError, perm, 10, 1, 3) self.assertRaises(TypeError, perm) diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst b/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst new file mode 100644 index 00000000000000..77b872319a9191 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-07-17-11-34.bpo-37178.b1StSv.rst @@ -0,0 +1,2 @@ +For math.perm(n, k), let k default to n, giving the same result as +factorial. diff --git a/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst b/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst new file mode 100644 index 00000000000000..500ef54fd61509 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-07-17-16-09.bpo-37178.Day_oB.rst @@ -0,0 +1,2 @@ +Give math.perm() a one argument form that means the same as +math.factorial(). diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index cdf4305641b7d9..966b99b6a36900 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -639,7 +639,7 @@ math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k } PyDoc_STRVAR(math_perm__doc__, -"perm($module, n, k, /)\n" +"perm($module, n, k=None, /)\n" "--\n" "\n" "Number of ways to choose k items from n items without repetition and with order.\n" @@ -647,6 +647,9 @@ PyDoc_STRVAR(math_perm__doc__, "Evaluates to n! / (n - k)! when k <= n and evaluates\n" "to zero when k > n.\n" "\n" +"If k is not specified or is None, then k defaults to n\n" +"and the function returns n!.\n" +"\n" "Raises TypeError if either of the arguments are not integers.\n" "Raises ValueError if either of the arguments are negative."); @@ -661,13 +664,17 @@ math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; PyObject *n; - PyObject *k; + PyObject *k = Py_None; - if (!_PyArg_CheckPositional("perm", nargs, 2, 2)) { + if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) { goto exit; } n = args[0]; + if (nargs < 2) { + goto skip_optional; + } k = args[1]; +skip_optional: return_value = math_perm_impl(module, n, k); exit: @@ -713,4 +720,4 @@ math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=5004266613284dcc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0eb1e76a769cdd30 input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 9a9a8159ced407..ed114767530805 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -3002,7 +3002,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) math.perm n: object - k: object + k: object = None / Number of ways to choose k items from n items without repetition and with order. @@ -3010,18 +3010,24 @@ Number of ways to choose k items from n items without repetition and with order. Evaluates to n! / (n - k)! when k <= n and evaluates to zero when k > n. +If k is not specified or is None, then k defaults to n +and the function returns n!. + Raises TypeError if either of the arguments are not integers. Raises ValueError if either of the arguments are negative. [clinic start generated code]*/ static PyObject * math_perm_impl(PyObject *module, PyObject *n, PyObject *k) -/*[clinic end generated code: output=e021a25469653e23 input=b2e7729d9a1949cf]*/ +/*[clinic end generated code: output=e021a25469653e23 input=5311c5a00f359b53]*/ { PyObject *result = NULL, *factor = NULL; int overflow, cmp; long long i, factors; + if (k == Py_None) { + return math_factorial(module, n); + } n = PyNumber_Index(n); if (n == NULL) { return NULL; From 45a14942c969ed508b35abd5e116cb18f84ce5b4 Mon Sep 17 00:00:00 2001 From: Marcin Niemira Date: Sun, 9 Jun 2019 07:05:06 +1000 Subject: [PATCH 362/441] bpo-11122: fix hardcoded path checking for rpmbuild in bdist_rpm.py (GH-10594) --- Lib/distutils/command/bdist_rpm.py | 5 +---- .../next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py index 20ca7ac6dcffaa..74381cc69a6ced 100644 --- a/Lib/distutils/command/bdist_rpm.py +++ b/Lib/distutils/command/bdist_rpm.py @@ -309,10 +309,7 @@ def run(self): # build package log.info("building RPMs") - rpm_cmd = ['rpm'] - if os.path.exists('/usr/bin/rpmbuild') or \ - os.path.exists('/bin/rpmbuild'): - rpm_cmd = ['rpmbuild'] + rpm_cmd = ['rpmbuild'] if self.source_only: # what kind of RPMs? rpm_cmd.append('-bs') diff --git a/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst b/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst new file mode 100644 index 00000000000000..483906613801cd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-11-12-19-08-50.bpo-11122.Gj7BQn.rst @@ -0,0 +1 @@ +Distutils won't check for rpmbuild in specified paths only. From b9438ceb20635b00f10615c5b6d8dbe56e1d486b Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 9 Jun 2019 19:07:42 +1000 Subject: [PATCH 363/441] Add some placeholder notes for major 3.8 features (GH-13927) --- Doc/whatsnew/3.8.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index bf75387d9517f3..99bb793830bc37 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -52,6 +52,13 @@ For full details, see the :ref:`changelog `. form. It will be updated substantially as Python 3.8 moves towards release, so it's worth checking back even after reading earlier versions. + Some notable items not yet covered here: + + * :pep:`574` - Pickle protocol 5 with out-of-band data buffer support + * :pep:`578` - Runtime audit hooks for potentially sensitive operations + * ``python -m asyncio`` runs a natively async REPL + * ... + Summary -- Release highlights ============================= From c879ff247ae1b67a790ff98d2d59145302cd4e4e Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 9 Jun 2019 14:47:15 +0200 Subject: [PATCH 364/441] bpo-36785: PEP 574 What's New entry (#13931) --- Doc/whatsnew/3.8.rst | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 99bb793830bc37..e2f9ce8dd6e580 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -54,7 +54,6 @@ For full details, see the :ref:`changelog `. Some notable items not yet covered here: - * :pep:`574` - Pickle protocol 5 with out-of-band data buffer support * :pep:`578` - Runtime audit hooks for potentially sensitive operations * ``python -m asyncio`` runs a natively async REPL * ... @@ -261,6 +260,23 @@ See :pep:`590` for a full description. (Contributed by Jeroen Demeyer and Mark Shannon in :issue:`36974`.) +Pickle protocol 5 with out-of-band data buffers +----------------------------------------------- + +When :mod:`pickle` is used to transfer large data between Python processes +in order to take advantage of multi-core or multi-machine processing, +it is important to optimize the transfer by reducing memory copies, and +possibly by applying custom techniques such as data-dependent compression. + +The :mod:`pickle` protocol 5 introduces support for out-of-band buffers +where :pep:`3118`-compatible data can be transmitted separately from the +main pickle stream, at the discretion of the communication layer. + +See :pep:`574` for a full description. + +(Contributed by Antoine Pitrou in :issue:`36785`.) + + Other Language Changes ====================== From e042a4553efd0ceca2234f68a4f1878f2ca04973 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 10 Jun 2019 13:35:52 +0300 Subject: [PATCH 365/441] Do not use explicit inheritance from object in the documentation. (GH-13936) --- Doc/howto/descriptor.rst | 24 ++++++++++++------------ Doc/library/copyreg.rst | 2 +- Doc/library/functools.rst | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index b29e590b20cba8..324625d7b3e809 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -145,7 +145,7 @@ print a message for each get or set. Overriding :meth:`__getattribute__` is alternate approach that could do this for every attribute. However, this descriptor is useful for monitoring just a few chosen attributes:: - class RevealAccess(object): + class RevealAccess: """A data descriptor that sets and returns values normally and prints a message logging their access. """ @@ -162,7 +162,7 @@ descriptor is useful for monitoring just a few chosen attributes:: print('Updating', self.name) self.val = val - >>> class MyClass(object): + >>> class MyClass: ... x = RevealAccess(10, 'var "x"') ... y = 5 ... @@ -194,7 +194,7 @@ triggers function calls upon access to an attribute. Its signature is:: The documentation shows a typical use to define a managed attribute ``x``:: - class C(object): + class C: def getx(self): return self.__x def setx(self, value): self.__x = value def delx(self): del self.__x @@ -203,7 +203,7 @@ The documentation shows a typical use to define a managed attribute ``x``:: To see how :func:`property` is implemented in terms of the descriptor protocol, here is a pure Python equivalent:: - class Property(object): + class Property: "Emulate PyProperty_Type() in Objects/descrobject.c" def __init__(self, fget=None, fset=None, fdel=None, doc=None): @@ -250,7 +250,7 @@ to be recalculated on every access; however, the programmer does not want to affect existing client code accessing the attribute directly. The solution is to wrap access to the value attribute in a property data descriptor:: - class Cell(object): + class Cell: . . . def getvalue(self): "Recalculate the cell before returning value" @@ -277,7 +277,7 @@ binding methods during attribute access. This means that all functions are non-data descriptors which return bound methods when they are invoked from an object. In pure Python, it works like this:: - class Function(object): + class Function: . . . def __get__(self, obj, objtype=None): "Simulate func_descr_get() in Objects/funcobject.c" @@ -287,7 +287,7 @@ object. In pure Python, it works like this:: Running the interpreter shows how the function descriptor works in practice:: - >>> class D(object): + >>> class D: ... def f(self, x): ... return x ... @@ -367,7 +367,7 @@ It can be called either from an object or the class: ``s.erf(1.5) --> .9332`` o Since staticmethods return the underlying function with no changes, the example calls are unexciting:: - >>> class E(object): + >>> class E: ... def f(x): ... print(x) ... f = staticmethod(f) @@ -380,7 +380,7 @@ calls are unexciting:: Using the non-data descriptor protocol, a pure Python version of :func:`staticmethod` would look like this:: - class StaticMethod(object): + class StaticMethod: "Emulate PyStaticMethod_Type() in Objects/funcobject.c" def __init__(self, f): @@ -393,7 +393,7 @@ Unlike static methods, class methods prepend the class reference to the argument list before calling the function. This format is the same for whether the caller is an object or a class:: - >>> class E(object): + >>> class E: ... def f(klass, x): ... return klass.__name__, x ... f = classmethod(f) @@ -410,7 +410,7 @@ is to create alternate class constructors. In Python 2.3, the classmethod :func:`dict.fromkeys` creates a new dictionary from a list of keys. The pure Python equivalent is:: - class Dict(object): + class Dict: . . . def fromkeys(klass, iterable, value=None): "Emulate dict_fromkeys() in Objects/dictobject.c" @@ -428,7 +428,7 @@ Now a new dictionary of unique keys can be constructed like this:: Using the non-data descriptor protocol, a pure Python version of :func:`classmethod` would look like this:: - class ClassMethod(object): + class ClassMethod: "Emulate PyClassMethod_Type() in Objects/funcobject.c" def __init__(self, f): diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst index 40fca56d8029e9..43920210095951 100644 --- a/Doc/library/copyreg.rst +++ b/Doc/library/copyreg.rst @@ -49,7 +49,7 @@ The example below would like to show how to register a pickle function and how it will be used: >>> import copyreg, copy, pickle - >>> class C(object): + >>> class C: ... def __init__(self, a): ... self.a = a ... diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 3a0b554e923c7a..d3debac8432b19 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -275,7 +275,7 @@ The :mod:`functools` module defines the following functions: Example:: - >>> class Cell(object): + >>> class Cell: ... def __init__(self): ... self._alive = False ... @property From 8a8b59c9794674b50b2242698c29038034f4864c Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Mon, 10 Jun 2019 17:19:48 +0200 Subject: [PATCH 366/441] bpo-37215: Fix dtrace issue introduce by bpo-36842 (GH-13940) Signed-off-by: Christian Heimes https://bugs.python.org/issue37215 --- Makefile.pre.in | 10 +++++----- .../C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst diff --git a/Makefile.pre.in b/Makefile.pre.in index a0bc9c1f1cc897..2b4e2d776ea9cd 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -438,7 +438,7 @@ LIBRARY_OBJS= \ # On some systems, object files that reference DTrace probes need to be modified # in-place by dtrace(1). DTRACE_DEPS = \ - Python/ceval.o Python/import.o Modules/gcmodule.o + Python/ceval.o Python/import.o Python/sysmodule.o Modules/gcmodule.o ######################################################################### # Rules @@ -780,7 +780,7 @@ Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile -DSHLIB_EXT='"$(EXT_SUFFIX)"' \ -o $@ $(srcdir)/Python/dynload_hpux.c -Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile +Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h $(CC) -c $(PY_CORE_CFLAGS) \ -DABIFLAGS='"$(ABIFLAGS)"' \ $(MULTIARCH_CPPFLAGS) \ @@ -938,9 +938,9 @@ Include/pydtrace_probes.h: $(srcdir)/Include/pydtrace.d sed 's/PYTHON_/PyDTrace_/' $@ > $@.tmp mv $@.tmp $@ -Python/ceval.o: Include/pydtrace.h -Python/import.o: Include/pydtrace.h -Modules/gcmodule.o: Include/pydtrace.h +Python/ceval.o: $(srcdir)/Include/pydtrace.h +Python/import.o: $(srcdir)/Include/pydtrace.h +Modules/gcmodule.o: $(srcdir)/Include/pydtrace.h Python/pydtrace.o: $(srcdir)/Include/pydtrace.d $(DTRACE_DEPS) $(DTRACE) $(DFLAGS) -o $@ -G -s $< $(DTRACE_DEPS) diff --git a/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst b/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst new file mode 100644 index 00000000000000..58038b21729b0f --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-06-10-15-32-34.bpo-37215.yzoNyU.rst @@ -0,0 +1 @@ +Fix dtrace issue introduce by bpo-36842 From 4f6f7c5a611905fb6b81671547f268c226bc646a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 11 Jun 2019 02:49:06 +0200 Subject: [PATCH 367/441] bpo-18748: Fix _pyio.IOBase destructor (closed case) (GH-13952) _pyio.IOBase destructor now does nothing if getting the closed attribute fails to better mimick _io.IOBase finalizer. --- Lib/_pyio.py | 10 ++++++++++ .../Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 43c24342ad6162..0b6493bc8dc926 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -405,6 +405,16 @@ def close(self): def __del__(self): """Destructor. Calls close().""" + try: + closed = self.closed + except Exception: + # If getting closed fails, then the object is probably + # in an unusable state, so ignore. + return + + if closed: + return + if _IOBASE_EMITS_UNRAISABLE: self.close() else: diff --git a/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst b/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst new file mode 100644 index 00000000000000..295ddebb2a4015 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-11-01-54-19.bpo-18748.ADqCkq.rst @@ -0,0 +1,2 @@ +:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` +attribute fails to better mimick :class:`_io.IOBase` finalizer. From b589cef9c4dada2fb84ce0fae5040ecf16d9d5ef Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 11 Jun 2019 03:10:59 +0200 Subject: [PATCH 368/441] bpo-37223: test_io: silence destructor errors (GH-13954) Implement also MockNonBlockWriterIO.seek() method. --- Lib/test/test_io.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 3a1f5ba5b6663d..102679b1d34243 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -277,6 +277,10 @@ def readable(self): def seekable(self): return True + def seek(self, pos, whence=0): + # naive implementation, enough for tests + return 0 + def writable(self): return True @@ -1486,6 +1490,9 @@ def test_misbehaved_io(self): self.assertRaises(OSError, bufio.seek, 0) self.assertRaises(OSError, bufio.tell) + # Silence destructor error + bufio.close = lambda: None + def test_no_extraneous_read(self): # Issue #9550; when the raw IO object has satisfied the read request, # we should not issue any additional reads, otherwise it may block @@ -1834,6 +1841,9 @@ def test_misbehaved_io(self): self.assertRaises(OSError, bufio.tell) self.assertRaises(OSError, bufio.write, b"abcdef") + # Silence destructor error + bufio.close = lambda: None + def test_max_buffer_size_removal(self): with self.assertRaises(TypeError): self.tp(self.MockRawIO(), 8, 12) From 408a2ef1aceff1f4270c44552fa39ef93d9283e3 Mon Sep 17 00:00:00 2001 From: aaronpaulhurst Date: Mon, 10 Jun 2019 18:54:24 -0700 Subject: [PATCH 369/441] closes bpo-35184: Fix XML_POOR_ENTROPY option that breaks makesetup parsing of pyexpat line in Setup. (GH-13064) When the line is uncommented, the equals character causes it to be incorrectly interpreted as a macro definition by makesetup. This results in invalid Makefile output. The expat code only requires XML_POOR_ENTROPY to be defined; the value is unnecessary. --- Modules/Setup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Setup b/Modules/Setup index e729ab883f410b..ed5ee6c5033b5b 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -338,7 +338,7 @@ _symtable symtablemodule.c # Interface to the Expat XML parser # More information on Expat can be found at www.libexpat.org. # -#pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DXML_POOR_ENTROPY=1 -DUSE_PYEXPAT_CAPI +#pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DXML_POOR_ENTROPY -DUSE_PYEXPAT_CAPI # Hye-Shik Chang's CJKCodecs From 1f11cf9521114447b3e32e2ac88f075ffaa37555 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 11 Jun 2019 01:15:24 -0700 Subject: [PATCH 370/441] bpo-37219: Remove erroneous optimization for differencing an empty set (GH-13965) --- Lib/test/test_set.py | 6 ++++++ .../2019-06-10-23-18-31.bpo-37219.jPSufq.rst | 1 + Objects/setobject.c | 8 -------- 3 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq.rst diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index bb1081f034fe80..e4766ab190be01 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -895,6 +895,12 @@ def test_pickling(self): self.assertEqual(self.set, copy, "%s != %s" % (self.set, copy)) + def test_issue_37219(self): + with self.assertRaises(TypeError): + set().difference(123) + with self.assertRaises(TypeError): + set().difference_update(123) + #------------------------------------------------------------------------------ class TestBasicOpsEmpty(TestBasicOps, unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq.rst new file mode 100644 index 00000000000000..ef8f52dce6784f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-10-23-18-31.bpo-37219.jPSufq.rst @@ -0,0 +1 @@ +Remove errorneous optimization for empty set differences. diff --git a/Objects/setobject.c b/Objects/setobject.c index bd031600c1be66..8cd95ba890dd5f 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1456,10 +1456,6 @@ PyDoc_STRVAR(isdisjoint_doc, static int set_difference_update_internal(PySetObject *so, PyObject *other) { - if (PySet_GET_SIZE(so) == 0) { - return 0; - } - if ((PyObject *)so == other) return set_clear_internal(so); @@ -1534,10 +1530,6 @@ set_difference(PySetObject *so, PyObject *other) Py_ssize_t pos = 0, other_size; int rv; - if (PySet_GET_SIZE(so) == 0) { - return set_copy(so, NULL); - } - if (PyAnySet_Check(other)) { other_size = PySet_GET_SIZE(other); } From 65aa64fae89a24491aae84ba0329eb8f3c68c389 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Tue, 11 Jun 2019 18:27:30 +0300 Subject: [PATCH 371/441] bpo-36607: Eliminate RuntimeError raised by asyncio.all_tasks() (GH-13971) If internal tasks weak set is changed by another thread during iteration. https://bugs.python.org/issue36607 --- Lib/asyncio/tasks.py | 38 ++++++++++++++++--- .../2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst | 2 + 2 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 95e85600a2e802..cd4832cfee246b 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -42,9 +42,22 @@ def all_tasks(loop=None): """Return a set of all tasks for the loop.""" if loop is None: loop = events.get_running_loop() - # NB: set(_all_tasks) is required to protect - # from https://bugs.python.org/issue34970 bug - return {t for t in list(_all_tasks) + # Looping over a WeakSet (_all_tasks) isn't safe as it can be updated from another + # thread while we do so. Therefore we cast it to list prior to filtering. The list + # cast itself requires iteration, so we repeat it several times ignoring + # RuntimeErrors (which are not very likely to occur). See issues 34970 and 36607 for + # details. + i = 0 + while True: + try: + tasks = list(_all_tasks) + except RuntimeError: + i += 1 + if i >= 1000: + raise + else: + break + return {t for t in tasks if futures._get_loop(t) is loop and not t.done()} @@ -54,9 +67,22 @@ def _all_tasks_compat(loop=None): # method. if loop is None: loop = events.get_event_loop() - # NB: set(_all_tasks) is required to protect - # from https://bugs.python.org/issue34970 bug - return {t for t in list(_all_tasks) if futures._get_loop(t) is loop} + # Looping over a WeakSet (_all_tasks) isn't safe as it can be updated from another + # thread while we do so. Therefore we cast it to list prior to filtering. The list + # cast itself requires iteration, so we repeat it several times ignoring + # RuntimeErrors (which are not very likely to occur). See issues 34970 and 36607 for + # details. + i = 0 + while True: + try: + tasks = list(_all_tasks) + except RuntimeError: + i += 1 + if i >= 1000: + raise + else: + break + return {t for t in tasks if futures._get_loop(t) is loop} def _set_task_name(task, name): diff --git a/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst b/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst new file mode 100644 index 00000000000000..337c8e2668c49e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-11-13-52-04.bpo-36607.5_mJkQ.rst @@ -0,0 +1,2 @@ +Eliminate :exc:`RuntimeError` raised by :func:`asyncio.all_tasks()` if +internal tasks weak set is changed by another thread during iteration. From 910b3fcb01c29f18ffd53086e36cd2cb9e5fae55 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 11 Jun 2019 09:18:31 -0700 Subject: [PATCH 372/441] closes bpo-33758: Skip test_get_type_hints_modules_forwardref. (GH-13977) This test "works" if things are run in the right order, so it's better to use @skip than @expectedFailure here. --- Lib/test/test_typing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index a65d639fe9e112..ba001c3462fcf5 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3,7 +3,7 @@ import pickle import re import sys -from unittest import TestCase, main, skipUnless, SkipTest, expectedFailure +from unittest import TestCase, main, skipUnless, SkipTest, skip from copy import copy, deepcopy from typing import Any, NoReturn @@ -2654,7 +2654,7 @@ def test_get_type_hints_modules(self): self.assertEqual(gth(ann_module2), {}) self.assertEqual(gth(ann_module3), {}) - @expectedFailure + @skip("known bug") def test_get_type_hints_modules_forwardref(self): # FIXME: This currently exposes a bug in typing. Cached forward references # don't account for the case where there are multiple types of the same From 44867bb9376e324493f0149ac8b3c33f23c9050d Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 11 Jun 2019 10:15:31 -0700 Subject: [PATCH 373/441] Fix test_posix if RWF_HIPRI is defined but not preadv2. (GH-13980) If preadv2 is not available, preadv will raise NotImplementedError. --- Lib/test/test_posix.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 5c93d0d507d252..0f07a8f2e68db8 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -310,6 +310,8 @@ def test_preadv_flags(self): buf = [bytearray(i) for i in [5, 3, 2]] self.assertEqual(posix.preadv(fd, buf, 3, os.RWF_HIPRI), 10) self.assertEqual([b't1tt2', b't3t', b'5t'], list(buf)) + except NotImplementedError: + self.skipTest("preadv2 not available") except OSError as inst: # Is possible that the macro RWF_HIPRI was defined at compilation time # but the option is not supported by the kernel or the runtime libc shared From 9b33ce48a7846dbdad32d4f8936b08e6b78a2faf Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 11 Jun 2019 13:42:35 -0700 Subject: [PATCH 374/441] bpo-35766: What's new in the ast and typing modules (#13984) --- Doc/whatsnew/3.8.rst | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index e2f9ce8dd6e580..eb276139192df9 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -363,6 +363,29 @@ Improved Modules ================ +ast +--- + +AST nodes now have ``end_lineno`` and ``end_col_offset`` attributes, +which give the precise location of the end of the node. (This only +applies to nodes that have ``lineno`` and ``col_offset`` attributes.) + +The :func:`ast.parse` function has some new flags: + +* ``type_comments=True`` causes it to return the text of :pep:`484` and + :pep:`526` type comments associated with certain AST nodes; + +* ``mode='func_type'`` can be used to parse :pep:`484` "signature type + comments" (returned for function definition AST nodes); + +* ``feature_version=N`` allows specifying the minor version of an + earlier Python 3 version. (For example, ``feature_version=4`` will + treat ``async`` and ``await`` as non-reserved words.) + +New function :func:`ast.get_source_segment` returns the source code +for a specific AST node. + + asyncio ------- @@ -762,6 +785,29 @@ time Added new clock :data:`~time.CLOCK_UPTIME_RAW` for macOS 10.12. (Contributed by Joannah Nanjekye in :issue:`35702`.) + +typing +------ + +The :mod:`typing` module incorporates several new features: + +* Protocol definitions. See :pep:`544`, :class:`typing.Protocol` and + :func:`typing.runtime_checkable`. Simple ABCs like + :class:`typing.SupportsInt` are now ``Protocol`` subclasses. + +* A dictionary type with per-key types. See :pep:`589` and + :class:`typing.TypedDict`. + +* Literal types. See :pep:`586` and :class:`typing.Literal`. + +* "Final" variables, functions, methods and classes. See :pep:`591`, + :class:`typing.Final` and :func:`typing.final`. + +* New protocol class :class:`typing.SupportsIndex`. + +* New functions :func:`typing.get_origin` and :func:`typing.get_args`. + + unicodedata ----------- From 04856c2193eb72d72c46b57fa08095235d732a73 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Tue, 11 Jun 2019 15:03:17 -0700 Subject: [PATCH 375/441] bpo-37238: Enable building for Windows using Visual Studio 2019 (GH-13988) --- PCbuild/python.props | 1 + PCbuild/pythoncore.vcxproj | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/PCbuild/python.props b/PCbuild/python.props index 11638fe348c863..e6642fc4818a0a 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -10,6 +10,7 @@ We set BasePlatformToolset for ICC's benefit, it's otherwise ignored. --> + v142 v141 v140 v120 diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 89625da944e1ab..09a63c04eab82c 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -511,7 +511,7 @@ - + From 10b55c1643b512b3a2cae8ab89c53683a13ca43e Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 11 Jun 2019 17:23:12 -0700 Subject: [PATCH 376/441] bpo-35766: Change format for feature_version to (major, minor) (GH-13992) (A single int is still allowed, but undocumented.) https://bugs.python.org/issue35766 --- Doc/library/ast.rst | 13 +++++++------ Doc/whatsnew/3.8.rst | 6 +++--- Lib/ast.py | 9 ++++++++- .../2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst | 1 + 4 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 1884bea80e8047..1e718382589c48 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -126,7 +126,7 @@ The abstract grammar is currently defined as follows: Apart from the node classes, the :mod:`ast` module defines these utility functions and classes for traversing abstract syntax trees: -.. function:: parse(source, filename='', mode='exec', *, type_comments=False, feature_version=-1) +.. function:: parse(source, filename='', mode='exec', *, type_comments=False, feature_version=None) Parse the source into an AST node. Equivalent to ``compile(source, filename, mode, ast.PyCF_ONLY_AST)``. @@ -145,11 +145,12 @@ and classes for traversing abstract syntax trees: modified to correspond to :pep:`484` "signature type comments", e.g. ``(str, int) -> List[str]``. - Also, setting ``feature_version`` to the minor version of an - earlier Python 3 version will attempt to parse using that version's - grammar. For example, setting ``feature_version=4`` will allow - the use of ``async`` and ``await`` as variable names. The lowest - supported value is 4; the highest is ``sys.version_info[1]``. + Also, setting ``feature_version`` to a tuple ``(major, minor)`` + will attempt to parse using that Python version's grammar. + Currently ``major`` must equal to ``3``. For example, setting + ``feature_version=(3, 4)`` will allow the use of ``async`` and + ``await`` as variable names. The lowest supported version is + ``(3, 4)``; the highest is ``sys.version_info[0:2]``. .. warning:: It is possible to crash the Python interpreter with a diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index eb276139192df9..264586434b9b08 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -378,9 +378,9 @@ The :func:`ast.parse` function has some new flags: * ``mode='func_type'`` can be used to parse :pep:`484` "signature type comments" (returned for function definition AST nodes); -* ``feature_version=N`` allows specifying the minor version of an - earlier Python 3 version. (For example, ``feature_version=4`` will - treat ``async`` and ``await`` as non-reserved words.) +* ``feature_version=(3, N)`` allows specifying an earlier Python 3 + version. (For example, ``feature_version=(3, 4)`` will treat + ``async`` and ``await`` as non-reserved words.) New function :func:`ast.get_source_segment` returns the source code for a specific AST node. diff --git a/Lib/ast.py b/Lib/ast.py index 64e7a2551fb1aa..70fbbdd2ffbd8a 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -28,7 +28,7 @@ def parse(source, filename='', mode='exec', *, - type_comments=False, feature_version=-1): + type_comments=False, feature_version=None): """ Parse the source into an AST node. Equivalent to compile(source, filename, mode, PyCF_ONLY_AST). @@ -37,6 +37,13 @@ def parse(source, filename='', mode='exec', *, flags = PyCF_ONLY_AST if type_comments: flags |= PyCF_TYPE_COMMENTS + if isinstance(feature_version, tuple): + major, minor = feature_version # Should be a 2-tuple. + assert major == 3 + feature_version = minor + elif feature_version is None: + feature_version = -1 + # Else it should be an int giving the minor version for 3.x. return compile(source, filename, mode, flags, feature_version=feature_version) diff --git a/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst b/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst new file mode 100644 index 00000000000000..6dd49998cb4c2d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-11-16-41-40.bpo-35766.v1Kj-T.rst @@ -0,0 +1 @@ +Change the format of feature_version to be a (major, minor) tuple. From efdf6ca90f7702824e7aeee1ceca949e7c20288a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Jun 2019 02:52:16 +0200 Subject: [PATCH 377/441] bpo-35766: compile(): rename feature_version parameter (GH-13994) Rename compile() feature_version parameter to _feature_version and convert it to a keyword-only parameter. Update also test_type_comments to pass feature_version as a tuple. --- Lib/ast.py | 2 +- Lib/test/test_type_comments.py | 5 +++-- Python/bltinmodule.c | 5 +++-- Python/clinic/bltinmodule.c.h | 14 +++++++++----- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index 70fbbdd2ffbd8a..ffeba179e51019 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -45,7 +45,7 @@ def parse(source, filename='', mode='exec', *, feature_version = -1 # Else it should be an int giving the minor version for 3.x. return compile(source, filename, mode, flags, - feature_version=feature_version) + _feature_version=feature_version) def literal_eval(node_or_string): diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 55b54e7f203edc..43be54efdbd974 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -228,8 +228,9 @@ def parse(self, source, feature_version=highest): feature_version=feature_version) def parse_all(self, source, minver=lowest, maxver=highest, expected_regex=""): - for feature_version in range(self.lowest, self.highest + 1): - if minver <= feature_version <= maxver: + for version in range(self.lowest, self.highest + 1): + feature_version = (3, version) + if minver <= version <= maxver: try: yield self.parse(source, feature_version) except SyntaxError as err: diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 56d882d387eeed..abf807a408f781 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -696,7 +696,8 @@ compile as builtin_compile flags: int = 0 dont_inherit: bool(accept={int}) = False optimize: int = -1 - feature_version: int = -1 + * + _feature_version as feature_version: int = -1 Compile source into a code object that can be executed by exec() or eval(). @@ -716,7 +717,7 @@ static PyObject * builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, const char *mode, int flags, int dont_inherit, int optimize, int feature_version) -/*[clinic end generated code: output=b0c09c84f116d3d7 input=5fcc30651a6acaa9]*/ +/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/ { PyObject *source_copy; const char *str; diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 0ed11bceeb87e2..abed6cc3e174de 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -151,7 +151,7 @@ builtin_chr(PyObject *module, PyObject *arg) PyDoc_STRVAR(builtin_compile__doc__, "compile($module, /, source, filename, mode, flags=0,\n" -" dont_inherit=False, optimize=-1, feature_version=-1)\n" +" dont_inherit=False, optimize=-1, *, _feature_version=-1)\n" "--\n" "\n" "Compile source into a code object that can be executed by exec() or eval().\n" @@ -179,7 +179,7 @@ static PyObject * builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "feature_version", NULL}; + static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; @@ -191,7 +191,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj int optimize = -1; int feature_version = -1; - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 7, 0, argsbuf); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 6, 0, argsbuf); if (!args) { goto exit; } @@ -257,6 +257,10 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } if (PyFloat_Check(args[6])) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float" ); @@ -266,7 +270,7 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (feature_version == -1 && PyErr_Occurred()) { goto exit; } -skip_optional_pos: +skip_optional_kwonly: return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize, feature_version); exit: @@ -845,4 +849,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=3f690311ac556c31 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e173df340a9e4516 input=a9049054013a1b77]*/ From eb976e47e261760330c1bed224019b073b05e994 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Jun 2019 04:07:38 +0200 Subject: [PATCH 378/441] bpo-36918: Fix "Exception ignored in" in test_urllib (GH-13996) Mock the HTTPConnection.close() method in a few unit tests to avoid logging "Exception ignored in: ..." messages. --- Lib/test/test_urllib.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index f9b2799d25bfd0..801f0fd647f4ab 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -56,7 +56,7 @@ def FancyURLopener(): return urllib.request.FancyURLopener() -def fakehttp(fakedata): +def fakehttp(fakedata, mock_close=False): class FakeSocket(io.BytesIO): io_refs = 1 @@ -90,15 +90,24 @@ class FakeHTTPConnection(http.client.HTTPConnection): def connect(self): self.sock = FakeSocket(self.fakedata) type(self).fakesock = self.sock + + if mock_close: + # bpo-36918: HTTPConnection destructor calls close() which calls + # flush(). Problem: flush() calls self.fp.flush() which raises + # "ValueError: I/O operation on closed file" which is logged as an + # "Exception ignored in". Override close() to silence this error. + def close(self): + pass FakeHTTPConnection.fakedata = fakedata return FakeHTTPConnection class FakeHTTPMixin(object): - def fakehttp(self, fakedata): + def fakehttp(self, fakedata, mock_close=False): + fake_http_class = fakehttp(fakedata, mock_close=mock_close) self._connection_class = http.client.HTTPConnection - http.client.HTTPConnection = fakehttp(fakedata) + http.client.HTTPConnection = fake_http_class def unfakehttp(self): http.client.HTTPConnection = self._connection_class @@ -400,7 +409,7 @@ def test_read_bogus(self): Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e Connection: close Content-Type: text/html; charset=iso-8859-1 -''') +''', mock_close=True) try: self.assertRaises(OSError, urlopen, "http://python.org/") finally: @@ -414,7 +423,7 @@ def test_invalid_redirect(self): Location: file://guidocomputer.athome.com:/python/license Connection: close Content-Type: text/html; charset=iso-8859-1 -''') +''', mock_close=True) try: msg = "Redirection to url 'file:" with self.assertRaisesRegex(urllib.error.HTTPError, msg): @@ -429,7 +438,7 @@ def test_redirect_limit_independent(self): self.fakehttp(b'''HTTP/1.1 302 Found Location: file://guidocomputer.athome.com:/python/license Connection: close -''') +''', mock_close=True) try: self.assertRaises(urllib.error.HTTPError, urlopen, "http://something") From 376ce9852eec4e97745c723f0dd0fe64383c6cd3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Jun 2019 04:41:16 +0200 Subject: [PATCH 379/441] bpo-26219: Fix compiler warning in _PyCode_InitOpcache() (GH-13997) Fix MSVC warning: objects\codeobject.c(285): warning C4244: '=': conversion from 'Py_ssize_t' to 'unsigned char', possible loss of data --- Objects/codeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 63ce4793597a13..1333cc833e1e4b 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -282,7 +282,7 @@ _PyCode_InitOpcache(PyCodeObject *co) co->co_opcache = NULL; } - co->co_opcache_size = opts; + co->co_opcache_size = (unsigned char)opts; return 0; } From 405f648db7c44b07348582b5101d4716e0ce5ac3 Mon Sep 17 00:00:00 2001 From: Yao Zuo Date: Tue, 11 Jun 2019 20:46:09 -0700 Subject: [PATCH 380/441] bpo-32625: Updated documentation for EXTENDED_ARG. (GH-13985) Python 3.6 changed the size of bytecode instruction, while the documentation for `EXTENDED_ARG` was not updated accordingly. --- Doc/library/dis.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 2a3ffb5e827119..5b79be626626de 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1219,10 +1219,10 @@ All of the following opcodes use their arguments. .. opcode:: EXTENDED_ARG (ext) - Prefixes any opcode which has an argument too big to fit into the default two - bytes. *ext* holds two additional bytes which, taken together with the - subsequent opcode's argument, comprise a four-byte argument, *ext* being the - two most-significant bytes. + Prefixes any opcode which has an argument too big to fit into the default one + byte. *ext* holds an additional byte which act as higher bits in the argument. + For each opcode, at most three prefixal ``EXTENDED_ARG`` are allowed, forming + an argument from two-byte to four-byte. .. opcode:: FORMAT_VALUE (flags) From a6e190e94b47324f14e22a09200c68b722d55699 Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Tue, 11 Jun 2019 21:30:35 -0700 Subject: [PATCH 381/441] bpo-29505: Fuzz json module, enforce size limit on int(x) fuzz (GH-13991) * bpo-29505: Enable fuzz testing of the json module, enforce size limit on int(x) fuzz and json input size to avoid timeouts. Contributed by by Ammar Askar for Google. --- Modules/_xxtestfuzz/README.rst | 10 ++++ .../dictionaries/fuzz_json_loads.dict | 40 +++++++++++++ .../fuzz_json_loads_corpus/empty_array.json | 1 + .../fuzz_json_loads_corpus/empty_object.json | 1 + .../fuzz_json_loads_corpus/pass1.json | 58 +++++++++++++++++++ .../fuzz_json_loads_corpus/pass2.json | 1 + .../fuzz_json_loads_corpus/pass3.json | 6 ++ .../fuzz_json_loads_corpus/simple_array.json | 1 + Modules/_xxtestfuzz/fuzz_tests.txt | 1 + Modules/_xxtestfuzz/fuzzer.c | 53 ++++++++++++++++- 10 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict create mode 100644 Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json create mode 100644 Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json create mode 100644 Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json create mode 100644 Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json create mode 100644 Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json create mode 100644 Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json diff --git a/Modules/_xxtestfuzz/README.rst b/Modules/_xxtestfuzz/README.rst index b48f3c89a42bb6..42bd02a03cbedd 100644 --- a/Modules/_xxtestfuzz/README.rst +++ b/Modules/_xxtestfuzz/README.rst @@ -35,6 +35,16 @@ And invoke it from ``LLVMFuzzerTestOneInput``:: ``LLVMFuzzerTestOneInput`` will run in oss-fuzz, with each test in ``fuzz_tests.txt`` run separately. +Seed data (corpus) for the test can be provided in a subfolder called +``_corpus`` such as ``fuzz_json_loads_corpus``. A wide variety +of good input samples allows the fuzzer to more easily explore a diverse +set of paths and provides a better base to find buggy input from. + +Dictionaries of tokens (see oss-fuzz documentation for more details) can +be placed in the ``dictionaries`` folder with the name of the test. +For example, ``dictionaries/fuzz_json_loads.dict`` contains JSON tokens +to guide the fuzzer. + What makes a good fuzz test --------------------------- diff --git a/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict b/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict new file mode 100644 index 00000000000000..ad64917ccc2c08 --- /dev/null +++ b/Modules/_xxtestfuzz/dictionaries/fuzz_json_loads.dict @@ -0,0 +1,40 @@ +"0" +",0" +":0" +"0:" +"-1.2e+3" + +"true" +"false" +"null" + +"\"\"" +",\"\"" +":\"\"" +"\"\":" + +"{}" +",{}" +":{}" +"{\"\":0}" +"{{}}" + +"[]" +",[]" +":[]" +"[0]" +"[[]]" + +"''" +"\\" +"\\b" +"\\f" +"\\n" +"\\r" +"\\t" +"\\u0000" +"\\x00" +"\\0" +"\\uD800\\uDC00" +"\\uDBFF\\uDFFF" + diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json new file mode 100644 index 00000000000000..fe51488c7066f6 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_array.json @@ -0,0 +1 @@ +[] diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json new file mode 100644 index 00000000000000..0967ef424bce67 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/empty_object.json @@ -0,0 +1 @@ +{} diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json new file mode 100644 index 00000000000000..70e26854369282 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass1.json @@ -0,0 +1,58 @@ +[ + "JSON Test Pattern pass1", + {"object with 1 member":["array with 1 element"]}, + {}, + [], + -42, + true, + false, + null, + { + "integer": 1234567890, + "real": -9876.543210, + "e": 0.123456789e-12, + "E": 1.234567890E+34, + "": 23456789012E66, + "zero": 0, + "one": 1, + "space": " ", + "quote": "\"", + "backslash": "\\", + "controls": "\b\f\n\r\t", + "slash": "/ & \/", + "alpha": "abcdefghijklmnopqrstuvwyz", + "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", + "digit": "0123456789", + "0123456789": "digit", + "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", + "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", + "true": true, + "false": false, + "null": null, + "array":[ ], + "object":{ }, + "address": "50 St. James Street", + "url": "http://www.JSON.org/", + "comment": "// /* */": " ", + " s p a c e d " :[1,2 , 3 + +, + +4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], + "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", + "quotes": "" \u0022 %22 0x22 034 "", + "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" +: "A key can be any string" + }, + 0.5 ,98.6 +, +99.44 +, + +1066, +1e1, +0.1e1, +1e-1, +1e00,2e+00,2e-00 +,"rosebud"] \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json new file mode 100644 index 00000000000000..d3c63c7ad845e4 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass2.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json new file mode 100644 index 00000000000000..4528d51f1ac615 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/pass3.json @@ -0,0 +1,6 @@ +{ + "JSON Test Pattern pass3": { + "The outermost value": "must be an object or array.", + "In this test": "It is an object." + } +} diff --git a/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json new file mode 100644 index 00000000000000..ce1e6ecaec72f4 --- /dev/null +++ b/Modules/_xxtestfuzz/fuzz_json_loads_corpus/simple_array.json @@ -0,0 +1 @@ +[1, 2, 3, "abcd", "xyz"] diff --git a/Modules/_xxtestfuzz/fuzz_tests.txt b/Modules/_xxtestfuzz/fuzz_tests.txt index 2e53bfdc71619c..f0121291eaa015 100644 --- a/Modules/_xxtestfuzz/fuzz_tests.txt +++ b/Modules/_xxtestfuzz/fuzz_tests.txt @@ -1,3 +1,4 @@ fuzz_builtin_float fuzz_builtin_int fuzz_builtin_unicode +fuzz_json_loads diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 54f816ebc93dae..e862a99cfb34ca 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -28,8 +28,15 @@ static int fuzz_builtin_float(const char* data, size_t size) { return 0; } +#define MAX_INT_TEST_SIZE 0x10000 + /* Fuzz PyLong_FromUnicodeObject as a proxy for int(str). */ static int fuzz_builtin_int(const char* data, size_t size) { + /* Ignore test cases with very long ints to avoid timeouts + int("9" * 1000000) is not a very interesting test caase */ + if (size > MAX_INT_TEST_SIZE) { + return 0; + } /* Pick a random valid base. (When the fuzzed function takes extra parameters, it's somewhat normal to hash the input to generate those parameters. We want to exercise all code paths, so we do so here.) */ @@ -72,6 +79,42 @@ static int fuzz_builtin_unicode(const char* data, size_t size) { return 0; } +#define MAX_JSON_TEST_SIZE 0x10000 + +/* Initialized in LLVMFuzzerTestOneInput */ +PyObject* json_loads_method = NULL; +/* Fuzz json.loads(x) */ +static int fuzz_json_loads(const char* data, size_t size) { + /* Since python supports arbitrarily large ints in JSON, + long inputs can lead to timeouts on boring inputs like + `json.loads("9" * 100000)` */ + if (size > MAX_JSON_TEST_SIZE) { + return 0; + } + PyObject* input_bytes = PyBytes_FromStringAndSize(data, size); + if (input_bytes == NULL) { + return 0; + } + PyObject* parsed = PyObject_CallFunctionObjArgs(json_loads_method, input_bytes, NULL); + /* Ignore ValueError as the fuzzer will more than likely + generate some invalid json and values */ + if (parsed == NULL && PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + } + /* Ignore RecursionError as the fuzzer generates long sequences of + arrays such as `[[[...` */ + if (parsed == NULL && PyErr_ExceptionMatches(PyExc_RecursionError)) { + PyErr_Clear(); + } + /* Ignore unicode errors, invalid byte sequences are common */ + if (parsed == NULL && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + PyErr_Clear(); + } + Py_DECREF(input_bytes); + Py_XDECREF(parsed); + return 0; +} + /* Run fuzzer and abort on failure. */ static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* , size_t)) { int rv = fuzzer((const char*) data, size); @@ -88,7 +131,6 @@ static int _run_fuzz(const uint8_t *data, size_t size, int(*fuzzer)(const char* /* CPython generates a lot of leak warnings for whatever reason. */ int __lsan_is_turned_off(void) { return 1; } -wchar_t wide_program_name[NAME_MAX]; int LLVMFuzzerInitialize(int *argc, char ***argv) { wchar_t* wide_program_name = Py_DecodeLocale(*argv[0], NULL); @@ -110,6 +152,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { initialize CPython ourselves on the first run. */ Py_InitializeEx(0); } +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_json_loads) + if (json_loads_method == NULL) { + PyObject* json_module = PyImport_ImportModule("json"); + json_loads_method = PyObject_GetAttrString(json_module, "loads"); + } +#endif int rv = 0; @@ -121,6 +169,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { #endif #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_builtin_unicode) rv |= _run_fuzz(data, size, fuzz_builtin_unicode); +#endif +#if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_json_loads) + rv |= _run_fuzz(data, size, fuzz_json_loads); #endif return rv; } From 32dda263e4e8c8e0fadc2bb29b9856e2f177dde9 Mon Sep 17 00:00:00 2001 From: Michael Felt Date: Wed, 12 Jun 2019 14:00:56 +0200 Subject: [PATCH 382/441] bpo-35545: Skip `test_asyncio.test_create_connection_ipv6_scope` on AIX (GH-14011) because "getaddrinfo()" behaves different on AIX https://bugs.python.org/issue35545 --- Lib/test/test_asyncio/test_base_events.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 02a97c60ac1a93..811b37425dd287 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1298,6 +1298,8 @@ def _test_create_connection_ip_addr(self, m_socket, allow_inet_pton): t.close() test_utils.run_briefly(self.loop) # allow transport to close + @unittest.skipIf(sys.platform.startswith('aix'), + "bpo-25545: IPv6 scope id and getaddrinfo() behave differently on AIX") @patch_socket def test_create_connection_ipv6_scope(self, m_socket): m_socket.getaddrinfo = socket.getaddrinfo From 5287022eeeb3c017d49fc8580b52e18377bf23f3 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 12 Jun 2019 15:37:56 +0000 Subject: [PATCH 383/441] bpo-37160: Thread native ID NetBSD support (GH-13835) --- Doc/library/_thread.rst | 2 +- Doc/library/threading.rst | 2 +- Include/pythread.h | 2 +- .../2019-06-05-09-24-17.bpo-37160.O3IAY3.rst | 1 + Python/thread_pthread.h | 5 +++++ 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 26568dcbf8f532..5b4fcde669e13b 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -106,7 +106,7 @@ This module defines the following constants and functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD. .. versionadded:: 3.8 diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 7fb9ac9979e42f..b4f4814c4ad37b 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -82,7 +82,7 @@ This module defines the following functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD. .. versionadded:: 3.8 diff --git a/Include/pythread.h b/Include/pythread.h index 84b79c87642575..79a9210af3a491 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -26,7 +26,7 @@ PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); -#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_WIN32) +#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); #endif diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3.rst new file mode 100644 index 00000000000000..c2fc6804a12688 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-05-09-24-17.bpo-37160.O3IAY3.rst @@ -0,0 +1 @@ +:func:`threading.get_native_id` now also supports NetBSD. diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 740b521b944621..9b4b23bdc7d7bf 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -18,6 +18,8 @@ # include /* pthread_getthreadid_np() */ #elif defined(__OpenBSD__) # include /* getthrid() */ +#elif defined(__NetBSD__) /* _lwp_self */ +# include #endif /* The POSIX spec requires that use of pthread_attr_setstacksize @@ -328,6 +330,9 @@ PyThread_get_thread_native_id(void) #elif defined(__OpenBSD__) pid_t native_id; native_id = getthrid(); +#elif defined(__NetBSD__) + lwpid_t native_id; + native_id = _lwp_self(); #endif return (unsigned long) native_id; } From daf62627518ad97ce66a48c49496aa0573cf0731 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Wed, 12 Jun 2019 10:16:49 -0700 Subject: [PATCH 384/441] bpo-37201: fix test_distutils failures for Windows ARM64 (GH-13902) --- Lib/distutils/_msvccompiler.py | 2 ++ Lib/distutils/tests/test_bdist_wininst.py | 4 ++++ Lib/distutils/util.py | 2 ++ Lib/sysconfig.py | 2 ++ PC/pyconfig.h | 6 +++--- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py index c7ac3f049ebf22..6e14f330d7f4d2 100644 --- a/Lib/distutils/_msvccompiler.py +++ b/Lib/distutils/_msvccompiler.py @@ -93,6 +93,7 @@ def _find_vc2017(): 'x86' : 'x86', 'x86_amd64' : 'x64', 'x86_arm' : 'arm', + 'x86_arm64' : 'arm64' } def _find_vcvarsall(plat_spec): @@ -190,6 +191,7 @@ def _find_exe(exe, paths=None): 'win32' : 'x86', 'win-amd64' : 'x86_amd64', 'win-arm32' : 'x86_arm', + 'win-arm64' : 'x86_arm64' } # A set containing the DLLs that are guaranteed to be available for diff --git a/Lib/distutils/tests/test_bdist_wininst.py b/Lib/distutils/tests/test_bdist_wininst.py index 4c19bbab219baf..163f1cc97bf9a8 100644 --- a/Lib/distutils/tests/test_bdist_wininst.py +++ b/Lib/distutils/tests/test_bdist_wininst.py @@ -1,10 +1,14 @@ """Tests for distutils.command.bdist_wininst.""" +import sys +import platform import unittest from test.support import run_unittest from distutils.command.bdist_wininst import bdist_wininst from distutils.tests import support +@unittest.skipIf(sys.platform == 'win32' and platform.machine() == 'ARM64', + 'bdist_wininst is not supported in this install') @unittest.skipIf(getattr(bdist_wininst, '_unsupported', False), 'bdist_wininst is not supported in this install') class BuildWinInstTestCase(support.TempdirManager, diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py index 50550e1893418c..17a94bc4283241 100644 --- a/Lib/distutils/util.py +++ b/Lib/distutils/util.py @@ -40,6 +40,8 @@ def get_host_platform(): return 'win-amd64' if '(arm)' in sys.version.lower(): return 'win-arm32' + if '(arm64)' in sys.version.lower(): + return 'win-arm64' return sys.platform # Set for cross builds explicitly diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index 8446c8deb2427e..e76e6927cb1ff3 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -628,6 +628,8 @@ def get_platform(): return 'win-amd64' if '(arm)' in sys.version.lower(): return 'win-arm32' + if '(arm64)' in sys.version.lower(): + return 'win-arm64' return sys.platform if os.name != "posix" or not hasattr(os, 'uname'): diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 122591276b4a7d..9228923cbea831 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -122,13 +122,13 @@ WIN32 is still required for the locale module. #if defined(_M_X64) || defined(_M_AMD64) #if defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") -#elif defined(_M_ARM64) -#define COMPILER _Py_PASTE_VERSION("64 bit (ARM)") -#define PYD_PLATFORM_TAG "win_arm64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") #endif /* __INTEL_COMPILER */ #define PYD_PLATFORM_TAG "win_amd64" +#elif defined(_M_ARM64) +#define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)") +#define PYD_PLATFORM_TAG "win_arm64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") #endif From ff6bb0aa95259413f359d42410526ff0b4dccfb7 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Wed, 12 Jun 2019 11:08:40 -0700 Subject: [PATCH 385/441] bpo-37236: pragma optimize off for _Py_c_quot on Windows arm64 (GH-13983) --- Objects/complexobject.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Objects/complexobject.c b/Objects/complexobject.c index f78c0fdf78def4..a49da4018411e7 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -55,6 +55,10 @@ _Py_c_prod(Py_complex a, Py_complex b) return r; } +/* Avoid bad optimization on Windows ARM64 until the compiler is fixed */ +#ifdef _M_ARM64 +#pragma optimize("", off) +#endif Py_complex _Py_c_quot(Py_complex a, Py_complex b) { @@ -112,6 +116,9 @@ _Py_c_quot(Py_complex a, Py_complex b) } return r; } +#ifdef _M_ARM64 +#pragma optimize("", on) +#endif Py_complex _Py_c_pow(Py_complex a, Py_complex b) From 0d1942774a70d561dbaaa980742dd0927e8aa51a Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Wed, 12 Jun 2019 21:50:23 +0300 Subject: [PATCH 386/441] Make asyncio stream sendfile fail on error (was hang) (GH-14025) --- Lib/test/test_asyncio/test_streams.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 74e385524dd54b..a1c62ecee662b3 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -1656,22 +1656,25 @@ def test_sendfile(self): async def serve_callback(stream): data = await stream.readline() - self.assertEqual(data, b'begin\n') + await stream.write(b'ack-' + data) data = await stream.readline() - self.assertEqual(data, b'data\n') + await stream.write(b'ack-' + data) data = await stream.readline() - self.assertEqual(data, b'end\n') - await stream.write(b'done\n') + await stream.write(b'ack-' + data) await stream.close() async def do_connect(host, port): stream = await asyncio.connect(host, port) await stream.write(b'begin\n') + data = await stream.readline() + self.assertEqual(b'ack-begin\n', data) with open(support.TESTFN, 'rb') as fp: await stream.sendfile(fp) + data = await stream.readline() + self.assertEqual(b'ack-data\n', data) await stream.write(b'end\n') data = await stream.readline() - self.assertEqual(data, b'done\n') + self.assertEqual(data, b'ack-end\n') await stream.close() async def test(): From 913fa1c8245d1cde6edb4254f4fb965cc91786ef Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Jun 2019 23:57:11 +0200 Subject: [PATCH 387/441] bpo-37223, test_io: silence last 'Exception ignored in:' (GH-14029) Use catch_unraisable_exception() to ignore 'Exception ignored in:' error when the internal BufferedWriter of the BufferedRWPair is destroyed. The C implementation doesn't give access to the internal BufferedWriter, so just ignore the warning instead. --- Lib/test/test_io.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 102679b1d34243..55686d74398355 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -2070,6 +2070,11 @@ def writer_close(): # Silence destructor error writer.close = lambda: None + writer = None + + with support.catch_unraisable_exception(): + pair = None + support.gc_collect() def test_reader_writer_close_error_on_close(self): def reader_close(): From 95f61c8b1619e736bd5e29a0da0183234634b6e8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 01:09:04 +0200 Subject: [PATCH 388/441] bpo-37069: regrtest uses sys.unraisablehook (GH-13759) regrtest now uses sys.unraisablehook() to mark a test as "environment altered" (ENV_CHANGED) if it emits an "unraisable exception". Moreover, regrtest logs a warning in this case. Use "python3 -m test --fail-env-changed" to catch unraisable exceptions in tests. --- Lib/test/libregrtest/setup.py | 4 +++ Lib/test/libregrtest/utils.py | 17 +++++++++++ Lib/test/test_regrtest.py | 30 ++++++++++++++++++- .../2019-06-13-00-46-25.bpo-37069.wdktFo.rst | 7 +++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index fb5ac350cd0847..36676bfa617b70 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -10,6 +10,8 @@ except ImportError: gc = None +from test.libregrtest.utils import setup_unraisable_hook + def setup_tests(ns): try: @@ -93,6 +95,8 @@ def _test_audit_hook(name, args): pass sys.addaudithook(_test_audit_hook) + setup_unraisable_hook() + def suppress_msvcrt_asserts(verbose): try: diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index fb9971a64f66c8..2691a2c30ce80a 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -2,6 +2,7 @@ import os.path import sys import textwrap +from test import support def format_duration(seconds): @@ -59,3 +60,19 @@ def printlist(x, width=70, indent=4, file=None): def print_warning(msg): print(f"Warning -- {msg}", file=sys.stderr, flush=True) + + +orig_unraisablehook = None + + +def regrtest_unraisable_hook(unraisable): + global orig_unraisablehook + support.environment_altered = True + print_warning("Unraisable exception") + orig_unraisablehook(unraisable) + + +def setup_unraisable_hook(): + global orig_unraisablehook + orig_unraisablehook = sys.unraisablehook + sys.unraisablehook = regrtest_unraisable_hook diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index b616e8974b9d2c..904b326d0e2049 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -499,7 +499,7 @@ def run_command(self, args, input=None, exitcode=0, **kw): if not input: input = '' if 'stderr' not in kw: - kw['stderr'] = subprocess.PIPE + kw['stderr'] = subprocess.STDOUT proc = subprocess.run(args, universal_newlines=True, input=input, @@ -1124,6 +1124,34 @@ def test_garbage(self): env_changed=[testname], fail_env_changed=True) + def test_unraisable_exc(self): + # --fail-env-changed must catch unraisable exception + code = textwrap.dedent(r""" + import unittest + import weakref + + class MyObject: + pass + + def weakref_callback(obj): + raise Exception("weakref callback bug") + + class Tests(unittest.TestCase): + def test_unraisable_exc(self): + obj = MyObject() + ref = weakref.ref(obj, weakref_callback) + # call weakref_callback() which logs + # an unraisable exception + obj = None + """) + testname = self.create_test(code=code) + + output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + self.check_executed_tests(output, [testname], + env_changed=[testname], + fail_env_changed=True) + self.assertIn("Warning -- Unraisable exception", output) + class TestUtils(unittest.TestCase): def test_format_duration(self): diff --git a/Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst b/Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst new file mode 100644 index 00000000000000..f9f6474ac8cfd0 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-06-13-00-46-25.bpo-37069.wdktFo.rst @@ -0,0 +1,7 @@ +regrtest now uses :func:`sys.unraisablehook` to mark a test as "environment +altered" (ENV_CHANGED) if it emits an "unraisable exception". Moreover, +regrtest logs a warning in this case. + +Use ``python3 -m test --fail-env-changed`` to catch unraisable exceptions in +tests. + From b4c7defe58695a6670a8fdeaef67a638bbb47e42 Mon Sep 17 00:00:00 2001 From: Paul Monson Date: Wed, 12 Jun 2019 16:13:27 -0700 Subject: [PATCH 389/441] =?UTF-8?q?bpo-36779:=20time.tzname=20returns=20em?= =?UTF-8?q?pty=20string=20on=20Windows=20if=20default=20cod=E2=80=A6=20(GH?= =?UTF-8?q?-13073)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling setlocale(LC_CTYPE, "") on a system where GetACP() returns CP_UTF8 results in empty strings in _tzname[]. This causes time.tzname to be an empty string. I have reported the bug to the UCRT team and will follow up, but it will take some time get a fix into production. In the meantime one possible workaround is to temporarily change the locale by calling setlocale(LC_CTYPE, "C") before calling _tzset and restore the current locale after if the GetACP() == CP_UTF8 or CP_UTF7 @zooba https://bugs.python.org/issue36779 --- .../2019-06-11-15-41-34.bpo-36779.0TMw6f.rst | 2 ++ Modules/timemodule.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst diff --git a/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst b/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst new file mode 100644 index 00000000000000..618cfcae7b8993 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-06-11-15-41-34.bpo-36779.0TMw6f.rst @@ -0,0 +1,2 @@ +Ensure ``time.tzname`` is correct on Windows when the active code page is +set to CP_UTF7 or CP_UTF8. diff --git a/Modules/timemodule.c b/Modules/timemodule.c index f991f31ee15ed7..bdc93a2b7ec1eb 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -1581,6 +1581,19 @@ init_timezone(PyObject *m) PyModule_AddIntConstant(m, "altzone", _Py_timezone-3600); #endif PyModule_AddIntConstant(m, "daylight", _Py_daylight); +#ifdef MS_WINDOWS + TIME_ZONE_INFORMATION tzinfo = {0}; + GetTimeZoneInformation(&tzinfo); + otz0 = PyUnicode_FromWideChar(tzinfo.StandardName, -1); + if (otz0 == NULL) { + return -1; + } + otz1 = PyUnicode_FromWideChar(tzinfo.DaylightName, -1); + if (otz1 == NULL) { + Py_DECREF(otz0); + return -1; + } +#else otz0 = PyUnicode_DecodeLocale(_Py_tzname[0], "surrogateescape"); if (otz0 == NULL) { return -1; @@ -1590,6 +1603,7 @@ init_timezone(PyObject *m) Py_DECREF(otz0); return -1; } +#endif // MS_WINDOWS PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1); if (tzname_obj == NULL) { return -1; From 468e5fec8a2f534f1685d59da3ca4fad425c38dd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 01:30:17 +0200 Subject: [PATCH 390/441] bpo-36402: Fix threading._shutdown() race condition (GH-13948) Fix a race condition at Python shutdown when waiting for threads. Wait until the Python thread state of all non-daemon threads get deleted (join all non-daemon threads), rather than just wait until Python threads complete. * Add threading._shutdown_locks: set of Thread._tstate_lock locks of non-daemon threads used by _shutdown() to wait until all Python thread states get deleted. See Thread._set_tstate_lock(). * Add also threading._shutdown_locks_lock to protect access to threading._shutdown_locks. * Add test_finalization_shutdown() test. --- Lib/test/test_threading.py | 55 ++++++++++++++++++- Lib/threading.py | 49 ++++++++++++++--- .../2019-06-11-00-35-02.bpo-36402.b0IJVp.rst | 4 ++ 3 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 6ac4ea9623de0d..ad90010b8a3821 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -583,6 +583,41 @@ def __del__(self): self.assertEqual(data.splitlines(), ["GC: True True True"] * 2) + def test_finalization_shutdown(self): + # bpo-36402: Py_Finalize() calls threading._shutdown() which must wait + # until Python thread states of all non-daemon threads get deleted. + # + # Test similar to SubinterpThreadingTests.test_threads_join_2(), but + # test the finalization of the main interpreter. + code = """if 1: + import os + import threading + import time + import random + + def random_sleep(): + seconds = random.random() * 0.010 + time.sleep(seconds) + + class Sleeper: + def __del__(self): + random_sleep() + + tls = threading.local() + + def f(): + # Sleep a bit so that the thread is still running when + # Py_Finalize() is called. + random_sleep() + tls.x = Sleeper() + random_sleep() + + threading.Thread(target=f).start() + random_sleep() + """ + rc, out, err = assert_python_ok("-c", code) + self.assertEqual(err, b"") + def test_tstate_lock(self): # Test an implementation detail of Thread objects. started = _thread.allocate_lock() @@ -878,15 +913,22 @@ def test_threads_join(self): self.addCleanup(os.close, w) code = r"""if 1: import os + import random import threading import time + def random_sleep(): + seconds = random.random() * 0.010 + time.sleep(seconds) + def f(): # Sleep a bit so that the thread is still running when # Py_EndInterpreter is called. - time.sleep(0.05) + random_sleep() os.write(%d, b"x") + threading.Thread(target=f).start() + random_sleep() """ % (w,) ret = test.support.run_in_subinterp(code) self.assertEqual(ret, 0) @@ -903,22 +945,29 @@ def test_threads_join_2(self): self.addCleanup(os.close, w) code = r"""if 1: import os + import random import threading import time + def random_sleep(): + seconds = random.random() * 0.010 + time.sleep(seconds) + class Sleeper: def __del__(self): - time.sleep(0.05) + random_sleep() tls = threading.local() def f(): # Sleep a bit so that the thread is still running when # Py_EndInterpreter is called. - time.sleep(0.05) + random_sleep() tls.x = Sleeper() os.write(%d, b"x") + threading.Thread(target=f).start() + random_sleep() """ % (w,) ret = test.support.run_in_subinterp(code) self.assertEqual(ret, 0) diff --git a/Lib/threading.py b/Lib/threading.py index 3d197eed6a7251..67926403770e62 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -739,6 +739,11 @@ def _newname(template="Thread-%d"): _active = {} # maps thread id to Thread object _limbo = {} _dangling = WeakSet() +# Set of Thread._tstate_lock locks of non-daemon threads used by _shutdown() +# to wait until all Python thread states get deleted: +# see Thread._set_tstate_lock(). +_shutdown_locks_lock = _allocate_lock() +_shutdown_locks = set() # Main class for threads @@ -903,6 +908,10 @@ def _set_tstate_lock(self): self._tstate_lock = _set_sentinel() self._tstate_lock.acquire() + if not self.daemon: + with _shutdown_locks_lock: + _shutdown_locks.add(self._tstate_lock) + def _bootstrap_inner(self): try: self._set_ident() @@ -954,6 +963,9 @@ def _stop(self): assert not lock.locked() self._is_stopped = True self._tstate_lock = None + if not self.daemon: + with _shutdown_locks_lock: + _shutdown_locks.discard(self._tstate_lock) def _delete(self): "Remove current thread from the dict of currently running threads." @@ -1342,6 +1354,9 @@ def enumerate(): _main_thread = _MainThread() def _shutdown(): + """ + Wait until the Python thread state of all non-daemon threads get deleted. + """ # Obscure: other threads may be waiting to join _main_thread. That's # dubious, but some code does it. We can't wait for C code to release # the main thread's tstate_lock - that won't happen until the interpreter @@ -1350,6 +1365,8 @@ def _shutdown(): if _main_thread._is_stopped: # _shutdown() was already called return + + # Main thread tlock = _main_thread._tstate_lock # The main thread isn't finished yet, so its thread state lock can't have # been released. @@ -1357,16 +1374,24 @@ def _shutdown(): assert tlock.locked() tlock.release() _main_thread._stop() - t = _pickSomeNonDaemonThread() - while t: - t.join() - t = _pickSomeNonDaemonThread() -def _pickSomeNonDaemonThread(): - for t in enumerate(): - if not t.daemon and t.is_alive(): - return t - return None + # Join all non-deamon threads + while True: + with _shutdown_locks_lock: + locks = list(_shutdown_locks) + _shutdown_locks.clear() + + if not locks: + break + + for lock in locks: + # mimick Thread.join() + lock.acquire() + lock.release() + + # new threads can be spawned while we were waiting for the other + # threads to complete + def main_thread(): """Return the main thread object. @@ -1392,12 +1417,18 @@ def _after_fork(): # Reset _active_limbo_lock, in case we forked while the lock was held # by another (non-forked) thread. http://bugs.python.org/issue874900 global _active_limbo_lock, _main_thread + global _shutdown_locks_lock, _shutdown_locks _active_limbo_lock = _allocate_lock() # fork() only copied the current thread; clear references to others. new_active = {} current = current_thread() _main_thread = current + + # reset _shutdown() locks: threads re-register their _tstate_lock below + _shutdown_locks_lock = _allocate_lock() + _shutdown_locks = set() + with _active_limbo_lock: # Dangling thread instances must still have their locks reset, # because someone may join() them. diff --git a/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst b/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst new file mode 100644 index 00000000000000..3bc537e40ff697 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-11-00-35-02.bpo-36402.b0IJVp.rst @@ -0,0 +1,4 @@ +Fix a race condition at Python shutdown when waiting for threads. Wait until +the Python thread state of all non-daemon threads get deleted (join all +non-daemon threads), rather than just wait until non-daemon Python threads +complete. From 2c9b498759f4fc74da82a0a96d059d666fa73f16 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 02:01:29 +0200 Subject: [PATCH 391/441] bpo-37253: Document PyCompilerFlags.cf_feature_version (GH-14019) * Update PyCompilerFlags structure documentation. * Document the new cf_feature_version field in the Changes in the C API section of the What's New in Python 3.8 doc. --- Doc/c-api/veryhigh.rst | 19 +++++++++++++++---- Doc/whatsnew/3.8.rst | 5 +++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 3fe0ae47aac35a..835afcb4f217f6 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -388,11 +388,22 @@ the same library that the Python runtime is using. Whenever ``PyCompilerFlags *flags`` is *NULL*, :attr:`cf_flags` is treated as equal to ``0``, and any modification due to ``from __future__ import`` is - discarded. :: + discarded. - struct PyCompilerFlags { - int cf_flags; - } + .. c:member:: int cf_flags + + Compiler flags. + + .. c:member:: int cf_feature_version; + + *cf_feature_version* is the minor Python version. It should be + initialized to ``PY_MINOR_VERSION``. + + The field is ignored by default, it is used if and only if + ``PyCF_ONLY_AST`` flag is set in *cf_flags*. + + .. versionchanged:: 3.8 + Added *cf_feature_version* field. .. c:var:: int CO_FUTURE_DIVISION diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 264586434b9b08..3e607130743df1 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1312,6 +1312,11 @@ Changes in the Python API Changes in the C API -------------------- +* The :c:type:`PyCompilerFlags` structure gets a new *cf_feature_version* + field. It should be initialized to ``PY_MINOR_VERSION``. The field is ignored + by default, it is used if and only if ``PyCF_ONLY_AST`` flag is set in + *cf_flags*. + * The :c:func:`PyEval_ReInitThreads` function has been removed from the C API. It should not be called explicitly: use :c:func:`PyOS_AfterFork_Child` instead. From 37d66d7d4bc7dbac9809d69966a774ebb32563be Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 02:16:41 +0200 Subject: [PATCH 392/441] bpo-37253: Add _PyCompilerFlags_INIT macro (GH-14018) Add a new _PyCompilerFlags_INIT macro to initialize PyCompilerFlags variables, rather than initializing cf_flags and cf_feature_version explicitly in each variable. --- Include/compile.h | 3 +++ Modules/main.c | 2 +- Modules/parsermodule.c | 3 +-- Modules/symtablemodule.c | 3 +-- Python/ast.c | 3 +-- Python/bltinmodule.c | 9 +++------ Python/compile.c | 4 +--- Python/pythonrun.c | 17 ++++------------- 8 files changed, 15 insertions(+), 29 deletions(-) diff --git a/Include/compile.h b/Include/compile.h index a833caa06b9dad..1cda955c142551 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -30,6 +30,9 @@ typedef struct { int cf_flags; /* bitmask of CO_xxx flags relevant to future */ int cf_feature_version; /* minor Python version (PyCF_ONLY_AST) */ } PyCompilerFlags; + +#define _PyCompilerFlags_INIT \ + (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} #endif /* Future feature support */ diff --git a/Modules/main.c b/Modules/main.c index 6b9406f7866672..853afedd7b9099 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -524,7 +524,7 @@ pymain_run_python(int *exitcode) } } - PyCompilerFlags cf = {.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION}; + PyCompilerFlags cf = _PyCompilerFlags_INIT; pymain_header(config); pymain_import_readline(config); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 36f92141915365..079d00f32aa6cd 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -336,8 +336,7 @@ parser_newstobject(node *st, int type) if (o != 0) { o->st_node = st; o->st_type = type; - o->st_flags.cf_flags = 0; - o->st_flags.cf_feature_version = PY_MINOR_VERSION; + o->st_flags = _PyCompilerFlags_INIT; } else { PyNode_Free(st); diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index d66cb44f69bdfe..9180f185e1e877 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -30,11 +30,10 @@ _symtable_symtable_impl(PyObject *module, PyObject *source, struct symtable *st; PyObject *t; int start; - PyCompilerFlags cf; + PyCompilerFlags cf = _PyCompilerFlags_INIT; PyObject *source_copy = NULL; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; const char *str = _Py_SourceAsString(source, "symtable", "string or bytes", &cf, &source_copy); if (str == NULL) { diff --git a/Python/ast.c b/Python/ast.c index df9242977e3f21..2a59415721485e 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -4845,7 +4845,6 @@ fstring_compile_expr(const char *expr_start, const char *expr_end, struct compiling *c, const node *n) { - PyCompilerFlags cf; node *mod_n; mod_ty mod; char *str; @@ -4887,8 +4886,8 @@ fstring_compile_expr(const char *expr_start, const char *expr_end, str[len+1] = ')'; str[len+2] = 0; + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = PyCF_ONLY_AST; - cf.cf_feature_version = PY_MINOR_VERSION; mod_n = PyParser_SimpleParseStringFlagsFilename(str, "", Py_eval_input, 0); if (!mod_n) { diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index abf807a408f781..c3e30593475d9d 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -723,12 +723,11 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, const char *str; int compile_mode = -1; int is_ast; - PyCompilerFlags cf; int start[] = {Py_file_input, Py_eval_input, Py_single_input, Py_func_type_input}; PyObject *result; + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; if (feature_version >= 0 && (flags & PyCF_ONLY_AST)) { cf.cf_feature_version = feature_version; } @@ -889,7 +888,6 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, { PyObject *result, *source_copy; const char *str; - PyCompilerFlags cf; if (locals != Py_None && !PyMapping_Check(locals)) { PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); @@ -941,8 +939,8 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, return PyEval_EvalCode(source, globals, locals); } + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy); if (str == NULL) return NULL; @@ -1032,9 +1030,8 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, else { PyObject *source_copy; const char *str; - PyCompilerFlags cf; + PyCompilerFlags cf = _PyCompilerFlags_INIT; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - cf.cf_feature_version = PY_MINOR_VERSION; str = _Py_SourceAsString(source, "exec", "string, bytes or code", &cf, &source_copy); diff --git a/Python/compile.c b/Python/compile.c index 9e4a2094ac9b92..4d3ecfe5d6fc9d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -309,7 +309,7 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, { struct compiler c; PyCodeObject *co = NULL; - PyCompilerFlags local_flags; + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; int merged; PyConfig *config = &_PyInterpreterState_GET_UNSAFE()->config; @@ -332,8 +332,6 @@ PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, if (c.c_future == NULL) goto finally; if (!flags) { - local_flags.cf_flags = 0; - local_flags.cf_feature_version = PY_MINOR_VERSION; flags = &local_flags; } merged = c.c_future->ff_features | flags->cf_flags; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 784c15bb4b22ce..8f3ee19279d912 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -91,7 +91,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * { PyObject *filename, *v; int ret, err; - PyCompilerFlags local_flags; + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; int nomem_count = 0; #ifdef Py_REF_DEBUG int show_ref_count = _PyInterpreterState_Get()->config.show_ref_count; @@ -105,8 +105,6 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * if (flags == NULL) { flags = &local_flags; - local_flags.cf_flags = 0; - local_flags.cf_feature_version = PY_MINOR_VERSION; } v = _PySys_GetObjectId(&PyId_ps1); if (v == NULL) { @@ -1283,10 +1281,7 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp struct symtable * Py_SymtableStringObject(const char *str, PyObject *filename, int start) { - PyCompilerFlags flags; - - flags.cf_flags = 0; - flags.cf_feature_version = PY_MINOR_VERSION; + PyCompilerFlags flags = _PyCompilerFlags_INIT; return _Py_SymtableStringObjectFlags(str, filename, start, &flags); } @@ -1331,7 +1326,7 @@ PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start, PyCompilerFlags *flags, PyArena *arena) { mod_ty mod; - PyCompilerFlags localflags; + PyCompilerFlags localflags = _PyCompilerFlags_INIT; perrdetail err; int iflags = PARSER_FLAGS(flags); if (flags && flags->cf_feature_version < 7) @@ -1341,8 +1336,6 @@ PyParser_ASTFromStringObject(const char *s, PyObject *filename, int start, &_PyParser_Grammar, start, &err, &iflags); if (flags == NULL) { - localflags.cf_flags = 0; - localflags.cf_feature_version = PY_MINOR_VERSION; flags = &localflags; } if (n) { @@ -1379,7 +1372,7 @@ PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc, PyArena *arena) { mod_ty mod; - PyCompilerFlags localflags; + PyCompilerFlags localflags = _PyCompilerFlags_INIT; perrdetail err; int iflags = PARSER_FLAGS(flags); @@ -1387,8 +1380,6 @@ PyParser_ASTFromFileObject(FILE *fp, PyObject *filename, const char* enc, &_PyParser_Grammar, start, ps1, ps2, &err, &iflags); if (flags == NULL) { - localflags.cf_flags = 0; - localflags.cf_feature_version = PY_MINOR_VERSION; flags = &localflags; } if (n) { From a04ea4f92ccbe20ffdbb5fa9b6bb93ee8da50f5d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 02:17:14 +0200 Subject: [PATCH 393/441] bpo-37253: Fix typo in PyCompilerFlags doc (GH-14036) Remove ";" to fix Sphinx formatting. --- Doc/c-api/veryhigh.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 835afcb4f217f6..e6704ddeca0906 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -394,7 +394,7 @@ the same library that the Python runtime is using. Compiler flags. - .. c:member:: int cf_feature_version; + .. c:member:: int cf_feature_version *cf_feature_version* is the minor Python version. It should be initialized to ``PY_MINOR_VERSION``. From 3a2883c313be3aff34c61a42e586f8507ba5945f Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Wed, 12 Jun 2019 23:31:45 -0400 Subject: [PATCH 394/441] Add 3.9 whatsnew file (GH-14040) --- Doc/whatsnew/3.9.rst | 115 +++++++++++++++++++++++++++++++++++++++++ Doc/whatsnew/index.rst | 1 + 2 files changed, 116 insertions(+) create mode 100644 Doc/whatsnew/3.9.rst diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst new file mode 100644 index 00000000000000..999519f0ce0753 --- /dev/null +++ b/Doc/whatsnew/3.9.rst @@ -0,0 +1,115 @@ +**************************** + What's New In Python 3.9 +**************************** + +:Release: |release| +:Date: |today| + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the bug/patch number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :issue:`12345`.) + + This saves the maintainer the effort of going through the Mercurial log + when researching a change. + +This article explains the new features in Python 3.9, compared to 3.8. + +For full details, see the :source:`Misc/NEWS` file. + +.. note:: + + Prerelease users should be aware that this document is currently in draft + form. It will be updated substantially as Python 3.9 moves towards release, + so it's worth checking back even after reading earlier versions. + + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.9. + Brevity is key. + + +.. PEP-sized items next. + + + +New Features +============ + + + +Other Language Changes +====================== + + + +New Modules +=========== + +* None yet. + + +Improved Modules +================ + + +Optimizations +============= + + +Build and C API Changes +======================= + + + +Deprecated +========== + + + +Removed +======= + + + +Porting to Python 3.9 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + + diff --git a/Doc/whatsnew/index.rst b/Doc/whatsnew/index.rst index b1160c03982152..954e38bc6f1e3d 100644 --- a/Doc/whatsnew/index.rst +++ b/Doc/whatsnew/index.rst @@ -11,6 +11,7 @@ anyone wishing to stay up-to-date after a new release. .. toctree:: :maxdepth: 2 + 3.9.rst 3.8.rst 3.7.rst 3.6.rst From d1c85a27ea9fe70163cad3443d5e534d94f08284 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Wed, 12 Jun 2019 22:41:03 -0500 Subject: [PATCH 395/441] bpo-37257: obmalloc: stop simple arena thrashing (#14039) GH-14039: allow (no more than) one wholly empty arena on the usable_arenas list. This prevents thrashing in some easily-provoked simple cases that could end up creating and destroying an arena on each loop iteration in client code. Intuitively, if the only arena on the list becomes empty, it makes scant sense to give it back to the system unless we know we'll never need another free pool again before another arena frees a pool. If the latter obtains, then - yes - this will "waste" an arena. --- .../2019-06-13-02-27-12.bpo-37257.IMxDvT.rst | 1 + Objects/obmalloc.c | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-37257.IMxDvT.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-37257.IMxDvT.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-37257.IMxDvT.rst new file mode 100644 index 00000000000000..ac8d90fd2998b4 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-13-02-27-12.bpo-37257.IMxDvT.rst @@ -0,0 +1 @@ +Python's small object allocator (``obmalloc.c``) now allows (no more than) one empty arena to remain available for immediate reuse, without returning it to the OS. This prevents thrashing in simple loops where an arena could be created and destroyed anew on each iteration. \ No newline at end of file diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index fc7bef6199466d..622da3ad08fcd4 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1758,7 +1758,12 @@ pymalloc_free(void *ctx, void *p) /* All the rest is arena management. We just freed * a pool, and there are 4 cases for arena mgmt: * 1. If all the pools are free, return the arena to - * the system free(). + * the system free(). Except if this is the last + * arena in the list, keep it to avoid thrashing: + * keeping one wholly free arena in the list avoids + * pathological cases where a simple loop would + * otherwise provoke needing to allocate and free an + * arena on every iteration. See bpo-37257. * 2. If this is the only free pool in the arena, * add the arena back to the `usable_arenas` list. * 3. If the "next" arena has a smaller count of free @@ -1767,7 +1772,7 @@ pymalloc_free(void *ctx, void *p) * nfreepools. * 4. Else there's nothing more to do. */ - if (nf == ao->ntotalpools) { + if (nf == ao->ntotalpools && ao->nextarena != NULL) { /* Case 1. First unlink ao from usable_arenas. */ assert(ao->prevarena == NULL || From 905e19a9bf9afd6439ea44fc6a4f3c8631750d6d Mon Sep 17 00:00:00 2001 From: Makdon Date: Thu, 13 Jun 2019 13:04:13 +0800 Subject: [PATCH 396/441] bpo-37216: update version to 3.9 in mac using document (GH-13966) --- Doc/using/mac.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index bc022fa58c0401..baf737ddaa9171 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -25,7 +25,7 @@ there. What you get after installing is a number of things: -* A :file:`MacPython 3.6` folder in your :file:`Applications` folder. In here +* A :file:`Python 3.9` folder in your :file:`Applications` folder. In here you find IDLE, the development environment that is a standard part of official Python distributions; PythonLauncher, which handles double-clicking Python scripts from the Finder; and the "Build Applet" tool, which allows you to @@ -93,7 +93,7 @@ aware of: programs that talk to the Aqua window manager (in other words, anything that has a GUI) need to be run in a special way. Use :program:`pythonw` instead of :program:`python` to start such scripts. -With Python 3.6, you can use either :program:`python` or :program:`pythonw`. +With Python 3.9, you can use either :program:`python` or :program:`pythonw`. Configuration From 8725c83ed5ca8959195ad8326db99d564a921749 Mon Sep 17 00:00:00 2001 From: Jeffrey Kintscher <49998481+websurfer5@users.noreply.github.com> Date: Thu, 13 Jun 2019 00:01:29 -0700 Subject: [PATCH 397/441] bpo-35070: test_getgrouplist may fail on macOS if too many groups (GH-13071) --- .../2019-05-09-18-50-55.bpo-35070.4vaqNL.rst | 2 ++ Modules/posixmodule.c | 32 ++++++++++--------- 2 files changed, 19 insertions(+), 15 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst diff --git a/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst b/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst new file mode 100644 index 00000000000000..e823f1d469cca6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-09-18-50-55.bpo-35070.4vaqNL.rst @@ -0,0 +1,2 @@ +posix.getgrouplist() now works correctly when the user belongs to +NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8f6cffffcdfbe8..7a471801db3943 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6722,6 +6722,13 @@ os_getpid_impl(PyObject *module) } #endif /* HAVE_GETPID */ +#ifdef NGROUPS_MAX +#define MAX_GROUPS NGROUPS_MAX +#else + /* defined to be 16 on Solaris7, so this should be a small number */ +#define MAX_GROUPS 64 +#endif + #ifdef HAVE_GETGROUPLIST /* AC 3.5: funny apple logic below */ @@ -6734,13 +6741,6 @@ Returns a list of groups to which a user belongs.\n\n\ static PyObject * posix_getgrouplist(PyObject *self, PyObject *args) { -#ifdef NGROUPS_MAX -#define MAX_GROUPS NGROUPS_MAX -#else - /* defined to be 16 on Solaris7, so this should be a small number */ -#define MAX_GROUPS 64 -#endif - const char *user; int i, ngroups; PyObject *list; @@ -6749,7 +6749,16 @@ posix_getgrouplist(PyObject *self, PyObject *args) #else gid_t *groups, basegid; #endif - ngroups = MAX_GROUPS; + + /* + * NGROUPS_MAX is defined by POSIX.1 as the maximum + * number of supplimental groups a users can belong to. + * We have to increment it by one because + * getgrouplist() returns both the supplemental groups + * and the primary group, i.e. all of the groups the + * user belongs to. + */ + ngroups = 1 + MAX_GROUPS; #ifdef __APPLE__ if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid)) @@ -6818,13 +6827,6 @@ os_getgroups_impl(PyObject *module) /*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/ { PyObject *result = NULL; - -#ifdef NGROUPS_MAX -#define MAX_GROUPS NGROUPS_MAX -#else - /* defined to be 16 on Solaris7, so this should be a small number */ -#define MAX_GROUPS 64 -#endif gid_t grouplist[MAX_GROUPS]; /* On MacOSX getgroups(2) can return more than MAX_GROUPS results From 022ac0a497b668d8b15e34e582a6396ead1a35e1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 09:18:45 +0200 Subject: [PATCH 398/441] bpo-37253: Remove PyAST_obj2mod_ex() function (GH-14020) PyAST_obj2mod_ex() is similar to PyAST_obj2mod() with an additional 'feature_version' parameter which is unused. --- Include/Python-ast.h | 1 - Parser/asdl_c.py | 6 ------ Python/Python-ast.c | 5 ----- 3 files changed, 12 deletions(-) diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 490d3b0846abe7..62626503403ba2 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -707,7 +707,6 @@ type_ignore_ty _Py_TypeIgnore(int lineno, string tag, PyArena *arena); PyObject* PyAST_mod2obj(mod_ty t); mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); -mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_version); int PyAST_Check(PyObject* obj); #ifdef __cplusplus diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 582c6ca57b65c4..f4fa271b6595bf 100644 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1190,11 +1190,6 @@ class PartingShots(StaticVisitor): /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) -{ - return PyAST_obj2mod_ex(ast, arena, mode, PY_MINOR_VERSION); -} - -mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_version) { mod_ty res; PyObject *req_type[3]; @@ -1280,7 +1275,6 @@ def main(srcfile, dump_module=False): f.write("\n") f.write("PyObject* PyAST_mod2obj(mod_ty t);\n") f.write("mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);\n") - f.write("mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_version);\n") f.write("int PyAST_Check(PyObject* obj);\n") f.write('\n') f.write('#ifdef __cplusplus\n') diff --git a/Python/Python-ast.c b/Python/Python-ast.c index dc2b1304f1f20b..0774c58e2d23f2 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -8990,11 +8990,6 @@ PyObject* PyAST_mod2obj(mod_ty t) /* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) -{ - return PyAST_obj2mod_ex(ast, arena, mode, PY_MINOR_VERSION); -} - -mod_ty PyAST_obj2mod_ex(PyObject* ast, PyArena* arena, int mode, int feature_version) { mod_ty res; PyObject *req_type[3]; From b4b814b3988abf69f07f8492d82e855c51b2a75d Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Thu, 13 Jun 2019 11:26:44 +0200 Subject: [PATCH 399/441] bpo-37231: optimize calls of special methods (GH-13973) --- .../2019-06-12-14-39-16.bpo-37231.LF41Es.rst | 2 + Objects/typeobject.c | 158 ++++++++++-------- 2 files changed, 88 insertions(+), 72 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-37231.LF41Es.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-37231.LF41Es.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-37231.LF41Es.rst new file mode 100644 index 00000000000000..2e277194f3c2d0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-12-14-39-16.bpo-37231.LF41Es.rst @@ -0,0 +1,2 @@ +The dispatching of type slots to special methods (for example calling +``__mul__`` when doing ``x * y``) has been made faster. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 006df8d1f090d5..ba128a90778c65 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1440,16 +1440,19 @@ lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound) return res; } -static PyObject* -call_unbound(int unbound, PyObject *func, PyObject *self, - PyObject **args, Py_ssize_t nargs) + +static inline PyObject* +vectorcall_unbound(int unbound, PyObject *func, + PyObject *const *args, Py_ssize_t nargs) { - if (unbound) { - return _PyObject_FastCall_Prepend(func, self, args, nargs); - } - else { - return _PyObject_FastCall(func, args, nargs); + size_t nargsf = nargs; + if (!unbound) { + /* Skip self argument, freeing up args[0] to use for + * PY_VECTORCALL_ARGUMENTS_OFFSET */ + args++; + nargsf = nargsf - 1 + PY_VECTORCALL_ARGUMENTS_OFFSET; } + return _PyObject_Vectorcall(func, args, nargsf, NULL); } static PyObject* @@ -1464,41 +1467,43 @@ call_unbound_noarg(int unbound, PyObject *func, PyObject *self) } } -/* A variation of PyObject_CallMethod* that uses lookup_maybe_method() - instead of PyObject_GetAttrString(). */ +/* A variation of PyObject_CallMethod* that uses lookup_method() + instead of PyObject_GetAttrString(). + + args is an argument vector of length nargs. The first element in this + vector is the special object "self" which is used for the method lookup */ static PyObject * -call_method(PyObject *obj, _Py_Identifier *name, - PyObject **args, Py_ssize_t nargs) +vectorcall_method(_Py_Identifier *name, + PyObject *const *args, Py_ssize_t nargs) { + assert(nargs >= 1); int unbound; - PyObject *func, *retval; - - func = lookup_method(obj, name, &unbound); + PyObject *self = args[0]; + PyObject *func = lookup_method(self, name, &unbound); if (func == NULL) { return NULL; } - retval = call_unbound(unbound, func, obj, args, nargs); + PyObject *retval = vectorcall_unbound(unbound, func, args, nargs); Py_DECREF(func); return retval; } -/* Clone of call_method() that returns NotImplemented when the lookup fails. */ - +/* Clone of vectorcall_method() that returns NotImplemented + * when the lookup fails. */ static PyObject * -call_maybe(PyObject *obj, _Py_Identifier *name, - PyObject **args, Py_ssize_t nargs) +vectorcall_maybe(_Py_Identifier *name, + PyObject *const *args, Py_ssize_t nargs) { + assert(nargs >= 1); int unbound; - PyObject *func, *retval; - - func = lookup_maybe_method(obj, name, &unbound); + PyObject *self = args[0]; + PyObject *func = lookup_maybe_method(self, name, &unbound); if (func == NULL) { if (!PyErr_Occurred()) Py_RETURN_NOTIMPLEMENTED; return NULL; } - - retval = call_unbound(unbound, func, obj, args, nargs); + PyObject *retval = vectorcall_unbound(unbound, func, args, nargs); Py_DECREF(func); return retval; } @@ -6084,17 +6089,18 @@ add_tp_new_wrapper(PyTypeObject *type) static PyObject * \ FUNCNAME(PyObject *self) \ { \ + PyObject* stack[1] = {self}; \ _Py_static_string(id, OPSTR); \ - return call_method(self, &id, NULL, 0); \ + return vectorcall_method(&id, stack, 1); \ } #define SLOT1(FUNCNAME, OPSTR, ARG1TYPE) \ static PyObject * \ FUNCNAME(PyObject *self, ARG1TYPE arg1) \ { \ - PyObject* stack[1] = {arg1}; \ + PyObject* stack[2] = {self, arg1}; \ _Py_static_string(id, OPSTR); \ - return call_method(self, &id, stack, 1); \ + return vectorcall_method(&id, stack, 2); \ } /* Boolean helper for SLOT1BINFULL(). @@ -6136,7 +6142,7 @@ method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *nam static PyObject * \ FUNCNAME(PyObject *self, PyObject *other) \ { \ - PyObject* stack[1]; \ + PyObject* stack[2]; \ _Py_static_string(op_id, OPSTR); \ _Py_static_string(rop_id, ROPSTR); \ int do_other = Py_TYPE(self) != Py_TYPE(other) && \ @@ -6148,23 +6154,26 @@ FUNCNAME(PyObject *self, PyObject *other) \ if (do_other && \ PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) && \ method_is_overloaded(self, other, &rop_id)) { \ - stack[0] = self; \ - r = call_maybe(other, &rop_id, stack, 1); \ + stack[0] = other; \ + stack[1] = self; \ + r = vectorcall_maybe(&rop_id, stack, 2); \ if (r != Py_NotImplemented) \ return r; \ Py_DECREF(r); \ do_other = 0; \ } \ - stack[0] = other; \ - r = call_maybe(self, &op_id, stack, 1); \ + stack[0] = self; \ + stack[1] = other; \ + r = vectorcall_maybe(&op_id, stack, 2); \ if (r != Py_NotImplemented || \ Py_TYPE(other) == Py_TYPE(self)) \ return r; \ Py_DECREF(r); \ } \ if (do_other) { \ - stack[0] = self; \ - return call_maybe(other, &rop_id, stack, 1); \ + stack[0] = other; \ + stack[1] = self; \ + return vectorcall_maybe(&rop_id, stack, 2); \ } \ Py_RETURN_NOTIMPLEMENTED; \ } @@ -6175,7 +6184,8 @@ FUNCNAME(PyObject *self, PyObject *other) \ static Py_ssize_t slot_sq_length(PyObject *self) { - PyObject *res = call_method(self, &PyId___len__, NULL, 0); + PyObject* stack[1] = {self}; + PyObject *res = vectorcall_method(&PyId___len__, stack, 1); Py_ssize_t len; if (res == NULL) @@ -6202,14 +6212,12 @@ slot_sq_length(PyObject *self) static PyObject * slot_sq_item(PyObject *self, Py_ssize_t i) { - PyObject *retval; - PyObject *args[1]; PyObject *ival = PyLong_FromSsize_t(i); if (ival == NULL) { return NULL; } - args[0] = ival; - retval = call_method(self, &PyId___getitem__, args, 1); + PyObject *stack[2] = {self, ival}; + PyObject *retval = vectorcall_method(&PyId___getitem__, stack, 2); Py_DECREF(ival); return retval; } @@ -6217,7 +6225,7 @@ slot_sq_item(PyObject *self, Py_ssize_t i) static int slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) { - PyObject *stack[2]; + PyObject *stack[3]; PyObject *res; PyObject *index_obj; @@ -6226,13 +6234,14 @@ slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) return -1; } - stack[0] = index_obj; + stack[0] = self; + stack[1] = index_obj; if (value == NULL) { - res = call_method(self, &PyId___delitem__, stack, 1); + res = vectorcall_method(&PyId___delitem__, stack, 2); } else { - stack[1] = value; - res = call_method(self, &PyId___setitem__, stack, 2); + stack[2] = value; + res = vectorcall_method(&PyId___setitem__, stack, 3); } Py_DECREF(index_obj); @@ -6259,8 +6268,8 @@ slot_sq_contains(PyObject *self, PyObject *value) return -1; } if (func != NULL) { - PyObject *args[1] = {value}; - res = call_unbound(unbound, func, self, args, 1); + PyObject *args[2] = {self, value}; + res = vectorcall_unbound(unbound, func, args, 2); Py_DECREF(func); if (res != NULL) { result = PyObject_IsTrue(res); @@ -6282,16 +6291,17 @@ SLOT1(slot_mp_subscript, "__getitem__", PyObject *) static int slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { - PyObject *stack[2]; + PyObject *stack[3]; PyObject *res; - stack[0] = key; + stack[0] = self; + stack[1] = key; if (value == NULL) { - res = call_method(self, &PyId___delitem__, stack, 1); + res = vectorcall_method(&PyId___delitem__, stack, 2); } else { - stack[1] = value; - res = call_method(self, &PyId___setitem__, stack, 2); + stack[2] = value; + res = vectorcall_method(&PyId___setitem__, stack, 3); } if (res == NULL) @@ -6324,8 +6334,8 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) slot_nb_power, so check before calling self.__pow__. */ if (Py_TYPE(self)->tp_as_number != NULL && Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { - PyObject* stack[2] = {other, modulus}; - return call_method(self, &PyId___pow__, stack, 2); + PyObject* stack[3] = {self, other, modulus}; + return vectorcall_method(&PyId___pow__, stack, 3); } Py_RETURN_NOTIMPLEMENTED; } @@ -6392,7 +6402,8 @@ static PyObject * slot_nb_index(PyObject *self) { _Py_IDENTIFIER(__index__); - return call_method(self, &PyId___index__, NULL, 0); + PyObject *stack[1] = {self}; + return vectorcall_method(&PyId___index__, stack, 1); } @@ -6414,9 +6425,9 @@ SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *) static PyObject * slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) { - PyObject *stack[1] = {arg1}; + PyObject *stack[2] = {self, arg1}; _Py_IDENTIFIER(__ipow__); - return call_method(self, &PyId___ipow__, stack, 1); + return vectorcall_method(&PyId___ipow__, stack, 2); } SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *) SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *) @@ -6533,8 +6544,8 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * slot_tp_getattro(PyObject *self, PyObject *name) { - PyObject *stack[1] = {name}; - return call_method(self, &PyId___getattribute__, stack, 1); + PyObject *stack[2] = {self, name}; + return vectorcall_method(&PyId___getattribute__, stack, 2); } static PyObject * @@ -6601,18 +6612,19 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) static int slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) { - PyObject *stack[2]; + PyObject *stack[3]; PyObject *res; _Py_IDENTIFIER(__delattr__); _Py_IDENTIFIER(__setattr__); - stack[0] = name; + stack[0] = self; + stack[1] = name; if (value == NULL) { - res = call_method(self, &PyId___delattr__, stack, 1); + res = vectorcall_method(&PyId___delattr__, stack, 2); } else { - stack[1] = value; - res = call_method(self, &PyId___setattr__, stack, 2); + stack[2] = value; + res = vectorcall_method(&PyId___setattr__, stack, 3); } if (res == NULL) return -1; @@ -6641,8 +6653,8 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_NOTIMPLEMENTED; } - PyObject *args[1] = {other}; - res = call_unbound(unbound, func, self, args, 1); + PyObject *stack[2] = {self, other}; + res = vectorcall_unbound(unbound, func, stack, 2); Py_DECREF(func); return res; } @@ -6685,7 +6697,8 @@ static PyObject * slot_tp_iternext(PyObject *self) { _Py_IDENTIFIER(__next__); - return call_method(self, &PyId___next__, NULL, 0); + PyObject *stack[1] = {self}; + return vectorcall_method(&PyId___next__, stack, 1); } static PyObject * @@ -6713,18 +6726,19 @@ slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type) static int slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) { - PyObject* stack[2]; + PyObject* stack[3]; PyObject *res; _Py_IDENTIFIER(__delete__); _Py_IDENTIFIER(__set__); - stack[0] = target; + stack[0] = self; + stack[1] = target; if (value == NULL) { - res = call_method(self, &PyId___delete__, stack, 1); + res = vectorcall_method(&PyId___delete__, stack, 2); } else { - stack[1] = value; - res = call_method(self, &PyId___set__, stack, 2); + stack[2] = value; + res = vectorcall_method(&PyId___set__, stack, 3); } if (res == NULL) return -1; From 6f75c873752a16a7ad8f35855b1e29f59d048e84 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 12:06:24 +0200 Subject: [PATCH 400/441] tbpo-36402: Fix threading.Thread._stop() (GH-14047) Remove the _tstate_lock from _shutdown_locks, don't remove None. --- Lib/test/test_threading.py | 24 ++++++++++++++++++++++++ Lib/threading.py | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index ad90010b8a3821..0a0a62bdf9bfaf 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -738,6 +738,30 @@ def callback(): finally: sys.settrace(old_trace) + @cpython_only + def test_shutdown_locks(self): + for daemon in (False, True): + with self.subTest(daemon=daemon): + event = threading.Event() + thread = threading.Thread(target=event.wait, daemon=daemon) + + # Thread.start() must add lock to _shutdown_locks, + # but only for non-daemon thread + thread.start() + tstate_lock = thread._tstate_lock + if not daemon: + self.assertIn(tstate_lock, threading._shutdown_locks) + else: + self.assertNotIn(tstate_lock, threading._shutdown_locks) + + # unblock the thread and join it + event.set() + thread.join() + + # Thread._stop() must remove tstate_lock from _shutdown_locks. + # Daemon threads must never add it to _shutdown_locks. + self.assertNotIn(tstate_lock, threading._shutdown_locks) + class ThreadJoinOnShutdown(BaseTestCase): diff --git a/Lib/threading.py b/Lib/threading.py index 67926403770e62..7c6d404bcd10f6 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -965,7 +965,7 @@ def _stop(self): self._tstate_lock = None if not self.daemon: with _shutdown_locks_lock: - _shutdown_locks.discard(self._tstate_lock) + _shutdown_locks.discard(lock) def _delete(self): "Remove current thread from the dict of currently running threads." From 63ab4ba07b492448844940c347787ba30735b7f2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 13:58:51 +0200 Subject: [PATCH 401/441] bpo-37210: Fix pure Python pickle when _pickle is unavailable (GH-14016) Allow pure Python implementation of pickle to work even when the C _pickle module is unavailable. Fix test_pickle when _pickle is missing: declare PyPicklerHookTests outside "if has_c_implementation:" block. --- Lib/pickle.py | 59 +++++++++++-------- Lib/test/test_pickle.py | 13 ++-- .../2019-06-12-16-10-50.bpo-37210.r4yMg6.rst | 1 + 3 files changed, 41 insertions(+), 32 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst diff --git a/Lib/pickle.py b/Lib/pickle.py index a67ac7dd8b686a..71aa57d500ecce 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -36,10 +36,16 @@ import codecs import _compat_pickle -from _pickle import PickleBuffer - __all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", - "Unpickler", "dump", "dumps", "load", "loads", "PickleBuffer"] + "Unpickler", "dump", "dumps", "load", "loads"] + +try: + from _pickle import PickleBuffer + __all__.append("PickleBuffer") + _HAVE_PICKLE_BUFFER = True +except ImportError: + _HAVE_PICKLE_BUFFER = False + # Shortcut for use in isinstance testing bytes_types = (bytes, bytearray) @@ -812,31 +818,32 @@ def save_bytearray(self, obj): self.write(BYTEARRAY8 + pack("= 5") - with obj.raw() as m: - if not m.contiguous: - raise PicklingError("PickleBuffer can not be pickled when " - "pointing to a non-contiguous buffer") - in_band = True - if self._buffer_callback is not None: - in_band = bool(self._buffer_callback(obj)) - if in_band: - # Write data in-band - # XXX The C implementation avoids a copy here - if m.readonly: - self.save_bytes(m.tobytes()) + if _HAVE_PICKLE_BUFFER: + def save_picklebuffer(self, obj): + if self.proto < 5: + raise PicklingError("PickleBuffer can only pickled with " + "protocol >= 5") + with obj.raw() as m: + if not m.contiguous: + raise PicklingError("PickleBuffer can not be pickled when " + "pointing to a non-contiguous buffer") + in_band = True + if self._buffer_callback is not None: + in_band = bool(self._buffer_callback(obj)) + if in_band: + # Write data in-band + # XXX The C implementation avoids a copy here + if m.readonly: + self.save_bytes(m.tobytes()) + else: + self.save_bytearray(m.tobytes()) else: - self.save_bytearray(m.tobytes()) - else: - # Write data out-of-band - self.write(NEXT_BUFFER) - if m.readonly: - self.write(READONLY_BUFFER) + # Write data out-of-band + self.write(NEXT_BUFFER) + if m.readonly: + self.write(READONLY_BUFFER) - dispatch[PickleBuffer] = save_picklebuffer + dispatch[PickleBuffer] = save_picklebuffer def save_str(self, obj): if self.bin: diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 5f7a879b935d92..2307b133dbd0d5 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -203,6 +203,13 @@ def get_dispatch_table(self): return collections.ChainMap({}, pickle.dispatch_table) +class PyPicklerHookTests(AbstractHookTests): + class CustomPyPicklerClass(pickle._Pickler, + AbstractCustomPicklerClass): + pass + pickler_class = CustomPyPicklerClass + + if has_c_implementation: class CPickleTests(AbstractPickleModuleTests): from _pickle import dump, dumps, load, loads, Pickler, Unpickler @@ -255,12 +262,6 @@ class CChainDispatchTableTests(AbstractDispatchTableTests): def get_dispatch_table(self): return collections.ChainMap({}, pickle.dispatch_table) - class PyPicklerHookTests(AbstractHookTests): - class CustomPyPicklerClass(pickle._Pickler, - AbstractCustomPicklerClass): - pass - pickler_class = CustomPyPicklerClass - class CPicklerHookTests(AbstractHookTests): class CustomCPicklerClass(_pickle.Pickler, AbstractCustomPicklerClass): pass diff --git a/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst b/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst new file mode 100644 index 00000000000000..58fc66b59059d4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-12-16-10-50.bpo-37210.r4yMg6.rst @@ -0,0 +1 @@ +Allow pure Python implementation of :mod:`pickle` to work even when the C :mod:`_pickle` module is unavailable. From 6d22cc8e90ccb1e1965b1a4bc79456e2cc1e5a3e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 14:44:54 +0200 Subject: [PATCH 402/441] bpo-37261: Fix support.catch_unraisable_exception() (GH-14052) The __exit__() method of test.support.catch_unraisable_exception context manager now ignores unraisable exception raised when clearing self.unraisable attribute. --- Doc/library/test.rst | 12 ++++++++++ Lib/test/support/__init__.py | 22 +++++++++++++++++-- .../2019-06-13-12-19-56.bpo-37261.NuKFVo.rst | 3 +++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst diff --git a/Doc/library/test.rst b/Doc/library/test.rst index b7a2595708d0ce..0a98c882465d85 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1086,6 +1086,18 @@ The :mod:`test.support` module defines the following functions: Context manager catching unraisable exception using :func:`sys.unraisablehook`. + If the *object* attribute of the unraisable hook is set and the object is + being finalized, the object is resurrected because the context manager + stores a strong reference to it (``cm.unraisable.object``). + + Storing the exception value (``cm.unraisable.exc_value``) creates a + reference cycle. The reference cycle is broken explicitly when the context + manager exits. + + Exiting the context manager clears the stored unraisable exception. It can + trigger a new unraisable exception (ex: the resurrected object is finalized + again and raises the same exception): it is silently ignored in this case. + Usage:: with support.catch_unraisable_exception() as cm: diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index d6ed2215f38340..174e0456dc7104 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3040,6 +3040,18 @@ class catch_unraisable_exception: """ Context manager catching unraisable exception using sys.unraisablehook. + If the *object* attribute of the unraisable hook is set and the object is + being finalized, the object is resurrected because the context manager + stores a strong reference to it (cm.unraisable.object). + + Storing the exception value (cm.unraisable.exc_value) creates a reference + cycle. The reference cycle is broken explicitly when the context manager + exits. + + Exiting the context manager clears the stored unraisable exception. It can + trigger a new unraisable exception (ex: the resurrected object is finalized + again and raises the same exception): it is silently ignored in this case. + Usage: with support.catch_unraisable_exception() as cm: @@ -3058,6 +3070,8 @@ def __init__(self): self._old_hook = None def _hook(self, unraisable): + # Storing unraisable.object can resurrect an object which is being + # finalized. Storing unraisable.exc_value creates a reference cycle. self.unraisable = unraisable def __enter__(self): @@ -3066,6 +3080,10 @@ def __enter__(self): return self def __exit__(self, *exc_info): - # Clear the unraisable exception to explicitly break a reference cycle - del self.unraisable + # Clear the unraisable exception to explicitly break a reference cycle. + # It can call _hook() again: ignore the new unraisable exception in + # this case. + self.unraisable = None + sys.unraisablehook = self._old_hook + del self.unraisable diff --git a/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst b/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst new file mode 100644 index 00000000000000..27ce78a70f2bfe --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-06-13-12-19-56.bpo-37261.NuKFVo.rst @@ -0,0 +1,3 @@ +Fix :func:`test.support.catch_unraisable_exception`: its __exit__() method +now ignores unraisable exception raised when clearing its ``unraisable`` +attribute. From 95492032c48fef20b9c7076a23fe7e46927a4688 Mon Sep 17 00:00:00 2001 From: Makdon Date: Thu, 13 Jun 2019 21:59:49 +0800 Subject: [PATCH 403/441] bpo-6689: os.path.commonpath raises ValueError for different drives isn't documented (GH-14045) It would raise ValueError("Paths don't have the same drive") if the paths on different drivers, which is not documented. os.path.commonpath raises ValueError when the *paths* are in different drivers, but it is not documented. Update the document according @Windsooon 's suggestion. It actually raise ValueError according line 355 of [test of path](https://github.com/python/cpython/blob/master/Lib/test/test_ntpath.py) https://bugs.python.org/issue6689 --- Doc/library/os.path.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 8e7ee8bfe7845f..a673b81278ea74 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -87,9 +87,10 @@ the :mod:`glob` module.) .. function:: commonpath(paths) Return the longest common sub-path of each pathname in the sequence - *paths*. Raise :exc:`ValueError` if *paths* contains both absolute and relative - pathnames, or if *paths* is empty. Unlike :func:`commonprefix`, this - returns a valid path. + *paths*. Raise :exc:`ValueError` if *paths* contain both absolute + and relative pathnames, the *paths* are on the different drives or + if *paths* is empty. Unlike :func:`commonprefix`, this returns a + valid path. .. availability:: Unix, Windows. From 3498c642f4e83f3d8e2214654c0fa8e0d51cebe5 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 13 Jun 2019 19:16:22 +0100 Subject: [PATCH 404/441] bpo-37213: Handle negative line deltas correctly in the peephole optimizer (GH-13969) The peephole optimizer was not optimizing correctly bytecode after negative deltas were introduced. This is due to the fact that some special values (255) were being searched for in both instruction pointer delta and line number deltas. --- Lib/test/test_peepholer.py | 81 +- .../2019-06-11-11-15-19.bpo-37213.UPii5K.rst | 2 + Python/importlib.h | 2213 ++++--- Python/importlib_external.h | 5472 ++++++++--------- Python/importlib_zipimport.h | 592 +- Python/peephole.c | 14 +- 6 files changed, 4229 insertions(+), 4145 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K.rst diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 794d104d5919bd..860ceeb003e7b3 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -1,5 +1,7 @@ import dis import unittest +import types +import textwrap from test.bytecode_helper import BytecodeTestCase @@ -18,6 +20,27 @@ def count_instr_recursively(f, opname): class TestTranforms(BytecodeTestCase): + def check_jump_targets(self, code): + instructions = list(dis.get_instructions(code)) + targets = {instr.offset: instr for instr in instructions} + for instr in instructions: + if 'JUMP_' not in instr.opname: + continue + tgt = targets[instr.argval] + # jump to unconditional jump + if tgt.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD'): + self.fail(f'{instr.opname} at {instr.offset} ' + f'jumps to {tgt.opname} at {tgt.offset}') + # unconditional jump to RETURN_VALUE + if (instr.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD') and + tgt.opname == 'RETURN_VALUE'): + self.fail(f'{instr.opname} at {instr.offset} ' + f'jumps to {tgt.opname} at {tgt.offset}') + # JUMP_IF_*_OR_POP jump to conditional jump + if '_OR_POP' in instr.opname and 'JUMP_IF_' in tgt.opname: + self.fail(f'{instr.opname} at {instr.offset} ' + f'jumps to {tgt.opname} at {tgt.offset}') + def test_unot(self): # UNARY_NOT POP_JUMP_IF_FALSE --> POP_JUMP_IF_TRUE' def unot(x): @@ -259,13 +282,69 @@ def f(x): def test_elim_jump_to_return(self): # JUMP_FORWARD to RETURN --> RETURN def f(cond, true_value, false_value): - return true_value if cond else false_value + # Intentionally use two-line expression to test issue37213. + return (true_value if cond + else false_value) + self.check_jump_targets(f) self.assertNotInBytecode(f, 'JUMP_FORWARD') self.assertNotInBytecode(f, 'JUMP_ABSOLUTE') returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertEqual(len(returns), 2) + def test_elim_jump_to_uncond_jump(self): + # POP_JUMP_IF_FALSE to JUMP_FORWARD --> POP_JUMP_IF_FALSE to non-jump + def f(): + if a: + # Intentionally use two-line expression to test issue37213. + if (c + or d): + foo() + else: + baz() + self.check_jump_targets(f) + + def test_elim_jump_to_uncond_jump2(self): + # POP_JUMP_IF_FALSE to JUMP_ABSOLUTE --> POP_JUMP_IF_FALSE to non-jump + def f(): + while a: + # Intentionally use two-line expression to test issue37213. + if (c + or d): + a = foo() + self.check_jump_targets(f) + + def test_elim_jump_to_uncond_jump3(self): + # Intentionally use two-line expressions to test issue37213. + # JUMP_IF_FALSE_OR_POP to JUMP_IF_FALSE_OR_POP --> JUMP_IF_FALSE_OR_POP to non-jump + def f(a, b, c): + return ((a and b) + and c) + self.check_jump_targets(f) + self.assertEqual(count_instr_recursively(f, 'JUMP_IF_FALSE_OR_POP'), 2) + # JUMP_IF_TRUE_OR_POP to JUMP_IF_TRUE_OR_POP --> JUMP_IF_TRUE_OR_POP to non-jump + def f(a, b, c): + return ((a or b) + or c) + self.check_jump_targets(f) + self.assertEqual(count_instr_recursively(f, 'JUMP_IF_TRUE_OR_POP'), 2) + # JUMP_IF_FALSE_OR_POP to JUMP_IF_TRUE_OR_POP --> POP_JUMP_IF_FALSE to non-jump + def f(a, b, c): + return ((a and b) + or c) + self.check_jump_targets(f) + self.assertNotInBytecode(f, 'JUMP_IF_FALSE_OR_POP') + self.assertInBytecode(f, 'JUMP_IF_TRUE_OR_POP') + self.assertInBytecode(f, 'POP_JUMP_IF_FALSE') + # JUMP_IF_TRUE_OR_POP to JUMP_IF_FALSE_OR_POP --> POP_JUMP_IF_TRUE to non-jump + def f(a, b, c): + return ((a or b) + and c) + self.check_jump_targets(f) + self.assertNotInBytecode(f, 'JUMP_IF_TRUE_OR_POP') + self.assertInBytecode(f, 'JUMP_IF_FALSE_OR_POP') + self.assertInBytecode(f, 'POP_JUMP_IF_TRUE') + def test_elim_jump_after_return1(self): # Eliminate dead code: jumps immediately after returns can't be reached def f(cond1, cond2): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K.rst new file mode 100644 index 00000000000000..b949883da9c2b3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-11-11-15-19.bpo-37213.UPii5K.rst @@ -0,0 +1,2 @@ +Handle correctly negative line offsets in the peephole optimizer. Patch by +Pablo Galindo. diff --git a/Python/importlib.h b/Python/importlib.h index 5bd1d179e2f0c8..a285a31e20653e 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -670,1121 +670,1120 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 1,18,1,10,1,8,1,4,255,6,2,122,19,77,111,100, 117,108,101,83,112,101,99,46,95,95,114,101,112,114,95,95, 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,8,0,0,0,67,0,0,0,115,114,0,0,0,124,0, - 106,0,125,2,122,76,124,0,106,1,124,1,106,1,107,2, + 0,8,0,0,0,67,0,0,0,115,106,0,0,0,124,0, + 106,0,125,2,122,72,124,0,106,1,124,1,106,1,107,2, 111,76,124,0,106,2,124,1,106,2,107,2,111,76,124,0, 106,3,124,1,106,3,107,2,111,76,124,2,124,1,106,0, 107,2,111,76,124,0,106,4,124,1,106,4,107,2,111,76, - 124,0,106,5,124,1,106,5,107,2,87,0,83,0,87,0, - 110,26,4,0,116,6,107,10,114,108,1,0,1,0,1,0, - 89,0,100,1,83,0,89,0,110,2,88,0,100,0,83,0, - 114,116,0,0,0,41,7,114,117,0,0,0,114,17,0,0, - 0,114,109,0,0,0,114,113,0,0,0,218,6,99,97,99, - 104,101,100,218,12,104,97,115,95,108,111,99,97,116,105,111, - 110,114,106,0,0,0,41,3,114,30,0,0,0,90,5,111, - 116,104,101,114,90,4,115,109,115,108,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,6,95,95,101,113,95, - 95,108,1,0,0,115,30,0,0,0,0,1,6,1,2,1, - 12,1,10,255,2,2,10,254,2,3,8,253,2,4,10,252, - 2,5,10,251,8,6,14,1,122,17,77,111,100,117,108,101, - 83,112,101,99,46,95,95,101,113,95,95,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, - 67,0,0,0,115,58,0,0,0,124,0,106,0,100,0,107, - 8,114,52,124,0,106,1,100,0,107,9,114,52,124,0,106, - 2,114,52,116,3,100,0,107,8,114,38,116,4,130,1,116, - 3,160,5,124,0,106,1,161,1,124,0,95,0,124,0,106, - 0,83,0,114,13,0,0,0,41,6,114,119,0,0,0,114, - 113,0,0,0,114,118,0,0,0,218,19,95,98,111,111,116, - 115,116,114,97,112,95,101,120,116,101,114,110,97,108,218,19, - 78,111,116,73,109,112,108,101,109,101,110,116,101,100,69,114, - 114,111,114,90,11,95,103,101,116,95,99,97,99,104,101,100, - 114,47,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,114,123,0,0,0,120,1,0,0,115,12,0, - 0,0,0,2,10,1,16,1,8,1,4,1,14,1,122,17, - 77,111,100,117,108,101,83,112,101,99,46,99,97,99,104,101, - 100,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,2,0,0,0,67,0,0,0,115,10,0,0,0,124, - 1,124,0,95,0,100,0,83,0,114,13,0,0,0,41,1, - 114,119,0,0,0,41,2,114,30,0,0,0,114,123,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,123,0,0,0,129,1,0,0,115,2,0,0,0,0,2, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,36,0,0,0,124,0, - 106,0,100,1,107,8,114,26,124,0,106,1,160,2,100,2, - 161,1,100,3,25,0,83,0,124,0,106,1,83,0,100,1, - 83,0,41,4,122,32,84,104,101,32,110,97,109,101,32,111, - 102,32,116,104,101,32,109,111,100,117,108,101,39,115,32,112, - 97,114,101,110,116,46,78,218,1,46,114,22,0,0,0,41, - 3,114,117,0,0,0,114,17,0,0,0,218,10,114,112,97, - 114,116,105,116,105,111,110,114,47,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,218,6,112,97,114, - 101,110,116,133,1,0,0,115,6,0,0,0,0,3,10,1, - 16,2,122,17,77,111,100,117,108,101,83,112,101,99,46,112, - 97,114,101,110,116,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,1,0,0,0,67,0,0,0,115,6, - 0,0,0,124,0,106,0,83,0,114,13,0,0,0,41,1, - 114,118,0,0,0,114,47,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,124,0,0,0,141,1, - 0,0,115,2,0,0,0,0,2,122,23,77,111,100,117,108, - 101,83,112,101,99,46,104,97,115,95,108,111,99,97,116,105, - 111,110,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,2,0,0,0,67,0,0,0,115,14,0,0,0, - 116,0,124,1,131,1,124,0,95,1,100,0,83,0,114,13, - 0,0,0,41,2,218,4,98,111,111,108,114,118,0,0,0, - 41,2,114,30,0,0,0,218,5,118,97,108,117,101,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,124,0, - 0,0,145,1,0,0,115,2,0,0,0,0,2,41,12,114, - 1,0,0,0,114,0,0,0,0,114,2,0,0,0,114,3, - 0,0,0,114,31,0,0,0,114,48,0,0,0,114,125,0, - 0,0,218,8,112,114,111,112,101,114,116,121,114,123,0,0, - 0,218,6,115,101,116,116,101,114,114,130,0,0,0,114,124, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,112,0,0,0,49,1,0,0, - 115,32,0,0,0,8,1,4,36,4,1,2,255,12,12,8, - 10,8,12,2,1,10,8,4,1,10,3,2,1,10,7,2, - 1,10,3,4,1,114,112,0,0,0,169,2,114,113,0,0, - 0,114,115,0,0,0,99,2,0,0,0,0,0,0,0,2, - 0,0,0,6,0,0,0,8,0,0,0,67,0,0,0,115, - 154,0,0,0,116,0,124,1,100,1,131,2,114,74,116,1, - 100,2,107,8,114,22,116,2,130,1,116,1,106,3,125,4, - 124,3,100,2,107,8,114,48,124,4,124,0,124,1,100,3, - 141,2,83,0,124,3,114,56,103,0,110,2,100,2,125,5, - 124,4,124,0,124,1,124,5,100,4,141,3,83,0,124,3, - 100,2,107,8,114,138,116,0,124,1,100,5,131,2,114,134, - 122,14,124,1,160,4,124,0,161,1,125,3,87,0,110,24, - 4,0,116,5,107,10,114,130,1,0,1,0,1,0,100,2, - 125,3,89,0,110,2,88,0,110,4,100,6,125,3,116,6, - 124,0,124,1,124,2,124,3,100,7,141,4,83,0,41,8, - 122,53,82,101,116,117,114,110,32,97,32,109,111,100,117,108, - 101,32,115,112,101,99,32,98,97,115,101,100,32,111,110,32, - 118,97,114,105,111,117,115,32,108,111,97,100,101,114,32,109, - 101,116,104,111,100,115,46,90,12,103,101,116,95,102,105,108, - 101,110,97,109,101,78,41,1,114,109,0,0,0,41,2,114, - 109,0,0,0,114,117,0,0,0,114,115,0,0,0,70,114, - 135,0,0,0,41,7,114,4,0,0,0,114,126,0,0,0, - 114,127,0,0,0,218,23,115,112,101,99,95,102,114,111,109, - 95,102,105,108,101,95,108,111,99,97,116,105,111,110,114,115, - 0,0,0,114,79,0,0,0,114,112,0,0,0,41,6,114, - 17,0,0,0,114,109,0,0,0,114,113,0,0,0,114,115, - 0,0,0,114,136,0,0,0,90,6,115,101,97,114,99,104, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 91,0,0,0,150,1,0,0,115,36,0,0,0,0,2,10, - 1,8,1,4,1,6,2,8,1,12,1,12,1,6,1,2, - 255,6,3,8,1,10,1,2,1,14,1,14,1,12,3,4, - 2,114,91,0,0,0,99,3,0,0,0,0,0,0,0,0, - 0,0,0,8,0,0,0,8,0,0,0,67,0,0,0,115, - 56,1,0,0,122,10,124,0,106,0,125,3,87,0,110,20, - 4,0,116,1,107,10,114,30,1,0,1,0,1,0,89,0, - 110,14,88,0,124,3,100,0,107,9,114,44,124,3,83,0, - 124,0,106,2,125,4,124,1,100,0,107,8,114,90,122,10, - 124,0,106,3,125,1,87,0,110,20,4,0,116,1,107,10, - 114,88,1,0,1,0,1,0,89,0,110,2,88,0,122,10, - 124,0,106,4,125,5,87,0,110,24,4,0,116,1,107,10, - 114,124,1,0,1,0,1,0,100,0,125,5,89,0,110,2, - 88,0,124,2,100,0,107,8,114,184,124,5,100,0,107,8, - 114,180,122,10,124,1,106,5,125,2,87,0,113,184,4,0, - 116,1,107,10,114,176,1,0,1,0,1,0,100,0,125,2, - 89,0,113,184,88,0,110,4,124,5,125,2,122,10,124,0, - 106,6,125,6,87,0,110,24,4,0,116,1,107,10,114,218, - 1,0,1,0,1,0,100,0,125,6,89,0,110,2,88,0, - 122,14,116,7,124,0,106,8,131,1,125,7,87,0,110,26, - 4,0,116,1,107,10,144,1,114,4,1,0,1,0,1,0, - 100,0,125,7,89,0,110,2,88,0,116,9,124,4,124,1, - 124,2,100,1,141,3,125,3,124,5,100,0,107,8,144,1, - 114,34,100,2,110,2,100,3,124,3,95,10,124,6,124,3, - 95,11,124,7,124,3,95,12,124,3,83,0,41,4,78,169, - 1,114,113,0,0,0,70,84,41,13,114,105,0,0,0,114, - 106,0,0,0,114,1,0,0,0,114,98,0,0,0,114,108, - 0,0,0,218,7,95,79,82,73,71,73,78,218,10,95,95, - 99,97,99,104,101,100,95,95,218,4,108,105,115,116,218,8, - 95,95,112,97,116,104,95,95,114,112,0,0,0,114,118,0, - 0,0,114,123,0,0,0,114,117,0,0,0,41,8,114,96, - 0,0,0,114,109,0,0,0,114,113,0,0,0,114,95,0, - 0,0,114,17,0,0,0,90,8,108,111,99,97,116,105,111, - 110,114,123,0,0,0,114,117,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,17,95,115,112,101, - 99,95,102,114,111,109,95,109,111,100,117,108,101,176,1,0, - 0,115,72,0,0,0,0,2,2,1,10,1,14,1,6,2, - 8,1,4,2,6,1,8,1,2,1,10,1,14,2,6,1, - 2,1,10,1,14,1,10,1,8,1,8,1,2,1,10,1, - 14,1,12,2,4,1,2,1,10,1,14,1,10,1,2,1, - 14,1,16,1,10,2,14,1,20,1,6,1,6,1,114,142, - 0,0,0,70,169,1,218,8,111,118,101,114,114,105,100,101, - 99,2,0,0,0,0,0,0,0,1,0,0,0,5,0,0, - 0,8,0,0,0,67,0,0,0,115,226,1,0,0,124,2, - 115,20,116,0,124,1,100,1,100,0,131,3,100,0,107,8, - 114,54,122,12,124,0,106,1,124,1,95,2,87,0,110,20, - 4,0,116,3,107,10,114,52,1,0,1,0,1,0,89,0, - 110,2,88,0,124,2,115,74,116,0,124,1,100,2,100,0, - 131,3,100,0,107,8,114,178,124,0,106,4,125,3,124,3, - 100,0,107,8,114,146,124,0,106,5,100,0,107,9,114,146, - 116,6,100,0,107,8,114,110,116,7,130,1,116,6,106,8, - 125,4,124,4,160,9,124,4,161,1,125,3,124,0,106,5, - 124,3,95,10,124,3,124,0,95,4,100,0,124,1,95,11, - 122,10,124,3,124,1,95,12,87,0,110,20,4,0,116,3, - 107,10,114,176,1,0,1,0,1,0,89,0,110,2,88,0, - 124,2,115,198,116,0,124,1,100,3,100,0,131,3,100,0, - 107,8,114,232,122,12,124,0,106,13,124,1,95,14,87,0, - 110,20,4,0,116,3,107,10,114,230,1,0,1,0,1,0, - 89,0,110,2,88,0,122,10,124,0,124,1,95,15,87,0, - 110,22,4,0,116,3,107,10,144,1,114,8,1,0,1,0, - 1,0,89,0,110,2,88,0,124,2,144,1,115,34,116,0, - 124,1,100,4,100,0,131,3,100,0,107,8,144,1,114,82, - 124,0,106,5,100,0,107,9,144,1,114,82,122,12,124,0, - 106,5,124,1,95,16,87,0,110,22,4,0,116,3,107,10, - 144,1,114,80,1,0,1,0,1,0,89,0,110,2,88,0, - 124,0,106,17,144,1,114,222,124,2,144,1,115,114,116,0, - 124,1,100,5,100,0,131,3,100,0,107,8,144,1,114,150, - 122,12,124,0,106,18,124,1,95,11,87,0,110,22,4,0, - 116,3,107,10,144,1,114,148,1,0,1,0,1,0,89,0, - 110,2,88,0,124,2,144,1,115,174,116,0,124,1,100,6, - 100,0,131,3,100,0,107,8,144,1,114,222,124,0,106,19, - 100,0,107,9,144,1,114,222,122,12,124,0,106,19,124,1, - 95,20,87,0,110,22,4,0,116,3,107,10,144,1,114,220, - 1,0,1,0,1,0,89,0,110,2,88,0,124,1,83,0, - 41,7,78,114,1,0,0,0,114,98,0,0,0,218,11,95, - 95,112,97,99,107,97,103,101,95,95,114,141,0,0,0,114, - 108,0,0,0,114,139,0,0,0,41,21,114,6,0,0,0, - 114,17,0,0,0,114,1,0,0,0,114,106,0,0,0,114, - 109,0,0,0,114,117,0,0,0,114,126,0,0,0,114,127, - 0,0,0,218,16,95,78,97,109,101,115,112,97,99,101,76, - 111,97,100,101,114,218,7,95,95,110,101,119,95,95,90,5, - 95,112,97,116,104,114,108,0,0,0,114,98,0,0,0,114, - 130,0,0,0,114,145,0,0,0,114,105,0,0,0,114,141, - 0,0,0,114,124,0,0,0,114,113,0,0,0,114,123,0, - 0,0,114,139,0,0,0,41,5,114,95,0,0,0,114,96, - 0,0,0,114,144,0,0,0,114,109,0,0,0,114,146,0, + 124,0,106,5,124,1,106,5,107,2,87,0,83,0,4,0, + 116,6,107,10,114,100,1,0,1,0,1,0,89,0,100,1, + 83,0,88,0,100,0,83,0,114,116,0,0,0,41,7,114, + 117,0,0,0,114,17,0,0,0,114,109,0,0,0,114,113, + 0,0,0,218,6,99,97,99,104,101,100,218,12,104,97,115, + 95,108,111,99,97,116,105,111,110,114,106,0,0,0,41,3, + 114,30,0,0,0,90,5,111,116,104,101,114,90,4,115,109, + 115,108,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,6,95,95,101,113,95,95,108,1,0,0,115,30,0, + 0,0,0,1,6,1,2,1,12,1,10,255,2,2,10,254, + 2,3,8,253,2,4,10,252,2,5,10,251,4,6,14,1, + 122,17,77,111,100,117,108,101,83,112,101,99,46,95,95,101, + 113,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,67,0,0,0,115,58,0,0, + 0,124,0,106,0,100,0,107,8,114,52,124,0,106,1,100, + 0,107,9,114,52,124,0,106,2,114,52,116,3,100,0,107, + 8,114,38,116,4,130,1,116,3,160,5,124,0,106,1,161, + 1,124,0,95,0,124,0,106,0,83,0,114,13,0,0,0, + 41,6,114,119,0,0,0,114,113,0,0,0,114,118,0,0, + 0,218,19,95,98,111,111,116,115,116,114,97,112,95,101,120, + 116,101,114,110,97,108,218,19,78,111,116,73,109,112,108,101, + 109,101,110,116,101,100,69,114,114,111,114,90,11,95,103,101, + 116,95,99,97,99,104,101,100,114,47,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,123,0,0, + 0,120,1,0,0,115,12,0,0,0,0,2,10,1,16,1, + 8,1,4,1,14,1,122,17,77,111,100,117,108,101,83,112, + 101,99,46,99,97,99,104,101,100,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, + 0,0,115,10,0,0,0,124,1,124,0,95,0,100,0,83, + 0,114,13,0,0,0,41,1,114,119,0,0,0,41,2,114, + 30,0,0,0,114,123,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,123,0,0,0,129,1,0, + 0,115,2,0,0,0,0,2,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, + 0,115,36,0,0,0,124,0,106,0,100,1,107,8,114,26, + 124,0,106,1,160,2,100,2,161,1,100,3,25,0,83,0, + 124,0,106,1,83,0,100,1,83,0,41,4,122,32,84,104, + 101,32,110,97,109,101,32,111,102,32,116,104,101,32,109,111, + 100,117,108,101,39,115,32,112,97,114,101,110,116,46,78,218, + 1,46,114,22,0,0,0,41,3,114,117,0,0,0,114,17, + 0,0,0,218,10,114,112,97,114,116,105,116,105,111,110,114, + 47,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,6,112,97,114,101,110,116,133,1,0,0,115, + 6,0,0,0,0,3,10,1,16,2,122,17,77,111,100,117, + 108,101,83,112,101,99,46,112,97,114,101,110,116,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0, + 0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,83, + 0,114,13,0,0,0,41,1,114,118,0,0,0,114,47,0, 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,218,18,95,105,110,105,116,95,109,111,100,117,108,101,95, - 97,116,116,114,115,221,1,0,0,115,96,0,0,0,0,4, - 20,1,2,1,12,1,14,1,6,2,20,1,6,1,8,2, - 10,1,8,1,4,1,6,2,10,1,8,1,6,11,6,1, - 2,1,10,1,14,1,6,2,20,1,2,1,12,1,14,1, - 6,2,2,1,10,1,16,1,6,2,24,1,12,1,2,1, - 12,1,16,1,6,2,8,1,24,1,2,1,12,1,16,1, - 6,2,24,1,12,1,2,1,12,1,16,1,6,1,114,148, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,3,0,0,0,67,0,0,0,115,82,0,0, - 0,100,1,125,1,116,0,124,0,106,1,100,2,131,2,114, - 30,124,0,106,1,160,2,124,0,161,1,125,1,110,20,116, - 0,124,0,106,1,100,3,131,2,114,50,116,3,100,4,131, - 1,130,1,124,1,100,1,107,8,114,68,116,4,124,0,106, - 5,131,1,125,1,116,6,124,0,124,1,131,2,1,0,124, - 1,83,0,41,5,122,43,67,114,101,97,116,101,32,97,32, - 109,111,100,117,108,101,32,98,97,115,101,100,32,111,110,32, - 116,104,101,32,112,114,111,118,105,100,101,100,32,115,112,101, - 99,46,78,218,13,99,114,101,97,116,101,95,109,111,100,117, - 108,101,218,11,101,120,101,99,95,109,111,100,117,108,101,122, - 66,108,111,97,100,101,114,115,32,116,104,97,116,32,100,101, - 102,105,110,101,32,101,120,101,99,95,109,111,100,117,108,101, - 40,41,32,109,117,115,116,32,97,108,115,111,32,100,101,102, - 105,110,101,32,99,114,101,97,116,101,95,109,111,100,117,108, - 101,40,41,41,7,114,4,0,0,0,114,109,0,0,0,114, - 149,0,0,0,114,79,0,0,0,114,18,0,0,0,114,17, - 0,0,0,114,148,0,0,0,169,2,114,95,0,0,0,114, - 96,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,16,109,111,100,117,108,101,95,102,114,111,109, - 95,115,112,101,99,37,2,0,0,115,18,0,0,0,0,3, - 4,1,12,3,14,1,12,1,8,2,8,1,10,1,10,1, - 114,152,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,106, - 0,0,0,124,0,106,0,100,1,107,8,114,14,100,2,110, - 4,124,0,106,0,125,1,124,0,106,1,100,1,107,8,114, - 66,124,0,106,2,100,1,107,8,114,50,100,3,160,3,124, - 1,161,1,83,0,100,4,160,3,124,1,124,0,106,2,161, - 2,83,0,110,36,124,0,106,4,114,86,100,5,160,3,124, - 1,124,0,106,1,161,2,83,0,100,6,160,3,124,0,106, - 0,124,0,106,1,161,2,83,0,100,1,83,0,41,7,122, - 38,82,101,116,117,114,110,32,116,104,101,32,114,101,112,114, - 32,116,111,32,117,115,101,32,102,111,114,32,116,104,101,32, - 109,111,100,117,108,101,46,78,114,100,0,0,0,114,101,0, - 0,0,114,102,0,0,0,114,103,0,0,0,250,18,60,109, - 111,100,117,108,101,32,123,33,114,125,32,40,123,125,41,62, - 41,5,114,17,0,0,0,114,113,0,0,0,114,109,0,0, - 0,114,45,0,0,0,114,124,0,0,0,41,2,114,95,0, - 0,0,114,17,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,107,0,0,0,54,2,0,0,115, - 16,0,0,0,0,3,20,1,10,1,10,1,10,2,16,2, - 6,1,14,2,114,107,0,0,0,99,2,0,0,0,0,0, - 0,0,0,0,0,0,4,0,0,0,10,0,0,0,67,0, - 0,0,115,204,0,0,0,124,0,106,0,125,2,116,1,124, - 2,131,1,143,180,1,0,116,2,106,3,160,4,124,2,161, - 1,124,1,107,9,114,54,100,1,160,5,124,2,161,1,125, - 3,116,6,124,3,124,2,100,2,141,2,130,1,122,106,124, - 0,106,7,100,3,107,8,114,106,124,0,106,8,100,3,107, - 8,114,90,116,6,100,4,124,0,106,0,100,2,141,2,130, - 1,116,9,124,0,124,1,100,5,100,6,141,3,1,0,110, - 52,116,9,124,0,124,1,100,5,100,6,141,3,1,0,116, - 10,124,0,106,7,100,7,131,2,115,146,124,0,106,7,160, - 11,124,2,161,1,1,0,110,12,124,0,106,7,160,12,124, - 1,161,1,1,0,87,0,53,0,116,2,106,3,160,13,124, - 0,106,0,161,1,125,1,124,1,116,2,106,3,124,0,106, - 0,60,0,88,0,87,0,53,0,81,0,82,0,88,0,124, - 1,83,0,41,8,122,70,69,120,101,99,117,116,101,32,116, - 104,101,32,115,112,101,99,39,115,32,115,112,101,99,105,102, - 105,101,100,32,109,111,100,117,108,101,32,105,110,32,97,110, - 32,101,120,105,115,116,105,110,103,32,109,111,100,117,108,101, - 39,115,32,110,97,109,101,115,112,97,99,101,46,122,30,109, - 111,100,117,108,101,32,123,33,114,125,32,110,111,116,32,105, - 110,32,115,121,115,46,109,111,100,117,108,101,115,114,16,0, - 0,0,78,250,14,109,105,115,115,105,110,103,32,108,111,97, - 100,101,114,84,114,143,0,0,0,114,150,0,0,0,41,14, - 114,17,0,0,0,114,50,0,0,0,114,15,0,0,0,114, - 92,0,0,0,114,34,0,0,0,114,45,0,0,0,114,79, - 0,0,0,114,109,0,0,0,114,117,0,0,0,114,148,0, - 0,0,114,4,0,0,0,218,11,108,111,97,100,95,109,111, - 100,117,108,101,114,150,0,0,0,218,3,112,111,112,41,4, - 114,95,0,0,0,114,96,0,0,0,114,17,0,0,0,218, - 3,109,115,103,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,93,0,0,0,71,2,0,0,115,34,0,0, - 0,0,2,6,1,10,1,16,1,10,1,12,1,2,1,10, - 1,10,1,14,2,16,2,14,1,12,4,14,2,16,4,14, - 1,24,1,114,93,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,8,0,0,0,67,0,0, - 0,115,26,1,0,0,122,18,124,0,106,0,160,1,124,0, - 106,2,161,1,1,0,87,0,110,52,1,0,1,0,1,0, - 124,0,106,2,116,3,106,4,107,6,114,64,116,3,106,4, - 160,5,124,0,106,2,161,1,125,1,124,1,116,3,106,4, - 124,0,106,2,60,0,130,0,89,0,110,2,88,0,116,3, - 106,4,160,5,124,0,106,2,161,1,125,1,124,1,116,3, - 106,4,124,0,106,2,60,0,116,6,124,1,100,1,100,0, - 131,3,100,0,107,8,114,148,122,12,124,0,106,0,124,1, - 95,7,87,0,110,20,4,0,116,8,107,10,114,146,1,0, - 1,0,1,0,89,0,110,2,88,0,116,6,124,1,100,2, - 100,0,131,3,100,0,107,8,114,226,122,40,124,1,106,9, - 124,1,95,10,116,11,124,1,100,3,131,2,115,202,124,0, - 106,2,160,12,100,4,161,1,100,5,25,0,124,1,95,10, - 87,0,110,20,4,0,116,8,107,10,114,224,1,0,1,0, - 1,0,89,0,110,2,88,0,116,6,124,1,100,6,100,0, - 131,3,100,0,107,8,144,1,114,22,122,10,124,0,124,1, - 95,13,87,0,110,22,4,0,116,8,107,10,144,1,114,20, - 1,0,1,0,1,0,89,0,110,2,88,0,124,1,83,0, - 41,7,78,114,98,0,0,0,114,145,0,0,0,114,141,0, - 0,0,114,128,0,0,0,114,22,0,0,0,114,105,0,0, - 0,41,14,114,109,0,0,0,114,155,0,0,0,114,17,0, - 0,0,114,15,0,0,0,114,92,0,0,0,114,156,0,0, - 0,114,6,0,0,0,114,98,0,0,0,114,106,0,0,0, - 114,1,0,0,0,114,145,0,0,0,114,4,0,0,0,114, - 129,0,0,0,114,105,0,0,0,114,151,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,25,95, - 108,111,97,100,95,98,97,99,107,119,97,114,100,95,99,111, - 109,112,97,116,105,98,108,101,101,2,0,0,115,54,0,0, - 0,0,4,2,1,18,1,6,1,12,1,14,1,12,1,8, - 3,14,1,12,1,16,1,2,1,12,1,14,1,6,1,16, - 1,2,4,8,1,10,1,22,1,14,1,6,1,18,1,2, - 1,10,1,16,1,6,1,114,158,0,0,0,99,1,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,11,0,0, - 0,67,0,0,0,115,220,0,0,0,124,0,106,0,100,0, - 107,9,114,30,116,1,124,0,106,0,100,1,131,2,115,30, - 116,2,124,0,131,1,83,0,116,3,124,0,131,1,125,1, - 100,2,124,0,95,4,122,162,124,1,116,5,106,6,124,0, - 106,7,60,0,122,52,124,0,106,0,100,0,107,8,114,96, - 124,0,106,8,100,0,107,8,114,108,116,9,100,3,124,0, - 106,7,100,4,141,2,130,1,110,12,124,0,106,0,160,10, - 124,1,161,1,1,0,87,0,110,50,1,0,1,0,1,0, - 122,14,116,5,106,6,124,0,106,7,61,0,87,0,110,20, - 4,0,116,11,107,10,114,152,1,0,1,0,1,0,89,0, - 110,2,88,0,130,0,89,0,110,2,88,0,116,5,106,6, - 160,12,124,0,106,7,161,1,125,1,124,1,116,5,106,6, - 124,0,106,7,60,0,116,13,100,5,124,0,106,7,124,0, - 106,0,131,3,1,0,87,0,53,0,100,6,124,0,95,4, - 88,0,124,1,83,0,41,7,78,114,150,0,0,0,84,114, - 154,0,0,0,114,16,0,0,0,122,18,105,109,112,111,114, - 116,32,123,33,114,125,32,35,32,123,33,114,125,70,41,14, - 114,109,0,0,0,114,4,0,0,0,114,158,0,0,0,114, - 152,0,0,0,90,13,95,105,110,105,116,105,97,108,105,122, - 105,110,103,114,15,0,0,0,114,92,0,0,0,114,17,0, - 0,0,114,117,0,0,0,114,79,0,0,0,114,150,0,0, - 0,114,63,0,0,0,114,156,0,0,0,114,76,0,0,0, - 114,151,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,14,95,108,111,97,100,95,117,110,108,111, - 99,107,101,100,138,2,0,0,115,46,0,0,0,0,2,10, - 2,12,1,8,2,8,5,6,1,2,1,12,1,2,1,10, - 1,10,1,16,3,16,1,6,1,2,1,14,1,14,1,6, - 1,8,5,14,1,12,1,20,2,8,2,114,159,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,10,0,0,0,67,0,0,0,115,42,0,0,0,116,0, - 124,0,106,1,131,1,143,22,1,0,116,2,124,0,131,1, - 87,0,2,0,53,0,81,0,82,0,163,0,83,0,81,0, - 82,0,88,0,100,1,83,0,41,2,122,191,82,101,116,117, - 114,110,32,97,32,110,101,119,32,109,111,100,117,108,101,32, - 111,98,106,101,99,116,44,32,108,111,97,100,101,100,32,98, - 121,32,116,104,101,32,115,112,101,99,39,115,32,108,111,97, - 100,101,114,46,10,10,32,32,32,32,84,104,101,32,109,111, - 100,117,108,101,32,105,115,32,110,111,116,32,97,100,100,101, - 100,32,116,111,32,105,116,115,32,112,97,114,101,110,116,46, - 10,10,32,32,32,32,73,102,32,97,32,109,111,100,117,108, - 101,32,105,115,32,97,108,114,101,97,100,121,32,105,110,32, - 115,121,115,46,109,111,100,117,108,101,115,44,32,116,104,97, - 116,32,101,120,105,115,116,105,110,103,32,109,111,100,117,108, - 101,32,103,101,116,115,10,32,32,32,32,99,108,111,98,98, - 101,114,101,100,46,10,10,32,32,32,32,78,41,3,114,50, - 0,0,0,114,17,0,0,0,114,159,0,0,0,41,1,114, - 95,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,94,0,0,0,180,2,0,0,115,4,0,0, - 0,0,9,12,1,114,94,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,64, - 0,0,0,115,136,0,0,0,101,0,90,1,100,0,90,2, - 100,1,90,3,101,4,100,2,100,3,132,0,131,1,90,5, - 101,6,100,19,100,5,100,6,132,1,131,1,90,7,101,6, - 100,20,100,7,100,8,132,1,131,1,90,8,101,6,100,9, - 100,10,132,0,131,1,90,9,101,6,100,11,100,12,132,0, - 131,1,90,10,101,6,101,11,100,13,100,14,132,0,131,1, - 131,1,90,12,101,6,101,11,100,15,100,16,132,0,131,1, - 131,1,90,13,101,6,101,11,100,17,100,18,132,0,131,1, - 131,1,90,14,101,6,101,15,131,1,90,16,100,4,83,0, - 41,21,218,15,66,117,105,108,116,105,110,73,109,112,111,114, - 116,101,114,122,144,77,101,116,97,32,112,97,116,104,32,105, - 109,112,111,114,116,32,102,111,114,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,115,46,10,10,32,32,32, - 32,65,108,108,32,109,101,116,104,111,100,115,32,97,114,101, - 32,101,105,116,104,101,114,32,99,108,97,115,115,32,111,114, - 32,115,116,97,116,105,99,32,109,101,116,104,111,100,115,32, - 116,111,32,97,118,111,105,100,32,116,104,101,32,110,101,101, - 100,32,116,111,10,32,32,32,32,105,110,115,116,97,110,116, - 105,97,116,101,32,116,104,101,32,99,108,97,115,115,46,10, - 10,32,32,32,32,99,1,0,0,0,0,0,0,0,0,0, - 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,12, - 0,0,0,100,1,160,0,124,0,106,1,161,1,83,0,41, - 2,250,115,82,101,116,117,114,110,32,114,101,112,114,32,102, - 111,114,32,116,104,101,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,101,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,84,104,101,32,105,109,112,111,114,116,32,109,97, - 99,104,105,110,101,114,121,32,100,111,101,115,32,116,104,101, - 32,106,111,98,32,105,116,115,101,108,102,46,10,10,32,32, - 32,32,32,32,32,32,122,24,60,109,111,100,117,108,101,32, - 123,33,114,125,32,40,98,117,105,108,116,45,105,110,41,62, - 41,2,114,45,0,0,0,114,1,0,0,0,41,1,114,96, + 0,114,124,0,0,0,141,1,0,0,115,2,0,0,0,0, + 2,122,23,77,111,100,117,108,101,83,112,101,99,46,104,97, + 115,95,108,111,99,97,116,105,111,110,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, + 0,0,0,115,14,0,0,0,116,0,124,1,131,1,124,0, + 95,1,100,0,83,0,114,13,0,0,0,41,2,218,4,98, + 111,111,108,114,118,0,0,0,41,2,114,30,0,0,0,218, + 5,118,97,108,117,101,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,124,0,0,0,145,1,0,0,115,2, + 0,0,0,0,2,41,12,114,1,0,0,0,114,0,0,0, + 0,114,2,0,0,0,114,3,0,0,0,114,31,0,0,0, + 114,48,0,0,0,114,125,0,0,0,218,8,112,114,111,112, + 101,114,116,121,114,123,0,0,0,218,6,115,101,116,116,101, + 114,114,130,0,0,0,114,124,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 112,0,0,0,49,1,0,0,115,32,0,0,0,8,1,4, + 36,4,1,2,255,12,12,8,10,8,12,2,1,10,8,4, + 1,10,3,2,1,10,7,2,1,10,3,4,1,114,112,0, + 0,0,169,2,114,113,0,0,0,114,115,0,0,0,99,2, + 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,8, + 0,0,0,67,0,0,0,115,154,0,0,0,116,0,124,1, + 100,1,131,2,114,74,116,1,100,2,107,8,114,22,116,2, + 130,1,116,1,106,3,125,4,124,3,100,2,107,8,114,48, + 124,4,124,0,124,1,100,3,141,2,83,0,124,3,114,56, + 103,0,110,2,100,2,125,5,124,4,124,0,124,1,124,5, + 100,4,141,3,83,0,124,3,100,2,107,8,114,138,116,0, + 124,1,100,5,131,2,114,134,122,14,124,1,160,4,124,0, + 161,1,125,3,87,0,113,138,4,0,116,5,107,10,114,130, + 1,0,1,0,1,0,100,2,125,3,89,0,113,138,88,0, + 110,4,100,6,125,3,116,6,124,0,124,1,124,2,124,3, + 100,7,141,4,83,0,41,8,122,53,82,101,116,117,114,110, + 32,97,32,109,111,100,117,108,101,32,115,112,101,99,32,98, + 97,115,101,100,32,111,110,32,118,97,114,105,111,117,115,32, + 108,111,97,100,101,114,32,109,101,116,104,111,100,115,46,90, + 12,103,101,116,95,102,105,108,101,110,97,109,101,78,41,1, + 114,109,0,0,0,41,2,114,109,0,0,0,114,117,0,0, + 0,114,115,0,0,0,70,114,135,0,0,0,41,7,114,4, + 0,0,0,114,126,0,0,0,114,127,0,0,0,218,23,115, + 112,101,99,95,102,114,111,109,95,102,105,108,101,95,108,111, + 99,97,116,105,111,110,114,115,0,0,0,114,79,0,0,0, + 114,112,0,0,0,41,6,114,17,0,0,0,114,109,0,0, + 0,114,113,0,0,0,114,115,0,0,0,114,136,0,0,0, + 90,6,115,101,97,114,99,104,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,91,0,0,0,150,1,0,0, + 115,36,0,0,0,0,2,10,1,8,1,4,1,6,2,8, + 1,12,1,12,1,6,1,2,255,6,3,8,1,10,1,2, + 1,14,1,14,1,12,3,4,2,114,91,0,0,0,99,3, + 0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,8, + 0,0,0,67,0,0,0,115,56,1,0,0,122,10,124,0, + 106,0,125,3,87,0,110,20,4,0,116,1,107,10,114,30, + 1,0,1,0,1,0,89,0,110,14,88,0,124,3,100,0, + 107,9,114,44,124,3,83,0,124,0,106,2,125,4,124,1, + 100,0,107,8,114,90,122,10,124,0,106,3,125,1,87,0, + 110,20,4,0,116,1,107,10,114,88,1,0,1,0,1,0, + 89,0,110,2,88,0,122,10,124,0,106,4,125,5,87,0, + 110,24,4,0,116,1,107,10,114,124,1,0,1,0,1,0, + 100,0,125,5,89,0,110,2,88,0,124,2,100,0,107,8, + 114,184,124,5,100,0,107,8,114,180,122,10,124,1,106,5, + 125,2,87,0,113,184,4,0,116,1,107,10,114,176,1,0, + 1,0,1,0,100,0,125,2,89,0,113,184,88,0,110,4, + 124,5,125,2,122,10,124,0,106,6,125,6,87,0,110,24, + 4,0,116,1,107,10,114,218,1,0,1,0,1,0,100,0, + 125,6,89,0,110,2,88,0,122,14,116,7,124,0,106,8, + 131,1,125,7,87,0,110,26,4,0,116,1,107,10,144,1, + 114,4,1,0,1,0,1,0,100,0,125,7,89,0,110,2, + 88,0,116,9,124,4,124,1,124,2,100,1,141,3,125,3, + 124,5,100,0,107,8,144,1,114,34,100,2,110,2,100,3, + 124,3,95,10,124,6,124,3,95,11,124,7,124,3,95,12, + 124,3,83,0,41,4,78,169,1,114,113,0,0,0,70,84, + 41,13,114,105,0,0,0,114,106,0,0,0,114,1,0,0, + 0,114,98,0,0,0,114,108,0,0,0,218,7,95,79,82, + 73,71,73,78,218,10,95,95,99,97,99,104,101,100,95,95, + 218,4,108,105,115,116,218,8,95,95,112,97,116,104,95,95, + 114,112,0,0,0,114,118,0,0,0,114,123,0,0,0,114, + 117,0,0,0,41,8,114,96,0,0,0,114,109,0,0,0, + 114,113,0,0,0,114,95,0,0,0,114,17,0,0,0,90, + 8,108,111,99,97,116,105,111,110,114,123,0,0,0,114,117, 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,99,0,0,0,204,2,0,0,115,2,0,0,0, - 0,7,122,27,66,117,105,108,116,105,110,73,109,112,111,114, - 116,101,114,46,109,111,100,117,108,101,95,114,101,112,114,78, - 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,5,0,0,0,67,0,0,0,115,44,0,0,0,124,2, - 100,0,107,9,114,12,100,0,83,0,116,0,160,1,124,1, - 161,1,114,36,116,2,124,1,124,0,100,1,100,2,141,3, - 83,0,100,0,83,0,100,0,83,0,41,3,78,122,8,98, - 117,105,108,116,45,105,110,114,137,0,0,0,41,3,114,57, - 0,0,0,90,10,105,115,95,98,117,105,108,116,105,110,114, - 91,0,0,0,169,4,218,3,99,108,115,114,81,0,0,0, - 218,4,112,97,116,104,218,6,116,97,114,103,101,116,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,9,102, - 105,110,100,95,115,112,101,99,213,2,0,0,115,10,0,0, - 0,0,2,8,1,4,1,10,1,14,2,122,25,66,117,105, - 108,116,105,110,73,109,112,111,114,116,101,114,46,102,105,110, - 100,95,115,112,101,99,99,3,0,0,0,0,0,0,0,0, - 0,0,0,4,0,0,0,4,0,0,0,67,0,0,0,115, - 30,0,0,0,124,0,160,0,124,1,124,2,161,2,125,3, - 124,3,100,1,107,9,114,26,124,3,106,1,83,0,100,1, - 83,0,41,2,122,175,70,105,110,100,32,116,104,101,32,98, - 117,105,108,116,45,105,110,32,109,111,100,117,108,101,46,10, - 10,32,32,32,32,32,32,32,32,73,102,32,39,112,97,116, - 104,39,32,105,115,32,101,118,101,114,32,115,112,101,99,105, - 102,105,101,100,32,116,104,101,110,32,116,104,101,32,115,101, - 97,114,99,104,32,105,115,32,99,111,110,115,105,100,101,114, - 101,100,32,97,32,102,97,105,108,117,114,101,46,10,10,32, - 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, - 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, - 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, - 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, - 32,32,32,32,32,78,41,2,114,166,0,0,0,114,109,0, - 0,0,41,4,114,163,0,0,0,114,81,0,0,0,114,164, - 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,11,102,105,110,100,95,109,111, - 100,117,108,101,222,2,0,0,115,4,0,0,0,0,9,12, - 1,122,27,66,117,105,108,116,105,110,73,109,112,111,114,116, - 101,114,46,102,105,110,100,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, - 0,0,0,67,0,0,0,115,46,0,0,0,124,1,106,0, - 116,1,106,2,107,7,114,34,116,3,100,1,160,4,124,1, - 106,0,161,1,124,1,106,0,100,2,141,2,130,1,116,5, - 116,6,106,7,124,1,131,2,83,0,41,3,122,24,67,114, - 101,97,116,101,32,97,32,98,117,105,108,116,45,105,110,32, - 109,111,100,117,108,101,114,77,0,0,0,114,16,0,0,0, - 41,8,114,17,0,0,0,114,15,0,0,0,114,78,0,0, - 0,114,79,0,0,0,114,45,0,0,0,114,67,0,0,0, - 114,57,0,0,0,90,14,99,114,101,97,116,101,95,98,117, - 105,108,116,105,110,41,2,114,30,0,0,0,114,95,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,149,0,0,0,234,2,0,0,115,10,0,0,0,0,3, - 12,1,12,1,4,255,6,2,122,29,66,117,105,108,116,105, - 110,73,109,112,111,114,116,101,114,46,99,114,101,97,116,101, + 0,0,218,17,95,115,112,101,99,95,102,114,111,109,95,109, + 111,100,117,108,101,176,1,0,0,115,72,0,0,0,0,2, + 2,1,10,1,14,1,6,2,8,1,4,2,6,1,8,1, + 2,1,10,1,14,2,6,1,2,1,10,1,14,1,10,1, + 8,1,8,1,2,1,10,1,14,1,12,2,4,1,2,1, + 10,1,14,1,10,1,2,1,14,1,16,1,10,2,14,1, + 20,1,6,1,6,1,114,142,0,0,0,70,169,1,218,8, + 111,118,101,114,114,105,100,101,99,2,0,0,0,0,0,0, + 0,1,0,0,0,5,0,0,0,8,0,0,0,67,0,0, + 0,115,226,1,0,0,124,2,115,20,116,0,124,1,100,1, + 100,0,131,3,100,0,107,8,114,54,122,12,124,0,106,1, + 124,1,95,2,87,0,110,20,4,0,116,3,107,10,114,52, + 1,0,1,0,1,0,89,0,110,2,88,0,124,2,115,74, + 116,0,124,1,100,2,100,0,131,3,100,0,107,8,114,178, + 124,0,106,4,125,3,124,3,100,0,107,8,114,146,124,0, + 106,5,100,0,107,9,114,146,116,6,100,0,107,8,114,110, + 116,7,130,1,116,6,106,8,125,4,124,4,160,9,124,4, + 161,1,125,3,124,0,106,5,124,3,95,10,124,3,124,0, + 95,4,100,0,124,1,95,11,122,10,124,3,124,1,95,12, + 87,0,110,20,4,0,116,3,107,10,114,176,1,0,1,0, + 1,0,89,0,110,2,88,0,124,2,115,198,116,0,124,1, + 100,3,100,0,131,3,100,0,107,8,114,232,122,12,124,0, + 106,13,124,1,95,14,87,0,110,20,4,0,116,3,107,10, + 114,230,1,0,1,0,1,0,89,0,110,2,88,0,122,10, + 124,0,124,1,95,15,87,0,110,22,4,0,116,3,107,10, + 144,1,114,8,1,0,1,0,1,0,89,0,110,2,88,0, + 124,2,144,1,115,34,116,0,124,1,100,4,100,0,131,3, + 100,0,107,8,144,1,114,82,124,0,106,5,100,0,107,9, + 144,1,114,82,122,12,124,0,106,5,124,1,95,16,87,0, + 110,22,4,0,116,3,107,10,144,1,114,80,1,0,1,0, + 1,0,89,0,110,2,88,0,124,0,106,17,144,1,114,222, + 124,2,144,1,115,114,116,0,124,1,100,5,100,0,131,3, + 100,0,107,8,144,1,114,150,122,12,124,0,106,18,124,1, + 95,11,87,0,110,22,4,0,116,3,107,10,144,1,114,148, + 1,0,1,0,1,0,89,0,110,2,88,0,124,2,144,1, + 115,174,116,0,124,1,100,6,100,0,131,3,100,0,107,8, + 144,1,114,222,124,0,106,19,100,0,107,9,144,1,114,222, + 122,12,124,0,106,19,124,1,95,20,87,0,110,22,4,0, + 116,3,107,10,144,1,114,220,1,0,1,0,1,0,89,0, + 110,2,88,0,124,1,83,0,41,7,78,114,1,0,0,0, + 114,98,0,0,0,218,11,95,95,112,97,99,107,97,103,101, + 95,95,114,141,0,0,0,114,108,0,0,0,114,139,0,0, + 0,41,21,114,6,0,0,0,114,17,0,0,0,114,1,0, + 0,0,114,106,0,0,0,114,109,0,0,0,114,117,0,0, + 0,114,126,0,0,0,114,127,0,0,0,218,16,95,78,97, + 109,101,115,112,97,99,101,76,111,97,100,101,114,218,7,95, + 95,110,101,119,95,95,90,5,95,112,97,116,104,114,108,0, + 0,0,114,98,0,0,0,114,130,0,0,0,114,145,0,0, + 0,114,105,0,0,0,114,141,0,0,0,114,124,0,0,0, + 114,113,0,0,0,114,123,0,0,0,114,139,0,0,0,41, + 5,114,95,0,0,0,114,96,0,0,0,114,144,0,0,0, + 114,109,0,0,0,114,146,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,18,95,105,110,105,116, + 95,109,111,100,117,108,101,95,97,116,116,114,115,221,1,0, + 0,115,96,0,0,0,0,4,20,1,2,1,12,1,14,1, + 6,2,20,1,6,1,8,2,10,1,8,1,4,1,6,2, + 10,1,8,1,6,11,6,1,2,1,10,1,14,1,6,2, + 20,1,2,1,12,1,14,1,6,2,2,1,10,1,16,1, + 6,2,24,1,12,1,2,1,12,1,16,1,6,2,8,1, + 24,1,2,1,12,1,16,1,6,2,24,1,12,1,2,1, + 12,1,16,1,6,1,114,148,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 67,0,0,0,115,82,0,0,0,100,1,125,1,116,0,124, + 0,106,1,100,2,131,2,114,30,124,0,106,1,160,2,124, + 0,161,1,125,1,110,20,116,0,124,0,106,1,100,3,131, + 2,114,50,116,3,100,4,131,1,130,1,124,1,100,1,107, + 8,114,68,116,4,124,0,106,5,131,1,125,1,116,6,124, + 0,124,1,131,2,1,0,124,1,83,0,41,5,122,43,67, + 114,101,97,116,101,32,97,32,109,111,100,117,108,101,32,98, + 97,115,101,100,32,111,110,32,116,104,101,32,112,114,111,118, + 105,100,101,100,32,115,112,101,99,46,78,218,13,99,114,101, + 97,116,101,95,109,111,100,117,108,101,218,11,101,120,101,99, + 95,109,111,100,117,108,101,122,66,108,111,97,100,101,114,115, + 32,116,104,97,116,32,100,101,102,105,110,101,32,101,120,101, + 99,95,109,111,100,117,108,101,40,41,32,109,117,115,116,32, + 97,108,115,111,32,100,101,102,105,110,101,32,99,114,101,97, + 116,101,95,109,111,100,117,108,101,40,41,41,7,114,4,0, + 0,0,114,109,0,0,0,114,149,0,0,0,114,79,0,0, + 0,114,18,0,0,0,114,17,0,0,0,114,148,0,0,0, + 169,2,114,95,0,0,0,114,96,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,16,109,111,100, + 117,108,101,95,102,114,111,109,95,115,112,101,99,37,2,0, + 0,115,18,0,0,0,0,3,4,1,12,3,14,1,12,1, + 8,2,8,1,10,1,10,1,114,152,0,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,67,0,0,0,115,106,0,0,0,124,0,106,0,100, + 1,107,8,114,14,100,2,110,4,124,0,106,0,125,1,124, + 0,106,1,100,1,107,8,114,66,124,0,106,2,100,1,107, + 8,114,50,100,3,160,3,124,1,161,1,83,0,100,4,160, + 3,124,1,124,0,106,2,161,2,83,0,110,36,124,0,106, + 4,114,86,100,5,160,3,124,1,124,0,106,1,161,2,83, + 0,100,6,160,3,124,0,106,0,124,0,106,1,161,2,83, + 0,100,1,83,0,41,7,122,38,82,101,116,117,114,110,32, + 116,104,101,32,114,101,112,114,32,116,111,32,117,115,101,32, + 102,111,114,32,116,104,101,32,109,111,100,117,108,101,46,78, + 114,100,0,0,0,114,101,0,0,0,114,102,0,0,0,114, + 103,0,0,0,250,18,60,109,111,100,117,108,101,32,123,33, + 114,125,32,40,123,125,41,62,41,5,114,17,0,0,0,114, + 113,0,0,0,114,109,0,0,0,114,45,0,0,0,114,124, + 0,0,0,41,2,114,95,0,0,0,114,17,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,107, + 0,0,0,54,2,0,0,115,16,0,0,0,0,3,20,1, + 10,1,10,1,10,2,16,2,6,1,14,2,114,107,0,0, + 0,99,2,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,10,0,0,0,67,0,0,0,115,204,0,0,0,124, + 0,106,0,125,2,116,1,124,2,131,1,143,180,1,0,116, + 2,106,3,160,4,124,2,161,1,124,1,107,9,114,54,100, + 1,160,5,124,2,161,1,125,3,116,6,124,3,124,2,100, + 2,141,2,130,1,122,106,124,0,106,7,100,3,107,8,114, + 106,124,0,106,8,100,3,107,8,114,90,116,6,100,4,124, + 0,106,0,100,2,141,2,130,1,116,9,124,0,124,1,100, + 5,100,6,141,3,1,0,110,52,116,9,124,0,124,1,100, + 5,100,6,141,3,1,0,116,10,124,0,106,7,100,7,131, + 2,115,146,124,0,106,7,160,11,124,2,161,1,1,0,110, + 12,124,0,106,7,160,12,124,1,161,1,1,0,87,0,53, + 0,116,2,106,3,160,13,124,0,106,0,161,1,125,1,124, + 1,116,2,106,3,124,0,106,0,60,0,88,0,87,0,53, + 0,81,0,82,0,88,0,124,1,83,0,41,8,122,70,69, + 120,101,99,117,116,101,32,116,104,101,32,115,112,101,99,39, + 115,32,115,112,101,99,105,102,105,101,100,32,109,111,100,117, + 108,101,32,105,110,32,97,110,32,101,120,105,115,116,105,110, + 103,32,109,111,100,117,108,101,39,115,32,110,97,109,101,115, + 112,97,99,101,46,122,30,109,111,100,117,108,101,32,123,33, + 114,125,32,110,111,116,32,105,110,32,115,121,115,46,109,111, + 100,117,108,101,115,114,16,0,0,0,78,250,14,109,105,115, + 115,105,110,103,32,108,111,97,100,101,114,84,114,143,0,0, + 0,114,150,0,0,0,41,14,114,17,0,0,0,114,50,0, + 0,0,114,15,0,0,0,114,92,0,0,0,114,34,0,0, + 0,114,45,0,0,0,114,79,0,0,0,114,109,0,0,0, + 114,117,0,0,0,114,148,0,0,0,114,4,0,0,0,218, + 11,108,111,97,100,95,109,111,100,117,108,101,114,150,0,0, + 0,218,3,112,111,112,41,4,114,95,0,0,0,114,96,0, + 0,0,114,17,0,0,0,218,3,109,115,103,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,93,0,0,0, + 71,2,0,0,115,34,0,0,0,0,2,6,1,10,1,16, + 1,10,1,12,1,2,1,10,1,10,1,14,2,16,2,14, + 1,12,4,14,2,16,4,14,1,24,1,114,93,0,0,0, + 99,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,8,0,0,0,67,0,0,0,115,26,1,0,0,122,18, + 124,0,106,0,160,1,124,0,106,2,161,1,1,0,87,0, + 110,52,1,0,1,0,1,0,124,0,106,2,116,3,106,4, + 107,6,114,64,116,3,106,4,160,5,124,0,106,2,161,1, + 125,1,124,1,116,3,106,4,124,0,106,2,60,0,130,0, + 89,0,110,2,88,0,116,3,106,4,160,5,124,0,106,2, + 161,1,125,1,124,1,116,3,106,4,124,0,106,2,60,0, + 116,6,124,1,100,1,100,0,131,3,100,0,107,8,114,148, + 122,12,124,0,106,0,124,1,95,7,87,0,110,20,4,0, + 116,8,107,10,114,146,1,0,1,0,1,0,89,0,110,2, + 88,0,116,6,124,1,100,2,100,0,131,3,100,0,107,8, + 114,226,122,40,124,1,106,9,124,1,95,10,116,11,124,1, + 100,3,131,2,115,202,124,0,106,2,160,12,100,4,161,1, + 100,5,25,0,124,1,95,10,87,0,110,20,4,0,116,8, + 107,10,114,224,1,0,1,0,1,0,89,0,110,2,88,0, + 116,6,124,1,100,6,100,0,131,3,100,0,107,8,144,1, + 114,22,122,10,124,0,124,1,95,13,87,0,110,22,4,0, + 116,8,107,10,144,1,114,20,1,0,1,0,1,0,89,0, + 110,2,88,0,124,1,83,0,41,7,78,114,98,0,0,0, + 114,145,0,0,0,114,141,0,0,0,114,128,0,0,0,114, + 22,0,0,0,114,105,0,0,0,41,14,114,109,0,0,0, + 114,155,0,0,0,114,17,0,0,0,114,15,0,0,0,114, + 92,0,0,0,114,156,0,0,0,114,6,0,0,0,114,98, + 0,0,0,114,106,0,0,0,114,1,0,0,0,114,145,0, + 0,0,114,4,0,0,0,114,129,0,0,0,114,105,0,0, + 0,114,151,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,25,95,108,111,97,100,95,98,97,99, + 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101, + 101,2,0,0,115,54,0,0,0,0,4,2,1,18,1,6, + 1,12,1,14,1,12,1,8,3,14,1,12,1,16,1,2, + 1,12,1,14,1,6,1,16,1,2,4,8,1,10,1,22, + 1,14,1,6,1,18,1,2,1,10,1,16,1,6,1,114, + 158,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,11,0,0,0,67,0,0,0,115,220,0, + 0,0,124,0,106,0,100,0,107,9,114,30,116,1,124,0, + 106,0,100,1,131,2,115,30,116,2,124,0,131,1,83,0, + 116,3,124,0,131,1,125,1,100,2,124,0,95,4,122,162, + 124,1,116,5,106,6,124,0,106,7,60,0,122,52,124,0, + 106,0,100,0,107,8,114,96,124,0,106,8,100,0,107,8, + 114,108,116,9,100,3,124,0,106,7,100,4,141,2,130,1, + 110,12,124,0,106,0,160,10,124,1,161,1,1,0,87,0, + 110,50,1,0,1,0,1,0,122,14,116,5,106,6,124,0, + 106,7,61,0,87,0,110,20,4,0,116,11,107,10,114,152, + 1,0,1,0,1,0,89,0,110,2,88,0,130,0,89,0, + 110,2,88,0,116,5,106,6,160,12,124,0,106,7,161,1, + 125,1,124,1,116,5,106,6,124,0,106,7,60,0,116,13, + 100,5,124,0,106,7,124,0,106,0,131,3,1,0,87,0, + 53,0,100,6,124,0,95,4,88,0,124,1,83,0,41,7, + 78,114,150,0,0,0,84,114,154,0,0,0,114,16,0,0, + 0,122,18,105,109,112,111,114,116,32,123,33,114,125,32,35, + 32,123,33,114,125,70,41,14,114,109,0,0,0,114,4,0, + 0,0,114,158,0,0,0,114,152,0,0,0,90,13,95,105, + 110,105,116,105,97,108,105,122,105,110,103,114,15,0,0,0, + 114,92,0,0,0,114,17,0,0,0,114,117,0,0,0,114, + 79,0,0,0,114,150,0,0,0,114,63,0,0,0,114,156, + 0,0,0,114,76,0,0,0,114,151,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,14,95,108, + 111,97,100,95,117,110,108,111,99,107,101,100,138,2,0,0, + 115,46,0,0,0,0,2,10,2,12,1,8,2,8,5,6, + 1,2,1,12,1,2,1,10,1,10,1,16,3,16,1,6, + 1,2,1,14,1,14,1,6,1,8,5,14,1,12,1,20, + 2,8,2,114,159,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,1,0,0,0,10,0,0,0,67,0,0, + 0,115,42,0,0,0,116,0,124,0,106,1,131,1,143,22, + 1,0,116,2,124,0,131,1,87,0,2,0,53,0,81,0, + 82,0,163,0,83,0,81,0,82,0,88,0,100,1,83,0, + 41,2,122,191,82,101,116,117,114,110,32,97,32,110,101,119, + 32,109,111,100,117,108,101,32,111,98,106,101,99,116,44,32, + 108,111,97,100,101,100,32,98,121,32,116,104,101,32,115,112, + 101,99,39,115,32,108,111,97,100,101,114,46,10,10,32,32, + 32,32,84,104,101,32,109,111,100,117,108,101,32,105,115,32, + 110,111,116,32,97,100,100,101,100,32,116,111,32,105,116,115, + 32,112,97,114,101,110,116,46,10,10,32,32,32,32,73,102, + 32,97,32,109,111,100,117,108,101,32,105,115,32,97,108,114, + 101,97,100,121,32,105,110,32,115,121,115,46,109,111,100,117, + 108,101,115,44,32,116,104,97,116,32,101,120,105,115,116,105, + 110,103,32,109,111,100,117,108,101,32,103,101,116,115,10,32, + 32,32,32,99,108,111,98,98,101,114,101,100,46,10,10,32, + 32,32,32,78,41,3,114,50,0,0,0,114,17,0,0,0, + 114,159,0,0,0,41,1,114,95,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,94,0,0,0, + 180,2,0,0,115,4,0,0,0,0,9,12,1,114,94,0, + 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,64,0,0,0,115,136,0,0,0, + 101,0,90,1,100,0,90,2,100,1,90,3,101,4,100,2, + 100,3,132,0,131,1,90,5,101,6,100,19,100,5,100,6, + 132,1,131,1,90,7,101,6,100,20,100,7,100,8,132,1, + 131,1,90,8,101,6,100,9,100,10,132,0,131,1,90,9, + 101,6,100,11,100,12,132,0,131,1,90,10,101,6,101,11, + 100,13,100,14,132,0,131,1,131,1,90,12,101,6,101,11, + 100,15,100,16,132,0,131,1,131,1,90,13,101,6,101,11, + 100,17,100,18,132,0,131,1,131,1,90,14,101,6,101,15, + 131,1,90,16,100,4,83,0,41,21,218,15,66,117,105,108, + 116,105,110,73,109,112,111,114,116,101,114,122,144,77,101,116, + 97,32,112,97,116,104,32,105,109,112,111,114,116,32,102,111, + 114,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,115,46,10,10,32,32,32,32,65,108,108,32,109,101,116, + 104,111,100,115,32,97,114,101,32,101,105,116,104,101,114,32, + 99,108,97,115,115,32,111,114,32,115,116,97,116,105,99,32, + 109,101,116,104,111,100,115,32,116,111,32,97,118,111,105,100, + 32,116,104,101,32,110,101,101,100,32,116,111,10,32,32,32, + 32,105,110,115,116,97,110,116,105,97,116,101,32,116,104,101, + 32,99,108,97,115,115,46,10,10,32,32,32,32,99,1,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0, + 0,0,67,0,0,0,115,12,0,0,0,100,1,160,0,124, + 0,106,1,161,1,83,0,41,2,250,115,82,101,116,117,114, + 110,32,114,101,112,114,32,102,111,114,32,116,104,101,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,101,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,84,104,101,32,105, + 109,112,111,114,116,32,109,97,99,104,105,110,101,114,121,32, + 100,111,101,115,32,116,104,101,32,106,111,98,32,105,116,115, + 101,108,102,46,10,10,32,32,32,32,32,32,32,32,122,24, + 60,109,111,100,117,108,101,32,123,33,114,125,32,40,98,117, + 105,108,116,45,105,110,41,62,41,2,114,45,0,0,0,114, + 1,0,0,0,41,1,114,96,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,99,0,0,0,204, + 2,0,0,115,2,0,0,0,0,7,122,27,66,117,105,108, + 116,105,110,73,109,112,111,114,116,101,114,46,109,111,100,117, + 108,101,95,114,101,112,114,78,99,4,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,5,0,0,0,67,0,0, + 0,115,44,0,0,0,124,2,100,0,107,9,114,12,100,0, + 83,0,116,0,160,1,124,1,161,1,114,36,116,2,124,1, + 124,0,100,1,100,2,141,3,83,0,100,0,83,0,100,0, + 83,0,41,3,78,122,8,98,117,105,108,116,45,105,110,114, + 137,0,0,0,41,3,114,57,0,0,0,90,10,105,115,95, + 98,117,105,108,116,105,110,114,91,0,0,0,169,4,218,3, + 99,108,115,114,81,0,0,0,218,4,112,97,116,104,218,6, + 116,97,114,103,101,116,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,9,102,105,110,100,95,115,112,101,99, + 213,2,0,0,115,10,0,0,0,0,2,8,1,4,1,10, + 1,14,2,122,25,66,117,105,108,116,105,110,73,109,112,111, + 114,116,101,114,46,102,105,110,100,95,115,112,101,99,99,3, + 0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,4, + 0,0,0,67,0,0,0,115,30,0,0,0,124,0,160,0, + 124,1,124,2,161,2,125,3,124,3,100,1,107,9,114,26, + 124,3,106,1,83,0,100,1,83,0,41,2,122,175,70,105, + 110,100,32,116,104,101,32,98,117,105,108,116,45,105,110,32, + 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, + 32,73,102,32,39,112,97,116,104,39,32,105,115,32,101,118, + 101,114,32,115,112,101,99,105,102,105,101,100,32,116,104,101, + 110,32,116,104,101,32,115,101,97,114,99,104,32,105,115,32, + 99,111,110,115,105,100,101,114,101,100,32,97,32,102,97,105, + 108,117,114,101,46,10,10,32,32,32,32,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,102, + 105,110,100,95,115,112,101,99,40,41,32,105,110,115,116,101, + 97,100,46,10,10,32,32,32,32,32,32,32,32,78,41,2, + 114,166,0,0,0,114,109,0,0,0,41,4,114,163,0,0, + 0,114,81,0,0,0,114,164,0,0,0,114,95,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 11,102,105,110,100,95,109,111,100,117,108,101,222,2,0,0, + 115,4,0,0,0,0,9,12,1,122,27,66,117,105,108,116, + 105,110,73,109,112,111,114,116,101,114,46,102,105,110,100,95, + 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,67,0,0,0,115, + 46,0,0,0,124,1,106,0,116,1,106,2,107,7,114,34, + 116,3,100,1,160,4,124,1,106,0,161,1,124,1,106,0, + 100,2,141,2,130,1,116,5,116,6,106,7,124,1,131,2, + 83,0,41,3,122,24,67,114,101,97,116,101,32,97,32,98, + 117,105,108,116,45,105,110,32,109,111,100,117,108,101,114,77, + 0,0,0,114,16,0,0,0,41,8,114,17,0,0,0,114, + 15,0,0,0,114,78,0,0,0,114,79,0,0,0,114,45, + 0,0,0,114,67,0,0,0,114,57,0,0,0,90,14,99, + 114,101,97,116,101,95,98,117,105,108,116,105,110,41,2,114, + 30,0,0,0,114,95,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,149,0,0,0,234,2,0, + 0,115,10,0,0,0,0,3,12,1,12,1,4,255,6,2, + 122,29,66,117,105,108,116,105,110,73,109,112,111,114,116,101, + 114,46,99,114,101,97,116,101,95,109,111,100,117,108,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 3,0,0,0,67,0,0,0,115,16,0,0,0,116,0,116, + 1,106,2,124,1,131,2,1,0,100,1,83,0,41,2,122, + 22,69,120,101,99,32,97,32,98,117,105,108,116,45,105,110, + 32,109,111,100,117,108,101,78,41,3,114,67,0,0,0,114, + 57,0,0,0,90,12,101,120,101,99,95,98,117,105,108,116, + 105,110,41,2,114,30,0,0,0,114,96,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,150,0, + 0,0,242,2,0,0,115,2,0,0,0,0,3,122,27,66, + 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,1,83,0,41,2,122,57, + 82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,98, + 117,105,108,116,45,105,110,32,109,111,100,117,108,101,115,32, + 100,111,32,110,111,116,32,104,97,118,101,32,99,111,100,101, + 32,111,98,106,101,99,116,115,46,78,114,10,0,0,0,169, + 2,114,163,0,0,0,114,81,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,8,103,101,116,95, + 99,111,100,101,247,2,0,0,115,2,0,0,0,0,4,122, + 24,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, + 46,103,101,116,95,99,111,100,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,122,56,82, + 101,116,117,114,110,32,78,111,110,101,32,97,115,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,100, + 111,32,110,111,116,32,104,97,118,101,32,115,111,117,114,99, + 101,32,99,111,100,101,46,78,114,10,0,0,0,114,168,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,218,10,103,101,116,95,115,111,117,114,99,101,253,2,0, + 0,115,2,0,0,0,0,4,122,26,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,103,101,116,95,115,111, + 117,114,99,101,99,2,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,83,0,41,2,122,52,82,101,116,117,114,110, + 32,70,97,108,115,101,32,97,115,32,98,117,105,108,116,45, + 105,110,32,109,111,100,117,108,101,115,32,97,114,101,32,110, + 101,118,101,114,32,112,97,99,107,97,103,101,115,46,70,114, + 10,0,0,0,114,168,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,115,0,0,0,3,3,0, + 0,115,2,0,0,0,0,4,122,26,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,105,115,95,112,97,99, + 107,97,103,101,41,2,78,78,41,1,78,41,17,114,1,0, + 0,0,114,0,0,0,0,114,2,0,0,0,114,3,0,0, + 0,218,12,115,116,97,116,105,99,109,101,116,104,111,100,114, + 99,0,0,0,218,11,99,108,97,115,115,109,101,116,104,111, + 100,114,166,0,0,0,114,167,0,0,0,114,149,0,0,0, + 114,150,0,0,0,114,86,0,0,0,114,169,0,0,0,114, + 170,0,0,0,114,115,0,0,0,114,97,0,0,0,114,155, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,160,0,0,0,195,2,0,0, + 115,42,0,0,0,8,2,4,7,2,1,10,8,2,1,12, + 8,2,1,12,11,2,1,10,7,2,1,10,4,2,1,2, + 1,12,4,2,1,2,1,12,4,2,1,2,1,12,4,114, + 160,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,64,0,0,0,115,144,0, + 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, + 90,4,101,5,100,3,100,4,132,0,131,1,90,6,101,7, + 100,22,100,6,100,7,132,1,131,1,90,8,101,7,100,23, + 100,8,100,9,132,1,131,1,90,9,101,7,100,10,100,11, + 132,0,131,1,90,10,101,5,100,12,100,13,132,0,131,1, + 90,11,101,7,100,14,100,15,132,0,131,1,90,12,101,7, + 101,13,100,16,100,17,132,0,131,1,131,1,90,14,101,7, + 101,13,100,18,100,19,132,0,131,1,131,1,90,15,101,7, + 101,13,100,20,100,21,132,0,131,1,131,1,90,16,100,5, + 83,0,41,24,218,14,70,114,111,122,101,110,73,109,112,111, + 114,116,101,114,122,142,77,101,116,97,32,112,97,116,104,32, + 105,109,112,111,114,116,32,102,111,114,32,102,114,111,122,101, + 110,32,109,111,100,117,108,101,115,46,10,10,32,32,32,32, + 65,108,108,32,109,101,116,104,111,100,115,32,97,114,101,32, + 101,105,116,104,101,114,32,99,108,97,115,115,32,111,114,32, + 115,116,97,116,105,99,32,109,101,116,104,111,100,115,32,116, + 111,32,97,118,111,105,100,32,116,104,101,32,110,101,101,100, + 32,116,111,10,32,32,32,32,105,110,115,116,97,110,116,105, + 97,116,101,32,116,104,101,32,99,108,97,115,115,46,10,10, + 32,32,32,32,90,6,102,114,111,122,101,110,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,67,0,0,0,115,16,0,0,0,100,1,160,0,124,0, + 106,1,116,2,106,3,161,2,83,0,41,2,114,161,0,0, + 0,114,153,0,0,0,41,4,114,45,0,0,0,114,1,0, + 0,0,114,173,0,0,0,114,138,0,0,0,41,1,218,1, + 109,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,99,0,0,0,23,3,0,0,115,2,0,0,0,0,7, + 122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,109,111,100,117,108,101,95,114,101,112,114,78,99,4,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0, + 0,0,67,0,0,0,115,34,0,0,0,116,0,160,1,124, + 1,161,1,114,26,116,2,124,1,124,0,124,0,106,3,100, + 1,141,3,83,0,100,0,83,0,100,0,83,0,41,2,78, + 114,137,0,0,0,41,4,114,57,0,0,0,114,88,0,0, + 0,114,91,0,0,0,114,138,0,0,0,114,162,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 166,0,0,0,32,3,0,0,115,6,0,0,0,0,2,10, + 1,16,2,122,24,70,114,111,122,101,110,73,109,112,111,114, + 116,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,18,0,0,0,116,0,160,1,124, + 1,161,1,114,14,124,0,83,0,100,1,83,0,41,2,122, + 93,70,105,110,100,32,97,32,102,114,111,122,101,110,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,41, + 2,114,57,0,0,0,114,88,0,0,0,41,3,114,163,0, + 0,0,114,81,0,0,0,114,164,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,167,0,0,0, + 39,3,0,0,115,2,0,0,0,0,7,122,26,70,114,111, + 122,101,110,73,109,112,111,114,116,101,114,46,102,105,110,100, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,83,0,41,2,122,42,85,115,101, + 32,100,101,102,97,117,108,116,32,115,101,109,97,110,116,105, + 99,115,32,102,111,114,32,109,111,100,117,108,101,32,99,114, + 101,97,116,105,111,110,46,78,114,10,0,0,0,41,2,114, + 163,0,0,0,114,95,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,149,0,0,0,48,3,0, + 0,115,2,0,0,0,0,2,122,28,70,114,111,122,101,110, + 73,109,112,111,114,116,101,114,46,99,114,101,97,116,101,95, + 109,111,100,117,108,101,99,1,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, + 64,0,0,0,124,0,106,0,106,1,125,1,116,2,160,3, + 124,1,161,1,115,36,116,4,100,1,160,5,124,1,161,1, + 124,1,100,2,141,2,130,1,116,6,116,2,106,7,124,1, + 131,2,125,2,116,8,124,2,124,0,106,9,131,2,1,0, + 100,0,83,0,114,87,0,0,0,41,10,114,105,0,0,0, + 114,17,0,0,0,114,57,0,0,0,114,88,0,0,0,114, + 79,0,0,0,114,45,0,0,0,114,67,0,0,0,218,17, + 103,101,116,95,102,114,111,122,101,110,95,111,98,106,101,99, + 116,218,4,101,120,101,99,114,7,0,0,0,41,3,114,96, + 0,0,0,114,17,0,0,0,218,4,99,111,100,101,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,150,0, + 0,0,52,3,0,0,115,14,0,0,0,0,2,8,1,10, + 1,10,1,2,255,6,2,12,1,122,26,70,114,111,122,101, + 110,73,109,112,111,114,116,101,114,46,101,120,101,99,95,109, + 111,100,117,108,101,99,2,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,10, + 0,0,0,116,0,124,0,124,1,131,2,83,0,41,1,122, + 95,76,111,97,100,32,97,32,102,114,111,122,101,110,32,109, + 111,100,117,108,101,46,10,10,32,32,32,32,32,32,32,32, + 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, + 101,120,101,99,95,109,111,100,117,108,101,40,41,32,105,110, + 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, + 41,1,114,97,0,0,0,114,168,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,155,0,0,0, + 61,3,0,0,115,2,0,0,0,0,7,122,26,70,114,111, + 122,101,110,73,109,112,111,114,116,101,114,46,108,111,97,100, 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, - 115,16,0,0,0,116,0,116,1,106,2,124,1,131,2,1, - 0,100,1,83,0,41,2,122,22,69,120,101,99,32,97,32, - 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,78, - 41,3,114,67,0,0,0,114,57,0,0,0,90,12,101,120, - 101,99,95,98,117,105,108,116,105,110,41,2,114,30,0,0, - 0,114,96,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,150,0,0,0,242,2,0,0,115,2, - 0,0,0,0,3,122,27,66,117,105,108,116,105,110,73,109, - 112,111,114,116,101,114,46,101,120,101,99,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 100,1,83,0,41,2,122,57,82,101,116,117,114,110,32,78, - 111,110,101,32,97,115,32,98,117,105,108,116,45,105,110,32, - 109,111,100,117,108,101,115,32,100,111,32,110,111,116,32,104, - 97,118,101,32,99,111,100,101,32,111,98,106,101,99,116,115, - 46,78,114,10,0,0,0,169,2,114,163,0,0,0,114,81, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,8,103,101,116,95,99,111,100,101,247,2,0,0, - 115,2,0,0,0,0,4,122,24,66,117,105,108,116,105,110, - 73,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, - 1,83,0,41,2,122,56,82,101,116,117,114,110,32,78,111, - 110,101,32,97,115,32,98,117,105,108,116,45,105,110,32,109, - 111,100,117,108,101,115,32,100,111,32,110,111,116,32,104,97, - 118,101,32,115,111,117,114,99,101,32,99,111,100,101,46,78, - 114,10,0,0,0,114,168,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,218,10,103,101,116,95,115, - 111,117,114,99,101,253,2,0,0,115,2,0,0,0,0,4, - 122,26,66,117,105,108,116,105,110,73,109,112,111,114,116,101, - 114,46,103,101,116,95,115,111,117,114,99,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,2, - 122,52,82,101,116,117,114,110,32,70,97,108,115,101,32,97, - 115,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, - 101,115,32,97,114,101,32,110,101,118,101,114,32,112,97,99, - 107,97,103,101,115,46,70,114,10,0,0,0,114,168,0,0, + 115,10,0,0,0,116,0,160,1,124,1,161,1,83,0,41, + 1,122,45,82,101,116,117,114,110,32,116,104,101,32,99,111, + 100,101,32,111,98,106,101,99,116,32,102,111,114,32,116,104, + 101,32,102,114,111,122,101,110,32,109,111,100,117,108,101,46, + 41,2,114,57,0,0,0,114,175,0,0,0,114,168,0,0, 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,115,0,0,0,3,3,0,0,115,2,0,0,0,0,4, - 122,26,66,117,105,108,116,105,110,73,109,112,111,114,116,101, - 114,46,105,115,95,112,97,99,107,97,103,101,41,2,78,78, - 41,1,78,41,17,114,1,0,0,0,114,0,0,0,0,114, - 2,0,0,0,114,3,0,0,0,218,12,115,116,97,116,105, - 99,109,101,116,104,111,100,114,99,0,0,0,218,11,99,108, - 97,115,115,109,101,116,104,111,100,114,166,0,0,0,114,167, - 0,0,0,114,149,0,0,0,114,150,0,0,0,114,86,0, - 0,0,114,169,0,0,0,114,170,0,0,0,114,115,0,0, - 0,114,97,0,0,0,114,155,0,0,0,114,10,0,0,0, + 114,169,0,0,0,70,3,0,0,115,2,0,0,0,0,4, + 122,23,70,114,111,122,101,110,73,109,112,111,114,116,101,114, + 46,103,101,116,95,99,111,100,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,4,0,0,0,100,1,83,0,41,2,122,54,82, + 101,116,117,114,110,32,78,111,110,101,32,97,115,32,102,114, + 111,122,101,110,32,109,111,100,117,108,101,115,32,100,111,32, + 110,111,116,32,104,97,118,101,32,115,111,117,114,99,101,32, + 99,111,100,101,46,78,114,10,0,0,0,114,168,0,0,0, 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, - 160,0,0,0,195,2,0,0,115,42,0,0,0,8,2,4, - 7,2,1,10,8,2,1,12,8,2,1,12,11,2,1,10, - 7,2,1,10,4,2,1,2,1,12,4,2,1,2,1,12, - 4,2,1,2,1,12,4,114,160,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,144,0,0,0,101,0,90,1,100,0, - 90,2,100,1,90,3,100,2,90,4,101,5,100,3,100,4, - 132,0,131,1,90,6,101,7,100,22,100,6,100,7,132,1, - 131,1,90,8,101,7,100,23,100,8,100,9,132,1,131,1, - 90,9,101,7,100,10,100,11,132,0,131,1,90,10,101,5, - 100,12,100,13,132,0,131,1,90,11,101,7,100,14,100,15, - 132,0,131,1,90,12,101,7,101,13,100,16,100,17,132,0, - 131,1,131,1,90,14,101,7,101,13,100,18,100,19,132,0, - 131,1,131,1,90,15,101,7,101,13,100,20,100,21,132,0, - 131,1,131,1,90,16,100,5,83,0,41,24,218,14,70,114, - 111,122,101,110,73,109,112,111,114,116,101,114,122,142,77,101, - 116,97,32,112,97,116,104,32,105,109,112,111,114,116,32,102, - 111,114,32,102,114,111,122,101,110,32,109,111,100,117,108,101, - 115,46,10,10,32,32,32,32,65,108,108,32,109,101,116,104, - 111,100,115,32,97,114,101,32,101,105,116,104,101,114,32,99, - 108,97,115,115,32,111,114,32,115,116,97,116,105,99,32,109, - 101,116,104,111,100,115,32,116,111,32,97,118,111,105,100,32, - 116,104,101,32,110,101,101,100,32,116,111,10,32,32,32,32, - 105,110,115,116,97,110,116,105,97,116,101,32,116,104,101,32, - 99,108,97,115,115,46,10,10,32,32,32,32,90,6,102,114, - 111,122,101,110,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,4,0,0,0,67,0,0,0,115,16,0, - 0,0,100,1,160,0,124,0,106,1,116,2,106,3,161,2, - 83,0,41,2,114,161,0,0,0,114,153,0,0,0,41,4, - 114,45,0,0,0,114,1,0,0,0,114,173,0,0,0,114, - 138,0,0,0,41,1,218,1,109,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,99,0,0,0,23,3,0, - 0,115,2,0,0,0,0,7,122,26,70,114,111,122,101,110, - 73,109,112,111,114,116,101,114,46,109,111,100,117,108,101,95, - 114,101,112,114,78,99,4,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,5,0,0,0,67,0,0,0,115,34, - 0,0,0,116,0,160,1,124,1,161,1,114,26,116,2,124, - 1,124,0,124,0,106,3,100,1,141,3,83,0,100,0,83, - 0,100,0,83,0,41,2,78,114,137,0,0,0,41,4,114, - 57,0,0,0,114,88,0,0,0,114,91,0,0,0,114,138, - 0,0,0,114,162,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,166,0,0,0,32,3,0,0, - 115,6,0,0,0,0,2,10,1,16,2,122,24,70,114,111, - 122,101,110,73,109,112,111,114,116,101,114,46,102,105,110,100, - 95,115,112,101,99,99,3,0,0,0,0,0,0,0,0,0, - 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,18, - 0,0,0,116,0,160,1,124,1,161,1,114,14,124,0,83, - 0,100,1,83,0,41,2,122,93,70,105,110,100,32,97,32, - 102,114,111,122,101,110,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, - 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,46,32,32,85,115,101,32,102,105,110,100,95,115,112,101, - 99,40,41,32,105,110,115,116,101,97,100,46,10,10,32,32, - 32,32,32,32,32,32,78,41,2,114,57,0,0,0,114,88, - 0,0,0,41,3,114,163,0,0,0,114,81,0,0,0,114, - 164,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,167,0,0,0,39,3,0,0,115,2,0,0, - 0,0,7,122,26,70,114,111,122,101,110,73,109,112,111,114, - 116,101,114,46,102,105,110,100,95,109,111,100,117,108,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, - 0,41,2,122,42,85,115,101,32,100,101,102,97,117,108,116, - 32,115,101,109,97,110,116,105,99,115,32,102,111,114,32,109, - 111,100,117,108,101,32,99,114,101,97,116,105,111,110,46,78, - 114,10,0,0,0,41,2,114,163,0,0,0,114,95,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 114,149,0,0,0,48,3,0,0,115,2,0,0,0,0,2, - 122,28,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,1, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, - 0,0,0,67,0,0,0,115,64,0,0,0,124,0,106,0, - 106,1,125,1,116,2,160,3,124,1,161,1,115,36,116,4, - 100,1,160,5,124,1,161,1,124,1,100,2,141,2,130,1, - 116,6,116,2,106,7,124,1,131,2,125,2,116,8,124,2, - 124,0,106,9,131,2,1,0,100,0,83,0,114,87,0,0, - 0,41,10,114,105,0,0,0,114,17,0,0,0,114,57,0, - 0,0,114,88,0,0,0,114,79,0,0,0,114,45,0,0, - 0,114,67,0,0,0,218,17,103,101,116,95,102,114,111,122, - 101,110,95,111,98,106,101,99,116,218,4,101,120,101,99,114, - 7,0,0,0,41,3,114,96,0,0,0,114,17,0,0,0, - 218,4,99,111,100,101,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,150,0,0,0,52,3,0,0,115,14, - 0,0,0,0,2,8,1,10,1,10,1,2,255,6,2,12, - 1,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101, - 114,46,101,120,101,99,95,109,111,100,117,108,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0, - 0,0,67,0,0,0,115,10,0,0,0,116,0,124,0,124, - 1,131,2,83,0,41,1,122,95,76,111,97,100,32,97,32, - 102,114,111,122,101,110,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, - 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,46,32,32,85,115,101,32,101,120,101,99,95,109,111,100, - 117,108,101,40,41,32,105,110,115,116,101,97,100,46,10,10, - 32,32,32,32,32,32,32,32,41,1,114,97,0,0,0,114, - 168,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,114,155,0,0,0,61,3,0,0,115,2,0,0, - 0,0,7,122,26,70,114,111,122,101,110,73,109,112,111,114, - 116,101,114,46,108,111,97,100,95,109,111,100,117,108,101,99, - 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,67,0,0,0,115,10,0,0,0,116,0,160, - 1,124,1,161,1,83,0,41,1,122,45,82,101,116,117,114, - 110,32,116,104,101,32,99,111,100,101,32,111,98,106,101,99, - 116,32,102,111,114,32,116,104,101,32,102,114,111,122,101,110, - 32,109,111,100,117,108,101,46,41,2,114,57,0,0,0,114, - 175,0,0,0,114,168,0,0,0,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,169,0,0,0,70,3,0, - 0,115,2,0,0,0,0,4,122,23,70,114,111,122,101,110, - 73,109,112,111,114,116,101,114,46,103,101,116,95,99,111,100, - 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, - 1,83,0,41,2,122,54,82,101,116,117,114,110,32,78,111, - 110,101,32,97,115,32,102,114,111,122,101,110,32,109,111,100, - 117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101, - 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,10, - 0,0,0,114,168,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,170,0,0,0,76,3,0,0, - 115,2,0,0,0,0,4,122,25,70,114,111,122,101,110,73, - 109,112,111,114,116,101,114,46,103,101,116,95,115,111,117,114, - 99,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,67,0,0,0,115,10,0,0,0, - 116,0,160,1,124,1,161,1,83,0,41,1,122,46,82,101, - 116,117,114,110,32,84,114,117,101,32,105,102,32,116,104,101, - 32,102,114,111,122,101,110,32,109,111,100,117,108,101,32,105, - 115,32,97,32,112,97,99,107,97,103,101,46,41,2,114,57, - 0,0,0,90,17,105,115,95,102,114,111,122,101,110,95,112, - 97,99,107,97,103,101,114,168,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,115,0,0,0,82, - 3,0,0,115,2,0,0,0,0,4,122,25,70,114,111,122, - 101,110,73,109,112,111,114,116,101,114,46,105,115,95,112,97, - 99,107,97,103,101,41,2,78,78,41,1,78,41,17,114,1, - 0,0,0,114,0,0,0,0,114,2,0,0,0,114,3,0, - 0,0,114,138,0,0,0,114,171,0,0,0,114,99,0,0, - 0,114,172,0,0,0,114,166,0,0,0,114,167,0,0,0, - 114,149,0,0,0,114,150,0,0,0,114,155,0,0,0,114, - 90,0,0,0,114,169,0,0,0,114,170,0,0,0,114,115, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,173,0,0,0,12,3,0,0, - 115,46,0,0,0,8,2,4,7,4,2,2,1,10,8,2, - 1,12,6,2,1,12,8,2,1,10,3,2,1,10,8,2, - 1,10,8,2,1,2,1,12,4,2,1,2,1,12,4,2, - 1,2,1,114,173,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, - 0,115,32,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, - 90,5,100,6,83,0,41,7,218,18,95,73,109,112,111,114, - 116,76,111,99,107,67,111,110,116,101,120,116,122,36,67,111, - 110,116,101,120,116,32,109,97,110,97,103,101,114,32,102,111, - 114,32,116,104,101,32,105,109,112,111,114,116,32,108,111,99, - 107,46,99,1,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,2,0,0,0,67,0,0,0,115,12,0,0,0, - 116,0,160,1,161,0,1,0,100,1,83,0,41,2,122,24, - 65,99,113,117,105,114,101,32,116,104,101,32,105,109,112,111, - 114,116,32,108,111,99,107,46,78,41,2,114,57,0,0,0, - 114,58,0,0,0,114,47,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,54,0,0,0,95,3, - 0,0,115,2,0,0,0,0,2,122,28,95,73,109,112,111, - 114,116,76,111,99,107,67,111,110,116,101,120,116,46,95,95, - 101,110,116,101,114,95,95,99,4,0,0,0,0,0,0,0, - 0,0,0,0,4,0,0,0,2,0,0,0,67,0,0,0, - 115,12,0,0,0,116,0,160,1,161,0,1,0,100,1,83, - 0,41,2,122,60,82,101,108,101,97,115,101,32,116,104,101, - 32,105,109,112,111,114,116,32,108,111,99,107,32,114,101,103, - 97,114,100,108,101,115,115,32,111,102,32,97,110,121,32,114, - 97,105,115,101,100,32,101,120,99,101,112,116,105,111,110,115, - 46,78,41,2,114,57,0,0,0,114,60,0,0,0,41,4, - 114,30,0,0,0,218,8,101,120,99,95,116,121,112,101,218, - 9,101,120,99,95,118,97,108,117,101,218,13,101,120,99,95, - 116,114,97,99,101,98,97,99,107,114,10,0,0,0,114,10, - 0,0,0,114,11,0,0,0,114,56,0,0,0,99,3,0, - 0,115,2,0,0,0,0,2,122,27,95,73,109,112,111,114, - 116,76,111,99,107,67,111,110,116,101,120,116,46,95,95,101, - 120,105,116,95,95,78,41,6,114,1,0,0,0,114,0,0, - 0,0,114,2,0,0,0,114,3,0,0,0,114,54,0,0, - 0,114,56,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,178,0,0,0,91, - 3,0,0,115,6,0,0,0,8,2,4,2,8,4,114,178, - 0,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, - 5,0,0,0,5,0,0,0,67,0,0,0,115,64,0,0, - 0,124,1,160,0,100,1,124,2,100,2,24,0,161,2,125, - 3,116,1,124,3,131,1,124,2,107,0,114,36,116,2,100, - 3,131,1,130,1,124,3,100,4,25,0,125,4,124,0,114, - 60,100,5,160,3,124,4,124,0,161,2,83,0,124,4,83, - 0,41,6,122,50,82,101,115,111,108,118,101,32,97,32,114, - 101,108,97,116,105,118,101,32,109,111,100,117,108,101,32,110, - 97,109,101,32,116,111,32,97,110,32,97,98,115,111,108,117, - 116,101,32,111,110,101,46,114,128,0,0,0,114,37,0,0, - 0,122,50,97,116,116,101,109,112,116,101,100,32,114,101,108, - 97,116,105,118,101,32,105,109,112,111,114,116,32,98,101,121, - 111,110,100,32,116,111,112,45,108,101,118,101,108,32,112,97, - 99,107,97,103,101,114,22,0,0,0,250,5,123,125,46,123, - 125,41,4,218,6,114,115,112,108,105,116,218,3,108,101,110, - 218,10,86,97,108,117,101,69,114,114,111,114,114,45,0,0, - 0,41,5,114,17,0,0,0,218,7,112,97,99,107,97,103, - 101,218,5,108,101,118,101,108,90,4,98,105,116,115,90,4, - 98,97,115,101,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,13,95,114,101,115,111,108,118,101,95,110,97, - 109,101,104,3,0,0,115,10,0,0,0,0,2,16,1,12, - 1,8,1,8,1,114,188,0,0,0,99,3,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, - 0,0,0,115,34,0,0,0,124,0,160,0,124,1,124,2, - 161,2,125,3,124,3,100,0,107,8,114,24,100,0,83,0, - 116,1,124,1,124,3,131,2,83,0,114,13,0,0,0,41, - 2,114,167,0,0,0,114,91,0,0,0,41,4,218,6,102, - 105,110,100,101,114,114,17,0,0,0,114,164,0,0,0,114, - 109,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,17,95,102,105,110,100,95,115,112,101,99,95, - 108,101,103,97,99,121,113,3,0,0,115,8,0,0,0,0, - 3,12,1,8,1,4,1,114,190,0,0,0,99,3,0,0, - 0,0,0,0,0,0,0,0,0,10,0,0,0,10,0,0, - 0,67,0,0,0,115,12,1,0,0,116,0,106,1,125,3, - 124,3,100,1,107,8,114,22,116,2,100,2,131,1,130,1, - 124,3,115,38,116,3,160,4,100,3,116,5,161,2,1,0, - 124,0,116,0,106,6,107,6,125,4,124,3,68,0,93,210, - 125,5,116,7,131,0,143,84,1,0,122,10,124,5,106,8, - 125,6,87,0,110,54,4,0,116,9,107,10,114,128,1,0, - 1,0,1,0,116,10,124,5,124,0,124,1,131,3,125,7, - 124,7,100,1,107,8,114,124,89,0,87,0,53,0,81,0, - 82,0,163,0,113,52,89,0,110,14,88,0,124,6,124,0, - 124,1,124,2,131,3,125,7,87,0,53,0,81,0,82,0, - 88,0,124,7,100,1,107,9,114,52,124,4,144,0,115,254, - 124,0,116,0,106,6,107,6,144,0,114,254,116,0,106,6, - 124,0,25,0,125,8,122,10,124,8,106,11,125,9,87,0, - 110,28,4,0,116,9,107,10,114,226,1,0,1,0,1,0, - 124,7,6,0,89,0,2,0,1,0,83,0,88,0,124,9, - 100,1,107,8,114,244,124,7,2,0,1,0,83,0,124,9, - 2,0,1,0,83,0,113,52,124,7,2,0,1,0,83,0, - 113,52,100,1,83,0,41,4,122,21,70,105,110,100,32,97, - 32,109,111,100,117,108,101,39,115,32,115,112,101,99,46,78, - 122,53,115,121,115,46,109,101,116,97,95,112,97,116,104,32, - 105,115,32,78,111,110,101,44,32,80,121,116,104,111,110,32, - 105,115,32,108,105,107,101,108,121,32,115,104,117,116,116,105, - 110,103,32,100,111,119,110,122,22,115,121,115,46,109,101,116, - 97,95,112,97,116,104,32,105,115,32,101,109,112,116,121,41, - 12,114,15,0,0,0,218,9,109,101,116,97,95,112,97,116, - 104,114,79,0,0,0,218,9,95,119,97,114,110,105,110,103, - 115,218,4,119,97,114,110,218,13,73,109,112,111,114,116,87, - 97,114,110,105,110,103,114,92,0,0,0,114,178,0,0,0, - 114,166,0,0,0,114,106,0,0,0,114,190,0,0,0,114, - 105,0,0,0,41,10,114,17,0,0,0,114,164,0,0,0, - 114,165,0,0,0,114,191,0,0,0,90,9,105,115,95,114, - 101,108,111,97,100,114,189,0,0,0,114,166,0,0,0,114, - 95,0,0,0,114,96,0,0,0,114,105,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,10,95, - 102,105,110,100,95,115,112,101,99,122,3,0,0,115,54,0, - 0,0,0,2,6,1,8,2,8,3,4,1,12,5,10,1, - 8,1,8,1,2,1,10,1,14,1,12,1,8,1,20,2, - 22,1,8,2,18,1,10,1,2,1,10,1,14,4,14,2, - 8,1,8,2,10,2,10,2,114,195,0,0,0,99,3,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,5,0, - 0,0,67,0,0,0,115,108,0,0,0,116,0,124,0,116, - 1,131,2,115,28,116,2,100,1,160,3,116,4,124,0,131, - 1,161,1,131,1,130,1,124,2,100,2,107,0,114,44,116, - 5,100,3,131,1,130,1,124,2,100,2,107,4,114,84,116, - 0,124,1,116,1,131,2,115,72,116,2,100,4,131,1,130, - 1,110,12,124,1,115,84,116,6,100,5,131,1,130,1,124, - 0,115,104,124,2,100,2,107,2,114,104,116,5,100,6,131, - 1,130,1,100,7,83,0,41,8,122,28,86,101,114,105,102, - 121,32,97,114,103,117,109,101,110,116,115,32,97,114,101,32, - 34,115,97,110,101,34,46,122,31,109,111,100,117,108,101,32, - 110,97,109,101,32,109,117,115,116,32,98,101,32,115,116,114, - 44,32,110,111,116,32,123,125,114,22,0,0,0,122,18,108, - 101,118,101,108,32,109,117,115,116,32,98,101,32,62,61,32, - 48,122,31,95,95,112,97,99,107,97,103,101,95,95,32,110, - 111,116,32,115,101,116,32,116,111,32,97,32,115,116,114,105, - 110,103,122,54,97,116,116,101,109,112,116,101,100,32,114,101, - 108,97,116,105,118,101,32,105,109,112,111,114,116,32,119,105, - 116,104,32,110,111,32,107,110,111,119,110,32,112,97,114,101, - 110,116,32,112,97,99,107,97,103,101,122,17,69,109,112,116, - 121,32,109,111,100,117,108,101,32,110,97,109,101,78,41,7, - 218,10,105,115,105,110,115,116,97,110,99,101,218,3,115,116, - 114,218,9,84,121,112,101,69,114,114,111,114,114,45,0,0, - 0,114,14,0,0,0,114,185,0,0,0,114,79,0,0,0, - 169,3,114,17,0,0,0,114,186,0,0,0,114,187,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,13,95,115,97,110,105,116,121,95,99,104,101,99,107,169, - 3,0,0,115,22,0,0,0,0,2,10,1,18,1,8,1, - 8,1,8,1,10,1,10,1,4,1,8,2,12,1,114,200, - 0,0,0,122,16,78,111,32,109,111,100,117,108,101,32,110, - 97,109,101,100,32,122,4,123,33,114,125,99,2,0,0,0, - 0,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0, - 67,0,0,0,115,220,0,0,0,100,0,125,2,124,0,160, - 0,100,1,161,1,100,2,25,0,125,3,124,3,114,134,124, - 3,116,1,106,2,107,7,114,42,116,3,124,1,124,3,131, - 2,1,0,124,0,116,1,106,2,107,6,114,62,116,1,106, - 2,124,0,25,0,83,0,116,1,106,2,124,3,25,0,125, - 4,122,10,124,4,106,4,125,2,87,0,110,50,4,0,116, - 5,107,10,114,132,1,0,1,0,1,0,116,6,100,3,23, - 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124, - 0,100,4,141,2,100,0,130,2,89,0,110,2,88,0,116, - 9,124,0,124,2,131,2,125,6,124,6,100,0,107,8,114, - 172,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141, - 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,114, - 216,116,1,106,2,124,3,25,0,125,4,116,11,124,4,124, - 0,160,0,100,1,161,1,100,5,25,0,124,7,131,3,1, - 0,124,7,83,0,41,6,78,114,128,0,0,0,114,22,0, - 0,0,122,23,59,32,123,33,114,125,32,105,115,32,110,111, - 116,32,97,32,112,97,99,107,97,103,101,114,16,0,0,0, - 233,2,0,0,0,41,12,114,129,0,0,0,114,15,0,0, - 0,114,92,0,0,0,114,67,0,0,0,114,141,0,0,0, - 114,106,0,0,0,218,8,95,69,82,82,95,77,83,71,114, - 45,0,0,0,218,19,77,111,100,117,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,114,195,0,0,0,114,159, - 0,0,0,114,5,0,0,0,41,8,114,17,0,0,0,218, - 7,105,109,112,111,114,116,95,114,164,0,0,0,114,130,0, - 0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108, - 101,114,157,0,0,0,114,95,0,0,0,114,96,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 23,95,102,105,110,100,95,97,110,100,95,108,111,97,100,95, - 117,110,108,111,99,107,101,100,188,3,0,0,115,42,0,0, - 0,0,1,4,1,14,1,4,1,10,1,10,2,10,1,10, - 1,10,1,2,1,10,1,14,1,16,1,20,1,10,1,8, - 1,20,2,8,1,4,2,10,1,22,1,114,205,0,0,0, - 99,2,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,10,0,0,0,67,0,0,0,115,106,0,0,0,116,0, - 124,0,131,1,143,50,1,0,116,1,106,2,160,3,124,0, - 116,4,161,2,125,2,124,2,116,4,107,8,114,54,116,5, - 124,0,124,1,131,2,87,0,2,0,53,0,81,0,82,0, - 163,0,83,0,87,0,53,0,81,0,82,0,88,0,124,2, - 100,1,107,8,114,94,100,2,160,6,124,0,161,1,125,3, - 116,7,124,3,124,0,100,3,141,2,130,1,116,8,124,0, - 131,1,1,0,124,2,83,0,41,4,122,25,70,105,110,100, - 32,97,110,100,32,108,111,97,100,32,116,104,101,32,109,111, - 100,117,108,101,46,78,122,40,105,109,112,111,114,116,32,111, - 102,32,123,125,32,104,97,108,116,101,100,59,32,78,111,110, - 101,32,105,110,32,115,121,115,46,109,111,100,117,108,101,115, - 114,16,0,0,0,41,9,114,50,0,0,0,114,15,0,0, - 0,114,92,0,0,0,114,34,0,0,0,218,14,95,78,69, - 69,68,83,95,76,79,65,68,73,78,71,114,205,0,0,0, - 114,45,0,0,0,114,203,0,0,0,114,65,0,0,0,41, - 4,114,17,0,0,0,114,204,0,0,0,114,96,0,0,0, - 114,75,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,14,95,102,105,110,100,95,97,110,100,95, - 108,111,97,100,218,3,0,0,115,22,0,0,0,0,2,10, - 1,14,1,8,1,32,2,8,1,4,1,2,255,4,2,12, - 2,8,1,114,207,0,0,0,114,22,0,0,0,99,3,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,4,0, - 0,0,67,0,0,0,115,42,0,0,0,116,0,124,0,124, - 1,124,2,131,3,1,0,124,2,100,1,107,4,114,32,116, - 1,124,0,124,1,124,2,131,3,125,0,116,2,124,0,116, - 3,131,2,83,0,41,2,97,50,1,0,0,73,109,112,111, - 114,116,32,97,110,100,32,114,101,116,117,114,110,32,116,104, - 101,32,109,111,100,117,108,101,32,98,97,115,101,100,32,111, - 110,32,105,116,115,32,110,97,109,101,44,32,116,104,101,32, - 112,97,99,107,97,103,101,32,116,104,101,32,99,97,108,108, - 32,105,115,10,32,32,32,32,98,101,105,110,103,32,109,97, - 100,101,32,102,114,111,109,44,32,97,110,100,32,116,104,101, - 32,108,101,118,101,108,32,97,100,106,117,115,116,109,101,110, - 116,46,10,10,32,32,32,32,84,104,105,115,32,102,117,110, - 99,116,105,111,110,32,114,101,112,114,101,115,101,110,116,115, - 32,116,104,101,32,103,114,101,97,116,101,115,116,32,99,111, - 109,109,111,110,32,100,101,110,111,109,105,110,97,116,111,114, - 32,111,102,32,102,117,110,99,116,105,111,110,97,108,105,116, - 121,10,32,32,32,32,98,101,116,119,101,101,110,32,105,109, - 112,111,114,116,95,109,111,100,117,108,101,32,97,110,100,32, - 95,95,105,109,112,111,114,116,95,95,46,32,84,104,105,115, - 32,105,110,99,108,117,100,101,115,32,115,101,116,116,105,110, - 103,32,95,95,112,97,99,107,97,103,101,95,95,32,105,102, - 10,32,32,32,32,116,104,101,32,108,111,97,100,101,114,32, - 100,105,100,32,110,111,116,46,10,10,32,32,32,32,114,22, - 0,0,0,41,4,114,200,0,0,0,114,188,0,0,0,114, - 207,0,0,0,218,11,95,103,99,100,95,105,109,112,111,114, - 116,114,199,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,208,0,0,0,234,3,0,0,115,8, - 0,0,0,0,9,12,1,8,1,12,1,114,208,0,0,0, - 169,1,218,9,114,101,99,117,114,115,105,118,101,99,3,0, - 0,0,0,0,0,0,1,0,0,0,8,0,0,0,11,0, - 0,0,67,0,0,0,115,226,0,0,0,124,1,68,0,93, - 216,125,4,116,0,124,4,116,1,131,2,115,66,124,3,114, - 34,124,0,106,2,100,1,23,0,125,5,110,4,100,2,125, - 5,116,3,100,3,124,5,155,0,100,4,116,4,124,4,131, - 1,106,2,155,0,157,4,131,1,130,1,110,154,124,4,100, - 5,107,2,114,108,124,3,115,106,116,5,124,0,100,6,131, - 2,114,106,116,6,124,0,124,0,106,7,124,2,100,7,100, - 8,141,4,1,0,110,112,116,5,124,0,124,4,131,2,115, - 220,100,9,160,8,124,0,106,2,124,4,161,2,125,6,122, - 14,116,9,124,2,124,6,131,2,1,0,87,0,110,72,4, - 0,116,10,107,10,114,218,1,0,125,7,1,0,122,42,124, - 7,106,11,124,6,107,2,114,200,116,12,106,13,160,14,124, - 6,116,15,161,2,100,10,107,9,114,200,87,0,89,0,162, - 8,113,4,130,0,87,0,53,0,100,10,125,7,126,7,88, - 0,89,0,110,2,88,0,113,4,124,0,83,0,41,11,122, - 238,70,105,103,117,114,101,32,111,117,116,32,119,104,97,116, - 32,95,95,105,109,112,111,114,116,95,95,32,115,104,111,117, - 108,100,32,114,101,116,117,114,110,46,10,10,32,32,32,32, - 84,104,101,32,105,109,112,111,114,116,95,32,112,97,114,97, - 109,101,116,101,114,32,105,115,32,97,32,99,97,108,108,97, - 98,108,101,32,119,104,105,99,104,32,116,97,107,101,115,32, - 116,104,101,32,110,97,109,101,32,111,102,32,109,111,100,117, - 108,101,32,116,111,10,32,32,32,32,105,109,112,111,114,116, - 46,32,73,116,32,105,115,32,114,101,113,117,105,114,101,100, - 32,116,111,32,100,101,99,111,117,112,108,101,32,116,104,101, - 32,102,117,110,99,116,105,111,110,32,102,114,111,109,32,97, - 115,115,117,109,105,110,103,32,105,109,112,111,114,116,108,105, - 98,39,115,10,32,32,32,32,105,109,112,111,114,116,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,105,115, - 32,100,101,115,105,114,101,100,46,10,10,32,32,32,32,122, - 8,46,95,95,97,108,108,95,95,122,13,96,96,102,114,111, - 109,32,108,105,115,116,39,39,122,8,73,116,101,109,32,105, - 110,32,122,18,32,109,117,115,116,32,98,101,32,115,116,114, - 44,32,110,111,116,32,250,1,42,218,7,95,95,97,108,108, - 95,95,84,114,209,0,0,0,114,182,0,0,0,78,41,16, - 114,196,0,0,0,114,197,0,0,0,114,1,0,0,0,114, - 198,0,0,0,114,14,0,0,0,114,4,0,0,0,218,16, - 95,104,97,110,100,108,101,95,102,114,111,109,108,105,115,116, - 114,212,0,0,0,114,45,0,0,0,114,67,0,0,0,114, - 203,0,0,0,114,17,0,0,0,114,15,0,0,0,114,92, - 0,0,0,114,34,0,0,0,114,206,0,0,0,41,8,114, - 96,0,0,0,218,8,102,114,111,109,108,105,115,116,114,204, - 0,0,0,114,210,0,0,0,218,1,120,90,5,119,104,101, - 114,101,90,9,102,114,111,109,95,110,97,109,101,90,3,101, - 120,99,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,213,0,0,0,249,3,0,0,115,44,0,0,0,0, - 10,8,1,10,1,4,1,12,2,4,1,28,2,8,1,14, - 1,10,1,2,255,8,2,10,1,14,1,2,1,14,1,16, - 4,10,1,16,255,2,2,8,1,22,1,114,213,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,6,0,0,0,67,0,0,0,115,146,0,0,0,124,0, - 160,0,100,1,161,1,125,1,124,0,160,0,100,2,161,1, - 125,2,124,1,100,3,107,9,114,82,124,2,100,3,107,9, - 114,78,124,1,124,2,106,1,107,3,114,78,116,2,106,3, - 100,4,124,1,155,2,100,5,124,2,106,1,155,2,100,6, - 157,5,116,4,100,7,100,8,141,3,1,0,124,1,83,0, - 124,2,100,3,107,9,114,96,124,2,106,1,83,0,116,2, - 106,3,100,9,116,4,100,7,100,8,141,3,1,0,124,0, - 100,10,25,0,125,1,100,11,124,0,107,7,114,142,124,1, - 160,5,100,12,161,1,100,13,25,0,125,1,124,1,83,0, - 41,14,122,167,67,97,108,99,117,108,97,116,101,32,119,104, - 97,116,32,95,95,112,97,99,107,97,103,101,95,95,32,115, - 104,111,117,108,100,32,98,101,46,10,10,32,32,32,32,95, - 95,112,97,99,107,97,103,101,95,95,32,105,115,32,110,111, - 116,32,103,117,97,114,97,110,116,101,101,100,32,116,111,32, - 98,101,32,100,101,102,105,110,101,100,32,111,114,32,99,111, - 117,108,100,32,98,101,32,115,101,116,32,116,111,32,78,111, - 110,101,10,32,32,32,32,116,111,32,114,101,112,114,101,115, - 101,110,116,32,116,104,97,116,32,105,116,115,32,112,114,111, - 112,101,114,32,118,97,108,117,101,32,105,115,32,117,110,107, - 110,111,119,110,46,10,10,32,32,32,32,114,145,0,0,0, - 114,105,0,0,0,78,122,32,95,95,112,97,99,107,97,103, - 101,95,95,32,33,61,32,95,95,115,112,101,99,95,95,46, - 112,97,114,101,110,116,32,40,122,4,32,33,61,32,250,1, - 41,233,3,0,0,0,41,1,90,10,115,116,97,99,107,108, - 101,118,101,108,122,89,99,97,110,39,116,32,114,101,115,111, - 108,118,101,32,112,97,99,107,97,103,101,32,102,114,111,109, - 32,95,95,115,112,101,99,95,95,32,111,114,32,95,95,112, - 97,99,107,97,103,101,95,95,44,32,102,97,108,108,105,110, - 103,32,98,97,99,107,32,111,110,32,95,95,110,97,109,101, - 95,95,32,97,110,100,32,95,95,112,97,116,104,95,95,114, - 1,0,0,0,114,141,0,0,0,114,128,0,0,0,114,22, - 0,0,0,41,6,114,34,0,0,0,114,130,0,0,0,114, - 192,0,0,0,114,193,0,0,0,114,194,0,0,0,114,129, - 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,186, - 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,17,95,99,97,108,99,95,95, - 95,112,97,99,107,97,103,101,95,95,30,4,0,0,115,38, - 0,0,0,0,7,10,1,10,1,8,1,18,1,22,2,2, - 0,2,254,6,3,4,1,8,1,6,2,6,2,2,0,2, - 254,6,3,8,1,8,1,14,1,114,219,0,0,0,114,10, - 0,0,0,99,5,0,0,0,0,0,0,0,0,0,0,0, - 9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,0, - 0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125, - 5,110,36,124,1,100,2,107,9,114,30,124,1,110,2,105, - 0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,124, - 7,124,4,131,3,125,5,124,3,115,150,124,4,100,1,107, - 2,114,84,116,0,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,83,0,124,0,115,92,124,5,83,0,116,3,124, - 0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,25, - 0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,100, - 2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,25, - 0,25,0,83,0,110,26,116,7,124,5,100,4,131,2,114, - 172,116,8,124,5,124,3,116,0,131,3,83,0,124,5,83, - 0,100,2,83,0,41,5,97,215,1,0,0,73,109,112,111, - 114,116,32,97,32,109,111,100,117,108,101,46,10,10,32,32, - 32,32,84,104,101,32,39,103,108,111,98,97,108,115,39,32, - 97,114,103,117,109,101,110,116,32,105,115,32,117,115,101,100, - 32,116,111,32,105,110,102,101,114,32,119,104,101,114,101,32, - 116,104,101,32,105,109,112,111,114,116,32,105,115,32,111,99, - 99,117,114,114,105,110,103,32,102,114,111,109,10,32,32,32, - 32,116,111,32,104,97,110,100,108,101,32,114,101,108,97,116, - 105,118,101,32,105,109,112,111,114,116,115,46,32,84,104,101, - 32,39,108,111,99,97,108,115,39,32,97,114,103,117,109,101, - 110,116,32,105,115,32,105,103,110,111,114,101,100,46,32,84, - 104,101,10,32,32,32,32,39,102,114,111,109,108,105,115,116, - 39,32,97,114,103,117,109,101,110,116,32,115,112,101,99,105, - 102,105,101,115,32,119,104,97,116,32,115,104,111,117,108,100, - 32,101,120,105,115,116,32,97,115,32,97,116,116,114,105,98, - 117,116,101,115,32,111,110,32,116,104,101,32,109,111,100,117, - 108,101,10,32,32,32,32,98,101,105,110,103,32,105,109,112, - 111,114,116,101,100,32,40,101,46,103,46,32,96,96,102,114, - 111,109,32,109,111,100,117,108,101,32,105,109,112,111,114,116, - 32,60,102,114,111,109,108,105,115,116,62,96,96,41,46,32, - 32,84,104,101,32,39,108,101,118,101,108,39,10,32,32,32, - 32,97,114,103,117,109,101,110,116,32,114,101,112,114,101,115, - 101,110,116,115,32,116,104,101,32,112,97,99,107,97,103,101, - 32,108,111,99,97,116,105,111,110,32,116,111,32,105,109,112, - 111,114,116,32,102,114,111,109,32,105,110,32,97,32,114,101, - 108,97,116,105,118,101,10,32,32,32,32,105,109,112,111,114, - 116,32,40,101,46,103,46,32,96,96,102,114,111,109,32,46, - 46,112,107,103,32,105,109,112,111,114,116,32,109,111,100,96, - 96,32,119,111,117,108,100,32,104,97,118,101,32,97,32,39, - 108,101,118,101,108,39,32,111,102,32,50,41,46,10,10,32, - 32,32,32,114,22,0,0,0,78,114,128,0,0,0,114,141, - 0,0,0,41,9,114,208,0,0,0,114,219,0,0,0,218, - 9,112,97,114,116,105,116,105,111,110,114,184,0,0,0,114, - 15,0,0,0,114,92,0,0,0,114,1,0,0,0,114,4, - 0,0,0,114,213,0,0,0,41,9,114,17,0,0,0,114, - 218,0,0,0,218,6,108,111,99,97,108,115,114,214,0,0, - 0,114,187,0,0,0,114,96,0,0,0,90,8,103,108,111, - 98,97,108,115,95,114,186,0,0,0,90,7,99,117,116,95, - 111,102,102,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,218,10,95,95,105,109,112,111,114,116,95,95,57,4, - 0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,8, - 1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,32, - 1,10,1,12,2,114,222,0,0,0,99,1,0,0,0,0, + 170,0,0,0,76,3,0,0,115,2,0,0,0,0,4,122, + 25,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, + 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,116,0,160,1,124,0,161,1, - 125,1,124,1,100,0,107,8,114,30,116,2,100,1,124,0, - 23,0,131,1,130,1,116,3,124,1,131,1,83,0,41,2, - 78,122,25,110,111,32,98,117,105,108,116,45,105,110,32,109, - 111,100,117,108,101,32,110,97,109,101,100,32,41,4,114,160, - 0,0,0,114,166,0,0,0,114,79,0,0,0,114,159,0, - 0,0,41,2,114,17,0,0,0,114,95,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,218,18,95, - 98,117,105,108,116,105,110,95,102,114,111,109,95,110,97,109, - 101,94,4,0,0,115,8,0,0,0,0,1,10,1,8,1, - 12,1,114,223,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,10,0,0,0,5,0,0,0,67,0,0,0, - 115,166,0,0,0,124,1,97,0,124,0,97,1,116,2,116, - 1,131,1,125,2,116,1,106,3,160,4,161,0,68,0,93, - 72,92,2,125,3,125,4,116,5,124,4,124,2,131,2,114, - 26,124,3,116,1,106,6,107,6,114,60,116,7,125,5,110, - 18,116,0,160,8,124,3,161,1,114,26,116,9,125,5,110, - 2,113,26,116,10,124,4,124,5,131,2,125,6,116,11,124, - 6,124,4,131,2,1,0,113,26,116,1,106,3,116,12,25, - 0,125,7,100,1,68,0,93,46,125,8,124,8,116,1,106, - 3,107,7,114,138,116,13,124,8,131,1,125,9,110,10,116, - 1,106,3,124,8,25,0,125,9,116,14,124,7,124,8,124, - 9,131,3,1,0,113,114,100,2,83,0,41,3,122,250,83, - 101,116,117,112,32,105,109,112,111,114,116,108,105,98,32,98, - 121,32,105,109,112,111,114,116,105,110,103,32,110,101,101,100, - 101,100,32,98,117,105,108,116,45,105,110,32,109,111,100,117, - 108,101,115,32,97,110,100,32,105,110,106,101,99,116,105,110, - 103,32,116,104,101,109,10,32,32,32,32,105,110,116,111,32, - 116,104,101,32,103,108,111,98,97,108,32,110,97,109,101,115, - 112,97,99,101,46,10,10,32,32,32,32,65,115,32,115,121, - 115,32,105,115,32,110,101,101,100,101,100,32,102,111,114,32, - 115,121,115,46,109,111,100,117,108,101,115,32,97,99,99,101, - 115,115,32,97,110,100,32,95,105,109,112,32,105,115,32,110, - 101,101,100,101,100,32,116,111,32,108,111,97,100,32,98,117, - 105,108,116,45,105,110,10,32,32,32,32,109,111,100,117,108, - 101,115,44,32,116,104,111,115,101,32,116,119,111,32,109,111, - 100,117,108,101,115,32,109,117,115,116,32,98,101,32,101,120, - 112,108,105,99,105,116,108,121,32,112,97,115,115,101,100,32, - 105,110,46,10,10,32,32,32,32,41,3,114,23,0,0,0, - 114,192,0,0,0,114,64,0,0,0,78,41,15,114,57,0, - 0,0,114,15,0,0,0,114,14,0,0,0,114,92,0,0, - 0,218,5,105,116,101,109,115,114,196,0,0,0,114,78,0, - 0,0,114,160,0,0,0,114,88,0,0,0,114,173,0,0, - 0,114,142,0,0,0,114,148,0,0,0,114,1,0,0,0, - 114,223,0,0,0,114,5,0,0,0,41,10,218,10,115,121, - 115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,109, - 111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,121, - 112,101,114,17,0,0,0,114,96,0,0,0,114,109,0,0, - 0,114,95,0,0,0,90,11,115,101,108,102,95,109,111,100, - 117,108,101,90,12,98,117,105,108,116,105,110,95,110,97,109, - 101,90,14,98,117,105,108,116,105,110,95,109,111,100,117,108, - 101,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,6,95,115,101,116,117,112,101,4,0,0,115,36,0,0, - 0,0,9,4,1,4,3,8,1,18,1,10,1,10,1,6, - 1,10,1,6,2,2,1,10,1,12,3,10,1,8,1,10, - 1,10,2,10,1,114,227,0,0,0,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,2, - 1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1, - 106,2,160,3,116,5,161,1,1,0,100,1,83,0,41,2, - 122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116, - 101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32, - 97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,78,41,6,114,227,0,0,0,114,15,0,0,0,114, - 191,0,0,0,114,120,0,0,0,114,160,0,0,0,114,173, - 0,0,0,41,2,114,225,0,0,0,114,226,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 95,105,110,115,116,97,108,108,136,4,0,0,115,6,0,0, - 0,0,2,10,2,12,1,114,228,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, - 0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,0, - 125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,5, - 25,0,161,1,1,0,100,2,83,0,41,3,122,57,73,110, - 115,116,97,108,108,32,105,109,112,111,114,116,101,114,115,32, - 116,104,97,116,32,114,101,113,117,105,114,101,32,101,120,116, - 101,114,110,97,108,32,102,105,108,101,115,121,115,116,101,109, - 32,97,99,99,101,115,115,114,22,0,0,0,78,41,6,218, - 26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, - 105,98,95,101,120,116,101,114,110,97,108,114,126,0,0,0, - 114,228,0,0,0,114,15,0,0,0,114,92,0,0,0,114, - 1,0,0,0,41,1,114,229,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,218,27,95,105,110,115, - 116,97,108,108,95,101,120,116,101,114,110,97,108,95,105,109, - 112,111,114,116,101,114,115,144,4,0,0,115,6,0,0,0, - 0,3,8,1,4,1,114,230,0,0,0,41,2,78,78,41, - 1,78,41,2,78,114,22,0,0,0,41,4,78,78,114,10, - 0,0,0,114,22,0,0,0,41,50,114,3,0,0,0,114, - 126,0,0,0,114,12,0,0,0,114,18,0,0,0,114,59, - 0,0,0,114,33,0,0,0,114,42,0,0,0,114,19,0, - 0,0,114,20,0,0,0,114,49,0,0,0,114,50,0,0, - 0,114,53,0,0,0,114,65,0,0,0,114,67,0,0,0, - 114,76,0,0,0,114,86,0,0,0,114,90,0,0,0,114, - 97,0,0,0,114,111,0,0,0,114,112,0,0,0,114,91, - 0,0,0,114,142,0,0,0,114,148,0,0,0,114,152,0, - 0,0,114,107,0,0,0,114,93,0,0,0,114,158,0,0, - 0,114,159,0,0,0,114,94,0,0,0,114,160,0,0,0, - 114,173,0,0,0,114,178,0,0,0,114,188,0,0,0,114, - 190,0,0,0,114,195,0,0,0,114,200,0,0,0,90,15, - 95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,114, - 202,0,0,0,114,205,0,0,0,218,6,111,98,106,101,99, - 116,114,206,0,0,0,114,207,0,0,0,114,208,0,0,0, - 114,213,0,0,0,114,219,0,0,0,114,222,0,0,0,114, - 223,0,0,0,114,227,0,0,0,114,228,0,0,0,114,230, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,8,60,109,111,100,117,108,101, - 62,1,0,0,0,115,94,0,0,0,4,24,4,2,8,8, - 8,8,4,2,4,3,16,4,14,68,14,21,14,16,8,37, - 8,17,8,11,14,8,8,11,8,12,8,16,8,36,14,101, - 16,26,10,45,14,72,8,17,8,17,8,30,8,37,8,42, - 8,15,14,73,14,79,14,13,8,9,8,9,10,47,8,16, - 4,1,8,2,8,27,6,3,8,16,10,15,14,37,8,27, - 10,37,8,7,8,35,8,8, + 0,0,0,115,10,0,0,0,116,0,160,1,124,1,161,1, + 83,0,41,1,122,46,82,101,116,117,114,110,32,84,114,117, + 101,32,105,102,32,116,104,101,32,102,114,111,122,101,110,32, + 109,111,100,117,108,101,32,105,115,32,97,32,112,97,99,107, + 97,103,101,46,41,2,114,57,0,0,0,90,17,105,115,95, + 102,114,111,122,101,110,95,112,97,99,107,97,103,101,114,168, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,115,0,0,0,82,3,0,0,115,2,0,0,0, + 0,4,122,25,70,114,111,122,101,110,73,109,112,111,114,116, + 101,114,46,105,115,95,112,97,99,107,97,103,101,41,2,78, + 78,41,1,78,41,17,114,1,0,0,0,114,0,0,0,0, + 114,2,0,0,0,114,3,0,0,0,114,138,0,0,0,114, + 171,0,0,0,114,99,0,0,0,114,172,0,0,0,114,166, + 0,0,0,114,167,0,0,0,114,149,0,0,0,114,150,0, + 0,0,114,155,0,0,0,114,90,0,0,0,114,169,0,0, + 0,114,170,0,0,0,114,115,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 173,0,0,0,12,3,0,0,115,46,0,0,0,8,2,4, + 7,4,2,2,1,10,8,2,1,12,6,2,1,12,8,2, + 1,10,3,2,1,10,8,2,1,10,8,2,1,2,1,12, + 4,2,1,2,1,12,4,2,1,2,1,114,173,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,32,0,0,0,101,0, + 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, + 90,4,100,4,100,5,132,0,90,5,100,6,83,0,41,7, + 218,18,95,73,109,112,111,114,116,76,111,99,107,67,111,110, + 116,101,120,116,122,36,67,111,110,116,101,120,116,32,109,97, + 110,97,103,101,114,32,102,111,114,32,116,104,101,32,105,109, + 112,111,114,116,32,108,111,99,107,46,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, + 0,0,0,115,12,0,0,0,116,0,160,1,161,0,1,0, + 100,1,83,0,41,2,122,24,65,99,113,117,105,114,101,32, + 116,104,101,32,105,109,112,111,114,116,32,108,111,99,107,46, + 78,41,2,114,57,0,0,0,114,58,0,0,0,114,47,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,54,0,0,0,95,3,0,0,115,2,0,0,0,0, + 2,122,28,95,73,109,112,111,114,116,76,111,99,107,67,111, + 110,116,101,120,116,46,95,95,101,110,116,101,114,95,95,99, + 4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0, + 2,0,0,0,67,0,0,0,115,12,0,0,0,116,0,160, + 1,161,0,1,0,100,1,83,0,41,2,122,60,82,101,108, + 101,97,115,101,32,116,104,101,32,105,109,112,111,114,116,32, + 108,111,99,107,32,114,101,103,97,114,100,108,101,115,115,32, + 111,102,32,97,110,121,32,114,97,105,115,101,100,32,101,120, + 99,101,112,116,105,111,110,115,46,78,41,2,114,57,0,0, + 0,114,60,0,0,0,41,4,114,30,0,0,0,218,8,101, + 120,99,95,116,121,112,101,218,9,101,120,99,95,118,97,108, + 117,101,218,13,101,120,99,95,116,114,97,99,101,98,97,99, + 107,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,56,0,0,0,99,3,0,0,115,2,0,0,0,0,2, + 122,27,95,73,109,112,111,114,116,76,111,99,107,67,111,110, + 116,101,120,116,46,95,95,101,120,105,116,95,95,78,41,6, + 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, + 3,0,0,0,114,54,0,0,0,114,56,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,178,0,0,0,91,3,0,0,115,6,0,0,0, + 8,2,4,2,8,4,114,178,0,0,0,99,3,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,64,0,0,0,124,1,160,0,100,1,124, + 2,100,2,24,0,161,2,125,3,116,1,124,3,131,1,124, + 2,107,0,114,36,116,2,100,3,131,1,130,1,124,3,100, + 4,25,0,125,4,124,0,114,60,100,5,160,3,124,4,124, + 0,161,2,83,0,124,4,83,0,41,6,122,50,82,101,115, + 111,108,118,101,32,97,32,114,101,108,97,116,105,118,101,32, + 109,111,100,117,108,101,32,110,97,109,101,32,116,111,32,97, + 110,32,97,98,115,111,108,117,116,101,32,111,110,101,46,114, + 128,0,0,0,114,37,0,0,0,122,50,97,116,116,101,109, + 112,116,101,100,32,114,101,108,97,116,105,118,101,32,105,109, + 112,111,114,116,32,98,101,121,111,110,100,32,116,111,112,45, + 108,101,118,101,108,32,112,97,99,107,97,103,101,114,22,0, + 0,0,250,5,123,125,46,123,125,41,4,218,6,114,115,112, + 108,105,116,218,3,108,101,110,218,10,86,97,108,117,101,69, + 114,114,111,114,114,45,0,0,0,41,5,114,17,0,0,0, + 218,7,112,97,99,107,97,103,101,218,5,108,101,118,101,108, + 90,4,98,105,116,115,90,4,98,97,115,101,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,13,95,114,101, + 115,111,108,118,101,95,110,97,109,101,104,3,0,0,115,10, + 0,0,0,0,2,16,1,12,1,8,1,8,1,114,188,0, + 0,0,99,3,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,4,0,0,0,67,0,0,0,115,34,0,0,0, + 124,0,160,0,124,1,124,2,161,2,125,3,124,3,100,0, + 107,8,114,24,100,0,83,0,116,1,124,1,124,3,131,2, + 83,0,114,13,0,0,0,41,2,114,167,0,0,0,114,91, + 0,0,0,41,4,218,6,102,105,110,100,101,114,114,17,0, + 0,0,114,164,0,0,0,114,109,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,17,95,102,105, + 110,100,95,115,112,101,99,95,108,101,103,97,99,121,113,3, + 0,0,115,8,0,0,0,0,3,12,1,8,1,4,1,114, + 190,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, + 0,10,0,0,0,10,0,0,0,67,0,0,0,115,12,1, + 0,0,116,0,106,1,125,3,124,3,100,1,107,8,114,22, + 116,2,100,2,131,1,130,1,124,3,115,38,116,3,160,4, + 100,3,116,5,161,2,1,0,124,0,116,0,106,6,107,6, + 125,4,124,3,68,0,93,210,125,5,116,7,131,0,143,84, + 1,0,122,10,124,5,106,8,125,6,87,0,110,54,4,0, + 116,9,107,10,114,128,1,0,1,0,1,0,116,10,124,5, + 124,0,124,1,131,3,125,7,124,7,100,1,107,8,114,124, + 89,0,87,0,53,0,81,0,82,0,163,0,113,52,89,0, + 110,14,88,0,124,6,124,0,124,1,124,2,131,3,125,7, + 87,0,53,0,81,0,82,0,88,0,124,7,100,1,107,9, + 114,52,124,4,144,0,115,254,124,0,116,0,106,6,107,6, + 144,0,114,254,116,0,106,6,124,0,25,0,125,8,122,10, + 124,8,106,11,125,9,87,0,110,28,4,0,116,9,107,10, + 114,226,1,0,1,0,1,0,124,7,6,0,89,0,2,0, + 1,0,83,0,88,0,124,9,100,1,107,8,114,244,124,7, + 2,0,1,0,83,0,124,9,2,0,1,0,83,0,113,52, + 124,7,2,0,1,0,83,0,113,52,100,1,83,0,41,4, + 122,21,70,105,110,100,32,97,32,109,111,100,117,108,101,39, + 115,32,115,112,101,99,46,78,122,53,115,121,115,46,109,101, + 116,97,95,112,97,116,104,32,105,115,32,78,111,110,101,44, + 32,80,121,116,104,111,110,32,105,115,32,108,105,107,101,108, + 121,32,115,104,117,116,116,105,110,103,32,100,111,119,110,122, + 22,115,121,115,46,109,101,116,97,95,112,97,116,104,32,105, + 115,32,101,109,112,116,121,41,12,114,15,0,0,0,218,9, + 109,101,116,97,95,112,97,116,104,114,79,0,0,0,218,9, + 95,119,97,114,110,105,110,103,115,218,4,119,97,114,110,218, + 13,73,109,112,111,114,116,87,97,114,110,105,110,103,114,92, + 0,0,0,114,178,0,0,0,114,166,0,0,0,114,106,0, + 0,0,114,190,0,0,0,114,105,0,0,0,41,10,114,17, + 0,0,0,114,164,0,0,0,114,165,0,0,0,114,191,0, + 0,0,90,9,105,115,95,114,101,108,111,97,100,114,189,0, + 0,0,114,166,0,0,0,114,95,0,0,0,114,96,0,0, + 0,114,105,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,10,95,102,105,110,100,95,115,112,101, + 99,122,3,0,0,115,54,0,0,0,0,2,6,1,8,2, + 8,3,4,1,12,5,10,1,8,1,8,1,2,1,10,1, + 14,1,12,1,8,1,20,2,22,1,8,2,18,1,10,1, + 2,1,10,1,14,4,14,2,8,1,8,2,10,2,10,2, + 114,195,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,5,0,0,0,67,0,0,0,115,108, + 0,0,0,116,0,124,0,116,1,131,2,115,28,116,2,100, + 1,160,3,116,4,124,0,131,1,161,1,131,1,130,1,124, + 2,100,2,107,0,114,44,116,5,100,3,131,1,130,1,124, + 2,100,2,107,4,114,84,116,0,124,1,116,1,131,2,115, + 72,116,2,100,4,131,1,130,1,110,12,124,1,115,84,116, + 6,100,5,131,1,130,1,124,0,115,104,124,2,100,2,107, + 2,114,104,116,5,100,6,131,1,130,1,100,7,83,0,41, + 8,122,28,86,101,114,105,102,121,32,97,114,103,117,109,101, + 110,116,115,32,97,114,101,32,34,115,97,110,101,34,46,122, + 31,109,111,100,117,108,101,32,110,97,109,101,32,109,117,115, + 116,32,98,101,32,115,116,114,44,32,110,111,116,32,123,125, + 114,22,0,0,0,122,18,108,101,118,101,108,32,109,117,115, + 116,32,98,101,32,62,61,32,48,122,31,95,95,112,97,99, + 107,97,103,101,95,95,32,110,111,116,32,115,101,116,32,116, + 111,32,97,32,115,116,114,105,110,103,122,54,97,116,116,101, + 109,112,116,101,100,32,114,101,108,97,116,105,118,101,32,105, + 109,112,111,114,116,32,119,105,116,104,32,110,111,32,107,110, + 111,119,110,32,112,97,114,101,110,116,32,112,97,99,107,97, + 103,101,122,17,69,109,112,116,121,32,109,111,100,117,108,101, + 32,110,97,109,101,78,41,7,218,10,105,115,105,110,115,116, + 97,110,99,101,218,3,115,116,114,218,9,84,121,112,101,69, + 114,114,111,114,114,45,0,0,0,114,14,0,0,0,114,185, + 0,0,0,114,79,0,0,0,169,3,114,17,0,0,0,114, + 186,0,0,0,114,187,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,13,95,115,97,110,105,116, + 121,95,99,104,101,99,107,169,3,0,0,115,22,0,0,0, + 0,2,10,1,18,1,8,1,8,1,8,1,10,1,10,1, + 4,1,8,2,12,1,114,200,0,0,0,122,16,78,111,32, + 109,111,100,117,108,101,32,110,97,109,101,100,32,122,4,123, + 33,114,125,99,2,0,0,0,0,0,0,0,0,0,0,0, + 8,0,0,0,8,0,0,0,67,0,0,0,115,220,0,0, + 0,100,0,125,2,124,0,160,0,100,1,161,1,100,2,25, + 0,125,3,124,3,114,134,124,3,116,1,106,2,107,7,114, + 42,116,3,124,1,124,3,131,2,1,0,124,0,116,1,106, + 2,107,6,114,62,116,1,106,2,124,0,25,0,83,0,116, + 1,106,2,124,3,25,0,125,4,122,10,124,4,106,4,125, + 2,87,0,110,50,4,0,116,5,107,10,114,132,1,0,1, + 0,1,0,116,6,100,3,23,0,160,7,124,0,124,3,161, + 2,125,5,116,8,124,5,124,0,100,4,141,2,100,0,130, + 2,89,0,110,2,88,0,116,9,124,0,124,2,131,2,125, + 6,124,6,100,0,107,8,114,172,116,8,116,6,160,7,124, + 0,161,1,124,0,100,4,141,2,130,1,110,8,116,10,124, + 6,131,1,125,7,124,3,114,216,116,1,106,2,124,3,25, + 0,125,4,116,11,124,4,124,0,160,0,100,1,161,1,100, + 5,25,0,124,7,131,3,1,0,124,7,83,0,41,6,78, + 114,128,0,0,0,114,22,0,0,0,122,23,59,32,123,33, + 114,125,32,105,115,32,110,111,116,32,97,32,112,97,99,107, + 97,103,101,114,16,0,0,0,233,2,0,0,0,41,12,114, + 129,0,0,0,114,15,0,0,0,114,92,0,0,0,114,67, + 0,0,0,114,141,0,0,0,114,106,0,0,0,218,8,95, + 69,82,82,95,77,83,71,114,45,0,0,0,218,19,77,111, + 100,117,108,101,78,111,116,70,111,117,110,100,69,114,114,111, + 114,114,195,0,0,0,114,159,0,0,0,114,5,0,0,0, + 41,8,114,17,0,0,0,218,7,105,109,112,111,114,116,95, + 114,164,0,0,0,114,130,0,0,0,90,13,112,97,114,101, + 110,116,95,109,111,100,117,108,101,114,157,0,0,0,114,95, + 0,0,0,114,96,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,23,95,102,105,110,100,95,97, + 110,100,95,108,111,97,100,95,117,110,108,111,99,107,101,100, + 188,3,0,0,115,42,0,0,0,0,1,4,1,14,1,4, + 1,10,1,10,2,10,1,10,1,10,1,2,1,10,1,14, + 1,16,1,20,1,10,1,8,1,20,2,8,1,4,2,10, + 1,22,1,114,205,0,0,0,99,2,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,10,0,0,0,67,0,0, + 0,115,106,0,0,0,116,0,124,0,131,1,143,50,1,0, + 116,1,106,2,160,3,124,0,116,4,161,2,125,2,124,2, + 116,4,107,8,114,54,116,5,124,0,124,1,131,2,87,0, + 2,0,53,0,81,0,82,0,163,0,83,0,87,0,53,0, + 81,0,82,0,88,0,124,2,100,1,107,8,114,94,100,2, + 160,6,124,0,161,1,125,3,116,7,124,3,124,0,100,3, + 141,2,130,1,116,8,124,0,131,1,1,0,124,2,83,0, + 41,4,122,25,70,105,110,100,32,97,110,100,32,108,111,97, + 100,32,116,104,101,32,109,111,100,117,108,101,46,78,122,40, + 105,109,112,111,114,116,32,111,102,32,123,125,32,104,97,108, + 116,101,100,59,32,78,111,110,101,32,105,110,32,115,121,115, + 46,109,111,100,117,108,101,115,114,16,0,0,0,41,9,114, + 50,0,0,0,114,15,0,0,0,114,92,0,0,0,114,34, + 0,0,0,218,14,95,78,69,69,68,83,95,76,79,65,68, + 73,78,71,114,205,0,0,0,114,45,0,0,0,114,203,0, + 0,0,114,65,0,0,0,41,4,114,17,0,0,0,114,204, + 0,0,0,114,96,0,0,0,114,75,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,218,14,95,102, + 105,110,100,95,97,110,100,95,108,111,97,100,218,3,0,0, + 115,22,0,0,0,0,2,10,1,14,1,8,1,32,2,8, + 1,4,1,2,255,4,2,12,2,8,1,114,207,0,0,0, + 114,22,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,42, + 0,0,0,116,0,124,0,124,1,124,2,131,3,1,0,124, + 2,100,1,107,4,114,32,116,1,124,0,124,1,124,2,131, + 3,125,0,116,2,124,0,116,3,131,2,83,0,41,2,97, + 50,1,0,0,73,109,112,111,114,116,32,97,110,100,32,114, + 101,116,117,114,110,32,116,104,101,32,109,111,100,117,108,101, + 32,98,97,115,101,100,32,111,110,32,105,116,115,32,110,97, + 109,101,44,32,116,104,101,32,112,97,99,107,97,103,101,32, + 116,104,101,32,99,97,108,108,32,105,115,10,32,32,32,32, + 98,101,105,110,103,32,109,97,100,101,32,102,114,111,109,44, + 32,97,110,100,32,116,104,101,32,108,101,118,101,108,32,97, + 100,106,117,115,116,109,101,110,116,46,10,10,32,32,32,32, + 84,104,105,115,32,102,117,110,99,116,105,111,110,32,114,101, + 112,114,101,115,101,110,116,115,32,116,104,101,32,103,114,101, + 97,116,101,115,116,32,99,111,109,109,111,110,32,100,101,110, + 111,109,105,110,97,116,111,114,32,111,102,32,102,117,110,99, + 116,105,111,110,97,108,105,116,121,10,32,32,32,32,98,101, + 116,119,101,101,110,32,105,109,112,111,114,116,95,109,111,100, + 117,108,101,32,97,110,100,32,95,95,105,109,112,111,114,116, + 95,95,46,32,84,104,105,115,32,105,110,99,108,117,100,101, + 115,32,115,101,116,116,105,110,103,32,95,95,112,97,99,107, + 97,103,101,95,95,32,105,102,10,32,32,32,32,116,104,101, + 32,108,111,97,100,101,114,32,100,105,100,32,110,111,116,46, + 10,10,32,32,32,32,114,22,0,0,0,41,4,114,200,0, + 0,0,114,188,0,0,0,114,207,0,0,0,218,11,95,103, + 99,100,95,105,109,112,111,114,116,114,199,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,208,0, + 0,0,234,3,0,0,115,8,0,0,0,0,9,12,1,8, + 1,12,1,114,208,0,0,0,169,1,218,9,114,101,99,117, + 114,115,105,118,101,99,3,0,0,0,0,0,0,0,1,0, + 0,0,8,0,0,0,11,0,0,0,67,0,0,0,115,226, + 0,0,0,124,1,68,0,93,216,125,4,116,0,124,4,116, + 1,131,2,115,66,124,3,114,34,124,0,106,2,100,1,23, + 0,125,5,110,4,100,2,125,5,116,3,100,3,124,5,155, + 0,100,4,116,4,124,4,131,1,106,2,155,0,157,4,131, + 1,130,1,113,4,124,4,100,5,107,2,114,108,124,3,115, + 220,116,5,124,0,100,6,131,2,114,220,116,6,124,0,124, + 0,106,7,124,2,100,7,100,8,141,4,1,0,113,4,116, + 5,124,0,124,4,131,2,115,4,100,9,160,8,124,0,106, + 2,124,4,161,2,125,6,122,14,116,9,124,2,124,6,131, + 2,1,0,87,0,113,4,4,0,116,10,107,10,114,218,1, + 0,125,7,1,0,122,42,124,7,106,11,124,6,107,2,114, + 200,116,12,106,13,160,14,124,6,116,15,161,2,100,10,107, + 9,114,200,87,0,89,0,162,8,113,4,130,0,87,0,53, + 0,100,10,125,7,126,7,88,0,89,0,113,4,88,0,113, + 4,124,0,83,0,41,11,122,238,70,105,103,117,114,101,32, + 111,117,116,32,119,104,97,116,32,95,95,105,109,112,111,114, + 116,95,95,32,115,104,111,117,108,100,32,114,101,116,117,114, + 110,46,10,10,32,32,32,32,84,104,101,32,105,109,112,111, + 114,116,95,32,112,97,114,97,109,101,116,101,114,32,105,115, + 32,97,32,99,97,108,108,97,98,108,101,32,119,104,105,99, + 104,32,116,97,107,101,115,32,116,104,101,32,110,97,109,101, + 32,111,102,32,109,111,100,117,108,101,32,116,111,10,32,32, + 32,32,105,109,112,111,114,116,46,32,73,116,32,105,115,32, + 114,101,113,117,105,114,101,100,32,116,111,32,100,101,99,111, + 117,112,108,101,32,116,104,101,32,102,117,110,99,116,105,111, + 110,32,102,114,111,109,32,97,115,115,117,109,105,110,103,32, + 105,109,112,111,114,116,108,105,98,39,115,10,32,32,32,32, + 105,109,112,111,114,116,32,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,32,105,115,32,100,101,115,105,114,101,100, + 46,10,10,32,32,32,32,122,8,46,95,95,97,108,108,95, + 95,122,13,96,96,102,114,111,109,32,108,105,115,116,39,39, + 122,8,73,116,101,109,32,105,110,32,122,18,32,109,117,115, + 116,32,98,101,32,115,116,114,44,32,110,111,116,32,250,1, + 42,218,7,95,95,97,108,108,95,95,84,114,209,0,0,0, + 114,182,0,0,0,78,41,16,114,196,0,0,0,114,197,0, + 0,0,114,1,0,0,0,114,198,0,0,0,114,14,0,0, + 0,114,4,0,0,0,218,16,95,104,97,110,100,108,101,95, + 102,114,111,109,108,105,115,116,114,212,0,0,0,114,45,0, + 0,0,114,67,0,0,0,114,203,0,0,0,114,17,0,0, + 0,114,15,0,0,0,114,92,0,0,0,114,34,0,0,0, + 114,206,0,0,0,41,8,114,96,0,0,0,218,8,102,114, + 111,109,108,105,115,116,114,204,0,0,0,114,210,0,0,0, + 218,1,120,90,5,119,104,101,114,101,90,9,102,114,111,109, + 95,110,97,109,101,90,3,101,120,99,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,213,0,0,0,249,3, + 0,0,115,44,0,0,0,0,10,8,1,10,1,4,1,12, + 2,4,1,28,2,8,1,14,1,10,1,2,255,8,2,10, + 1,14,1,2,1,14,1,16,4,10,1,16,255,2,2,8, + 1,22,1,114,213,0,0,0,99,1,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,6,0,0,0,67,0,0, + 0,115,146,0,0,0,124,0,160,0,100,1,161,1,125,1, + 124,0,160,0,100,2,161,1,125,2,124,1,100,3,107,9, + 114,82,124,2,100,3,107,9,114,78,124,1,124,2,106,1, + 107,3,114,78,116,2,106,3,100,4,124,1,155,2,100,5, + 124,2,106,1,155,2,100,6,157,5,116,4,100,7,100,8, + 141,3,1,0,124,1,83,0,124,2,100,3,107,9,114,96, + 124,2,106,1,83,0,116,2,106,3,100,9,116,4,100,7, + 100,8,141,3,1,0,124,0,100,10,25,0,125,1,100,11, + 124,0,107,7,114,142,124,1,160,5,100,12,161,1,100,13, + 25,0,125,1,124,1,83,0,41,14,122,167,67,97,108,99, + 117,108,97,116,101,32,119,104,97,116,32,95,95,112,97,99, + 107,97,103,101,95,95,32,115,104,111,117,108,100,32,98,101, + 46,10,10,32,32,32,32,95,95,112,97,99,107,97,103,101, + 95,95,32,105,115,32,110,111,116,32,103,117,97,114,97,110, + 116,101,101,100,32,116,111,32,98,101,32,100,101,102,105,110, + 101,100,32,111,114,32,99,111,117,108,100,32,98,101,32,115, + 101,116,32,116,111,32,78,111,110,101,10,32,32,32,32,116, + 111,32,114,101,112,114,101,115,101,110,116,32,116,104,97,116, + 32,105,116,115,32,112,114,111,112,101,114,32,118,97,108,117, + 101,32,105,115,32,117,110,107,110,111,119,110,46,10,10,32, + 32,32,32,114,145,0,0,0,114,105,0,0,0,78,122,32, + 95,95,112,97,99,107,97,103,101,95,95,32,33,61,32,95, + 95,115,112,101,99,95,95,46,112,97,114,101,110,116,32,40, + 122,4,32,33,61,32,250,1,41,233,3,0,0,0,41,1, + 90,10,115,116,97,99,107,108,101,118,101,108,122,89,99,97, + 110,39,116,32,114,101,115,111,108,118,101,32,112,97,99,107, + 97,103,101,32,102,114,111,109,32,95,95,115,112,101,99,95, + 95,32,111,114,32,95,95,112,97,99,107,97,103,101,95,95, + 44,32,102,97,108,108,105,110,103,32,98,97,99,107,32,111, + 110,32,95,95,110,97,109,101,95,95,32,97,110,100,32,95, + 95,112,97,116,104,95,95,114,1,0,0,0,114,141,0,0, + 0,114,128,0,0,0,114,22,0,0,0,41,6,114,34,0, + 0,0,114,130,0,0,0,114,192,0,0,0,114,193,0,0, + 0,114,194,0,0,0,114,129,0,0,0,41,3,218,7,103, + 108,111,98,97,108,115,114,186,0,0,0,114,95,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 17,95,99,97,108,99,95,95,95,112,97,99,107,97,103,101, + 95,95,30,4,0,0,115,38,0,0,0,0,7,10,1,10, + 1,8,1,18,1,22,2,2,0,2,254,6,3,4,1,8, + 1,6,2,6,2,2,0,2,254,6,3,8,1,8,1,14, + 1,114,219,0,0,0,114,10,0,0,0,99,5,0,0,0, + 0,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0, + 67,0,0,0,115,180,0,0,0,124,4,100,1,107,2,114, + 18,116,0,124,0,131,1,125,5,110,36,124,1,100,2,107, + 9,114,30,124,1,110,2,105,0,125,6,116,1,124,6,131, + 1,125,7,116,0,124,0,124,7,124,4,131,3,125,5,124, + 3,115,150,124,4,100,1,107,2,114,84,116,0,124,0,160, + 2,100,3,161,1,100,1,25,0,131,1,83,0,124,0,115, + 92,124,5,83,0,116,3,124,0,131,1,116,3,124,0,160, + 2,100,3,161,1,100,1,25,0,131,1,24,0,125,8,116, + 4,106,5,124,5,106,6,100,2,116,3,124,5,106,6,131, + 1,124,8,24,0,133,2,25,0,25,0,83,0,110,26,116, + 7,124,5,100,4,131,2,114,172,116,8,124,5,124,3,116, + 0,131,3,83,0,124,5,83,0,100,2,83,0,41,5,97, + 215,1,0,0,73,109,112,111,114,116,32,97,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,84,104,101,32,39,103, + 108,111,98,97,108,115,39,32,97,114,103,117,109,101,110,116, + 32,105,115,32,117,115,101,100,32,116,111,32,105,110,102,101, + 114,32,119,104,101,114,101,32,116,104,101,32,105,109,112,111, + 114,116,32,105,115,32,111,99,99,117,114,114,105,110,103,32, + 102,114,111,109,10,32,32,32,32,116,111,32,104,97,110,100, + 108,101,32,114,101,108,97,116,105,118,101,32,105,109,112,111, + 114,116,115,46,32,84,104,101,32,39,108,111,99,97,108,115, + 39,32,97,114,103,117,109,101,110,116,32,105,115,32,105,103, + 110,111,114,101,100,46,32,84,104,101,10,32,32,32,32,39, + 102,114,111,109,108,105,115,116,39,32,97,114,103,117,109,101, + 110,116,32,115,112,101,99,105,102,105,101,115,32,119,104,97, + 116,32,115,104,111,117,108,100,32,101,120,105,115,116,32,97, + 115,32,97,116,116,114,105,98,117,116,101,115,32,111,110,32, + 116,104,101,32,109,111,100,117,108,101,10,32,32,32,32,98, + 101,105,110,103,32,105,109,112,111,114,116,101,100,32,40,101, + 46,103,46,32,96,96,102,114,111,109,32,109,111,100,117,108, + 101,32,105,109,112,111,114,116,32,60,102,114,111,109,108,105, + 115,116,62,96,96,41,46,32,32,84,104,101,32,39,108,101, + 118,101,108,39,10,32,32,32,32,97,114,103,117,109,101,110, + 116,32,114,101,112,114,101,115,101,110,116,115,32,116,104,101, + 32,112,97,99,107,97,103,101,32,108,111,99,97,116,105,111, + 110,32,116,111,32,105,109,112,111,114,116,32,102,114,111,109, + 32,105,110,32,97,32,114,101,108,97,116,105,118,101,10,32, + 32,32,32,105,109,112,111,114,116,32,40,101,46,103,46,32, + 96,96,102,114,111,109,32,46,46,112,107,103,32,105,109,112, + 111,114,116,32,109,111,100,96,96,32,119,111,117,108,100,32, + 104,97,118,101,32,97,32,39,108,101,118,101,108,39,32,111, + 102,32,50,41,46,10,10,32,32,32,32,114,22,0,0,0, + 78,114,128,0,0,0,114,141,0,0,0,41,9,114,208,0, + 0,0,114,219,0,0,0,218,9,112,97,114,116,105,116,105, + 111,110,114,184,0,0,0,114,15,0,0,0,114,92,0,0, + 0,114,1,0,0,0,114,4,0,0,0,114,213,0,0,0, + 41,9,114,17,0,0,0,114,218,0,0,0,218,6,108,111, + 99,97,108,115,114,214,0,0,0,114,187,0,0,0,114,96, + 0,0,0,90,8,103,108,111,98,97,108,115,95,114,186,0, + 0,0,90,7,99,117,116,95,111,102,102,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,10,95,95,105,109, + 112,111,114,116,95,95,57,4,0,0,115,30,0,0,0,0, + 11,8,1,10,2,16,1,8,1,12,1,4,3,8,1,18, + 1,4,1,4,4,26,3,32,1,10,1,12,2,114,222,0, + 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 116,0,160,1,124,0,161,1,125,1,124,1,100,0,107,8, + 114,30,116,2,100,1,124,0,23,0,131,1,130,1,116,3, + 124,1,131,1,83,0,41,2,78,122,25,110,111,32,98,117, + 105,108,116,45,105,110,32,109,111,100,117,108,101,32,110,97, + 109,101,100,32,41,4,114,160,0,0,0,114,166,0,0,0, + 114,79,0,0,0,114,159,0,0,0,41,2,114,17,0,0, + 0,114,95,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,218,18,95,98,117,105,108,116,105,110,95, + 102,114,111,109,95,110,97,109,101,94,4,0,0,115,8,0, + 0,0,0,1,10,1,8,1,12,1,114,223,0,0,0,99, + 2,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0, + 5,0,0,0,67,0,0,0,115,166,0,0,0,124,1,97, + 0,124,0,97,1,116,2,116,1,131,1,125,2,116,1,106, + 3,160,4,161,0,68,0,93,72,92,2,125,3,125,4,116, + 5,124,4,124,2,131,2,114,26,124,3,116,1,106,6,107, + 6,114,60,116,7,125,5,110,18,116,0,160,8,124,3,161, + 1,114,26,116,9,125,5,110,2,113,26,116,10,124,4,124, + 5,131,2,125,6,116,11,124,6,124,4,131,2,1,0,113, + 26,116,1,106,3,116,12,25,0,125,7,100,1,68,0,93, + 46,125,8,124,8,116,1,106,3,107,7,114,138,116,13,124, + 8,131,1,125,9,110,10,116,1,106,3,124,8,25,0,125, + 9,116,14,124,7,124,8,124,9,131,3,1,0,113,114,100, + 2,83,0,41,3,122,250,83,101,116,117,112,32,105,109,112, + 111,114,116,108,105,98,32,98,121,32,105,109,112,111,114,116, + 105,110,103,32,110,101,101,100,101,100,32,98,117,105,108,116, + 45,105,110,32,109,111,100,117,108,101,115,32,97,110,100,32, + 105,110,106,101,99,116,105,110,103,32,116,104,101,109,10,32, + 32,32,32,105,110,116,111,32,116,104,101,32,103,108,111,98, + 97,108,32,110,97,109,101,115,112,97,99,101,46,10,10,32, + 32,32,32,65,115,32,115,121,115,32,105,115,32,110,101,101, + 100,101,100,32,102,111,114,32,115,121,115,46,109,111,100,117, + 108,101,115,32,97,99,99,101,115,115,32,97,110,100,32,95, + 105,109,112,32,105,115,32,110,101,101,100,101,100,32,116,111, + 32,108,111,97,100,32,98,117,105,108,116,45,105,110,10,32, + 32,32,32,109,111,100,117,108,101,115,44,32,116,104,111,115, + 101,32,116,119,111,32,109,111,100,117,108,101,115,32,109,117, + 115,116,32,98,101,32,101,120,112,108,105,99,105,116,108,121, + 32,112,97,115,115,101,100,32,105,110,46,10,10,32,32,32, + 32,41,3,114,23,0,0,0,114,192,0,0,0,114,64,0, + 0,0,78,41,15,114,57,0,0,0,114,15,0,0,0,114, + 14,0,0,0,114,92,0,0,0,218,5,105,116,101,109,115, + 114,196,0,0,0,114,78,0,0,0,114,160,0,0,0,114, + 88,0,0,0,114,173,0,0,0,114,142,0,0,0,114,148, + 0,0,0,114,1,0,0,0,114,223,0,0,0,114,5,0, + 0,0,41,10,218,10,115,121,115,95,109,111,100,117,108,101, + 218,11,95,105,109,112,95,109,111,100,117,108,101,90,11,109, + 111,100,117,108,101,95,116,121,112,101,114,17,0,0,0,114, + 96,0,0,0,114,109,0,0,0,114,95,0,0,0,90,11, + 115,101,108,102,95,109,111,100,117,108,101,90,12,98,117,105, + 108,116,105,110,95,110,97,109,101,90,14,98,117,105,108,116, + 105,110,95,109,111,100,117,108,101,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,6,95,115,101,116,117,112, + 101,4,0,0,115,36,0,0,0,0,9,4,1,4,3,8, + 1,18,1,10,1,10,1,6,1,10,1,6,2,2,1,10, + 1,12,3,10,1,8,1,10,1,10,2,10,1,114,227,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, + 116,0,124,0,124,1,131,2,1,0,116,1,106,2,160,3, + 116,4,161,1,1,0,116,1,106,2,160,3,116,5,161,1, + 1,0,100,1,83,0,41,2,122,48,73,110,115,116,97,108, + 108,32,105,109,112,111,114,116,101,114,115,32,102,111,114,32, + 98,117,105,108,116,105,110,32,97,110,100,32,102,114,111,122, + 101,110,32,109,111,100,117,108,101,115,78,41,6,114,227,0, + 0,0,114,15,0,0,0,114,191,0,0,0,114,120,0,0, + 0,114,160,0,0,0,114,173,0,0,0,41,2,114,225,0, + 0,0,114,226,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,218,8,95,105,110,115,116,97,108,108, + 136,4,0,0,115,6,0,0,0,0,2,10,2,12,1,114, + 228,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,4,0,0,0,67,0,0,0,115,32,0, + 0,0,100,1,100,2,108,0,125,0,124,0,97,1,124,0, + 160,2,116,3,106,4,116,5,25,0,161,1,1,0,100,2, + 83,0,41,3,122,57,73,110,115,116,97,108,108,32,105,109, + 112,111,114,116,101,114,115,32,116,104,97,116,32,114,101,113, + 117,105,114,101,32,101,120,116,101,114,110,97,108,32,102,105, + 108,101,115,121,115,116,101,109,32,97,99,99,101,115,115,114, + 22,0,0,0,78,41,6,218,26,95,102,114,111,122,101,110, + 95,105,109,112,111,114,116,108,105,98,95,101,120,116,101,114, + 110,97,108,114,126,0,0,0,114,228,0,0,0,114,15,0, + 0,0,114,92,0,0,0,114,1,0,0,0,41,1,114,229, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,27,95,105,110,115,116,97,108,108,95,101,120,116, + 101,114,110,97,108,95,105,109,112,111,114,116,101,114,115,144, + 4,0,0,115,6,0,0,0,0,3,8,1,4,1,114,230, + 0,0,0,41,2,78,78,41,1,78,41,2,78,114,22,0, + 0,0,41,4,78,78,114,10,0,0,0,114,22,0,0,0, + 41,50,114,3,0,0,0,114,126,0,0,0,114,12,0,0, + 0,114,18,0,0,0,114,59,0,0,0,114,33,0,0,0, + 114,42,0,0,0,114,19,0,0,0,114,20,0,0,0,114, + 49,0,0,0,114,50,0,0,0,114,53,0,0,0,114,65, + 0,0,0,114,67,0,0,0,114,76,0,0,0,114,86,0, + 0,0,114,90,0,0,0,114,97,0,0,0,114,111,0,0, + 0,114,112,0,0,0,114,91,0,0,0,114,142,0,0,0, + 114,148,0,0,0,114,152,0,0,0,114,107,0,0,0,114, + 93,0,0,0,114,158,0,0,0,114,159,0,0,0,114,94, + 0,0,0,114,160,0,0,0,114,173,0,0,0,114,178,0, + 0,0,114,188,0,0,0,114,190,0,0,0,114,195,0,0, + 0,114,200,0,0,0,90,15,95,69,82,82,95,77,83,71, + 95,80,82,69,70,73,88,114,202,0,0,0,114,205,0,0, + 0,218,6,111,98,106,101,99,116,114,206,0,0,0,114,207, + 0,0,0,114,208,0,0,0,114,213,0,0,0,114,219,0, + 0,0,114,222,0,0,0,114,223,0,0,0,114,227,0,0, + 0,114,228,0,0,0,114,230,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, + 8,60,109,111,100,117,108,101,62,1,0,0,0,115,94,0, + 0,0,4,24,4,2,8,8,8,8,4,2,4,3,16,4, + 14,68,14,21,14,16,8,37,8,17,8,11,14,8,8,11, + 8,12,8,16,8,36,14,101,16,26,10,45,14,72,8,17, + 8,17,8,30,8,37,8,42,8,15,14,73,14,79,14,13, + 8,9,8,9,10,47,8,16,4,1,8,2,8,27,6,3, + 8,16,10,15,14,37,8,27,10,37,8,7,8,35,8,8, }; diff --git a/Python/importlib_external.h b/Python/importlib_external.h index e724560d67a1c2..9b86fe6b72a94c 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -1,1003 +1,1001 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_bootstrap_external[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,5,0,0,0,64,0,0,0,115,52,2,0,0,100,0, + 0,5,0,0,0,64,0,0,0,115,32,2,0,0,100,0, 90,0,100,1,90,1,100,2,90,2,101,2,101,1,23,0, 90,3,100,3,100,4,132,0,90,4,100,5,100,6,132,0, 90,5,100,7,100,8,132,0,90,6,100,9,100,10,132,0, 90,7,100,11,100,12,132,0,90,8,100,13,100,14,132,0, 90,9,100,15,100,16,132,0,90,10,100,17,100,18,132,0, 90,11,100,19,100,20,132,0,90,12,100,21,100,22,132,0, - 90,13,100,23,100,24,132,0,90,14,100,25,102,1,100,26, - 100,27,132,1,90,15,101,16,101,15,106,17,131,1,90,18, - 100,28,160,19,100,29,100,30,161,2,100,31,23,0,90,20, - 101,21,160,22,101,20,100,30,161,2,90,23,100,32,90,24, - 100,33,90,25,100,34,103,1,90,26,100,35,103,1,90,27, - 101,27,4,0,90,28,90,29,100,36,102,1,100,36,100,37, - 156,1,100,38,100,39,132,3,90,30,100,40,100,41,132,0, - 90,31,100,42,100,43,132,0,90,32,100,44,100,45,132,0, - 90,33,100,46,100,47,132,0,90,34,100,48,100,49,132,0, - 90,35,100,50,100,51,132,0,90,36,100,52,100,53,132,0, - 90,37,100,54,100,55,132,0,90,38,100,56,100,57,132,0, - 90,39,100,36,100,36,100,36,102,3,100,58,100,59,132,1, - 90,40,100,60,100,60,102,2,100,61,100,62,132,1,90,41, - 100,63,102,1,100,64,100,65,132,1,90,42,100,66,100,67, - 132,0,90,43,101,44,131,0,90,45,100,36,102,1,100,36, - 101,45,100,68,156,2,100,69,100,70,132,3,90,46,71,0, - 100,71,100,72,132,0,100,72,131,2,90,47,71,0,100,73, - 100,74,132,0,100,74,131,2,90,48,71,0,100,75,100,76, - 132,0,100,76,101,48,131,3,90,49,71,0,100,77,100,78, - 132,0,100,78,131,2,90,50,71,0,100,79,100,80,132,0, - 100,80,101,50,101,49,131,4,90,51,71,0,100,81,100,82, - 132,0,100,82,101,50,101,48,131,4,90,52,103,0,90,53, - 71,0,100,83,100,84,132,0,100,84,101,50,101,48,131,4, - 90,54,71,0,100,85,100,86,132,0,100,86,131,2,90,55, - 71,0,100,87,100,88,132,0,100,88,131,2,90,56,71,0, - 100,89,100,90,132,0,100,90,131,2,90,57,71,0,100,91, - 100,92,132,0,100,92,131,2,90,58,100,36,102,1,100,93, - 100,94,132,1,90,59,100,95,100,96,132,0,90,60,100,97, - 100,98,132,0,90,61,100,99,100,100,132,0,90,62,100,36, - 83,0,41,101,97,94,1,0,0,67,111,114,101,32,105,109, - 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, - 112,97,116,104,45,98,97,115,101,100,32,105,109,112,111,114, - 116,46,10,10,84,104,105,115,32,109,111,100,117,108,101,32, - 105,115,32,78,79,84,32,109,101,97,110,116,32,116,111,32, - 98,101,32,100,105,114,101,99,116,108,121,32,105,109,112,111, - 114,116,101,100,33,32,73,116,32,104,97,115,32,98,101,101, - 110,32,100,101,115,105,103,110,101,100,32,115,117,99,104,10, - 116,104,97,116,32,105,116,32,99,97,110,32,98,101,32,98, - 111,111,116,115,116,114,97,112,112,101,100,32,105,110,116,111, - 32,80,121,116,104,111,110,32,97,115,32,116,104,101,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, - 32,105,109,112,111,114,116,46,32,65,115,10,115,117,99,104, - 32,105,116,32,114,101,113,117,105,114,101,115,32,116,104,101, - 32,105,110,106,101,99,116,105,111,110,32,111,102,32,115,112, - 101,99,105,102,105,99,32,109,111,100,117,108,101,115,32,97, - 110,100,32,97,116,116,114,105,98,117,116,101,115,32,105,110, - 32,111,114,100,101,114,32,116,111,10,119,111,114,107,46,32, - 79,110,101,32,115,104,111,117,108,100,32,117,115,101,32,105, - 109,112,111,114,116,108,105,98,32,97,115,32,116,104,101,32, - 112,117,98,108,105,99,45,102,97,99,105,110,103,32,118,101, - 114,115,105,111,110,32,111,102,32,116,104,105,115,32,109,111, - 100,117,108,101,46,10,10,41,1,218,3,119,105,110,41,2, - 90,6,99,121,103,119,105,110,90,6,100,97,114,119,105,110, - 99,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,3,0,0,0,115,60,0,0,0,116,0, - 106,1,160,2,116,3,161,1,114,48,116,0,106,1,160,2, - 116,4,161,1,114,30,100,1,137,0,110,4,100,2,137,0, - 135,0,102,1,100,3,100,4,132,8,125,0,110,8,100,5, - 100,4,132,0,125,0,124,0,83,0,41,6,78,90,12,80, - 89,84,72,79,78,67,65,83,69,79,75,115,12,0,0,0, - 80,89,84,72,79,78,67,65,83,69,79,75,99,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,19,0,0,0,115,10,0,0,0,136,0,116,0,106,1, - 107,6,83,0,41,1,250,53,84,114,117,101,32,105,102,32, - 102,105,108,101,110,97,109,101,115,32,109,117,115,116,32,98, - 101,32,99,104,101,99,107,101,100,32,99,97,115,101,45,105, - 110,115,101,110,115,105,116,105,118,101,108,121,46,41,2,218, - 3,95,111,115,90,7,101,110,118,105,114,111,110,169,0,169, - 1,218,3,107,101,121,114,3,0,0,0,250,38,60,102,114, - 111,122,101,110,32,105,109,112,111,114,116,108,105,98,46,95, - 98,111,111,116,115,116,114,97,112,95,101,120,116,101,114,110, - 97,108,62,218,11,95,114,101,108,97,120,95,99,97,115,101, - 36,0,0,0,115,2,0,0,0,0,2,122,37,95,109,97, - 107,101,95,114,101,108,97,120,95,99,97,115,101,46,60,108, - 111,99,97,108,115,62,46,95,114,101,108,97,120,95,99,97, - 115,101,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,1,0,0,0,83,0,0,0,115,4,0,0,0, - 100,1,83,0,41,2,114,1,0,0,0,70,114,3,0,0, - 0,114,3,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,7,0,0,0,40,0,0,0,115,2, - 0,0,0,0,2,41,5,218,3,115,121,115,218,8,112,108, - 97,116,102,111,114,109,218,10,115,116,97,114,116,115,119,105, - 116,104,218,27,95,67,65,83,69,95,73,78,83,69,78,83, - 73,84,73,86,69,95,80,76,65,84,70,79,82,77,83,218, - 35,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, - 86,69,95,80,76,65,84,70,79,82,77,83,95,83,84,82, - 95,75,69,89,41,1,114,7,0,0,0,114,3,0,0,0, - 114,4,0,0,0,114,6,0,0,0,218,16,95,109,97,107, - 101,95,114,101,108,97,120,95,99,97,115,101,29,0,0,0, - 115,14,0,0,0,0,1,12,1,12,1,6,2,4,2,14, - 4,8,3,114,13,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, - 0,115,20,0,0,0,116,0,124,0,131,1,100,1,64,0, - 160,1,100,2,100,3,161,2,83,0,41,4,122,42,67,111, - 110,118,101,114,116,32,97,32,51,50,45,98,105,116,32,105, - 110,116,101,103,101,114,32,116,111,32,108,105,116,116,108,101, - 45,101,110,100,105,97,110,46,236,3,0,0,0,255,127,255, - 127,3,0,233,4,0,0,0,218,6,108,105,116,116,108,101, - 41,2,218,3,105,110,116,218,8,116,111,95,98,121,116,101, - 115,41,1,218,1,120,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,112,97,99,107,95,117,105,110, - 116,51,50,46,0,0,0,115,2,0,0,0,0,2,114,20, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,4,0,0,0,67,0,0,0,115,28,0,0, - 0,116,0,124,0,131,1,100,1,107,2,115,16,116,1,130, - 1,116,2,160,3,124,0,100,2,161,2,83,0,41,3,122, - 47,67,111,110,118,101,114,116,32,52,32,98,121,116,101,115, - 32,105,110,32,108,105,116,116,108,101,45,101,110,100,105,97, - 110,32,116,111,32,97,110,32,105,110,116,101,103,101,114,46, - 114,15,0,0,0,114,16,0,0,0,169,4,218,3,108,101, - 110,218,14,65,115,115,101,114,116,105,111,110,69,114,114,111, - 114,114,17,0,0,0,218,10,102,114,111,109,95,98,121,116, - 101,115,169,1,218,4,100,97,116,97,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,14,95,117,110,112,97, - 99,107,95,117,105,110,116,51,50,51,0,0,0,115,4,0, - 0,0,0,2,16,1,114,27,0,0,0,99,1,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, - 67,0,0,0,115,28,0,0,0,116,0,124,0,131,1,100, - 1,107,2,115,16,116,1,130,1,116,2,160,3,124,0,100, - 2,161,2,83,0,41,3,122,47,67,111,110,118,101,114,116, - 32,50,32,98,121,116,101,115,32,105,110,32,108,105,116,116, - 108,101,45,101,110,100,105,97,110,32,116,111,32,97,110,32, - 105,110,116,101,103,101,114,46,233,2,0,0,0,114,16,0, - 0,0,114,21,0,0,0,114,25,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,14,95,117,110, - 112,97,99,107,95,117,105,110,116,49,54,56,0,0,0,115, - 4,0,0,0,0,2,16,1,114,29,0,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,71,0,0,0,115,20,0,0,0,116,0,160,1,100, - 1,100,2,132,0,124,0,68,0,131,1,161,1,83,0,41, - 3,122,31,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,106,111,105,110,40, - 41,46,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,5,0,0,0,83,0,0,0,115,26,0,0,0, - 103,0,124,0,93,18,125,1,124,1,114,22,124,1,160,0, - 116,1,161,1,145,2,113,4,83,0,114,3,0,0,0,41, - 2,218,6,114,115,116,114,105,112,218,15,112,97,116,104,95, - 115,101,112,97,114,97,116,111,114,115,41,2,218,2,46,48, - 218,4,112,97,114,116,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,10,60,108,105,115,116,99,111,109,112, - 62,64,0,0,0,115,6,0,0,0,6,1,2,0,4,255, - 122,30,95,112,97,116,104,95,106,111,105,110,46,60,108,111, - 99,97,108,115,62,46,60,108,105,115,116,99,111,109,112,62, - 41,2,218,8,112,97,116,104,95,115,101,112,218,4,106,111, - 105,110,41,1,218,10,112,97,116,104,95,112,97,114,116,115, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 10,95,112,97,116,104,95,106,111,105,110,62,0,0,0,115, - 6,0,0,0,0,2,10,1,2,255,114,38,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 5,0,0,0,67,0,0,0,115,96,0,0,0,116,0,116, - 1,131,1,100,1,107,2,114,36,124,0,160,2,116,3,161, - 1,92,3,125,1,125,2,125,3,124,1,124,3,102,2,83, - 0,116,4,124,0,131,1,68,0,93,42,125,4,124,4,116, - 1,107,6,114,44,124,0,106,5,124,4,100,1,100,2,141, - 2,92,2,125,1,125,3,124,1,124,3,102,2,2,0,1, - 0,83,0,113,44,100,3,124,0,102,2,83,0,41,4,122, - 32,82,101,112,108,97,99,101,109,101,110,116,32,102,111,114, - 32,111,115,46,112,97,116,104,46,115,112,108,105,116,40,41, - 46,233,1,0,0,0,41,1,90,8,109,97,120,115,112,108, - 105,116,218,0,41,6,114,22,0,0,0,114,31,0,0,0, - 218,10,114,112,97,114,116,105,116,105,111,110,114,35,0,0, - 0,218,8,114,101,118,101,114,115,101,100,218,6,114,115,112, - 108,105,116,41,5,218,4,112,97,116,104,90,5,102,114,111, - 110,116,218,1,95,218,4,116,97,105,108,114,19,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 11,95,112,97,116,104,95,115,112,108,105,116,68,0,0,0, - 115,16,0,0,0,0,2,12,1,16,1,8,1,12,1,8, - 1,18,1,14,1,114,47,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, - 0,0,0,115,10,0,0,0,116,0,160,1,124,0,161,1, - 83,0,41,1,122,126,83,116,97,116,32,116,104,101,32,112, - 97,116,104,46,10,10,32,32,32,32,77,97,100,101,32,97, - 32,115,101,112,97,114,97,116,101,32,102,117,110,99,116,105, - 111,110,32,116,111,32,109,97,107,101,32,105,116,32,101,97, - 115,105,101,114,32,116,111,32,111,118,101,114,114,105,100,101, - 32,105,110,32,101,120,112,101,114,105,109,101,110,116,115,10, - 32,32,32,32,40,101,46,103,46,32,99,97,99,104,101,32, - 115,116,97,116,32,114,101,115,117,108,116,115,41,46,10,10, - 32,32,32,32,41,2,114,2,0,0,0,90,4,115,116,97, - 116,169,1,114,44,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,10,95,112,97,116,104,95,115, - 116,97,116,80,0,0,0,115,2,0,0,0,0,7,114,49, - 0,0,0,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,8,0,0,0,67,0,0,0,115,50,0,0, - 0,122,12,116,0,124,0,131,1,125,2,87,0,110,22,4, - 0,116,1,107,10,114,34,1,0,1,0,1,0,89,0,100, - 1,83,0,88,0,124,2,106,2,100,2,64,0,124,1,107, - 2,83,0,41,3,122,49,84,101,115,116,32,119,104,101,116, - 104,101,114,32,116,104,101,32,112,97,116,104,32,105,115,32, - 116,104,101,32,115,112,101,99,105,102,105,101,100,32,109,111, - 100,101,32,116,121,112,101,46,70,105,0,240,0,0,41,3, - 114,49,0,0,0,218,7,79,83,69,114,114,111,114,218,7, - 115,116,95,109,111,100,101,41,3,114,44,0,0,0,218,4, - 109,111,100,101,90,9,115,116,97,116,95,105,110,102,111,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,18, - 95,112,97,116,104,95,105,115,95,109,111,100,101,95,116,121, - 112,101,90,0,0,0,115,10,0,0,0,0,2,2,1,12, - 1,14,1,8,1,114,53,0,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, - 0,0,0,115,10,0,0,0,116,0,124,0,100,1,131,2, - 83,0,41,2,122,31,82,101,112,108,97,99,101,109,101,110, - 116,32,102,111,114,32,111,115,46,112,97,116,104,46,105,115, - 102,105,108,101,46,105,0,128,0,0,41,1,114,53,0,0, - 0,114,48,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,112,97,116,104,95,105,115,102, - 105,108,101,99,0,0,0,115,2,0,0,0,0,2,114,54, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,115,22,0,0, - 0,124,0,115,12,116,0,160,1,161,0,125,0,116,2,124, - 0,100,1,131,2,83,0,41,2,122,30,82,101,112,108,97, - 99,101,109,101,110,116,32,102,111,114,32,111,115,46,112,97, - 116,104,46,105,115,100,105,114,46,105,0,64,0,0,41,3, - 114,2,0,0,0,218,6,103,101,116,99,119,100,114,53,0, - 0,0,114,48,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,218,11,95,112,97,116,104,95,105,115, - 100,105,114,104,0,0,0,115,6,0,0,0,0,2,4,1, - 8,1,114,56,0,0,0,99,1,0,0,0,0,0,0,0, - 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, - 115,26,0,0,0,124,0,160,0,116,1,161,1,112,24,124, - 0,100,1,100,2,133,2,25,0,116,2,107,6,83,0,41, - 3,122,142,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,105,115,97,98,115, - 46,10,10,32,32,32,32,67,111,110,115,105,100,101,114,115, - 32,97,32,87,105,110,100,111,119,115,32,100,114,105,118,101, - 45,114,101,108,97,116,105,118,101,32,112,97,116,104,32,40, - 110,111,32,100,114,105,118,101,44,32,98,117,116,32,115,116, - 97,114,116,115,32,119,105,116,104,32,115,108,97,115,104,41, - 32,116,111,10,32,32,32,32,115,116,105,108,108,32,98,101, - 32,34,97,98,115,111,108,117,116,101,34,46,10,32,32,32, - 32,114,39,0,0,0,233,3,0,0,0,41,3,114,10,0, - 0,0,114,31,0,0,0,218,20,95,112,97,116,104,115,101, - 112,115,95,119,105,116,104,95,99,111,108,111,110,114,48,0, + 90,13,100,23,100,24,132,0,90,14,100,101,100,26,100,27, + 132,1,90,15,101,16,101,15,106,17,131,1,90,18,100,28, + 160,19,100,29,100,30,161,2,100,31,23,0,90,20,101,21, + 160,22,101,20,100,30,161,2,90,23,100,32,90,24,100,33, + 90,25,100,34,103,1,90,26,100,35,103,1,90,27,101,27, + 4,0,90,28,90,29,100,102,100,36,100,37,156,1,100,38, + 100,39,132,3,90,30,100,40,100,41,132,0,90,31,100,42, + 100,43,132,0,90,32,100,44,100,45,132,0,90,33,100,46, + 100,47,132,0,90,34,100,48,100,49,132,0,90,35,100,50, + 100,51,132,0,90,36,100,52,100,53,132,0,90,37,100,54, + 100,55,132,0,90,38,100,56,100,57,132,0,90,39,100,103, + 100,58,100,59,132,1,90,40,100,104,100,61,100,62,132,1, + 90,41,100,105,100,64,100,65,132,1,90,42,100,66,100,67, + 132,0,90,43,101,44,131,0,90,45,100,106,100,36,101,45, + 100,68,156,2,100,69,100,70,132,3,90,46,71,0,100,71, + 100,72,132,0,100,72,131,2,90,47,71,0,100,73,100,74, + 132,0,100,74,131,2,90,48,71,0,100,75,100,76,132,0, + 100,76,101,48,131,3,90,49,71,0,100,77,100,78,132,0, + 100,78,131,2,90,50,71,0,100,79,100,80,132,0,100,80, + 101,50,101,49,131,4,90,51,71,0,100,81,100,82,132,0, + 100,82,101,50,101,48,131,4,90,52,103,0,90,53,71,0, + 100,83,100,84,132,0,100,84,101,50,101,48,131,4,90,54, + 71,0,100,85,100,86,132,0,100,86,131,2,90,55,71,0, + 100,87,100,88,132,0,100,88,131,2,90,56,71,0,100,89, + 100,90,132,0,100,90,131,2,90,57,71,0,100,91,100,92, + 132,0,100,92,131,2,90,58,100,107,100,93,100,94,132,1, + 90,59,100,95,100,96,132,0,90,60,100,97,100,98,132,0, + 90,61,100,99,100,100,132,0,90,62,100,36,83,0,41,108, + 97,94,1,0,0,67,111,114,101,32,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,32,111,102,32,112,97,116,104, + 45,98,97,115,101,100,32,105,109,112,111,114,116,46,10,10, + 84,104,105,115,32,109,111,100,117,108,101,32,105,115,32,78, + 79,84,32,109,101,97,110,116,32,116,111,32,98,101,32,100, + 105,114,101,99,116,108,121,32,105,109,112,111,114,116,101,100, + 33,32,73,116,32,104,97,115,32,98,101,101,110,32,100,101, + 115,105,103,110,101,100,32,115,117,99,104,10,116,104,97,116, + 32,105,116,32,99,97,110,32,98,101,32,98,111,111,116,115, + 116,114,97,112,112,101,100,32,105,110,116,111,32,80,121,116, + 104,111,110,32,97,115,32,116,104,101,32,105,109,112,108,101, + 109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,112, + 111,114,116,46,32,65,115,10,115,117,99,104,32,105,116,32, + 114,101,113,117,105,114,101,115,32,116,104,101,32,105,110,106, + 101,99,116,105,111,110,32,111,102,32,115,112,101,99,105,102, + 105,99,32,109,111,100,117,108,101,115,32,97,110,100,32,97, + 116,116,114,105,98,117,116,101,115,32,105,110,32,111,114,100, + 101,114,32,116,111,10,119,111,114,107,46,32,79,110,101,32, + 115,104,111,117,108,100,32,117,115,101,32,105,109,112,111,114, + 116,108,105,98,32,97,115,32,116,104,101,32,112,117,98,108, + 105,99,45,102,97,99,105,110,103,32,118,101,114,115,105,111, + 110,32,111,102,32,116,104,105,115,32,109,111,100,117,108,101, + 46,10,10,41,1,218,3,119,105,110,41,2,90,6,99,121, + 103,119,105,110,90,6,100,97,114,119,105,110,99,0,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,3,0,0,0,115,60,0,0,0,116,0,106,1,160,2, + 116,3,161,1,114,48,116,0,106,1,160,2,116,4,161,1, + 114,30,100,1,137,0,110,4,100,2,137,0,135,0,102,1, + 100,3,100,4,132,8,125,0,110,8,100,5,100,4,132,0, + 125,0,124,0,83,0,41,6,78,90,12,80,89,84,72,79, + 78,67,65,83,69,79,75,115,12,0,0,0,80,89,84,72, + 79,78,67,65,83,69,79,75,99,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,19,0,0, + 0,115,10,0,0,0,136,0,116,0,106,1,107,6,83,0, + 41,1,250,53,84,114,117,101,32,105,102,32,102,105,108,101, + 110,97,109,101,115,32,109,117,115,116,32,98,101,32,99,104, + 101,99,107,101,100,32,99,97,115,101,45,105,110,115,101,110, + 115,105,116,105,118,101,108,121,46,41,2,218,3,95,111,115, + 90,7,101,110,118,105,114,111,110,169,0,169,1,218,3,107, + 101,121,114,3,0,0,0,250,38,60,102,114,111,122,101,110, + 32,105,109,112,111,114,116,108,105,98,46,95,98,111,111,116, + 115,116,114,97,112,95,101,120,116,101,114,110,97,108,62,218, + 11,95,114,101,108,97,120,95,99,97,115,101,36,0,0,0, + 115,2,0,0,0,0,2,122,37,95,109,97,107,101,95,114, + 101,108,97,120,95,99,97,115,101,46,60,108,111,99,97,108, + 115,62,46,95,114,101,108,97,120,95,99,97,115,101,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,83,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,114,1,0,0,0,70,114,3,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,7,0,0,0,40,0,0,0,115,2,0,0,0,0, + 2,41,5,218,3,115,121,115,218,8,112,108,97,116,102,111, + 114,109,218,10,115,116,97,114,116,115,119,105,116,104,218,27, + 95,67,65,83,69,95,73,78,83,69,78,83,73,84,73,86, + 69,95,80,76,65,84,70,79,82,77,83,218,35,95,67,65, + 83,69,95,73,78,83,69,78,83,73,84,73,86,69,95,80, + 76,65,84,70,79,82,77,83,95,83,84,82,95,75,69,89, + 41,1,114,7,0,0,0,114,3,0,0,0,114,4,0,0, + 0,114,6,0,0,0,218,16,95,109,97,107,101,95,114,101, + 108,97,120,95,99,97,115,101,29,0,0,0,115,14,0,0, + 0,0,1,12,1,12,1,6,2,4,2,14,4,8,3,114, + 13,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,1,0,0,0,4,0,0,0,67,0,0,0,115,20,0, + 0,0,116,0,124,0,131,1,100,1,64,0,160,1,100,2, + 100,3,161,2,83,0,41,4,122,42,67,111,110,118,101,114, + 116,32,97,32,51,50,45,98,105,116,32,105,110,116,101,103, + 101,114,32,116,111,32,108,105,116,116,108,101,45,101,110,100, + 105,97,110,46,236,3,0,0,0,255,127,255,127,3,0,233, + 4,0,0,0,218,6,108,105,116,116,108,101,41,2,218,3, + 105,110,116,218,8,116,111,95,98,121,116,101,115,41,1,218, + 1,120,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,12,95,112,97,99,107,95,117,105,110,116,51,50,46, + 0,0,0,115,2,0,0,0,0,2,114,20,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 4,0,0,0,67,0,0,0,115,28,0,0,0,116,0,124, + 0,131,1,100,1,107,2,115,16,116,1,130,1,116,2,160, + 3,124,0,100,2,161,2,83,0,41,3,122,47,67,111,110, + 118,101,114,116,32,52,32,98,121,116,101,115,32,105,110,32, + 108,105,116,116,108,101,45,101,110,100,105,97,110,32,116,111, + 32,97,110,32,105,110,116,101,103,101,114,46,114,15,0,0, + 0,114,16,0,0,0,169,4,218,3,108,101,110,218,14,65, + 115,115,101,114,116,105,111,110,69,114,114,111,114,114,17,0, + 0,0,218,10,102,114,111,109,95,98,121,116,101,115,169,1, + 218,4,100,97,116,97,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,14,95,117,110,112,97,99,107,95,117, + 105,110,116,51,50,51,0,0,0,115,4,0,0,0,0,2, + 16,1,114,27,0,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,4,0,0,0,67,0,0,0, + 115,28,0,0,0,116,0,124,0,131,1,100,1,107,2,115, + 16,116,1,130,1,116,2,160,3,124,0,100,2,161,2,83, + 0,41,3,122,47,67,111,110,118,101,114,116,32,50,32,98, + 121,116,101,115,32,105,110,32,108,105,116,116,108,101,45,101, + 110,100,105,97,110,32,116,111,32,97,110,32,105,110,116,101, + 103,101,114,46,233,2,0,0,0,114,16,0,0,0,114,21, + 0,0,0,114,25,0,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,218,14,95,117,110,112,97,99,107, + 95,117,105,110,116,49,54,56,0,0,0,115,4,0,0,0, + 0,2,16,1,114,29,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,4,0,0,0,71,0, + 0,0,115,20,0,0,0,116,0,160,1,100,1,100,2,132, + 0,124,0,68,0,131,1,161,1,83,0,41,3,122,31,82, + 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, + 115,46,112,97,116,104,46,106,111,105,110,40,41,46,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,5, + 0,0,0,83,0,0,0,115,26,0,0,0,103,0,124,0, + 93,18,125,1,124,1,114,4,124,1,160,0,116,1,161,1, + 145,2,113,4,83,0,114,3,0,0,0,41,2,218,6,114, + 115,116,114,105,112,218,15,112,97,116,104,95,115,101,112,97, + 114,97,116,111,114,115,41,2,218,2,46,48,218,4,112,97, + 114,116,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,218,10,60,108,105,115,116,99,111,109,112,62,64,0,0, + 0,115,6,0,0,0,6,1,2,0,4,255,122,30,95,112, + 97,116,104,95,106,111,105,110,46,60,108,111,99,97,108,115, + 62,46,60,108,105,115,116,99,111,109,112,62,41,2,218,8, + 112,97,116,104,95,115,101,112,218,4,106,111,105,110,41,1, + 218,10,112,97,116,104,95,112,97,114,116,115,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,10,95,112,97, + 116,104,95,106,111,105,110,62,0,0,0,115,6,0,0,0, + 0,2,10,1,2,255,114,38,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 67,0,0,0,115,96,0,0,0,116,0,116,1,131,1,100, + 1,107,2,114,36,124,0,160,2,116,3,161,1,92,3,125, + 1,125,2,125,3,124,1,124,3,102,2,83,0,116,4,124, + 0,131,1,68,0,93,42,125,4,124,4,116,1,107,6,114, + 44,124,0,106,5,124,4,100,1,100,2,141,2,92,2,125, + 1,125,3,124,1,124,3,102,2,2,0,1,0,83,0,113, + 44,100,3,124,0,102,2,83,0,41,4,122,32,82,101,112, + 108,97,99,101,109,101,110,116,32,102,111,114,32,111,115,46, + 112,97,116,104,46,115,112,108,105,116,40,41,46,233,1,0, + 0,0,41,1,90,8,109,97,120,115,112,108,105,116,218,0, + 41,6,114,22,0,0,0,114,31,0,0,0,218,10,114,112, + 97,114,116,105,116,105,111,110,114,35,0,0,0,218,8,114, + 101,118,101,114,115,101,100,218,6,114,115,112,108,105,116,41, + 5,218,4,112,97,116,104,90,5,102,114,111,110,116,218,1, + 95,218,4,116,97,105,108,114,19,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,11,95,112,97, + 116,104,95,115,112,108,105,116,68,0,0,0,115,16,0,0, + 0,0,2,12,1,16,1,8,1,12,1,8,1,18,1,14, + 1,114,47,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 10,0,0,0,116,0,160,1,124,0,161,1,83,0,41,1, + 122,126,83,116,97,116,32,116,104,101,32,112,97,116,104,46, + 10,10,32,32,32,32,77,97,100,101,32,97,32,115,101,112, + 97,114,97,116,101,32,102,117,110,99,116,105,111,110,32,116, + 111,32,109,97,107,101,32,105,116,32,101,97,115,105,101,114, + 32,116,111,32,111,118,101,114,114,105,100,101,32,105,110,32, + 101,120,112,101,114,105,109,101,110,116,115,10,32,32,32,32, + 40,101,46,103,46,32,99,97,99,104,101,32,115,116,97,116, + 32,114,101,115,117,108,116,115,41,46,10,10,32,32,32,32, + 41,2,114,2,0,0,0,90,4,115,116,97,116,169,1,114, + 44,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,10,95,112,97,116,104,95,115,116,97,116,80, + 0,0,0,115,2,0,0,0,0,7,114,49,0,0,0,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 8,0,0,0,67,0,0,0,115,50,0,0,0,122,12,116, + 0,124,0,131,1,125,2,87,0,110,22,4,0,116,1,107, + 10,114,34,1,0,1,0,1,0,89,0,100,1,83,0,88, + 0,124,2,106,2,100,2,64,0,124,1,107,2,83,0,41, + 3,122,49,84,101,115,116,32,119,104,101,116,104,101,114,32, + 116,104,101,32,112,97,116,104,32,105,115,32,116,104,101,32, + 115,112,101,99,105,102,105,101,100,32,109,111,100,101,32,116, + 121,112,101,46,70,105,0,240,0,0,41,3,114,49,0,0, + 0,218,7,79,83,69,114,114,111,114,218,7,115,116,95,109, + 111,100,101,41,3,114,44,0,0,0,218,4,109,111,100,101, + 90,9,115,116,97,116,95,105,110,102,111,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,18,95,112,97,116, + 104,95,105,115,95,109,111,100,101,95,116,121,112,101,90,0, + 0,0,115,10,0,0,0,0,2,2,1,12,1,14,1,8, + 1,114,53,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 10,0,0,0,116,0,124,0,100,1,131,2,83,0,41,2, + 122,31,82,101,112,108,97,99,101,109,101,110,116,32,102,111, + 114,32,111,115,46,112,97,116,104,46,105,115,102,105,108,101, + 46,105,0,128,0,0,41,1,114,53,0,0,0,114,48,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,11,95,112,97,116,104,95,105,115,97,98,115,111,0, - 0,0,115,2,0,0,0,0,6,114,59,0,0,0,233,182, - 1,0,0,99,3,0,0,0,0,0,0,0,0,0,0,0, - 6,0,0,0,11,0,0,0,67,0,0,0,115,162,0,0, - 0,100,1,160,0,124,0,116,1,124,0,131,1,161,2,125, - 3,116,2,160,3,124,3,116,2,106,4,116,2,106,5,66, - 0,116,2,106,6,66,0,124,2,100,2,64,0,161,3,125, - 4,122,50,116,7,160,8,124,4,100,3,161,2,143,16,125, - 5,124,5,160,9,124,1,161,1,1,0,87,0,53,0,81, - 0,82,0,88,0,116,2,160,10,124,3,124,0,161,2,1, - 0,87,0,110,58,4,0,116,11,107,10,114,156,1,0,1, - 0,1,0,122,14,116,2,160,12,124,3,161,1,1,0,87, - 0,110,20,4,0,116,11,107,10,114,148,1,0,1,0,1, - 0,89,0,110,2,88,0,130,0,89,0,110,2,88,0,100, - 4,83,0,41,5,122,162,66,101,115,116,45,101,102,102,111, - 114,116,32,102,117,110,99,116,105,111,110,32,116,111,32,119, - 114,105,116,101,32,100,97,116,97,32,116,111,32,97,32,112, - 97,116,104,32,97,116,111,109,105,99,97,108,108,121,46,10, - 32,32,32,32,66,101,32,112,114,101,112,97,114,101,100,32, - 116,111,32,104,97,110,100,108,101,32,97,32,70,105,108,101, - 69,120,105,115,116,115,69,114,114,111,114,32,105,102,32,99, - 111,110,99,117,114,114,101,110,116,32,119,114,105,116,105,110, - 103,32,111,102,32,116,104,101,10,32,32,32,32,116,101,109, - 112,111,114,97,114,121,32,102,105,108,101,32,105,115,32,97, - 116,116,101,109,112,116,101,100,46,250,5,123,125,46,123,125, - 114,60,0,0,0,90,2,119,98,78,41,13,218,6,102,111, - 114,109,97,116,218,2,105,100,114,2,0,0,0,90,4,111, - 112,101,110,90,6,79,95,69,88,67,76,90,7,79,95,67, - 82,69,65,84,90,8,79,95,87,82,79,78,76,89,218,3, - 95,105,111,218,6,70,105,108,101,73,79,218,5,119,114,105, - 116,101,218,7,114,101,112,108,97,99,101,114,50,0,0,0, - 90,6,117,110,108,105,110,107,41,6,114,44,0,0,0,114, - 26,0,0,0,114,52,0,0,0,90,8,112,97,116,104,95, - 116,109,112,90,2,102,100,218,4,102,105,108,101,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,13,95,119, - 114,105,116,101,95,97,116,111,109,105,99,120,0,0,0,115, - 30,0,0,0,0,5,16,1,6,1,16,0,6,255,4,2, - 2,3,14,1,20,1,16,1,14,1,2,1,14,1,14,1, - 6,1,114,69,0,0,0,105,82,13,0,0,114,28,0,0, - 0,114,16,0,0,0,115,2,0,0,0,13,10,90,11,95, - 95,112,121,99,97,99,104,101,95,95,122,4,111,112,116,45, - 122,3,46,112,121,122,4,46,112,121,99,78,41,1,218,12, - 111,112,116,105,109,105,122,97,116,105,111,110,99,2,0,0, - 0,0,0,0,0,1,0,0,0,12,0,0,0,5,0,0, - 0,67,0,0,0,115,88,1,0,0,124,1,100,1,107,9, - 114,52,116,0,160,1,100,2,116,2,161,2,1,0,124,2, - 100,1,107,9,114,40,100,3,125,3,116,3,124,3,131,1, - 130,1,124,1,114,48,100,4,110,2,100,5,125,2,116,4, - 160,5,124,0,161,1,125,0,116,6,124,0,131,1,92,2, - 125,4,125,5,124,5,160,7,100,6,161,1,92,3,125,6, - 125,7,125,8,116,8,106,9,106,10,125,9,124,9,100,1, - 107,8,114,114,116,11,100,7,131,1,130,1,100,4,160,12, - 124,6,114,126,124,6,110,2,124,8,124,7,124,9,103,3, - 161,1,125,10,124,2,100,1,107,8,114,172,116,8,106,13, - 106,14,100,8,107,2,114,164,100,4,125,2,110,8,116,8, - 106,13,106,14,125,2,116,15,124,2,131,1,125,2,124,2, - 100,4,107,3,114,224,124,2,160,16,161,0,115,210,116,17, - 100,9,160,18,124,2,161,1,131,1,130,1,100,10,160,18, - 124,10,116,19,124,2,161,3,125,10,124,10,116,20,100,8, - 25,0,23,0,125,11,116,8,106,21,100,1,107,9,144,1, - 114,76,116,22,124,4,131,1,144,1,115,16,116,23,116,4, - 160,24,161,0,124,4,131,2,125,4,124,4,100,5,25,0, - 100,11,107,2,144,1,114,56,124,4,100,8,25,0,116,25, - 107,7,144,1,114,56,124,4,100,12,100,1,133,2,25,0, - 125,4,116,23,116,8,106,21,124,4,160,26,116,25,161,1, - 124,11,131,3,83,0,116,23,124,4,116,27,124,11,131,3, - 83,0,41,13,97,254,2,0,0,71,105,118,101,110,32,116, - 104,101,32,112,97,116,104,32,116,111,32,97,32,46,112,121, - 32,102,105,108,101,44,32,114,101,116,117,114,110,32,116,104, - 101,32,112,97,116,104,32,116,111,32,105,116,115,32,46,112, - 121,99,32,102,105,108,101,46,10,10,32,32,32,32,84,104, - 101,32,46,112,121,32,102,105,108,101,32,100,111,101,115,32, - 110,111,116,32,110,101,101,100,32,116,111,32,101,120,105,115, - 116,59,32,116,104,105,115,32,115,105,109,112,108,121,32,114, - 101,116,117,114,110,115,32,116,104,101,32,112,97,116,104,32, - 116,111,32,116,104,101,10,32,32,32,32,46,112,121,99,32, - 102,105,108,101,32,99,97,108,99,117,108,97,116,101,100,32, - 97,115,32,105,102,32,116,104,101,32,46,112,121,32,102,105, - 108,101,32,119,101,114,101,32,105,109,112,111,114,116,101,100, - 46,10,10,32,32,32,32,84,104,101,32,39,111,112,116,105, - 109,105,122,97,116,105,111,110,39,32,112,97,114,97,109,101, - 116,101,114,32,99,111,110,116,114,111,108,115,32,116,104,101, - 32,112,114,101,115,117,109,101,100,32,111,112,116,105,109,105, - 122,97,116,105,111,110,32,108,101,118,101,108,32,111,102,10, - 32,32,32,32,116,104,101,32,98,121,116,101,99,111,100,101, - 32,102,105,108,101,46,32,73,102,32,39,111,112,116,105,109, - 105,122,97,116,105,111,110,39,32,105,115,32,110,111,116,32, - 78,111,110,101,44,32,116,104,101,32,115,116,114,105,110,103, - 32,114,101,112,114,101,115,101,110,116,97,116,105,111,110,10, - 32,32,32,32,111,102,32,116,104,101,32,97,114,103,117,109, - 101,110,116,32,105,115,32,116,97,107,101,110,32,97,110,100, - 32,118,101,114,105,102,105,101,100,32,116,111,32,98,101,32, - 97,108,112,104,97,110,117,109,101,114,105,99,32,40,101,108, - 115,101,32,86,97,108,117,101,69,114,114,111,114,10,32,32, - 32,32,105,115,32,114,97,105,115,101,100,41,46,10,10,32, - 32,32,32,84,104,101,32,100,101,98,117,103,95,111,118,101, - 114,114,105,100,101,32,112,97,114,97,109,101,116,101,114,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,73, - 102,32,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 32,105,115,32,110,111,116,32,78,111,110,101,44,10,32,32, - 32,32,97,32,84,114,117,101,32,118,97,108,117,101,32,105, - 115,32,116,104,101,32,115,97,109,101,32,97,115,32,115,101, + 0,218,12,95,112,97,116,104,95,105,115,102,105,108,101,99, + 0,0,0,115,2,0,0,0,0,2,114,54,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,22,0,0,0,124,0,115, + 12,116,0,160,1,161,0,125,0,116,2,124,0,100,1,131, + 2,83,0,41,2,122,30,82,101,112,108,97,99,101,109,101, + 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,105, + 115,100,105,114,46,105,0,64,0,0,41,3,114,2,0,0, + 0,218,6,103,101,116,99,119,100,114,53,0,0,0,114,48, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,11,95,112,97,116,104,95,105,115,100,105,114,104, + 0,0,0,115,6,0,0,0,0,2,4,1,8,1,114,56, + 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,3,0,0,0,67,0,0,0,115,26,0,0, + 0,124,0,160,0,116,1,161,1,112,24,124,0,100,1,100, + 2,133,2,25,0,116,2,107,6,83,0,41,3,122,142,82, + 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, + 115,46,112,97,116,104,46,105,115,97,98,115,46,10,10,32, + 32,32,32,67,111,110,115,105,100,101,114,115,32,97,32,87, + 105,110,100,111,119,115,32,100,114,105,118,101,45,114,101,108, + 97,116,105,118,101,32,112,97,116,104,32,40,110,111,32,100, + 114,105,118,101,44,32,98,117,116,32,115,116,97,114,116,115, + 32,119,105,116,104,32,115,108,97,115,104,41,32,116,111,10, + 32,32,32,32,115,116,105,108,108,32,98,101,32,34,97,98, + 115,111,108,117,116,101,34,46,10,32,32,32,32,114,39,0, + 0,0,233,3,0,0,0,41,3,114,10,0,0,0,114,31, + 0,0,0,218,20,95,112,97,116,104,115,101,112,115,95,119, + 105,116,104,95,99,111,108,111,110,114,48,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,11,95, + 112,97,116,104,95,105,115,97,98,115,111,0,0,0,115,2, + 0,0,0,0,6,114,59,0,0,0,233,182,1,0,0,99, + 3,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, + 11,0,0,0,67,0,0,0,115,162,0,0,0,100,1,160, + 0,124,0,116,1,124,0,131,1,161,2,125,3,116,2,160, + 3,124,3,116,2,106,4,116,2,106,5,66,0,116,2,106, + 6,66,0,124,2,100,2,64,0,161,3,125,4,122,50,116, + 7,160,8,124,4,100,3,161,2,143,16,125,5,124,5,160, + 9,124,1,161,1,1,0,87,0,53,0,81,0,82,0,88, + 0,116,2,160,10,124,3,124,0,161,2,1,0,87,0,110, + 58,4,0,116,11,107,10,114,156,1,0,1,0,1,0,122, + 14,116,2,160,12,124,3,161,1,1,0,87,0,110,20,4, + 0,116,11,107,10,114,148,1,0,1,0,1,0,89,0,110, + 2,88,0,130,0,89,0,110,2,88,0,100,4,83,0,41, + 5,122,162,66,101,115,116,45,101,102,102,111,114,116,32,102, + 117,110,99,116,105,111,110,32,116,111,32,119,114,105,116,101, + 32,100,97,116,97,32,116,111,32,97,32,112,97,116,104,32, + 97,116,111,109,105,99,97,108,108,121,46,10,32,32,32,32, + 66,101,32,112,114,101,112,97,114,101,100,32,116,111,32,104, + 97,110,100,108,101,32,97,32,70,105,108,101,69,120,105,115, + 116,115,69,114,114,111,114,32,105,102,32,99,111,110,99,117, + 114,114,101,110,116,32,119,114,105,116,105,110,103,32,111,102, + 32,116,104,101,10,32,32,32,32,116,101,109,112,111,114,97, + 114,121,32,102,105,108,101,32,105,115,32,97,116,116,101,109, + 112,116,101,100,46,250,5,123,125,46,123,125,114,60,0,0, + 0,90,2,119,98,78,41,13,218,6,102,111,114,109,97,116, + 218,2,105,100,114,2,0,0,0,90,4,111,112,101,110,90, + 6,79,95,69,88,67,76,90,7,79,95,67,82,69,65,84, + 90,8,79,95,87,82,79,78,76,89,218,3,95,105,111,218, + 6,70,105,108,101,73,79,218,5,119,114,105,116,101,218,7, + 114,101,112,108,97,99,101,114,50,0,0,0,90,6,117,110, + 108,105,110,107,41,6,114,44,0,0,0,114,26,0,0,0, + 114,52,0,0,0,90,8,112,97,116,104,95,116,109,112,90, + 2,102,100,218,4,102,105,108,101,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,95,119,114,105,116,101, + 95,97,116,111,109,105,99,120,0,0,0,115,30,0,0,0, + 0,5,16,1,6,1,16,0,6,255,4,2,2,3,14,1, + 20,1,16,1,14,1,2,1,14,1,14,1,6,1,114,69, + 0,0,0,105,82,13,0,0,114,28,0,0,0,114,16,0, + 0,0,115,2,0,0,0,13,10,90,11,95,95,112,121,99, + 97,99,104,101,95,95,122,4,111,112,116,45,122,3,46,112, + 121,122,4,46,112,121,99,78,41,1,218,12,111,112,116,105, + 109,105,122,97,116,105,111,110,99,2,0,0,0,0,0,0, + 0,1,0,0,0,12,0,0,0,5,0,0,0,67,0,0, + 0,115,88,1,0,0,124,1,100,1,107,9,114,52,116,0, + 160,1,100,2,116,2,161,2,1,0,124,2,100,1,107,9, + 114,40,100,3,125,3,116,3,124,3,131,1,130,1,124,1, + 114,48,100,4,110,2,100,5,125,2,116,4,160,5,124,0, + 161,1,125,0,116,6,124,0,131,1,92,2,125,4,125,5, + 124,5,160,7,100,6,161,1,92,3,125,6,125,7,125,8, + 116,8,106,9,106,10,125,9,124,9,100,1,107,8,114,114, + 116,11,100,7,131,1,130,1,100,4,160,12,124,6,114,126, + 124,6,110,2,124,8,124,7,124,9,103,3,161,1,125,10, + 124,2,100,1,107,8,114,172,116,8,106,13,106,14,100,8, + 107,2,114,164,100,4,125,2,110,8,116,8,106,13,106,14, + 125,2,116,15,124,2,131,1,125,2,124,2,100,4,107,3, + 114,224,124,2,160,16,161,0,115,210,116,17,100,9,160,18, + 124,2,161,1,131,1,130,1,100,10,160,18,124,10,116,19, + 124,2,161,3,125,10,124,10,116,20,100,8,25,0,23,0, + 125,11,116,8,106,21,100,1,107,9,144,1,114,76,116,22, + 124,4,131,1,144,1,115,16,116,23,116,4,160,24,161,0, + 124,4,131,2,125,4,124,4,100,5,25,0,100,11,107,2, + 144,1,114,56,124,4,100,8,25,0,116,25,107,7,144,1, + 114,56,124,4,100,12,100,1,133,2,25,0,125,4,116,23, + 116,8,106,21,124,4,160,26,116,25,161,1,124,11,131,3, + 83,0,116,23,124,4,116,27,124,11,131,3,83,0,41,13, + 97,254,2,0,0,71,105,118,101,110,32,116,104,101,32,112, + 97,116,104,32,116,111,32,97,32,46,112,121,32,102,105,108, + 101,44,32,114,101,116,117,114,110,32,116,104,101,32,112,97, + 116,104,32,116,111,32,105,116,115,32,46,112,121,99,32,102, + 105,108,101,46,10,10,32,32,32,32,84,104,101,32,46,112, + 121,32,102,105,108,101,32,100,111,101,115,32,110,111,116,32, + 110,101,101,100,32,116,111,32,101,120,105,115,116,59,32,116, + 104,105,115,32,115,105,109,112,108,121,32,114,101,116,117,114, + 110,115,32,116,104,101,32,112,97,116,104,32,116,111,32,116, + 104,101,10,32,32,32,32,46,112,121,99,32,102,105,108,101, + 32,99,97,108,99,117,108,97,116,101,100,32,97,115,32,105, + 102,32,116,104,101,32,46,112,121,32,102,105,108,101,32,119, + 101,114,101,32,105,109,112,111,114,116,101,100,46,10,10,32, + 32,32,32,84,104,101,32,39,111,112,116,105,109,105,122,97, + 116,105,111,110,39,32,112,97,114,97,109,101,116,101,114,32, + 99,111,110,116,114,111,108,115,32,116,104,101,32,112,114,101, + 115,117,109,101,100,32,111,112,116,105,109,105,122,97,116,105, + 111,110,32,108,101,118,101,108,32,111,102,10,32,32,32,32, + 116,104,101,32,98,121,116,101,99,111,100,101,32,102,105,108, + 101,46,32,73,102,32,39,111,112,116,105,109,105,122,97,116, + 105,111,110,39,32,105,115,32,110,111,116,32,78,111,110,101, + 44,32,116,104,101,32,115,116,114,105,110,103,32,114,101,112, + 114,101,115,101,110,116,97,116,105,111,110,10,32,32,32,32, + 111,102,32,116,104,101,32,97,114,103,117,109,101,110,116,32, + 105,115,32,116,97,107,101,110,32,97,110,100,32,118,101,114, + 105,102,105,101,100,32,116,111,32,98,101,32,97,108,112,104, + 97,110,117,109,101,114,105,99,32,40,101,108,115,101,32,86, + 97,108,117,101,69,114,114,111,114,10,32,32,32,32,105,115, + 32,114,97,105,115,101,100,41,46,10,10,32,32,32,32,84, + 104,101,32,100,101,98,117,103,95,111,118,101,114,114,105,100, + 101,32,112,97,114,97,109,101,116,101,114,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,46,32,73,102,32,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,32,105,115,32, + 110,111,116,32,78,111,110,101,44,10,32,32,32,32,97,32, + 84,114,117,101,32,118,97,108,117,101,32,105,115,32,116,104, + 101,32,115,97,109,101,32,97,115,32,115,101,116,116,105,110, + 103,32,39,111,112,116,105,109,105,122,97,116,105,111,110,39, + 32,116,111,32,116,104,101,32,101,109,112,116,121,32,115,116, + 114,105,110,103,10,32,32,32,32,119,104,105,108,101,32,97, + 32,70,97,108,115,101,32,118,97,108,117,101,32,105,115,32, + 101,113,117,105,118,97,108,101,110,116,32,116,111,32,115,101, 116,116,105,110,103,32,39,111,112,116,105,109,105,122,97,116, - 105,111,110,39,32,116,111,32,116,104,101,32,101,109,112,116, - 121,32,115,116,114,105,110,103,10,32,32,32,32,119,104,105, - 108,101,32,97,32,70,97,108,115,101,32,118,97,108,117,101, - 32,105,115,32,101,113,117,105,118,97,108,101,110,116,32,116, - 111,32,115,101,116,116,105,110,103,32,39,111,112,116,105,109, - 105,122,97,116,105,111,110,39,32,116,111,32,39,49,39,46, - 10,10,32,32,32,32,73,102,32,115,121,115,46,105,109,112, - 108,101,109,101,110,116,97,116,105,111,110,46,99,97,99,104, - 101,95,116,97,103,32,105,115,32,78,111,110,101,32,116,104, - 101,110,32,78,111,116,73,109,112,108,101,109,101,110,116,101, - 100,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, - 46,10,10,32,32,32,32,78,122,70,116,104,101,32,100,101, - 98,117,103,95,111,118,101,114,114,105,100,101,32,112,97,114, - 97,109,101,116,101,114,32,105,115,32,100,101,112,114,101,99, - 97,116,101,100,59,32,117,115,101,32,39,111,112,116,105,109, - 105,122,97,116,105,111,110,39,32,105,110,115,116,101,97,100, - 122,50,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 32,111,114,32,111,112,116,105,109,105,122,97,116,105,111,110, - 32,109,117,115,116,32,98,101,32,115,101,116,32,116,111,32, - 78,111,110,101,114,40,0,0,0,114,39,0,0,0,218,1, - 46,250,36,115,121,115,46,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,32, - 105,115,32,78,111,110,101,233,0,0,0,0,122,24,123,33, - 114,125,32,105,115,32,110,111,116,32,97,108,112,104,97,110, - 117,109,101,114,105,99,122,7,123,125,46,123,125,123,125,250, - 1,58,114,28,0,0,0,41,28,218,9,95,119,97,114,110, - 105,110,103,115,218,4,119,97,114,110,218,18,68,101,112,114, - 101,99,97,116,105,111,110,87,97,114,110,105,110,103,218,9, - 84,121,112,101,69,114,114,111,114,114,2,0,0,0,218,6, - 102,115,112,97,116,104,114,47,0,0,0,114,41,0,0,0, - 114,8,0,0,0,218,14,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,218,9,99,97,99,104,101,95,116,97,103, - 218,19,78,111,116,73,109,112,108,101,109,101,110,116,101,100, - 69,114,114,111,114,114,36,0,0,0,218,5,102,108,97,103, - 115,218,8,111,112,116,105,109,105,122,101,218,3,115,116,114, - 218,7,105,115,97,108,110,117,109,218,10,86,97,108,117,101, - 69,114,114,111,114,114,62,0,0,0,218,4,95,79,80,84, - 218,17,66,89,84,69,67,79,68,69,95,83,85,70,70,73, - 88,69,83,218,14,112,121,99,97,99,104,101,95,112,114,101, - 102,105,120,114,59,0,0,0,114,38,0,0,0,114,55,0, - 0,0,114,31,0,0,0,218,6,108,115,116,114,105,112,218, - 8,95,80,89,67,65,67,72,69,41,12,114,44,0,0,0, - 90,14,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 114,70,0,0,0,218,7,109,101,115,115,97,103,101,218,4, - 104,101,97,100,114,46,0,0,0,90,4,98,97,115,101,218, - 3,115,101,112,218,4,114,101,115,116,90,3,116,97,103,90, - 15,97,108,109,111,115,116,95,102,105,108,101,110,97,109,101, - 218,8,102,105,108,101,110,97,109,101,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,17,99,97,99,104,101, - 95,102,114,111,109,95,115,111,117,114,99,101,33,1,0,0, - 115,72,0,0,0,0,18,8,1,6,1,2,255,4,2,8, - 1,4,1,8,1,12,1,10,1,12,1,16,1,8,1,8, - 1,8,1,24,1,8,1,12,1,6,2,8,1,8,1,8, - 1,8,1,14,1,14,1,12,1,12,9,10,1,14,5,28, - 1,12,4,2,1,4,1,8,1,2,253,4,5,114,98,0, - 0,0,99,1,0,0,0,0,0,0,0,0,0,0,0,10, - 0,0,0,5,0,0,0,67,0,0,0,115,46,1,0,0, - 116,0,106,1,106,2,100,1,107,8,114,20,116,3,100,2, - 131,1,130,1,116,4,160,5,124,0,161,1,125,0,116,6, - 124,0,131,1,92,2,125,1,125,2,100,3,125,3,116,0, - 106,7,100,1,107,9,114,102,116,0,106,7,160,8,116,9, - 161,1,125,4,124,1,160,10,124,4,116,11,23,0,161,1, - 114,102,124,1,116,12,124,4,131,1,100,1,133,2,25,0, - 125,1,100,4,125,3,124,3,115,144,116,6,124,1,131,1, - 92,2,125,1,125,5,124,5,116,13,107,3,114,144,116,14, - 116,13,155,0,100,5,124,0,155,2,157,3,131,1,130,1, - 124,2,160,15,100,6,161,1,125,6,124,6,100,7,107,7, - 114,178,116,14,100,8,124,2,155,2,157,2,131,1,130,1, - 110,92,124,6,100,9,107,2,144,1,114,14,124,2,160,16, - 100,6,100,10,161,2,100,11,25,0,125,7,124,7,160,10, - 116,17,161,1,115,228,116,14,100,12,116,17,155,2,157,2, - 131,1,130,1,124,7,116,12,116,17,131,1,100,1,133,2, - 25,0,125,8,124,8,160,18,161,0,144,1,115,14,116,14, - 100,13,124,7,155,2,100,14,157,3,131,1,130,1,124,2, - 160,19,100,6,161,1,100,15,25,0,125,9,116,20,124,1, - 124,9,116,21,100,15,25,0,23,0,131,2,83,0,41,16, - 97,110,1,0,0,71,105,118,101,110,32,116,104,101,32,112, - 97,116,104,32,116,111,32,97,32,46,112,121,99,46,32,102, - 105,108,101,44,32,114,101,116,117,114,110,32,116,104,101,32, - 112,97,116,104,32,116,111,32,105,116,115,32,46,112,121,32, - 102,105,108,101,46,10,10,32,32,32,32,84,104,101,32,46, - 112,121,99,32,102,105,108,101,32,100,111,101,115,32,110,111, - 116,32,110,101,101,100,32,116,111,32,101,120,105,115,116,59, - 32,116,104,105,115,32,115,105,109,112,108,121,32,114,101,116, - 117,114,110,115,32,116,104,101,32,112,97,116,104,32,116,111, - 10,32,32,32,32,116,104,101,32,46,112,121,32,102,105,108, - 101,32,99,97,108,99,117,108,97,116,101,100,32,116,111,32, - 99,111,114,114,101,115,112,111,110,100,32,116,111,32,116,104, - 101,32,46,112,121,99,32,102,105,108,101,46,32,32,73,102, - 32,112,97,116,104,32,100,111,101,115,10,32,32,32,32,110, - 111,116,32,99,111,110,102,111,114,109,32,116,111,32,80,69, - 80,32,51,49,52,55,47,52,56,56,32,102,111,114,109,97, - 116,44,32,86,97,108,117,101,69,114,114,111,114,32,119,105, - 108,108,32,98,101,32,114,97,105,115,101,100,46,32,73,102, - 10,32,32,32,32,115,121,115,46,105,109,112,108,101,109,101, + 105,111,110,39,32,116,111,32,39,49,39,46,10,10,32,32, + 32,32,73,102,32,115,121,115,46,105,109,112,108,101,109,101, 110,116,97,116,105,111,110,46,99,97,99,104,101,95,116,97, 103,32,105,115,32,78,111,110,101,32,116,104,101,110,32,78, 111,116,73,109,112,108,101,109,101,110,116,101,100,69,114,114, 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,114,72,0,0,0,70,84,122,31,32,110,111, - 116,32,98,111,116,116,111,109,45,108,101,118,101,108,32,100, - 105,114,101,99,116,111,114,121,32,105,110,32,114,71,0,0, - 0,62,2,0,0,0,114,28,0,0,0,114,57,0,0,0, - 122,29,101,120,112,101,99,116,101,100,32,111,110,108,121,32, - 50,32,111,114,32,51,32,100,111,116,115,32,105,110,32,114, - 57,0,0,0,114,28,0,0,0,233,254,255,255,255,122,53, - 111,112,116,105,109,105,122,97,116,105,111,110,32,112,111,114, - 116,105,111,110,32,111,102,32,102,105,108,101,110,97,109,101, - 32,100,111,101,115,32,110,111,116,32,115,116,97,114,116,32, - 119,105,116,104,32,122,19,111,112,116,105,109,105,122,97,116, - 105,111,110,32,108,101,118,101,108,32,122,29,32,105,115,32, - 110,111,116,32,97,110,32,97,108,112,104,97,110,117,109,101, - 114,105,99,32,118,97,108,117,101,114,73,0,0,0,41,22, - 114,8,0,0,0,114,80,0,0,0,114,81,0,0,0,114, - 82,0,0,0,114,2,0,0,0,114,79,0,0,0,114,47, - 0,0,0,114,90,0,0,0,114,30,0,0,0,114,31,0, - 0,0,114,10,0,0,0,114,35,0,0,0,114,22,0,0, - 0,114,92,0,0,0,114,87,0,0,0,218,5,99,111,117, - 110,116,114,43,0,0,0,114,88,0,0,0,114,86,0,0, - 0,218,9,112,97,114,116,105,116,105,111,110,114,38,0,0, - 0,218,15,83,79,85,82,67,69,95,83,85,70,70,73,88, - 69,83,41,10,114,44,0,0,0,114,94,0,0,0,90,16, - 112,121,99,97,99,104,101,95,102,105,108,101,110,97,109,101, - 90,23,102,111,117,110,100,95,105,110,95,112,121,99,97,99, - 104,101,95,112,114,101,102,105,120,90,13,115,116,114,105,112, - 112,101,100,95,112,97,116,104,90,7,112,121,99,97,99,104, - 101,90,9,100,111,116,95,99,111,117,110,116,114,70,0,0, - 0,90,9,111,112,116,95,108,101,118,101,108,90,13,98,97, - 115,101,95,102,105,108,101,110,97,109,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,17,115,111,117,114, - 99,101,95,102,114,111,109,95,99,97,99,104,101,104,1,0, - 0,115,52,0,0,0,0,9,12,1,8,1,10,1,12,1, - 4,1,10,1,12,1,14,1,16,1,4,1,4,1,12,1, - 8,1,18,2,10,1,8,1,16,1,10,1,16,1,10,1, - 14,2,16,1,10,1,16,2,14,1,114,103,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 9,0,0,0,67,0,0,0,115,126,0,0,0,116,0,124, - 0,131,1,100,1,107,2,114,16,100,2,83,0,124,0,160, - 1,100,3,161,1,92,3,125,1,125,2,125,3,124,1,114, - 56,124,3,160,2,161,0,100,4,100,5,133,2,25,0,100, - 6,107,3,114,60,124,0,83,0,122,12,116,3,124,0,131, - 1,125,4,87,0,110,36,4,0,116,4,116,5,102,2,107, - 10,114,108,1,0,1,0,1,0,124,0,100,2,100,5,133, - 2,25,0,125,4,89,0,110,2,88,0,116,6,124,4,131, - 1,114,122,124,4,83,0,124,0,83,0,41,7,122,188,67, - 111,110,118,101,114,116,32,97,32,98,121,116,101,99,111,100, - 101,32,102,105,108,101,32,112,97,116,104,32,116,111,32,97, - 32,115,111,117,114,99,101,32,112,97,116,104,32,40,105,102, - 32,112,111,115,115,105,98,108,101,41,46,10,10,32,32,32, - 32,84,104,105,115,32,102,117,110,99,116,105,111,110,32,101, - 120,105,115,116,115,32,112,117,114,101,108,121,32,102,111,114, - 32,98,97,99,107,119,97,114,100,115,45,99,111,109,112,97, - 116,105,98,105,108,105,116,121,32,102,111,114,10,32,32,32, - 32,80,121,73,109,112,111,114,116,95,69,120,101,99,67,111, - 100,101,77,111,100,117,108,101,87,105,116,104,70,105,108,101, - 110,97,109,101,115,40,41,32,105,110,32,116,104,101,32,67, - 32,65,80,73,46,10,10,32,32,32,32,114,73,0,0,0, - 78,114,71,0,0,0,233,253,255,255,255,233,255,255,255,255, - 90,2,112,121,41,7,114,22,0,0,0,114,41,0,0,0, - 218,5,108,111,119,101,114,114,103,0,0,0,114,82,0,0, - 0,114,87,0,0,0,114,54,0,0,0,41,5,218,13,98, - 121,116,101,99,111,100,101,95,112,97,116,104,114,96,0,0, - 0,114,45,0,0,0,90,9,101,120,116,101,110,115,105,111, - 110,218,11,115,111,117,114,99,101,95,112,97,116,104,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,15,95, - 103,101,116,95,115,111,117,114,99,101,102,105,108,101,144,1, - 0,0,115,20,0,0,0,0,7,12,1,4,1,16,1,24, - 1,4,1,2,1,12,1,18,1,18,1,114,109,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,8,0,0,0,67,0,0,0,115,74,0,0,0,124,0, - 160,0,116,1,116,2,131,1,161,1,114,48,122,10,116,3, - 124,0,131,1,87,0,83,0,4,0,116,4,107,10,114,44, - 1,0,1,0,1,0,89,0,113,70,88,0,110,22,124,0, - 160,0,116,1,116,5,131,1,161,1,114,66,124,0,83,0, - 100,0,83,0,100,0,83,0,169,1,78,41,6,218,8,101, - 110,100,115,119,105,116,104,218,5,116,117,112,108,101,114,102, - 0,0,0,114,98,0,0,0,114,82,0,0,0,114,89,0, - 0,0,41,1,114,97,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,11,95,103,101,116,95,99, - 97,99,104,101,100,163,1,0,0,115,16,0,0,0,0,1, - 14,1,2,1,10,1,14,1,8,1,14,1,4,2,114,113, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,8,0,0,0,67,0,0,0,115,52,0,0, - 0,122,14,116,0,124,0,131,1,106,1,125,1,87,0,110, - 24,4,0,116,2,107,10,114,38,1,0,1,0,1,0,100, - 1,125,1,89,0,110,2,88,0,124,1,100,2,79,0,125, - 1,124,1,83,0,41,3,122,51,67,97,108,99,117,108,97, - 116,101,32,116,104,101,32,109,111,100,101,32,112,101,114,109, - 105,115,115,105,111,110,115,32,102,111,114,32,97,32,98,121, - 116,101,99,111,100,101,32,102,105,108,101,46,114,60,0,0, - 0,233,128,0,0,0,41,3,114,49,0,0,0,114,51,0, - 0,0,114,50,0,0,0,41,2,114,44,0,0,0,114,52, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,10,95,99,97,108,99,95,109,111,100,101,175,1, - 0,0,115,12,0,0,0,0,2,2,1,14,1,14,1,10, - 3,8,1,114,115,0,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,8,0,0,0,3,0,0, - 0,115,68,0,0,0,100,6,135,0,102,1,100,2,100,3, - 132,9,125,1,122,10,116,0,106,1,125,2,87,0,110,28, - 4,0,116,2,107,10,114,52,1,0,1,0,1,0,100,4, - 100,5,132,0,125,2,89,0,110,2,88,0,124,2,124,1, - 136,0,131,2,1,0,124,1,83,0,41,7,122,252,68,101, - 99,111,114,97,116,111,114,32,116,111,32,118,101,114,105,102, - 121,32,116,104,97,116,32,116,104,101,32,109,111,100,117,108, - 101,32,98,101,105,110,103,32,114,101,113,117,101,115,116,101, - 100,32,109,97,116,99,104,101,115,32,116,104,101,32,111,110, - 101,32,116,104,101,10,32,32,32,32,108,111,97,100,101,114, - 32,99,97,110,32,104,97,110,100,108,101,46,10,10,32,32, - 32,32,84,104,101,32,102,105,114,115,116,32,97,114,103,117, - 109,101,110,116,32,40,115,101,108,102,41,32,109,117,115,116, - 32,100,101,102,105,110,101,32,95,110,97,109,101,32,119,104, - 105,99,104,32,116,104,101,32,115,101,99,111,110,100,32,97, - 114,103,117,109,101,110,116,32,105,115,10,32,32,32,32,99, - 111,109,112,97,114,101,100,32,97,103,97,105,110,115,116,46, - 32,73,102,32,116,104,101,32,99,111,109,112,97,114,105,115, - 111,110,32,102,97,105,108,115,32,116,104,101,110,32,73,109, - 112,111,114,116,69,114,114,111,114,32,105,115,32,114,97,105, - 115,101,100,46,10,10,32,32,32,32,78,99,2,0,0,0, - 0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, - 31,0,0,0,115,66,0,0,0,124,1,100,0,107,8,114, - 16,124,0,106,0,125,1,110,32,124,0,106,0,124,1,107, - 3,114,48,116,1,100,1,124,0,106,0,124,1,102,2,22, - 0,124,1,100,2,141,2,130,1,136,0,124,0,124,1,102, - 2,124,2,158,2,124,3,142,1,83,0,41,3,78,122,30, - 108,111,97,100,101,114,32,102,111,114,32,37,115,32,99,97, - 110,110,111,116,32,104,97,110,100,108,101,32,37,115,169,1, - 218,4,110,97,109,101,41,2,114,117,0,0,0,218,11,73, - 109,112,111,114,116,69,114,114,111,114,41,4,218,4,115,101, - 108,102,114,117,0,0,0,218,4,97,114,103,115,90,6,107, - 119,97,114,103,115,169,1,218,6,109,101,116,104,111,100,114, - 3,0,0,0,114,6,0,0,0,218,19,95,99,104,101,99, - 107,95,110,97,109,101,95,119,114,97,112,112,101,114,195,1, - 0,0,115,18,0,0,0,0,1,8,1,8,1,10,1,4, - 1,8,255,2,1,2,255,6,2,122,40,95,99,104,101,99, - 107,95,110,97,109,101,46,60,108,111,99,97,108,115,62,46, - 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, - 112,101,114,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,7,0,0,0,83,0,0,0,115,56,0,0, - 0,100,1,68,0,93,32,125,2,116,0,124,1,124,2,131, - 2,114,4,116,1,124,0,124,2,116,2,124,1,124,2,131, - 2,131,3,1,0,113,4,124,0,106,3,160,4,124,1,106, - 3,161,1,1,0,100,0,83,0,41,2,78,41,4,218,10, - 95,95,109,111,100,117,108,101,95,95,218,8,95,95,110,97, - 109,101,95,95,218,12,95,95,113,117,97,108,110,97,109,101, - 95,95,218,7,95,95,100,111,99,95,95,41,5,218,7,104, - 97,115,97,116,116,114,218,7,115,101,116,97,116,116,114,218, - 7,103,101,116,97,116,116,114,218,8,95,95,100,105,99,116, - 95,95,218,6,117,112,100,97,116,101,41,3,90,3,110,101, - 119,90,3,111,108,100,114,67,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,5,95,119,114,97, - 112,206,1,0,0,115,8,0,0,0,0,1,8,1,10,1, - 20,1,122,26,95,99,104,101,99,107,95,110,97,109,101,46, - 60,108,111,99,97,108,115,62,46,95,119,114,97,112,41,1, - 78,41,3,218,10,95,98,111,111,116,115,116,114,97,112,114, - 133,0,0,0,218,9,78,97,109,101,69,114,114,111,114,41, - 3,114,122,0,0,0,114,123,0,0,0,114,133,0,0,0, - 114,3,0,0,0,114,121,0,0,0,114,6,0,0,0,218, - 11,95,99,104,101,99,107,95,110,97,109,101,187,1,0,0, - 115,14,0,0,0,0,8,14,7,2,1,10,1,14,2,14, - 5,10,1,114,136,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,5,0,0,0,6,0,0,0,67,0,0, - 0,115,60,0,0,0,124,0,160,0,124,1,161,1,92,2, - 125,2,125,3,124,2,100,1,107,8,114,56,116,1,124,3, - 131,1,114,56,100,2,125,4,116,2,160,3,124,4,160,4, - 124,3,100,3,25,0,161,1,116,5,161,2,1,0,124,2, - 83,0,41,4,122,155,84,114,121,32,116,111,32,102,105,110, - 100,32,97,32,108,111,97,100,101,114,32,102,111,114,32,116, - 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, - 117,108,101,32,98,121,32,100,101,108,101,103,97,116,105,110, - 103,32,116,111,10,32,32,32,32,115,101,108,102,46,102,105, - 110,100,95,108,111,97,100,101,114,40,41,46,10,10,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,32,105,110,32,102, - 97,118,111,114,32,111,102,32,102,105,110,100,101,114,46,102, - 105,110,100,95,115,112,101,99,40,41,46,10,10,32,32,32, - 32,78,122,44,78,111,116,32,105,109,112,111,114,116,105,110, - 103,32,100,105,114,101,99,116,111,114,121,32,123,125,58,32, - 109,105,115,115,105,110,103,32,95,95,105,110,105,116,95,95, - 114,73,0,0,0,41,6,218,11,102,105,110,100,95,108,111, - 97,100,101,114,114,22,0,0,0,114,75,0,0,0,114,76, - 0,0,0,114,62,0,0,0,218,13,73,109,112,111,114,116, - 87,97,114,110,105,110,103,41,5,114,119,0,0,0,218,8, - 102,117,108,108,110,97,109,101,218,6,108,111,97,100,101,114, - 218,8,112,111,114,116,105,111,110,115,218,3,109,115,103,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,17, - 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, - 109,215,1,0,0,115,10,0,0,0,0,10,14,1,16,1, - 4,1,22,1,114,143,0,0,0,99,3,0,0,0,0,0, - 0,0,0,0,0,0,6,0,0,0,4,0,0,0,67,0, - 0,0,115,158,0,0,0,124,0,100,1,100,2,133,2,25, - 0,125,3,124,3,116,0,107,3,114,60,100,3,124,1,155, - 2,100,4,124,3,155,2,157,4,125,4,116,1,160,2,100, - 5,124,4,161,2,1,0,116,3,124,4,102,1,124,2,142, - 1,130,1,116,4,124,0,131,1,100,6,107,0,114,102,100, - 7,124,1,155,2,157,2,125,4,116,1,160,2,100,5,124, - 4,161,2,1,0,116,5,124,4,131,1,130,1,116,6,124, - 0,100,2,100,8,133,2,25,0,131,1,125,5,124,5,100, - 9,64,0,114,154,100,10,124,5,155,2,100,11,124,1,155, - 2,157,4,125,4,116,3,124,4,102,1,124,2,142,1,130, - 1,124,5,83,0,41,12,97,84,2,0,0,80,101,114,102, - 111,114,109,32,98,97,115,105,99,32,118,97,108,105,100,105, - 116,121,32,99,104,101,99,107,105,110,103,32,111,102,32,97, - 32,112,121,99,32,104,101,97,100,101,114,32,97,110,100,32, - 114,101,116,117,114,110,32,116,104,101,32,102,108,97,103,115, - 32,102,105,101,108,100,44,10,32,32,32,32,119,104,105,99, - 104,32,100,101,116,101,114,109,105,110,101,115,32,104,111,119, - 32,116,104,101,32,112,121,99,32,115,104,111,117,108,100,32, - 98,101,32,102,117,114,116,104,101,114,32,118,97,108,105,100, - 97,116,101,100,32,97,103,97,105,110,115,116,32,116,104,101, - 32,115,111,117,114,99,101,46,10,10,32,32,32,32,42,100, + 32,32,32,78,122,70,116,104,101,32,100,101,98,117,103,95, + 111,118,101,114,114,105,100,101,32,112,97,114,97,109,101,116, + 101,114,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 59,32,117,115,101,32,39,111,112,116,105,109,105,122,97,116, + 105,111,110,39,32,105,110,115,116,101,97,100,122,50,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,32,111,114,32, + 111,112,116,105,109,105,122,97,116,105,111,110,32,109,117,115, + 116,32,98,101,32,115,101,116,32,116,111,32,78,111,110,101, + 114,40,0,0,0,114,39,0,0,0,218,1,46,250,36,115, + 121,115,46,105,109,112,108,101,109,101,110,116,97,116,105,111, + 110,46,99,97,99,104,101,95,116,97,103,32,105,115,32,78, + 111,110,101,233,0,0,0,0,122,24,123,33,114,125,32,105, + 115,32,110,111,116,32,97,108,112,104,97,110,117,109,101,114, + 105,99,122,7,123,125,46,123,125,123,125,250,1,58,114,28, + 0,0,0,41,28,218,9,95,119,97,114,110,105,110,103,115, + 218,4,119,97,114,110,218,18,68,101,112,114,101,99,97,116, + 105,111,110,87,97,114,110,105,110,103,218,9,84,121,112,101, + 69,114,114,111,114,114,2,0,0,0,218,6,102,115,112,97, + 116,104,114,47,0,0,0,114,41,0,0,0,114,8,0,0, + 0,218,14,105,109,112,108,101,109,101,110,116,97,116,105,111, + 110,218,9,99,97,99,104,101,95,116,97,103,218,19,78,111, + 116,73,109,112,108,101,109,101,110,116,101,100,69,114,114,111, + 114,114,36,0,0,0,218,5,102,108,97,103,115,218,8,111, + 112,116,105,109,105,122,101,218,3,115,116,114,218,7,105,115, + 97,108,110,117,109,218,10,86,97,108,117,101,69,114,114,111, + 114,114,62,0,0,0,218,4,95,79,80,84,218,17,66,89, + 84,69,67,79,68,69,95,83,85,70,70,73,88,69,83,218, + 14,112,121,99,97,99,104,101,95,112,114,101,102,105,120,114, + 59,0,0,0,114,38,0,0,0,114,55,0,0,0,114,31, + 0,0,0,218,6,108,115,116,114,105,112,218,8,95,80,89, + 67,65,67,72,69,41,12,114,44,0,0,0,90,14,100,101, + 98,117,103,95,111,118,101,114,114,105,100,101,114,70,0,0, + 0,218,7,109,101,115,115,97,103,101,218,4,104,101,97,100, + 114,46,0,0,0,90,4,98,97,115,101,218,3,115,101,112, + 218,4,114,101,115,116,90,3,116,97,103,90,15,97,108,109, + 111,115,116,95,102,105,108,101,110,97,109,101,218,8,102,105, + 108,101,110,97,109,101,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,17,99,97,99,104,101,95,102,114,111, + 109,95,115,111,117,114,99,101,33,1,0,0,115,72,0,0, + 0,0,18,8,1,6,1,2,255,4,2,8,1,4,1,8, + 1,12,1,10,1,12,1,16,1,8,1,8,1,8,1,24, + 1,8,1,12,1,6,2,8,1,8,1,8,1,8,1,14, + 1,14,1,12,1,12,9,10,1,14,5,28,1,12,4,2, + 1,4,1,8,1,2,253,4,5,114,98,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,5, + 0,0,0,67,0,0,0,115,46,1,0,0,116,0,106,1, + 106,2,100,1,107,8,114,20,116,3,100,2,131,1,130,1, + 116,4,160,5,124,0,161,1,125,0,116,6,124,0,131,1, + 92,2,125,1,125,2,100,3,125,3,116,0,106,7,100,1, + 107,9,114,102,116,0,106,7,160,8,116,9,161,1,125,4, + 124,1,160,10,124,4,116,11,23,0,161,1,114,102,124,1, + 116,12,124,4,131,1,100,1,133,2,25,0,125,1,100,4, + 125,3,124,3,115,144,116,6,124,1,131,1,92,2,125,1, + 125,5,124,5,116,13,107,3,114,144,116,14,116,13,155,0, + 100,5,124,0,155,2,157,3,131,1,130,1,124,2,160,15, + 100,6,161,1,125,6,124,6,100,7,107,7,114,178,116,14, + 100,8,124,2,155,2,157,2,131,1,130,1,110,92,124,6, + 100,9,107,2,144,1,114,14,124,2,160,16,100,6,100,10, + 161,2,100,11,25,0,125,7,124,7,160,10,116,17,161,1, + 115,228,116,14,100,12,116,17,155,2,157,2,131,1,130,1, + 124,7,116,12,116,17,131,1,100,1,133,2,25,0,125,8, + 124,8,160,18,161,0,144,1,115,14,116,14,100,13,124,7, + 155,2,100,14,157,3,131,1,130,1,124,2,160,19,100,6, + 161,1,100,15,25,0,125,9,116,20,124,1,124,9,116,21, + 100,15,25,0,23,0,131,2,83,0,41,16,97,110,1,0, + 0,71,105,118,101,110,32,116,104,101,32,112,97,116,104,32, + 116,111,32,97,32,46,112,121,99,46,32,102,105,108,101,44, + 32,114,101,116,117,114,110,32,116,104,101,32,112,97,116,104, + 32,116,111,32,105,116,115,32,46,112,121,32,102,105,108,101, + 46,10,10,32,32,32,32,84,104,101,32,46,112,121,99,32, + 102,105,108,101,32,100,111,101,115,32,110,111,116,32,110,101, + 101,100,32,116,111,32,101,120,105,115,116,59,32,116,104,105, + 115,32,115,105,109,112,108,121,32,114,101,116,117,114,110,115, + 32,116,104,101,32,112,97,116,104,32,116,111,10,32,32,32, + 32,116,104,101,32,46,112,121,32,102,105,108,101,32,99,97, + 108,99,117,108,97,116,101,100,32,116,111,32,99,111,114,114, + 101,115,112,111,110,100,32,116,111,32,116,104,101,32,46,112, + 121,99,32,102,105,108,101,46,32,32,73,102,32,112,97,116, + 104,32,100,111,101,115,10,32,32,32,32,110,111,116,32,99, + 111,110,102,111,114,109,32,116,111,32,80,69,80,32,51,49, + 52,55,47,52,56,56,32,102,111,114,109,97,116,44,32,86, + 97,108,117,101,69,114,114,111,114,32,119,105,108,108,32,98, + 101,32,114,97,105,115,101,100,46,32,73,102,10,32,32,32, + 32,115,121,115,46,105,109,112,108,101,109,101,110,116,97,116, + 105,111,110,46,99,97,99,104,101,95,116,97,103,32,105,115, + 32,78,111,110,101,32,116,104,101,110,32,78,111,116,73,109, + 112,108,101,109,101,110,116,101,100,69,114,114,111,114,32,105, + 115,32,114,97,105,115,101,100,46,10,10,32,32,32,32,78, + 114,72,0,0,0,70,84,122,31,32,110,111,116,32,98,111, + 116,116,111,109,45,108,101,118,101,108,32,100,105,114,101,99, + 116,111,114,121,32,105,110,32,114,71,0,0,0,62,2,0, + 0,0,114,28,0,0,0,114,57,0,0,0,122,29,101,120, + 112,101,99,116,101,100,32,111,110,108,121,32,50,32,111,114, + 32,51,32,100,111,116,115,32,105,110,32,114,57,0,0,0, + 114,28,0,0,0,233,254,255,255,255,122,53,111,112,116,105, + 109,105,122,97,116,105,111,110,32,112,111,114,116,105,111,110, + 32,111,102,32,102,105,108,101,110,97,109,101,32,100,111,101, + 115,32,110,111,116,32,115,116,97,114,116,32,119,105,116,104, + 32,122,19,111,112,116,105,109,105,122,97,116,105,111,110,32, + 108,101,118,101,108,32,122,29,32,105,115,32,110,111,116,32, + 97,110,32,97,108,112,104,97,110,117,109,101,114,105,99,32, + 118,97,108,117,101,114,73,0,0,0,41,22,114,8,0,0, + 0,114,80,0,0,0,114,81,0,0,0,114,82,0,0,0, + 114,2,0,0,0,114,79,0,0,0,114,47,0,0,0,114, + 90,0,0,0,114,30,0,0,0,114,31,0,0,0,114,10, + 0,0,0,114,35,0,0,0,114,22,0,0,0,114,92,0, + 0,0,114,87,0,0,0,218,5,99,111,117,110,116,114,43, + 0,0,0,114,88,0,0,0,114,86,0,0,0,218,9,112, + 97,114,116,105,116,105,111,110,114,38,0,0,0,218,15,83, + 79,85,82,67,69,95,83,85,70,70,73,88,69,83,41,10, + 114,44,0,0,0,114,94,0,0,0,90,16,112,121,99,97, + 99,104,101,95,102,105,108,101,110,97,109,101,90,23,102,111, + 117,110,100,95,105,110,95,112,121,99,97,99,104,101,95,112, + 114,101,102,105,120,90,13,115,116,114,105,112,112,101,100,95, + 112,97,116,104,90,7,112,121,99,97,99,104,101,90,9,100, + 111,116,95,99,111,117,110,116,114,70,0,0,0,90,9,111, + 112,116,95,108,101,118,101,108,90,13,98,97,115,101,95,102, + 105,108,101,110,97,109,101,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,17,115,111,117,114,99,101,95,102, + 114,111,109,95,99,97,99,104,101,104,1,0,0,115,52,0, + 0,0,0,9,12,1,8,1,10,1,12,1,4,1,10,1, + 12,1,14,1,16,1,4,1,4,1,12,1,8,1,18,2, + 10,1,8,1,16,1,10,1,16,1,10,1,14,2,16,1, + 10,1,16,2,14,1,114,103,0,0,0,99,1,0,0,0, + 0,0,0,0,0,0,0,0,5,0,0,0,9,0,0,0, + 67,0,0,0,115,126,0,0,0,116,0,124,0,131,1,100, + 1,107,2,114,16,100,2,83,0,124,0,160,1,100,3,161, + 1,92,3,125,1,125,2,125,3,124,1,114,56,124,3,160, + 2,161,0,100,4,100,5,133,2,25,0,100,6,107,3,114, + 60,124,0,83,0,122,12,116,3,124,0,131,1,125,4,87, + 0,110,36,4,0,116,4,116,5,102,2,107,10,114,108,1, + 0,1,0,1,0,124,0,100,2,100,5,133,2,25,0,125, + 4,89,0,110,2,88,0,116,6,124,4,131,1,114,122,124, + 4,83,0,124,0,83,0,41,7,122,188,67,111,110,118,101, + 114,116,32,97,32,98,121,116,101,99,111,100,101,32,102,105, + 108,101,32,112,97,116,104,32,116,111,32,97,32,115,111,117, + 114,99,101,32,112,97,116,104,32,40,105,102,32,112,111,115, + 115,105,98,108,101,41,46,10,10,32,32,32,32,84,104,105, + 115,32,102,117,110,99,116,105,111,110,32,101,120,105,115,116, + 115,32,112,117,114,101,108,121,32,102,111,114,32,98,97,99, + 107,119,97,114,100,115,45,99,111,109,112,97,116,105,98,105, + 108,105,116,121,32,102,111,114,10,32,32,32,32,80,121,73, + 109,112,111,114,116,95,69,120,101,99,67,111,100,101,77,111, + 100,117,108,101,87,105,116,104,70,105,108,101,110,97,109,101, + 115,40,41,32,105,110,32,116,104,101,32,67,32,65,80,73, + 46,10,10,32,32,32,32,114,73,0,0,0,78,114,71,0, + 0,0,233,253,255,255,255,233,255,255,255,255,90,2,112,121, + 41,7,114,22,0,0,0,114,41,0,0,0,218,5,108,111, + 119,101,114,114,103,0,0,0,114,82,0,0,0,114,87,0, + 0,0,114,54,0,0,0,41,5,218,13,98,121,116,101,99, + 111,100,101,95,112,97,116,104,114,96,0,0,0,114,45,0, + 0,0,90,9,101,120,116,101,110,115,105,111,110,218,11,115, + 111,117,114,99,101,95,112,97,116,104,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,15,95,103,101,116,95, + 115,111,117,114,99,101,102,105,108,101,144,1,0,0,115,20, + 0,0,0,0,7,12,1,4,1,16,1,24,1,4,1,2, + 1,12,1,18,1,18,1,114,109,0,0,0,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0, + 0,67,0,0,0,115,74,0,0,0,124,0,160,0,116,1, + 116,2,131,1,161,1,114,48,122,10,116,3,124,0,131,1, + 87,0,83,0,4,0,116,4,107,10,114,44,1,0,1,0, + 1,0,89,0,113,70,88,0,110,22,124,0,160,0,116,1, + 116,5,131,1,161,1,114,66,124,0,83,0,100,0,83,0, + 100,0,83,0,169,1,78,41,6,218,8,101,110,100,115,119, + 105,116,104,218,5,116,117,112,108,101,114,102,0,0,0,114, + 98,0,0,0,114,82,0,0,0,114,89,0,0,0,41,1, + 114,97,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,11,95,103,101,116,95,99,97,99,104,101, + 100,163,1,0,0,115,16,0,0,0,0,1,14,1,2,1, + 10,1,14,1,8,1,14,1,4,2,114,113,0,0,0,99, + 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 8,0,0,0,67,0,0,0,115,52,0,0,0,122,14,116, + 0,124,0,131,1,106,1,125,1,87,0,110,24,4,0,116, + 2,107,10,114,38,1,0,1,0,1,0,100,1,125,1,89, + 0,110,2,88,0,124,1,100,2,79,0,125,1,124,1,83, + 0,41,3,122,51,67,97,108,99,117,108,97,116,101,32,116, + 104,101,32,109,111,100,101,32,112,101,114,109,105,115,115,105, + 111,110,115,32,102,111,114,32,97,32,98,121,116,101,99,111, + 100,101,32,102,105,108,101,46,114,60,0,0,0,233,128,0, + 0,0,41,3,114,49,0,0,0,114,51,0,0,0,114,50, + 0,0,0,41,2,114,44,0,0,0,114,52,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,10, + 95,99,97,108,99,95,109,111,100,101,175,1,0,0,115,12, + 0,0,0,0,2,2,1,14,1,14,1,10,3,8,1,114, + 115,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,8,0,0,0,3,0,0,0,115,68,0, + 0,0,100,6,135,0,102,1,100,2,100,3,132,9,125,1, + 122,10,116,0,106,1,125,2,87,0,110,28,4,0,116,2, + 107,10,114,52,1,0,1,0,1,0,100,4,100,5,132,0, + 125,2,89,0,110,2,88,0,124,2,124,1,136,0,131,2, + 1,0,124,1,83,0,41,7,122,252,68,101,99,111,114,97, + 116,111,114,32,116,111,32,118,101,114,105,102,121,32,116,104, + 97,116,32,116,104,101,32,109,111,100,117,108,101,32,98,101, + 105,110,103,32,114,101,113,117,101,115,116,101,100,32,109,97, + 116,99,104,101,115,32,116,104,101,32,111,110,101,32,116,104, + 101,10,32,32,32,32,108,111,97,100,101,114,32,99,97,110, + 32,104,97,110,100,108,101,46,10,10,32,32,32,32,84,104, + 101,32,102,105,114,115,116,32,97,114,103,117,109,101,110,116, + 32,40,115,101,108,102,41,32,109,117,115,116,32,100,101,102, + 105,110,101,32,95,110,97,109,101,32,119,104,105,99,104,32, + 116,104,101,32,115,101,99,111,110,100,32,97,114,103,117,109, + 101,110,116,32,105,115,10,32,32,32,32,99,111,109,112,97, + 114,101,100,32,97,103,97,105,110,115,116,46,32,73,102,32, + 116,104,101,32,99,111,109,112,97,114,105,115,111,110,32,102, + 97,105,108,115,32,116,104,101,110,32,73,109,112,111,114,116, + 69,114,114,111,114,32,105,115,32,114,97,105,115,101,100,46, + 10,10,32,32,32,32,78,99,2,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,4,0,0,0,31,0,0,0, + 115,66,0,0,0,124,1,100,0,107,8,114,16,124,0,106, + 0,125,1,110,32,124,0,106,0,124,1,107,3,114,48,116, + 1,100,1,124,0,106,0,124,1,102,2,22,0,124,1,100, + 2,141,2,130,1,136,0,124,0,124,1,102,2,124,2,158, + 2,124,3,142,1,83,0,41,3,78,122,30,108,111,97,100, + 101,114,32,102,111,114,32,37,115,32,99,97,110,110,111,116, + 32,104,97,110,100,108,101,32,37,115,169,1,218,4,110,97, + 109,101,41,2,114,117,0,0,0,218,11,73,109,112,111,114, + 116,69,114,114,111,114,41,4,218,4,115,101,108,102,114,117, + 0,0,0,218,4,97,114,103,115,90,6,107,119,97,114,103, + 115,169,1,218,6,109,101,116,104,111,100,114,3,0,0,0, + 114,6,0,0,0,218,19,95,99,104,101,99,107,95,110,97, + 109,101,95,119,114,97,112,112,101,114,195,1,0,0,115,18, + 0,0,0,0,1,8,1,8,1,10,1,4,1,8,255,2, + 1,2,255,6,2,122,40,95,99,104,101,99,107,95,110,97, + 109,101,46,60,108,111,99,97,108,115,62,46,95,99,104,101, + 99,107,95,110,97,109,101,95,119,114,97,112,112,101,114,99, + 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 7,0,0,0,83,0,0,0,115,56,0,0,0,100,1,68, + 0,93,32,125,2,116,0,124,1,124,2,131,2,114,4,116, + 1,124,0,124,2,116,2,124,1,124,2,131,2,131,3,1, + 0,113,4,124,0,106,3,160,4,124,1,106,3,161,1,1, + 0,100,0,83,0,41,2,78,41,4,218,10,95,95,109,111, + 100,117,108,101,95,95,218,8,95,95,110,97,109,101,95,95, + 218,12,95,95,113,117,97,108,110,97,109,101,95,95,218,7, + 95,95,100,111,99,95,95,41,5,218,7,104,97,115,97,116, + 116,114,218,7,115,101,116,97,116,116,114,218,7,103,101,116, + 97,116,116,114,218,8,95,95,100,105,99,116,95,95,218,6, + 117,112,100,97,116,101,41,3,90,3,110,101,119,90,3,111, + 108,100,114,67,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,5,95,119,114,97,112,206,1,0, + 0,115,8,0,0,0,0,1,8,1,10,1,20,1,122,26, + 95,99,104,101,99,107,95,110,97,109,101,46,60,108,111,99, + 97,108,115,62,46,95,119,114,97,112,41,1,78,41,3,218, + 10,95,98,111,111,116,115,116,114,97,112,114,133,0,0,0, + 218,9,78,97,109,101,69,114,114,111,114,41,3,114,122,0, + 0,0,114,123,0,0,0,114,133,0,0,0,114,3,0,0, + 0,114,121,0,0,0,114,6,0,0,0,218,11,95,99,104, + 101,99,107,95,110,97,109,101,187,1,0,0,115,14,0,0, + 0,0,8,14,7,2,1,10,1,14,2,14,5,10,1,114, + 136,0,0,0,99,2,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,6,0,0,0,67,0,0,0,115,60,0, + 0,0,124,0,160,0,124,1,161,1,92,2,125,2,125,3, + 124,2,100,1,107,8,114,56,116,1,124,3,131,1,114,56, + 100,2,125,4,116,2,160,3,124,4,160,4,124,3,100,3, + 25,0,161,1,116,5,161,2,1,0,124,2,83,0,41,4, + 122,155,84,114,121,32,116,111,32,102,105,110,100,32,97,32, + 108,111,97,100,101,114,32,102,111,114,32,116,104,101,32,115, + 112,101,99,105,102,105,101,100,32,109,111,100,117,108,101,32, + 98,121,32,100,101,108,101,103,97,116,105,110,103,32,116,111, + 10,32,32,32,32,115,101,108,102,46,102,105,110,100,95,108, + 111,97,100,101,114,40,41,46,10,10,32,32,32,32,84,104, + 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,32,105,110,32,102,97,118,111,114, + 32,111,102,32,102,105,110,100,101,114,46,102,105,110,100,95, + 115,112,101,99,40,41,46,10,10,32,32,32,32,78,122,44, + 78,111,116,32,105,109,112,111,114,116,105,110,103,32,100,105, + 114,101,99,116,111,114,121,32,123,125,58,32,109,105,115,115, + 105,110,103,32,95,95,105,110,105,116,95,95,114,73,0,0, + 0,41,6,218,11,102,105,110,100,95,108,111,97,100,101,114, + 114,22,0,0,0,114,75,0,0,0,114,76,0,0,0,114, + 62,0,0,0,218,13,73,109,112,111,114,116,87,97,114,110, + 105,110,103,41,5,114,119,0,0,0,218,8,102,117,108,108, + 110,97,109,101,218,6,108,111,97,100,101,114,218,8,112,111, + 114,116,105,111,110,115,218,3,109,115,103,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,17,95,102,105,110, + 100,95,109,111,100,117,108,101,95,115,104,105,109,215,1,0, + 0,115,10,0,0,0,0,10,14,1,16,1,4,1,22,1, + 114,143,0,0,0,99,3,0,0,0,0,0,0,0,0,0, + 0,0,6,0,0,0,4,0,0,0,67,0,0,0,115,158, + 0,0,0,124,0,100,1,100,2,133,2,25,0,125,3,124, + 3,116,0,107,3,114,60,100,3,124,1,155,2,100,4,124, + 3,155,2,157,4,125,4,116,1,160,2,100,5,124,4,161, + 2,1,0,116,3,124,4,102,1,124,2,142,1,130,1,116, + 4,124,0,131,1,100,6,107,0,114,102,100,7,124,1,155, + 2,157,2,125,4,116,1,160,2,100,5,124,4,161,2,1, + 0,116,5,124,4,131,1,130,1,116,6,124,0,100,2,100, + 8,133,2,25,0,131,1,125,5,124,5,100,9,64,0,114, + 154,100,10,124,5,155,2,100,11,124,1,155,2,157,4,125, + 4,116,3,124,4,102,1,124,2,142,1,130,1,124,5,83, + 0,41,12,97,84,2,0,0,80,101,114,102,111,114,109,32, + 98,97,115,105,99,32,118,97,108,105,100,105,116,121,32,99, + 104,101,99,107,105,110,103,32,111,102,32,97,32,112,121,99, + 32,104,101,97,100,101,114,32,97,110,100,32,114,101,116,117, + 114,110,32,116,104,101,32,102,108,97,103,115,32,102,105,101, + 108,100,44,10,32,32,32,32,119,104,105,99,104,32,100,101, + 116,101,114,109,105,110,101,115,32,104,111,119,32,116,104,101, + 32,112,121,99,32,115,104,111,117,108,100,32,98,101,32,102, + 117,114,116,104,101,114,32,118,97,108,105,100,97,116,101,100, + 32,97,103,97,105,110,115,116,32,116,104,101,32,115,111,117, + 114,99,101,46,10,10,32,32,32,32,42,100,97,116,97,42, + 32,105,115,32,116,104,101,32,99,111,110,116,101,110,116,115, + 32,111,102,32,116,104,101,32,112,121,99,32,102,105,108,101, + 46,32,40,79,110,108,121,32,116,104,101,32,102,105,114,115, + 116,32,49,54,32,98,121,116,101,115,32,97,114,101,10,32, + 32,32,32,114,101,113,117,105,114,101,100,44,32,116,104,111, + 117,103,104,46,41,10,10,32,32,32,32,42,110,97,109,101, + 42,32,105,115,32,116,104,101,32,110,97,109,101,32,111,102, + 32,116,104,101,32,109,111,100,117,108,101,32,98,101,105,110, + 103,32,105,109,112,111,114,116,101,100,46,32,73,116,32,105, + 115,32,117,115,101,100,32,102,111,114,32,108,111,103,103,105, + 110,103,46,10,10,32,32,32,32,42,101,120,99,95,100,101, + 116,97,105,108,115,42,32,105,115,32,97,32,100,105,99,116, + 105,111,110,97,114,121,32,112,97,115,115,101,100,32,116,111, + 32,73,109,112,111,114,116,69,114,114,111,114,32,105,102,32, + 105,116,32,114,97,105,115,101,100,32,102,111,114,10,32,32, + 32,32,105,109,112,114,111,118,101,100,32,100,101,98,117,103, + 103,105,110,103,46,10,10,32,32,32,32,73,109,112,111,114, + 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, + 32,119,104,101,110,32,116,104,101,32,109,97,103,105,99,32, + 110,117,109,98,101,114,32,105,115,32,105,110,99,111,114,114, + 101,99,116,32,111,114,32,119,104,101,110,32,116,104,101,32, + 102,108,97,103,115,10,32,32,32,32,102,105,101,108,100,32, + 105,115,32,105,110,118,97,108,105,100,46,32,69,79,70,69, + 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,119, + 104,101,110,32,116,104,101,32,100,97,116,97,32,105,115,32, + 102,111,117,110,100,32,116,111,32,98,101,32,116,114,117,110, + 99,97,116,101,100,46,10,10,32,32,32,32,78,114,15,0, + 0,0,122,20,98,97,100,32,109,97,103,105,99,32,110,117, + 109,98,101,114,32,105,110,32,122,2,58,32,250,2,123,125, + 233,16,0,0,0,122,40,114,101,97,99,104,101,100,32,69, + 79,70,32,119,104,105,108,101,32,114,101,97,100,105,110,103, + 32,112,121,99,32,104,101,97,100,101,114,32,111,102,32,233, + 8,0,0,0,233,252,255,255,255,122,14,105,110,118,97,108, + 105,100,32,102,108,97,103,115,32,122,4,32,105,110,32,41, + 7,218,12,77,65,71,73,67,95,78,85,77,66,69,82,114, + 134,0,0,0,218,16,95,118,101,114,98,111,115,101,95,109, + 101,115,115,97,103,101,114,118,0,0,0,114,22,0,0,0, + 218,8,69,79,70,69,114,114,111,114,114,27,0,0,0,41, + 6,114,26,0,0,0,114,117,0,0,0,218,11,101,120,99, + 95,100,101,116,97,105,108,115,90,5,109,97,103,105,99,114, + 93,0,0,0,114,83,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,95,99,108,97,115,115, + 105,102,121,95,112,121,99,232,1,0,0,115,28,0,0,0, + 0,16,12,1,8,1,16,1,12,1,12,1,12,1,10,1, + 12,1,8,1,16,2,8,1,16,1,12,1,114,152,0,0, + 0,99,5,0,0,0,0,0,0,0,0,0,0,0,6,0, + 0,0,4,0,0,0,67,0,0,0,115,112,0,0,0,116, + 0,124,0,100,1,100,2,133,2,25,0,131,1,124,1,100, + 3,64,0,107,3,114,58,100,4,124,3,155,2,157,2,125, + 5,116,1,160,2,100,5,124,5,161,2,1,0,116,3,124, + 5,102,1,124,4,142,1,130,1,124,2,100,6,107,9,114, + 108,116,0,124,0,100,2,100,7,133,2,25,0,131,1,124, + 2,100,3,64,0,107,3,114,108,116,3,100,4,124,3,155, + 2,157,2,102,1,124,4,142,1,130,1,100,6,83,0,41, + 8,97,7,2,0,0,86,97,108,105,100,97,116,101,32,97, + 32,112,121,99,32,97,103,97,105,110,115,116,32,116,104,101, + 32,115,111,117,114,99,101,32,108,97,115,116,45,109,111,100, + 105,102,105,101,100,32,116,105,109,101,46,10,10,32,32,32, + 32,42,100,97,116,97,42,32,105,115,32,116,104,101,32,99, + 111,110,116,101,110,116,115,32,111,102,32,116,104,101,32,112, + 121,99,32,102,105,108,101,46,32,40,79,110,108,121,32,116, + 104,101,32,102,105,114,115,116,32,49,54,32,98,121,116,101, + 115,32,97,114,101,10,32,32,32,32,114,101,113,117,105,114, + 101,100,46,41,10,10,32,32,32,32,42,115,111,117,114,99, + 101,95,109,116,105,109,101,42,32,105,115,32,116,104,101,32, + 108,97,115,116,32,109,111,100,105,102,105,101,100,32,116,105, + 109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,115, + 111,117,114,99,101,32,102,105,108,101,46,10,10,32,32,32, + 32,42,115,111,117,114,99,101,95,115,105,122,101,42,32,105, + 115,32,78,111,110,101,32,111,114,32,116,104,101,32,115,105, + 122,101,32,111,102,32,116,104,101,32,115,111,117,114,99,101, + 32,102,105,108,101,32,105,110,32,98,121,116,101,115,46,10, + 10,32,32,32,32,42,110,97,109,101,42,32,105,115,32,116, + 104,101,32,110,97,109,101,32,111,102,32,116,104,101,32,109, + 111,100,117,108,101,32,98,101,105,110,103,32,105,109,112,111, + 114,116,101,100,46,32,73,116,32,105,115,32,117,115,101,100, + 32,102,111,114,32,108,111,103,103,105,110,103,46,10,10,32, + 32,32,32,42,101,120,99,95,100,101,116,97,105,108,115,42, + 32,105,115,32,97,32,100,105,99,116,105,111,110,97,114,121, + 32,112,97,115,115,101,100,32,116,111,32,73,109,112,111,114, + 116,69,114,114,111,114,32,105,102,32,105,116,32,114,97,105, + 115,101,100,32,102,111,114,10,32,32,32,32,105,109,112,114, + 111,118,101,100,32,100,101,98,117,103,103,105,110,103,46,10, + 10,32,32,32,32,65,110,32,73,109,112,111,114,116,69,114, + 114,111,114,32,105,115,32,114,97,105,115,101,100,32,105,102, + 32,116,104,101,32,98,121,116,101,99,111,100,101,32,105,115, + 32,115,116,97,108,101,46,10,10,32,32,32,32,114,146,0, + 0,0,233,12,0,0,0,114,14,0,0,0,122,22,98,121, + 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, + 102,111,114,32,114,144,0,0,0,78,114,145,0,0,0,41, + 4,114,27,0,0,0,114,134,0,0,0,114,149,0,0,0, + 114,118,0,0,0,41,6,114,26,0,0,0,218,12,115,111, + 117,114,99,101,95,109,116,105,109,101,218,11,115,111,117,114, + 99,101,95,115,105,122,101,114,117,0,0,0,114,151,0,0, + 0,114,93,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,23,95,118,97,108,105,100,97,116,101, + 95,116,105,109,101,115,116,97,109,112,95,112,121,99,9,2, + 0,0,115,16,0,0,0,0,19,24,1,10,1,12,1,12, + 1,8,1,22,255,2,2,114,156,0,0,0,99,4,0,0, + 0,0,0,0,0,0,0,0,0,4,0,0,0,3,0,0, + 0,67,0,0,0,115,38,0,0,0,124,0,100,1,100,2, + 133,2,25,0,124,1,107,3,114,34,116,0,100,3,124,2, + 155,2,157,2,102,1,124,3,142,1,130,1,100,4,83,0, + 41,5,97,243,1,0,0,86,97,108,105,100,97,116,101,32, + 97,32,104,97,115,104,45,98,97,115,101,100,32,112,121,99, + 32,98,121,32,99,104,101,99,107,105,110,103,32,116,104,101, + 32,114,101,97,108,32,115,111,117,114,99,101,32,104,97,115, + 104,32,97,103,97,105,110,115,116,32,116,104,101,32,111,110, + 101,32,105,110,10,32,32,32,32,116,104,101,32,112,121,99, + 32,104,101,97,100,101,114,46,10,10,32,32,32,32,42,100, 97,116,97,42,32,105,115,32,116,104,101,32,99,111,110,116, 101,110,116,115,32,111,102,32,116,104,101,32,112,121,99,32, 102,105,108,101,46,32,40,79,110,108,121,32,116,104,101,32, 102,105,114,115,116,32,49,54,32,98,121,116,101,115,32,97, - 114,101,10,32,32,32,32,114,101,113,117,105,114,101,100,44, - 32,116,104,111,117,103,104,46,41,10,10,32,32,32,32,42, - 110,97,109,101,42,32,105,115,32,116,104,101,32,110,97,109, - 101,32,111,102,32,116,104,101,32,109,111,100,117,108,101,32, - 98,101,105,110,103,32,105,109,112,111,114,116,101,100,46,32, - 73,116,32,105,115,32,117,115,101,100,32,102,111,114,32,108, - 111,103,103,105,110,103,46,10,10,32,32,32,32,42,101,120, - 99,95,100,101,116,97,105,108,115,42,32,105,115,32,97,32, - 100,105,99,116,105,111,110,97,114,121,32,112,97,115,115,101, - 100,32,116,111,32,73,109,112,111,114,116,69,114,114,111,114, - 32,105,102,32,105,116,32,114,97,105,115,101,100,32,102,111, - 114,10,32,32,32,32,105,109,112,114,111,118,101,100,32,100, - 101,98,117,103,103,105,110,103,46,10,10,32,32,32,32,73, - 109,112,111,114,116,69,114,114,111,114,32,105,115,32,114,97, - 105,115,101,100,32,119,104,101,110,32,116,104,101,32,109,97, - 103,105,99,32,110,117,109,98,101,114,32,105,115,32,105,110, - 99,111,114,114,101,99,116,32,111,114,32,119,104,101,110,32, - 116,104,101,32,102,108,97,103,115,10,32,32,32,32,102,105, - 101,108,100,32,105,115,32,105,110,118,97,108,105,100,46,32, - 69,79,70,69,114,114,111,114,32,105,115,32,114,97,105,115, - 101,100,32,119,104,101,110,32,116,104,101,32,100,97,116,97, - 32,105,115,32,102,111,117,110,100,32,116,111,32,98,101,32, - 116,114,117,110,99,97,116,101,100,46,10,10,32,32,32,32, - 78,114,15,0,0,0,122,20,98,97,100,32,109,97,103,105, - 99,32,110,117,109,98,101,114,32,105,110,32,122,2,58,32, - 250,2,123,125,233,16,0,0,0,122,40,114,101,97,99,104, - 101,100,32,69,79,70,32,119,104,105,108,101,32,114,101,97, - 100,105,110,103,32,112,121,99,32,104,101,97,100,101,114,32, - 111,102,32,233,8,0,0,0,233,252,255,255,255,122,14,105, - 110,118,97,108,105,100,32,102,108,97,103,115,32,122,4,32, - 105,110,32,41,7,218,12,77,65,71,73,67,95,78,85,77, - 66,69,82,114,134,0,0,0,218,16,95,118,101,114,98,111, - 115,101,95,109,101,115,115,97,103,101,114,118,0,0,0,114, - 22,0,0,0,218,8,69,79,70,69,114,114,111,114,114,27, - 0,0,0,41,6,114,26,0,0,0,114,117,0,0,0,218, - 11,101,120,99,95,100,101,116,97,105,108,115,90,5,109,97, - 103,105,99,114,93,0,0,0,114,83,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,13,95,99, - 108,97,115,115,105,102,121,95,112,121,99,232,1,0,0,115, - 28,0,0,0,0,16,12,1,8,1,16,1,12,1,12,1, - 12,1,10,1,12,1,8,1,16,2,8,1,16,1,12,1, - 114,152,0,0,0,99,5,0,0,0,0,0,0,0,0,0, - 0,0,6,0,0,0,4,0,0,0,67,0,0,0,115,112, - 0,0,0,116,0,124,0,100,1,100,2,133,2,25,0,131, - 1,124,1,100,3,64,0,107,3,114,58,100,4,124,3,155, - 2,157,2,125,5,116,1,160,2,100,5,124,5,161,2,1, - 0,116,3,124,5,102,1,124,4,142,1,130,1,124,2,100, - 6,107,9,114,108,116,0,124,0,100,2,100,7,133,2,25, - 0,131,1,124,2,100,3,64,0,107,3,114,108,116,3,100, - 4,124,3,155,2,157,2,102,1,124,4,142,1,130,1,100, - 6,83,0,41,8,97,7,2,0,0,86,97,108,105,100,97, - 116,101,32,97,32,112,121,99,32,97,103,97,105,110,115,116, - 32,116,104,101,32,115,111,117,114,99,101,32,108,97,115,116, - 45,109,111,100,105,102,105,101,100,32,116,105,109,101,46,10, - 10,32,32,32,32,42,100,97,116,97,42,32,105,115,32,116, - 104,101,32,99,111,110,116,101,110,116,115,32,111,102,32,116, - 104,101,32,112,121,99,32,102,105,108,101,46,32,40,79,110, - 108,121,32,116,104,101,32,102,105,114,115,116,32,49,54,32, - 98,121,116,101,115,32,97,114,101,10,32,32,32,32,114,101, - 113,117,105,114,101,100,46,41,10,10,32,32,32,32,42,115, - 111,117,114,99,101,95,109,116,105,109,101,42,32,105,115,32, - 116,104,101,32,108,97,115,116,32,109,111,100,105,102,105,101, - 100,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116, - 104,101,32,115,111,117,114,99,101,32,102,105,108,101,46,10, - 10,32,32,32,32,42,115,111,117,114,99,101,95,115,105,122, - 101,42,32,105,115,32,78,111,110,101,32,111,114,32,116,104, - 101,32,115,105,122,101,32,111,102,32,116,104,101,32,115,111, - 117,114,99,101,32,102,105,108,101,32,105,110,32,98,121,116, - 101,115,46,10,10,32,32,32,32,42,110,97,109,101,42,32, - 105,115,32,116,104,101,32,110,97,109,101,32,111,102,32,116, - 104,101,32,109,111,100,117,108,101,32,98,101,105,110,103,32, - 105,109,112,111,114,116,101,100,46,32,73,116,32,105,115,32, - 117,115,101,100,32,102,111,114,32,108,111,103,103,105,110,103, - 46,10,10,32,32,32,32,42,101,120,99,95,100,101,116,97, - 105,108,115,42,32,105,115,32,97,32,100,105,99,116,105,111, - 110,97,114,121,32,112,97,115,115,101,100,32,116,111,32,73, - 109,112,111,114,116,69,114,114,111,114,32,105,102,32,105,116, - 32,114,97,105,115,101,100,32,102,111,114,10,32,32,32,32, - 105,109,112,114,111,118,101,100,32,100,101,98,117,103,103,105, - 110,103,46,10,10,32,32,32,32,65,110,32,73,109,112,111, - 114,116,69,114,114,111,114,32,105,115,32,114,97,105,115,101, - 100,32,105,102,32,116,104,101,32,98,121,116,101,99,111,100, - 101,32,105,115,32,115,116,97,108,101,46,10,10,32,32,32, - 32,114,146,0,0,0,233,12,0,0,0,114,14,0,0,0, - 122,22,98,121,116,101,99,111,100,101,32,105,115,32,115,116, - 97,108,101,32,102,111,114,32,114,144,0,0,0,78,114,145, - 0,0,0,41,4,114,27,0,0,0,114,134,0,0,0,114, - 149,0,0,0,114,118,0,0,0,41,6,114,26,0,0,0, - 218,12,115,111,117,114,99,101,95,109,116,105,109,101,218,11, - 115,111,117,114,99,101,95,115,105,122,101,114,117,0,0,0, - 114,151,0,0,0,114,93,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,23,95,118,97,108,105, - 100,97,116,101,95,116,105,109,101,115,116,97,109,112,95,112, - 121,99,9,2,0,0,115,16,0,0,0,0,19,24,1,10, - 1,12,1,12,1,8,1,22,255,2,2,114,156,0,0,0, - 99,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,3,0,0,0,67,0,0,0,115,38,0,0,0,124,0, - 100,1,100,2,133,2,25,0,124,1,107,3,114,34,116,0, - 100,3,124,2,155,2,157,2,102,1,124,3,142,1,130,1, - 100,4,83,0,41,5,97,243,1,0,0,86,97,108,105,100, - 97,116,101,32,97,32,104,97,115,104,45,98,97,115,101,100, - 32,112,121,99,32,98,121,32,99,104,101,99,107,105,110,103, - 32,116,104,101,32,114,101,97,108,32,115,111,117,114,99,101, - 32,104,97,115,104,32,97,103,97,105,110,115,116,32,116,104, - 101,32,111,110,101,32,105,110,10,32,32,32,32,116,104,101, - 32,112,121,99,32,104,101,97,100,101,114,46,10,10,32,32, - 32,32,42,100,97,116,97,42,32,105,115,32,116,104,101,32, - 99,111,110,116,101,110,116,115,32,111,102,32,116,104,101,32, - 112,121,99,32,102,105,108,101,46,32,40,79,110,108,121,32, - 116,104,101,32,102,105,114,115,116,32,49,54,32,98,121,116, - 101,115,32,97,114,101,10,32,32,32,32,114,101,113,117,105, - 114,101,100,46,41,10,10,32,32,32,32,42,115,111,117,114, - 99,101,95,104,97,115,104,42,32,105,115,32,116,104,101,32, - 105,109,112,111,114,116,108,105,98,46,117,116,105,108,46,115, - 111,117,114,99,101,95,104,97,115,104,40,41,32,111,102,32, - 116,104,101,32,115,111,117,114,99,101,32,102,105,108,101,46, - 10,10,32,32,32,32,42,110,97,109,101,42,32,105,115,32, - 116,104,101,32,110,97,109,101,32,111,102,32,116,104,101,32, - 109,111,100,117,108,101,32,98,101,105,110,103,32,105,109,112, - 111,114,116,101,100,46,32,73,116,32,105,115,32,117,115,101, - 100,32,102,111,114,32,108,111,103,103,105,110,103,46,10,10, - 32,32,32,32,42,101,120,99,95,100,101,116,97,105,108,115, - 42,32,105,115,32,97,32,100,105,99,116,105,111,110,97,114, - 121,32,112,97,115,115,101,100,32,116,111,32,73,109,112,111, - 114,116,69,114,114,111,114,32,105,102,32,105,116,32,114,97, - 105,115,101,100,32,102,111,114,10,32,32,32,32,105,109,112, - 114,111,118,101,100,32,100,101,98,117,103,103,105,110,103,46, - 10,10,32,32,32,32,65,110,32,73,109,112,111,114,116,69, - 114,114,111,114,32,105,115,32,114,97,105,115,101,100,32,105, - 102,32,116,104,101,32,98,121,116,101,99,111,100,101,32,105, - 115,32,115,116,97,108,101,46,10,10,32,32,32,32,114,146, - 0,0,0,114,145,0,0,0,122,46,104,97,115,104,32,105, - 110,32,98,121,116,101,99,111,100,101,32,100,111,101,115,110, - 39,116,32,109,97,116,99,104,32,104,97,115,104,32,111,102, - 32,115,111,117,114,99,101,32,78,41,1,114,118,0,0,0, - 41,4,114,26,0,0,0,218,11,115,111,117,114,99,101,95, - 104,97,115,104,114,117,0,0,0,114,151,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,18,95, - 118,97,108,105,100,97,116,101,95,104,97,115,104,95,112,121, - 99,37,2,0,0,115,12,0,0,0,0,17,16,1,2,1, - 8,255,2,2,2,254,114,158,0,0,0,99,4,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, - 67,0,0,0,115,82,0,0,0,116,0,160,1,124,0,161, - 1,125,4,116,2,124,4,116,3,131,2,114,58,116,4,160, - 5,100,1,124,2,161,2,1,0,124,3,100,2,107,9,114, - 52,116,6,160,7,124,4,124,3,161,2,1,0,124,4,83, - 0,110,20,116,8,100,3,160,9,124,2,161,1,124,1,124, - 2,100,4,141,3,130,1,100,2,83,0,41,5,122,35,67, - 111,109,112,105,108,101,32,98,121,116,101,99,111,100,101,32, - 97,115,32,102,111,117,110,100,32,105,110,32,97,32,112,121, - 99,46,122,21,99,111,100,101,32,111,98,106,101,99,116,32, - 102,114,111,109,32,123,33,114,125,78,122,23,78,111,110,45, - 99,111,100,101,32,111,98,106,101,99,116,32,105,110,32,123, - 33,114,125,169,2,114,117,0,0,0,114,44,0,0,0,41, - 10,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, - 115,218,10,105,115,105,110,115,116,97,110,99,101,218,10,95, - 99,111,100,101,95,116,121,112,101,114,134,0,0,0,114,149, - 0,0,0,218,4,95,105,109,112,90,16,95,102,105,120,95, - 99,111,95,102,105,108,101,110,97,109,101,114,118,0,0,0, - 114,62,0,0,0,41,5,114,26,0,0,0,114,117,0,0, - 0,114,107,0,0,0,114,108,0,0,0,218,4,99,111,100, - 101,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,17,95,99,111,109,112,105,108,101,95,98,121,116,101,99, - 111,100,101,61,2,0,0,115,20,0,0,0,0,2,10,1, - 10,1,12,1,8,1,12,1,6,2,10,1,2,0,2,255, - 114,165,0,0,0,114,73,0,0,0,99,3,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,67, - 0,0,0,115,70,0,0,0,116,0,116,1,131,1,125,3, - 124,3,160,2,116,3,100,1,131,1,161,1,1,0,124,3, - 160,2,116,3,124,1,131,1,161,1,1,0,124,3,160,2, - 116,3,124,2,131,1,161,1,1,0,124,3,160,2,116,4, - 160,5,124,0,161,1,161,1,1,0,124,3,83,0,41,2, - 122,43,80,114,111,100,117,99,101,32,116,104,101,32,100,97, - 116,97,32,102,111,114,32,97,32,116,105,109,101,115,116,97, - 109,112,45,98,97,115,101,100,32,112,121,99,46,114,73,0, - 0,0,41,6,218,9,98,121,116,101,97,114,114,97,121,114, - 148,0,0,0,218,6,101,120,116,101,110,100,114,20,0,0, - 0,114,160,0,0,0,218,5,100,117,109,112,115,41,4,114, - 164,0,0,0,218,5,109,116,105,109,101,114,155,0,0,0, - 114,26,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,22,95,99,111,100,101,95,116,111,95,116, - 105,109,101,115,116,97,109,112,95,112,121,99,74,2,0,0, - 115,12,0,0,0,0,2,8,1,14,1,14,1,14,1,16, - 1,114,170,0,0,0,84,99,3,0,0,0,0,0,0,0, + 114,101,10,32,32,32,32,114,101,113,117,105,114,101,100,46, + 41,10,10,32,32,32,32,42,115,111,117,114,99,101,95,104, + 97,115,104,42,32,105,115,32,116,104,101,32,105,109,112,111, + 114,116,108,105,98,46,117,116,105,108,46,115,111,117,114,99, + 101,95,104,97,115,104,40,41,32,111,102,32,116,104,101,32, + 115,111,117,114,99,101,32,102,105,108,101,46,10,10,32,32, + 32,32,42,110,97,109,101,42,32,105,115,32,116,104,101,32, + 110,97,109,101,32,111,102,32,116,104,101,32,109,111,100,117, + 108,101,32,98,101,105,110,103,32,105,109,112,111,114,116,101, + 100,46,32,73,116,32,105,115,32,117,115,101,100,32,102,111, + 114,32,108,111,103,103,105,110,103,46,10,10,32,32,32,32, + 42,101,120,99,95,100,101,116,97,105,108,115,42,32,105,115, + 32,97,32,100,105,99,116,105,111,110,97,114,121,32,112,97, + 115,115,101,100,32,116,111,32,73,109,112,111,114,116,69,114, + 114,111,114,32,105,102,32,105,116,32,114,97,105,115,101,100, + 32,102,111,114,10,32,32,32,32,105,109,112,114,111,118,101, + 100,32,100,101,98,117,103,103,105,110,103,46,10,10,32,32, + 32,32,65,110,32,73,109,112,111,114,116,69,114,114,111,114, + 32,105,115,32,114,97,105,115,101,100,32,105,102,32,116,104, + 101,32,98,121,116,101,99,111,100,101,32,105,115,32,115,116, + 97,108,101,46,10,10,32,32,32,32,114,146,0,0,0,114, + 145,0,0,0,122,46,104,97,115,104,32,105,110,32,98,121, + 116,101,99,111,100,101,32,100,111,101,115,110,39,116,32,109, + 97,116,99,104,32,104,97,115,104,32,111,102,32,115,111,117, + 114,99,101,32,78,41,1,114,118,0,0,0,41,4,114,26, + 0,0,0,218,11,115,111,117,114,99,101,95,104,97,115,104, + 114,117,0,0,0,114,151,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,18,95,118,97,108,105, + 100,97,116,101,95,104,97,115,104,95,112,121,99,37,2,0, + 0,115,12,0,0,0,0,17,16,1,2,1,8,255,2,2, + 2,254,114,158,0,0,0,99,4,0,0,0,0,0,0,0, 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,80,0,0,0,116,0,116,1,131,1,125,3,100,1,124, - 2,100,1,62,0,66,0,125,4,124,3,160,2,116,3,124, - 4,131,1,161,1,1,0,116,4,124,1,131,1,100,2,107, - 2,115,50,116,5,130,1,124,3,160,2,124,1,161,1,1, - 0,124,3,160,2,116,6,160,7,124,0,161,1,161,1,1, - 0,124,3,83,0,41,3,122,38,80,114,111,100,117,99,101, - 32,116,104,101,32,100,97,116,97,32,102,111,114,32,97,32, - 104,97,115,104,45,98,97,115,101,100,32,112,121,99,46,114, - 39,0,0,0,114,146,0,0,0,41,8,114,166,0,0,0, - 114,148,0,0,0,114,167,0,0,0,114,20,0,0,0,114, - 22,0,0,0,114,23,0,0,0,114,160,0,0,0,114,168, - 0,0,0,41,5,114,164,0,0,0,114,157,0,0,0,90, - 7,99,104,101,99,107,101,100,114,26,0,0,0,114,83,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,17,95,99,111,100,101,95,116,111,95,104,97,115,104, - 95,112,121,99,84,2,0,0,115,14,0,0,0,0,2,8, - 1,12,1,14,1,16,1,10,1,16,1,114,171,0,0,0, - 99,1,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,6,0,0,0,67,0,0,0,115,62,0,0,0,100,1, - 100,2,108,0,125,1,116,1,160,2,124,0,161,1,106,3, - 125,2,124,1,160,4,124,2,161,1,125,3,116,1,160,5, - 100,2,100,3,161,2,125,4,124,4,160,6,124,0,160,6, - 124,3,100,1,25,0,161,1,161,1,83,0,41,4,122,121, - 68,101,99,111,100,101,32,98,121,116,101,115,32,114,101,112, - 114,101,115,101,110,116,105,110,103,32,115,111,117,114,99,101, - 32,99,111,100,101,32,97,110,100,32,114,101,116,117,114,110, - 32,116,104,101,32,115,116,114,105,110,103,46,10,10,32,32, - 32,32,85,110,105,118,101,114,115,97,108,32,110,101,119,108, - 105,110,101,32,115,117,112,112,111,114,116,32,105,115,32,117, - 115,101,100,32,105,110,32,116,104,101,32,100,101,99,111,100, - 105,110,103,46,10,32,32,32,32,114,73,0,0,0,78,84, - 41,7,218,8,116,111,107,101,110,105,122,101,114,64,0,0, - 0,90,7,66,121,116,101,115,73,79,90,8,114,101,97,100, - 108,105,110,101,90,15,100,101,116,101,99,116,95,101,110,99, - 111,100,105,110,103,90,25,73,110,99,114,101,109,101,110,116, - 97,108,78,101,119,108,105,110,101,68,101,99,111,100,101,114, - 218,6,100,101,99,111,100,101,41,5,218,12,115,111,117,114, - 99,101,95,98,121,116,101,115,114,172,0,0,0,90,21,115, - 111,117,114,99,101,95,98,121,116,101,115,95,114,101,97,100, - 108,105,110,101,218,8,101,110,99,111,100,105,110,103,90,15, - 110,101,119,108,105,110,101,95,100,101,99,111,100,101,114,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,13, - 100,101,99,111,100,101,95,115,111,117,114,99,101,95,2,0, - 0,115,10,0,0,0,0,5,8,1,12,1,10,1,12,1, - 114,176,0,0,0,169,2,114,140,0,0,0,218,26,115,117, - 98,109,111,100,117,108,101,95,115,101,97,114,99,104,95,108, - 111,99,97,116,105,111,110,115,99,2,0,0,0,0,0,0, - 0,2,0,0,0,9,0,0,0,8,0,0,0,67,0,0, - 0,115,16,1,0,0,124,1,100,1,107,8,114,60,100,2, - 125,1,116,0,124,2,100,3,131,2,114,70,122,14,124,2, - 160,1,124,0,161,1,125,1,87,0,113,70,4,0,116,2, - 107,10,114,56,1,0,1,0,1,0,89,0,113,70,88,0, - 110,10,116,3,160,4,124,1,161,1,125,1,116,5,106,6, - 124,0,124,2,124,1,100,4,141,3,125,4,100,5,124,4, - 95,7,124,2,100,1,107,8,114,154,116,8,131,0,68,0, - 93,42,92,2,125,5,125,6,124,1,160,9,116,10,124,6, - 131,1,161,1,114,106,124,5,124,0,124,1,131,2,125,2, - 124,2,124,4,95,11,1,0,113,154,113,106,100,1,83,0, - 124,3,116,12,107,8,114,220,116,0,124,2,100,6,131,2, - 114,226,122,14,124,2,160,13,124,0,161,1,125,7,87,0, - 110,20,4,0,116,2,107,10,114,206,1,0,1,0,1,0, - 89,0,113,226,88,0,124,7,114,226,103,0,124,4,95,14, - 110,6,124,3,124,4,95,14,124,4,106,14,103,0,107,2, - 144,1,114,12,124,1,144,1,114,12,116,15,124,1,131,1, - 100,7,25,0,125,8,124,4,106,14,160,16,124,8,161,1, - 1,0,124,4,83,0,41,8,97,61,1,0,0,82,101,116, - 117,114,110,32,97,32,109,111,100,117,108,101,32,115,112,101, - 99,32,98,97,115,101,100,32,111,110,32,97,32,102,105,108, - 101,32,108,111,99,97,116,105,111,110,46,10,10,32,32,32, - 32,84,111,32,105,110,100,105,99,97,116,101,32,116,104,97, - 116,32,116,104,101,32,109,111,100,117,108,101,32,105,115,32, - 97,32,112,97,99,107,97,103,101,44,32,115,101,116,10,32, - 32,32,32,115,117,98,109,111,100,117,108,101,95,115,101,97, - 114,99,104,95,108,111,99,97,116,105,111,110,115,32,116,111, - 32,97,32,108,105,115,116,32,111,102,32,100,105,114,101,99, - 116,111,114,121,32,112,97,116,104,115,46,32,32,65,110,10, - 32,32,32,32,101,109,112,116,121,32,108,105,115,116,32,105, - 115,32,115,117,102,102,105,99,105,101,110,116,44,32,116,104, - 111,117,103,104,32,105,116,115,32,110,111,116,32,111,116,104, - 101,114,119,105,115,101,32,117,115,101,102,117,108,32,116,111, - 32,116,104,101,10,32,32,32,32,105,109,112,111,114,116,32, - 115,121,115,116,101,109,46,10,10,32,32,32,32,84,104,101, - 32,108,111,97,100,101,114,32,109,117,115,116,32,116,97,107, - 101,32,97,32,115,112,101,99,32,97,115,32,105,116,115,32, - 111,110,108,121,32,95,95,105,110,105,116,95,95,40,41,32, - 97,114,103,46,10,10,32,32,32,32,78,122,9,60,117,110, - 107,110,111,119,110,62,218,12,103,101,116,95,102,105,108,101, - 110,97,109,101,169,1,218,6,111,114,105,103,105,110,84,218, - 10,105,115,95,112,97,99,107,97,103,101,114,73,0,0,0, - 41,17,114,128,0,0,0,114,179,0,0,0,114,118,0,0, - 0,114,2,0,0,0,114,79,0,0,0,114,134,0,0,0, - 218,10,77,111,100,117,108,101,83,112,101,99,90,13,95,115, - 101,116,95,102,105,108,101,97,116,116,114,218,27,95,103,101, - 116,95,115,117,112,112,111,114,116,101,100,95,102,105,108,101, - 95,108,111,97,100,101,114,115,114,111,0,0,0,114,112,0, - 0,0,114,140,0,0,0,218,9,95,80,79,80,85,76,65, - 84,69,114,182,0,0,0,114,178,0,0,0,114,47,0,0, - 0,218,6,97,112,112,101,110,100,41,9,114,117,0,0,0, - 90,8,108,111,99,97,116,105,111,110,114,140,0,0,0,114, - 178,0,0,0,218,4,115,112,101,99,218,12,108,111,97,100, - 101,114,95,99,108,97,115,115,218,8,115,117,102,102,105,120, - 101,115,114,182,0,0,0,90,7,100,105,114,110,97,109,101, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 23,115,112,101,99,95,102,114,111,109,95,102,105,108,101,95, - 108,111,99,97,116,105,111,110,112,2,0,0,115,62,0,0, - 0,0,12,8,4,4,1,10,2,2,1,14,1,14,1,8, - 2,10,8,16,1,6,3,8,1,14,1,14,1,10,1,6, - 1,6,2,4,3,8,2,10,1,2,1,14,1,14,1,6, - 2,4,1,8,2,6,1,12,1,6,1,12,1,12,2,114, - 190,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,4,0,0,0,64,0,0,0,115,86,0, - 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, - 90,4,100,3,90,5,100,4,90,6,101,7,100,5,100,6, - 132,0,131,1,90,8,101,7,100,7,100,8,132,0,131,1, - 90,9,101,7,100,9,100,9,102,2,100,10,100,11,132,1, - 131,1,90,10,101,7,100,9,102,1,100,12,100,13,132,1, - 131,1,90,11,100,9,83,0,41,14,218,21,87,105,110,100, - 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, - 114,122,62,77,101,116,97,32,112,97,116,104,32,102,105,110, - 100,101,114,32,102,111,114,32,109,111,100,117,108,101,115,32, - 100,101,99,108,97,114,101,100,32,105,110,32,116,104,101,32, - 87,105,110,100,111,119,115,32,114,101,103,105,115,116,114,121, - 46,122,59,83,111,102,116,119,97,114,101,92,80,121,116,104, - 111,110,92,80,121,116,104,111,110,67,111,114,101,92,123,115, - 121,115,95,118,101,114,115,105,111,110,125,92,77,111,100,117, - 108,101,115,92,123,102,117,108,108,110,97,109,101,125,122,65, - 83,111,102,116,119,97,114,101,92,80,121,116,104,111,110,92, - 80,121,116,104,111,110,67,111,114,101,92,123,115,121,115,95, - 118,101,114,115,105,111,110,125,92,77,111,100,117,108,101,115, - 92,123,102,117,108,108,110,97,109,101,125,92,68,101,98,117, - 103,70,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,8,0,0,0,67,0,0,0,115,56,0,0,0, - 122,16,116,0,160,1,116,0,106,2,124,1,161,2,87,0, - 83,0,4,0,116,3,107,10,114,50,1,0,1,0,1,0, - 116,0,160,1,116,0,106,4,124,1,161,2,6,0,89,0, - 83,0,88,0,100,0,83,0,114,110,0,0,0,41,5,218, - 7,95,119,105,110,114,101,103,90,7,79,112,101,110,75,101, - 121,90,17,72,75,69,89,95,67,85,82,82,69,78,84,95, - 85,83,69,82,114,50,0,0,0,90,18,72,75,69,89,95, - 76,79,67,65,76,95,77,65,67,72,73,78,69,41,2,218, - 3,99,108,115,114,5,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,14,95,111,112,101,110,95, - 114,101,103,105,115,116,114,121,192,2,0,0,115,8,0,0, - 0,0,2,2,1,16,1,14,1,122,36,87,105,110,100,111, - 119,115,82,101,103,105,115,116,114,121,70,105,110,100,101,114, - 46,95,111,112,101,110,95,114,101,103,105,115,116,114,121,99, - 2,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, - 9,0,0,0,67,0,0,0,115,118,0,0,0,124,0,106, - 0,114,14,124,0,106,1,125,2,110,6,124,0,106,2,125, - 2,124,2,106,3,124,1,100,1,116,4,106,5,100,0,100, - 2,133,2,25,0,22,0,100,3,141,2,125,3,122,38,124, - 0,160,6,124,3,161,1,143,18,125,4,116,7,160,8,124, - 4,100,4,161,2,125,5,87,0,53,0,81,0,82,0,88, - 0,87,0,110,26,4,0,116,9,107,10,114,112,1,0,1, - 0,1,0,89,0,100,0,83,0,89,0,110,2,88,0,124, + 115,80,0,0,0,116,0,160,1,124,0,161,1,125,4,116, + 2,124,4,116,3,131,2,114,56,116,4,160,5,100,1,124, + 2,161,2,1,0,124,3,100,2,107,9,114,52,116,6,160, + 7,124,4,124,3,161,2,1,0,124,4,83,0,116,8,100, + 3,160,9,124,2,161,1,124,1,124,2,100,4,141,3,130, + 1,100,2,83,0,41,5,122,35,67,111,109,112,105,108,101, + 32,98,121,116,101,99,111,100,101,32,97,115,32,102,111,117, + 110,100,32,105,110,32,97,32,112,121,99,46,122,21,99,111, + 100,101,32,111,98,106,101,99,116,32,102,114,111,109,32,123, + 33,114,125,78,122,23,78,111,110,45,99,111,100,101,32,111, + 98,106,101,99,116,32,105,110,32,123,33,114,125,169,2,114, + 117,0,0,0,114,44,0,0,0,41,10,218,7,109,97,114, + 115,104,97,108,90,5,108,111,97,100,115,218,10,105,115,105, + 110,115,116,97,110,99,101,218,10,95,99,111,100,101,95,116, + 121,112,101,114,134,0,0,0,114,149,0,0,0,218,4,95, + 105,109,112,90,16,95,102,105,120,95,99,111,95,102,105,108, + 101,110,97,109,101,114,118,0,0,0,114,62,0,0,0,41, + 5,114,26,0,0,0,114,117,0,0,0,114,107,0,0,0, + 114,108,0,0,0,218,4,99,111,100,101,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,17,95,99,111,109, + 112,105,108,101,95,98,121,116,101,99,111,100,101,61,2,0, + 0,115,20,0,0,0,0,2,10,1,10,1,12,1,8,1, + 12,1,4,2,10,1,2,0,2,255,114,165,0,0,0,114, + 73,0,0,0,99,3,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,5,0,0,0,67,0,0,0,115,70,0, + 0,0,116,0,116,1,131,1,125,3,124,3,160,2,116,3, + 100,1,131,1,161,1,1,0,124,3,160,2,116,3,124,1, + 131,1,161,1,1,0,124,3,160,2,116,3,124,2,131,1, + 161,1,1,0,124,3,160,2,116,4,160,5,124,0,161,1, + 161,1,1,0,124,3,83,0,41,2,122,43,80,114,111,100, + 117,99,101,32,116,104,101,32,100,97,116,97,32,102,111,114, + 32,97,32,116,105,109,101,115,116,97,109,112,45,98,97,115, + 101,100,32,112,121,99,46,114,73,0,0,0,41,6,218,9, + 98,121,116,101,97,114,114,97,121,114,148,0,0,0,218,6, + 101,120,116,101,110,100,114,20,0,0,0,114,160,0,0,0, + 218,5,100,117,109,112,115,41,4,114,164,0,0,0,218,5, + 109,116,105,109,101,114,155,0,0,0,114,26,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,22, + 95,99,111,100,101,95,116,111,95,116,105,109,101,115,116,97, + 109,112,95,112,121,99,74,2,0,0,115,12,0,0,0,0, + 2,8,1,14,1,14,1,14,1,16,1,114,170,0,0,0, + 84,99,3,0,0,0,0,0,0,0,0,0,0,0,5,0, + 0,0,5,0,0,0,67,0,0,0,115,80,0,0,0,116, + 0,116,1,131,1,125,3,100,1,124,2,100,1,62,0,66, + 0,125,4,124,3,160,2,116,3,124,4,131,1,161,1,1, + 0,116,4,124,1,131,1,100,2,107,2,115,50,116,5,130, + 1,124,3,160,2,124,1,161,1,1,0,124,3,160,2,116, + 6,160,7,124,0,161,1,161,1,1,0,124,3,83,0,41, + 3,122,38,80,114,111,100,117,99,101,32,116,104,101,32,100, + 97,116,97,32,102,111,114,32,97,32,104,97,115,104,45,98, + 97,115,101,100,32,112,121,99,46,114,39,0,0,0,114,146, + 0,0,0,41,8,114,166,0,0,0,114,148,0,0,0,114, + 167,0,0,0,114,20,0,0,0,114,22,0,0,0,114,23, + 0,0,0,114,160,0,0,0,114,168,0,0,0,41,5,114, + 164,0,0,0,114,157,0,0,0,90,7,99,104,101,99,107, + 101,100,114,26,0,0,0,114,83,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,17,95,99,111, + 100,101,95,116,111,95,104,97,115,104,95,112,121,99,84,2, + 0,0,115,14,0,0,0,0,2,8,1,12,1,14,1,16, + 1,10,1,16,1,114,171,0,0,0,99,1,0,0,0,0, + 0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,67, + 0,0,0,115,62,0,0,0,100,1,100,2,108,0,125,1, + 116,1,160,2,124,0,161,1,106,3,125,2,124,1,160,4, + 124,2,161,1,125,3,116,1,160,5,100,2,100,3,161,2, + 125,4,124,4,160,6,124,0,160,6,124,3,100,1,25,0, + 161,1,161,1,83,0,41,4,122,121,68,101,99,111,100,101, + 32,98,121,116,101,115,32,114,101,112,114,101,115,101,110,116, + 105,110,103,32,115,111,117,114,99,101,32,99,111,100,101,32, + 97,110,100,32,114,101,116,117,114,110,32,116,104,101,32,115, + 116,114,105,110,103,46,10,10,32,32,32,32,85,110,105,118, + 101,114,115,97,108,32,110,101,119,108,105,110,101,32,115,117, + 112,112,111,114,116,32,105,115,32,117,115,101,100,32,105,110, + 32,116,104,101,32,100,101,99,111,100,105,110,103,46,10,32, + 32,32,32,114,73,0,0,0,78,84,41,7,218,8,116,111, + 107,101,110,105,122,101,114,64,0,0,0,90,7,66,121,116, + 101,115,73,79,90,8,114,101,97,100,108,105,110,101,90,15, + 100,101,116,101,99,116,95,101,110,99,111,100,105,110,103,90, + 25,73,110,99,114,101,109,101,110,116,97,108,78,101,119,108, + 105,110,101,68,101,99,111,100,101,114,218,6,100,101,99,111, + 100,101,41,5,218,12,115,111,117,114,99,101,95,98,121,116, + 101,115,114,172,0,0,0,90,21,115,111,117,114,99,101,95, + 98,121,116,101,115,95,114,101,97,100,108,105,110,101,218,8, + 101,110,99,111,100,105,110,103,90,15,110,101,119,108,105,110, + 101,95,100,101,99,111,100,101,114,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,100,101,99,111,100,101, + 95,115,111,117,114,99,101,95,2,0,0,115,10,0,0,0, + 0,5,8,1,12,1,10,1,12,1,114,176,0,0,0,169, + 2,114,140,0,0,0,218,26,115,117,98,109,111,100,117,108, + 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, + 110,115,99,2,0,0,0,0,0,0,0,2,0,0,0,9, + 0,0,0,8,0,0,0,67,0,0,0,115,16,1,0,0, + 124,1,100,1,107,8,114,60,100,2,125,1,116,0,124,2, + 100,3,131,2,114,70,122,14,124,2,160,1,124,0,161,1, + 125,1,87,0,113,70,4,0,116,2,107,10,114,56,1,0, + 1,0,1,0,89,0,113,70,88,0,110,10,116,3,160,4, + 124,1,161,1,125,1,116,5,106,6,124,0,124,2,124,1, + 100,4,141,3,125,4,100,5,124,4,95,7,124,2,100,1, + 107,8,114,154,116,8,131,0,68,0,93,42,92,2,125,5, + 125,6,124,1,160,9,116,10,124,6,131,1,161,1,114,106, + 124,5,124,0,124,1,131,2,125,2,124,2,124,4,95,11, + 1,0,113,154,113,106,100,1,83,0,124,3,116,12,107,8, + 114,220,116,0,124,2,100,6,131,2,114,226,122,14,124,2, + 160,13,124,0,161,1,125,7,87,0,110,20,4,0,116,2, + 107,10,114,206,1,0,1,0,1,0,89,0,113,226,88,0, + 124,7,114,226,103,0,124,4,95,14,110,6,124,3,124,4, + 95,14,124,4,106,14,103,0,107,2,144,1,114,12,124,1, + 144,1,114,12,116,15,124,1,131,1,100,7,25,0,125,8, + 124,4,106,14,160,16,124,8,161,1,1,0,124,4,83,0, + 41,8,97,61,1,0,0,82,101,116,117,114,110,32,97,32, + 109,111,100,117,108,101,32,115,112,101,99,32,98,97,115,101, + 100,32,111,110,32,97,32,102,105,108,101,32,108,111,99,97, + 116,105,111,110,46,10,10,32,32,32,32,84,111,32,105,110, + 100,105,99,97,116,101,32,116,104,97,116,32,116,104,101,32, + 109,111,100,117,108,101,32,105,115,32,97,32,112,97,99,107, + 97,103,101,44,32,115,101,116,10,32,32,32,32,115,117,98, + 109,111,100,117,108,101,95,115,101,97,114,99,104,95,108,111, + 99,97,116,105,111,110,115,32,116,111,32,97,32,108,105,115, + 116,32,111,102,32,100,105,114,101,99,116,111,114,121,32,112, + 97,116,104,115,46,32,32,65,110,10,32,32,32,32,101,109, + 112,116,121,32,108,105,115,116,32,105,115,32,115,117,102,102, + 105,99,105,101,110,116,44,32,116,104,111,117,103,104,32,105, + 116,115,32,110,111,116,32,111,116,104,101,114,119,105,115,101, + 32,117,115,101,102,117,108,32,116,111,32,116,104,101,10,32, + 32,32,32,105,109,112,111,114,116,32,115,121,115,116,101,109, + 46,10,10,32,32,32,32,84,104,101,32,108,111,97,100,101, + 114,32,109,117,115,116,32,116,97,107,101,32,97,32,115,112, + 101,99,32,97,115,32,105,116,115,32,111,110,108,121,32,95, + 95,105,110,105,116,95,95,40,41,32,97,114,103,46,10,10, + 32,32,32,32,78,122,9,60,117,110,107,110,111,119,110,62, + 218,12,103,101,116,95,102,105,108,101,110,97,109,101,169,1, + 218,6,111,114,105,103,105,110,84,218,10,105,115,95,112,97, + 99,107,97,103,101,114,73,0,0,0,41,17,114,128,0,0, + 0,114,179,0,0,0,114,118,0,0,0,114,2,0,0,0, + 114,79,0,0,0,114,134,0,0,0,218,10,77,111,100,117, + 108,101,83,112,101,99,90,13,95,115,101,116,95,102,105,108, + 101,97,116,116,114,218,27,95,103,101,116,95,115,117,112,112, + 111,114,116,101,100,95,102,105,108,101,95,108,111,97,100,101, + 114,115,114,111,0,0,0,114,112,0,0,0,114,140,0,0, + 0,218,9,95,80,79,80,85,76,65,84,69,114,182,0,0, + 0,114,178,0,0,0,114,47,0,0,0,218,6,97,112,112, + 101,110,100,41,9,114,117,0,0,0,90,8,108,111,99,97, + 116,105,111,110,114,140,0,0,0,114,178,0,0,0,218,4, + 115,112,101,99,218,12,108,111,97,100,101,114,95,99,108,97, + 115,115,218,8,115,117,102,102,105,120,101,115,114,182,0,0, + 0,90,7,100,105,114,110,97,109,101,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,23,115,112,101,99,95, + 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, + 111,110,112,2,0,0,115,62,0,0,0,0,12,8,4,4, + 1,10,2,2,1,14,1,14,1,8,2,10,8,16,1,6, + 3,8,1,14,1,14,1,10,1,6,1,6,2,4,3,8, + 2,10,1,2,1,14,1,14,1,6,2,4,1,8,2,6, + 1,12,1,6,1,12,1,12,2,114,190,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, + 0,0,0,64,0,0,0,115,80,0,0,0,101,0,90,1, + 100,0,90,2,100,1,90,3,100,2,90,4,100,3,90,5, + 100,4,90,6,101,7,100,5,100,6,132,0,131,1,90,8, + 101,7,100,7,100,8,132,0,131,1,90,9,101,7,100,14, + 100,10,100,11,132,1,131,1,90,10,101,7,100,15,100,12, + 100,13,132,1,131,1,90,11,100,9,83,0,41,16,218,21, + 87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70, + 105,110,100,101,114,122,62,77,101,116,97,32,112,97,116,104, + 32,102,105,110,100,101,114,32,102,111,114,32,109,111,100,117, + 108,101,115,32,100,101,99,108,97,114,101,100,32,105,110,32, + 116,104,101,32,87,105,110,100,111,119,115,32,114,101,103,105, + 115,116,114,121,46,122,59,83,111,102,116,119,97,114,101,92, + 80,121,116,104,111,110,92,80,121,116,104,111,110,67,111,114, + 101,92,123,115,121,115,95,118,101,114,115,105,111,110,125,92, + 77,111,100,117,108,101,115,92,123,102,117,108,108,110,97,109, + 101,125,122,65,83,111,102,116,119,97,114,101,92,80,121,116, + 104,111,110,92,80,121,116,104,111,110,67,111,114,101,92,123, + 115,121,115,95,118,101,114,115,105,111,110,125,92,77,111,100, + 117,108,101,115,92,123,102,117,108,108,110,97,109,101,125,92, + 68,101,98,117,103,70,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,8,0,0,0,67,0,0,0,115, + 56,0,0,0,122,16,116,0,160,1,116,0,106,2,124,1, + 161,2,87,0,83,0,4,0,116,3,107,10,114,50,1,0, + 1,0,1,0,116,0,160,1,116,0,106,4,124,1,161,2, + 6,0,89,0,83,0,88,0,100,0,83,0,114,110,0,0, + 0,41,5,218,7,95,119,105,110,114,101,103,90,7,79,112, + 101,110,75,101,121,90,17,72,75,69,89,95,67,85,82,82, + 69,78,84,95,85,83,69,82,114,50,0,0,0,90,18,72, + 75,69,89,95,76,79,67,65,76,95,77,65,67,72,73,78, + 69,41,2,218,3,99,108,115,114,5,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,14,95,111, + 112,101,110,95,114,101,103,105,115,116,114,121,192,2,0,0, + 115,8,0,0,0,0,2,2,1,16,1,14,1,122,36,87, + 105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,105, + 110,100,101,114,46,95,111,112,101,110,95,114,101,103,105,115, + 116,114,121,99,2,0,0,0,0,0,0,0,0,0,0,0, + 6,0,0,0,9,0,0,0,67,0,0,0,115,114,0,0, + 0,124,0,106,0,114,14,124,0,106,1,125,2,110,6,124, + 0,106,2,125,2,124,2,106,3,124,1,100,1,116,4,106, + 5,100,0,100,2,133,2,25,0,22,0,100,3,141,2,125, + 3,122,38,124,0,160,6,124,3,161,1,143,18,125,4,116, + 7,160,8,124,4,100,4,161,2,125,5,87,0,53,0,81, + 0,82,0,88,0,87,0,110,22,4,0,116,9,107,10,114, + 108,1,0,1,0,1,0,89,0,100,0,83,0,88,0,124, 5,83,0,41,5,78,122,5,37,100,46,37,100,114,28,0, 0,0,41,2,114,139,0,0,0,90,11,115,121,115,95,118, 101,114,115,105,111,110,114,40,0,0,0,41,10,218,11,68, @@ -1013,7 +1011,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,0,114,3,0,0,0,114,6,0,0,0,218,16,95, 115,101,97,114,99,104,95,114,101,103,105,115,116,114,121,199, 2,0,0,115,24,0,0,0,0,2,6,1,8,2,6,1, - 6,1,16,255,6,2,2,1,12,1,26,1,14,1,12,1, + 6,1,16,255,6,2,2,1,12,1,26,1,14,1,8,1, 122,38,87,105,110,100,111,119,115,82,101,103,105,115,116,114, 121,70,105,110,100,101,114,46,95,115,101,97,114,99,104,95, 114,101,103,105,115,116,114,121,78,99,4,0,0,0,0,0, @@ -1057,1781 +1055,1783 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 115,8,0,0,0,0,7,12,1,8,1,6,2,122,33,87, 105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,105, 110,100,101,114,46,102,105,110,100,95,109,111,100,117,108,101, - 41,12,114,125,0,0,0,114,124,0,0,0,114,126,0,0, - 0,114,127,0,0,0,114,197,0,0,0,114,196,0,0,0, - 114,195,0,0,0,218,11,99,108,97,115,115,109,101,116,104, - 111,100,114,194,0,0,0,114,200,0,0,0,114,203,0,0, - 0,114,206,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,191,0,0,0,180, - 2,0,0,115,28,0,0,0,8,2,4,3,2,255,2,4, - 2,255,2,3,4,2,2,1,10,6,2,1,10,14,2,1, - 16,15,2,1,114,191,0,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, - 0,0,115,48,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, - 0,90,5,100,6,100,7,132,0,90,6,100,8,100,9,132, - 0,90,7,100,10,83,0,41,11,218,13,95,76,111,97,100, - 101,114,66,97,115,105,99,115,122,83,66,97,115,101,32,99, - 108,97,115,115,32,111,102,32,99,111,109,109,111,110,32,99, - 111,100,101,32,110,101,101,100,101,100,32,98,121,32,98,111, - 116,104,32,83,111,117,114,99,101,76,111,97,100,101,114,32, - 97,110,100,10,32,32,32,32,83,111,117,114,99,101,108,101, - 115,115,70,105,108,101,76,111,97,100,101,114,46,99,2,0, - 0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0, - 0,0,67,0,0,0,115,64,0,0,0,116,0,124,0,160, - 1,124,1,161,1,131,1,100,1,25,0,125,2,124,2,160, - 2,100,2,100,1,161,2,100,3,25,0,125,3,124,1,160, - 3,100,2,161,1,100,4,25,0,125,4,124,3,100,5,107, - 2,111,62,124,4,100,5,107,3,83,0,41,6,122,141,67, - 111,110,99,114,101,116,101,32,105,109,112,108,101,109,101,110, - 116,97,116,105,111,110,32,111,102,32,73,110,115,112,101,99, - 116,76,111,97,100,101,114,46,105,115,95,112,97,99,107,97, - 103,101,32,98,121,32,99,104,101,99,107,105,110,103,32,105, - 102,10,32,32,32,32,32,32,32,32,116,104,101,32,112,97, - 116,104,32,114,101,116,117,114,110,101,100,32,98,121,32,103, - 101,116,95,102,105,108,101,110,97,109,101,32,104,97,115,32, - 97,32,102,105,108,101,110,97,109,101,32,111,102,32,39,95, - 95,105,110,105,116,95,95,46,112,121,39,46,114,39,0,0, - 0,114,71,0,0,0,114,73,0,0,0,114,28,0,0,0, - 218,8,95,95,105,110,105,116,95,95,41,4,114,47,0,0, - 0,114,179,0,0,0,114,43,0,0,0,114,41,0,0,0, - 41,5,114,119,0,0,0,114,139,0,0,0,114,97,0,0, - 0,90,13,102,105,108,101,110,97,109,101,95,98,97,115,101, - 90,9,116,97,105,108,95,110,97,109,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,182,0,0,0,249, - 2,0,0,115,8,0,0,0,0,3,18,1,16,1,14,1, - 122,24,95,76,111,97,100,101,114,66,97,115,105,99,115,46, - 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,83,0,169,2,122,42, - 85,115,101,32,100,101,102,97,117,108,116,32,115,101,109,97, - 110,116,105,99,115,32,102,111,114,32,109,111,100,117,108,101, - 32,99,114,101,97,116,105,111,110,46,78,114,3,0,0,0, - 169,2,114,119,0,0,0,114,187,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,13,99,114,101, - 97,116,101,95,109,111,100,117,108,101,1,3,0,0,115,2, - 0,0,0,0,1,122,27,95,76,111,97,100,101,114,66,97, - 115,105,99,115,46,99,114,101,97,116,101,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,5,0,0,0,67,0,0,0,115,56,0,0,0, - 124,0,160,0,124,1,106,1,161,1,125,2,124,2,100,1, - 107,8,114,36,116,2,100,2,160,3,124,1,106,1,161,1, - 131,1,130,1,116,4,160,5,116,6,124,2,124,1,106,7, - 161,3,1,0,100,1,83,0,41,3,122,19,69,120,101,99, - 117,116,101,32,116,104,101,32,109,111,100,117,108,101,46,78, - 122,52,99,97,110,110,111,116,32,108,111,97,100,32,109,111, - 100,117,108,101,32,123,33,114,125,32,119,104,101,110,32,103, - 101,116,95,99,111,100,101,40,41,32,114,101,116,117,114,110, - 115,32,78,111,110,101,41,8,218,8,103,101,116,95,99,111, - 100,101,114,125,0,0,0,114,118,0,0,0,114,62,0,0, - 0,114,134,0,0,0,218,25,95,99,97,108,108,95,119,105, - 116,104,95,102,114,97,109,101,115,95,114,101,109,111,118,101, - 100,218,4,101,120,101,99,114,131,0,0,0,41,3,114,119, - 0,0,0,218,6,109,111,100,117,108,101,114,164,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 11,101,120,101,99,95,109,111,100,117,108,101,4,3,0,0, - 115,12,0,0,0,0,2,12,1,8,1,6,1,4,255,6, - 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,67,0,0,0,115,12,0,0,0,116,0,160,1,124,0, - 124,1,161,2,83,0,41,1,122,26,84,104,105,115,32,109, - 111,100,117,108,101,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,46,41,2,114,134,0,0,0,218,17,95,108,111, - 97,100,95,109,111,100,117,108,101,95,115,104,105,109,169,2, - 114,119,0,0,0,114,139,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,11,108,111,97,100,95, - 109,111,100,117,108,101,12,3,0,0,115,2,0,0,0,0, - 2,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, - 46,108,111,97,100,95,109,111,100,117,108,101,78,41,8,114, - 125,0,0,0,114,124,0,0,0,114,126,0,0,0,114,127, - 0,0,0,114,182,0,0,0,114,212,0,0,0,114,217,0, - 0,0,114,220,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,208,0,0,0, - 244,2,0,0,115,10,0,0,0,8,2,4,3,8,8,8, - 3,8,8,114,208,0,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,74,0,0,0,101,0,90,1,100,0,90,2,100,1, - 100,2,132,0,90,3,100,3,100,4,132,0,90,4,100,5, - 100,6,132,0,90,5,100,7,100,8,132,0,90,6,100,9, - 100,10,132,0,90,7,100,11,100,12,156,1,100,13,100,14, - 132,2,90,8,100,15,100,16,132,0,90,9,100,17,83,0, - 41,18,218,12,83,111,117,114,99,101,76,111,97,100,101,114, - 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,8,0,0,0,116,0, - 130,1,100,1,83,0,41,2,122,165,79,112,116,105,111,110, - 97,108,32,109,101,116,104,111,100,32,116,104,97,116,32,114, - 101,116,117,114,110,115,32,116,104,101,32,109,111,100,105,102, - 105,99,97,116,105,111,110,32,116,105,109,101,32,40,97,110, - 32,105,110,116,41,32,102,111,114,32,116,104,101,10,32,32, - 32,32,32,32,32,32,115,112,101,99,105,102,105,101,100,32, - 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, - 32,32,32,32,32,32,32,82,97,105,115,101,115,32,79,83, - 69,114,114,111,114,32,119,104,101,110,32,116,104,101,32,112, - 97,116,104,32,99,97,110,110,111,116,32,98,101,32,104,97, - 110,100,108,101,100,46,10,32,32,32,32,32,32,32,32,78, - 41,1,114,50,0,0,0,169,2,114,119,0,0,0,114,44, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,10,112,97,116,104,95,109,116,105,109,101,19,3, - 0,0,115,2,0,0,0,0,6,122,23,83,111,117,114,99, - 101,76,111,97,100,101,114,46,112,97,116,104,95,109,116,105, - 109,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,4,0,0,0,67,0,0,0,115,14,0,0,0, - 100,1,124,0,160,0,124,1,161,1,105,1,83,0,41,2, - 97,158,1,0,0,79,112,116,105,111,110,97,108,32,109,101, - 116,104,111,100,32,114,101,116,117,114,110,105,110,103,32,97, - 32,109,101,116,97,100,97,116,97,32,100,105,99,116,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 10,32,32,32,32,32,32,32,32,112,97,116,104,32,40,97, - 32,115,116,114,41,46,10,10,32,32,32,32,32,32,32,32, - 80,111,115,115,105,98,108,101,32,107,101,121,115,58,10,32, - 32,32,32,32,32,32,32,45,32,39,109,116,105,109,101,39, - 32,40,109,97,110,100,97,116,111,114,121,41,32,105,115,32, - 116,104,101,32,110,117,109,101,114,105,99,32,116,105,109,101, - 115,116,97,109,112,32,111,102,32,108,97,115,116,32,115,111, - 117,114,99,101,10,32,32,32,32,32,32,32,32,32,32,99, - 111,100,101,32,109,111,100,105,102,105,99,97,116,105,111,110, - 59,10,32,32,32,32,32,32,32,32,45,32,39,115,105,122, - 101,39,32,40,111,112,116,105,111,110,97,108,41,32,105,115, - 32,116,104,101,32,115,105,122,101,32,105,110,32,98,121,116, - 101,115,32,111,102,32,116,104,101,32,115,111,117,114,99,101, - 32,99,111,100,101,46,10,10,32,32,32,32,32,32,32,32, - 73,109,112,108,101,109,101,110,116,105,110,103,32,116,104,105, - 115,32,109,101,116,104,111,100,32,97,108,108,111,119,115,32, - 116,104,101,32,108,111,97,100,101,114,32,116,111,32,114,101, - 97,100,32,98,121,116,101,99,111,100,101,32,102,105,108,101, - 115,46,10,32,32,32,32,32,32,32,32,82,97,105,115,101, - 115,32,79,83,69,114,114,111,114,32,119,104,101,110,32,116, - 104,101,32,112,97,116,104,32,99,97,110,110,111,116,32,98, - 101,32,104,97,110,100,108,101,100,46,10,32,32,32,32,32, - 32,32,32,114,169,0,0,0,41,1,114,223,0,0,0,114, - 222,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,10,112,97,116,104,95,115,116,97,116,115,27, - 3,0,0,115,2,0,0,0,0,12,122,23,83,111,117,114, - 99,101,76,111,97,100,101,114,46,112,97,116,104,95,115,116, - 97,116,115,99,4,0,0,0,0,0,0,0,0,0,0,0, - 4,0,0,0,4,0,0,0,67,0,0,0,115,12,0,0, - 0,124,0,160,0,124,2,124,3,161,2,83,0,41,1,122, - 228,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, - 32,119,104,105,99,104,32,119,114,105,116,101,115,32,100,97, - 116,97,32,40,98,121,116,101,115,41,32,116,111,32,97,32, - 102,105,108,101,32,112,97,116,104,32,40,97,32,115,116,114, - 41,46,10,10,32,32,32,32,32,32,32,32,73,109,112,108, - 101,109,101,110,116,105,110,103,32,116,104,105,115,32,109,101, - 116,104,111,100,32,97,108,108,111,119,115,32,102,111,114,32, - 116,104,101,32,119,114,105,116,105,110,103,32,111,102,32,98, - 121,116,101,99,111,100,101,32,102,105,108,101,115,46,10,10, - 32,32,32,32,32,32,32,32,84,104,101,32,115,111,117,114, - 99,101,32,112,97,116,104,32,105,115,32,110,101,101,100,101, - 100,32,105,110,32,111,114,100,101,114,32,116,111,32,99,111, - 114,114,101,99,116,108,121,32,116,114,97,110,115,102,101,114, - 32,112,101,114,109,105,115,115,105,111,110,115,10,32,32,32, - 32,32,32,32,32,41,1,218,8,115,101,116,95,100,97,116, - 97,41,4,114,119,0,0,0,114,108,0,0,0,90,10,99, - 97,99,104,101,95,112,97,116,104,114,26,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,15,95, - 99,97,99,104,101,95,98,121,116,101,99,111,100,101,41,3, - 0,0,115,2,0,0,0,0,8,122,28,83,111,117,114,99, - 101,76,111,97,100,101,114,46,95,99,97,99,104,101,95,98, - 121,116,101,99,111,100,101,99,3,0,0,0,0,0,0,0, - 0,0,0,0,3,0,0,0,1,0,0,0,67,0,0,0, - 115,4,0,0,0,100,1,83,0,41,2,122,150,79,112,116, - 105,111,110,97,108,32,109,101,116,104,111,100,32,119,104,105, - 99,104,32,119,114,105,116,101,115,32,100,97,116,97,32,40, - 98,121,116,101,115,41,32,116,111,32,97,32,102,105,108,101, - 32,112,97,116,104,32,40,97,32,115,116,114,41,46,10,10, - 32,32,32,32,32,32,32,32,73,109,112,108,101,109,101,110, - 116,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100, - 32,97,108,108,111,119,115,32,102,111,114,32,116,104,101,32, - 119,114,105,116,105,110,103,32,111,102,32,98,121,116,101,99, - 111,100,101,32,102,105,108,101,115,46,10,32,32,32,32,32, - 32,32,32,78,114,3,0,0,0,41,3,114,119,0,0,0, - 114,44,0,0,0,114,26,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,225,0,0,0,51,3, - 0,0,115,2,0,0,0,0,1,122,21,83,111,117,114,99, - 101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,97, - 99,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,10,0,0,0,67,0,0,0,115,82,0,0,0,124,0, - 160,0,124,1,161,1,125,2,122,14,124,0,160,1,124,2, - 161,1,125,3,87,0,110,48,4,0,116,2,107,10,114,72, - 1,0,125,4,1,0,122,18,116,3,100,1,124,1,100,2, - 141,2,124,4,130,2,87,0,53,0,100,3,125,4,126,4, - 88,0,89,0,110,2,88,0,116,4,124,3,131,1,83,0, - 41,4,122,52,67,111,110,99,114,101,116,101,32,105,109,112, - 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,73, - 110,115,112,101,99,116,76,111,97,100,101,114,46,103,101,116, - 95,115,111,117,114,99,101,46,122,39,115,111,117,114,99,101, - 32,110,111,116,32,97,118,97,105,108,97,98,108,101,32,116, - 104,114,111,117,103,104,32,103,101,116,95,100,97,116,97,40, - 41,114,116,0,0,0,78,41,5,114,179,0,0,0,218,8, - 103,101,116,95,100,97,116,97,114,50,0,0,0,114,118,0, - 0,0,114,176,0,0,0,41,5,114,119,0,0,0,114,139, - 0,0,0,114,44,0,0,0,114,174,0,0,0,218,3,101, - 120,99,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,10,103,101,116,95,115,111,117,114,99,101,58,3,0, - 0,115,20,0,0,0,0,2,10,1,2,1,14,1,16,1, - 4,1,2,255,4,1,2,255,20,2,122,23,83,111,117,114, - 99,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,114,105,0,0,0,41,1,218,9,95,111,112,116, - 105,109,105,122,101,99,3,0,0,0,0,0,0,0,1,0, - 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,22, - 0,0,0,116,0,106,1,116,2,124,1,124,2,100,1,100, - 2,124,3,100,3,141,6,83,0,41,4,122,130,82,101,116, - 117,114,110,32,116,104,101,32,99,111,100,101,32,111,98,106, - 101,99,116,32,99,111,109,112,105,108,101,100,32,102,114,111, - 109,32,115,111,117,114,99,101,46,10,10,32,32,32,32,32, - 32,32,32,84,104,101,32,39,100,97,116,97,39,32,97,114, - 103,117,109,101,110,116,32,99,97,110,32,98,101,32,97,110, - 121,32,111,98,106,101,99,116,32,116,121,112,101,32,116,104, - 97,116,32,99,111,109,112,105,108,101,40,41,32,115,117,112, - 112,111,114,116,115,46,10,32,32,32,32,32,32,32,32,114, - 215,0,0,0,84,41,2,218,12,100,111,110,116,95,105,110, - 104,101,114,105,116,114,84,0,0,0,41,3,114,134,0,0, - 0,114,214,0,0,0,218,7,99,111,109,112,105,108,101,41, - 4,114,119,0,0,0,114,26,0,0,0,114,44,0,0,0, - 114,230,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,14,115,111,117,114,99,101,95,116,111,95, - 99,111,100,101,68,3,0,0,115,8,0,0,0,0,5,12, - 1,2,0,2,255,122,27,83,111,117,114,99,101,76,111,97, - 100,101,114,46,115,111,117,114,99,101,95,116,111,95,99,111, - 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,15, - 0,0,0,9,0,0,0,67,0,0,0,115,34,2,0,0, - 124,0,160,0,124,1,161,1,125,2,100,1,125,3,100,1, - 125,4,100,1,125,5,100,2,125,6,100,3,125,7,122,12, - 116,1,124,2,131,1,125,8,87,0,110,26,4,0,116,2, - 107,10,114,68,1,0,1,0,1,0,100,1,125,8,89,0, - 144,1,110,48,88,0,122,14,124,0,160,3,124,2,161,1, - 125,9,87,0,110,22,4,0,116,4,107,10,114,106,1,0, - 1,0,1,0,89,0,144,1,110,10,88,0,116,5,124,9, - 100,4,25,0,131,1,125,3,122,14,124,0,160,6,124,8, - 161,1,125,10,87,0,110,20,4,0,116,4,107,10,114,154, - 1,0,1,0,1,0,89,0,110,218,88,0,124,1,124,8, - 100,5,156,2,125,11,122,148,116,7,124,10,124,1,124,11, - 131,3,125,12,116,8,124,10,131,1,100,6,100,1,133,2, - 25,0,125,13,124,12,100,7,64,0,100,8,107,3,125,6, - 124,6,144,1,114,36,124,12,100,9,64,0,100,8,107,3, - 125,7,116,9,106,10,100,10,107,3,144,1,114,34,124,7, - 115,254,116,9,106,10,100,11,107,2,144,1,114,34,124,0, - 160,6,124,2,161,1,125,4,116,9,160,11,116,12,124,4, - 161,2,125,5,116,13,124,10,124,5,124,1,124,11,131,4, - 1,0,110,20,116,14,124,10,124,3,124,9,100,12,25,0, - 124,1,124,11,131,5,1,0,87,0,110,26,4,0,116,15, - 116,16,102,2,107,10,144,1,114,84,1,0,1,0,1,0, - 89,0,110,32,88,0,116,17,160,18,100,13,124,8,124,2, - 161,3,1,0,116,19,124,13,124,1,124,8,124,2,100,14, - 141,4,83,0,124,4,100,1,107,8,144,1,114,136,124,0, - 160,6,124,2,161,1,125,4,124,0,160,20,124,4,124,2, - 161,2,125,14,116,17,160,18,100,15,124,2,161,2,1,0, - 116,21,106,22,144,2,115,30,124,8,100,1,107,9,144,2, - 114,30,124,3,100,1,107,9,144,2,114,30,124,6,144,1, - 114,228,124,5,100,1,107,8,144,1,114,214,116,9,160,11, - 124,4,161,1,125,5,116,23,124,14,124,5,124,7,131,3, - 125,10,110,16,116,24,124,14,124,3,116,25,124,4,131,1, - 131,3,125,10,122,18,124,0,160,26,124,2,124,8,124,10, - 161,3,1,0,87,0,110,22,4,0,116,2,107,10,144,2, - 114,28,1,0,1,0,1,0,89,0,110,2,88,0,124,14, - 83,0,41,16,122,190,67,111,110,99,114,101,116,101,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, - 32,73,110,115,112,101,99,116,76,111,97,100,101,114,46,103, - 101,116,95,99,111,100,101,46,10,10,32,32,32,32,32,32, - 32,32,82,101,97,100,105,110,103,32,111,102,32,98,121,116, - 101,99,111,100,101,32,114,101,113,117,105,114,101,115,32,112, - 97,116,104,95,115,116,97,116,115,32,116,111,32,98,101,32, - 105,109,112,108,101,109,101,110,116,101,100,46,32,84,111,32, - 119,114,105,116,101,10,32,32,32,32,32,32,32,32,98,121, - 116,101,99,111,100,101,44,32,115,101,116,95,100,97,116,97, - 32,109,117,115,116,32,97,108,115,111,32,98,101,32,105,109, - 112,108,101,109,101,110,116,101,100,46,10,10,32,32,32,32, - 32,32,32,32,78,70,84,114,169,0,0,0,114,159,0,0, - 0,114,145,0,0,0,114,39,0,0,0,114,73,0,0,0, - 114,28,0,0,0,90,5,110,101,118,101,114,90,6,97,108, - 119,97,121,115,218,4,115,105,122,101,122,13,123,125,32,109, - 97,116,99,104,101,115,32,123,125,41,3,114,117,0,0,0, - 114,107,0,0,0,114,108,0,0,0,122,19,99,111,100,101, - 32,111,98,106,101,99,116,32,102,114,111,109,32,123,125,41, - 27,114,179,0,0,0,114,98,0,0,0,114,82,0,0,0, - 114,224,0,0,0,114,50,0,0,0,114,17,0,0,0,114, - 227,0,0,0,114,152,0,0,0,218,10,109,101,109,111,114, - 121,118,105,101,119,114,163,0,0,0,90,21,99,104,101,99, - 107,95,104,97,115,104,95,98,97,115,101,100,95,112,121,99, - 115,114,157,0,0,0,218,17,95,82,65,87,95,77,65,71, - 73,67,95,78,85,77,66,69,82,114,158,0,0,0,114,156, - 0,0,0,114,118,0,0,0,114,150,0,0,0,114,134,0, - 0,0,114,149,0,0,0,114,165,0,0,0,114,233,0,0, - 0,114,8,0,0,0,218,19,100,111,110,116,95,119,114,105, - 116,101,95,98,121,116,101,99,111,100,101,114,171,0,0,0, - 114,170,0,0,0,114,22,0,0,0,114,226,0,0,0,41, - 15,114,119,0,0,0,114,139,0,0,0,114,108,0,0,0, - 114,154,0,0,0,114,174,0,0,0,114,157,0,0,0,90, - 10,104,97,115,104,95,98,97,115,101,100,90,12,99,104,101, - 99,107,95,115,111,117,114,99,101,114,107,0,0,0,218,2, - 115,116,114,26,0,0,0,114,151,0,0,0,114,83,0,0, - 0,90,10,98,121,116,101,115,95,100,97,116,97,90,11,99, - 111,100,101,95,111,98,106,101,99,116,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,213,0,0,0,76,3, - 0,0,115,152,0,0,0,0,7,10,1,4,1,4,1,4, - 1,4,1,4,1,2,1,12,1,14,1,12,2,2,1,14, - 1,14,1,8,2,12,1,2,1,14,1,14,1,6,3,2, - 1,2,254,6,4,2,1,12,1,16,1,12,1,6,1,12, - 1,12,1,2,255,2,2,8,254,4,3,10,1,4,1,2, - 1,2,254,4,4,8,1,2,255,6,3,2,1,2,1,2, - 1,6,1,2,1,2,251,8,7,20,1,6,2,8,1,2, - 255,4,2,6,1,2,1,2,254,6,3,10,1,10,1,12, - 1,12,1,18,1,6,255,4,2,6,1,10,1,10,1,14, - 2,6,1,6,255,4,2,2,1,18,1,16,1,6,1,122, - 21,83,111,117,114,99,101,76,111,97,100,101,114,46,103,101, - 116,95,99,111,100,101,78,41,10,114,125,0,0,0,114,124, - 0,0,0,114,126,0,0,0,114,223,0,0,0,114,224,0, - 0,0,114,226,0,0,0,114,225,0,0,0,114,229,0,0, - 0,114,233,0,0,0,114,213,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 221,0,0,0,17,3,0,0,115,14,0,0,0,8,2,8, - 8,8,14,8,10,8,7,8,10,14,8,114,221,0,0,0, + 41,2,78,78,41,1,78,41,12,114,125,0,0,0,114,124, + 0,0,0,114,126,0,0,0,114,127,0,0,0,114,197,0, + 0,0,114,196,0,0,0,114,195,0,0,0,218,11,99,108, + 97,115,115,109,101,116,104,111,100,114,194,0,0,0,114,200, + 0,0,0,114,203,0,0,0,114,206,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,191,0,0,0,180,2,0,0,115,28,0,0,0,8, + 2,4,3,2,255,2,4,2,255,2,3,4,2,2,1,10, + 6,2,1,10,14,2,1,12,15,2,1,114,191,0,0,0, 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,0,0,0,0,115,124,0,0,0,101,0, + 0,2,0,0,0,64,0,0,0,115,48,0,0,0,101,0, 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, 90,4,100,4,100,5,132,0,90,5,100,6,100,7,132,0, - 90,6,101,7,135,0,102,1,100,8,100,9,132,8,131,1, - 90,8,101,7,100,10,100,11,132,0,131,1,90,9,100,12, - 100,13,132,0,90,10,101,7,100,14,100,15,132,0,131,1, - 90,11,100,16,100,17,132,0,90,12,100,18,100,19,132,0, - 90,13,100,20,100,21,132,0,90,14,100,22,100,23,132,0, - 90,15,135,0,4,0,90,16,83,0,41,24,218,10,70,105, - 108,101,76,111,97,100,101,114,122,103,66,97,115,101,32,102, - 105,108,101,32,108,111,97,100,101,114,32,99,108,97,115,115, - 32,119,104,105,99,104,32,105,109,112,108,101,109,101,110,116, - 115,32,116,104,101,32,108,111,97,100,101,114,32,112,114,111, - 116,111,99,111,108,32,109,101,116,104,111,100,115,32,116,104, - 97,116,10,32,32,32,32,114,101,113,117,105,114,101,32,102, - 105,108,101,32,115,121,115,116,101,109,32,117,115,97,103,101, - 46,99,3,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,124, - 1,124,0,95,0,124,2,124,0,95,1,100,1,83,0,41, - 2,122,75,67,97,99,104,101,32,116,104,101,32,109,111,100, - 117,108,101,32,110,97,109,101,32,97,110,100,32,116,104,101, - 32,112,97,116,104,32,116,111,32,116,104,101,32,102,105,108, - 101,32,102,111,117,110,100,32,98,121,32,116,104,101,10,32, - 32,32,32,32,32,32,32,102,105,110,100,101,114,46,78,114, - 159,0,0,0,41,3,114,119,0,0,0,114,139,0,0,0, - 114,44,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,209,0,0,0,166,3,0,0,115,4,0, - 0,0,0,3,6,1,122,19,70,105,108,101,76,111,97,100, - 101,114,46,95,95,105,110,105,116,95,95,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, - 67,0,0,0,115,24,0,0,0,124,0,106,0,124,1,106, - 0,107,2,111,22,124,0,106,1,124,1,106,1,107,2,83, - 0,114,110,0,0,0,169,2,218,9,95,95,99,108,97,115, - 115,95,95,114,131,0,0,0,169,2,114,119,0,0,0,90, - 5,111,116,104,101,114,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,6,95,95,101,113,95,95,172,3,0, - 0,115,6,0,0,0,0,1,12,1,10,255,122,17,70,105, - 108,101,76,111,97,100,101,114,46,95,95,101,113,95,95,99, - 1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, - 3,0,0,0,67,0,0,0,115,20,0,0,0,116,0,124, - 0,106,1,131,1,116,0,124,0,106,2,131,1,65,0,83, - 0,114,110,0,0,0,169,3,218,4,104,97,115,104,114,117, - 0,0,0,114,44,0,0,0,169,1,114,119,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,8, - 95,95,104,97,115,104,95,95,176,3,0,0,115,2,0,0, - 0,0,1,122,19,70,105,108,101,76,111,97,100,101,114,46, - 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,3,0,0, - 0,115,16,0,0,0,116,0,116,1,124,0,131,2,160,2, - 124,1,161,1,83,0,41,1,122,100,76,111,97,100,32,97, - 32,109,111,100,117,108,101,32,102,114,111,109,32,97,32,102, - 105,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, - 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, - 114,101,99,97,116,101,100,46,32,32,85,115,101,32,101,120, - 101,99,95,109,111,100,117,108,101,40,41,32,105,110,115,116, - 101,97,100,46,10,10,32,32,32,32,32,32,32,32,41,3, - 218,5,115,117,112,101,114,114,239,0,0,0,114,220,0,0, - 0,114,219,0,0,0,169,1,114,241,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,220,0,0,0,179,3,0,0, - 115,2,0,0,0,0,10,122,22,70,105,108,101,76,111,97, - 100,101,114,46,108,111,97,100,95,109,111,100,117,108,101,99, + 90,6,100,8,100,9,132,0,90,7,100,10,83,0,41,11, + 218,13,95,76,111,97,100,101,114,66,97,115,105,99,115,122, + 83,66,97,115,101,32,99,108,97,115,115,32,111,102,32,99, + 111,109,109,111,110,32,99,111,100,101,32,110,101,101,100,101, + 100,32,98,121,32,98,111,116,104,32,83,111,117,114,99,101, + 76,111,97,100,101,114,32,97,110,100,10,32,32,32,32,83, + 111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,97, + 100,101,114,46,99,2,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,4,0,0,0,67,0,0,0,115,64,0, + 0,0,116,0,124,0,160,1,124,1,161,1,131,1,100,1, + 25,0,125,2,124,2,160,2,100,2,100,1,161,2,100,3, + 25,0,125,3,124,1,160,3,100,2,161,1,100,4,25,0, + 125,4,124,3,100,5,107,2,111,62,124,4,100,5,107,3, + 83,0,41,6,122,141,67,111,110,99,114,101,116,101,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, + 32,73,110,115,112,101,99,116,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,32,98,121,32,99,104,101, + 99,107,105,110,103,32,105,102,10,32,32,32,32,32,32,32, + 32,116,104,101,32,112,97,116,104,32,114,101,116,117,114,110, + 101,100,32,98,121,32,103,101,116,95,102,105,108,101,110,97, + 109,101,32,104,97,115,32,97,32,102,105,108,101,110,97,109, + 101,32,111,102,32,39,95,95,105,110,105,116,95,95,46,112, + 121,39,46,114,39,0,0,0,114,71,0,0,0,114,73,0, + 0,0,114,28,0,0,0,218,8,95,95,105,110,105,116,95, + 95,41,4,114,47,0,0,0,114,179,0,0,0,114,43,0, + 0,0,114,41,0,0,0,41,5,114,119,0,0,0,114,139, + 0,0,0,114,97,0,0,0,90,13,102,105,108,101,110,97, + 109,101,95,98,97,115,101,90,9,116,97,105,108,95,110,97, + 109,101,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,182,0,0,0,249,2,0,0,115,8,0,0,0,0, + 3,18,1,16,1,14,1,122,24,95,76,111,97,100,101,114, + 66,97,115,105,99,115,46,105,115,95,112,97,99,107,97,103, + 101,99,2,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, + 1,83,0,169,2,122,42,85,115,101,32,100,101,102,97,117, + 108,116,32,115,101,109,97,110,116,105,99,115,32,102,111,114, + 32,109,111,100,117,108,101,32,99,114,101,97,116,105,111,110, + 46,78,114,3,0,0,0,169,2,114,119,0,0,0,114,187, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,13,99,114,101,97,116,101,95,109,111,100,117,108, + 101,1,3,0,0,115,2,0,0,0,0,1,122,27,95,76, + 111,97,100,101,114,66,97,115,105,99,115,46,99,114,101,97, + 116,101,95,109,111,100,117,108,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,5,0,0,0,67,0, + 0,0,115,56,0,0,0,124,0,160,0,124,1,106,1,161, + 1,125,2,124,2,100,1,107,8,114,36,116,2,100,2,160, + 3,124,1,106,1,161,1,131,1,130,1,116,4,160,5,116, + 6,124,2,124,1,106,7,161,3,1,0,100,1,83,0,41, + 3,122,19,69,120,101,99,117,116,101,32,116,104,101,32,109, + 111,100,117,108,101,46,78,122,52,99,97,110,110,111,116,32, + 108,111,97,100,32,109,111,100,117,108,101,32,123,33,114,125, + 32,119,104,101,110,32,103,101,116,95,99,111,100,101,40,41, + 32,114,101,116,117,114,110,115,32,78,111,110,101,41,8,218, + 8,103,101,116,95,99,111,100,101,114,125,0,0,0,114,118, + 0,0,0,114,62,0,0,0,114,134,0,0,0,218,25,95, + 99,97,108,108,95,119,105,116,104,95,102,114,97,109,101,115, + 95,114,101,109,111,118,101,100,218,4,101,120,101,99,114,131, + 0,0,0,41,3,114,119,0,0,0,218,6,109,111,100,117, + 108,101,114,164,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,11,101,120,101,99,95,109,111,100, + 117,108,101,4,3,0,0,115,12,0,0,0,0,2,12,1, + 8,1,6,1,4,255,6,2,122,25,95,76,111,97,100,101, + 114,66,97,115,105,99,115,46,101,120,101,99,95,109,111,100, + 117,108,101,99,2,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,4,0,0,0,67,0,0,0,115,12,0,0, + 0,116,0,160,1,124,0,124,1,161,2,83,0,41,1,122, + 26,84,104,105,115,32,109,111,100,117,108,101,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,41,2,114,134,0, + 0,0,218,17,95,108,111,97,100,95,109,111,100,117,108,101, + 95,115,104,105,109,169,2,114,119,0,0,0,114,139,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,11,108,111,97,100,95,109,111,100,117,108,101,12,3,0, + 0,115,2,0,0,0,0,2,122,25,95,76,111,97,100,101, + 114,66,97,115,105,99,115,46,108,111,97,100,95,109,111,100, + 117,108,101,78,41,8,114,125,0,0,0,114,124,0,0,0, + 114,126,0,0,0,114,127,0,0,0,114,182,0,0,0,114, + 212,0,0,0,114,217,0,0,0,114,220,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,208,0,0,0,244,2,0,0,115,10,0,0,0, + 8,2,4,3,8,8,8,3,8,8,114,208,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,64,0,0,0,115,74,0,0,0,101,0,90, + 1,100,0,90,2,100,1,100,2,132,0,90,3,100,3,100, + 4,132,0,90,4,100,5,100,6,132,0,90,5,100,7,100, + 8,132,0,90,6,100,9,100,10,132,0,90,7,100,11,100, + 12,156,1,100,13,100,14,132,2,90,8,100,15,100,16,132, + 0,90,9,100,17,83,0,41,18,218,12,83,111,117,114,99, + 101,76,111,97,100,101,114,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,8,0,0,0,116,0,130,1,100,1,83,0,41,2,122, + 165,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, + 32,116,104,97,116,32,114,101,116,117,114,110,115,32,116,104, + 101,32,109,111,100,105,102,105,99,97,116,105,111,110,32,116, + 105,109,101,32,40,97,110,32,105,110,116,41,32,102,111,114, + 32,116,104,101,10,32,32,32,32,32,32,32,32,115,112,101, + 99,105,102,105,101,100,32,112,97,116,104,32,40,97,32,115, + 116,114,41,46,10,10,32,32,32,32,32,32,32,32,82,97, + 105,115,101,115,32,79,83,69,114,114,111,114,32,119,104,101, + 110,32,116,104,101,32,112,97,116,104,32,99,97,110,110,111, + 116,32,98,101,32,104,97,110,100,108,101,100,46,10,32,32, + 32,32,32,32,32,32,78,41,1,114,50,0,0,0,169,2, + 114,119,0,0,0,114,44,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,10,112,97,116,104,95, + 109,116,105,109,101,19,3,0,0,115,2,0,0,0,0,6, + 122,23,83,111,117,114,99,101,76,111,97,100,101,114,46,112, + 97,116,104,95,109,116,105,109,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,4,0,0,0,67,0, + 0,0,115,14,0,0,0,100,1,124,0,160,0,124,1,161, + 1,105,1,83,0,41,2,97,158,1,0,0,79,112,116,105, + 111,110,97,108,32,109,101,116,104,111,100,32,114,101,116,117, + 114,110,105,110,103,32,97,32,109,101,116,97,100,97,116,97, + 32,100,105,99,116,32,102,111,114,32,116,104,101,32,115,112, + 101,99,105,102,105,101,100,10,32,32,32,32,32,32,32,32, + 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, + 32,32,32,32,32,32,32,80,111,115,115,105,98,108,101,32, + 107,101,121,115,58,10,32,32,32,32,32,32,32,32,45,32, + 39,109,116,105,109,101,39,32,40,109,97,110,100,97,116,111, + 114,121,41,32,105,115,32,116,104,101,32,110,117,109,101,114, + 105,99,32,116,105,109,101,115,116,97,109,112,32,111,102,32, + 108,97,115,116,32,115,111,117,114,99,101,10,32,32,32,32, + 32,32,32,32,32,32,99,111,100,101,32,109,111,100,105,102, + 105,99,97,116,105,111,110,59,10,32,32,32,32,32,32,32, + 32,45,32,39,115,105,122,101,39,32,40,111,112,116,105,111, + 110,97,108,41,32,105,115,32,116,104,101,32,115,105,122,101, + 32,105,110,32,98,121,116,101,115,32,111,102,32,116,104,101, + 32,115,111,117,114,99,101,32,99,111,100,101,46,10,10,32, + 32,32,32,32,32,32,32,73,109,112,108,101,109,101,110,116, + 105,110,103,32,116,104,105,115,32,109,101,116,104,111,100,32, + 97,108,108,111,119,115,32,116,104,101,32,108,111,97,100,101, + 114,32,116,111,32,114,101,97,100,32,98,121,116,101,99,111, + 100,101,32,102,105,108,101,115,46,10,32,32,32,32,32,32, + 32,32,82,97,105,115,101,115,32,79,83,69,114,114,111,114, + 32,119,104,101,110,32,116,104,101,32,112,97,116,104,32,99, + 97,110,110,111,116,32,98,101,32,104,97,110,100,108,101,100, + 46,10,32,32,32,32,32,32,32,32,114,169,0,0,0,41, + 1,114,223,0,0,0,114,222,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,10,112,97,116,104, + 95,115,116,97,116,115,27,3,0,0,115,2,0,0,0,0, + 12,122,23,83,111,117,114,99,101,76,111,97,100,101,114,46, + 112,97,116,104,95,115,116,97,116,115,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, + 0,0,0,115,12,0,0,0,124,0,160,0,124,2,124,3, + 161,2,83,0,41,1,122,228,79,112,116,105,111,110,97,108, + 32,109,101,116,104,111,100,32,119,104,105,99,104,32,119,114, + 105,116,101,115,32,100,97,116,97,32,40,98,121,116,101,115, + 41,32,116,111,32,97,32,102,105,108,101,32,112,97,116,104, + 32,40,97,32,115,116,114,41,46,10,10,32,32,32,32,32, + 32,32,32,73,109,112,108,101,109,101,110,116,105,110,103,32, + 116,104,105,115,32,109,101,116,104,111,100,32,97,108,108,111, + 119,115,32,102,111,114,32,116,104,101,32,119,114,105,116,105, + 110,103,32,111,102,32,98,121,116,101,99,111,100,101,32,102, + 105,108,101,115,46,10,10,32,32,32,32,32,32,32,32,84, + 104,101,32,115,111,117,114,99,101,32,112,97,116,104,32,105, + 115,32,110,101,101,100,101,100,32,105,110,32,111,114,100,101, + 114,32,116,111,32,99,111,114,114,101,99,116,108,121,32,116, + 114,97,110,115,102,101,114,32,112,101,114,109,105,115,115,105, + 111,110,115,10,32,32,32,32,32,32,32,32,41,1,218,8, + 115,101,116,95,100,97,116,97,41,4,114,119,0,0,0,114, + 108,0,0,0,90,10,99,97,99,104,101,95,112,97,116,104, + 114,26,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,15,95,99,97,99,104,101,95,98,121,116, + 101,99,111,100,101,41,3,0,0,115,2,0,0,0,0,8, + 122,28,83,111,117,114,99,101,76,111,97,100,101,114,46,95, + 99,97,99,104,101,95,98,121,116,101,99,111,100,101,99,3, + 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,1, + 0,0,0,67,0,0,0,115,4,0,0,0,100,1,83,0, + 41,2,122,150,79,112,116,105,111,110,97,108,32,109,101,116, + 104,111,100,32,119,104,105,99,104,32,119,114,105,116,101,115, + 32,100,97,116,97,32,40,98,121,116,101,115,41,32,116,111, + 32,97,32,102,105,108,101,32,112,97,116,104,32,40,97,32, + 115,116,114,41,46,10,10,32,32,32,32,32,32,32,32,73, + 109,112,108,101,109,101,110,116,105,110,103,32,116,104,105,115, + 32,109,101,116,104,111,100,32,97,108,108,111,119,115,32,102, + 111,114,32,116,104,101,32,119,114,105,116,105,110,103,32,111, + 102,32,98,121,116,101,99,111,100,101,32,102,105,108,101,115, + 46,10,32,32,32,32,32,32,32,32,78,114,3,0,0,0, + 41,3,114,119,0,0,0,114,44,0,0,0,114,26,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,225,0,0,0,51,3,0,0,115,2,0,0,0,0,1, + 122,21,83,111,117,114,99,101,76,111,97,100,101,114,46,115, + 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,10,0,0,0,67,0,0,0, + 115,82,0,0,0,124,0,160,0,124,1,161,1,125,2,122, + 14,124,0,160,1,124,2,161,1,125,3,87,0,110,48,4, + 0,116,2,107,10,114,72,1,0,125,4,1,0,122,18,116, + 3,100,1,124,1,100,2,141,2,124,4,130,2,87,0,53, + 0,100,3,125,4,126,4,88,0,89,0,110,2,88,0,116, + 4,124,3,131,1,83,0,41,4,122,52,67,111,110,99,114, + 101,116,101,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,111,102,32,73,110,115,112,101,99,116,76,111,97, + 100,101,114,46,103,101,116,95,115,111,117,114,99,101,46,122, + 39,115,111,117,114,99,101,32,110,111,116,32,97,118,97,105, + 108,97,98,108,101,32,116,104,114,111,117,103,104,32,103,101, + 116,95,100,97,116,97,40,41,114,116,0,0,0,78,41,5, + 114,179,0,0,0,218,8,103,101,116,95,100,97,116,97,114, + 50,0,0,0,114,118,0,0,0,114,176,0,0,0,41,5, + 114,119,0,0,0,114,139,0,0,0,114,44,0,0,0,114, + 174,0,0,0,218,3,101,120,99,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,10,103,101,116,95,115,111, + 117,114,99,101,58,3,0,0,115,20,0,0,0,0,2,10, + 1,2,1,14,1,16,1,4,1,2,255,4,1,2,255,20, + 2,122,23,83,111,117,114,99,101,76,111,97,100,101,114,46, + 103,101,116,95,115,111,117,114,99,101,114,105,0,0,0,41, + 1,218,9,95,111,112,116,105,109,105,122,101,99,3,0,0, + 0,0,0,0,0,1,0,0,0,4,0,0,0,8,0,0, + 0,67,0,0,0,115,22,0,0,0,116,0,106,1,116,2, + 124,1,124,2,100,1,100,2,124,3,100,3,141,6,83,0, + 41,4,122,130,82,101,116,117,114,110,32,116,104,101,32,99, + 111,100,101,32,111,98,106,101,99,116,32,99,111,109,112,105, + 108,101,100,32,102,114,111,109,32,115,111,117,114,99,101,46, + 10,10,32,32,32,32,32,32,32,32,84,104,101,32,39,100, + 97,116,97,39,32,97,114,103,117,109,101,110,116,32,99,97, + 110,32,98,101,32,97,110,121,32,111,98,106,101,99,116,32, + 116,121,112,101,32,116,104,97,116,32,99,111,109,112,105,108, + 101,40,41,32,115,117,112,112,111,114,116,115,46,10,32,32, + 32,32,32,32,32,32,114,215,0,0,0,84,41,2,218,12, + 100,111,110,116,95,105,110,104,101,114,105,116,114,84,0,0, + 0,41,3,114,134,0,0,0,114,214,0,0,0,218,7,99, + 111,109,112,105,108,101,41,4,114,119,0,0,0,114,26,0, + 0,0,114,44,0,0,0,114,230,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,14,115,111,117, + 114,99,101,95,116,111,95,99,111,100,101,68,3,0,0,115, + 8,0,0,0,0,5,12,1,2,0,2,255,122,27,83,111, + 117,114,99,101,76,111,97,100,101,114,46,115,111,117,114,99, + 101,95,116,111,95,99,111,100,101,99,2,0,0,0,0,0, + 0,0,0,0,0,0,15,0,0,0,9,0,0,0,67,0, + 0,0,115,34,2,0,0,124,0,160,0,124,1,161,1,125, + 2,100,1,125,3,100,1,125,4,100,1,125,5,100,2,125, + 6,100,3,125,7,122,12,116,1,124,2,131,1,125,8,87, + 0,110,26,4,0,116,2,107,10,114,68,1,0,1,0,1, + 0,100,1,125,8,89,0,144,1,110,48,88,0,122,14,124, + 0,160,3,124,2,161,1,125,9,87,0,110,22,4,0,116, + 4,107,10,114,106,1,0,1,0,1,0,89,0,144,1,110, + 10,88,0,116,5,124,9,100,4,25,0,131,1,125,3,122, + 14,124,0,160,6,124,8,161,1,125,10,87,0,110,20,4, + 0,116,4,107,10,114,154,1,0,1,0,1,0,89,0,110, + 218,88,0,124,1,124,8,100,5,156,2,125,11,122,148,116, + 7,124,10,124,1,124,11,131,3,125,12,116,8,124,10,131, + 1,100,6,100,1,133,2,25,0,125,13,124,12,100,7,64, + 0,100,8,107,3,125,6,124,6,144,1,114,36,124,12,100, + 9,64,0,100,8,107,3,125,7,116,9,106,10,100,10,107, + 3,144,1,114,56,124,7,115,254,116,9,106,10,100,11,107, + 2,144,1,114,56,124,0,160,6,124,2,161,1,125,4,116, + 9,160,11,116,12,124,4,161,2,125,5,116,13,124,10,124, + 5,124,1,124,11,131,4,1,0,110,20,116,14,124,10,124, + 3,124,9,100,12,25,0,124,1,124,11,131,5,1,0,87, + 0,110,26,4,0,116,15,116,16,102,2,107,10,144,1,114, + 84,1,0,1,0,1,0,89,0,110,32,88,0,116,17,160, + 18,100,13,124,8,124,2,161,3,1,0,116,19,124,13,124, + 1,124,8,124,2,100,14,141,4,83,0,124,4,100,1,107, + 8,144,1,114,136,124,0,160,6,124,2,161,1,125,4,124, + 0,160,20,124,4,124,2,161,2,125,14,116,17,160,18,100, + 15,124,2,161,2,1,0,116,21,106,22,144,2,115,30,124, + 8,100,1,107,9,144,2,114,30,124,3,100,1,107,9,144, + 2,114,30,124,6,144,1,114,228,124,5,100,1,107,8,144, + 1,114,214,116,9,160,11,124,4,161,1,125,5,116,23,124, + 14,124,5,124,7,131,3,125,10,110,16,116,24,124,14,124, + 3,116,25,124,4,131,1,131,3,125,10,122,18,124,0,160, + 26,124,2,124,8,124,10,161,3,1,0,87,0,110,22,4, + 0,116,2,107,10,144,2,114,28,1,0,1,0,1,0,89, + 0,110,2,88,0,124,14,83,0,41,16,122,190,67,111,110, + 99,114,101,116,101,32,105,109,112,108,101,109,101,110,116,97, + 116,105,111,110,32,111,102,32,73,110,115,112,101,99,116,76, + 111,97,100,101,114,46,103,101,116,95,99,111,100,101,46,10, + 10,32,32,32,32,32,32,32,32,82,101,97,100,105,110,103, + 32,111,102,32,98,121,116,101,99,111,100,101,32,114,101,113, + 117,105,114,101,115,32,112,97,116,104,95,115,116,97,116,115, + 32,116,111,32,98,101,32,105,109,112,108,101,109,101,110,116, + 101,100,46,32,84,111,32,119,114,105,116,101,10,32,32,32, + 32,32,32,32,32,98,121,116,101,99,111,100,101,44,32,115, + 101,116,95,100,97,116,97,32,109,117,115,116,32,97,108,115, + 111,32,98,101,32,105,109,112,108,101,109,101,110,116,101,100, + 46,10,10,32,32,32,32,32,32,32,32,78,70,84,114,169, + 0,0,0,114,159,0,0,0,114,145,0,0,0,114,39,0, + 0,0,114,73,0,0,0,114,28,0,0,0,90,5,110,101, + 118,101,114,90,6,97,108,119,97,121,115,218,4,115,105,122, + 101,122,13,123,125,32,109,97,116,99,104,101,115,32,123,125, + 41,3,114,117,0,0,0,114,107,0,0,0,114,108,0,0, + 0,122,19,99,111,100,101,32,111,98,106,101,99,116,32,102, + 114,111,109,32,123,125,41,27,114,179,0,0,0,114,98,0, + 0,0,114,82,0,0,0,114,224,0,0,0,114,50,0,0, + 0,114,17,0,0,0,114,227,0,0,0,114,152,0,0,0, + 218,10,109,101,109,111,114,121,118,105,101,119,114,163,0,0, + 0,90,21,99,104,101,99,107,95,104,97,115,104,95,98,97, + 115,101,100,95,112,121,99,115,114,157,0,0,0,218,17,95, + 82,65,87,95,77,65,71,73,67,95,78,85,77,66,69,82, + 114,158,0,0,0,114,156,0,0,0,114,118,0,0,0,114, + 150,0,0,0,114,134,0,0,0,114,149,0,0,0,114,165, + 0,0,0,114,233,0,0,0,114,8,0,0,0,218,19,100, + 111,110,116,95,119,114,105,116,101,95,98,121,116,101,99,111, + 100,101,114,171,0,0,0,114,170,0,0,0,114,22,0,0, + 0,114,226,0,0,0,41,15,114,119,0,0,0,114,139,0, + 0,0,114,108,0,0,0,114,154,0,0,0,114,174,0,0, + 0,114,157,0,0,0,90,10,104,97,115,104,95,98,97,115, + 101,100,90,12,99,104,101,99,107,95,115,111,117,114,99,101, + 114,107,0,0,0,218,2,115,116,114,26,0,0,0,114,151, + 0,0,0,114,83,0,0,0,90,10,98,121,116,101,115,95, + 100,97,116,97,90,11,99,111,100,101,95,111,98,106,101,99, + 116,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,213,0,0,0,76,3,0,0,115,152,0,0,0,0,7, + 10,1,4,1,4,1,4,1,4,1,4,1,2,1,12,1, + 14,1,12,2,2,1,14,1,14,1,8,2,12,1,2,1, + 14,1,14,1,6,3,2,1,2,254,6,4,2,1,12,1, + 16,1,12,1,6,1,12,1,12,1,2,255,2,2,8,254, + 4,3,10,1,4,1,2,1,2,254,4,4,8,1,2,255, + 6,3,2,1,2,1,2,1,6,1,2,1,2,251,8,7, + 20,1,6,2,8,1,2,255,4,2,6,1,2,1,2,254, + 6,3,10,1,10,1,12,1,12,1,18,1,6,255,4,2, + 6,1,10,1,10,1,14,2,6,1,6,255,4,2,2,1, + 18,1,16,1,6,1,122,21,83,111,117,114,99,101,76,111, + 97,100,101,114,46,103,101,116,95,99,111,100,101,78,41,10, + 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, + 223,0,0,0,114,224,0,0,0,114,226,0,0,0,114,225, + 0,0,0,114,229,0,0,0,114,233,0,0,0,114,213,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,221,0,0,0,17,3,0,0,115, + 14,0,0,0,8,2,8,8,8,14,8,10,8,7,8,10, + 14,8,114,221,0,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0, + 115,124,0,0,0,101,0,90,1,100,0,90,2,100,1,90, + 3,100,2,100,3,132,0,90,4,100,4,100,5,132,0,90, + 5,100,6,100,7,132,0,90,6,101,7,135,0,102,1,100, + 8,100,9,132,8,131,1,90,8,101,7,100,10,100,11,132, + 0,131,1,90,9,100,12,100,13,132,0,90,10,101,7,100, + 14,100,15,132,0,131,1,90,11,100,16,100,17,132,0,90, + 12,100,18,100,19,132,0,90,13,100,20,100,21,132,0,90, + 14,100,22,100,23,132,0,90,15,135,0,4,0,90,16,83, + 0,41,24,218,10,70,105,108,101,76,111,97,100,101,114,122, + 103,66,97,115,101,32,102,105,108,101,32,108,111,97,100,101, + 114,32,99,108,97,115,115,32,119,104,105,99,104,32,105,109, + 112,108,101,109,101,110,116,115,32,116,104,101,32,108,111,97, + 100,101,114,32,112,114,111,116,111,99,111,108,32,109,101,116, + 104,111,100,115,32,116,104,97,116,10,32,32,32,32,114,101, + 113,117,105,114,101,32,102,105,108,101,32,115,121,115,116,101, + 109,32,117,115,97,103,101,46,99,3,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,0, + 0,115,16,0,0,0,124,1,124,0,95,0,124,2,124,0, + 95,1,100,1,83,0,41,2,122,75,67,97,99,104,101,32, + 116,104,101,32,109,111,100,117,108,101,32,110,97,109,101,32, + 97,110,100,32,116,104,101,32,112,97,116,104,32,116,111,32, + 116,104,101,32,102,105,108,101,32,102,111,117,110,100,32,98, + 121,32,116,104,101,10,32,32,32,32,32,32,32,32,102,105, + 110,100,101,114,46,78,114,159,0,0,0,41,3,114,119,0, + 0,0,114,139,0,0,0,114,44,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,209,0,0,0, + 166,3,0,0,115,4,0,0,0,0,3,6,1,122,19,70, + 105,108,101,76,111,97,100,101,114,46,95,95,105,110,105,116, + 95,95,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,2,0,0,0,67,0,0,0,115,24,0,0,0, + 124,0,106,0,124,1,106,0,107,2,111,22,124,0,106,1, + 124,1,106,1,107,2,83,0,114,110,0,0,0,169,2,218, + 9,95,95,99,108,97,115,115,95,95,114,131,0,0,0,169, + 2,114,119,0,0,0,90,5,111,116,104,101,114,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,6,95,95, + 101,113,95,95,172,3,0,0,115,6,0,0,0,0,1,12, + 1,10,255,122,17,70,105,108,101,76,111,97,100,101,114,46, + 95,95,101,113,95,95,99,1,0,0,0,0,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 20,0,0,0,116,0,124,0,106,1,131,1,116,0,124,0, + 106,2,131,1,65,0,83,0,114,110,0,0,0,169,3,218, + 4,104,97,115,104,114,117,0,0,0,114,44,0,0,0,169, + 1,114,119,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,6,0,0,0,218,8,95,95,104,97,115,104,95,95,176, + 3,0,0,115,2,0,0,0,0,1,122,19,70,105,108,101, + 76,111,97,100,101,114,46,95,95,104,97,115,104,95,95,99, 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 1,0,0,0,67,0,0,0,115,6,0,0,0,124,0,106, - 0,83,0,169,1,122,58,82,101,116,117,114,110,32,116,104, - 101,32,112,97,116,104,32,116,111,32,116,104,101,32,115,111, - 117,114,99,101,32,102,105,108,101,32,97,115,32,102,111,117, - 110,100,32,98,121,32,116,104,101,32,102,105,110,100,101,114, - 46,114,48,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,179,0,0,0,191, - 3,0,0,115,2,0,0,0,0,3,122,23,70,105,108,101, - 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, - 97,109,101,99,2,0,0,0,0,0,0,0,0,0,0,0, - 3,0,0,0,10,0,0,0,67,0,0,0,115,102,0,0, - 0,116,0,124,0,116,1,116,2,102,2,131,2,114,58,116, - 3,160,4,116,5,124,1,131,1,161,1,143,22,125,2,124, - 2,160,6,161,0,87,0,2,0,53,0,81,0,82,0,163, - 0,83,0,81,0,82,0,88,0,110,40,116,3,160,7,124, - 1,100,1,161,2,143,22,125,2,124,2,160,6,161,0,87, - 0,2,0,53,0,81,0,82,0,163,0,83,0,81,0,82, - 0,88,0,100,2,83,0,41,3,122,39,82,101,116,117,114, - 110,32,116,104,101,32,100,97,116,97,32,102,114,111,109,32, - 112,97,116,104,32,97,115,32,114,97,119,32,98,121,116,101, - 115,46,218,1,114,78,41,8,114,161,0,0,0,114,221,0, - 0,0,218,19,69,120,116,101,110,115,105,111,110,70,105,108, - 101,76,111,97,100,101,114,114,64,0,0,0,90,9,111,112, - 101,110,95,99,111,100,101,114,85,0,0,0,90,4,114,101, - 97,100,114,65,0,0,0,41,3,114,119,0,0,0,114,44, - 0,0,0,114,68,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,227,0,0,0,196,3,0,0, - 115,10,0,0,0,0,2,14,1,16,1,28,2,14,1,122, - 19,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, - 100,97,116,97,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,3,0,0,0,67,0,0,0,115,18,0, - 0,0,124,0,160,0,124,1,161,1,114,14,124,0,83,0, - 100,0,83,0,114,110,0,0,0,41,1,114,182,0,0,0, - 169,2,114,119,0,0,0,114,216,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,218,19,103,101,116, - 95,114,101,115,111,117,114,99,101,95,114,101,97,100,101,114, - 207,3,0,0,115,6,0,0,0,0,2,10,1,4,1,122, - 30,70,105,108,101,76,111,97,100,101,114,46,103,101,116,95, - 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,99, - 2,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, - 4,0,0,0,67,0,0,0,115,32,0,0,0,116,0,116, - 1,124,0,106,2,131,1,100,1,25,0,124,1,131,2,125, - 2,116,3,160,4,124,2,100,2,161,2,83,0,41,3,78, - 114,73,0,0,0,114,251,0,0,0,41,5,114,38,0,0, - 0,114,47,0,0,0,114,44,0,0,0,114,64,0,0,0, - 114,65,0,0,0,169,3,114,119,0,0,0,90,8,114,101, - 115,111,117,114,99,101,114,44,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,13,111,112,101,110, - 95,114,101,115,111,117,114,99,101,213,3,0,0,115,4,0, - 0,0,0,1,20,1,122,24,70,105,108,101,76,111,97,100, - 101,114,46,111,112,101,110,95,114,101,115,111,117,114,99,101, - 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,3,0,0,0,67,0,0,0,115,38,0,0,0,124,0, - 160,0,124,1,161,1,115,14,116,1,130,1,116,2,116,3, - 124,0,106,4,131,1,100,1,25,0,124,1,131,2,125,2, - 124,2,83,0,169,2,78,114,73,0,0,0,41,5,218,11, - 105,115,95,114,101,115,111,117,114,99,101,218,17,70,105,108, - 101,78,111,116,70,111,117,110,100,69,114,114,111,114,114,38, - 0,0,0,114,47,0,0,0,114,44,0,0,0,114,255,0, + 3,0,0,0,3,0,0,0,115,16,0,0,0,116,0,116, + 1,124,0,131,2,160,2,124,1,161,1,83,0,41,1,122, + 100,76,111,97,100,32,97,32,109,111,100,117,108,101,32,102, + 114,111,109,32,97,32,102,105,108,101,46,10,10,32,32,32, + 32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,100, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,32, + 32,85,115,101,32,101,120,101,99,95,109,111,100,117,108,101, + 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, + 32,32,32,32,32,41,3,218,5,115,117,112,101,114,114,239, + 0,0,0,114,220,0,0,0,114,219,0,0,0,169,1,114, + 241,0,0,0,114,3,0,0,0,114,6,0,0,0,114,220, + 0,0,0,179,3,0,0,115,2,0,0,0,0,10,122,22, + 70,105,108,101,76,111,97,100,101,114,46,108,111,97,100,95, + 109,111,100,117,108,101,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, + 6,0,0,0,124,0,106,0,83,0,169,1,122,58,82,101, + 116,117,114,110,32,116,104,101,32,112,97,116,104,32,116,111, + 32,116,104,101,32,115,111,117,114,99,101,32,102,105,108,101, + 32,97,115,32,102,111,117,110,100,32,98,121,32,116,104,101, + 32,102,105,110,100,101,114,46,114,48,0,0,0,114,219,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,13,114,101,115,111,117,114,99,101,95,112,97,116,104, - 217,3,0,0,115,8,0,0,0,0,1,10,1,4,1,20, - 1,122,24,70,105,108,101,76,111,97,100,101,114,46,114,101, - 115,111,117,114,99,101,95,112,97,116,104,99,2,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,40,0,0,0,116,0,124,1,107,6,114, - 12,100,1,83,0,116,1,116,2,124,0,106,3,131,1,100, - 2,25,0,124,1,131,2,125,2,116,4,124,2,131,1,83, - 0,41,3,78,70,114,73,0,0,0,41,5,114,35,0,0, - 0,114,38,0,0,0,114,47,0,0,0,114,44,0,0,0, - 114,54,0,0,0,169,3,114,119,0,0,0,114,117,0,0, - 0,114,44,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,2,1,0,0,223,3,0,0,115,8, - 0,0,0,0,1,8,1,4,1,20,1,122,22,70,105,108, - 101,76,111,97,100,101,114,46,105,115,95,114,101,115,111,117, - 114,99,101,99,1,0,0,0,0,0,0,0,0,0,0,0, - 1,0,0,0,5,0,0,0,67,0,0,0,115,24,0,0, - 0,116,0,116,1,160,2,116,3,124,0,106,4,131,1,100, - 1,25,0,161,1,131,1,83,0,114,1,1,0,0,41,5, - 218,4,105,116,101,114,114,2,0,0,0,218,7,108,105,115, - 116,100,105,114,114,47,0,0,0,114,44,0,0,0,114,246, + 0,114,179,0,0,0,191,3,0,0,115,2,0,0,0,0, + 3,122,23,70,105,108,101,76,111,97,100,101,114,46,103,101, + 116,95,102,105,108,101,110,97,109,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,10,0,0,0,67, + 0,0,0,115,102,0,0,0,116,0,124,0,116,1,116,2, + 102,2,131,2,114,58,116,3,160,4,116,5,124,1,131,1, + 161,1,143,22,125,2,124,2,160,6,161,0,87,0,2,0, + 53,0,81,0,82,0,163,0,83,0,81,0,82,0,88,0, + 110,40,116,3,160,7,124,1,100,1,161,2,143,22,125,2, + 124,2,160,6,161,0,87,0,2,0,53,0,81,0,82,0, + 163,0,83,0,81,0,82,0,88,0,100,2,83,0,41,3, + 122,39,82,101,116,117,114,110,32,116,104,101,32,100,97,116, + 97,32,102,114,111,109,32,112,97,116,104,32,97,115,32,114, + 97,119,32,98,121,116,101,115,46,218,1,114,78,41,8,114, + 161,0,0,0,114,221,0,0,0,218,19,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,114,64, + 0,0,0,90,9,111,112,101,110,95,99,111,100,101,114,85, + 0,0,0,90,4,114,101,97,100,114,65,0,0,0,41,3, + 114,119,0,0,0,114,44,0,0,0,114,68,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,227, + 0,0,0,196,3,0,0,115,10,0,0,0,0,2,14,1, + 16,1,28,2,14,1,122,19,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,100,97,116,97,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 67,0,0,0,115,18,0,0,0,124,0,160,0,124,1,161, + 1,114,14,124,0,83,0,100,0,83,0,114,110,0,0,0, + 41,1,114,182,0,0,0,169,2,114,119,0,0,0,114,216, 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, - 0,0,218,8,99,111,110,116,101,110,116,115,229,3,0,0, - 115,2,0,0,0,0,1,122,19,70,105,108,101,76,111,97, - 100,101,114,46,99,111,110,116,101,110,116,115,41,17,114,125, - 0,0,0,114,124,0,0,0,114,126,0,0,0,114,127,0, - 0,0,114,209,0,0,0,114,243,0,0,0,114,247,0,0, - 0,114,136,0,0,0,114,220,0,0,0,114,179,0,0,0, - 114,227,0,0,0,114,254,0,0,0,114,0,1,0,0,114, - 4,1,0,0,114,2,1,0,0,114,8,1,0,0,90,13, - 95,95,99,108,97,115,115,99,101,108,108,95,95,114,3,0, - 0,0,114,3,0,0,0,114,249,0,0,0,114,6,0,0, - 0,114,239,0,0,0,161,3,0,0,115,30,0,0,0,8, - 2,4,3,8,6,8,4,8,3,2,1,14,11,2,1,10, - 4,8,11,2,1,10,5,8,4,8,6,8,6,114,239,0, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,64,0,0,0,115,46,0,0,0, - 101,0,90,1,100,0,90,2,100,1,90,3,100,2,100,3, - 132,0,90,4,100,4,100,5,132,0,90,5,100,6,100,7, - 156,1,100,8,100,9,132,2,90,6,100,10,83,0,41,11, - 218,16,83,111,117,114,99,101,70,105,108,101,76,111,97,100, - 101,114,122,62,67,111,110,99,114,101,116,101,32,105,109,112, - 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,83, - 111,117,114,99,101,76,111,97,100,101,114,32,117,115,105,110, - 103,32,116,104,101,32,102,105,108,101,32,115,121,115,116,101, - 109,46,99,2,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,3,0,0,0,67,0,0,0,115,22,0,0,0, - 116,0,124,1,131,1,125,2,124,2,106,1,124,2,106,2, - 100,1,156,2,83,0,41,2,122,33,82,101,116,117,114,110, - 32,116,104,101,32,109,101,116,97,100,97,116,97,32,102,111, - 114,32,116,104,101,32,112,97,116,104,46,41,2,114,169,0, - 0,0,114,234,0,0,0,41,3,114,49,0,0,0,218,8, - 115,116,95,109,116,105,109,101,90,7,115,116,95,115,105,122, - 101,41,3,114,119,0,0,0,114,44,0,0,0,114,238,0, + 0,0,218,19,103,101,116,95,114,101,115,111,117,114,99,101, + 95,114,101,97,100,101,114,207,3,0,0,115,6,0,0,0, + 0,2,10,1,4,1,122,30,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,114,101,115,111,117,114,99,101,95, + 114,101,97,100,101,114,99,2,0,0,0,0,0,0,0,0, + 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, + 32,0,0,0,116,0,116,1,124,0,106,2,131,1,100,1, + 25,0,124,1,131,2,125,2,116,3,160,4,124,2,100,2, + 161,2,83,0,41,3,78,114,73,0,0,0,114,251,0,0, + 0,41,5,114,38,0,0,0,114,47,0,0,0,114,44,0, + 0,0,114,64,0,0,0,114,65,0,0,0,169,3,114,119, + 0,0,0,90,8,114,101,115,111,117,114,99,101,114,44,0, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,224,0,0,0,237,3,0,0,115,4,0,0,0,0, - 2,8,1,122,27,83,111,117,114,99,101,70,105,108,101,76, - 111,97,100,101,114,46,112,97,116,104,95,115,116,97,116,115, - 99,4,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,5,0,0,0,67,0,0,0,115,24,0,0,0,116,0, - 124,1,131,1,125,4,124,0,106,1,124,2,124,3,124,4, - 100,1,141,3,83,0,41,2,78,169,1,218,5,95,109,111, - 100,101,41,2,114,115,0,0,0,114,225,0,0,0,41,5, - 114,119,0,0,0,114,108,0,0,0,114,107,0,0,0,114, - 26,0,0,0,114,52,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,226,0,0,0,242,3,0, - 0,115,4,0,0,0,0,2,8,1,122,32,83,111,117,114, - 99,101,70,105,108,101,76,111,97,100,101,114,46,95,99,97, - 99,104,101,95,98,121,116,101,99,111,100,101,114,60,0,0, - 0,114,11,1,0,0,99,3,0,0,0,0,0,0,0,1, - 0,0,0,9,0,0,0,11,0,0,0,67,0,0,0,115, - 0,1,0,0,116,0,124,1,131,1,92,2,125,4,125,5, - 103,0,125,6,124,4,114,52,116,1,124,4,131,1,115,52, - 116,0,124,4,131,1,92,2,125,4,125,7,124,6,160,2, - 124,7,161,1,1,0,113,16,116,3,124,6,131,1,68,0, - 93,112,125,7,116,4,124,4,124,7,131,2,125,4,122,14, - 116,5,160,6,124,4,161,1,1,0,87,0,110,82,4,0, - 116,7,107,10,114,112,1,0,1,0,1,0,89,0,113,60, - 89,0,110,60,4,0,116,8,107,10,114,170,1,0,125,8, - 1,0,122,30,116,9,160,10,100,1,124,4,124,8,161,3, - 1,0,87,0,89,0,162,10,1,0,100,2,83,0,87,0, - 53,0,100,2,125,8,126,8,88,0,89,0,110,2,88,0, - 113,60,122,28,116,11,124,1,124,2,124,3,131,3,1,0, - 116,9,160,10,100,3,124,1,161,2,1,0,87,0,110,48, - 4,0,116,8,107,10,114,250,1,0,125,8,1,0,122,18, - 116,9,160,10,100,1,124,1,124,8,161,3,1,0,87,0, - 53,0,100,2,125,8,126,8,88,0,89,0,110,2,88,0, - 100,2,83,0,41,4,122,27,87,114,105,116,101,32,98,121, - 116,101,115,32,100,97,116,97,32,116,111,32,97,32,102,105, - 108,101,46,122,27,99,111,117,108,100,32,110,111,116,32,99, - 114,101,97,116,101,32,123,33,114,125,58,32,123,33,114,125, - 78,122,12,99,114,101,97,116,101,100,32,123,33,114,125,41, - 12,114,47,0,0,0,114,56,0,0,0,114,186,0,0,0, - 114,42,0,0,0,114,38,0,0,0,114,2,0,0,0,90, - 5,109,107,100,105,114,218,15,70,105,108,101,69,120,105,115, - 116,115,69,114,114,111,114,114,50,0,0,0,114,134,0,0, - 0,114,149,0,0,0,114,69,0,0,0,41,9,114,119,0, - 0,0,114,44,0,0,0,114,26,0,0,0,114,12,1,0, - 0,218,6,112,97,114,101,110,116,114,97,0,0,0,114,37, - 0,0,0,114,33,0,0,0,114,228,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,225,0,0, - 0,247,3,0,0,115,48,0,0,0,0,2,12,1,4,2, - 12,1,12,1,12,2,12,1,10,1,2,1,14,1,14,2, - 8,1,16,3,6,1,2,0,2,255,4,2,32,1,2,1, - 12,1,16,1,16,2,8,1,2,255,122,25,83,111,117,114, - 99,101,70,105,108,101,76,111,97,100,101,114,46,115,101,116, - 95,100,97,116,97,78,41,7,114,125,0,0,0,114,124,0, - 0,0,114,126,0,0,0,114,127,0,0,0,114,224,0,0, - 0,114,226,0,0,0,114,225,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 9,1,0,0,233,3,0,0,115,8,0,0,0,8,2,4, - 2,8,5,8,5,114,9,1,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, - 0,0,0,115,32,0,0,0,101,0,90,1,100,0,90,2, - 100,1,90,3,100,2,100,3,132,0,90,4,100,4,100,5, - 132,0,90,5,100,6,83,0,41,7,218,20,83,111,117,114, - 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, - 122,45,76,111,97,100,101,114,32,119,104,105,99,104,32,104, - 97,110,100,108,101,115,32,115,111,117,114,99,101,108,101,115, - 115,32,102,105,108,101,32,105,109,112,111,114,116,115,46,99, - 2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 5,0,0,0,67,0,0,0,115,68,0,0,0,124,0,160, - 0,124,1,161,1,125,2,124,0,160,1,124,2,161,1,125, - 3,124,1,124,2,100,1,156,2,125,4,116,2,124,3,124, - 1,124,4,131,3,1,0,116,3,116,4,124,3,131,1,100, - 2,100,0,133,2,25,0,124,1,124,2,100,3,141,3,83, - 0,41,4,78,114,159,0,0,0,114,145,0,0,0,41,2, - 114,117,0,0,0,114,107,0,0,0,41,5,114,179,0,0, - 0,114,227,0,0,0,114,152,0,0,0,114,165,0,0,0, - 114,235,0,0,0,41,5,114,119,0,0,0,114,139,0,0, - 0,114,44,0,0,0,114,26,0,0,0,114,151,0,0,0, + 0,218,13,111,112,101,110,95,114,101,115,111,117,114,99,101, + 213,3,0,0,115,4,0,0,0,0,1,20,1,122,24,70, + 105,108,101,76,111,97,100,101,114,46,111,112,101,110,95,114, + 101,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, + 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, + 115,38,0,0,0,124,0,160,0,124,1,161,1,115,14,116, + 1,130,1,116,2,116,3,124,0,106,4,131,1,100,1,25, + 0,124,1,131,2,125,2,124,2,83,0,169,2,78,114,73, + 0,0,0,41,5,218,11,105,115,95,114,101,115,111,117,114, + 99,101,218,17,70,105,108,101,78,111,116,70,111,117,110,100, + 69,114,114,111,114,114,38,0,0,0,114,47,0,0,0,114, + 44,0,0,0,114,255,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,13,114,101,115,111,117,114, + 99,101,95,112,97,116,104,217,3,0,0,115,8,0,0,0, + 0,1,10,1,4,1,20,1,122,24,70,105,108,101,76,111, + 97,100,101,114,46,114,101,115,111,117,114,99,101,95,112,97, + 116,104,99,2,0,0,0,0,0,0,0,0,0,0,0,3, + 0,0,0,3,0,0,0,67,0,0,0,115,40,0,0,0, + 116,0,124,1,107,6,114,12,100,1,83,0,116,1,116,2, + 124,0,106,3,131,1,100,2,25,0,124,1,131,2,125,2, + 116,4,124,2,131,1,83,0,41,3,78,70,114,73,0,0, + 0,41,5,114,35,0,0,0,114,38,0,0,0,114,47,0, + 0,0,114,44,0,0,0,114,54,0,0,0,169,3,114,119, + 0,0,0,114,117,0,0,0,114,44,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,2,1,0, + 0,223,3,0,0,115,8,0,0,0,0,1,8,1,4,1, + 20,1,122,22,70,105,108,101,76,111,97,100,101,114,46,105, + 115,95,114,101,115,111,117,114,99,101,99,1,0,0,0,0, + 0,0,0,0,0,0,0,1,0,0,0,5,0,0,0,67, + 0,0,0,115,24,0,0,0,116,0,116,1,160,2,116,3, + 124,0,106,4,131,1,100,1,25,0,161,1,131,1,83,0, + 114,1,1,0,0,41,5,218,4,105,116,101,114,114,2,0, + 0,0,218,7,108,105,115,116,100,105,114,114,47,0,0,0, + 114,44,0,0,0,114,246,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,218,8,99,111,110,116,101, + 110,116,115,229,3,0,0,115,2,0,0,0,0,1,122,19, + 70,105,108,101,76,111,97,100,101,114,46,99,111,110,116,101, + 110,116,115,41,17,114,125,0,0,0,114,124,0,0,0,114, + 126,0,0,0,114,127,0,0,0,114,209,0,0,0,114,243, + 0,0,0,114,247,0,0,0,114,136,0,0,0,114,220,0, + 0,0,114,179,0,0,0,114,227,0,0,0,114,254,0,0, + 0,114,0,1,0,0,114,4,1,0,0,114,2,1,0,0, + 114,8,1,0,0,90,13,95,95,99,108,97,115,115,99,101, + 108,108,95,95,114,3,0,0,0,114,3,0,0,0,114,249, + 0,0,0,114,6,0,0,0,114,239,0,0,0,161,3,0, + 0,115,30,0,0,0,8,2,4,3,8,6,8,4,8,3, + 2,1,14,11,2,1,10,4,8,11,2,1,10,5,8,4, + 8,6,8,6,114,239,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,64,0, + 0,0,115,46,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,100,2,100,3,132,0,90,4,100,4,100,5,132, + 0,90,5,100,6,100,7,156,1,100,8,100,9,132,2,90, + 6,100,10,83,0,41,11,218,16,83,111,117,114,99,101,70, + 105,108,101,76,111,97,100,101,114,122,62,67,111,110,99,114, + 101,116,101,32,105,109,112,108,101,109,101,110,116,97,116,105, + 111,110,32,111,102,32,83,111,117,114,99,101,76,111,97,100, + 101,114,32,117,115,105,110,103,32,116,104,101,32,102,105,108, + 101,32,115,121,115,116,101,109,46,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,3,0,0,0,67,0, + 0,0,115,22,0,0,0,116,0,124,1,131,1,125,2,124, + 2,106,1,124,2,106,2,100,1,156,2,83,0,41,2,122, + 33,82,101,116,117,114,110,32,116,104,101,32,109,101,116,97, + 100,97,116,97,32,102,111,114,32,116,104,101,32,112,97,116, + 104,46,41,2,114,169,0,0,0,114,234,0,0,0,41,3, + 114,49,0,0,0,218,8,115,116,95,109,116,105,109,101,90, + 7,115,116,95,115,105,122,101,41,3,114,119,0,0,0,114, + 44,0,0,0,114,238,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,224,0,0,0,237,3,0, + 0,115,4,0,0,0,0,2,8,1,122,27,83,111,117,114, + 99,101,70,105,108,101,76,111,97,100,101,114,46,112,97,116, + 104,95,115,116,97,116,115,99,4,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, + 115,24,0,0,0,116,0,124,1,131,1,125,4,124,0,106, + 1,124,2,124,3,124,4,100,1,141,3,83,0,41,2,78, + 169,1,218,5,95,109,111,100,101,41,2,114,115,0,0,0, + 114,225,0,0,0,41,5,114,119,0,0,0,114,108,0,0, + 0,114,107,0,0,0,114,26,0,0,0,114,52,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 213,0,0,0,26,4,0,0,115,22,0,0,0,0,1,10, - 1,10,4,2,1,2,254,6,4,12,1,2,1,14,1,2, - 1,2,253,122,29,83,111,117,114,99,101,108,101,115,115,70, - 105,108,101,76,111,97,100,101,114,46,103,101,116,95,99,111, - 100,101,99,2,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,1,0,0,0,67,0,0,0,115,4,0,0,0, - 100,1,83,0,41,2,122,39,82,101,116,117,114,110,32,78, - 111,110,101,32,97,115,32,116,104,101,114,101,32,105,115,32, - 110,111,32,115,111,117,114,99,101,32,99,111,100,101,46,78, - 114,3,0,0,0,114,219,0,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,229,0,0,0,42,4, - 0,0,115,2,0,0,0,0,2,122,31,83,111,117,114,99, - 101,108,101,115,115,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,115,111,117,114,99,101,78,41,6,114,125,0, - 0,0,114,124,0,0,0,114,126,0,0,0,114,127,0,0, - 0,114,213,0,0,0,114,229,0,0,0,114,3,0,0,0, + 226,0,0,0,242,3,0,0,115,4,0,0,0,0,2,8, + 1,122,32,83,111,117,114,99,101,70,105,108,101,76,111,97, + 100,101,114,46,95,99,97,99,104,101,95,98,121,116,101,99, + 111,100,101,114,60,0,0,0,114,11,1,0,0,99,3,0, + 0,0,0,0,0,0,1,0,0,0,9,0,0,0,11,0, + 0,0,67,0,0,0,115,252,0,0,0,116,0,124,1,131, + 1,92,2,125,4,125,5,103,0,125,6,124,4,114,52,116, + 1,124,4,131,1,115,52,116,0,124,4,131,1,92,2,125, + 4,125,7,124,6,160,2,124,7,161,1,1,0,113,16,116, + 3,124,6,131,1,68,0,93,108,125,7,116,4,124,4,124, + 7,131,2,125,4,122,14,116,5,160,6,124,4,161,1,1, + 0,87,0,113,60,4,0,116,7,107,10,114,112,1,0,1, + 0,1,0,89,0,113,60,89,0,113,60,4,0,116,8,107, + 10,114,166,1,0,125,8,1,0,122,26,116,9,160,10,100, + 1,124,4,124,8,161,3,1,0,87,0,89,0,162,6,1, + 0,100,2,83,0,100,2,125,8,126,8,88,0,89,0,113, + 60,88,0,113,60,122,28,116,11,124,1,124,2,124,3,131, + 3,1,0,116,9,160,10,100,3,124,1,161,2,1,0,87, + 0,110,48,4,0,116,8,107,10,114,246,1,0,125,8,1, + 0,122,18,116,9,160,10,100,1,124,1,124,8,161,3,1, + 0,87,0,53,0,100,2,125,8,126,8,88,0,89,0,110, + 2,88,0,100,2,83,0,41,4,122,27,87,114,105,116,101, + 32,98,121,116,101,115,32,100,97,116,97,32,116,111,32,97, + 32,102,105,108,101,46,122,27,99,111,117,108,100,32,110,111, + 116,32,99,114,101,97,116,101,32,123,33,114,125,58,32,123, + 33,114,125,78,122,12,99,114,101,97,116,101,100,32,123,33, + 114,125,41,12,114,47,0,0,0,114,56,0,0,0,114,186, + 0,0,0,114,42,0,0,0,114,38,0,0,0,114,2,0, + 0,0,90,5,109,107,100,105,114,218,15,70,105,108,101,69, + 120,105,115,116,115,69,114,114,111,114,114,50,0,0,0,114, + 134,0,0,0,114,149,0,0,0,114,69,0,0,0,41,9, + 114,119,0,0,0,114,44,0,0,0,114,26,0,0,0,114, + 12,1,0,0,218,6,112,97,114,101,110,116,114,97,0,0, + 0,114,37,0,0,0,114,33,0,0,0,114,228,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, - 15,1,0,0,22,4,0,0,115,6,0,0,0,8,2,4, - 2,8,16,114,15,1,0,0,99,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,92,0,0,0,101,0,90,1,100,0,90,2,100,1, - 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, - 90,5,100,6,100,7,132,0,90,6,100,8,100,9,132,0, - 90,7,100,10,100,11,132,0,90,8,100,12,100,13,132,0, - 90,9,100,14,100,15,132,0,90,10,100,16,100,17,132,0, - 90,11,101,12,100,18,100,19,132,0,131,1,90,13,100,20, - 83,0,41,21,114,252,0,0,0,122,93,76,111,97,100,101, - 114,32,102,111,114,32,101,120,116,101,110,115,105,111,110,32, - 109,111,100,117,108,101,115,46,10,10,32,32,32,32,84,104, - 101,32,99,111,110,115,116,114,117,99,116,111,114,32,105,115, - 32,100,101,115,105,103,110,101,100,32,116,111,32,119,111,114, - 107,32,119,105,116,104,32,70,105,108,101,70,105,110,100,101, - 114,46,10,10,32,32,32,32,99,3,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,2,0,0,0,67,0,0, - 0,115,16,0,0,0,124,1,124,0,95,0,124,2,124,0, - 95,1,100,0,83,0,114,110,0,0,0,114,159,0,0,0, - 114,5,1,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,209,0,0,0,59,4,0,0,115,4,0, - 0,0,0,1,6,1,122,28,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,95,95,105,110, - 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,24,0, - 0,0,124,0,106,0,124,1,106,0,107,2,111,22,124,0, - 106,1,124,1,106,1,107,2,83,0,114,110,0,0,0,114, - 240,0,0,0,114,242,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,243,0,0,0,63,4,0, - 0,115,6,0,0,0,0,1,12,1,10,255,122,26,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,95,95,101,113,95,95,99,1,0,0,0,0,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,20,0,0,0,116,0,124,0,106,1,131,1,116,0, - 124,0,106,2,131,1,65,0,83,0,114,110,0,0,0,114, - 244,0,0,0,114,246,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,247,0,0,0,67,4,0, - 0,115,2,0,0,0,0,1,122,28,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,95,95, - 104,97,115,104,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,5,0,0,0,67,0,0,0,115, - 36,0,0,0,116,0,160,1,116,2,106,3,124,1,161,2, - 125,2,116,0,160,4,100,1,124,1,106,5,124,0,106,6, - 161,3,1,0,124,2,83,0,41,2,122,38,67,114,101,97, - 116,101,32,97,110,32,117,110,105,116,105,97,108,105,122,101, - 100,32,101,120,116,101,110,115,105,111,110,32,109,111,100,117, - 108,101,122,38,101,120,116,101,110,115,105,111,110,32,109,111, - 100,117,108,101,32,123,33,114,125,32,108,111,97,100,101,100, - 32,102,114,111,109,32,123,33,114,125,41,7,114,134,0,0, - 0,114,214,0,0,0,114,163,0,0,0,90,14,99,114,101, - 97,116,101,95,100,121,110,97,109,105,99,114,149,0,0,0, - 114,117,0,0,0,114,44,0,0,0,41,3,114,119,0,0, - 0,114,187,0,0,0,114,216,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,212,0,0,0,70, - 4,0,0,115,18,0,0,0,0,2,4,1,4,0,2,255, - 4,2,6,1,4,0,4,255,4,2,122,33,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 99,114,101,97,116,101,95,109,111,100,117,108,101,99,2,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,5,0, - 0,0,67,0,0,0,115,36,0,0,0,116,0,160,1,116, - 2,106,3,124,1,161,2,1,0,116,0,160,4,100,1,124, - 0,106,5,124,0,106,6,161,3,1,0,100,2,83,0,41, - 3,122,30,73,110,105,116,105,97,108,105,122,101,32,97,110, - 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, - 101,122,40,101,120,116,101,110,115,105,111,110,32,109,111,100, - 117,108,101,32,123,33,114,125,32,101,120,101,99,117,116,101, - 100,32,102,114,111,109,32,123,33,114,125,78,41,7,114,134, - 0,0,0,114,214,0,0,0,114,163,0,0,0,90,12,101, - 120,101,99,95,100,121,110,97,109,105,99,114,149,0,0,0, - 114,117,0,0,0,114,44,0,0,0,114,253,0,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,217, - 0,0,0,78,4,0,0,115,10,0,0,0,0,2,14,1, - 6,1,4,0,4,255,122,31,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,101,120,101,99, - 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,4,0,0,0,3,0,0,0, - 115,36,0,0,0,116,0,124,0,106,1,131,1,100,1,25, - 0,137,0,116,2,135,0,102,1,100,2,100,3,132,8,116, - 3,68,0,131,1,131,1,83,0,41,4,122,49,82,101,116, - 117,114,110,32,84,114,117,101,32,105,102,32,116,104,101,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 32,105,115,32,97,32,112,97,99,107,97,103,101,46,114,39, - 0,0,0,99,1,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,51,0,0,0,115,26,0,0, - 0,124,0,93,18,125,1,136,0,100,0,124,1,23,0,107, - 2,86,0,1,0,113,2,100,1,83,0,41,2,114,209,0, - 0,0,78,114,3,0,0,0,169,2,114,32,0,0,0,218, - 6,115,117,102,102,105,120,169,1,90,9,102,105,108,101,95, - 110,97,109,101,114,3,0,0,0,114,6,0,0,0,218,9, - 60,103,101,110,101,120,112,114,62,87,4,0,0,115,4,0, - 0,0,4,1,2,255,122,49,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,105,115,95,112, - 97,99,107,97,103,101,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,41,4,114,47,0,0,0, - 114,44,0,0,0,218,3,97,110,121,218,18,69,88,84,69, - 78,83,73,79,78,95,83,85,70,70,73,88,69,83,114,219, - 0,0,0,114,3,0,0,0,114,18,1,0,0,114,6,0, - 0,0,114,182,0,0,0,84,4,0,0,115,8,0,0,0, - 0,2,14,1,12,1,2,255,122,30,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,105,115, - 95,112,97,99,107,97,103,101,99,2,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, - 0,115,4,0,0,0,100,1,83,0,41,2,122,63,82,101, - 116,117,114,110,32,78,111,110,101,32,97,115,32,97,110,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 32,99,97,110,110,111,116,32,99,114,101,97,116,101,32,97, - 32,99,111,100,101,32,111,98,106,101,99,116,46,78,114,3, - 0,0,0,114,219,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,213,0,0,0,90,4,0,0, - 115,2,0,0,0,0,2,122,28,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, + 225,0,0,0,247,3,0,0,115,48,0,0,0,0,2,12, + 1,4,2,12,1,12,1,12,2,12,1,10,1,2,1,14, + 1,14,2,8,1,16,3,6,1,2,0,2,255,4,2,28, + 1,2,1,12,1,16,1,16,2,8,1,2,255,122,25,83, + 111,117,114,99,101,70,105,108,101,76,111,97,100,101,114,46, + 115,101,116,95,100,97,116,97,78,41,7,114,125,0,0,0, + 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, + 224,0,0,0,114,226,0,0,0,114,225,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,9,1,0,0,233,3,0,0,115,8,0,0,0, + 8,2,4,2,8,5,8,5,114,9,1,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,64,0,0,0,115,32,0,0,0,101,0,90,1,100, + 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, + 4,100,5,132,0,90,5,100,6,83,0,41,7,218,20,83, + 111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,97, + 100,101,114,122,45,76,111,97,100,101,114,32,119,104,105,99, + 104,32,104,97,110,100,108,101,115,32,115,111,117,114,99,101, + 108,101,115,115,32,102,105,108,101,32,105,109,112,111,114,116, + 115,46,99,2,0,0,0,0,0,0,0,0,0,0,0,5, + 0,0,0,5,0,0,0,67,0,0,0,115,68,0,0,0, + 124,0,160,0,124,1,161,1,125,2,124,0,160,1,124,2, + 161,1,125,3,124,1,124,2,100,1,156,2,125,4,116,2, + 124,3,124,1,124,4,131,3,1,0,116,3,116,4,124,3, + 131,1,100,2,100,0,133,2,25,0,124,1,124,2,100,3, + 141,3,83,0,41,4,78,114,159,0,0,0,114,145,0,0, + 0,41,2,114,117,0,0,0,114,107,0,0,0,41,5,114, + 179,0,0,0,114,227,0,0,0,114,152,0,0,0,114,165, + 0,0,0,114,235,0,0,0,41,5,114,119,0,0,0,114, + 139,0,0,0,114,44,0,0,0,114,26,0,0,0,114,151, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,213,0,0,0,26,4,0,0,115,22,0,0,0, + 0,1,10,1,10,4,2,1,2,254,6,4,12,1,2,1, + 14,1,2,1,2,253,122,29,83,111,117,114,99,101,108,101, + 115,115,70,105,108,101,76,111,97,100,101,114,46,103,101,116, 95,99,111,100,101,99,2,0,0,0,0,0,0,0,0,0, 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, - 0,0,0,100,1,83,0,41,2,122,53,82,101,116,117,114, - 110,32,78,111,110,101,32,97,115,32,101,120,116,101,110,115, - 105,111,110,32,109,111,100,117,108,101,115,32,104,97,118,101, - 32,110,111,32,115,111,117,114,99,101,32,99,111,100,101,46, + 0,0,0,100,1,83,0,41,2,122,39,82,101,116,117,114, + 110,32,78,111,110,101,32,97,115,32,116,104,101,114,101,32, + 105,115,32,110,111,32,115,111,117,114,99,101,32,99,111,100, + 101,46,78,114,3,0,0,0,114,219,0,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,229,0,0, + 0,42,4,0,0,115,2,0,0,0,0,2,122,31,83,111, + 117,114,99,101,108,101,115,115,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,115,111,117,114,99,101,78,41,6, + 114,125,0,0,0,114,124,0,0,0,114,126,0,0,0,114, + 127,0,0,0,114,213,0,0,0,114,229,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,114,15,1,0,0,22,4,0,0,115,6,0,0,0, + 8,2,4,2,8,16,114,15,1,0,0,99,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 64,0,0,0,115,92,0,0,0,101,0,90,1,100,0,90, + 2,100,1,90,3,100,2,100,3,132,0,90,4,100,4,100, + 5,132,0,90,5,100,6,100,7,132,0,90,6,100,8,100, + 9,132,0,90,7,100,10,100,11,132,0,90,8,100,12,100, + 13,132,0,90,9,100,14,100,15,132,0,90,10,100,16,100, + 17,132,0,90,11,101,12,100,18,100,19,132,0,131,1,90, + 13,100,20,83,0,41,21,114,252,0,0,0,122,93,76,111, + 97,100,101,114,32,102,111,114,32,101,120,116,101,110,115,105, + 111,110,32,109,111,100,117,108,101,115,46,10,10,32,32,32, + 32,84,104,101,32,99,111,110,115,116,114,117,99,116,111,114, + 32,105,115,32,100,101,115,105,103,110,101,100,32,116,111,32, + 119,111,114,107,32,119,105,116,104,32,70,105,108,101,70,105, + 110,100,101,114,46,10,10,32,32,32,32,99,3,0,0,0, + 0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0, + 67,0,0,0,115,16,0,0,0,124,1,124,0,95,0,124, + 2,124,0,95,1,100,0,83,0,114,110,0,0,0,114,159, + 0,0,0,114,5,1,0,0,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,209,0,0,0,59,4,0,0, + 115,4,0,0,0,0,1,6,1,122,28,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,95, + 95,105,110,105,116,95,95,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, + 115,24,0,0,0,124,0,106,0,124,1,106,0,107,2,111, + 22,124,0,106,1,124,1,106,1,107,2,83,0,114,110,0, + 0,0,114,240,0,0,0,114,242,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,243,0,0,0, + 63,4,0,0,115,6,0,0,0,0,1,12,1,10,255,122, + 26,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, + 97,100,101,114,46,95,95,101,113,95,95,99,1,0,0,0, + 0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, + 67,0,0,0,115,20,0,0,0,116,0,124,0,106,1,131, + 1,116,0,124,0,106,2,131,1,65,0,83,0,114,110,0, + 0,0,114,244,0,0,0,114,246,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,247,0,0,0, + 67,4,0,0,115,2,0,0,0,0,1,122,28,69,120,116, + 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, + 46,95,95,104,97,115,104,95,95,99,2,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,5,0,0,0,67,0, + 0,0,115,36,0,0,0,116,0,160,1,116,2,106,3,124, + 1,161,2,125,2,116,0,160,4,100,1,124,1,106,5,124, + 0,106,6,161,3,1,0,124,2,83,0,41,2,122,38,67, + 114,101,97,116,101,32,97,110,32,117,110,105,116,105,97,108, + 105,122,101,100,32,101,120,116,101,110,115,105,111,110,32,109, + 111,100,117,108,101,122,38,101,120,116,101,110,115,105,111,110, + 32,109,111,100,117,108,101,32,123,33,114,125,32,108,111,97, + 100,101,100,32,102,114,111,109,32,123,33,114,125,41,7,114, + 134,0,0,0,114,214,0,0,0,114,163,0,0,0,90,14, + 99,114,101,97,116,101,95,100,121,110,97,109,105,99,114,149, + 0,0,0,114,117,0,0,0,114,44,0,0,0,41,3,114, + 119,0,0,0,114,187,0,0,0,114,216,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,212,0, + 0,0,70,4,0,0,115,18,0,0,0,0,2,4,1,4, + 0,2,255,4,2,6,1,4,0,4,255,4,2,122,33,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 101,114,46,99,114,101,97,116,101,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,5,0,0,0,67,0,0,0,115,36,0,0,0,116,0, + 160,1,116,2,106,3,124,1,161,2,1,0,116,0,160,4, + 100,1,124,0,106,5,124,0,106,6,161,3,1,0,100,2, + 83,0,41,3,122,30,73,110,105,116,105,97,108,105,122,101, + 32,97,110,32,101,120,116,101,110,115,105,111,110,32,109,111, + 100,117,108,101,122,40,101,120,116,101,110,115,105,111,110,32, + 109,111,100,117,108,101,32,123,33,114,125,32,101,120,101,99, + 117,116,101,100,32,102,114,111,109,32,123,33,114,125,78,41, + 7,114,134,0,0,0,114,214,0,0,0,114,163,0,0,0, + 90,12,101,120,101,99,95,100,121,110,97,109,105,99,114,149, + 0,0,0,114,117,0,0,0,114,44,0,0,0,114,253,0, + 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, + 0,114,217,0,0,0,78,4,0,0,115,10,0,0,0,0, + 2,14,1,6,1,4,0,4,255,122,31,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,3, + 0,0,0,115,36,0,0,0,116,0,124,0,106,1,131,1, + 100,1,25,0,137,0,116,2,135,0,102,1,100,2,100,3, + 132,8,116,3,68,0,131,1,131,1,83,0,41,4,122,49, + 82,101,116,117,114,110,32,84,114,117,101,32,105,102,32,116, + 104,101,32,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,32,105,115,32,97,32,112,97,99,107,97,103,101, + 46,114,39,0,0,0,99,1,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,51,0,0,0,115, + 26,0,0,0,124,0,93,18,125,1,136,0,100,0,124,1, + 23,0,107,2,86,0,1,0,113,2,100,1,83,0,41,2, + 114,209,0,0,0,78,114,3,0,0,0,169,2,114,32,0, + 0,0,218,6,115,117,102,102,105,120,169,1,90,9,102,105, + 108,101,95,110,97,109,101,114,3,0,0,0,114,6,0,0, + 0,218,9,60,103,101,110,101,120,112,114,62,87,4,0,0, + 115,4,0,0,0,4,1,2,255,122,49,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,105, + 115,95,112,97,99,107,97,103,101,46,60,108,111,99,97,108, + 115,62,46,60,103,101,110,101,120,112,114,62,41,4,114,47, + 0,0,0,114,44,0,0,0,218,3,97,110,121,218,18,69, + 88,84,69,78,83,73,79,78,95,83,85,70,70,73,88,69, + 83,114,219,0,0,0,114,3,0,0,0,114,18,1,0,0, + 114,6,0,0,0,114,182,0,0,0,84,4,0,0,115,8, + 0,0,0,0,2,14,1,12,1,2,255,122,30,69,120,116, + 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, + 46,105,115,95,112,97,99,107,97,103,101,99,2,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, + 67,0,0,0,115,4,0,0,0,100,1,83,0,41,2,122, + 63,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, + 97,110,32,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,32,99,97,110,110,111,116,32,99,114,101,97,116, + 101,32,97,32,99,111,100,101,32,111,98,106,101,99,116,46, 78,114,3,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,229,0,0,0,94, - 4,0,0,115,2,0,0,0,0,2,122,30,69,120,116,101, + 114,3,0,0,0,114,6,0,0,0,114,213,0,0,0,90, + 4,0,0,115,2,0,0,0,0,2,122,28,69,120,116,101, 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,115,111,117,114,99,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,6,0,0,0,124,0,106,0,83,0,114,250, - 0,0,0,114,48,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,179,0,0, - 0,98,4,0,0,115,2,0,0,0,0,3,122,32,69,120, - 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,102,105,108,101,110,97,109,101,78,41, - 14,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,127,0,0,0,114,209,0,0,0,114,243,0,0,0,114, - 247,0,0,0,114,212,0,0,0,114,217,0,0,0,114,182, - 0,0,0,114,213,0,0,0,114,229,0,0,0,114,136,0, - 0,0,114,179,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,3,0,0,0,114,6,0,0,0,114,252,0,0,0, - 51,4,0,0,115,22,0,0,0,8,2,4,6,8,4,8, - 4,8,3,8,8,8,6,8,6,8,4,8,4,2,1,114, - 252,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,64,0,0,0,115,104,0, - 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, - 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, - 100,7,132,0,90,6,100,8,100,9,132,0,90,7,100,10, - 100,11,132,0,90,8,100,12,100,13,132,0,90,9,100,14, - 100,15,132,0,90,10,100,16,100,17,132,0,90,11,100,18, - 100,19,132,0,90,12,100,20,100,21,132,0,90,13,100,22, - 100,23,132,0,90,14,100,24,83,0,41,25,218,14,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,97,38,1,0, - 0,82,101,112,114,101,115,101,110,116,115,32,97,32,110,97, - 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,39, - 115,32,112,97,116,104,46,32,32,73,116,32,117,115,101,115, - 32,116,104,101,32,109,111,100,117,108,101,32,110,97,109,101, - 10,32,32,32,32,116,111,32,102,105,110,100,32,105,116,115, - 32,112,97,114,101,110,116,32,109,111,100,117,108,101,44,32, - 97,110,100,32,102,114,111,109,32,116,104,101,114,101,32,105, - 116,32,108,111,111,107,115,32,117,112,32,116,104,101,32,112, - 97,114,101,110,116,39,115,10,32,32,32,32,95,95,112,97, - 116,104,95,95,46,32,32,87,104,101,110,32,116,104,105,115, - 32,99,104,97,110,103,101,115,44,32,116,104,101,32,109,111, - 100,117,108,101,39,115,32,111,119,110,32,112,97,116,104,32, - 105,115,32,114,101,99,111,109,112,117,116,101,100,44,10,32, - 32,32,32,117,115,105,110,103,32,112,97,116,104,95,102,105, - 110,100,101,114,46,32,32,70,111,114,32,116,111,112,45,108, - 101,118,101,108,32,109,111,100,117,108,101,115,44,32,116,104, - 101,32,112,97,114,101,110,116,32,109,111,100,117,108,101,39, - 115,32,112,97,116,104,10,32,32,32,32,105,115,32,115,121, - 115,46,112,97,116,104,46,99,4,0,0,0,0,0,0,0, - 0,0,0,0,4,0,0,0,3,0,0,0,67,0,0,0, - 115,36,0,0,0,124,1,124,0,95,0,124,2,124,0,95, - 1,116,2,124,0,160,3,161,0,131,1,124,0,95,4,124, - 3,124,0,95,5,100,0,83,0,114,110,0,0,0,41,6, - 218,5,95,110,97,109,101,218,5,95,112,97,116,104,114,112, - 0,0,0,218,16,95,103,101,116,95,112,97,114,101,110,116, - 95,112,97,116,104,218,17,95,108,97,115,116,95,112,97,114, - 101,110,116,95,112,97,116,104,218,12,95,112,97,116,104,95, - 102,105,110,100,101,114,169,4,114,119,0,0,0,114,117,0, - 0,0,114,44,0,0,0,90,11,112,97,116,104,95,102,105, - 110,100,101,114,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,114,209,0,0,0,111,4,0,0,115,8,0,0, - 0,0,1,6,1,6,1,14,1,122,23,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,46,95,95,105,110,105,116, - 95,95,99,1,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, - 124,0,106,0,160,1,100,1,161,1,92,3,125,1,125,2, - 125,3,124,2,100,2,107,2,114,30,100,3,83,0,124,1, - 100,4,102,2,83,0,41,5,122,62,82,101,116,117,114,110, - 115,32,97,32,116,117,112,108,101,32,111,102,32,40,112,97, - 114,101,110,116,45,109,111,100,117,108,101,45,110,97,109,101, - 44,32,112,97,114,101,110,116,45,112,97,116,104,45,97,116, - 116,114,45,110,97,109,101,41,114,71,0,0,0,114,40,0, - 0,0,41,2,114,8,0,0,0,114,44,0,0,0,90,8, - 95,95,112,97,116,104,95,95,41,2,114,23,1,0,0,114, - 41,0,0,0,41,4,114,119,0,0,0,114,14,1,0,0, - 218,3,100,111,116,90,2,109,101,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,23,95,102,105,110,100,95, - 112,97,114,101,110,116,95,112,97,116,104,95,110,97,109,101, - 115,117,4,0,0,115,8,0,0,0,0,2,18,1,8,2, - 4,3,122,38,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,102,105,110,100,95,112,97,114,101,110,116,95, - 112,97,116,104,95,110,97,109,101,115,99,1,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,28,0,0,0,124,0,160,0,161,0,92,2, - 125,1,125,2,116,1,116,2,106,3,124,1,25,0,124,2, - 131,2,83,0,114,110,0,0,0,41,4,114,30,1,0,0, - 114,130,0,0,0,114,8,0,0,0,218,7,109,111,100,117, - 108,101,115,41,3,114,119,0,0,0,90,18,112,97,114,101, - 110,116,95,109,111,100,117,108,101,95,110,97,109,101,90,14, - 112,97,116,104,95,97,116,116,114,95,110,97,109,101,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,25,1, - 0,0,127,4,0,0,115,4,0,0,0,0,1,12,1,122, - 31,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104, - 99,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,4,0,0,0,67,0,0,0,115,80,0,0,0,116,0, - 124,0,160,1,161,0,131,1,125,1,124,1,124,0,106,2, - 107,3,114,74,124,0,160,3,124,0,106,4,124,1,161,2, - 125,2,124,2,100,0,107,9,114,68,124,2,106,5,100,0, - 107,8,114,68,124,2,106,6,114,68,124,2,106,6,124,0, - 95,7,124,1,124,0,95,2,124,0,106,7,83,0,114,110, - 0,0,0,41,8,114,112,0,0,0,114,25,1,0,0,114, - 26,1,0,0,114,27,1,0,0,114,23,1,0,0,114,140, - 0,0,0,114,178,0,0,0,114,24,1,0,0,41,3,114, - 119,0,0,0,90,11,112,97,114,101,110,116,95,112,97,116, - 104,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,114,101,99,97,108,99,117,108, - 97,116,101,131,4,0,0,115,16,0,0,0,0,2,12,1, - 10,1,14,3,18,1,6,1,8,1,6,1,122,27,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,114,101, - 99,97,108,99,117,108,97,116,101,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, - 1,83,0,114,110,0,0,0,41,2,114,6,1,0,0,114, - 32,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,8,95,95,105,116,101,114, - 95,95,144,4,0,0,115,2,0,0,0,0,1,122,23,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 105,116,101,114,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, - 12,0,0,0,124,0,160,0,161,0,124,1,25,0,83,0, - 114,110,0,0,0,169,1,114,32,1,0,0,41,2,114,119, - 0,0,0,218,5,105,110,100,101,120,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,11,95,95,103,101,116, - 105,116,101,109,95,95,147,4,0,0,115,2,0,0,0,0, - 1,122,26,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,95,103,101,116,105,116,101,109,95,95,99,3,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, - 0,0,67,0,0,0,115,14,0,0,0,124,2,124,0,106, - 0,124,1,60,0,100,0,83,0,114,110,0,0,0,41,1, - 114,24,1,0,0,41,3,114,119,0,0,0,114,35,1,0, - 0,114,44,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,11,95,95,115,101,116,105,116,101,109, - 95,95,150,4,0,0,115,2,0,0,0,0,1,122,26,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 115,101,116,105,116,101,109,95,95,99,1,0,0,0,0,0, - 0,0,0,0,0,0,1,0,0,0,3,0,0,0,67,0, - 0,0,115,12,0,0,0,116,0,124,0,160,1,161,0,131, - 1,83,0,114,110,0,0,0,41,2,114,22,0,0,0,114, - 32,1,0,0,114,246,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,218,7,95,95,108,101,110,95, - 95,153,4,0,0,115,2,0,0,0,0,1,122,22,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,108, - 101,110,95,95,99,1,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,3,0,0,0,67,0,0,0,115,12,0, - 0,0,100,1,160,0,124,0,106,1,161,1,83,0,41,2, - 78,122,20,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,40,123,33,114,125,41,41,2,114,62,0,0,0,114,24, - 1,0,0,114,246,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,8,95,95,114,101,112,114,95, - 95,156,4,0,0,115,2,0,0,0,0,1,122,23,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,114, - 101,112,114,95,95,99,2,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,12, - 0,0,0,124,1,124,0,160,0,161,0,107,6,83,0,114, - 110,0,0,0,114,34,1,0,0,169,2,114,119,0,0,0, - 218,4,105,116,101,109,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,12,95,95,99,111,110,116,97,105,110, - 115,95,95,159,4,0,0,115,2,0,0,0,0,1,122,27, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,95, - 95,99,111,110,116,97,105,110,115,95,95,99,2,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, - 67,0,0,0,115,16,0,0,0,124,0,106,0,160,1,124, - 1,161,1,1,0,100,0,83,0,114,110,0,0,0,41,2, - 114,24,1,0,0,114,186,0,0,0,114,40,1,0,0,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,186, - 0,0,0,162,4,0,0,115,2,0,0,0,0,1,122,21, - 95,78,97,109,101,115,112,97,99,101,80,97,116,104,46,97, - 112,112,101,110,100,78,41,15,114,125,0,0,0,114,124,0, - 0,0,114,126,0,0,0,114,127,0,0,0,114,209,0,0, - 0,114,30,1,0,0,114,25,1,0,0,114,32,1,0,0, - 114,33,1,0,0,114,36,1,0,0,114,37,1,0,0,114, - 38,1,0,0,114,39,1,0,0,114,42,1,0,0,114,186, - 0,0,0,114,3,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,22,1,0,0,104,4,0,0, - 115,24,0,0,0,8,1,4,6,8,6,8,10,8,4,8, - 13,8,3,8,3,8,3,8,3,8,3,8,3,114,22,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,64,0,0,0,115,80,0,0,0, - 101,0,90,1,100,0,90,2,100,1,100,2,132,0,90,3, - 101,4,100,3,100,4,132,0,131,1,90,5,100,5,100,6, - 132,0,90,6,100,7,100,8,132,0,90,7,100,9,100,10, - 132,0,90,8,100,11,100,12,132,0,90,9,100,13,100,14, - 132,0,90,10,100,15,100,16,132,0,90,11,100,17,83,0, - 41,18,218,16,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,99,4,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,4,0,0,0,67,0,0,0,115,18,0, - 0,0,116,0,124,1,124,2,124,3,131,3,124,0,95,1, - 100,0,83,0,114,110,0,0,0,41,2,114,22,1,0,0, - 114,24,1,0,0,114,28,1,0,0,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,114,209,0,0,0,168,4, - 0,0,115,2,0,0,0,0,1,122,25,95,78,97,109,101, - 115,112,97,99,101,76,111,97,100,101,114,46,95,95,105,110, - 105,116,95,95,99,2,0,0,0,0,0,0,0,0,0,0, - 0,2,0,0,0,3,0,0,0,67,0,0,0,115,12,0, - 0,0,100,1,160,0,124,1,106,1,161,1,83,0,41,2, - 122,115,82,101,116,117,114,110,32,114,101,112,114,32,102,111, - 114,32,116,104,101,32,109,111,100,117,108,101,46,10,10,32, - 32,32,32,32,32,32,32,84,104,101,32,109,101,116,104,111, - 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, - 32,32,84,104,101,32,105,109,112,111,114,116,32,109,97,99, - 104,105,110,101,114,121,32,100,111,101,115,32,116,104,101,32, - 106,111,98,32,105,116,115,101,108,102,46,10,10,32,32,32, - 32,32,32,32,32,122,25,60,109,111,100,117,108,101,32,123, - 33,114,125,32,40,110,97,109,101,115,112,97,99,101,41,62, - 41,2,114,62,0,0,0,114,125,0,0,0,41,2,114,193, - 0,0,0,114,216,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,218,11,109,111,100,117,108,101,95, - 114,101,112,114,171,4,0,0,115,2,0,0,0,0,7,122, - 28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, - 114,46,109,111,100,117,108,101,95,114,101,112,114,99,2,0, + 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,115,4,0,0,0,100,1,83,0,41,2,122,53,82,101, + 116,117,114,110,32,78,111,110,101,32,97,115,32,101,120,116, + 101,110,115,105,111,110,32,109,111,100,117,108,101,115,32,104, + 97,118,101,32,110,111,32,115,111,117,114,99,101,32,99,111, + 100,101,46,78,114,3,0,0,0,114,219,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,229,0, + 0,0,94,4,0,0,115,2,0,0,0,0,2,122,30,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,115,111,117,114,99,101,99,2,0, 0,0,0,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,83,0,41, - 2,78,84,114,3,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,182,0,0, - 0,180,4,0,0,115,2,0,0,0,0,1,122,27,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,105, - 115,95,112,97,99,107,97,103,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, - 0,0,115,4,0,0,0,100,1,83,0,41,2,78,114,40, - 0,0,0,114,3,0,0,0,114,219,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,229,0,0, - 0,183,4,0,0,115,2,0,0,0,0,1,122,27,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,103, - 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,6,0,0,0,67,0, - 0,0,115,16,0,0,0,116,0,100,1,100,2,100,3,100, - 4,100,5,141,4,83,0,41,6,78,114,40,0,0,0,122, - 8,60,115,116,114,105,110,103,62,114,215,0,0,0,84,41, - 1,114,231,0,0,0,41,1,114,232,0,0,0,114,219,0, + 0,0,67,0,0,0,115,6,0,0,0,124,0,106,0,83, + 0,114,250,0,0,0,114,48,0,0,0,114,219,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 179,0,0,0,98,4,0,0,115,2,0,0,0,0,3,122, + 32,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, + 97,100,101,114,46,103,101,116,95,102,105,108,101,110,97,109, + 101,78,41,14,114,125,0,0,0,114,124,0,0,0,114,126, + 0,0,0,114,127,0,0,0,114,209,0,0,0,114,243,0, + 0,0,114,247,0,0,0,114,212,0,0,0,114,217,0,0, + 0,114,182,0,0,0,114,213,0,0,0,114,229,0,0,0, + 114,136,0,0,0,114,179,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,252, + 0,0,0,51,4,0,0,115,22,0,0,0,8,2,4,6, + 8,4,8,4,8,3,8,8,8,6,8,6,8,4,8,4, + 2,1,114,252,0,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,0, + 115,104,0,0,0,101,0,90,1,100,0,90,2,100,1,90, + 3,100,2,100,3,132,0,90,4,100,4,100,5,132,0,90, + 5,100,6,100,7,132,0,90,6,100,8,100,9,132,0,90, + 7,100,10,100,11,132,0,90,8,100,12,100,13,132,0,90, + 9,100,14,100,15,132,0,90,10,100,16,100,17,132,0,90, + 11,100,18,100,19,132,0,90,12,100,20,100,21,132,0,90, + 13,100,22,100,23,132,0,90,14,100,24,83,0,41,25,218, + 14,95,78,97,109,101,115,112,97,99,101,80,97,116,104,97, + 38,1,0,0,82,101,112,114,101,115,101,110,116,115,32,97, + 32,110,97,109,101,115,112,97,99,101,32,112,97,99,107,97, + 103,101,39,115,32,112,97,116,104,46,32,32,73,116,32,117, + 115,101,115,32,116,104,101,32,109,111,100,117,108,101,32,110, + 97,109,101,10,32,32,32,32,116,111,32,102,105,110,100,32, + 105,116,115,32,112,97,114,101,110,116,32,109,111,100,117,108, + 101,44,32,97,110,100,32,102,114,111,109,32,116,104,101,114, + 101,32,105,116,32,108,111,111,107,115,32,117,112,32,116,104, + 101,32,112,97,114,101,110,116,39,115,10,32,32,32,32,95, + 95,112,97,116,104,95,95,46,32,32,87,104,101,110,32,116, + 104,105,115,32,99,104,97,110,103,101,115,44,32,116,104,101, + 32,109,111,100,117,108,101,39,115,32,111,119,110,32,112,97, + 116,104,32,105,115,32,114,101,99,111,109,112,117,116,101,100, + 44,10,32,32,32,32,117,115,105,110,103,32,112,97,116,104, + 95,102,105,110,100,101,114,46,32,32,70,111,114,32,116,111, + 112,45,108,101,118,101,108,32,109,111,100,117,108,101,115,44, + 32,116,104,101,32,112,97,114,101,110,116,32,109,111,100,117, + 108,101,39,115,32,112,97,116,104,10,32,32,32,32,105,115, + 32,115,121,115,46,112,97,116,104,46,99,4,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,67, + 0,0,0,115,36,0,0,0,124,1,124,0,95,0,124,2, + 124,0,95,1,116,2,124,0,160,3,161,0,131,1,124,0, + 95,4,124,3,124,0,95,5,100,0,83,0,114,110,0,0, + 0,41,6,218,5,95,110,97,109,101,218,5,95,112,97,116, + 104,114,112,0,0,0,218,16,95,103,101,116,95,112,97,114, + 101,110,116,95,112,97,116,104,218,17,95,108,97,115,116,95, + 112,97,114,101,110,116,95,112,97,116,104,218,12,95,112,97, + 116,104,95,102,105,110,100,101,114,169,4,114,119,0,0,0, + 114,117,0,0,0,114,44,0,0,0,90,11,112,97,116,104, + 95,102,105,110,100,101,114,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,114,209,0,0,0,111,4,0,0,115, + 8,0,0,0,0,1,6,1,6,1,14,1,122,23,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,105, + 110,105,116,95,95,99,1,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,38, + 0,0,0,124,0,106,0,160,1,100,1,161,1,92,3,125, + 1,125,2,125,3,124,2,100,2,107,2,114,30,100,3,83, + 0,124,1,100,4,102,2,83,0,41,5,122,62,82,101,116, + 117,114,110,115,32,97,32,116,117,112,108,101,32,111,102,32, + 40,112,97,114,101,110,116,45,109,111,100,117,108,101,45,110, + 97,109,101,44,32,112,97,114,101,110,116,45,112,97,116,104, + 45,97,116,116,114,45,110,97,109,101,41,114,71,0,0,0, + 114,40,0,0,0,41,2,114,8,0,0,0,114,44,0,0, + 0,90,8,95,95,112,97,116,104,95,95,41,2,114,23,1, + 0,0,114,41,0,0,0,41,4,114,119,0,0,0,114,14, + 1,0,0,218,3,100,111,116,90,2,109,101,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,23,95,102,105, + 110,100,95,112,97,114,101,110,116,95,112,97,116,104,95,110, + 97,109,101,115,117,4,0,0,115,8,0,0,0,0,2,18, + 1,8,2,4,3,122,38,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,46,95,102,105,110,100,95,112,97,114,101, + 110,116,95,112,97,116,104,95,110,97,109,101,115,99,1,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,28,0,0,0,124,0,160,0,161, + 0,92,2,125,1,125,2,116,1,116,2,106,3,124,1,25, + 0,124,2,131,2,83,0,114,110,0,0,0,41,4,114,30, + 1,0,0,114,130,0,0,0,114,8,0,0,0,218,7,109, + 111,100,117,108,101,115,41,3,114,119,0,0,0,90,18,112, + 97,114,101,110,116,95,109,111,100,117,108,101,95,110,97,109, + 101,90,14,112,97,116,104,95,97,116,116,114,95,110,97,109, + 101,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,25,1,0,0,127,4,0,0,115,4,0,0,0,0,1, + 12,1,122,31,95,78,97,109,101,115,112,97,99,101,80,97, + 116,104,46,95,103,101,116,95,112,97,114,101,110,116,95,112, + 97,116,104,99,1,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,4,0,0,0,67,0,0,0,115,80,0,0, + 0,116,0,124,0,160,1,161,0,131,1,125,1,124,1,124, + 0,106,2,107,3,114,74,124,0,160,3,124,0,106,4,124, + 1,161,2,125,2,124,2,100,0,107,9,114,68,124,2,106, + 5,100,0,107,8,114,68,124,2,106,6,114,68,124,2,106, + 6,124,0,95,7,124,1,124,0,95,2,124,0,106,7,83, + 0,114,110,0,0,0,41,8,114,112,0,0,0,114,25,1, + 0,0,114,26,1,0,0,114,27,1,0,0,114,23,1,0, + 0,114,140,0,0,0,114,178,0,0,0,114,24,1,0,0, + 41,3,114,119,0,0,0,90,11,112,97,114,101,110,116,95, + 112,97,116,104,114,187,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,12,95,114,101,99,97,108, + 99,117,108,97,116,101,131,4,0,0,115,16,0,0,0,0, + 2,12,1,10,1,14,3,18,1,6,1,8,1,6,1,122, + 27,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,114,101,99,97,108,99,117,108,97,116,101,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,67,0,0,0,115,12,0,0,0,116,0,124,0,160,1, + 161,0,131,1,83,0,114,110,0,0,0,41,2,114,6,1, + 0,0,114,32,1,0,0,114,246,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,8,95,95,105, + 116,101,114,95,95,144,4,0,0,115,2,0,0,0,0,1, + 122,23,95,78,97,109,101,115,112,97,99,101,80,97,116,104, + 46,95,95,105,116,101,114,95,95,99,2,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, + 0,0,115,12,0,0,0,124,0,160,0,161,0,124,1,25, + 0,83,0,114,110,0,0,0,169,1,114,32,1,0,0,41, + 2,114,119,0,0,0,218,5,105,110,100,101,120,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,218,11,95,95, + 103,101,116,105,116,101,109,95,95,147,4,0,0,115,2,0, + 0,0,0,1,122,26,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,103,101,116,105,116,101,109,95,95, + 99,3,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,3,0,0,0,67,0,0,0,115,14,0,0,0,124,2, + 124,0,106,0,124,1,60,0,100,0,83,0,114,110,0,0, + 0,41,1,114,24,1,0,0,41,3,114,119,0,0,0,114, + 35,1,0,0,114,44,0,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,11,95,95,115,101,116,105, + 116,101,109,95,95,150,4,0,0,115,2,0,0,0,0,1, + 122,26,95,78,97,109,101,115,112,97,99,101,80,97,116,104, + 46,95,95,115,101,116,105,116,101,109,95,95,99,1,0,0, + 0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,67,0,0,0,115,12,0,0,0,116,0,124,0,160,1, + 161,0,131,1,83,0,114,110,0,0,0,41,2,114,22,0, + 0,0,114,32,1,0,0,114,246,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,218,7,95,95,108, + 101,110,95,95,153,4,0,0,115,2,0,0,0,0,1,122, + 22,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,95,108,101,110,95,95,99,1,0,0,0,0,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, + 115,12,0,0,0,100,1,160,0,124,0,106,1,161,1,83, + 0,41,2,78,122,20,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,40,123,33,114,125,41,41,2,114,62,0,0, + 0,114,24,1,0,0,114,246,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,8,95,95,114,101, + 112,114,95,95,156,4,0,0,115,2,0,0,0,0,1,122, + 23,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,95,114,101,112,114,95,95,99,2,0,0,0,0,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, + 0,115,12,0,0,0,124,1,124,0,160,0,161,0,107,6, + 83,0,114,110,0,0,0,114,34,1,0,0,169,2,114,119, + 0,0,0,218,4,105,116,101,109,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,12,95,95,99,111,110,116, + 97,105,110,115,95,95,159,4,0,0,115,2,0,0,0,0, + 1,122,27,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,46,95,95,99,111,110,116,97,105,110,115,95,95,99,2, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,67,0,0,0,115,16,0,0,0,124,0,106,0, + 160,1,124,1,161,1,1,0,100,0,83,0,114,110,0,0, + 0,41,2,114,24,1,0,0,114,186,0,0,0,114,40,1, 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,213,0,0,0,186,4,0,0,115,2,0,0,0,0, - 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, - 100,101,114,46,103,101,116,95,99,111,100,101,99,2,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,1,83,0,114,210, - 0,0,0,114,3,0,0,0,114,211,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,212,0,0, - 0,189,4,0,0,115,2,0,0,0,0,1,122,30,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,99, - 114,101,97,116,101,95,109,111,100,117,108,101,99,2,0,0, + 0,114,186,0,0,0,162,4,0,0,115,2,0,0,0,0, + 1,122,21,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,46,97,112,112,101,110,100,78,41,15,114,125,0,0,0, + 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, + 209,0,0,0,114,30,1,0,0,114,25,1,0,0,114,32, + 1,0,0,114,33,1,0,0,114,36,1,0,0,114,37,1, + 0,0,114,38,1,0,0,114,39,1,0,0,114,42,1,0, + 0,114,186,0,0,0,114,3,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,22,1,0,0,104, + 4,0,0,115,24,0,0,0,8,1,4,6,8,6,8,10, + 8,4,8,13,8,3,8,3,8,3,8,3,8,3,8,3, + 114,22,1,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,80, + 0,0,0,101,0,90,1,100,0,90,2,100,1,100,2,132, + 0,90,3,101,4,100,3,100,4,132,0,131,1,90,5,100, + 5,100,6,132,0,90,6,100,7,100,8,132,0,90,7,100, + 9,100,10,132,0,90,8,100,11,100,12,132,0,90,9,100, + 13,100,14,132,0,90,10,100,15,100,16,132,0,90,11,100, + 17,83,0,41,18,218,16,95,78,97,109,101,115,112,97,99, + 101,76,111,97,100,101,114,99,4,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,4,0,0,0,67,0,0,0, + 115,18,0,0,0,116,0,124,1,124,2,124,3,131,3,124, + 0,95,1,100,0,83,0,114,110,0,0,0,41,2,114,22, + 1,0,0,114,24,1,0,0,114,28,1,0,0,114,3,0, + 0,0,114,3,0,0,0,114,6,0,0,0,114,209,0,0, + 0,168,4,0,0,115,2,0,0,0,0,1,122,25,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,95, + 95,105,110,105,116,95,95,99,2,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, + 115,12,0,0,0,100,1,160,0,124,1,106,1,161,1,83, + 0,41,2,122,115,82,101,116,117,114,110,32,114,101,112,114, + 32,102,111,114,32,116,104,101,32,109,111,100,117,108,101,46, + 10,10,32,32,32,32,32,32,32,32,84,104,101,32,109,101, + 116,104,111,100,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,46,32,32,84,104,101,32,105,109,112,111,114,116,32, + 109,97,99,104,105,110,101,114,121,32,100,111,101,115,32,116, + 104,101,32,106,111,98,32,105,116,115,101,108,102,46,10,10, + 32,32,32,32,32,32,32,32,122,25,60,109,111,100,117,108, + 101,32,123,33,114,125,32,40,110,97,109,101,115,112,97,99, + 101,41,62,41,2,114,62,0,0,0,114,125,0,0,0,41, + 2,114,193,0,0,0,114,216,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,218,11,109,111,100,117, + 108,101,95,114,101,112,114,171,4,0,0,115,2,0,0,0, + 0,7,122,28,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,109,111,100,117,108,101,95,114,101,112,114, + 99,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 83,0,41,2,78,84,114,3,0,0,0,114,219,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 182,0,0,0,180,4,0,0,115,2,0,0,0,0,1,122, + 27,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,105,115,95,112,97,99,107,97,103,101,99,2,0,0, 0,0,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,0,83,0,114,110, - 0,0,0,114,3,0,0,0,114,253,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,217,0,0, - 0,192,4,0,0,115,2,0,0,0,0,1,122,28,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,101, - 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, - 0,0,0,115,26,0,0,0,116,0,160,1,100,1,124,0, - 106,2,161,2,1,0,116,0,160,3,124,0,124,1,161,2, - 83,0,41,2,122,98,76,111,97,100,32,97,32,110,97,109, - 101,115,112,97,99,101,32,109,111,100,117,108,101,46,10,10, - 32,32,32,32,32,32,32,32,84,104,105,115,32,109,101,116, - 104,111,100,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,46,32,32,85,115,101,32,101,120,101,99,95,109,111,100, - 117,108,101,40,41,32,105,110,115,116,101,97,100,46,10,10, - 32,32,32,32,32,32,32,32,122,38,110,97,109,101,115,112, - 97,99,101,32,109,111,100,117,108,101,32,108,111,97,100,101, - 100,32,119,105,116,104,32,112,97,116,104,32,123,33,114,125, - 41,4,114,134,0,0,0,114,149,0,0,0,114,24,1,0, - 0,114,218,0,0,0,114,219,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,220,0,0,0,195, - 4,0,0,115,8,0,0,0,0,7,6,1,4,255,4,2, - 122,28,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,108,111,97,100,95,109,111,100,117,108,101,78,41, - 12,114,125,0,0,0,114,124,0,0,0,114,126,0,0,0, - 114,209,0,0,0,114,207,0,0,0,114,44,1,0,0,114, - 182,0,0,0,114,229,0,0,0,114,213,0,0,0,114,212, - 0,0,0,114,217,0,0,0,114,220,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,43,1,0,0,167,4,0,0,115,18,0,0,0,8, - 1,8,3,2,1,10,8,8,3,8,3,8,3,8,3,8, - 3,114,43,1,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, - 172,0,0,0,101,0,90,1,100,0,90,2,100,1,90,3, - 101,4,100,2,100,3,132,0,131,1,90,5,101,4,100,4, - 100,5,132,0,131,1,90,6,101,4,100,6,100,7,132,0, - 131,1,90,7,101,4,100,8,100,9,132,0,131,1,90,8, - 101,4,100,28,100,11,100,12,132,1,131,1,90,9,101,4, - 100,29,100,13,100,14,132,1,131,1,90,10,101,4,100,30, - 100,15,100,16,132,1,131,1,90,11,100,17,90,12,101,4, - 100,31,100,18,100,19,132,1,131,1,90,13,101,4,100,20, - 100,21,132,0,131,1,90,14,101,15,100,22,100,23,132,0, - 131,1,90,16,101,4,100,24,100,25,132,0,131,1,90,17, - 101,4,100,26,100,27,132,0,131,1,90,18,100,10,83,0, - 41,32,218,10,80,97,116,104,70,105,110,100,101,114,122,62, - 77,101,116,97,32,112,97,116,104,32,102,105,110,100,101,114, - 32,102,111,114,32,115,121,115,46,112,97,116,104,32,97,110, - 100,32,112,97,99,107,97,103,101,32,95,95,112,97,116,104, - 95,95,32,97,116,116,114,105,98,117,116,101,115,46,99,1, - 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,4, - 0,0,0,67,0,0,0,115,64,0,0,0,116,0,116,1, - 106,2,160,3,161,0,131,1,68,0,93,44,92,2,125,1, - 125,2,124,2,100,1,107,8,114,40,116,1,106,2,124,1, - 61,0,113,14,116,4,124,2,100,2,131,2,114,14,124,2, - 160,5,161,0,1,0,113,14,100,1,83,0,41,3,122,125, - 67,97,108,108,32,116,104,101,32,105,110,118,97,108,105,100, - 97,116,101,95,99,97,99,104,101,115,40,41,32,109,101,116, - 104,111,100,32,111,110,32,97,108,108,32,112,97,116,104,32, - 101,110,116,114,121,32,102,105,110,100,101,114,115,10,32,32, - 32,32,32,32,32,32,115,116,111,114,101,100,32,105,110,32, - 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,115,32,40,119,104,101,114,101,32, - 105,109,112,108,101,109,101,110,116,101,100,41,46,78,218,17, - 105,110,118,97,108,105,100,97,116,101,95,99,97,99,104,101, - 115,41,6,218,4,108,105,115,116,114,8,0,0,0,218,19, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,218,5,105,116,101,109,115,114,128,0,0,0,114, - 46,1,0,0,41,3,114,193,0,0,0,114,117,0,0,0, - 218,6,102,105,110,100,101,114,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,46,1,0,0,213,4,0,0, - 115,10,0,0,0,0,4,22,1,8,1,10,1,10,1,122, - 28,80,97,116,104,70,105,110,100,101,114,46,105,110,118,97, - 108,105,100,97,116,101,95,99,97,99,104,101,115,99,2,0, - 0,0,0,0,0,0,0,0,0,0,3,0,0,0,9,0, - 0,0,67,0,0,0,115,84,0,0,0,116,0,106,1,100, - 1,107,9,114,28,116,0,106,1,115,28,116,2,160,3,100, - 2,116,4,161,2,1,0,116,0,106,1,68,0,93,44,125, - 2,122,14,124,2,124,1,131,1,87,0,2,0,1,0,83, - 0,4,0,116,5,107,10,114,76,1,0,1,0,1,0,89, - 0,113,34,89,0,113,34,88,0,113,34,100,1,83,0,41, - 3,122,46,83,101,97,114,99,104,32,115,121,115,46,112,97, - 116,104,95,104,111,111,107,115,32,102,111,114,32,97,32,102, - 105,110,100,101,114,32,102,111,114,32,39,112,97,116,104,39, - 46,78,122,23,115,121,115,46,112,97,116,104,95,104,111,111, - 107,115,32,105,115,32,101,109,112,116,121,41,6,114,8,0, - 0,0,218,10,112,97,116,104,95,104,111,111,107,115,114,75, - 0,0,0,114,76,0,0,0,114,138,0,0,0,114,118,0, - 0,0,41,3,114,193,0,0,0,114,44,0,0,0,90,4, - 104,111,111,107,114,3,0,0,0,114,3,0,0,0,114,6, - 0,0,0,218,11,95,112,97,116,104,95,104,111,111,107,115, - 223,4,0,0,115,16,0,0,0,0,3,16,1,12,1,10, - 1,2,1,14,1,14,1,12,2,122,22,80,97,116,104,70, - 105,110,100,101,114,46,95,112,97,116,104,95,104,111,111,107, - 115,99,2,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,8,0,0,0,67,0,0,0,115,104,0,0,0,124, - 1,100,1,107,2,114,44,122,12,116,0,160,1,161,0,125, - 1,87,0,110,22,4,0,116,2,107,10,114,42,1,0,1, - 0,1,0,89,0,100,2,83,0,88,0,122,14,116,3,106, - 4,124,1,25,0,125,2,87,0,110,40,4,0,116,5,107, - 10,114,98,1,0,1,0,1,0,124,0,160,6,124,1,161, - 1,125,2,124,2,116,3,106,4,124,1,60,0,89,0,110, - 2,88,0,124,2,83,0,41,3,122,210,71,101,116,32,116, - 104,101,32,102,105,110,100,101,114,32,102,111,114,32,116,104, - 101,32,112,97,116,104,32,101,110,116,114,121,32,102,114,111, - 109,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, - 116,101,114,95,99,97,99,104,101,46,10,10,32,32,32,32, - 32,32,32,32,73,102,32,116,104,101,32,112,97,116,104,32, - 101,110,116,114,121,32,105,115,32,110,111,116,32,105,110,32, - 116,104,101,32,99,97,99,104,101,44,32,102,105,110,100,32, - 116,104,101,32,97,112,112,114,111,112,114,105,97,116,101,32, - 102,105,110,100,101,114,10,32,32,32,32,32,32,32,32,97, - 110,100,32,99,97,99,104,101,32,105,116,46,32,73,102,32, - 110,111,32,102,105,110,100,101,114,32,105,115,32,97,118,97, - 105,108,97,98,108,101,44,32,115,116,111,114,101,32,78,111, - 110,101,46,10,10,32,32,32,32,32,32,32,32,114,40,0, - 0,0,78,41,7,114,2,0,0,0,114,55,0,0,0,114, - 3,1,0,0,114,8,0,0,0,114,48,1,0,0,218,8, - 75,101,121,69,114,114,111,114,114,52,1,0,0,41,3,114, - 193,0,0,0,114,44,0,0,0,114,50,1,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,218,20,95, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,236,4,0,0,115,22,0,0,0,0,8,8,1, - 2,1,12,1,14,3,8,1,2,1,14,1,14,1,10,1, - 16,1,122,31,80,97,116,104,70,105,110,100,101,114,46,95, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,99,3,0,0,0,0,0,0,0,0,0,0,0, - 6,0,0,0,4,0,0,0,67,0,0,0,115,82,0,0, - 0,116,0,124,2,100,1,131,2,114,26,124,2,160,1,124, - 1,161,1,92,2,125,3,125,4,110,14,124,2,160,2,124, - 1,161,1,125,3,103,0,125,4,124,3,100,0,107,9,114, - 60,116,3,160,4,124,1,124,3,161,2,83,0,116,3,160, - 5,124,1,100,0,161,2,125,5,124,4,124,5,95,6,124, - 5,83,0,41,2,78,114,137,0,0,0,41,7,114,128,0, - 0,0,114,137,0,0,0,114,206,0,0,0,114,134,0,0, - 0,114,201,0,0,0,114,183,0,0,0,114,178,0,0,0, - 41,6,114,193,0,0,0,114,139,0,0,0,114,50,1,0, - 0,114,140,0,0,0,114,141,0,0,0,114,187,0,0,0, + 0,67,0,0,0,115,4,0,0,0,100,1,83,0,41,2, + 78,114,40,0,0,0,114,3,0,0,0,114,219,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 229,0,0,0,183,4,0,0,115,2,0,0,0,0,1,122, + 27,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,103,101,116,95,115,111,117,114,99,101,99,2,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,6,0,0, + 0,67,0,0,0,115,16,0,0,0,116,0,100,1,100,2, + 100,3,100,4,100,5,141,4,83,0,41,6,78,114,40,0, + 0,0,122,8,60,115,116,114,105,110,103,62,114,215,0,0, + 0,84,41,1,114,231,0,0,0,41,1,114,232,0,0,0, + 114,219,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,213,0,0,0,186,4,0,0,115,2,0, + 0,0,0,1,122,25,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,101,114,46,103,101,116,95,99,111,100,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,83, + 0,114,210,0,0,0,114,3,0,0,0,114,211,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 212,0,0,0,189,4,0,0,115,2,0,0,0,0,1,122, + 30,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,99,114,101,97,116,101,95,109,111,100,117,108,101,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,0,83, + 0,114,110,0,0,0,114,3,0,0,0,114,253,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 217,0,0,0,192,4,0,0,115,2,0,0,0,0,1,122, + 28,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,101,120,101,99,95,109,111,100,117,108,101,99,2,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,67,0,0,0,115,26,0,0,0,116,0,160,1,100, + 1,124,0,106,2,161,2,1,0,116,0,160,3,124,0,124, + 1,161,2,83,0,41,2,122,98,76,111,97,100,32,97,32, + 110,97,109,101,115,112,97,99,101,32,109,111,100,117,108,101, + 46,10,10,32,32,32,32,32,32,32,32,84,104,105,115,32, + 109,101,116,104,111,100,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,46,32,32,85,115,101,32,101,120,101,99,95, + 109,111,100,117,108,101,40,41,32,105,110,115,116,101,97,100, + 46,10,10,32,32,32,32,32,32,32,32,122,38,110,97,109, + 101,115,112,97,99,101,32,109,111,100,117,108,101,32,108,111, + 97,100,101,100,32,119,105,116,104,32,112,97,116,104,32,123, + 33,114,125,41,4,114,134,0,0,0,114,149,0,0,0,114, + 24,1,0,0,114,218,0,0,0,114,219,0,0,0,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,220,0, + 0,0,195,4,0,0,115,8,0,0,0,0,7,6,1,4, + 255,4,2,122,28,95,78,97,109,101,115,112,97,99,101,76, + 111,97,100,101,114,46,108,111,97,100,95,109,111,100,117,108, + 101,78,41,12,114,125,0,0,0,114,124,0,0,0,114,126, + 0,0,0,114,209,0,0,0,114,207,0,0,0,114,44,1, + 0,0,114,182,0,0,0,114,229,0,0,0,114,213,0,0, + 0,114,212,0,0,0,114,217,0,0,0,114,220,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,43,1,0,0,167,4,0,0,115,18,0, + 0,0,8,1,8,3,2,1,10,8,8,3,8,3,8,3, + 8,3,8,3,114,43,1,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,64,0, + 0,0,115,172,0,0,0,101,0,90,1,100,0,90,2,100, + 1,90,3,101,4,100,2,100,3,132,0,131,1,90,5,101, + 4,100,4,100,5,132,0,131,1,90,6,101,4,100,6,100, + 7,132,0,131,1,90,7,101,4,100,8,100,9,132,0,131, + 1,90,8,101,4,100,28,100,11,100,12,132,1,131,1,90, + 9,101,4,100,29,100,13,100,14,132,1,131,1,90,10,101, + 4,100,30,100,15,100,16,132,1,131,1,90,11,100,17,90, + 12,101,4,100,31,100,18,100,19,132,1,131,1,90,13,101, + 4,100,20,100,21,132,0,131,1,90,14,101,15,100,22,100, + 23,132,0,131,1,90,16,101,4,100,24,100,25,132,0,131, + 1,90,17,101,4,100,26,100,27,132,0,131,1,90,18,100, + 10,83,0,41,32,218,10,80,97,116,104,70,105,110,100,101, + 114,122,62,77,101,116,97,32,112,97,116,104,32,102,105,110, + 100,101,114,32,102,111,114,32,115,121,115,46,112,97,116,104, + 32,97,110,100,32,112,97,99,107,97,103,101,32,95,95,112, + 97,116,104,95,95,32,97,116,116,114,105,98,117,116,101,115, + 46,99,1,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,4,0,0,0,67,0,0,0,115,64,0,0,0,116, + 0,116,1,106,2,160,3,161,0,131,1,68,0,93,44,92, + 2,125,1,125,2,124,2,100,1,107,8,114,40,116,1,106, + 2,124,1,61,0,113,14,116,4,124,2,100,2,131,2,114, + 14,124,2,160,5,161,0,1,0,113,14,100,1,83,0,41, + 3,122,125,67,97,108,108,32,116,104,101,32,105,110,118,97, + 108,105,100,97,116,101,95,99,97,99,104,101,115,40,41,32, + 109,101,116,104,111,100,32,111,110,32,97,108,108,32,112,97, + 116,104,32,101,110,116,114,121,32,102,105,110,100,101,114,115, + 10,32,32,32,32,32,32,32,32,115,116,111,114,101,100,32, + 105,110,32,115,121,115,46,112,97,116,104,95,105,109,112,111, + 114,116,101,114,95,99,97,99,104,101,115,32,40,119,104,101, + 114,101,32,105,109,112,108,101,109,101,110,116,101,100,41,46, + 78,218,17,105,110,118,97,108,105,100,97,116,101,95,99,97, + 99,104,101,115,41,6,218,4,108,105,115,116,114,8,0,0, + 0,218,19,112,97,116,104,95,105,109,112,111,114,116,101,114, + 95,99,97,99,104,101,218,5,105,116,101,109,115,114,128,0, + 0,0,114,46,1,0,0,41,3,114,193,0,0,0,114,117, + 0,0,0,218,6,102,105,110,100,101,114,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,46,1,0,0,213, + 4,0,0,115,10,0,0,0,0,4,22,1,8,1,10,1, + 10,1,122,28,80,97,116,104,70,105,110,100,101,114,46,105, + 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,9,0,0,0,67,0,0,0,115,84,0,0,0,116,0, + 106,1,100,1,107,9,114,28,116,0,106,1,115,28,116,2, + 160,3,100,2,116,4,161,2,1,0,116,0,106,1,68,0, + 93,44,125,2,122,14,124,2,124,1,131,1,87,0,2,0, + 1,0,83,0,4,0,116,5,107,10,114,76,1,0,1,0, + 1,0,89,0,113,34,89,0,113,34,88,0,113,34,100,1, + 83,0,41,3,122,46,83,101,97,114,99,104,32,115,121,115, + 46,112,97,116,104,95,104,111,111,107,115,32,102,111,114,32, + 97,32,102,105,110,100,101,114,32,102,111,114,32,39,112,97, + 116,104,39,46,78,122,23,115,121,115,46,112,97,116,104,95, + 104,111,111,107,115,32,105,115,32,101,109,112,116,121,41,6, + 114,8,0,0,0,218,10,112,97,116,104,95,104,111,111,107, + 115,114,75,0,0,0,114,76,0,0,0,114,138,0,0,0, + 114,118,0,0,0,41,3,114,193,0,0,0,114,44,0,0, + 0,90,4,104,111,111,107,114,3,0,0,0,114,3,0,0, + 0,114,6,0,0,0,218,11,95,112,97,116,104,95,104,111, + 111,107,115,223,4,0,0,115,16,0,0,0,0,3,16,1, + 12,1,10,1,2,1,14,1,14,1,12,2,122,22,80,97, + 116,104,70,105,110,100,101,114,46,95,112,97,116,104,95,104, + 111,111,107,115,99,2,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,8,0,0,0,67,0,0,0,115,104,0, + 0,0,124,1,100,1,107,2,114,44,122,12,116,0,160,1, + 161,0,125,1,87,0,110,22,4,0,116,2,107,10,114,42, + 1,0,1,0,1,0,89,0,100,2,83,0,88,0,122,14, + 116,3,106,4,124,1,25,0,125,2,87,0,110,40,4,0, + 116,5,107,10,114,98,1,0,1,0,1,0,124,0,160,6, + 124,1,161,1,125,2,124,2,116,3,106,4,124,1,60,0, + 89,0,110,2,88,0,124,2,83,0,41,3,122,210,71,101, + 116,32,116,104,101,32,102,105,110,100,101,114,32,102,111,114, + 32,116,104,101,32,112,97,116,104,32,101,110,116,114,121,32, + 102,114,111,109,32,115,121,115,46,112,97,116,104,95,105,109, + 112,111,114,116,101,114,95,99,97,99,104,101,46,10,10,32, + 32,32,32,32,32,32,32,73,102,32,116,104,101,32,112,97, + 116,104,32,101,110,116,114,121,32,105,115,32,110,111,116,32, + 105,110,32,116,104,101,32,99,97,99,104,101,44,32,102,105, + 110,100,32,116,104,101,32,97,112,112,114,111,112,114,105,97, + 116,101,32,102,105,110,100,101,114,10,32,32,32,32,32,32, + 32,32,97,110,100,32,99,97,99,104,101,32,105,116,46,32, + 73,102,32,110,111,32,102,105,110,100,101,114,32,105,115,32, + 97,118,97,105,108,97,98,108,101,44,32,115,116,111,114,101, + 32,78,111,110,101,46,10,10,32,32,32,32,32,32,32,32, + 114,40,0,0,0,78,41,7,114,2,0,0,0,114,55,0, + 0,0,114,3,1,0,0,114,8,0,0,0,114,48,1,0, + 0,218,8,75,101,121,69,114,114,111,114,114,52,1,0,0, + 41,3,114,193,0,0,0,114,44,0,0,0,114,50,1,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 218,20,95,112,97,116,104,95,105,109,112,111,114,116,101,114, + 95,99,97,99,104,101,236,4,0,0,115,22,0,0,0,0, + 8,8,1,2,1,12,1,14,3,8,1,2,1,14,1,14, + 1,10,1,16,1,122,31,80,97,116,104,70,105,110,100,101, + 114,46,95,112,97,116,104,95,105,109,112,111,114,116,101,114, + 95,99,97,99,104,101,99,3,0,0,0,0,0,0,0,0, + 0,0,0,6,0,0,0,4,0,0,0,67,0,0,0,115, + 82,0,0,0,116,0,124,2,100,1,131,2,114,26,124,2, + 160,1,124,1,161,1,92,2,125,3,125,4,110,14,124,2, + 160,2,124,1,161,1,125,3,103,0,125,4,124,3,100,0, + 107,9,114,60,116,3,160,4,124,1,124,3,161,2,83,0, + 116,3,160,5,124,1,100,0,161,2,125,5,124,4,124,5, + 95,6,124,5,83,0,41,2,78,114,137,0,0,0,41,7, + 114,128,0,0,0,114,137,0,0,0,114,206,0,0,0,114, + 134,0,0,0,114,201,0,0,0,114,183,0,0,0,114,178, + 0,0,0,41,6,114,193,0,0,0,114,139,0,0,0,114, + 50,1,0,0,114,140,0,0,0,114,141,0,0,0,114,187, + 0,0,0,114,3,0,0,0,114,3,0,0,0,114,6,0, + 0,0,218,16,95,108,101,103,97,99,121,95,103,101,116,95, + 115,112,101,99,2,5,0,0,115,18,0,0,0,0,4,10, + 1,16,2,10,1,4,1,8,1,12,1,12,1,6,1,122, + 27,80,97,116,104,70,105,110,100,101,114,46,95,108,101,103, + 97,99,121,95,103,101,116,95,115,112,101,99,78,99,4,0, + 0,0,0,0,0,0,0,0,0,0,9,0,0,0,5,0, + 0,0,67,0,0,0,115,166,0,0,0,103,0,125,4,124, + 2,68,0,93,134,125,5,116,0,124,5,116,1,116,2,102, + 2,131,2,115,28,113,8,124,0,160,3,124,5,161,1,125, + 6,124,6,100,1,107,9,114,8,116,4,124,6,100,2,131, + 2,114,70,124,6,160,5,124,1,124,3,161,2,125,7,110, + 12,124,0,160,6,124,1,124,6,161,2,125,7,124,7,100, + 1,107,8,114,92,113,8,124,7,106,7,100,1,107,9,114, + 110,124,7,2,0,1,0,83,0,124,7,106,8,125,8,124, + 8,100,1,107,8,114,132,116,9,100,3,131,1,130,1,124, + 4,160,10,124,8,161,1,1,0,113,8,116,11,160,12,124, + 1,100,1,161,2,125,7,124,4,124,7,95,8,124,7,83, + 0,41,4,122,63,70,105,110,100,32,116,104,101,32,108,111, + 97,100,101,114,32,111,114,32,110,97,109,101,115,112,97,99, + 101,95,112,97,116,104,32,102,111,114,32,116,104,105,115,32, + 109,111,100,117,108,101,47,112,97,99,107,97,103,101,32,110, + 97,109,101,46,78,114,203,0,0,0,122,19,115,112,101,99, + 32,109,105,115,115,105,110,103,32,108,111,97,100,101,114,41, + 13,114,161,0,0,0,114,85,0,0,0,218,5,98,121,116, + 101,115,114,54,1,0,0,114,128,0,0,0,114,203,0,0, + 0,114,55,1,0,0,114,140,0,0,0,114,178,0,0,0, + 114,118,0,0,0,114,167,0,0,0,114,134,0,0,0,114, + 183,0,0,0,41,9,114,193,0,0,0,114,139,0,0,0, + 114,44,0,0,0,114,202,0,0,0,218,14,110,97,109,101, + 115,112,97,99,101,95,112,97,116,104,90,5,101,110,116,114, + 121,114,50,1,0,0,114,187,0,0,0,114,141,0,0,0, 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, - 16,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, - 99,2,5,0,0,115,18,0,0,0,0,4,10,1,16,2, - 10,1,4,1,8,1,12,1,12,1,6,1,122,27,80,97, - 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, - 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, - 0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,67, - 0,0,0,115,166,0,0,0,103,0,125,4,124,2,68,0, - 93,134,125,5,116,0,124,5,116,1,116,2,102,2,131,2, - 115,28,113,8,124,0,160,3,124,5,161,1,125,6,124,6, - 100,1,107,9,114,8,116,4,124,6,100,2,131,2,114,70, - 124,6,160,5,124,1,124,3,161,2,125,7,110,12,124,0, - 160,6,124,1,124,6,161,2,125,7,124,7,100,1,107,8, - 114,92,113,8,124,7,106,7,100,1,107,9,114,110,124,7, - 2,0,1,0,83,0,124,7,106,8,125,8,124,8,100,1, - 107,8,114,132,116,9,100,3,131,1,130,1,124,4,160,10, - 124,8,161,1,1,0,113,8,116,11,160,12,124,1,100,1, - 161,2,125,7,124,4,124,7,95,8,124,7,83,0,41,4, - 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, - 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, - 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, - 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, - 46,78,114,203,0,0,0,122,19,115,112,101,99,32,109,105, - 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,161, - 0,0,0,114,85,0,0,0,218,5,98,121,116,101,115,114, - 54,1,0,0,114,128,0,0,0,114,203,0,0,0,114,55, - 1,0,0,114,140,0,0,0,114,178,0,0,0,114,118,0, - 0,0,114,167,0,0,0,114,134,0,0,0,114,183,0,0, - 0,41,9,114,193,0,0,0,114,139,0,0,0,114,44,0, - 0,0,114,202,0,0,0,218,14,110,97,109,101,115,112,97, - 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,50, - 1,0,0,114,187,0,0,0,114,141,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,218,9,95,103, - 101,116,95,115,112,101,99,17,5,0,0,115,40,0,0,0, - 0,5,4,1,8,1,14,1,2,1,10,1,8,1,10,1, - 14,2,12,1,8,1,2,1,10,1,8,1,6,1,8,1, - 8,5,12,2,12,1,6,1,122,20,80,97,116,104,70,105, - 110,100,101,114,46,95,103,101,116,95,115,112,101,99,99,4, - 0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5, - 0,0,0,67,0,0,0,115,100,0,0,0,124,2,100,1, - 107,8,114,14,116,0,106,1,125,2,124,0,160,2,124,1, - 124,2,124,3,161,3,125,4,124,4,100,1,107,8,114,40, - 100,1,83,0,124,4,106,3,100,1,107,8,114,92,124,4, - 106,4,125,5,124,5,114,86,100,1,124,4,95,5,116,6, - 124,1,124,5,124,0,106,2,131,3,124,4,95,4,124,4, - 83,0,100,1,83,0,110,4,124,4,83,0,100,1,83,0, - 41,2,122,141,84,114,121,32,116,111,32,102,105,110,100,32, - 97,32,115,112,101,99,32,102,111,114,32,39,102,117,108,108, - 110,97,109,101,39,32,111,110,32,115,121,115,46,112,97,116, - 104,32,111,114,32,39,112,97,116,104,39,46,10,10,32,32, - 32,32,32,32,32,32,84,104,101,32,115,101,97,114,99,104, - 32,105,115,32,98,97,115,101,100,32,111,110,32,115,121,115, - 46,112,97,116,104,95,104,111,111,107,115,32,97,110,100,32, - 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,46,10,32,32,32,32,32,32,32, - 32,78,41,7,114,8,0,0,0,114,44,0,0,0,114,58, - 1,0,0,114,140,0,0,0,114,178,0,0,0,114,181,0, - 0,0,114,22,1,0,0,41,6,114,193,0,0,0,114,139, - 0,0,0,114,44,0,0,0,114,202,0,0,0,114,187,0, - 0,0,114,57,1,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,203,0,0,0,49,5,0,0,115, - 26,0,0,0,0,6,8,1,6,1,14,1,8,1,4,1, - 10,1,6,1,4,3,6,1,16,1,4,2,6,2,122,20, - 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, - 115,112,101,99,99,3,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,4,0,0,0,67,0,0,0,115,30,0, - 0,0,124,0,160,0,124,1,124,2,161,2,125,3,124,3, - 100,1,107,8,114,24,100,1,83,0,124,3,106,1,83,0, - 41,2,122,170,102,105,110,100,32,116,104,101,32,109,111,100, - 117,108,101,32,111,110,32,115,121,115,46,112,97,116,104,32, - 111,114,32,39,112,97,116,104,39,32,98,97,115,101,100,32, - 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, - 115,32,97,110,100,10,32,32,32,32,32,32,32,32,115,121, - 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, - 99,97,99,104,101,46,10,10,32,32,32,32,32,32,32,32, + 9,95,103,101,116,95,115,112,101,99,17,5,0,0,115,40, + 0,0,0,0,5,4,1,8,1,14,1,2,1,10,1,8, + 1,10,1,14,2,12,1,8,1,2,1,10,1,8,1,6, + 1,8,1,8,5,12,2,12,1,6,1,122,20,80,97,116, + 104,70,105,110,100,101,114,46,95,103,101,116,95,115,112,101, + 99,99,4,0,0,0,0,0,0,0,0,0,0,0,6,0, + 0,0,5,0,0,0,67,0,0,0,115,100,0,0,0,124, + 2,100,1,107,8,114,14,116,0,106,1,125,2,124,0,160, + 2,124,1,124,2,124,3,161,3,125,4,124,4,100,1,107, + 8,114,40,100,1,83,0,124,4,106,3,100,1,107,8,114, + 92,124,4,106,4,125,5,124,5,114,86,100,1,124,4,95, + 5,116,6,124,1,124,5,124,0,106,2,131,3,124,4,95, + 4,124,4,83,0,100,1,83,0,110,4,124,4,83,0,100, + 1,83,0,41,2,122,141,84,114,121,32,116,111,32,102,105, + 110,100,32,97,32,115,112,101,99,32,102,111,114,32,39,102, + 117,108,108,110,97,109,101,39,32,111,110,32,115,121,115,46, + 112,97,116,104,32,111,114,32,39,112,97,116,104,39,46,10, + 10,32,32,32,32,32,32,32,32,84,104,101,32,115,101,97, + 114,99,104,32,105,115,32,98,97,115,101,100,32,111,110,32, + 115,121,115,46,112,97,116,104,95,104,111,111,107,115,32,97, + 110,100,32,115,121,115,46,112,97,116,104,95,105,109,112,111, + 114,116,101,114,95,99,97,99,104,101,46,10,32,32,32,32, + 32,32,32,32,78,41,7,114,8,0,0,0,114,44,0,0, + 0,114,58,1,0,0,114,140,0,0,0,114,178,0,0,0, + 114,181,0,0,0,114,22,1,0,0,41,6,114,193,0,0, + 0,114,139,0,0,0,114,44,0,0,0,114,202,0,0,0, + 114,187,0,0,0,114,57,1,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,203,0,0,0,49,5, + 0,0,115,26,0,0,0,0,6,8,1,6,1,14,1,8, + 1,4,1,10,1,6,1,4,3,6,1,16,1,4,2,6, + 2,122,20,80,97,116,104,70,105,110,100,101,114,46,102,105, + 110,100,95,115,112,101,99,99,3,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,4,0,0,0,67,0,0,0, + 115,30,0,0,0,124,0,160,0,124,1,124,2,161,2,125, + 3,124,3,100,1,107,8,114,24,100,1,83,0,124,3,106, + 1,83,0,41,2,122,170,102,105,110,100,32,116,104,101,32, + 109,111,100,117,108,101,32,111,110,32,115,121,115,46,112,97, + 116,104,32,111,114,32,39,112,97,116,104,39,32,98,97,115, + 101,100,32,111,110,32,115,121,115,46,112,97,116,104,95,104, + 111,111,107,115,32,97,110,100,10,32,32,32,32,32,32,32, + 32,115,121,115,46,112,97,116,104,95,105,109,112,111,114,116, + 101,114,95,99,97,99,104,101,46,10,10,32,32,32,32,32, + 32,32,32,84,104,105,115,32,109,101,116,104,111,100,32,105, + 115,32,100,101,112,114,101,99,97,116,101,100,46,32,32,85, + 115,101,32,102,105,110,100,95,115,112,101,99,40,41,32,105, + 110,115,116,101,97,100,46,10,10,32,32,32,32,32,32,32, + 32,78,114,204,0,0,0,114,205,0,0,0,114,3,0,0, + 0,114,3,0,0,0,114,6,0,0,0,114,206,0,0,0, + 73,5,0,0,115,8,0,0,0,0,8,12,1,8,1,4, + 1,122,22,80,97,116,104,70,105,110,100,101,114,46,102,105, + 110,100,95,109,111,100,117,108,101,122,45,40,63,58,123,112, + 97,116,116,101,114,110,125,40,45,46,42,41,63,92,46,40, + 100,105,115,116,124,101,103,103,41,45,105,110,102,111,124,69, + 71,71,45,73,78,70,79,41,99,3,0,0,0,0,0,0, + 0,0,0,0,0,7,0,0,0,4,0,0,0,67,0,0, + 0,115,78,0,0,0,100,1,100,2,108,0,125,3,100,1, + 100,3,108,1,109,2,125,4,1,0,124,2,100,2,107,8, + 114,34,116,3,106,4,125,2,124,1,100,2,107,8,114,46, + 100,4,110,8,124,3,160,5,124,1,161,1,125,5,124,0, + 160,6,124,5,124,2,161,2,125,6,116,7,124,4,124,6, + 131,2,83,0,41,5,97,37,1,0,0,10,32,32,32,32, + 32,32,32,32,70,105,110,100,32,100,105,115,116,114,105,98, + 117,116,105,111,110,115,46,10,10,32,32,32,32,32,32,32, + 32,82,101,116,117,114,110,32,97,110,32,105,116,101,114,97, + 98,108,101,32,111,102,32,97,108,108,32,68,105,115,116,114, + 105,98,117,116,105,111,110,32,105,110,115,116,97,110,99,101, + 115,32,99,97,112,97,98,108,101,32,111,102,10,32,32,32, + 32,32,32,32,32,108,111,97,100,105,110,103,32,116,104,101, + 32,109,101,116,97,100,97,116,97,32,102,111,114,32,112,97, + 99,107,97,103,101,115,32,109,97,116,99,104,105,110,103,32, + 116,104,101,32,96,96,110,97,109,101,96,96,10,32,32,32, + 32,32,32,32,32,40,111,114,32,97,108,108,32,110,97,109, + 101,115,32,105,102,32,110,111,116,32,115,117,112,112,108,105, + 101,100,41,32,97,108,111,110,103,32,116,104,101,32,112,97, + 116,104,115,32,105,110,32,116,104,101,32,108,105,115,116,10, + 32,32,32,32,32,32,32,32,111,102,32,100,105,114,101,99, + 116,111,114,105,101,115,32,96,96,112,97,116,104,96,96,32, + 40,100,101,102,97,117,108,116,115,32,116,111,32,115,121,115, + 46,112,97,116,104,41,46,10,32,32,32,32,32,32,32,32, + 114,73,0,0,0,78,41,1,218,16,80,97,116,104,68,105, + 115,116,114,105,98,117,116,105,111,110,122,2,46,42,41,8, + 218,2,114,101,90,18,105,109,112,111,114,116,108,105,98,46, + 109,101,116,97,100,97,116,97,114,59,1,0,0,114,8,0, + 0,0,114,44,0,0,0,90,6,101,115,99,97,112,101,218, + 13,95,115,101,97,114,99,104,95,112,97,116,104,115,218,3, + 109,97,112,41,7,114,193,0,0,0,114,117,0,0,0,114, + 44,0,0,0,114,60,1,0,0,114,59,1,0,0,218,7, + 112,97,116,116,101,114,110,90,5,102,111,117,110,100,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,18,102, + 105,110,100,95,100,105,115,116,114,105,98,117,116,105,111,110, + 115,88,5,0,0,115,14,0,0,0,0,10,8,1,12,1, + 8,1,6,1,22,1,12,1,122,29,80,97,116,104,70,105, + 110,100,101,114,46,102,105,110,100,95,100,105,115,116,114,105, + 98,117,116,105,111,110,115,99,3,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,6,0,0,0,3,0,0,0, + 115,44,0,0,0,100,1,100,2,108,0,125,3,124,3,106, + 1,160,2,135,0,135,1,102,2,100,3,100,4,132,8,116, + 3,136,0,106,4,124,2,131,2,68,0,131,1,161,1,83, + 0,41,5,122,49,70,105,110,100,32,109,101,116,97,100,97, + 116,97,32,100,105,114,101,99,116,111,114,105,101,115,32,105, + 110,32,112,97,116,104,115,32,104,101,117,114,105,115,116,105, + 99,97,108,108,121,46,114,73,0,0,0,78,99,1,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,5,0,0, + 0,51,0,0,0,115,26,0,0,0,124,0,93,18,125,1, + 136,0,160,0,124,1,136,1,161,2,86,0,1,0,113,2, + 100,0,83,0,114,110,0,0,0,41,1,218,12,95,115,101, + 97,114,99,104,95,112,97,116,104,41,2,114,32,0,0,0, + 114,44,0,0,0,169,2,114,193,0,0,0,114,63,1,0, + 0,114,3,0,0,0,114,6,0,0,0,114,19,1,0,0, + 110,5,0,0,115,4,0,0,0,4,2,2,255,122,43,80, + 97,116,104,70,105,110,100,101,114,46,95,115,101,97,114,99, + 104,95,112,97,116,104,115,46,60,108,111,99,97,108,115,62, + 46,60,103,101,110,101,120,112,114,62,41,5,218,9,105,116, + 101,114,116,111,111,108,115,90,5,99,104,97,105,110,90,13, + 102,114,111,109,95,105,116,101,114,97,98,108,101,114,62,1, + 0,0,218,12,95,115,119,105,116,99,104,95,112,97,116,104, + 41,4,114,193,0,0,0,114,63,1,0,0,90,5,112,97, + 116,104,115,114,67,1,0,0,114,3,0,0,0,114,66,1, + 0,0,114,6,0,0,0,114,61,1,0,0,106,5,0,0, + 115,8,0,0,0,0,3,8,1,18,2,10,254,122,24,80, + 97,116,104,70,105,110,100,101,114,46,95,115,101,97,114,99, + 104,95,112,97,116,104,115,99,1,0,0,0,0,0,0,0, + 0,0,0,0,4,0,0,0,10,0,0,0,67,0,0,0, + 115,78,0,0,0,100,1,100,2,108,0,109,1,125,1,1, + 0,100,1,100,0,108,2,125,2,100,1,100,3,108,3,109, + 4,125,3,1,0,124,1,116,5,131,1,143,24,1,0,124, + 2,160,4,124,0,161,1,87,0,2,0,53,0,81,0,82, + 0,163,0,83,0,81,0,82,0,88,0,124,3,124,0,131, + 1,83,0,41,4,78,114,73,0,0,0,41,1,218,8,115, + 117,112,112,114,101,115,115,41,1,218,4,80,97,116,104,41, + 6,90,10,99,111,110,116,101,120,116,108,105,98,114,69,1, + 0,0,218,7,122,105,112,102,105,108,101,90,7,112,97,116, + 104,108,105,98,114,70,1,0,0,218,9,69,120,99,101,112, + 116,105,111,110,41,4,114,44,0,0,0,114,69,1,0,0, + 114,71,1,0,0,114,70,1,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,68,1,0,0,115,5, + 0,0,115,12,0,0,0,0,2,12,1,8,1,12,1,10, + 1,28,1,122,23,80,97,116,104,70,105,110,100,101,114,46, + 95,115,119,105,116,99,104,95,112,97,116,104,99,4,0,0, + 0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0, + 0,67,0,0,0,115,32,0,0,0,100,1,100,0,108,0, + 125,4,124,4,106,1,124,1,116,2,124,3,106,3,131,1, + 124,4,106,4,100,2,141,3,83,0,41,3,78,114,73,0, + 0,0,41,1,114,83,0,0,0,41,5,114,60,1,0,0, + 90,5,109,97,116,99,104,114,85,0,0,0,114,117,0,0, + 0,90,10,73,71,78,79,82,69,67,65,83,69,41,5,114, + 193,0,0,0,114,63,1,0,0,218,4,114,111,111,116,114, + 41,1,0,0,114,60,1,0,0,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,10,95,112,114,101,100,105, + 99,97,116,101,124,5,0,0,115,4,0,0,0,0,2,8, + 1,122,21,80,97,116,104,70,105,110,100,101,114,46,95,112, + 114,101,100,105,99,97,116,101,99,3,0,0,0,0,0,0, + 0,0,0,0,0,4,0,0,0,4,0,0,0,3,0,0, + 0,115,64,0,0,0,136,2,160,0,161,0,115,12,100,1, + 83,0,124,2,160,1,100,2,100,3,161,2,125,3,136,0, + 106,2,106,3,124,3,100,4,141,1,137,1,135,0,135,1, + 135,2,102,3,100,5,100,6,132,8,136,2,160,4,161,0, + 68,0,131,1,83,0,41,7,78,114,3,0,0,0,250,1, + 45,114,45,0,0,0,41,1,114,63,1,0,0,99,1,0, + 0,0,0,0,0,0,0,0,0,0,2,0,0,0,6,0, + 0,0,51,0,0,0,115,32,0,0,0,124,0,93,24,125, + 1,136,0,160,0,136,1,136,2,124,1,161,3,114,2,124, + 1,86,0,1,0,113,2,100,0,83,0,114,110,0,0,0, + 41,1,114,74,1,0,0,41,2,114,32,0,0,0,114,41, + 1,0,0,169,3,114,193,0,0,0,90,7,109,97,116,99, + 104,101,114,114,73,1,0,0,114,3,0,0,0,114,6,0, + 0,0,114,19,1,0,0,135,5,0,0,115,6,0,0,0, + 4,0,2,1,14,255,122,42,80,97,116,104,70,105,110,100, + 101,114,46,95,115,101,97,114,99,104,95,112,97,116,104,46, + 60,108,111,99,97,108,115,62,46,60,103,101,110,101,120,112, + 114,62,41,5,90,6,105,115,95,100,105,114,114,67,0,0, + 0,218,15,115,101,97,114,99,104,95,116,101,109,112,108,97, + 116,101,114,62,0,0,0,90,7,105,116,101,114,100,105,114, + 41,4,114,193,0,0,0,114,73,1,0,0,114,63,1,0, + 0,90,10,110,111,114,109,97,108,105,122,101,100,114,3,0, + 0,0,114,76,1,0,0,114,6,0,0,0,114,65,1,0, + 0,129,5,0,0,115,10,0,0,0,0,2,8,1,4,1, + 12,1,14,1,122,23,80,97,116,104,70,105,110,100,101,114, + 46,95,115,101,97,114,99,104,95,112,97,116,104,41,1,78, + 41,2,78,78,41,1,78,41,2,78,78,41,19,114,125,0, + 0,0,114,124,0,0,0,114,126,0,0,0,114,127,0,0, + 0,114,207,0,0,0,114,46,1,0,0,114,52,1,0,0, + 114,54,1,0,0,114,55,1,0,0,114,58,1,0,0,114, + 203,0,0,0,114,206,0,0,0,114,77,1,0,0,114,64, + 1,0,0,114,61,1,0,0,218,12,115,116,97,116,105,99, + 109,101,116,104,111,100,114,68,1,0,0,114,74,1,0,0, + 114,65,1,0,0,114,3,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,45,1,0,0,209,4, + 0,0,115,52,0,0,0,8,2,4,2,2,1,10,9,2, + 1,10,12,2,1,10,21,2,1,10,14,2,1,12,31,2, + 1,12,23,2,1,12,12,4,2,2,1,12,17,2,1,10, + 8,2,1,10,8,2,1,10,4,2,1,114,45,1,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,64,0,0,0,115,90,0,0,0,101,0, + 90,1,100,0,90,2,100,1,90,3,100,2,100,3,132,0, + 90,4,100,4,100,5,132,0,90,5,101,6,90,7,100,6, + 100,7,132,0,90,8,100,8,100,9,132,0,90,9,100,19, + 100,11,100,12,132,1,90,10,100,13,100,14,132,0,90,11, + 101,12,100,15,100,16,132,0,131,1,90,13,100,17,100,18, + 132,0,90,14,100,10,83,0,41,20,218,10,70,105,108,101, + 70,105,110,100,101,114,122,172,70,105,108,101,45,98,97,115, + 101,100,32,102,105,110,100,101,114,46,10,10,32,32,32,32, + 73,110,116,101,114,97,99,116,105,111,110,115,32,119,105,116, + 104,32,116,104,101,32,102,105,108,101,32,115,121,115,116,101, + 109,32,97,114,101,32,99,97,99,104,101,100,32,102,111,114, + 32,112,101,114,102,111,114,109,97,110,99,101,44,32,98,101, + 105,110,103,10,32,32,32,32,114,101,102,114,101,115,104,101, + 100,32,119,104,101,110,32,116,104,101,32,100,105,114,101,99, + 116,111,114,121,32,116,104,101,32,102,105,110,100,101,114,32, + 105,115,32,104,97,110,100,108,105,110,103,32,104,97,115,32, + 98,101,101,110,32,109,111,100,105,102,105,101,100,46,10,10, + 32,32,32,32,99,2,0,0,0,0,0,0,0,0,0,0, + 0,5,0,0,0,6,0,0,0,7,0,0,0,115,84,0, + 0,0,103,0,125,3,124,2,68,0,93,32,92,2,137,0, + 125,4,124,3,160,0,135,0,102,1,100,1,100,2,132,8, + 124,4,68,0,131,1,161,1,1,0,113,8,124,3,124,0, + 95,1,124,1,112,54,100,3,124,0,95,2,100,4,124,0, + 95,3,116,4,131,0,124,0,95,5,116,4,131,0,124,0, + 95,6,100,5,83,0,41,6,122,154,73,110,105,116,105,97, + 108,105,122,101,32,119,105,116,104,32,116,104,101,32,112,97, + 116,104,32,116,111,32,115,101,97,114,99,104,32,111,110,32, + 97,110,100,32,97,32,118,97,114,105,97,98,108,101,32,110, + 117,109,98,101,114,32,111,102,10,32,32,32,32,32,32,32, + 32,50,45,116,117,112,108,101,115,32,99,111,110,116,97,105, + 110,105,110,103,32,116,104,101,32,108,111,97,100,101,114,32, + 97,110,100,32,116,104,101,32,102,105,108,101,32,115,117,102, + 102,105,120,101,115,32,116,104,101,32,108,111,97,100,101,114, + 10,32,32,32,32,32,32,32,32,114,101,99,111,103,110,105, + 122,101,115,46,99,1,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,3,0,0,0,51,0,0,0,115,22,0, + 0,0,124,0,93,14,125,1,124,1,136,0,102,2,86,0, + 1,0,113,2,100,0,83,0,114,110,0,0,0,114,3,0, + 0,0,114,16,1,0,0,169,1,114,140,0,0,0,114,3, + 0,0,0,114,6,0,0,0,114,19,1,0,0,154,5,0, + 0,115,4,0,0,0,4,0,2,0,122,38,70,105,108,101, + 70,105,110,100,101,114,46,95,95,105,110,105,116,95,95,46, + 60,108,111,99,97,108,115,62,46,60,103,101,110,101,120,112, + 114,62,114,71,0,0,0,114,105,0,0,0,78,41,7,114, + 167,0,0,0,218,8,95,108,111,97,100,101,114,115,114,44, + 0,0,0,218,11,95,112,97,116,104,95,109,116,105,109,101, + 218,3,115,101,116,218,11,95,112,97,116,104,95,99,97,99, + 104,101,218,19,95,114,101,108,97,120,101,100,95,112,97,116, + 104,95,99,97,99,104,101,41,5,114,119,0,0,0,114,44, + 0,0,0,218,14,108,111,97,100,101,114,95,100,101,116,97, + 105,108,115,90,7,108,111,97,100,101,114,115,114,189,0,0, + 0,114,3,0,0,0,114,80,1,0,0,114,6,0,0,0, + 114,209,0,0,0,148,5,0,0,115,16,0,0,0,0,4, + 4,1,12,1,26,1,6,2,10,1,6,1,8,1,122,19, + 70,105,108,101,70,105,110,100,101,114,46,95,95,105,110,105, + 116,95,95,99,1,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,2,0,0,0,67,0,0,0,115,10,0,0, + 0,100,1,124,0,95,0,100,2,83,0,41,3,122,31,73, + 110,118,97,108,105,100,97,116,101,32,116,104,101,32,100,105, + 114,101,99,116,111,114,121,32,109,116,105,109,101,46,114,105, + 0,0,0,78,41,1,114,82,1,0,0,114,246,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,114, + 46,1,0,0,162,5,0,0,115,2,0,0,0,0,2,122, + 28,70,105,108,101,70,105,110,100,101,114,46,105,110,118,97, + 108,105,100,97,116,101,95,99,97,99,104,101,115,99,2,0, + 0,0,0,0,0,0,0,0,0,0,3,0,0,0,3,0, + 0,0,67,0,0,0,115,42,0,0,0,124,0,160,0,124, + 1,161,1,125,2,124,2,100,1,107,8,114,26,100,1,103, + 0,102,2,83,0,124,2,106,1,124,2,106,2,112,38,103, + 0,102,2,83,0,41,2,122,197,84,114,121,32,116,111,32, + 102,105,110,100,32,97,32,108,111,97,100,101,114,32,102,111, + 114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, + 109,111,100,117,108,101,44,32,111,114,32,116,104,101,32,110, + 97,109,101,115,112,97,99,101,10,32,32,32,32,32,32,32, + 32,112,97,99,107,97,103,101,32,112,111,114,116,105,111,110, + 115,46,32,82,101,116,117,114,110,115,32,40,108,111,97,100, + 101,114,44,32,108,105,115,116,45,111,102,45,112,111,114,116, + 105,111,110,115,41,46,10,10,32,32,32,32,32,32,32,32, 84,104,105,115,32,109,101,116,104,111,100,32,105,115,32,100, 101,112,114,101,99,97,116,101,100,46,32,32,85,115,101,32, 102,105,110,100,95,115,112,101,99,40,41,32,105,110,115,116, - 101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,114, - 204,0,0,0,114,205,0,0,0,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,206,0,0,0,73,5,0, - 0,115,8,0,0,0,0,8,12,1,8,1,4,1,122,22, - 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, - 109,111,100,117,108,101,122,45,40,63,58,123,112,97,116,116, - 101,114,110,125,40,45,46,42,41,63,92,46,40,100,105,115, - 116,124,101,103,103,41,45,105,110,102,111,124,69,71,71,45, - 73,78,70,79,41,99,3,0,0,0,0,0,0,0,0,0, - 0,0,7,0,0,0,4,0,0,0,67,0,0,0,115,78, - 0,0,0,100,1,100,2,108,0,125,3,100,1,100,3,108, - 1,109,2,125,4,1,0,124,2,100,2,107,8,114,34,116, - 3,106,4,125,2,124,1,100,2,107,8,114,46,100,4,110, - 8,124,3,160,5,124,1,161,1,125,5,124,0,160,6,124, - 5,124,2,161,2,125,6,116,7,124,4,124,6,131,2,83, - 0,41,5,97,37,1,0,0,10,32,32,32,32,32,32,32, - 32,70,105,110,100,32,100,105,115,116,114,105,98,117,116,105, - 111,110,115,46,10,10,32,32,32,32,32,32,32,32,82,101, - 116,117,114,110,32,97,110,32,105,116,101,114,97,98,108,101, - 32,111,102,32,97,108,108,32,68,105,115,116,114,105,98,117, - 116,105,111,110,32,105,110,115,116,97,110,99,101,115,32,99, - 97,112,97,98,108,101,32,111,102,10,32,32,32,32,32,32, - 32,32,108,111,97,100,105,110,103,32,116,104,101,32,109,101, - 116,97,100,97,116,97,32,102,111,114,32,112,97,99,107,97, - 103,101,115,32,109,97,116,99,104,105,110,103,32,116,104,101, - 32,96,96,110,97,109,101,96,96,10,32,32,32,32,32,32, - 32,32,40,111,114,32,97,108,108,32,110,97,109,101,115,32, - 105,102,32,110,111,116,32,115,117,112,112,108,105,101,100,41, - 32,97,108,111,110,103,32,116,104,101,32,112,97,116,104,115, - 32,105,110,32,116,104,101,32,108,105,115,116,10,32,32,32, - 32,32,32,32,32,111,102,32,100,105,114,101,99,116,111,114, - 105,101,115,32,96,96,112,97,116,104,96,96,32,40,100,101, - 102,97,117,108,116,115,32,116,111,32,115,121,115,46,112,97, - 116,104,41,46,10,32,32,32,32,32,32,32,32,114,73,0, - 0,0,78,41,1,218,16,80,97,116,104,68,105,115,116,114, - 105,98,117,116,105,111,110,122,2,46,42,41,8,218,2,114, - 101,90,18,105,109,112,111,114,116,108,105,98,46,109,101,116, - 97,100,97,116,97,114,59,1,0,0,114,8,0,0,0,114, - 44,0,0,0,90,6,101,115,99,97,112,101,218,13,95,115, - 101,97,114,99,104,95,112,97,116,104,115,218,3,109,97,112, - 41,7,114,193,0,0,0,114,117,0,0,0,114,44,0,0, - 0,114,60,1,0,0,114,59,1,0,0,218,7,112,97,116, - 116,101,114,110,90,5,102,111,117,110,100,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,218,18,102,105,110,100, - 95,100,105,115,116,114,105,98,117,116,105,111,110,115,88,5, - 0,0,115,14,0,0,0,0,10,8,1,12,1,8,1,6, - 1,22,1,12,1,122,29,80,97,116,104,70,105,110,100,101, - 114,46,102,105,110,100,95,100,105,115,116,114,105,98,117,116, - 105,111,110,115,99,3,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,6,0,0,0,3,0,0,0,115,44,0, - 0,0,100,1,100,2,108,0,125,3,124,3,106,1,160,2, - 135,0,135,1,102,2,100,3,100,4,132,8,116,3,136,0, - 106,4,124,2,131,2,68,0,131,1,161,1,83,0,41,5, - 122,49,70,105,110,100,32,109,101,116,97,100,97,116,97,32, - 100,105,114,101,99,116,111,114,105,101,115,32,105,110,32,112, - 97,116,104,115,32,104,101,117,114,105,115,116,105,99,97,108, - 108,121,46,114,73,0,0,0,78,99,1,0,0,0,0,0, - 0,0,0,0,0,0,2,0,0,0,5,0,0,0,51,0, - 0,0,115,26,0,0,0,124,0,93,18,125,1,136,0,160, - 0,124,1,136,1,161,2,86,0,1,0,113,2,100,0,83, - 0,114,110,0,0,0,41,1,218,12,95,115,101,97,114,99, - 104,95,112,97,116,104,41,2,114,32,0,0,0,114,44,0, - 0,0,169,2,114,193,0,0,0,114,63,1,0,0,114,3, - 0,0,0,114,6,0,0,0,114,19,1,0,0,110,5,0, - 0,115,4,0,0,0,4,2,2,255,122,43,80,97,116,104, - 70,105,110,100,101,114,46,95,115,101,97,114,99,104,95,112, - 97,116,104,115,46,60,108,111,99,97,108,115,62,46,60,103, - 101,110,101,120,112,114,62,41,5,218,9,105,116,101,114,116, - 111,111,108,115,90,5,99,104,97,105,110,90,13,102,114,111, - 109,95,105,116,101,114,97,98,108,101,114,62,1,0,0,218, - 12,95,115,119,105,116,99,104,95,112,97,116,104,41,4,114, - 193,0,0,0,114,63,1,0,0,90,5,112,97,116,104,115, - 114,67,1,0,0,114,3,0,0,0,114,66,1,0,0,114, - 6,0,0,0,114,61,1,0,0,106,5,0,0,115,8,0, - 0,0,0,3,8,1,18,2,10,254,122,24,80,97,116,104, - 70,105,110,100,101,114,46,95,115,101,97,114,99,104,95,112, - 97,116,104,115,99,1,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,10,0,0,0,67,0,0,0,115,78,0, - 0,0,100,1,100,2,108,0,109,1,125,1,1,0,100,1, - 100,0,108,2,125,2,100,1,100,3,108,3,109,4,125,3, - 1,0,124,1,116,5,131,1,143,24,1,0,124,2,160,4, - 124,0,161,1,87,0,2,0,53,0,81,0,82,0,163,0, - 83,0,81,0,82,0,88,0,124,3,124,0,131,1,83,0, - 41,4,78,114,73,0,0,0,41,1,218,8,115,117,112,112, - 114,101,115,115,41,1,218,4,80,97,116,104,41,6,90,10, - 99,111,110,116,101,120,116,108,105,98,114,69,1,0,0,218, - 7,122,105,112,102,105,108,101,90,7,112,97,116,104,108,105, - 98,114,70,1,0,0,218,9,69,120,99,101,112,116,105,111, - 110,41,4,114,44,0,0,0,114,69,1,0,0,114,71,1, - 0,0,114,70,1,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,68,1,0,0,115,5,0,0,115, - 12,0,0,0,0,2,12,1,8,1,12,1,10,1,28,1, - 122,23,80,97,116,104,70,105,110,100,101,114,46,95,115,119, - 105,116,99,104,95,112,97,116,104,99,4,0,0,0,0,0, - 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, - 0,0,115,32,0,0,0,100,1,100,0,108,0,125,4,124, - 4,106,1,124,1,116,2,124,3,106,3,131,1,124,4,106, - 4,100,2,141,3,83,0,41,3,78,114,73,0,0,0,41, - 1,114,83,0,0,0,41,5,114,60,1,0,0,90,5,109, - 97,116,99,104,114,85,0,0,0,114,117,0,0,0,90,10, - 73,71,78,79,82,69,67,65,83,69,41,5,114,193,0,0, - 0,114,63,1,0,0,218,4,114,111,111,116,114,41,1,0, - 0,114,60,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,218,10,95,112,114,101,100,105,99,97,116, - 101,124,5,0,0,115,4,0,0,0,0,2,8,1,122,21, - 80,97,116,104,70,105,110,100,101,114,46,95,112,114,101,100, - 105,99,97,116,101,99,3,0,0,0,0,0,0,0,0,0, - 0,0,4,0,0,0,4,0,0,0,3,0,0,0,115,64, - 0,0,0,136,2,160,0,161,0,115,12,100,1,83,0,124, - 2,160,1,100,2,100,3,161,2,125,3,136,0,106,2,106, - 3,124,3,100,4,141,1,137,1,135,0,135,1,135,2,102, - 3,100,5,100,6,132,8,136,2,160,4,161,0,68,0,131, - 1,83,0,41,7,78,114,3,0,0,0,250,1,45,114,45, - 0,0,0,41,1,114,63,1,0,0,99,1,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,51, - 0,0,0,115,32,0,0,0,124,0,93,24,125,1,136,0, - 160,0,136,1,136,2,124,1,161,3,114,26,124,1,86,0, - 1,0,113,2,100,0,83,0,114,110,0,0,0,41,1,114, - 74,1,0,0,41,2,114,32,0,0,0,114,41,1,0,0, - 169,3,114,193,0,0,0,90,7,109,97,116,99,104,101,114, - 114,73,1,0,0,114,3,0,0,0,114,6,0,0,0,114, - 19,1,0,0,135,5,0,0,115,6,0,0,0,4,0,2, - 1,14,255,122,42,80,97,116,104,70,105,110,100,101,114,46, - 95,115,101,97,114,99,104,95,112,97,116,104,46,60,108,111, - 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,41, - 5,90,6,105,115,95,100,105,114,114,67,0,0,0,218,15, - 115,101,97,114,99,104,95,116,101,109,112,108,97,116,101,114, - 62,0,0,0,90,7,105,116,101,114,100,105,114,41,4,114, - 193,0,0,0,114,73,1,0,0,114,63,1,0,0,90,10, - 110,111,114,109,97,108,105,122,101,100,114,3,0,0,0,114, - 76,1,0,0,114,6,0,0,0,114,65,1,0,0,129,5, - 0,0,115,10,0,0,0,0,2,8,1,4,1,12,1,14, - 1,122,23,80,97,116,104,70,105,110,100,101,114,46,95,115, - 101,97,114,99,104,95,112,97,116,104,41,1,78,41,2,78, - 78,41,1,78,41,2,78,78,41,19,114,125,0,0,0,114, - 124,0,0,0,114,126,0,0,0,114,127,0,0,0,114,207, - 0,0,0,114,46,1,0,0,114,52,1,0,0,114,54,1, - 0,0,114,55,1,0,0,114,58,1,0,0,114,203,0,0, - 0,114,206,0,0,0,114,77,1,0,0,114,64,1,0,0, - 114,61,1,0,0,218,12,115,116,97,116,105,99,109,101,116, - 104,111,100,114,68,1,0,0,114,74,1,0,0,114,65,1, - 0,0,114,3,0,0,0,114,3,0,0,0,114,3,0,0, - 0,114,6,0,0,0,114,45,1,0,0,209,4,0,0,115, - 52,0,0,0,8,2,4,2,2,1,10,9,2,1,10,12, - 2,1,10,21,2,1,10,14,2,1,12,31,2,1,12,23, - 2,1,12,12,4,2,2,1,12,17,2,1,10,8,2,1, - 10,8,2,1,10,4,2,1,114,45,1,0,0,99,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,64,0,0,0,115,90,0,0,0,101,0,90,1,100, - 0,90,2,100,1,90,3,100,2,100,3,132,0,90,4,100, - 4,100,5,132,0,90,5,101,6,90,7,100,6,100,7,132, - 0,90,8,100,8,100,9,132,0,90,9,100,19,100,11,100, - 12,132,1,90,10,100,13,100,14,132,0,90,11,101,12,100, - 15,100,16,132,0,131,1,90,13,100,17,100,18,132,0,90, - 14,100,10,83,0,41,20,218,10,70,105,108,101,70,105,110, - 100,101,114,122,172,70,105,108,101,45,98,97,115,101,100,32, - 102,105,110,100,101,114,46,10,10,32,32,32,32,73,110,116, - 101,114,97,99,116,105,111,110,115,32,119,105,116,104,32,116, - 104,101,32,102,105,108,101,32,115,121,115,116,101,109,32,97, - 114,101,32,99,97,99,104,101,100,32,102,111,114,32,112,101, - 114,102,111,114,109,97,110,99,101,44,32,98,101,105,110,103, - 10,32,32,32,32,114,101,102,114,101,115,104,101,100,32,119, - 104,101,110,32,116,104,101,32,100,105,114,101,99,116,111,114, - 121,32,116,104,101,32,102,105,110,100,101,114,32,105,115,32, - 104,97,110,100,108,105,110,103,32,104,97,115,32,98,101,101, - 110,32,109,111,100,105,102,105,101,100,46,10,10,32,32,32, - 32,99,2,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,6,0,0,0,7,0,0,0,115,84,0,0,0,103, - 0,125,3,124,2,68,0,93,32,92,2,137,0,125,4,124, - 3,160,0,135,0,102,1,100,1,100,2,132,8,124,4,68, - 0,131,1,161,1,1,0,113,8,124,3,124,0,95,1,124, - 1,112,54,100,3,124,0,95,2,100,4,124,0,95,3,116, - 4,131,0,124,0,95,5,116,4,131,0,124,0,95,6,100, - 5,83,0,41,6,122,154,73,110,105,116,105,97,108,105,122, - 101,32,119,105,116,104,32,116,104,101,32,112,97,116,104,32, - 116,111,32,115,101,97,114,99,104,32,111,110,32,97,110,100, - 32,97,32,118,97,114,105,97,98,108,101,32,110,117,109,98, - 101,114,32,111,102,10,32,32,32,32,32,32,32,32,50,45, - 116,117,112,108,101,115,32,99,111,110,116,97,105,110,105,110, - 103,32,116,104,101,32,108,111,97,100,101,114,32,97,110,100, - 32,116,104,101,32,102,105,108,101,32,115,117,102,102,105,120, - 101,115,32,116,104,101,32,108,111,97,100,101,114,10,32,32, - 32,32,32,32,32,32,114,101,99,111,103,110,105,122,101,115, - 46,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,51,0,0,0,115,22,0,0,0,124, - 0,93,14,125,1,124,1,136,0,102,2,86,0,1,0,113, - 2,100,0,83,0,114,110,0,0,0,114,3,0,0,0,114, - 16,1,0,0,169,1,114,140,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,19,1,0,0,154,5,0,0,115,4, - 0,0,0,4,0,2,0,122,38,70,105,108,101,70,105,110, - 100,101,114,46,95,95,105,110,105,116,95,95,46,60,108,111, - 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,114, - 71,0,0,0,114,105,0,0,0,78,41,7,114,167,0,0, - 0,218,8,95,108,111,97,100,101,114,115,114,44,0,0,0, - 218,11,95,112,97,116,104,95,109,116,105,109,101,218,3,115, - 101,116,218,11,95,112,97,116,104,95,99,97,99,104,101,218, - 19,95,114,101,108,97,120,101,100,95,112,97,116,104,95,99, - 97,99,104,101,41,5,114,119,0,0,0,114,44,0,0,0, - 218,14,108,111,97,100,101,114,95,100,101,116,97,105,108,115, - 90,7,108,111,97,100,101,114,115,114,189,0,0,0,114,3, - 0,0,0,114,80,1,0,0,114,6,0,0,0,114,209,0, - 0,0,148,5,0,0,115,16,0,0,0,0,4,4,1,12, - 1,26,1,6,2,10,1,6,1,8,1,122,19,70,105,108, - 101,70,105,110,100,101,114,46,95,95,105,110,105,116,95,95, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,78,41, + 3,114,203,0,0,0,114,140,0,0,0,114,178,0,0,0, + 41,3,114,119,0,0,0,114,139,0,0,0,114,187,0,0, + 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, + 114,137,0,0,0,168,5,0,0,115,8,0,0,0,0,7, + 10,1,8,1,8,1,122,22,70,105,108,101,70,105,110,100, + 101,114,46,102,105,110,100,95,108,111,97,100,101,114,99,6, + 0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,6, + 0,0,0,67,0,0,0,115,26,0,0,0,124,1,124,2, + 124,3,131,2,125,6,116,0,124,2,124,3,124,6,124,4, + 100,1,141,4,83,0,41,2,78,114,177,0,0,0,41,1, + 114,190,0,0,0,41,7,114,119,0,0,0,114,188,0,0, + 0,114,139,0,0,0,114,44,0,0,0,90,4,115,109,115, + 108,114,202,0,0,0,114,140,0,0,0,114,3,0,0,0, + 114,3,0,0,0,114,6,0,0,0,114,58,1,0,0,180, + 5,0,0,115,8,0,0,0,0,1,10,1,8,1,2,255, + 122,20,70,105,108,101,70,105,110,100,101,114,46,95,103,101, + 116,95,115,112,101,99,78,99,3,0,0,0,0,0,0,0, + 0,0,0,0,14,0,0,0,8,0,0,0,67,0,0,0, + 115,98,1,0,0,100,1,125,3,124,1,160,0,100,2,161, + 1,100,3,25,0,125,4,122,24,116,1,124,0,106,2,112, + 34,116,3,160,4,161,0,131,1,106,5,125,5,87,0,110, + 24,4,0,116,6,107,10,114,66,1,0,1,0,1,0,100, + 4,125,5,89,0,110,2,88,0,124,5,124,0,106,7,107, + 3,114,92,124,0,160,8,161,0,1,0,124,5,124,0,95, + 7,116,9,131,0,114,114,124,0,106,10,125,6,124,4,160, + 11,161,0,125,7,110,10,124,0,106,12,125,6,124,4,125, + 7,124,7,124,6,107,6,114,218,116,13,124,0,106,2,124, + 4,131,2,125,8,124,0,106,14,68,0,93,58,92,2,125, + 9,125,10,100,5,124,9,23,0,125,11,116,13,124,8,124, + 11,131,2,125,12,116,15,124,12,131,1,114,150,124,0,160, + 16,124,10,124,1,124,12,124,8,103,1,124,2,161,5,2, + 0,1,0,83,0,113,150,116,17,124,8,131,1,125,3,124, + 0,106,14,68,0,93,82,92,2,125,9,125,10,116,13,124, + 0,106,2,124,4,124,9,23,0,131,2,125,12,116,18,106, + 19,100,6,124,12,100,3,100,7,141,3,1,0,124,7,124, + 9,23,0,124,6,107,6,114,224,116,15,124,12,131,1,114, + 224,124,0,160,16,124,10,124,1,124,12,100,8,124,2,161, + 5,2,0,1,0,83,0,113,224,124,3,144,1,114,94,116, + 18,160,19,100,9,124,8,161,2,1,0,116,18,160,20,124, + 1,100,8,161,2,125,13,124,8,103,1,124,13,95,21,124, + 13,83,0,100,8,83,0,41,10,122,111,84,114,121,32,116, + 111,32,102,105,110,100,32,97,32,115,112,101,99,32,102,111, + 114,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, + 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, + 32,82,101,116,117,114,110,115,32,116,104,101,32,109,97,116, + 99,104,105,110,103,32,115,112,101,99,44,32,111,114,32,78, + 111,110,101,32,105,102,32,110,111,116,32,102,111,117,110,100, + 46,10,32,32,32,32,32,32,32,32,70,114,71,0,0,0, + 114,28,0,0,0,114,105,0,0,0,114,209,0,0,0,122, + 9,116,114,121,105,110,103,32,123,125,41,1,90,9,118,101, + 114,98,111,115,105,116,121,78,122,25,112,111,115,115,105,98, + 108,101,32,110,97,109,101,115,112,97,99,101,32,102,111,114, + 32,123,125,41,22,114,41,0,0,0,114,49,0,0,0,114, + 44,0,0,0,114,2,0,0,0,114,55,0,0,0,114,10, + 1,0,0,114,50,0,0,0,114,82,1,0,0,218,11,95, + 102,105,108,108,95,99,97,99,104,101,114,7,0,0,0,114, + 85,1,0,0,114,106,0,0,0,114,84,1,0,0,114,38, + 0,0,0,114,81,1,0,0,114,54,0,0,0,114,58,1, + 0,0,114,56,0,0,0,114,134,0,0,0,114,149,0,0, + 0,114,183,0,0,0,114,178,0,0,0,41,14,114,119,0, + 0,0,114,139,0,0,0,114,202,0,0,0,90,12,105,115, + 95,110,97,109,101,115,112,97,99,101,90,11,116,97,105,108, + 95,109,111,100,117,108,101,114,169,0,0,0,90,5,99,97, + 99,104,101,90,12,99,97,99,104,101,95,109,111,100,117,108, + 101,90,9,98,97,115,101,95,112,97,116,104,114,17,1,0, + 0,114,188,0,0,0,90,13,105,110,105,116,95,102,105,108, + 101,110,97,109,101,90,9,102,117,108,108,95,112,97,116,104, + 114,187,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,114,203,0,0,0,185,5,0,0,115,74,0, + 0,0,0,5,4,1,14,1,2,1,24,1,14,1,10,1, + 10,1,8,1,6,2,6,1,6,1,10,2,6,1,4,2, + 8,1,12,1,14,1,8,1,10,1,8,1,26,4,8,2, + 14,1,16,1,16,1,12,1,8,1,10,1,2,0,2,255, + 10,2,6,1,12,1,12,1,8,1,4,1,122,20,70,105, + 108,101,70,105,110,100,101,114,46,102,105,110,100,95,115,112, + 101,99,99,1,0,0,0,0,0,0,0,0,0,0,0,9, + 0,0,0,10,0,0,0,67,0,0,0,115,190,0,0,0, + 124,0,106,0,125,1,122,22,116,1,160,2,124,1,112,22, + 116,1,160,3,161,0,161,1,125,2,87,0,110,30,4,0, + 116,4,116,5,116,6,102,3,107,10,114,58,1,0,1,0, + 1,0,103,0,125,2,89,0,110,2,88,0,116,7,106,8, + 160,9,100,1,161,1,115,84,116,10,124,2,131,1,124,0, + 95,11,110,74,116,10,131,0,125,3,124,2,68,0,93,56, + 125,4,124,4,160,12,100,2,161,1,92,3,125,5,125,6, + 125,7,124,6,114,136,100,3,160,13,124,5,124,7,160,14, + 161,0,161,2,125,8,110,4,124,5,125,8,124,3,160,15, + 124,8,161,1,1,0,113,94,124,3,124,0,95,11,116,7, + 106,8,160,9,116,16,161,1,114,186,100,4,100,5,132,0, + 124,2,68,0,131,1,124,0,95,17,100,6,83,0,41,7, + 122,68,70,105,108,108,32,116,104,101,32,99,97,99,104,101, + 32,111,102,32,112,111,116,101,110,116,105,97,108,32,109,111, + 100,117,108,101,115,32,97,110,100,32,112,97,99,107,97,103, + 101,115,32,102,111,114,32,116,104,105,115,32,100,105,114,101, + 99,116,111,114,121,46,114,0,0,0,0,114,71,0,0,0, + 114,61,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,4,0,0,0,83,0,0,0,115,20, + 0,0,0,104,0,124,0,93,12,125,1,124,1,160,0,161, + 0,146,2,113,4,83,0,114,3,0,0,0,41,1,114,106, + 0,0,0,41,2,114,32,0,0,0,90,2,102,110,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,218,9,60, + 115,101,116,99,111,109,112,62,6,6,0,0,115,4,0,0, + 0,6,0,2,0,122,41,70,105,108,101,70,105,110,100,101, + 114,46,95,102,105,108,108,95,99,97,99,104,101,46,60,108, + 111,99,97,108,115,62,46,60,115,101,116,99,111,109,112,62, + 78,41,18,114,44,0,0,0,114,2,0,0,0,114,7,1, + 0,0,114,55,0,0,0,114,3,1,0,0,218,15,80,101, + 114,109,105,115,115,105,111,110,69,114,114,111,114,218,18,78, + 111,116,65,68,105,114,101,99,116,111,114,121,69,114,114,111, + 114,114,8,0,0,0,114,9,0,0,0,114,10,0,0,0, + 114,83,1,0,0,114,84,1,0,0,114,101,0,0,0,114, + 62,0,0,0,114,106,0,0,0,218,3,97,100,100,114,11, + 0,0,0,114,85,1,0,0,41,9,114,119,0,0,0,114, + 44,0,0,0,114,8,1,0,0,90,21,108,111,119,101,114, + 95,115,117,102,102,105,120,95,99,111,110,116,101,110,116,115, + 114,41,1,0,0,114,117,0,0,0,114,29,1,0,0,114, + 17,1,0,0,90,8,110,101,119,95,110,97,109,101,114,3, + 0,0,0,114,3,0,0,0,114,6,0,0,0,114,87,1, + 0,0,233,5,0,0,115,34,0,0,0,0,2,6,1,2, + 1,22,1,20,3,10,3,12,1,12,7,6,1,8,1,16, + 1,4,1,18,2,4,1,12,1,6,1,12,1,122,22,70, + 105,108,101,70,105,110,100,101,114,46,95,102,105,108,108,95, + 99,97,99,104,101,99,1,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,3,0,0,0,7,0,0,0,115,18, + 0,0,0,135,0,135,1,102,2,100,1,100,2,132,8,125, + 2,124,2,83,0,41,3,97,20,1,0,0,65,32,99,108, + 97,115,115,32,109,101,116,104,111,100,32,119,104,105,99,104, + 32,114,101,116,117,114,110,115,32,97,32,99,108,111,115,117, + 114,101,32,116,111,32,117,115,101,32,111,110,32,115,121,115, + 46,112,97,116,104,95,104,111,111,107,10,32,32,32,32,32, + 32,32,32,119,104,105,99,104,32,119,105,108,108,32,114,101, + 116,117,114,110,32,97,110,32,105,110,115,116,97,110,99,101, + 32,117,115,105,110,103,32,116,104,101,32,115,112,101,99,105, + 102,105,101,100,32,108,111,97,100,101,114,115,32,97,110,100, + 32,116,104,101,32,112,97,116,104,10,32,32,32,32,32,32, + 32,32,99,97,108,108,101,100,32,111,110,32,116,104,101,32, + 99,108,111,115,117,114,101,46,10,10,32,32,32,32,32,32, + 32,32,73,102,32,116,104,101,32,112,97,116,104,32,99,97, + 108,108,101,100,32,111,110,32,116,104,101,32,99,108,111,115, + 117,114,101,32,105,115,32,110,111,116,32,97,32,100,105,114, + 101,99,116,111,114,121,44,32,73,109,112,111,114,116,69,114, + 114,111,114,32,105,115,10,32,32,32,32,32,32,32,32,114, + 97,105,115,101,100,46,10,10,32,32,32,32,32,32,32,32, 99,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - 0,2,0,0,0,67,0,0,0,115,10,0,0,0,100,1, - 124,0,95,0,100,2,83,0,41,3,122,31,73,110,118,97, - 108,105,100,97,116,101,32,116,104,101,32,100,105,114,101,99, - 116,111,114,121,32,109,116,105,109,101,46,114,105,0,0,0, - 78,41,1,114,82,1,0,0,114,246,0,0,0,114,3,0, - 0,0,114,3,0,0,0,114,6,0,0,0,114,46,1,0, - 0,162,5,0,0,115,2,0,0,0,0,2,122,28,70,105, - 108,101,70,105,110,100,101,114,46,105,110,118,97,108,105,100, - 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, - 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, - 0,0,0,115,42,0,0,0,124,0,160,0,124,1,161,1, - 125,2,124,2,100,1,107,8,114,26,100,1,103,0,102,2, - 83,0,124,2,106,1,124,2,106,2,112,38,103,0,102,2, - 83,0,41,2,122,197,84,114,121,32,116,111,32,102,105,110, - 100,32,97,32,108,111,97,100,101,114,32,102,111,114,32,116, - 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, - 117,108,101,44,32,111,114,32,116,104,101,32,110,97,109,101, - 115,112,97,99,101,10,32,32,32,32,32,32,32,32,112,97, - 99,107,97,103,101,32,112,111,114,116,105,111,110,115,46,32, - 82,101,116,117,114,110,115,32,40,108,111,97,100,101,114,44, - 32,108,105,115,116,45,111,102,45,112,111,114,116,105,111,110, - 115,41,46,10,10,32,32,32,32,32,32,32,32,84,104,105, - 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, - 101,99,97,116,101,100,46,32,32,85,115,101,32,102,105,110, - 100,95,115,112,101,99,40,41,32,105,110,115,116,101,97,100, - 46,10,10,32,32,32,32,32,32,32,32,78,41,3,114,203, - 0,0,0,114,140,0,0,0,114,178,0,0,0,41,3,114, - 119,0,0,0,114,139,0,0,0,114,187,0,0,0,114,3, - 0,0,0,114,3,0,0,0,114,6,0,0,0,114,137,0, - 0,0,168,5,0,0,115,8,0,0,0,0,7,10,1,8, - 1,8,1,122,22,70,105,108,101,70,105,110,100,101,114,46, - 102,105,110,100,95,108,111,97,100,101,114,99,6,0,0,0, - 0,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0, - 67,0,0,0,115,26,0,0,0,124,1,124,2,124,3,131, - 2,125,6,116,0,124,2,124,3,124,6,124,4,100,1,141, - 4,83,0,41,2,78,114,177,0,0,0,41,1,114,190,0, - 0,0,41,7,114,119,0,0,0,114,188,0,0,0,114,139, - 0,0,0,114,44,0,0,0,90,4,115,109,115,108,114,202, - 0,0,0,114,140,0,0,0,114,3,0,0,0,114,3,0, - 0,0,114,6,0,0,0,114,58,1,0,0,180,5,0,0, - 115,8,0,0,0,0,1,10,1,8,1,2,255,122,20,70, - 105,108,101,70,105,110,100,101,114,46,95,103,101,116,95,115, - 112,101,99,78,99,3,0,0,0,0,0,0,0,0,0,0, - 0,14,0,0,0,8,0,0,0,67,0,0,0,115,102,1, - 0,0,100,1,125,3,124,1,160,0,100,2,161,1,100,3, - 25,0,125,4,122,24,116,1,124,0,106,2,112,34,116,3, - 160,4,161,0,131,1,106,5,125,5,87,0,110,24,4,0, - 116,6,107,10,114,66,1,0,1,0,1,0,100,4,125,5, - 89,0,110,2,88,0,124,5,124,0,106,7,107,3,114,92, - 124,0,160,8,161,0,1,0,124,5,124,0,95,7,116,9, - 131,0,114,114,124,0,106,10,125,6,124,4,160,11,161,0, - 125,7,110,10,124,0,106,12,125,6,124,4,125,7,124,7, - 124,6,107,6,114,218,116,13,124,0,106,2,124,4,131,2, - 125,8,124,0,106,14,68,0,93,58,92,2,125,9,125,10, - 100,5,124,9,23,0,125,11,116,13,124,8,124,11,131,2, - 125,12,116,15,124,12,131,1,114,208,124,0,160,16,124,10, - 124,1,124,12,124,8,103,1,124,2,161,5,2,0,1,0, - 83,0,113,150,116,17,124,8,131,1,125,3,124,0,106,14, - 68,0,93,86,92,2,125,9,125,10,116,13,124,0,106,2, - 124,4,124,9,23,0,131,2,125,12,116,18,106,19,100,6, - 124,12,100,3,100,7,141,3,1,0,124,7,124,9,23,0, - 124,6,107,6,144,1,114,54,116,15,124,12,131,1,144,1, - 114,54,124,0,160,16,124,10,124,1,124,12,100,8,124,2, - 161,5,2,0,1,0,83,0,113,224,124,3,144,1,114,98, - 116,18,160,19,100,9,124,8,161,2,1,0,116,18,160,20, - 124,1,100,8,161,2,125,13,124,8,103,1,124,13,95,21, - 124,13,83,0,100,8,83,0,41,10,122,111,84,114,121,32, - 116,111,32,102,105,110,100,32,97,32,115,112,101,99,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32, - 32,32,82,101,116,117,114,110,115,32,116,104,101,32,109,97, - 116,99,104,105,110,103,32,115,112,101,99,44,32,111,114,32, - 78,111,110,101,32,105,102,32,110,111,116,32,102,111,117,110, - 100,46,10,32,32,32,32,32,32,32,32,70,114,71,0,0, - 0,114,28,0,0,0,114,105,0,0,0,114,209,0,0,0, - 122,9,116,114,121,105,110,103,32,123,125,41,1,90,9,118, - 101,114,98,111,115,105,116,121,78,122,25,112,111,115,115,105, - 98,108,101,32,110,97,109,101,115,112,97,99,101,32,102,111, - 114,32,123,125,41,22,114,41,0,0,0,114,49,0,0,0, - 114,44,0,0,0,114,2,0,0,0,114,55,0,0,0,114, - 10,1,0,0,114,50,0,0,0,114,82,1,0,0,218,11, - 95,102,105,108,108,95,99,97,99,104,101,114,7,0,0,0, - 114,85,1,0,0,114,106,0,0,0,114,84,1,0,0,114, - 38,0,0,0,114,81,1,0,0,114,54,0,0,0,114,58, - 1,0,0,114,56,0,0,0,114,134,0,0,0,114,149,0, - 0,0,114,183,0,0,0,114,178,0,0,0,41,14,114,119, - 0,0,0,114,139,0,0,0,114,202,0,0,0,90,12,105, - 115,95,110,97,109,101,115,112,97,99,101,90,11,116,97,105, - 108,95,109,111,100,117,108,101,114,169,0,0,0,90,5,99, - 97,99,104,101,90,12,99,97,99,104,101,95,109,111,100,117, - 108,101,90,9,98,97,115,101,95,112,97,116,104,114,17,1, - 0,0,114,188,0,0,0,90,13,105,110,105,116,95,102,105, - 108,101,110,97,109,101,90,9,102,117,108,108,95,112,97,116, - 104,114,187,0,0,0,114,3,0,0,0,114,3,0,0,0, - 114,6,0,0,0,114,203,0,0,0,185,5,0,0,115,74, - 0,0,0,0,5,4,1,14,1,2,1,24,1,14,1,10, - 1,10,1,8,1,6,2,6,1,6,1,10,2,6,1,4, - 2,8,1,12,1,14,1,8,1,10,1,8,1,26,4,8, - 2,14,1,16,1,16,1,14,1,10,1,10,1,2,0,2, - 255,10,2,6,1,12,1,12,1,8,1,4,1,122,20,70, - 105,108,101,70,105,110,100,101,114,46,102,105,110,100,95,115, - 112,101,99,99,1,0,0,0,0,0,0,0,0,0,0,0, - 9,0,0,0,10,0,0,0,67,0,0,0,115,190,0,0, - 0,124,0,106,0,125,1,122,22,116,1,160,2,124,1,112, - 22,116,1,160,3,161,0,161,1,125,2,87,0,110,30,4, - 0,116,4,116,5,116,6,102,3,107,10,114,58,1,0,1, - 0,1,0,103,0,125,2,89,0,110,2,88,0,116,7,106, - 8,160,9,100,1,161,1,115,84,116,10,124,2,131,1,124, - 0,95,11,110,74,116,10,131,0,125,3,124,2,68,0,93, - 56,125,4,124,4,160,12,100,2,161,1,92,3,125,5,125, - 6,125,7,124,6,114,136,100,3,160,13,124,5,124,7,160, - 14,161,0,161,2,125,8,110,4,124,5,125,8,124,3,160, - 15,124,8,161,1,1,0,113,94,124,3,124,0,95,11,116, - 7,106,8,160,9,116,16,161,1,114,186,100,4,100,5,132, - 0,124,2,68,0,131,1,124,0,95,17,100,6,83,0,41, - 7,122,68,70,105,108,108,32,116,104,101,32,99,97,99,104, - 101,32,111,102,32,112,111,116,101,110,116,105,97,108,32,109, - 111,100,117,108,101,115,32,97,110,100,32,112,97,99,107,97, - 103,101,115,32,102,111,114,32,116,104,105,115,32,100,105,114, - 101,99,116,111,114,121,46,114,0,0,0,0,114,71,0,0, - 0,114,61,0,0,0,99,1,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,4,0,0,0,83,0,0,0,115, - 20,0,0,0,104,0,124,0,93,12,125,1,124,1,160,0, - 161,0,146,2,113,4,83,0,114,3,0,0,0,41,1,114, - 106,0,0,0,41,2,114,32,0,0,0,90,2,102,110,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,218,9, - 60,115,101,116,99,111,109,112,62,6,6,0,0,115,4,0, - 0,0,6,0,2,0,122,41,70,105,108,101,70,105,110,100, - 101,114,46,95,102,105,108,108,95,99,97,99,104,101,46,60, - 108,111,99,97,108,115,62,46,60,115,101,116,99,111,109,112, - 62,78,41,18,114,44,0,0,0,114,2,0,0,0,114,7, - 1,0,0,114,55,0,0,0,114,3,1,0,0,218,15,80, - 101,114,109,105,115,115,105,111,110,69,114,114,111,114,218,18, - 78,111,116,65,68,105,114,101,99,116,111,114,121,69,114,114, - 111,114,114,8,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,83,1,0,0,114,84,1,0,0,114,101,0,0,0, - 114,62,0,0,0,114,106,0,0,0,218,3,97,100,100,114, - 11,0,0,0,114,85,1,0,0,41,9,114,119,0,0,0, - 114,44,0,0,0,114,8,1,0,0,90,21,108,111,119,101, - 114,95,115,117,102,102,105,120,95,99,111,110,116,101,110,116, - 115,114,41,1,0,0,114,117,0,0,0,114,29,1,0,0, - 114,17,1,0,0,90,8,110,101,119,95,110,97,109,101,114, - 3,0,0,0,114,3,0,0,0,114,6,0,0,0,114,87, - 1,0,0,233,5,0,0,115,34,0,0,0,0,2,6,1, - 2,1,22,1,20,3,10,3,12,1,12,7,6,1,8,1, - 16,1,4,1,18,2,4,1,12,1,6,1,12,1,122,22, - 70,105,108,101,70,105,110,100,101,114,46,95,102,105,108,108, - 95,99,97,99,104,101,99,1,0,0,0,0,0,0,0,0, - 0,0,0,3,0,0,0,3,0,0,0,7,0,0,0,115, - 18,0,0,0,135,0,135,1,102,2,100,1,100,2,132,8, - 125,2,124,2,83,0,41,3,97,20,1,0,0,65,32,99, - 108,97,115,115,32,109,101,116,104,111,100,32,119,104,105,99, - 104,32,114,101,116,117,114,110,115,32,97,32,99,108,111,115, - 117,114,101,32,116,111,32,117,115,101,32,111,110,32,115,121, - 115,46,112,97,116,104,95,104,111,111,107,10,32,32,32,32, - 32,32,32,32,119,104,105,99,104,32,119,105,108,108,32,114, - 101,116,117,114,110,32,97,110,32,105,110,115,116,97,110,99, - 101,32,117,115,105,110,103,32,116,104,101,32,115,112,101,99, - 105,102,105,101,100,32,108,111,97,100,101,114,115,32,97,110, - 100,32,116,104,101,32,112,97,116,104,10,32,32,32,32,32, - 32,32,32,99,97,108,108,101,100,32,111,110,32,116,104,101, - 32,99,108,111,115,117,114,101,46,10,10,32,32,32,32,32, - 32,32,32,73,102,32,116,104,101,32,112,97,116,104,32,99, - 97,108,108,101,100,32,111,110,32,116,104,101,32,99,108,111, - 115,117,114,101,32,105,115,32,110,111,116,32,97,32,100,105, - 114,101,99,116,111,114,121,44,32,73,109,112,111,114,116,69, - 114,114,111,114,32,105,115,10,32,32,32,32,32,32,32,32, - 114,97,105,115,101,100,46,10,10,32,32,32,32,32,32,32, - 32,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,4,0,0,0,19,0,0,0,115,34,0,0,0,116, - 0,124,0,131,1,115,20,116,1,100,1,124,0,100,2,141, - 2,130,1,136,0,124,0,102,1,136,1,158,2,142,0,83, - 0,41,3,122,45,80,97,116,104,32,104,111,111,107,32,102, - 111,114,32,105,109,112,111,114,116,108,105,98,46,109,97,99, - 104,105,110,101,114,121,46,70,105,108,101,70,105,110,100,101, - 114,46,122,30,111,110,108,121,32,100,105,114,101,99,116,111, - 114,105,101,115,32,97,114,101,32,115,117,112,112,111,114,116, - 101,100,114,48,0,0,0,41,2,114,56,0,0,0,114,118, - 0,0,0,114,48,0,0,0,169,2,114,193,0,0,0,114, - 86,1,0,0,114,3,0,0,0,114,6,0,0,0,218,24, - 112,97,116,104,95,104,111,111,107,95,102,111,114,95,70,105, - 108,101,70,105,110,100,101,114,18,6,0,0,115,6,0,0, - 0,0,2,8,1,12,1,122,54,70,105,108,101,70,105,110, - 100,101,114,46,112,97,116,104,95,104,111,111,107,46,60,108, - 111,99,97,108,115,62,46,112,97,116,104,95,104,111,111,107, - 95,102,111,114,95,70,105,108,101,70,105,110,100,101,114,114, - 3,0,0,0,41,3,114,193,0,0,0,114,86,1,0,0, - 114,93,1,0,0,114,3,0,0,0,114,92,1,0,0,114, - 6,0,0,0,218,9,112,97,116,104,95,104,111,111,107,8, - 6,0,0,115,4,0,0,0,0,10,14,6,122,20,70,105, - 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, - 111,107,99,1,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,67,0,0,0,115,12,0,0,0, - 100,1,160,0,124,0,106,1,161,1,83,0,41,2,78,122, - 16,70,105,108,101,70,105,110,100,101,114,40,123,33,114,125, - 41,41,2,114,62,0,0,0,114,44,0,0,0,114,246,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,114,39,1,0,0,26,6,0,0,115,2,0,0,0,0, - 1,122,19,70,105,108,101,70,105,110,100,101,114,46,95,95, - 114,101,112,114,95,95,41,1,78,41,15,114,125,0,0,0, - 114,124,0,0,0,114,126,0,0,0,114,127,0,0,0,114, - 209,0,0,0,114,46,1,0,0,114,143,0,0,0,114,206, - 0,0,0,114,137,0,0,0,114,58,1,0,0,114,203,0, - 0,0,114,87,1,0,0,114,207,0,0,0,114,94,1,0, - 0,114,39,1,0,0,114,3,0,0,0,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,79,1,0,0,139, - 5,0,0,115,22,0,0,0,8,2,4,7,8,14,8,4, - 4,2,8,12,8,5,10,48,8,31,2,1,10,17,114,79, - 1,0,0,99,4,0,0,0,0,0,0,0,0,0,0,0, - 6,0,0,0,8,0,0,0,67,0,0,0,115,146,0,0, - 0,124,0,160,0,100,1,161,1,125,4,124,0,160,0,100, - 2,161,1,125,5,124,4,115,66,124,5,114,36,124,5,106, - 1,125,4,110,30,124,2,124,3,107,2,114,56,116,2,124, - 1,124,2,131,2,125,4,110,10,116,3,124,1,124,2,131, - 2,125,4,124,5,115,84,116,4,124,1,124,2,124,4,100, - 3,141,3,125,5,122,36,124,5,124,0,100,2,60,0,124, - 4,124,0,100,1,60,0,124,2,124,0,100,4,60,0,124, - 3,124,0,100,5,60,0,87,0,110,20,4,0,116,5,107, - 10,114,140,1,0,1,0,1,0,89,0,110,2,88,0,100, - 0,83,0,41,6,78,218,10,95,95,108,111,97,100,101,114, - 95,95,218,8,95,95,115,112,101,99,95,95,114,80,1,0, - 0,90,8,95,95,102,105,108,101,95,95,90,10,95,95,99, - 97,99,104,101,100,95,95,41,6,218,3,103,101,116,114,140, - 0,0,0,114,15,1,0,0,114,9,1,0,0,114,190,0, - 0,0,114,72,1,0,0,41,6,90,2,110,115,114,117,0, - 0,0,90,8,112,97,116,104,110,97,109,101,90,9,99,112, - 97,116,104,110,97,109,101,114,140,0,0,0,114,187,0,0, + 0,4,0,0,0,19,0,0,0,115,34,0,0,0,116,0, + 124,0,131,1,115,20,116,1,100,1,124,0,100,2,141,2, + 130,1,136,0,124,0,102,1,136,1,158,2,142,0,83,0, + 41,3,122,45,80,97,116,104,32,104,111,111,107,32,102,111, + 114,32,105,109,112,111,114,116,108,105,98,46,109,97,99,104, + 105,110,101,114,121,46,70,105,108,101,70,105,110,100,101,114, + 46,122,30,111,110,108,121,32,100,105,114,101,99,116,111,114, + 105,101,115,32,97,114,101,32,115,117,112,112,111,114,116,101, + 100,114,48,0,0,0,41,2,114,56,0,0,0,114,118,0, + 0,0,114,48,0,0,0,169,2,114,193,0,0,0,114,86, + 1,0,0,114,3,0,0,0,114,6,0,0,0,218,24,112, + 97,116,104,95,104,111,111,107,95,102,111,114,95,70,105,108, + 101,70,105,110,100,101,114,18,6,0,0,115,6,0,0,0, + 0,2,8,1,12,1,122,54,70,105,108,101,70,105,110,100, + 101,114,46,112,97,116,104,95,104,111,111,107,46,60,108,111, + 99,97,108,115,62,46,112,97,116,104,95,104,111,111,107,95, + 102,111,114,95,70,105,108,101,70,105,110,100,101,114,114,3, + 0,0,0,41,3,114,193,0,0,0,114,86,1,0,0,114, + 93,1,0,0,114,3,0,0,0,114,92,1,0,0,114,6, + 0,0,0,218,9,112,97,116,104,95,104,111,111,107,8,6, + 0,0,115,4,0,0,0,0,10,14,6,122,20,70,105,108, + 101,70,105,110,100,101,114,46,112,97,116,104,95,104,111,111, + 107,99,1,0,0,0,0,0,0,0,0,0,0,0,1,0, + 0,0,3,0,0,0,67,0,0,0,115,12,0,0,0,100, + 1,160,0,124,0,106,1,161,1,83,0,41,2,78,122,16, + 70,105,108,101,70,105,110,100,101,114,40,123,33,114,125,41, + 41,2,114,62,0,0,0,114,44,0,0,0,114,246,0,0, 0,114,3,0,0,0,114,3,0,0,0,114,6,0,0,0, - 218,14,95,102,105,120,95,117,112,95,109,111,100,117,108,101, - 32,6,0,0,115,34,0,0,0,0,2,10,1,10,1,4, - 1,4,1,8,1,8,1,12,2,10,1,4,1,14,1,2, - 1,8,1,8,1,8,1,12,1,14,2,114,98,1,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, - 0,3,0,0,0,67,0,0,0,115,38,0,0,0,116,0, - 116,1,160,2,161,0,102,2,125,0,116,3,116,4,102,2, - 125,1,116,5,116,6,102,2,125,2,124,0,124,1,124,2, - 103,3,83,0,41,1,122,95,82,101,116,117,114,110,115,32, - 97,32,108,105,115,116,32,111,102,32,102,105,108,101,45,98, - 97,115,101,100,32,109,111,100,117,108,101,32,108,111,97,100, - 101,114,115,46,10,10,32,32,32,32,69,97,99,104,32,105, - 116,101,109,32,105,115,32,97,32,116,117,112,108,101,32,40, - 108,111,97,100,101,114,44,32,115,117,102,102,105,120,101,115, - 41,46,10,32,32,32,32,41,7,114,252,0,0,0,114,163, - 0,0,0,218,18,101,120,116,101,110,115,105,111,110,95,115, - 117,102,102,105,120,101,115,114,9,1,0,0,114,102,0,0, - 0,114,15,1,0,0,114,89,0,0,0,41,3,90,10,101, - 120,116,101,110,115,105,111,110,115,90,6,115,111,117,114,99, - 101,90,8,98,121,116,101,99,111,100,101,114,3,0,0,0, - 114,3,0,0,0,114,6,0,0,0,114,184,0,0,0,55, - 6,0,0,115,8,0,0,0,0,5,12,1,8,1,8,1, - 114,184,0,0,0,99,1,0,0,0,0,0,0,0,0,0, - 0,0,12,0,0,0,9,0,0,0,67,0,0,0,115,178, - 1,0,0,124,0,97,0,116,0,106,1,97,1,116,0,106, - 2,97,2,116,1,106,3,116,4,25,0,125,1,100,1,68, - 0,93,48,125,2,124,2,116,1,106,3,107,7,114,56,116, - 0,160,5,124,2,161,1,125,3,110,10,116,1,106,3,124, - 2,25,0,125,3,116,6,124,1,124,2,124,3,131,3,1, - 0,113,30,100,2,100,3,103,1,102,2,100,4,100,5,100, - 3,103,2,102,2,102,2,125,4,124,4,68,0,93,110,92, - 2,125,5,125,6,116,7,100,6,100,7,132,0,124,6,68, - 0,131,1,131,1,115,136,116,8,130,1,124,6,100,8,25, - 0,125,7,124,5,116,1,106,3,107,6,114,170,116,1,106, - 3,124,5,25,0,125,8,1,0,113,226,113,106,122,20,116, - 0,160,5,124,5,161,1,125,8,87,0,1,0,113,226,87, - 0,113,106,4,0,116,9,107,10,114,214,1,0,1,0,1, - 0,89,0,113,106,89,0,113,106,88,0,113,106,116,9,100, - 9,131,1,130,1,116,6,124,1,100,10,124,8,131,3,1, - 0,116,6,124,1,100,11,124,7,131,3,1,0,116,6,124, - 1,100,12,100,13,160,10,124,6,161,1,131,3,1,0,116, - 6,124,1,100,14,100,15,100,16,132,0,124,6,68,0,131, - 1,131,3,1,0,116,0,160,5,100,17,161,1,125,9,116, - 6,124,1,100,17,124,9,131,3,1,0,116,0,160,5,100, - 18,161,1,125,10,116,6,124,1,100,18,124,10,131,3,1, - 0,124,5,100,4,107,2,144,1,114,110,116,0,160,5,100, - 19,161,1,125,11,116,6,124,1,100,20,124,11,131,3,1, - 0,116,6,124,1,100,21,116,11,131,0,131,3,1,0,116, - 12,160,13,116,2,160,14,161,0,161,1,1,0,124,5,100, - 4,107,2,144,1,114,174,116,15,160,16,100,22,161,1,1, - 0,100,23,116,12,107,6,144,1,114,174,100,24,116,17,95, - 18,100,25,83,0,41,26,122,205,83,101,116,117,112,32,116, - 104,101,32,112,97,116,104,45,98,97,115,101,100,32,105,109, - 112,111,114,116,101,114,115,32,102,111,114,32,105,109,112,111, - 114,116,108,105,98,32,98,121,32,105,109,112,111,114,116,105, - 110,103,32,110,101,101,100,101,100,10,32,32,32,32,98,117, - 105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,97, - 110,100,32,105,110,106,101,99,116,105,110,103,32,116,104,101, - 109,32,105,110,116,111,32,116,104,101,32,103,108,111,98,97, - 108,32,110,97,109,101,115,112,97,99,101,46,10,10,32,32, - 32,32,79,116,104,101,114,32,99,111,109,112,111,110,101,110, - 116,115,32,97,114,101,32,101,120,116,114,97,99,116,101,100, - 32,102,114,111,109,32,116,104,101,32,99,111,114,101,32,98, - 111,111,116,115,116,114,97,112,32,109,111,100,117,108,101,46, - 10,10,32,32,32,32,41,4,114,64,0,0,0,114,75,0, - 0,0,218,8,98,117,105,108,116,105,110,115,114,160,0,0, - 0,90,5,112,111,115,105,120,250,1,47,90,2,110,116,250, - 1,92,99,1,0,0,0,0,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,115,0,0,0,115,26,0,0,0, - 124,0,93,18,125,1,116,0,124,1,131,1,100,0,107,2, - 86,0,1,0,113,2,100,1,83,0,41,2,114,39,0,0, - 0,78,41,1,114,22,0,0,0,41,2,114,32,0,0,0, - 114,95,0,0,0,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,114,19,1,0,0,91,6,0,0,115,4,0, - 0,0,4,0,2,0,122,25,95,115,101,116,117,112,46,60, - 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, - 62,114,73,0,0,0,122,30,105,109,112,111,114,116,108,105, - 98,32,114,101,113,117,105,114,101,115,32,112,111,115,105,120, - 32,111,114,32,110,116,114,2,0,0,0,114,35,0,0,0, - 114,31,0,0,0,114,40,0,0,0,114,58,0,0,0,99, - 1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, - 4,0,0,0,83,0,0,0,115,22,0,0,0,104,0,124, - 0,93,14,125,1,100,0,124,1,155,0,157,2,146,2,113, - 4,83,0,41,1,114,74,0,0,0,114,3,0,0,0,41, - 2,114,32,0,0,0,218,1,115,114,3,0,0,0,114,3, - 0,0,0,114,6,0,0,0,114,88,1,0,0,107,6,0, - 0,115,4,0,0,0,6,0,2,0,122,25,95,115,101,116, - 117,112,46,60,108,111,99,97,108,115,62,46,60,115,101,116, - 99,111,109,112,62,90,7,95,116,104,114,101,97,100,90,8, - 95,119,101,97,107,114,101,102,90,6,119,105,110,114,101,103, - 114,192,0,0,0,114,7,0,0,0,122,4,46,112,121,119, - 122,6,95,100,46,112,121,100,84,78,41,19,114,134,0,0, - 0,114,8,0,0,0,114,163,0,0,0,114,31,1,0,0, - 114,125,0,0,0,90,18,95,98,117,105,108,116,105,110,95, - 102,114,111,109,95,110,97,109,101,114,129,0,0,0,218,3, - 97,108,108,114,23,0,0,0,114,118,0,0,0,114,36,0, - 0,0,114,13,0,0,0,114,21,1,0,0,114,167,0,0, - 0,114,99,1,0,0,114,102,0,0,0,114,186,0,0,0, - 114,191,0,0,0,114,195,0,0,0,41,12,218,17,95,98, - 111,111,116,115,116,114,97,112,95,109,111,100,117,108,101,90, - 11,115,101,108,102,95,109,111,100,117,108,101,90,12,98,117, - 105,108,116,105,110,95,110,97,109,101,90,14,98,117,105,108, - 116,105,110,95,109,111,100,117,108,101,90,10,111,115,95,100, - 101,116,97,105,108,115,90,10,98,117,105,108,116,105,110,95, - 111,115,114,31,0,0,0,114,35,0,0,0,90,9,111,115, - 95,109,111,100,117,108,101,90,13,116,104,114,101,97,100,95, - 109,111,100,117,108,101,90,14,119,101,97,107,114,101,102,95, - 109,111,100,117,108,101,90,13,119,105,110,114,101,103,95,109, - 111,100,117,108,101,114,3,0,0,0,114,3,0,0,0,114, - 6,0,0,0,218,6,95,115,101,116,117,112,66,6,0,0, - 115,78,0,0,0,0,8,4,1,6,1,6,3,10,1,8, - 1,10,1,12,2,10,1,14,3,22,1,12,2,22,1,8, - 1,10,1,10,1,6,2,2,1,10,1,10,1,14,1,12, - 2,8,1,12,1,12,1,18,1,22,3,10,1,12,3,10, - 1,12,3,10,1,10,1,12,3,14,1,14,1,10,1,10, - 1,10,1,114,106,1,0,0,99,1,0,0,0,0,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,67,0,0, - 0,115,50,0,0,0,116,0,124,0,131,1,1,0,116,1, - 131,0,125,1,116,2,106,3,160,4,116,5,106,6,124,1, - 142,0,103,1,161,1,1,0,116,2,106,7,160,8,116,9, - 161,1,1,0,100,1,83,0,41,2,122,41,73,110,115,116, - 97,108,108,32,116,104,101,32,112,97,116,104,45,98,97,115, - 101,100,32,105,109,112,111,114,116,32,99,111,109,112,111,110, - 101,110,116,115,46,78,41,10,114,106,1,0,0,114,184,0, - 0,0,114,8,0,0,0,114,51,1,0,0,114,167,0,0, - 0,114,79,1,0,0,114,94,1,0,0,218,9,109,101,116, - 97,95,112,97,116,104,114,186,0,0,0,114,45,1,0,0, - 41,2,114,105,1,0,0,90,17,115,117,112,112,111,114,116, - 101,100,95,108,111,97,100,101,114,115,114,3,0,0,0,114, - 3,0,0,0,114,6,0,0,0,218,8,95,105,110,115,116, - 97,108,108,131,6,0,0,115,8,0,0,0,0,2,8,1, - 6,1,20,1,114,108,1,0,0,41,63,114,127,0,0,0, - 114,12,0,0,0,90,37,95,67,65,83,69,95,73,78,83, - 69,78,83,73,84,73,86,69,95,80,76,65,84,70,79,82, - 77,83,95,66,89,84,69,83,95,75,69,89,114,11,0,0, - 0,114,13,0,0,0,114,20,0,0,0,114,27,0,0,0, - 114,29,0,0,0,114,38,0,0,0,114,47,0,0,0,114, - 49,0,0,0,114,53,0,0,0,114,54,0,0,0,114,56, - 0,0,0,114,59,0,0,0,114,69,0,0,0,218,4,116, - 121,112,101,218,8,95,95,99,111,100,101,95,95,114,162,0, - 0,0,114,18,0,0,0,114,148,0,0,0,114,17,0,0, - 0,114,24,0,0,0,114,236,0,0,0,114,92,0,0,0, - 114,88,0,0,0,114,102,0,0,0,114,89,0,0,0,90, - 23,68,69,66,85,71,95,66,89,84,69,67,79,68,69,95, - 83,85,70,70,73,88,69,83,90,27,79,80,84,73,77,73, - 90,69,68,95,66,89,84,69,67,79,68,69,95,83,85,70, - 70,73,88,69,83,114,98,0,0,0,114,103,0,0,0,114, - 109,0,0,0,114,113,0,0,0,114,115,0,0,0,114,136, - 0,0,0,114,143,0,0,0,114,152,0,0,0,114,156,0, - 0,0,114,158,0,0,0,114,165,0,0,0,114,170,0,0, - 0,114,171,0,0,0,114,176,0,0,0,218,6,111,98,106, - 101,99,116,114,185,0,0,0,114,190,0,0,0,114,191,0, - 0,0,114,208,0,0,0,114,221,0,0,0,114,239,0,0, - 0,114,9,1,0,0,114,15,1,0,0,114,21,1,0,0, - 114,252,0,0,0,114,22,1,0,0,114,43,1,0,0,114, - 45,1,0,0,114,79,1,0,0,114,98,1,0,0,114,184, - 0,0,0,114,106,1,0,0,114,108,1,0,0,114,3,0, - 0,0,114,3,0,0,0,114,3,0,0,0,114,6,0,0, - 0,218,8,60,109,111,100,117,108,101,62,1,0,0,0,115, - 126,0,0,0,4,22,4,1,4,1,2,1,2,255,4,4, - 8,17,8,5,8,5,8,6,8,6,8,12,8,10,8,9, - 8,5,8,7,8,9,12,22,10,127,0,8,16,1,12,2, - 4,1,4,2,6,2,6,2,8,2,18,71,8,40,8,19, - 8,12,8,12,8,28,8,17,8,33,8,28,8,24,16,13, - 14,10,12,11,8,14,6,3,6,1,2,255,12,68,14,64, - 14,29,16,127,0,17,14,72,18,45,18,26,4,3,18,53, - 14,63,14,42,14,127,0,59,14,127,0,22,12,23,8,11, - 8,65, + 114,39,1,0,0,26,6,0,0,115,2,0,0,0,0,1, + 122,19,70,105,108,101,70,105,110,100,101,114,46,95,95,114, + 101,112,114,95,95,41,1,78,41,15,114,125,0,0,0,114, + 124,0,0,0,114,126,0,0,0,114,127,0,0,0,114,209, + 0,0,0,114,46,1,0,0,114,143,0,0,0,114,206,0, + 0,0,114,137,0,0,0,114,58,1,0,0,114,203,0,0, + 0,114,87,1,0,0,114,207,0,0,0,114,94,1,0,0, + 114,39,1,0,0,114,3,0,0,0,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,79,1,0,0,139,5, + 0,0,115,22,0,0,0,8,2,4,7,8,14,8,4,4, + 2,8,12,8,5,10,48,8,31,2,1,10,17,114,79,1, + 0,0,99,4,0,0,0,0,0,0,0,0,0,0,0,6, + 0,0,0,8,0,0,0,67,0,0,0,115,146,0,0,0, + 124,0,160,0,100,1,161,1,125,4,124,0,160,0,100,2, + 161,1,125,5,124,4,115,66,124,5,114,36,124,5,106,1, + 125,4,110,30,124,2,124,3,107,2,114,56,116,2,124,1, + 124,2,131,2,125,4,110,10,116,3,124,1,124,2,131,2, + 125,4,124,5,115,84,116,4,124,1,124,2,124,4,100,3, + 141,3,125,5,122,36,124,5,124,0,100,2,60,0,124,4, + 124,0,100,1,60,0,124,2,124,0,100,4,60,0,124,3, + 124,0,100,5,60,0,87,0,110,20,4,0,116,5,107,10, + 114,140,1,0,1,0,1,0,89,0,110,2,88,0,100,0, + 83,0,41,6,78,218,10,95,95,108,111,97,100,101,114,95, + 95,218,8,95,95,115,112,101,99,95,95,114,80,1,0,0, + 90,8,95,95,102,105,108,101,95,95,90,10,95,95,99,97, + 99,104,101,100,95,95,41,6,218,3,103,101,116,114,140,0, + 0,0,114,15,1,0,0,114,9,1,0,0,114,190,0,0, + 0,114,72,1,0,0,41,6,90,2,110,115,114,117,0,0, + 0,90,8,112,97,116,104,110,97,109,101,90,9,99,112,97, + 116,104,110,97,109,101,114,140,0,0,0,114,187,0,0,0, + 114,3,0,0,0,114,3,0,0,0,114,6,0,0,0,218, + 14,95,102,105,120,95,117,112,95,109,111,100,117,108,101,32, + 6,0,0,115,34,0,0,0,0,2,10,1,10,1,4,1, + 4,1,8,1,8,1,12,2,10,1,4,1,14,1,2,1, + 8,1,8,1,8,1,12,1,14,2,114,98,1,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0, + 3,0,0,0,67,0,0,0,115,38,0,0,0,116,0,116, + 1,160,2,161,0,102,2,125,0,116,3,116,4,102,2,125, + 1,116,5,116,6,102,2,125,2,124,0,124,1,124,2,103, + 3,83,0,41,1,122,95,82,101,116,117,114,110,115,32,97, + 32,108,105,115,116,32,111,102,32,102,105,108,101,45,98,97, + 115,101,100,32,109,111,100,117,108,101,32,108,111,97,100,101, + 114,115,46,10,10,32,32,32,32,69,97,99,104,32,105,116, + 101,109,32,105,115,32,97,32,116,117,112,108,101,32,40,108, + 111,97,100,101,114,44,32,115,117,102,102,105,120,101,115,41, + 46,10,32,32,32,32,41,7,114,252,0,0,0,114,163,0, + 0,0,218,18,101,120,116,101,110,115,105,111,110,95,115,117, + 102,102,105,120,101,115,114,9,1,0,0,114,102,0,0,0, + 114,15,1,0,0,114,89,0,0,0,41,3,90,10,101,120, + 116,101,110,115,105,111,110,115,90,6,115,111,117,114,99,101, + 90,8,98,121,116,101,99,111,100,101,114,3,0,0,0,114, + 3,0,0,0,114,6,0,0,0,114,184,0,0,0,55,6, + 0,0,115,8,0,0,0,0,5,12,1,8,1,8,1,114, + 184,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, + 0,12,0,0,0,9,0,0,0,67,0,0,0,115,178,1, + 0,0,124,0,97,0,116,0,106,1,97,1,116,0,106,2, + 97,2,116,1,106,3,116,4,25,0,125,1,100,1,68,0, + 93,48,125,2,124,2,116,1,106,3,107,7,114,56,116,0, + 160,5,124,2,161,1,125,3,110,10,116,1,106,3,124,2, + 25,0,125,3,116,6,124,1,124,2,124,3,131,3,1,0, + 113,30,100,2,100,3,103,1,102,2,100,4,100,5,100,3, + 103,2,102,2,102,2,125,4,124,4,68,0,93,110,92,2, + 125,5,125,6,116,7,100,6,100,7,132,0,124,6,68,0, + 131,1,131,1,115,136,116,8,130,1,124,6,100,8,25,0, + 125,7,124,5,116,1,106,3,107,6,114,170,116,1,106,3, + 124,5,25,0,125,8,1,0,113,226,113,106,122,20,116,0, + 160,5,124,5,161,1,125,8,87,0,1,0,113,226,87,0, + 113,106,4,0,116,9,107,10,114,214,1,0,1,0,1,0, + 89,0,113,106,89,0,113,106,88,0,113,106,116,9,100,9, + 131,1,130,1,116,6,124,1,100,10,124,8,131,3,1,0, + 116,6,124,1,100,11,124,7,131,3,1,0,116,6,124,1, + 100,12,100,13,160,10,124,6,161,1,131,3,1,0,116,6, + 124,1,100,14,100,15,100,16,132,0,124,6,68,0,131,1, + 131,3,1,0,116,0,160,5,100,17,161,1,125,9,116,6, + 124,1,100,17,124,9,131,3,1,0,116,0,160,5,100,18, + 161,1,125,10,116,6,124,1,100,18,124,10,131,3,1,0, + 124,5,100,4,107,2,144,1,114,110,116,0,160,5,100,19, + 161,1,125,11,116,6,124,1,100,20,124,11,131,3,1,0, + 116,6,124,1,100,21,116,11,131,0,131,3,1,0,116,12, + 160,13,116,2,160,14,161,0,161,1,1,0,124,5,100,4, + 107,2,144,1,114,174,116,15,160,16,100,22,161,1,1,0, + 100,23,116,12,107,6,144,1,114,174,100,24,116,17,95,18, + 100,25,83,0,41,26,122,205,83,101,116,117,112,32,116,104, + 101,32,112,97,116,104,45,98,97,115,101,100,32,105,109,112, + 111,114,116,101,114,115,32,102,111,114,32,105,109,112,111,114, + 116,108,105,98,32,98,121,32,105,109,112,111,114,116,105,110, + 103,32,110,101,101,100,101,100,10,32,32,32,32,98,117,105, + 108,116,45,105,110,32,109,111,100,117,108,101,115,32,97,110, + 100,32,105,110,106,101,99,116,105,110,103,32,116,104,101,109, + 32,105,110,116,111,32,116,104,101,32,103,108,111,98,97,108, + 32,110,97,109,101,115,112,97,99,101,46,10,10,32,32,32, + 32,79,116,104,101,114,32,99,111,109,112,111,110,101,110,116, + 115,32,97,114,101,32,101,120,116,114,97,99,116,101,100,32, + 102,114,111,109,32,116,104,101,32,99,111,114,101,32,98,111, + 111,116,115,116,114,97,112,32,109,111,100,117,108,101,46,10, + 10,32,32,32,32,41,4,114,64,0,0,0,114,75,0,0, + 0,218,8,98,117,105,108,116,105,110,115,114,160,0,0,0, + 90,5,112,111,115,105,120,250,1,47,90,2,110,116,250,1, + 92,99,1,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,115,0,0,0,115,26,0,0,0,124, + 0,93,18,125,1,116,0,124,1,131,1,100,0,107,2,86, + 0,1,0,113,2,100,1,83,0,41,2,114,39,0,0,0, + 78,41,1,114,22,0,0,0,41,2,114,32,0,0,0,114, + 95,0,0,0,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,114,19,1,0,0,91,6,0,0,115,4,0,0, + 0,4,0,2,0,122,25,95,115,101,116,117,112,46,60,108, + 111,99,97,108,115,62,46,60,103,101,110,101,120,112,114,62, + 114,73,0,0,0,122,30,105,109,112,111,114,116,108,105,98, + 32,114,101,113,117,105,114,101,115,32,112,111,115,105,120,32, + 111,114,32,110,116,114,2,0,0,0,114,35,0,0,0,114, + 31,0,0,0,114,40,0,0,0,114,58,0,0,0,99,1, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,83,0,0,0,115,22,0,0,0,104,0,124,0, + 93,14,125,1,100,0,124,1,155,0,157,2,146,2,113,4, + 83,0,41,1,114,74,0,0,0,114,3,0,0,0,41,2, + 114,32,0,0,0,218,1,115,114,3,0,0,0,114,3,0, + 0,0,114,6,0,0,0,114,88,1,0,0,107,6,0,0, + 115,4,0,0,0,6,0,2,0,122,25,95,115,101,116,117, + 112,46,60,108,111,99,97,108,115,62,46,60,115,101,116,99, + 111,109,112,62,90,7,95,116,104,114,101,97,100,90,8,95, + 119,101,97,107,114,101,102,90,6,119,105,110,114,101,103,114, + 192,0,0,0,114,7,0,0,0,122,4,46,112,121,119,122, + 6,95,100,46,112,121,100,84,78,41,19,114,134,0,0,0, + 114,8,0,0,0,114,163,0,0,0,114,31,1,0,0,114, + 125,0,0,0,90,18,95,98,117,105,108,116,105,110,95,102, + 114,111,109,95,110,97,109,101,114,129,0,0,0,218,3,97, + 108,108,114,23,0,0,0,114,118,0,0,0,114,36,0,0, + 0,114,13,0,0,0,114,21,1,0,0,114,167,0,0,0, + 114,99,1,0,0,114,102,0,0,0,114,186,0,0,0,114, + 191,0,0,0,114,195,0,0,0,41,12,218,17,95,98,111, + 111,116,115,116,114,97,112,95,109,111,100,117,108,101,90,11, + 115,101,108,102,95,109,111,100,117,108,101,90,12,98,117,105, + 108,116,105,110,95,110,97,109,101,90,14,98,117,105,108,116, + 105,110,95,109,111,100,117,108,101,90,10,111,115,95,100,101, + 116,97,105,108,115,90,10,98,117,105,108,116,105,110,95,111, + 115,114,31,0,0,0,114,35,0,0,0,90,9,111,115,95, + 109,111,100,117,108,101,90,13,116,104,114,101,97,100,95,109, + 111,100,117,108,101,90,14,119,101,97,107,114,101,102,95,109, + 111,100,117,108,101,90,13,119,105,110,114,101,103,95,109,111, + 100,117,108,101,114,3,0,0,0,114,3,0,0,0,114,6, + 0,0,0,218,6,95,115,101,116,117,112,66,6,0,0,115, + 78,0,0,0,0,8,4,1,6,1,6,3,10,1,8,1, + 10,1,12,2,10,1,14,3,22,1,12,2,22,1,8,1, + 10,1,10,1,6,2,2,1,10,1,10,1,14,1,12,2, + 8,1,12,1,12,1,18,1,22,3,10,1,12,3,10,1, + 12,3,10,1,10,1,12,3,14,1,14,1,10,1,10,1, + 10,1,114,106,1,0,0,99,1,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,4,0,0,0,67,0,0,0, + 115,50,0,0,0,116,0,124,0,131,1,1,0,116,1,131, + 0,125,1,116,2,106,3,160,4,116,5,106,6,124,1,142, + 0,103,1,161,1,1,0,116,2,106,7,160,8,116,9,161, + 1,1,0,100,1,83,0,41,2,122,41,73,110,115,116,97, + 108,108,32,116,104,101,32,112,97,116,104,45,98,97,115,101, + 100,32,105,109,112,111,114,116,32,99,111,109,112,111,110,101, + 110,116,115,46,78,41,10,114,106,1,0,0,114,184,0,0, + 0,114,8,0,0,0,114,51,1,0,0,114,167,0,0,0, + 114,79,1,0,0,114,94,1,0,0,218,9,109,101,116,97, + 95,112,97,116,104,114,186,0,0,0,114,45,1,0,0,41, + 2,114,105,1,0,0,90,17,115,117,112,112,111,114,116,101, + 100,95,108,111,97,100,101,114,115,114,3,0,0,0,114,3, + 0,0,0,114,6,0,0,0,218,8,95,105,110,115,116,97, + 108,108,131,6,0,0,115,8,0,0,0,0,2,8,1,6, + 1,20,1,114,108,1,0,0,41,1,114,60,0,0,0,41, + 1,78,41,3,78,78,78,41,2,114,73,0,0,0,114,73, + 0,0,0,41,1,84,41,1,78,41,1,78,41,63,114,127, + 0,0,0,114,12,0,0,0,90,37,95,67,65,83,69,95, + 73,78,83,69,78,83,73,84,73,86,69,95,80,76,65,84, + 70,79,82,77,83,95,66,89,84,69,83,95,75,69,89,114, + 11,0,0,0,114,13,0,0,0,114,20,0,0,0,114,27, + 0,0,0,114,29,0,0,0,114,38,0,0,0,114,47,0, + 0,0,114,49,0,0,0,114,53,0,0,0,114,54,0,0, + 0,114,56,0,0,0,114,59,0,0,0,114,69,0,0,0, + 218,4,116,121,112,101,218,8,95,95,99,111,100,101,95,95, + 114,162,0,0,0,114,18,0,0,0,114,148,0,0,0,114, + 17,0,0,0,114,24,0,0,0,114,236,0,0,0,114,92, + 0,0,0,114,88,0,0,0,114,102,0,0,0,114,89,0, + 0,0,90,23,68,69,66,85,71,95,66,89,84,69,67,79, + 68,69,95,83,85,70,70,73,88,69,83,90,27,79,80,84, + 73,77,73,90,69,68,95,66,89,84,69,67,79,68,69,95, + 83,85,70,70,73,88,69,83,114,98,0,0,0,114,103,0, + 0,0,114,109,0,0,0,114,113,0,0,0,114,115,0,0, + 0,114,136,0,0,0,114,143,0,0,0,114,152,0,0,0, + 114,156,0,0,0,114,158,0,0,0,114,165,0,0,0,114, + 170,0,0,0,114,171,0,0,0,114,176,0,0,0,218,6, + 111,98,106,101,99,116,114,185,0,0,0,114,190,0,0,0, + 114,191,0,0,0,114,208,0,0,0,114,221,0,0,0,114, + 239,0,0,0,114,9,1,0,0,114,15,1,0,0,114,21, + 1,0,0,114,252,0,0,0,114,22,1,0,0,114,43,1, + 0,0,114,45,1,0,0,114,79,1,0,0,114,98,1,0, + 0,114,184,0,0,0,114,106,1,0,0,114,108,1,0,0, + 114,3,0,0,0,114,3,0,0,0,114,3,0,0,0,114, + 6,0,0,0,218,8,60,109,111,100,117,108,101,62,1,0, + 0,0,115,126,0,0,0,4,22,4,1,4,1,2,1,2, + 255,4,4,8,17,8,5,8,5,8,6,8,6,8,12,8, + 10,8,9,8,5,8,7,8,9,10,22,10,127,0,8,16, + 1,12,2,4,1,4,2,6,2,6,2,8,2,16,71,8, + 40,8,19,8,12,8,12,8,28,8,17,8,33,8,28,8, + 24,10,13,10,10,10,11,8,14,6,3,4,1,2,255,12, + 68,14,64,14,29,16,127,0,17,14,72,18,45,18,26,4, + 3,18,53,14,63,14,42,14,127,0,59,14,127,0,22,10, + 23,8,11,8,65, }; diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index cbb3d909a10b7b..056e85d343d8b6 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -783,301 +783,301 @@ const unsigned char _Py_M__zipimport[] = { 0,0,0,218,9,95,101,113,95,109,116,105,109,101,65,2, 0,0,115,2,0,0,0,0,2,114,147,0,0,0,99,5, 0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,8, - 0,0,0,67,0,0,0,115,68,1,0,0,124,3,124,2, + 0,0,0,67,0,0,0,115,60,1,0,0,124,3,124,2, 100,1,156,2,125,5,122,18,116,0,160,1,124,4,124,3, - 124,5,161,3,125,6,87,0,110,26,4,0,116,2,107,10, - 114,54,1,0,1,0,1,0,89,0,100,0,83,0,89,0, - 110,2,88,0,124,6,100,2,64,0,100,3,107,3,125,7, - 124,7,114,190,124,6,100,4,64,0,100,3,107,3,125,8, - 116,3,106,4,100,5,107,3,114,188,124,8,115,108,116,3, - 106,4,100,6,107,2,114,188,116,5,124,0,124,2,131,2, - 125,9,124,9,100,0,107,9,114,188,116,3,160,6,116,0, - 106,7,124,9,161,2,125,10,122,20,116,8,160,9,124,4, - 124,10,124,3,124,5,161,4,1,0,87,0,110,26,4,0, - 116,2,107,10,114,186,1,0,1,0,1,0,89,0,100,0, - 83,0,89,0,110,2,88,0,110,84,116,10,124,0,124,2, - 131,2,92,2,125,11,125,12,124,11,144,1,114,18,116,11, - 116,12,124,4,100,7,100,8,133,2,25,0,131,1,124,11, - 131,2,114,254,116,12,124,4,100,8,100,9,133,2,25,0, - 131,1,124,12,107,3,144,1,114,18,116,13,160,14,100,10, - 124,3,155,2,157,2,161,1,1,0,100,0,83,0,116,15, - 160,16,124,4,100,9,100,0,133,2,25,0,161,1,125,13, - 116,17,124,13,116,18,131,2,144,1,115,64,116,19,100,11, - 124,1,155,2,100,12,157,3,131,1,130,1,124,13,83,0, - 41,13,78,41,2,114,59,0,0,0,114,13,0,0,0,114, - 5,0,0,0,114,0,0,0,0,114,86,0,0,0,90,5, - 110,101,118,101,114,90,6,97,108,119,97,121,115,114,99,0, - 0,0,114,94,0,0,0,114,95,0,0,0,122,22,98,121, - 116,101,99,111,100,101,32,105,115,32,115,116,97,108,101,32, - 102,111,114,32,122,16,99,111,109,112,105,108,101,100,32,109, - 111,100,117,108,101,32,122,21,32,105,115,32,110,111,116,32, - 97,32,99,111,100,101,32,111,98,106,101,99,116,41,20,114, - 21,0,0,0,90,13,95,99,108,97,115,115,105,102,121,95, - 112,121,99,114,75,0,0,0,218,4,95,105,109,112,90,21, - 99,104,101,99,107,95,104,97,115,104,95,98,97,115,101,100, - 95,112,121,99,115,218,15,95,103,101,116,95,112,121,99,95, - 115,111,117,114,99,101,218,11,115,111,117,114,99,101,95,104, - 97,115,104,90,17,95,82,65,87,95,77,65,71,73,67,95, - 78,85,77,66,69,82,90,18,95,98,111,111,115,116,114,97, - 112,95,101,120,116,101,114,110,97,108,90,18,95,118,97,108, - 105,100,97,116,101,95,104,97,115,104,95,112,121,99,218,29, - 95,103,101,116,95,109,116,105,109,101,95,97,110,100,95,115, - 105,122,101,95,111,102,95,115,111,117,114,99,101,114,147,0, - 0,0,114,2,0,0,0,114,76,0,0,0,114,77,0,0, - 0,218,7,109,97,114,115,104,97,108,90,5,108,111,97,100, - 115,114,15,0,0,0,218,10,95,99,111,100,101,95,116,121, - 112,101,218,9,84,121,112,101,69,114,114,111,114,41,14,114, - 32,0,0,0,114,53,0,0,0,114,63,0,0,0,114,38, - 0,0,0,114,126,0,0,0,90,11,101,120,99,95,100,101, - 116,97,105,108,115,114,129,0,0,0,90,10,104,97,115,104, - 95,98,97,115,101,100,90,12,99,104,101,99,107,95,115,111, - 117,114,99,101,90,12,115,111,117,114,99,101,95,98,121,116, - 101,115,114,150,0,0,0,90,12,115,111,117,114,99,101,95, - 109,116,105,109,101,90,11,115,111,117,114,99,101,95,115,105, - 122,101,114,46,0,0,0,114,9,0,0,0,114,9,0,0, - 0,114,10,0,0,0,218,15,95,117,110,109,97,114,115,104, - 97,108,95,99,111,100,101,75,2,0,0,115,88,0,0,0, - 0,2,2,1,2,254,6,5,2,1,18,1,14,1,12,2, - 12,1,4,1,12,1,10,1,2,255,2,1,8,255,2,2, - 10,1,8,1,4,1,4,1,2,254,4,5,2,1,4,1, - 2,0,2,0,2,0,2,255,8,2,14,1,14,3,8,255, - 6,3,6,3,22,1,18,255,4,2,4,1,8,255,4,2, - 4,2,18,1,12,1,16,1,114,155,0,0,0,99,1,0, - 0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0, - 0,0,67,0,0,0,115,28,0,0,0,124,0,160,0,100, - 1,100,2,161,2,125,0,124,0,160,0,100,3,100,2,161, - 2,125,0,124,0,83,0,41,4,78,115,2,0,0,0,13, - 10,243,1,0,0,0,10,243,1,0,0,0,13,41,1,114, - 19,0,0,0,41,1,218,6,115,111,117,114,99,101,114,9, - 0,0,0,114,9,0,0,0,114,10,0,0,0,218,23,95, - 110,111,114,109,97,108,105,122,101,95,108,105,110,101,95,101, - 110,100,105,110,103,115,126,2,0,0,115,6,0,0,0,0, - 1,12,1,12,1,114,159,0,0,0,99,2,0,0,0,0, - 0,0,0,0,0,0,0,2,0,0,0,6,0,0,0,67, - 0,0,0,115,24,0,0,0,116,0,124,1,131,1,125,1, - 116,1,124,1,124,0,100,1,100,2,100,3,141,4,83,0, - 41,4,78,114,74,0,0,0,84,41,1,90,12,100,111,110, - 116,95,105,110,104,101,114,105,116,41,2,114,159,0,0,0, - 218,7,99,111,109,112,105,108,101,41,2,114,53,0,0,0, - 114,158,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,218,15,95,99,111,109,112,105,108,101,95,115, - 111,117,114,99,101,133,2,0,0,115,4,0,0,0,0,1, - 8,1,114,161,0,0,0,99,2,0,0,0,0,0,0,0, - 0,0,0,0,2,0,0,0,11,0,0,0,67,0,0,0, - 115,68,0,0,0,116,0,160,1,124,0,100,1,63,0,100, - 2,23,0,124,0,100,3,63,0,100,4,64,0,124,0,100, - 5,64,0,124,1,100,6,63,0,124,1,100,3,63,0,100, - 7,64,0,124,1,100,5,64,0,100,8,20,0,100,9,100, - 9,100,9,102,9,161,1,83,0,41,10,78,233,9,0,0, - 0,105,188,7,0,0,233,5,0,0,0,233,15,0,0,0, - 233,31,0,0,0,233,11,0,0,0,233,63,0,0,0,114, - 86,0,0,0,114,14,0,0,0,41,2,114,131,0,0,0, - 90,6,109,107,116,105,109,101,41,2,218,1,100,114,138,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,218,14,95,112,97,114,115,101,95,100,111,115,116,105,109, - 101,139,2,0,0,115,22,0,0,0,0,1,4,1,10,1, - 10,1,6,1,6,1,10,1,10,1,2,0,2,0,2,249, - 114,169,0,0,0,99,2,0,0,0,0,0,0,0,0,0, - 0,0,6,0,0,0,10,0,0,0,67,0,0,0,115,116, - 0,0,0,122,82,124,1,100,1,100,0,133,2,25,0,100, - 2,107,6,115,22,116,0,130,1,124,1,100,0,100,1,133, - 2,25,0,125,1,124,0,106,1,124,1,25,0,125,2,124, - 2,100,3,25,0,125,3,124,2,100,4,25,0,125,4,124, - 2,100,5,25,0,125,5,116,2,124,4,124,3,131,2,124, - 5,102,2,87,0,83,0,4,0,116,3,116,4,116,5,102, - 3,107,10,114,110,1,0,1,0,1,0,89,0,100,6,83, - 0,88,0,100,0,83,0,41,7,78,114,14,0,0,0,169, - 2,218,1,99,218,1,111,114,163,0,0,0,233,6,0,0, - 0,233,3,0,0,0,41,2,114,0,0,0,0,114,0,0, - 0,0,41,6,218,14,65,115,115,101,114,116,105,111,110,69, - 114,114,111,114,114,28,0,0,0,114,169,0,0,0,114,26, - 0,0,0,218,10,73,110,100,101,120,69,114,114,111,114,114, - 154,0,0,0,41,6,114,32,0,0,0,114,13,0,0,0, - 114,54,0,0,0,114,131,0,0,0,114,132,0,0,0,90, - 17,117,110,99,111,109,112,114,101,115,115,101,100,95,115,105, - 122,101,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,151,0,0,0,152,2,0,0,115,20,0,0,0,0, - 1,2,2,20,1,12,1,10,3,8,1,8,1,8,1,16, - 1,20,1,114,151,0,0,0,99,2,0,0,0,0,0,0, - 0,0,0,0,0,3,0,0,0,8,0,0,0,67,0,0, - 0,115,86,0,0,0,124,1,100,1,100,0,133,2,25,0, - 100,2,107,6,115,20,116,0,130,1,124,1,100,0,100,1, - 133,2,25,0,125,1,122,14,124,0,106,1,124,1,25,0, - 125,2,87,0,110,22,4,0,116,2,107,10,114,68,1,0, - 1,0,1,0,89,0,100,0,83,0,88,0,116,3,124,0, - 106,4,124,2,131,2,83,0,100,0,83,0,41,3,78,114, - 14,0,0,0,114,170,0,0,0,41,5,114,175,0,0,0, - 114,28,0,0,0,114,26,0,0,0,114,52,0,0,0,114, - 29,0,0,0,41,3,114,32,0,0,0,114,13,0,0,0, - 114,54,0,0,0,114,9,0,0,0,114,9,0,0,0,114, - 10,0,0,0,114,149,0,0,0,171,2,0,0,115,14,0, - 0,0,0,2,20,1,12,2,2,1,14,1,14,1,8,2, - 114,149,0,0,0,99,2,0,0,0,0,0,0,0,0,0, - 0,0,11,0,0,0,9,0,0,0,67,0,0,0,115,198, - 0,0,0,116,0,124,0,124,1,131,2,125,2,116,1,68, - 0,93,160,92,3,125,3,125,4,125,5,124,2,124,3,23, - 0,125,6,116,2,106,3,100,1,124,0,106,4,116,5,124, - 6,100,2,100,3,141,5,1,0,122,14,124,0,106,6,124, - 6,25,0,125,7,87,0,110,20,4,0,116,7,107,10,114, - 88,1,0,1,0,1,0,89,0,113,14,88,0,124,7,100, - 4,25,0,125,8,116,8,124,0,106,4,124,7,131,2,125, - 9,124,4,114,132,116,9,124,0,124,8,124,6,124,1,124, - 9,131,5,125,10,110,10,116,10,124,8,124,9,131,2,125, - 10,124,10,100,0,107,8,114,152,113,14,124,7,100,4,25, - 0,125,8,124,10,124,5,124,8,102,3,2,0,1,0,83, - 0,113,14,116,11,100,5,124,1,155,2,157,2,124,1,100, - 6,141,2,130,1,100,0,83,0,41,7,78,122,13,116,114, - 121,105,110,103,32,123,125,123,125,123,125,114,86,0,0,0, - 41,1,90,9,118,101,114,98,111,115,105,116,121,114,0,0, - 0,0,114,57,0,0,0,114,58,0,0,0,41,12,114,36, - 0,0,0,114,89,0,0,0,114,76,0,0,0,114,77,0, - 0,0,114,29,0,0,0,114,20,0,0,0,114,28,0,0, - 0,114,26,0,0,0,114,52,0,0,0,114,155,0,0,0, - 114,161,0,0,0,114,3,0,0,0,41,11,114,32,0,0, - 0,114,38,0,0,0,114,13,0,0,0,114,90,0,0,0, - 114,91,0,0,0,114,47,0,0,0,114,63,0,0,0,114, - 54,0,0,0,114,40,0,0,0,114,126,0,0,0,114,46, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,114,44,0,0,0,186,2,0,0,115,36,0,0,0, - 0,1,10,1,14,1,8,1,22,1,2,1,14,1,14,1, - 6,2,8,1,12,1,4,1,18,2,10,1,8,3,2,1, - 8,1,16,2,114,44,0,0,0,99,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,2,0,0,0,64,0, - 0,0,115,60,0,0,0,101,0,90,1,100,0,90,2,100, - 1,90,3,100,2,90,4,100,3,100,4,132,0,90,5,100, - 5,100,6,132,0,90,6,100,7,100,8,132,0,90,7,100, - 9,100,10,132,0,90,8,100,11,100,12,132,0,90,9,100, - 13,83,0,41,14,114,80,0,0,0,122,165,80,114,105,118, - 97,116,101,32,99,108,97,115,115,32,117,115,101,100,32,116, - 111,32,115,117,112,112,111,114,116,32,90,105,112,73,109,112, - 111,114,116,46,103,101,116,95,114,101,115,111,117,114,99,101, - 95,114,101,97,100,101,114,40,41,46,10,10,32,32,32,32, - 84,104,105,115,32,99,108,97,115,115,32,105,115,32,97,108, - 108,111,119,101,100,32,116,111,32,114,101,102,101,114,101,110, - 99,101,32,97,108,108,32,116,104,101,32,105,110,110,97,114, - 100,115,32,97,110,100,32,112,114,105,118,97,116,101,32,112, - 97,114,116,115,32,111,102,10,32,32,32,32,116,104,101,32, - 122,105,112,105,109,112,111,114,116,101,114,46,10,32,32,32, - 32,70,99,3,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, - 124,1,124,0,95,0,124,2,124,0,95,1,100,0,83,0, - 114,88,0,0,0,41,2,114,4,0,0,0,114,38,0,0, - 0,41,3,114,32,0,0,0,114,4,0,0,0,114,38,0, - 0,0,114,9,0,0,0,114,9,0,0,0,114,10,0,0, - 0,114,34,0,0,0,220,2,0,0,115,4,0,0,0,0, - 1,6,1,122,33,95,90,105,112,73,109,112,111,114,116,82, - 101,115,111,117,114,99,101,82,101,97,100,101,114,46,95,95, - 105,110,105,116,95,95,99,2,0,0,0,0,0,0,0,0, - 0,0,0,5,0,0,0,8,0,0,0,67,0,0,0,115, - 92,0,0,0,124,0,106,0,160,1,100,1,100,2,161,2, - 125,2,124,2,155,0,100,2,124,1,155,0,157,3,125,3, - 100,3,100,4,108,2,109,3,125,4,1,0,122,18,124,4, - 124,0,106,4,160,5,124,3,161,1,131,1,87,0,83,0, - 4,0,116,6,107,10,114,86,1,0,1,0,1,0,116,7, - 124,3,131,1,130,1,89,0,110,2,88,0,100,0,83,0, - 41,5,78,114,85,0,0,0,114,109,0,0,0,114,0,0, - 0,0,41,1,218,7,66,121,116,101,115,73,79,41,8,114, - 38,0,0,0,114,19,0,0,0,90,2,105,111,114,177,0, - 0,0,114,4,0,0,0,114,55,0,0,0,114,22,0,0, - 0,218,17,70,105,108,101,78,111,116,70,111,117,110,100,69, - 114,114,111,114,41,5,114,32,0,0,0,218,8,114,101,115, - 111,117,114,99,101,218,16,102,117,108,108,110,97,109,101,95, - 97,115,95,112,97,116,104,114,13,0,0,0,114,177,0,0, - 0,114,9,0,0,0,114,9,0,0,0,114,10,0,0,0, - 218,13,111,112,101,110,95,114,101,115,111,117,114,99,101,224, - 2,0,0,115,14,0,0,0,0,1,14,1,14,1,12,1, - 2,1,18,1,14,1,122,38,95,90,105,112,73,109,112,111, - 114,116,82,101,115,111,117,114,99,101,82,101,97,100,101,114, - 46,111,112,101,110,95,114,101,115,111,117,114,99,101,99,2, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,1, - 0,0,0,67,0,0,0,115,8,0,0,0,116,0,130,1, - 100,0,83,0,114,88,0,0,0,41,1,114,178,0,0,0, - 41,2,114,32,0,0,0,114,179,0,0,0,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,13,114,101,115, - 111,117,114,99,101,95,112,97,116,104,233,2,0,0,115,2, - 0,0,0,0,4,122,38,95,90,105,112,73,109,112,111,114, - 116,82,101,115,111,117,114,99,101,82,101,97,100,101,114,46, - 114,101,115,111,117,114,99,101,95,112,97,116,104,99,2,0, - 0,0,0,0,0,0,0,0,0,0,4,0,0,0,8,0, - 0,0,67,0,0,0,115,72,0,0,0,124,0,106,0,160, - 1,100,1,100,2,161,2,125,2,124,2,155,0,100,2,124, - 1,155,0,157,3,125,3,122,16,124,0,106,2,160,3,124, - 3,161,1,1,0,87,0,110,22,4,0,116,4,107,10,114, - 66,1,0,1,0,1,0,89,0,100,3,83,0,88,0,100, - 4,83,0,41,5,78,114,85,0,0,0,114,109,0,0,0, - 70,84,41,5,114,38,0,0,0,114,19,0,0,0,114,4, - 0,0,0,114,55,0,0,0,114,22,0,0,0,41,4,114, - 32,0,0,0,114,59,0,0,0,114,180,0,0,0,114,13, - 0,0,0,114,9,0,0,0,114,9,0,0,0,114,10,0, - 0,0,218,11,105,115,95,114,101,115,111,117,114,99,101,239, - 2,0,0,115,14,0,0,0,0,3,14,1,14,1,2,1, - 16,1,14,1,8,1,122,36,95,90,105,112,73,109,112,111, - 114,116,82,101,115,111,117,114,99,101,82,101,97,100,101,114, - 46,105,115,95,114,101,115,111,117,114,99,101,99,1,0,0, - 0,0,0,0,0,0,0,0,0,9,0,0,0,9,0,0, - 0,99,0,0,0,115,186,0,0,0,100,1,100,2,108,0, - 109,1,125,1,1,0,124,1,124,0,106,2,160,3,124,0, - 106,4,161,1,131,1,125,2,124,2,160,5,124,0,106,2, - 106,6,161,1,125,3,124,3,106,7,100,3,107,2,115,58, - 116,8,130,1,124,3,106,9,125,4,116,10,131,0,125,5, - 124,0,106,2,106,11,68,0,93,102,125,6,122,18,124,1, - 124,6,131,1,160,5,124,4,161,1,125,7,87,0,110,24, - 4,0,116,12,107,10,114,124,1,0,1,0,1,0,89,0, - 113,78,89,0,110,2,88,0,124,7,106,9,106,7,125,8, - 116,13,124,8,131,1,100,1,107,2,114,156,124,7,106,7, - 86,0,1,0,113,78,124,8,124,5,107,7,114,78,124,5, - 160,14,124,8,161,1,1,0,124,8,86,0,1,0,113,78, - 100,0,83,0,41,4,78,114,0,0,0,0,41,1,218,4, - 80,97,116,104,114,60,0,0,0,41,15,90,7,112,97,116, - 104,108,105,98,114,184,0,0,0,114,4,0,0,0,114,56, - 0,0,0,114,38,0,0,0,90,11,114,101,108,97,116,105, - 118,101,95,116,111,114,29,0,0,0,114,59,0,0,0,114, - 175,0,0,0,90,6,112,97,114,101,110,116,218,3,115,101, - 116,114,28,0,0,0,114,23,0,0,0,114,51,0,0,0, - 218,3,97,100,100,41,9,114,32,0,0,0,114,184,0,0, - 0,90,13,102,117,108,108,110,97,109,101,95,112,97,116,104, - 90,13,114,101,108,97,116,105,118,101,95,112,97,116,104,90, - 12,112,97,99,107,97,103,101,95,112,97,116,104,90,12,115, - 117,98,100,105,114,115,95,115,101,101,110,218,8,102,105,108, - 101,110,97,109,101,90,8,114,101,108,97,116,105,118,101,90, - 11,112,97,114,101,110,116,95,110,97,109,101,114,9,0,0, - 0,114,9,0,0,0,114,10,0,0,0,218,8,99,111,110, - 116,101,110,116,115,250,2,0,0,115,34,0,0,0,0,8, - 12,1,18,1,14,3,14,1,6,1,6,1,12,1,2,1, - 18,1,14,1,10,5,8,1,12,1,10,1,8,1,10,1, - 122,33,95,90,105,112,73,109,112,111,114,116,82,101,115,111, - 117,114,99,101,82,101,97,100,101,114,46,99,111,110,116,101, - 110,116,115,78,41,10,114,6,0,0,0,114,7,0,0,0, - 114,8,0,0,0,114,84,0,0,0,114,81,0,0,0,114, - 34,0,0,0,114,181,0,0,0,114,182,0,0,0,114,183, - 0,0,0,114,188,0,0,0,114,9,0,0,0,114,9,0, - 0,0,114,9,0,0,0,114,10,0,0,0,114,80,0,0, - 0,212,2,0,0,115,14,0,0,0,8,1,4,5,4,2, - 8,4,8,9,8,6,8,11,114,80,0,0,0,41,45,114, - 84,0,0,0,90,26,95,102,114,111,122,101,110,95,105,109, - 112,111,114,116,108,105,98,95,101,120,116,101,114,110,97,108, - 114,21,0,0,0,114,1,0,0,0,114,2,0,0,0,90, - 17,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, - 105,98,114,76,0,0,0,114,148,0,0,0,114,110,0,0, - 0,114,152,0,0,0,114,67,0,0,0,114,131,0,0,0, - 90,7,95,95,97,108,108,95,95,114,20,0,0,0,90,15, - 112,97,116,104,95,115,101,112,97,114,97,116,111,114,115,114, - 18,0,0,0,114,75,0,0,0,114,3,0,0,0,114,25, - 0,0,0,218,4,116,121,112,101,114,70,0,0,0,114,113, - 0,0,0,114,115,0,0,0,114,117,0,0,0,114,4,0, - 0,0,114,89,0,0,0,114,36,0,0,0,114,37,0,0, - 0,114,35,0,0,0,114,27,0,0,0,114,122,0,0,0, - 114,142,0,0,0,114,144,0,0,0,114,52,0,0,0,114, - 147,0,0,0,114,155,0,0,0,218,8,95,95,99,111,100, - 101,95,95,114,153,0,0,0,114,159,0,0,0,114,161,0, - 0,0,114,169,0,0,0,114,151,0,0,0,114,149,0,0, - 0,114,44,0,0,0,114,80,0,0,0,114,9,0,0,0, - 114,9,0,0,0,114,9,0,0,0,114,10,0,0,0,218, - 8,60,109,111,100,117,108,101,62,1,0,0,0,115,88,0, - 0,0,4,16,8,1,16,1,8,1,8,1,8,1,8,1, - 8,1,8,2,8,3,6,1,14,3,16,4,4,2,8,2, - 4,1,4,1,4,2,14,127,0,127,0,1,12,1,12,1, - 2,1,2,252,4,9,8,4,8,9,8,31,8,126,2,254, - 2,29,4,5,8,21,8,46,8,10,8,46,10,5,8,7, - 8,6,8,13,8,19,8,15,8,26, + 124,5,161,3,125,6,87,0,110,22,4,0,116,2,107,10, + 114,50,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 124,6,100,2,64,0,100,3,107,3,125,7,124,7,114,182, + 124,6,100,4,64,0,100,3,107,3,125,8,116,3,106,4, + 100,5,107,3,114,180,124,8,115,104,116,3,106,4,100,6, + 107,2,114,180,116,5,124,0,124,2,131,2,125,9,124,9, + 100,0,107,9,114,180,116,3,160,6,116,0,106,7,124,9, + 161,2,125,10,122,20,116,8,160,9,124,4,124,10,124,3, + 124,5,161,4,1,0,87,0,110,22,4,0,116,2,107,10, + 114,178,1,0,1,0,1,0,89,0,100,0,83,0,88,0, + 110,84,116,10,124,0,124,2,131,2,92,2,125,11,125,12, + 124,11,144,1,114,10,116,11,116,12,124,4,100,7,100,8, + 133,2,25,0,131,1,124,11,131,2,114,246,116,12,124,4, + 100,8,100,9,133,2,25,0,131,1,124,12,107,3,144,1, + 114,10,116,13,160,14,100,10,124,3,155,2,157,2,161,1, + 1,0,100,0,83,0,116,15,160,16,124,4,100,9,100,0, + 133,2,25,0,161,1,125,13,116,17,124,13,116,18,131,2, + 144,1,115,56,116,19,100,11,124,1,155,2,100,12,157,3, + 131,1,130,1,124,13,83,0,41,13,78,41,2,114,59,0, + 0,0,114,13,0,0,0,114,5,0,0,0,114,0,0,0, + 0,114,86,0,0,0,90,5,110,101,118,101,114,90,6,97, + 108,119,97,121,115,114,99,0,0,0,114,94,0,0,0,114, + 95,0,0,0,122,22,98,121,116,101,99,111,100,101,32,105, + 115,32,115,116,97,108,101,32,102,111,114,32,122,16,99,111, + 109,112,105,108,101,100,32,109,111,100,117,108,101,32,122,21, + 32,105,115,32,110,111,116,32,97,32,99,111,100,101,32,111, + 98,106,101,99,116,41,20,114,21,0,0,0,90,13,95,99, + 108,97,115,115,105,102,121,95,112,121,99,114,75,0,0,0, + 218,4,95,105,109,112,90,21,99,104,101,99,107,95,104,97, + 115,104,95,98,97,115,101,100,95,112,121,99,115,218,15,95, + 103,101,116,95,112,121,99,95,115,111,117,114,99,101,218,11, + 115,111,117,114,99,101,95,104,97,115,104,90,17,95,82,65, + 87,95,77,65,71,73,67,95,78,85,77,66,69,82,90,18, + 95,98,111,111,115,116,114,97,112,95,101,120,116,101,114,110, + 97,108,90,18,95,118,97,108,105,100,97,116,101,95,104,97, + 115,104,95,112,121,99,218,29,95,103,101,116,95,109,116,105, + 109,101,95,97,110,100,95,115,105,122,101,95,111,102,95,115, + 111,117,114,99,101,114,147,0,0,0,114,2,0,0,0,114, + 76,0,0,0,114,77,0,0,0,218,7,109,97,114,115,104, + 97,108,90,5,108,111,97,100,115,114,15,0,0,0,218,10, + 95,99,111,100,101,95,116,121,112,101,218,9,84,121,112,101, + 69,114,114,111,114,41,14,114,32,0,0,0,114,53,0,0, + 0,114,63,0,0,0,114,38,0,0,0,114,126,0,0,0, + 90,11,101,120,99,95,100,101,116,97,105,108,115,114,129,0, + 0,0,90,10,104,97,115,104,95,98,97,115,101,100,90,12, + 99,104,101,99,107,95,115,111,117,114,99,101,90,12,115,111, + 117,114,99,101,95,98,121,116,101,115,114,150,0,0,0,90, + 12,115,111,117,114,99,101,95,109,116,105,109,101,90,11,115, + 111,117,114,99,101,95,115,105,122,101,114,46,0,0,0,114, + 9,0,0,0,114,9,0,0,0,114,10,0,0,0,218,15, + 95,117,110,109,97,114,115,104,97,108,95,99,111,100,101,75, + 2,0,0,115,88,0,0,0,0,2,2,1,2,254,6,5, + 2,1,18,1,14,1,8,2,12,1,4,1,12,1,10,1, + 2,255,2,1,8,255,2,2,10,1,8,1,4,1,4,1, + 2,254,4,5,2,1,4,1,2,0,2,0,2,0,2,255, + 8,2,14,1,10,3,8,255,6,3,6,3,22,1,18,255, + 4,2,4,1,8,255,4,2,4,2,18,1,12,1,16,1, + 114,155,0,0,0,99,1,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,4,0,0,0,67,0,0,0,115,28, + 0,0,0,124,0,160,0,100,1,100,2,161,2,125,0,124, + 0,160,0,100,3,100,2,161,2,125,0,124,0,83,0,41, + 4,78,115,2,0,0,0,13,10,243,1,0,0,0,10,243, + 1,0,0,0,13,41,1,114,19,0,0,0,41,1,218,6, + 115,111,117,114,99,101,114,9,0,0,0,114,9,0,0,0, + 114,10,0,0,0,218,23,95,110,111,114,109,97,108,105,122, + 101,95,108,105,110,101,95,101,110,100,105,110,103,115,126,2, + 0,0,115,6,0,0,0,0,1,12,1,12,1,114,159,0, + 0,0,99,2,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,6,0,0,0,67,0,0,0,115,24,0,0,0, + 116,0,124,1,131,1,125,1,116,1,124,1,124,0,100,1, + 100,2,100,3,141,4,83,0,41,4,78,114,74,0,0,0, + 84,41,1,90,12,100,111,110,116,95,105,110,104,101,114,105, + 116,41,2,114,159,0,0,0,218,7,99,111,109,112,105,108, + 101,41,2,114,53,0,0,0,114,158,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,218,15,95,99, + 111,109,112,105,108,101,95,115,111,117,114,99,101,133,2,0, + 0,115,4,0,0,0,0,1,8,1,114,161,0,0,0,99, + 2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 11,0,0,0,67,0,0,0,115,68,0,0,0,116,0,160, + 1,124,0,100,1,63,0,100,2,23,0,124,0,100,3,63, + 0,100,4,64,0,124,0,100,5,64,0,124,1,100,6,63, + 0,124,1,100,3,63,0,100,7,64,0,124,1,100,5,64, + 0,100,8,20,0,100,9,100,9,100,9,102,9,161,1,83, + 0,41,10,78,233,9,0,0,0,105,188,7,0,0,233,5, + 0,0,0,233,15,0,0,0,233,31,0,0,0,233,11,0, + 0,0,233,63,0,0,0,114,86,0,0,0,114,14,0,0, + 0,41,2,114,131,0,0,0,90,6,109,107,116,105,109,101, + 41,2,218,1,100,114,138,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,218,14,95,112,97,114,115, + 101,95,100,111,115,116,105,109,101,139,2,0,0,115,22,0, + 0,0,0,1,4,1,10,1,10,1,6,1,6,1,10,1, + 10,1,2,0,2,0,2,249,114,169,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,6,0,0,0,10,0, + 0,0,67,0,0,0,115,116,0,0,0,122,82,124,1,100, + 1,100,0,133,2,25,0,100,2,107,6,115,22,116,0,130, + 1,124,1,100,0,100,1,133,2,25,0,125,1,124,0,106, + 1,124,1,25,0,125,2,124,2,100,3,25,0,125,3,124, + 2,100,4,25,0,125,4,124,2,100,5,25,0,125,5,116, + 2,124,4,124,3,131,2,124,5,102,2,87,0,83,0,4, + 0,116,3,116,4,116,5,102,3,107,10,114,110,1,0,1, + 0,1,0,89,0,100,6,83,0,88,0,100,0,83,0,41, + 7,78,114,14,0,0,0,169,2,218,1,99,218,1,111,114, + 163,0,0,0,233,6,0,0,0,233,3,0,0,0,41,2, + 114,0,0,0,0,114,0,0,0,0,41,6,218,14,65,115, + 115,101,114,116,105,111,110,69,114,114,111,114,114,28,0,0, + 0,114,169,0,0,0,114,26,0,0,0,218,10,73,110,100, + 101,120,69,114,114,111,114,114,154,0,0,0,41,6,114,32, + 0,0,0,114,13,0,0,0,114,54,0,0,0,114,131,0, + 0,0,114,132,0,0,0,90,17,117,110,99,111,109,112,114, + 101,115,115,101,100,95,115,105,122,101,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,114,151,0,0,0,152,2, + 0,0,115,20,0,0,0,0,1,2,2,20,1,12,1,10, + 3,8,1,8,1,8,1,16,1,20,1,114,151,0,0,0, + 99,2,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,8,0,0,0,67,0,0,0,115,86,0,0,0,124,1, + 100,1,100,0,133,2,25,0,100,2,107,6,115,20,116,0, + 130,1,124,1,100,0,100,1,133,2,25,0,125,1,122,14, + 124,0,106,1,124,1,25,0,125,2,87,0,110,22,4,0, + 116,2,107,10,114,68,1,0,1,0,1,0,89,0,100,0, + 83,0,88,0,116,3,124,0,106,4,124,2,131,2,83,0, + 100,0,83,0,41,3,78,114,14,0,0,0,114,170,0,0, + 0,41,5,114,175,0,0,0,114,28,0,0,0,114,26,0, + 0,0,114,52,0,0,0,114,29,0,0,0,41,3,114,32, + 0,0,0,114,13,0,0,0,114,54,0,0,0,114,9,0, + 0,0,114,9,0,0,0,114,10,0,0,0,114,149,0,0, + 0,171,2,0,0,115,14,0,0,0,0,2,20,1,12,2, + 2,1,14,1,14,1,8,2,114,149,0,0,0,99,2,0, + 0,0,0,0,0,0,0,0,0,0,11,0,0,0,9,0, + 0,0,67,0,0,0,115,198,0,0,0,116,0,124,0,124, + 1,131,2,125,2,116,1,68,0,93,160,92,3,125,3,125, + 4,125,5,124,2,124,3,23,0,125,6,116,2,106,3,100, + 1,124,0,106,4,116,5,124,6,100,2,100,3,141,5,1, + 0,122,14,124,0,106,6,124,6,25,0,125,7,87,0,110, + 20,4,0,116,7,107,10,114,88,1,0,1,0,1,0,89, + 0,113,14,88,0,124,7,100,4,25,0,125,8,116,8,124, + 0,106,4,124,7,131,2,125,9,124,4,114,132,116,9,124, + 0,124,8,124,6,124,1,124,9,131,5,125,10,110,10,116, + 10,124,8,124,9,131,2,125,10,124,10,100,0,107,8,114, + 152,113,14,124,7,100,4,25,0,125,8,124,10,124,5,124, + 8,102,3,2,0,1,0,83,0,113,14,116,11,100,5,124, + 1,155,2,157,2,124,1,100,6,141,2,130,1,100,0,83, + 0,41,7,78,122,13,116,114,121,105,110,103,32,123,125,123, + 125,123,125,114,86,0,0,0,41,1,90,9,118,101,114,98, + 111,115,105,116,121,114,0,0,0,0,114,57,0,0,0,114, + 58,0,0,0,41,12,114,36,0,0,0,114,89,0,0,0, + 114,76,0,0,0,114,77,0,0,0,114,29,0,0,0,114, + 20,0,0,0,114,28,0,0,0,114,26,0,0,0,114,52, + 0,0,0,114,155,0,0,0,114,161,0,0,0,114,3,0, + 0,0,41,11,114,32,0,0,0,114,38,0,0,0,114,13, + 0,0,0,114,90,0,0,0,114,91,0,0,0,114,47,0, + 0,0,114,63,0,0,0,114,54,0,0,0,114,40,0,0, + 0,114,126,0,0,0,114,46,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,114,44,0,0,0,186, + 2,0,0,115,36,0,0,0,0,1,10,1,14,1,8,1, + 22,1,2,1,14,1,14,1,6,2,8,1,12,1,4,1, + 18,2,10,1,8,3,2,1,8,1,16,2,114,44,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,64,0,0,0,115,60,0,0,0,101, + 0,90,1,100,0,90,2,100,1,90,3,100,2,90,4,100, + 3,100,4,132,0,90,5,100,5,100,6,132,0,90,6,100, + 7,100,8,132,0,90,7,100,9,100,10,132,0,90,8,100, + 11,100,12,132,0,90,9,100,13,83,0,41,14,114,80,0, + 0,0,122,165,80,114,105,118,97,116,101,32,99,108,97,115, + 115,32,117,115,101,100,32,116,111,32,115,117,112,112,111,114, + 116,32,90,105,112,73,109,112,111,114,116,46,103,101,116,95, + 114,101,115,111,117,114,99,101,95,114,101,97,100,101,114,40, + 41,46,10,10,32,32,32,32,84,104,105,115,32,99,108,97, + 115,115,32,105,115,32,97,108,108,111,119,101,100,32,116,111, + 32,114,101,102,101,114,101,110,99,101,32,97,108,108,32,116, + 104,101,32,105,110,110,97,114,100,115,32,97,110,100,32,112, + 114,105,118,97,116,101,32,112,97,114,116,115,32,111,102,10, + 32,32,32,32,116,104,101,32,122,105,112,105,109,112,111,114, + 116,101,114,46,10,32,32,32,32,70,99,3,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,67, + 0,0,0,115,16,0,0,0,124,1,124,0,95,0,124,2, + 124,0,95,1,100,0,83,0,114,88,0,0,0,41,2,114, + 4,0,0,0,114,38,0,0,0,41,3,114,32,0,0,0, + 114,4,0,0,0,114,38,0,0,0,114,9,0,0,0,114, + 9,0,0,0,114,10,0,0,0,114,34,0,0,0,220,2, + 0,0,115,4,0,0,0,0,1,6,1,122,33,95,90,105, + 112,73,109,112,111,114,116,82,101,115,111,117,114,99,101,82, + 101,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, + 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,8, + 0,0,0,67,0,0,0,115,92,0,0,0,124,0,106,0, + 160,1,100,1,100,2,161,2,125,2,124,2,155,0,100,2, + 124,1,155,0,157,3,125,3,100,3,100,4,108,2,109,3, + 125,4,1,0,122,18,124,4,124,0,106,4,160,5,124,3, + 161,1,131,1,87,0,83,0,4,0,116,6,107,10,114,86, + 1,0,1,0,1,0,116,7,124,3,131,1,130,1,89,0, + 110,2,88,0,100,0,83,0,41,5,78,114,85,0,0,0, + 114,109,0,0,0,114,0,0,0,0,41,1,218,7,66,121, + 116,101,115,73,79,41,8,114,38,0,0,0,114,19,0,0, + 0,90,2,105,111,114,177,0,0,0,114,4,0,0,0,114, + 55,0,0,0,114,22,0,0,0,218,17,70,105,108,101,78, + 111,116,70,111,117,110,100,69,114,114,111,114,41,5,114,32, + 0,0,0,218,8,114,101,115,111,117,114,99,101,218,16,102, + 117,108,108,110,97,109,101,95,97,115,95,112,97,116,104,114, + 13,0,0,0,114,177,0,0,0,114,9,0,0,0,114,9, + 0,0,0,114,10,0,0,0,218,13,111,112,101,110,95,114, + 101,115,111,117,114,99,101,224,2,0,0,115,14,0,0,0, + 0,1,14,1,14,1,12,1,2,1,18,1,14,1,122,38, + 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, + 99,101,82,101,97,100,101,114,46,111,112,101,110,95,114,101, + 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, + 8,0,0,0,116,0,130,1,100,0,83,0,114,88,0,0, + 0,41,1,114,178,0,0,0,41,2,114,32,0,0,0,114, + 179,0,0,0,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,13,114,101,115,111,117,114,99,101,95,112,97, + 116,104,233,2,0,0,115,2,0,0,0,0,4,122,38,95, + 90,105,112,73,109,112,111,114,116,82,101,115,111,117,114,99, + 101,82,101,97,100,101,114,46,114,101,115,111,117,114,99,101, + 95,112,97,116,104,99,2,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,8,0,0,0,67,0,0,0,115,72, + 0,0,0,124,0,106,0,160,1,100,1,100,2,161,2,125, + 2,124,2,155,0,100,2,124,1,155,0,157,3,125,3,122, + 16,124,0,106,2,160,3,124,3,161,1,1,0,87,0,110, + 22,4,0,116,4,107,10,114,66,1,0,1,0,1,0,89, + 0,100,3,83,0,88,0,100,4,83,0,41,5,78,114,85, + 0,0,0,114,109,0,0,0,70,84,41,5,114,38,0,0, + 0,114,19,0,0,0,114,4,0,0,0,114,55,0,0,0, + 114,22,0,0,0,41,4,114,32,0,0,0,114,59,0,0, + 0,114,180,0,0,0,114,13,0,0,0,114,9,0,0,0, + 114,9,0,0,0,114,10,0,0,0,218,11,105,115,95,114, + 101,115,111,117,114,99,101,239,2,0,0,115,14,0,0,0, + 0,3,14,1,14,1,2,1,16,1,14,1,8,1,122,36, + 95,90,105,112,73,109,112,111,114,116,82,101,115,111,117,114, + 99,101,82,101,97,100,101,114,46,105,115,95,114,101,115,111, + 117,114,99,101,99,1,0,0,0,0,0,0,0,0,0,0, + 0,9,0,0,0,9,0,0,0,99,0,0,0,115,186,0, + 0,0,100,1,100,2,108,0,109,1,125,1,1,0,124,1, + 124,0,106,2,160,3,124,0,106,4,161,1,131,1,125,2, + 124,2,160,5,124,0,106,2,106,6,161,1,125,3,124,3, + 106,7,100,3,107,2,115,58,116,8,130,1,124,3,106,9, + 125,4,116,10,131,0,125,5,124,0,106,2,106,11,68,0, + 93,102,125,6,122,18,124,1,124,6,131,1,160,5,124,4, + 161,1,125,7,87,0,110,24,4,0,116,12,107,10,114,124, + 1,0,1,0,1,0,89,0,113,78,89,0,110,2,88,0, + 124,7,106,9,106,7,125,8,116,13,124,8,131,1,100,1, + 107,2,114,156,124,7,106,7,86,0,1,0,113,78,124,8, + 124,5,107,7,114,78,124,5,160,14,124,8,161,1,1,0, + 124,8,86,0,1,0,113,78,100,0,83,0,41,4,78,114, + 0,0,0,0,41,1,218,4,80,97,116,104,114,60,0,0, + 0,41,15,90,7,112,97,116,104,108,105,98,114,184,0,0, + 0,114,4,0,0,0,114,56,0,0,0,114,38,0,0,0, + 90,11,114,101,108,97,116,105,118,101,95,116,111,114,29,0, + 0,0,114,59,0,0,0,114,175,0,0,0,90,6,112,97, + 114,101,110,116,218,3,115,101,116,114,28,0,0,0,114,23, + 0,0,0,114,51,0,0,0,218,3,97,100,100,41,9,114, + 32,0,0,0,114,184,0,0,0,90,13,102,117,108,108,110, + 97,109,101,95,112,97,116,104,90,13,114,101,108,97,116,105, + 118,101,95,112,97,116,104,90,12,112,97,99,107,97,103,101, + 95,112,97,116,104,90,12,115,117,98,100,105,114,115,95,115, + 101,101,110,218,8,102,105,108,101,110,97,109,101,90,8,114, + 101,108,97,116,105,118,101,90,11,112,97,114,101,110,116,95, + 110,97,109,101,114,9,0,0,0,114,9,0,0,0,114,10, + 0,0,0,218,8,99,111,110,116,101,110,116,115,250,2,0, + 0,115,34,0,0,0,0,8,12,1,18,1,14,3,14,1, + 6,1,6,1,12,1,2,1,18,1,14,1,10,5,8,1, + 12,1,10,1,8,1,10,1,122,33,95,90,105,112,73,109, + 112,111,114,116,82,101,115,111,117,114,99,101,82,101,97,100, + 101,114,46,99,111,110,116,101,110,116,115,78,41,10,114,6, + 0,0,0,114,7,0,0,0,114,8,0,0,0,114,84,0, + 0,0,114,81,0,0,0,114,34,0,0,0,114,181,0,0, + 0,114,182,0,0,0,114,183,0,0,0,114,188,0,0,0, + 114,9,0,0,0,114,9,0,0,0,114,9,0,0,0,114, + 10,0,0,0,114,80,0,0,0,212,2,0,0,115,14,0, + 0,0,8,1,4,5,4,2,8,4,8,9,8,6,8,11, + 114,80,0,0,0,41,45,114,84,0,0,0,90,26,95,102, + 114,111,122,101,110,95,105,109,112,111,114,116,108,105,98,95, + 101,120,116,101,114,110,97,108,114,21,0,0,0,114,1,0, + 0,0,114,2,0,0,0,90,17,95,102,114,111,122,101,110, + 95,105,109,112,111,114,116,108,105,98,114,76,0,0,0,114, + 148,0,0,0,114,110,0,0,0,114,152,0,0,0,114,67, + 0,0,0,114,131,0,0,0,90,7,95,95,97,108,108,95, + 95,114,20,0,0,0,90,15,112,97,116,104,95,115,101,112, + 97,114,97,116,111,114,115,114,18,0,0,0,114,75,0,0, + 0,114,3,0,0,0,114,25,0,0,0,218,4,116,121,112, + 101,114,70,0,0,0,114,113,0,0,0,114,115,0,0,0, + 114,117,0,0,0,114,4,0,0,0,114,89,0,0,0,114, + 36,0,0,0,114,37,0,0,0,114,35,0,0,0,114,27, + 0,0,0,114,122,0,0,0,114,142,0,0,0,114,144,0, + 0,0,114,52,0,0,0,114,147,0,0,0,114,155,0,0, + 0,218,8,95,95,99,111,100,101,95,95,114,153,0,0,0, + 114,159,0,0,0,114,161,0,0,0,114,169,0,0,0,114, + 151,0,0,0,114,149,0,0,0,114,44,0,0,0,114,80, + 0,0,0,114,9,0,0,0,114,9,0,0,0,114,9,0, + 0,0,114,10,0,0,0,218,8,60,109,111,100,117,108,101, + 62,1,0,0,0,115,88,0,0,0,4,16,8,1,16,1, + 8,1,8,1,8,1,8,1,8,1,8,2,8,3,6,1, + 14,3,16,4,4,2,8,2,4,1,4,1,4,2,14,127, + 0,127,0,1,12,1,12,1,2,1,2,252,4,9,8,4, + 8,9,8,31,8,126,2,254,2,29,4,5,8,21,8,46, + 8,10,8,46,10,5,8,7,8,6,8,13,8,19,8,15, + 8,26, }; diff --git a/Python/peephole.c b/Python/peephole.c index 1ce3535626e9a6..6f3e2ed88b2bed 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -250,12 +250,16 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, lnotab = (unsigned char*)PyBytes_AS_STRING(lnotab_obj); tabsiz = PyBytes_GET_SIZE(lnotab_obj); assert(tabsiz == 0 || Py_REFCNT(lnotab_obj) == 1); - if (memchr(lnotab, 255, tabsiz) != NULL) { - /* 255 value are used for multibyte bytecode instructions */ - goto exitUnchanged; + + /* Don't optimize if lnotab contains instruction pointer delta larger + than +255 (encoded as multiple bytes), just to keep the peephole optimizer + simple. The optimizer leaves line number deltas unchanged. */ + + for (j = 0; j < tabsiz; j += 2) { + if (lnotab[j] == 255) { + goto exitUnchanged; + } } - /* Note: -128 and 127 special values for line number delta are ok, - the peephole optimizer doesn't modify line numbers. */ assert(PyBytes_Check(code)); Py_ssize_t codesize = PyBytes_GET_SIZE(code); From 838f26402de82640698c38ea9d2be65c6cf780d6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Jun 2019 22:41:23 +0200 Subject: [PATCH 405/441] bpo-36710: Pass explicitly tstate in sysmodule.c (GH-14060) * Replace global var Py_VerboseFlag with interp->config.verbose. * Add _PyErr_NoMemory(tstate) function. * Add tstate parameter to _PyEval_SetCoroutineOriginTrackingDepth() and move the function to the internal API. * Replace _PySys_InitMain(runtime, interp) with _PySys_InitMain(runtime, tstate). --- Include/ceval.h | 1 - Include/internal/pycore_ceval.h | 3 + Include/internal/pycore_pyerrors.h | 2 + Include/internal/pycore_pylifecycle.h | 2 +- Python/ceval.c | 3 +- Python/errors.c | 10 +- Python/pylifecycle.c | 5 +- Python/sysmodule.c | 414 +++++++++++++++----------- 8 files changed, 262 insertions(+), 178 deletions(-) diff --git a/Include/ceval.h b/Include/ceval.h index 36fd014a91a7dd..e78194d512371a 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -31,7 +31,6 @@ PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, #ifndef Py_LIMITED_API PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); -PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth(int new_depth); PyAPI_FUNC(int) _PyEval_GetCoroutineOriginTrackingDepth(void); PyAPI_FUNC(void) _PyEval_SetAsyncGenFirstiter(PyObject *); PyAPI_FUNC(PyObject *) _PyEval_GetAsyncGenFirstiter(void); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 4c1c0e2439eea4..30cd6c9e09e44d 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -27,6 +27,9 @@ PyAPI_FUNC(void) _PyEval_SignalAsyncExc( struct _ceval_runtime_state *ceval); PyAPI_FUNC(void) _PyEval_ReInitThreads( _PyRuntimeState *runtime); +PyAPI_FUNC(void) _PyEval_SetCoroutineOriginTrackingDepth( + PyThreadState *tstate, + int new_depth); /* Private function */ void _PyEval_Fini(void); diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index 23327ef7839743..2efbf4a62f817c 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -39,6 +39,8 @@ PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate); PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception); +PyAPI_FUNC(PyObject *) _PyErr_NoMemory(PyThreadState *tstate); + PyAPI_FUNC(void) _PyErr_SetString( PyThreadState *tstate, PyObject *exception, diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 8a692ea1649512..6bfadd49eef8ba 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -45,7 +45,7 @@ extern PyStatus _PySys_Create( extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); extern int _PySys_InitMain( _PyRuntimeState *runtime, - PyInterpreterState *interp); + PyThreadState *tstate); extern PyStatus _PyImport_Init(PyInterpreterState *interp); extern PyStatus _PyExc_Init(void); extern PyStatus _PyErr_Init(void); diff --git a/Python/ceval.c b/Python/ceval.c index 7063647d584f65..bb0416f4cebacf 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4728,10 +4728,9 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) } void -_PyEval_SetCoroutineOriginTrackingDepth(int new_depth) +_PyEval_SetCoroutineOriginTrackingDepth(PyThreadState *tstate, int new_depth) { assert(new_depth >= 0); - PyThreadState *tstate = _PyThreadState_GET(); tstate->coroutine_origin_tracking_depth = new_depth; } diff --git a/Python/errors.c b/Python/errors.c index 8a94afdd8c4101..b3b9ac94cd1495 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -547,9 +547,8 @@ PyErr_BadArgument(void) } PyObject * -PyErr_NoMemory(void) +_PyErr_NoMemory(PyThreadState *tstate) { - PyThreadState *tstate = _PyThreadState_GET(); if (Py_TYPE(PyExc_MemoryError) == NULL) { /* PyErr_NoMemory() has been called before PyExc_MemoryError has been initialized by _PyExc_Init() */ @@ -560,6 +559,13 @@ PyErr_NoMemory(void) return NULL; } +PyObject * +PyErr_NoMemory(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_NoMemory(tstate); +} + PyObject * PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 751c4d6d1d631c..54e8ce2b1557af 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -899,6 +899,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) } /* Configure the main interpreter */ + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); PyConfig *config = &interp->config; if (runtime->initialized) { @@ -919,7 +920,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) return _PyStatus_ERR("can't initialize time"); } - if (_PySys_InitMain(runtime, interp) < 0) { + if (_PySys_InitMain(runtime, tstate) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } @@ -1456,7 +1457,7 @@ new_interpreter(PyThreadState **tstate_p) } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); - if (_PySys_InitMain(runtime, interp) < 0) { + if (_PySys_InitMain(runtime, tstate) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 12b1bd7711d5b8..fcbcb3b24d5206 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -17,10 +17,12 @@ Data members: #include "Python.h" #include "code.h" #include "frameobject.h" +#include "pycore_ceval.h" #include "pycore_initconfig.h" +#include "pycore_pathconfig.h" +#include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" -#include "pycore_pathconfig.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" #include "pythread.h" @@ -59,30 +61,38 @@ _Py_IDENTIFIER(stderr); _Py_IDENTIFIER(warnoptions); _Py_IDENTIFIER(write); -PyObject * -_PySys_GetObjectId(_Py_Identifier *key) +static PyObject * +sys_get_object_id(PyThreadState *tstate, _Py_Identifier *key) { - PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + PyObject *sd = tstate->interp->sysdict; if (sd == NULL) { return NULL; } return _PyDict_GetItemId(sd, key); } +PyObject * +_PySys_GetObjectId(_Py_Identifier *key) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return sys_get_object_id(tstate, key); +} + PyObject * PySys_GetObject(const char *name) { - PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *sd = tstate->interp->sysdict; if (sd == NULL) { return NULL; } return PyDict_GetItemString(sd, name); } -int -_PySys_SetObjectId(_Py_Identifier *key, PyObject *v) +static int +sys_set_object_id(PyThreadState *tstate, _Py_Identifier *key, PyObject *v) { - PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + PyObject *sd = tstate->interp->sysdict; if (v == NULL) { if (_PyDict_GetItemId(sd, key) == NULL) { return 0; @@ -97,9 +107,16 @@ _PySys_SetObjectId(_Py_Identifier *key, PyObject *v) } int -PySys_SetObject(const char *name, PyObject *v) +_PySys_SetObjectId(_Py_Identifier *key, PyObject *v) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return sys_set_object_id(tstate, key, v); +} + +static int +sys_set_object(PyThreadState *tstate, const char *name, PyObject *v) { - PyObject *sd = _PyInterpreterState_GET_UNSAFE()->sysdict; + PyObject *sd = tstate->interp->sysdict; if (v == NULL) { if (PyDict_GetItemString(sd, name) == NULL) { return 0; @@ -113,10 +130,16 @@ PySys_SetObject(const char *name, PyObject *v) } } +int +PySys_SetObject(const char *name, PyObject *v) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return sys_set_object(tstate, name, v); +} + static int -should_audit(void) +should_audit(PyThreadState *ts) { - PyThreadState *ts = _PyThreadState_GET(); if (!ts) { return 0; } @@ -134,6 +157,7 @@ PySys_Audit(const char *event, const char *argFormat, ...) PyObject *hooks = NULL; PyObject *hook = NULL; int res = -1; + PyThreadState *ts = _PyThreadState_GET(); /* N format is inappropriate, because you do not know whether the reference is consumed by the call. @@ -141,18 +165,16 @@ PySys_Audit(const char *event, const char *argFormat, ...) assert(!argFormat || !strchr(argFormat, 'N')); /* Early exit when no hooks are registered */ - if (!should_audit()) { + if (!should_audit(ts)) { return 0; } _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; - PyThreadState *ts = _PyThreadState_GET(); - PyInterpreterState *is = ts ? ts->interp : NULL; int dtrace = PyDTrace_AUDIT_ENABLED(); PyObject *exc_type, *exc_value, *exc_tb; if (ts) { - PyErr_Fetch(&exc_type, &exc_value, &exc_tb); + _PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb); } /* Initialize event args now */ @@ -185,6 +207,7 @@ PySys_Audit(const char *event, const char *argFormat, ...) } /* Call interpreter hooks */ + PyInterpreterState *is = ts ? ts->interp : NULL; if (is && is->audit_hooks) { eventName = PyUnicode_FromString(event); if (!eventName) { @@ -206,9 +229,9 @@ PySys_Audit(const char *event, const char *argFormat, ...) if (o) { canTrace = PyObject_IsTrue(o); Py_DECREF(o); - } else if (PyErr_Occurred() && - PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); + } else if (_PyErr_Occurred(ts) && + _PyErr_ExceptionMatches(ts, PyExc_AttributeError)) { + _PyErr_Clear(ts); canTrace = 0; } if (canTrace < 0) { @@ -232,7 +255,7 @@ PySys_Audit(const char *event, const char *argFormat, ...) } ts->use_tracing = (ts->c_tracefunc || ts->c_profilefunc); ts->tracing--; - if (PyErr_Occurred()) { + if (_PyErr_Occurred(ts)) { goto exit; } } @@ -247,9 +270,9 @@ PySys_Audit(const char *event, const char *argFormat, ...) if (ts) { if (!res) { - PyErr_Restore(exc_type, exc_value, exc_tb); + _PyErr_Restore(ts, exc_type, exc_value, exc_tb); } else { - assert(PyErr_Occurred()); + assert(_PyErr_Occurred(ts)); Py_XDECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); @@ -263,22 +286,26 @@ PySys_Audit(const char *event, const char *argFormat, ...) * finalization. In general, it should not need to be called, * and as such it is not defined in any header files. */ -void _PySys_ClearAuditHooks(void) { +void +_PySys_ClearAuditHooks(void) +{ /* Must be finalizing to clear hooks */ _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *ts = _PyRuntimeState_GetThreadState(runtime); assert(!ts || _Py_CURRENTLY_FINALIZING(runtime, ts)); - if (!ts || !_Py_CURRENTLY_FINALIZING(runtime, ts)) + if (!ts || !_Py_CURRENTLY_FINALIZING(runtime, ts)) { return; + } - if (Py_VerboseFlag) { + const PyConfig *config = &ts->interp->config; + if (config->verbose) { PySys_WriteStderr("# clear sys.audit hooks\n"); } /* Hooks can abort later hooks for this event, but cannot abort the clear operation itself. */ PySys_Audit("cpython._PySys_ClearAuditHooks", NULL); - PyErr_Clear(); + _PyErr_Clear(ts); _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n; _PyRuntime.audit_hook_head = NULL; @@ -292,13 +319,16 @@ void _PySys_ClearAuditHooks(void) { int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) { + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + /* Invoke existing audit hooks to allow them an opportunity to abort. */ /* Cannot invoke hooks until we are initialized */ - if (Py_IsInitialized()) { + if (runtime->initialized) { if (PySys_Audit("sys.addaudithook", NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_Exception)) { + if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) { /* We do not report errors derived from Exception */ - PyErr_Clear(); + _PyErr_Clear(tstate); return 0; } return -1; @@ -310,15 +340,17 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); _PyRuntime.audit_hook_head = e; } else { - while (e->next) + while (e->next) { e = e->next; + } e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc( sizeof(_Py_AuditHookEntry)); } if (!e) { - if (Py_IsInitialized()) - PyErr_NoMemory(); + if (runtime->initialized) { + _PyErr_NoMemory(tstate); + } return -1; } @@ -341,17 +373,19 @@ static PyObject * sys_addaudithook_impl(PyObject *module, PyObject *hook) /*[clinic end generated code: output=4f9c17aaeb02f44e input=0f3e191217a45e34]*/ { + PyThreadState *tstate = _PyThreadState_GET(); + /* Invoke existing audit hooks to allow them an opportunity to abort. */ if (PySys_Audit("sys.addaudithook", NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_Exception)) { + if (_PyErr_ExceptionMatches(tstate, PyExc_Exception)) { /* We do not report errors derived from Exception */ - PyErr_Clear(); + _PyErr_Clear(tstate); Py_RETURN_NONE; } return NULL; } - PyInterpreterState *is = _PyInterpreterState_Get(); + PyInterpreterState *is = tstate->interp; if (is->audit_hooks == NULL) { is->audit_hooks = PyList_New(0); @@ -375,23 +409,29 @@ Passes the event to any audit hooks that are attached."); static PyObject * sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc) { + PyThreadState *tstate = _PyThreadState_GET(); + if (argc == 0) { - PyErr_SetString(PyExc_TypeError, "audit() missing 1 required positional argument: 'event'"); + _PyErr_SetString(tstate, PyExc_TypeError, + "audit() missing 1 required positional argument: " + "'event'"); return NULL; } - if (!should_audit()) { + if (!should_audit(tstate)) { Py_RETURN_NONE; } PyObject *auditEvent = args[0]; if (!auditEvent) { - PyErr_SetString(PyExc_TypeError, "expected str for argument 'event'"); + _PyErr_SetString(tstate, PyExc_TypeError, + "expected str for argument 'event'"); return NULL; } if (!PyUnicode_Check(auditEvent)) { - PyErr_Format(PyExc_TypeError, "expected str for argument 'event', not %.200s", - Py_TYPE(auditEvent)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "expected str for argument 'event', not %.200s", + Py_TYPE(auditEvent)->tp_name); return NULL; } const char *event = PyUnicode_AsUTF8(auditEvent); @@ -418,7 +458,8 @@ sys_audit(PyObject *self, PyObject *const *args, Py_ssize_t argc) static PyObject * sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) { - assert(!PyErr_Occurred()); + PyThreadState *tstate = _PyThreadState_GET(); + assert(!_PyErr_Occurred(tstate)); char *envar = Py_GETENV("PYTHONBREAKPOINT"); if (envar == NULL || strlen(envar) == 0) { @@ -434,7 +475,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb * we need to save a copy of envar. */ envar = _PyMem_RawStrdup(envar); if (envar == NULL) { - PyErr_NoMemory(); + _PyErr_NoMemory(tstate); return NULL; } const char *last_dot = strrchr(envar, '.'); @@ -463,7 +504,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb Py_DECREF(modulepath); if (module == NULL) { - if (PyErr_ExceptionMatches(PyExc_ImportError)) { + if (_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) { goto warn; } PyMem_RawFree(envar); @@ -474,7 +515,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb Py_DECREF(module); if (hook == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { goto warn; } PyMem_RawFree(envar); @@ -487,7 +528,7 @@ sys_breakpointhook(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb warn: /* If any of the imports went wrong, then warn and ignore. */ - PyErr_Clear(); + _PyErr_Clear(tstate); int status = PyErr_WarnFormat( PyExc_RuntimeWarning, 0, "Ignoring unimportable $PYTHONBREAKPOINT: \"%s\"", envar); @@ -513,7 +554,7 @@ PyDoc_STRVAR(breakpointhook_doc, Helper function for sys_displayhook(). */ static int -sys_displayhook_unencodable(PyObject *outf, PyObject *o) +sys_displayhook_unencodable(PyThreadState *tstate, PyObject *outf, PyObject *o) { PyObject *stdout_encoding = NULL; PyObject *encoded, *escaped_str, *repr_str, *buffer, *result; @@ -547,7 +588,7 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) Py_DECREF(result); } else { - PyErr_Clear(); + _PyErr_Clear(tstate); escaped_str = PyUnicode_FromEncodedObject(encoded, stdout_encoding_str, "strict"); @@ -585,11 +626,13 @@ sys_displayhook(PyObject *module, PyObject *o) PyObject *builtins; static PyObject *newline = NULL; int err; + PyThreadState *tstate = _PyThreadState_GET(); builtins = _PyImport_GetModuleId(&PyId_builtins); if (builtins == NULL) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "lost builtins module"); } return NULL; } @@ -603,19 +646,20 @@ sys_displayhook(PyObject *module, PyObject *o) } if (_PyObject_SetAttrId(builtins, &PyId__, Py_None) != 0) return NULL; - outf = _PySys_GetObjectId(&PyId_stdout); + outf = sys_get_object_id(tstate, &PyId_stdout); if (outf == NULL || outf == Py_None) { - PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); + _PyErr_SetString(tstate, PyExc_RuntimeError, "lost sys.stdout"); return NULL; } if (PyFile_WriteObject(o, outf, 0) != 0) { - if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { + if (_PyErr_ExceptionMatches(tstate, PyExc_UnicodeEncodeError)) { /* repr(o) is not encodable to sys.stdout.encoding with * sys.stdout.errors error handler (which is probably 'strict') */ - PyErr_Clear(); - err = sys_displayhook_unencodable(outf, o); - if (err) + _PyErr_Clear(tstate); + err = sys_displayhook_unencodable(tstate, outf, o); + if (err) { return NULL; + } } else { return NULL; @@ -722,7 +766,8 @@ sys_exit_impl(PyObject *module, PyObject *status) /*[clinic end generated code: output=13870986c1ab2ec0 input=a737351f86685e9c]*/ { /* Raise SystemExit so callers may catch it or clean up. */ - PyErr_SetObject(PyExc_SystemExit, status); + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetObject(tstate, PyExc_SystemExit, status); return NULL; } @@ -751,8 +796,8 @@ static PyObject * sys_getfilesystemencoding_impl(PyObject *module) /*[clinic end generated code: output=1dc4bdbe9be44aa7 input=8475f8649b8c7d8c]*/ { - PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const PyConfig *config = &interp->config; + PyThreadState *tstate = _PyThreadState_GET(); + const PyConfig *config = &tstate->interp->config; return PyUnicode_FromWideChar(config->filesystem_encoding, -1); } @@ -766,8 +811,8 @@ static PyObject * sys_getfilesystemencodeerrors_impl(PyObject *module) /*[clinic end generated code: output=ba77b36bbf7c96f5 input=22a1e8365566f1e5]*/ { - PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE(); - const PyConfig *config = &interp->config; + PyThreadState *tstate = _PyThreadState_GET(); + const PyConfig *config = &tstate->interp->config; return PyUnicode_FromWideChar(config->filesystem_errors, -1); } @@ -788,14 +833,15 @@ static PyObject * sys_intern_impl(PyObject *module, PyObject *s) /*[clinic end generated code: output=be680c24f5c9e5d6 input=849483c006924e2f]*/ { + PyThreadState *tstate = _PyThreadState_GET(); if (PyUnicode_CheckExact(s)) { Py_INCREF(s); PyUnicode_InternInPlace(&s); return s; } else { - PyErr_Format(PyExc_TypeError, - "can't intern %.400s", s->ob_type->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "can't intern %.400s", s->ob_type->tp_name); return NULL; } } @@ -833,19 +879,17 @@ static PyObject * call_trampoline(PyObject* callback, PyFrameObject *frame, int what, PyObject *arg) { - PyObject *result; - PyObject *stack[3]; - if (PyFrame_FastToLocalsWithError(frame) < 0) { return NULL; } + PyObject *stack[3]; stack[0] = (PyObject *)frame; stack[1] = whatstrings[what]; stack[2] = (arg != NULL) ? arg : Py_None; /* call the Python-level function */ - result = _PyObject_FastCall(callback, stack, 3); + PyObject *result = _PyObject_FastCall(callback, stack, 3); PyFrame_LocalsToFast(frame, 1); if (result == NULL) { @@ -1001,11 +1045,12 @@ sys_setcheckinterval_impl(PyObject *module, int n) if (PyErr_WarnEx(PyExc_DeprecationWarning, "sys.getcheckinterval() and sys.setcheckinterval() " "are deprecated. Use sys.setswitchinterval() " - "instead.", 1) < 0) + "instead.", 1) < 0) { return NULL; + } - PyInterpreterState *interp = _PyInterpreterState_Get(); - interp->check_interval = n; + PyThreadState *tstate = _PyThreadState_GET(); + tstate->interp->check_interval = n; Py_RETURN_NONE; } @@ -1022,10 +1067,12 @@ sys_getcheckinterval_impl(PyObject *module) if (PyErr_WarnEx(PyExc_DeprecationWarning, "sys.getcheckinterval() and sys.setcheckinterval() " "are deprecated. Use sys.getswitchinterval() " - "instead.", 1) < 0) + "instead.", 1) < 0) { return NULL; - PyInterpreterState *interp = _PyInterpreterState_Get(); - return PyLong_FromLong(interp->check_interval); + } + + PyThreadState *tstate = _PyThreadState_GET(); + return PyLong_FromLong(tstate->interp->check_interval); } /*[clinic input] @@ -1048,9 +1095,10 @@ static PyObject * sys_setswitchinterval_impl(PyObject *module, double interval) /*[clinic end generated code: output=65a19629e5153983 input=561b477134df91d9]*/ { + PyThreadState *tstate = _PyThreadState_GET(); if (interval <= 0.0) { - PyErr_SetString(PyExc_ValueError, - "switch interval must be strictly positive"); + _PyErr_SetString(tstate, PyExc_ValueError, + "switch interval must be strictly positive"); return NULL; } _PyEval_SetSwitchInterval((unsigned long) (1e6 * interval)); @@ -1089,11 +1137,11 @@ sys_setrecursionlimit_impl(PyObject *module, int new_limit) /*[clinic end generated code: output=35e1c64754800ace input=b0f7a23393924af3]*/ { int mark; - PyThreadState *tstate; + PyThreadState *tstate = _PyThreadState_GET(); if (new_limit < 1) { - PyErr_SetString(PyExc_ValueError, - "recursion limit must be greater or equal than 1"); + _PyErr_SetString(tstate, PyExc_ValueError, + "recursion limit must be greater or equal than 1"); return NULL; } @@ -1107,12 +1155,11 @@ sys_setrecursionlimit_impl(PyObject *module, int new_limit) the new low-water mark. Otherwise it may not be possible anymore to reset the overflowed flag to 0. */ mark = _Py_RecursionLimitLowerWaterMark(new_limit); - tstate = _PyThreadState_GET(); if (tstate->recursion_depth >= mark) { - PyErr_Format(PyExc_RecursionError, - "cannot set the recursion limit to %i at " - "the recursion depth %i: the limit is too low", - new_limit, tstate->recursion_depth); + _PyErr_Format(tstate, PyExc_RecursionError, + "cannot set the recursion limit to %i at " + "the recursion depth %i: the limit is too low", + new_limit, tstate->recursion_depth); return NULL; } @@ -1137,11 +1184,12 @@ static PyObject * sys_set_coroutine_origin_tracking_depth_impl(PyObject *module, int depth) /*[clinic end generated code: output=0a2123c1cc6759c5 input=a1d0a05f89d2c426]*/ { + PyThreadState *tstate = _PyThreadState_GET(); if (depth < 0) { - PyErr_SetString(PyExc_ValueError, "depth must be >= 0"); + _PyErr_SetString(tstate, PyExc_ValueError, "depth must be >= 0"); return NULL; } - _PyEval_SetCoroutineOriginTrackingDepth(depth); + _PyEval_SetCoroutineOriginTrackingDepth(tstate, depth); Py_RETURN_NONE; } @@ -1185,6 +1233,7 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) static char *keywords[] = {"firstiter", "finalizer", NULL}; PyObject *firstiter = NULL; PyObject *finalizer = NULL; + PyThreadState *tstate = _PyThreadState_GET(); if (!PyArg_ParseTupleAndKeywords( args, kw, "|OO", keywords, @@ -1194,9 +1243,9 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) if (finalizer && finalizer != Py_None) { if (!PyCallable_Check(finalizer)) { - PyErr_Format(PyExc_TypeError, - "callable finalizer expected, got %.50s", - Py_TYPE(finalizer)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "callable finalizer expected, got %.50s", + Py_TYPE(finalizer)->tp_name); return NULL; } _PyEval_SetAsyncGenFinalizer(finalizer); @@ -1207,9 +1256,9 @@ sys_set_asyncgen_hooks(PyObject *self, PyObject *args, PyObject *kw) if (firstiter && firstiter != Py_None) { if (!PyCallable_Check(firstiter)) { - PyErr_Format(PyExc_TypeError, - "callable firstiter expected, got %.50s", - Py_TYPE(firstiter)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "callable firstiter expected, got %.50s", + Py_TYPE(firstiter)->tp_name); return NULL; } _PyEval_SetAsyncGenFirstiter(firstiter); @@ -1297,7 +1346,7 @@ static PyStructSequence_Desc hash_info_desc = { }; static PyObject * -get_hash_info(void) +get_hash_info(PyThreadState *tstate) { PyObject *hash_info; int field = 0; @@ -1324,7 +1373,7 @@ get_hash_info(void) PyLong_FromLong(hashfunc->seed_bits)); PyStructSequence_SET_ITEM(hash_info, field++, PyLong_FromLong(Py_HASH_CUTOFF)); - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { Py_CLEAR(hash_info); return NULL; } @@ -1408,6 +1457,7 @@ sys_getwindowsversion_impl(PyObject *module) wchar_t kernel32_path[MAX_PATH]; LPVOID verblock; DWORD verblock_size; + PyThreadState *tstate = _PyThreadState_GET(); ver.dwOSVersionInfoSize = sizeof(ver); if (!GetVersionExW((OSVERSIONINFOW*) &ver)) @@ -1458,7 +1508,7 @@ sys_getwindowsversion_impl(PyObject *module) realBuild )); - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { Py_DECREF(version); return NULL; } @@ -1515,8 +1565,8 @@ static PyObject * sys_setdlopenflags_impl(PyObject *module, int new_val) /*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/ { - PyInterpreterState *interp = _PyInterpreterState_Get(); - interp->dlopenflags = new_val; + PyThreadState *tstate = _PyThreadState_GET(); + tstate->interp->dlopenflags = new_val; Py_RETURN_NONE; } @@ -1533,8 +1583,8 @@ static PyObject * sys_getdlopenflags_impl(PyObject *module) /*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/ { - PyInterpreterState *interp = _PyInterpreterState_Get(); - return PyLong_FromLong(interp->dlopenflags); + PyThreadState *tstate = _PyThreadState_GET(); + return PyLong_FromLong(tstate->interp->dlopenflags); } #endif /* HAVE_DLOPEN */ @@ -1566,17 +1616,20 @@ _PySys_GetSizeOf(PyObject *o) PyObject *res = NULL; PyObject *method; Py_ssize_t size; + PyThreadState *tstate = _PyThreadState_GET(); /* Make sure the type is initialized. float gets initialized late */ - if (PyType_Ready(Py_TYPE(o)) < 0) + if (PyType_Ready(Py_TYPE(o)) < 0) { return (size_t)-1; + } method = _PyObject_LookupSpecial(o, &PyId___sizeof__); if (method == NULL) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __sizeof__", - Py_TYPE(o)->tp_name); + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "Type %.100s doesn't define __sizeof__", + Py_TYPE(o)->tp_name); + } } else { res = _PyObject_CallNoArg(method); @@ -1588,11 +1641,12 @@ _PySys_GetSizeOf(PyObject *o) size = PyLong_AsSsize_t(res); Py_DECREF(res); - if (size == -1 && PyErr_Occurred()) + if (size == -1 && _PyErr_Occurred(tstate)) return (size_t)-1; if (size < 0) { - PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0"); + _PyErr_SetString(tstate, PyExc_ValueError, + "__sizeof__() should return >= 0"); return (size_t)-1; } @@ -1608,17 +1662,19 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) static char *kwlist[] = {"object", "default", 0}; size_t size; PyObject *o, *dflt = NULL; + PyThreadState *tstate = _PyThreadState_GET(); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", - kwlist, &o, &dflt)) + kwlist, &o, &dflt)) { return NULL; + } size = _PySys_GetSizeOf(o); - if (size == (size_t)-1 && PyErr_Occurred()) { + if (size == (size_t)-1 && _PyErr_Occurred(tstate)) { /* Has a default value been given */ - if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Clear(); + if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { + _PyErr_Clear(tstate); Py_INCREF(dflt); return dflt; } @@ -1716,7 +1772,8 @@ static PyObject * sys__getframe_impl(PyObject *module, int depth) /*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/ { - PyFrameObject *f = _PyThreadState_GET()->frame; + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *f = tstate->frame; if (PySys_Audit("sys._getframe", "O", f) < 0) { return NULL; @@ -1727,8 +1784,8 @@ sys__getframe_impl(PyObject *module, int depth) --depth; } if (f == NULL) { - PyErr_SetString(PyExc_ValueError, - "call stack is not deep enough"); + _PyErr_SetString(tstate, PyExc_ValueError, + "call stack is not deep enough"); return NULL; } Py_INCREF(f); @@ -2078,10 +2135,9 @@ _clear_all_preinit_options(void) } static int -_PySys_ReadPreInitOptions(void) +sys_read_preinit_options(PyThreadState *tstate) { /* Rerun the add commands with the actual sys module available */ - PyThreadState *tstate = _PyThreadState_GET(); if (tstate == NULL) { /* Still don't have a thread state, so something is wrong! */ return -1; @@ -2102,9 +2158,9 @@ _PySys_ReadPreInitOptions(void) } static PyObject * -get_warnoptions(void) +get_warnoptions(PyThreadState *tstate) { - PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); + PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); if (warnoptions == NULL || !PyList_Check(warnoptions)) { /* PEP432 TODO: we can reach this if warnoptions is NULL in the main * interpreter config. When that happens, we need to properly set @@ -2117,9 +2173,10 @@ get_warnoptions(void) * reachable again. */ warnoptions = PyList_New(0); - if (warnoptions == NULL) + if (warnoptions == NULL) { return NULL; - if (_PySys_SetObjectId(&PyId_warnoptions, warnoptions)) { + } + if (sys_set_object_id(tstate, &PyId_warnoptions, warnoptions)) { Py_DECREF(warnoptions); return NULL; } @@ -2137,16 +2194,16 @@ PySys_ResetWarnOptions(void) return; } - PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); + PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); if (warnoptions == NULL || !PyList_Check(warnoptions)) return; PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL); } static int -_PySys_AddWarnOptionWithError(PyObject *option) +_PySys_AddWarnOptionWithError(PyThreadState *tstate, PyObject *option) { - PyObject *warnoptions = get_warnoptions(); + PyObject *warnoptions = get_warnoptions(tstate); if (warnoptions == NULL) { return -1; } @@ -2159,10 +2216,11 @@ _PySys_AddWarnOptionWithError(PyObject *option) void PySys_AddWarnOptionUnicode(PyObject *option) { - if (_PySys_AddWarnOptionWithError(option) < 0) { + PyThreadState *tstate = _PyThreadState_GET(); + if (_PySys_AddWarnOptionWithError(tstate, option) < 0) { /* No return value, therefore clear error state if possible */ - if (_PyThreadState_UncheckedGet()) { - PyErr_Clear(); + if (tstate) { + _PyErr_Clear(tstate); } } } @@ -2186,15 +2244,16 @@ PySys_AddWarnOption(const wchar_t *s) int PySys_HasWarnOptions(void) { - PyObject *warnoptions = _PySys_GetObjectId(&PyId_warnoptions); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *warnoptions = sys_get_object_id(tstate, &PyId_warnoptions); return (warnoptions != NULL && PyList_Check(warnoptions) && PyList_GET_SIZE(warnoptions) > 0); } static PyObject * -get_xoptions(void) +get_xoptions(PyThreadState *tstate) { - PyObject *xoptions = _PySys_GetObjectId(&PyId__xoptions); + PyObject *xoptions = sys_get_object_id(tstate, &PyId__xoptions); if (xoptions == NULL || !PyDict_Check(xoptions)) { /* PEP432 TODO: we can reach this if xoptions is NULL in the main * interpreter config. When that happens, we need to properly set @@ -2207,9 +2266,10 @@ get_xoptions(void) * reachable again. */ xoptions = PyDict_New(); - if (xoptions == NULL) + if (xoptions == NULL) { return NULL; - if (_PySys_SetObjectId(&PyId__xoptions, xoptions)) { + } + if (sys_set_object_id(tstate, &PyId__xoptions, xoptions)) { Py_DECREF(xoptions); return NULL; } @@ -2223,7 +2283,8 @@ _PySys_AddXOptionWithError(const wchar_t *s) { PyObject *name = NULL, *value = NULL; - PyObject *opts = get_xoptions(); + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *opts = get_xoptions(tstate); if (opts == NULL) { goto error; } @@ -2264,8 +2325,8 @@ PySys_AddXOption(const wchar_t *s) } if (_PySys_AddXOptionWithError(s) < 0) { /* No return value, therefore clear error state if possible */ - if (_PyThreadState_UncheckedGet()) { - PyErr_Clear(); + if (tstate) { + _PyErr_Clear(tstate); } } } @@ -2273,7 +2334,8 @@ PySys_AddXOption(const wchar_t *s) PyObject * PySys_GetXOptions(void) { - return get_xoptions(); + PyThreadState *tstate = _PyThreadState_GET(); + return get_xoptions(tstate); } /* XXX This doc string is too long to be a single string literal in VC++ 5.0. @@ -2413,12 +2475,12 @@ static PyStructSequence_Desc flags_desc = { }; static PyObject* -make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) +make_flags(_PyRuntimeState *runtime, PyThreadState *tstate) { int pos = 0; PyObject *seq; const PyPreConfig *preconfig = &runtime->preconfig; - const PyConfig *config = &interp->config; + const PyConfig *config = &tstate->interp->config; seq = PyStructSequence_New(&FlagsType); if (seq == NULL) @@ -2446,7 +2508,7 @@ make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) SetFlag(preconfig->utf8_mode); #undef SetFlag - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { Py_DECREF(seq); return NULL; } @@ -2477,7 +2539,7 @@ static PyStructSequence_Desc version_info_desc = { }; static PyObject * -make_version_info(void) +make_version_info(PyThreadState *tstate) { PyObject *version_info; char *s; @@ -2515,7 +2577,7 @@ make_version_info(void) #undef SetIntItem #undef SetStrItem - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { Py_CLEAR(version_info); return NULL; } @@ -2633,7 +2695,7 @@ static struct PyModuleDef sysmodule = { } while (0) static PyStatus -_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, +_PySys_InitCore(_PyRuntimeState *runtime, PyThreadState *tstate, PyObject *sysdict) { PyObject *version_info; @@ -2678,7 +2740,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, } } SET_SYS_FROM_STRING("hash_info", - get_hash_info()); + get_hash_info(tstate)); SET_SYS_FROM_STRING("maxunicode", PyLong_FromLong(0x10FFFF)); SET_SYS_FROM_STRING("builtin_module_names", @@ -2709,14 +2771,15 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, goto type_init_failed; } } - version_info = make_version_info(); + version_info = make_version_info(tstate); SET_SYS_FROM_STRING("version_info", version_info); /* prevent user from creating new instances */ VersionInfoType.tp_init = NULL; VersionInfoType.tp_new = NULL; res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__"); - if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) - PyErr_Clear(); + if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyErr_Clear(tstate); + } /* implementation */ SET_SYS_FROM_STRING("implementation", make_impl_info(version_info)); @@ -2728,7 +2791,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, } } /* Set flags to their default values (updated by _PySys_InitMain()) */ - SET_SYS_FROM_STRING("flags", make_flags(runtime, interp)); + SET_SYS_FROM_STRING("flags", make_flags(runtime, tstate)); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -2740,10 +2803,10 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, /* prevent user from creating new instances */ WindowsVersionType.tp_init = NULL; WindowsVersionType.tp_new = NULL; - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__"); - if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { - PyErr_Clear(); + if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyErr_Clear(tstate); } #endif @@ -2766,7 +2829,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, } } - if (PyErr_Occurred()) { + if (_PyErr_Occurred(tstate)) { goto err_occurred; } return _PyStatus_OK(); @@ -2849,10 +2912,10 @@ sys_create_xoptions_dict(const PyConfig *config) int -_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) +_PySys_InitMain(_PyRuntimeState *runtime, PyThreadState *tstate) { - PyObject *sysdict = interp->sysdict; - const PyConfig *config = &interp->config; + PyObject *sysdict = tstate->interp->sysdict; + const PyConfig *config = &tstate->interp->config; int res; #define COPY_LIST(KEY, VALUE) \ @@ -2903,34 +2966,37 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) #undef SET_SYS_FROM_WSTR /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp)); + SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, tstate)); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; res = PyDict_DelItemString(FlagsType.tp_dict, "__new__"); if (res < 0) { - if (!PyErr_ExceptionMatches(PyExc_KeyError)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { return res; } - PyErr_Clear(); + _PyErr_Clear(tstate); } SET_SYS_FROM_STRING_INT_RESULT("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode)); - if (get_warnoptions() == NULL) + if (get_warnoptions(tstate) == NULL) { return -1; + } - if (get_xoptions() == NULL) + if (get_xoptions(tstate) == NULL) return -1; /* Transfer any sys.warnoptions and sys._xoptions set directly * by an embedding application from the linked list to the module. */ - if (_PySys_ReadPreInitOptions() != 0) + if (sys_read_preinit_options(tstate) != 0) return -1; - if (PyErr_Occurred()) - return -1; + if (_PyErr_Occurred(tstate)) { + goto err_occurred; + } + return 0; err_occurred: @@ -2973,6 +3039,8 @@ PyStatus _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, PyObject **sysmod_p) { + PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyObject *modules = PyDict_New(); if (modules == NULL) { return _PyStatus_ERR("can't make modules dictionary"); @@ -3000,7 +3068,7 @@ _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, return status; } - status = _PySys_InitCore(runtime, interp, sysdict); + status = _PySys_InitCore(runtime, tstate, sysdict); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -3051,8 +3119,10 @@ PySys_SetPath(const wchar_t *path) PyObject *v; if ((v = makepathobject(path, DELIM)) == NULL) Py_FatalError("can't create sys.path"); - if (_PySys_SetObjectId(&PyId_path, v) != 0) + PyThreadState *tstate = _PyThreadState_GET(); + if (sys_set_object_id(tstate, &PyId_path, v) != 0) { Py_FatalError("can't assign sys.path"); + } Py_DECREF(v); } @@ -3078,6 +3148,8 @@ make_sys_argv(int argc, wchar_t * const * argv) void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) { + PyThreadState *tstate = _PyThreadState_GET(); + if (argc < 1 || argv == NULL) { /* Ensure at least one (empty) argument is seen */ wchar_t* empty_argv[1] = {L""}; @@ -3089,7 +3161,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) if (av == NULL) { Py_FatalError("no mem for sys.argv"); } - if (PySys_SetObject("argv", av) != 0) { + if (sys_set_object(tstate, "argv", av) != 0) { Py_DECREF(av); Py_FatalError("can't assign sys.argv"); } @@ -3105,7 +3177,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath) Py_FatalError("can't compute path0 from argv"); } - PyObject *sys_path = _PySys_GetObjectId(&PyId_path); + PyObject *sys_path = sys_get_object_id(tstate, &PyId_path); if (sys_path != NULL) { if (PyList_Insert(sys_path, 0, path0) < 0) { Py_DECREF(path0); @@ -3208,12 +3280,13 @@ sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va) PyObject *error_type, *error_value, *error_traceback; char buffer[1001]; int written; + PyThreadState *tstate = _PyThreadState_GET(); - PyErr_Fetch(&error_type, &error_value, &error_traceback); - file = _PySys_GetObjectId(key); + _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); + file = sys_get_object_id(tstate, key); written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); if (sys_pyfile_write(buffer, file) != 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); fputs(buffer, fp); } if (written < 0 || (size_t)written >= sizeof(buffer)) { @@ -3221,7 +3294,7 @@ sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va) if (sys_pyfile_write(truncated, file) != 0) fputs(truncated, fp); } - PyErr_Restore(error_type, error_value, error_traceback); + _PyErr_Restore(tstate, error_type, error_value, error_traceback); } void @@ -3250,20 +3323,21 @@ sys_format(_Py_Identifier *key, FILE *fp, const char *format, va_list va) PyObject *file, *message; PyObject *error_type, *error_value, *error_traceback; const char *utf8; + PyThreadState *tstate = _PyThreadState_GET(); - PyErr_Fetch(&error_type, &error_value, &error_traceback); - file = _PySys_GetObjectId(key); + _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); + file = sys_get_object_id(tstate, key); message = PyUnicode_FromFormatV(format, va); if (message != NULL) { if (sys_pyfile_write_unicode(message, file) != 0) { - PyErr_Clear(); + _PyErr_Clear(tstate); utf8 = PyUnicode_AsUTF8(message); if (utf8 != NULL) fputs(utf8, fp); } Py_DECREF(message); } - PyErr_Restore(error_type, error_value, error_traceback); + _PyErr_Restore(tstate, error_type, error_value, error_traceback); } void From d0eeb936d8daf05d7d89f6935e3f4c0dee49c5be Mon Sep 17 00:00:00 2001 From: Michael Felt Date: Fri, 14 Jun 2019 00:34:46 +0200 Subject: [PATCH 406/441] bpo-37077: Add native thread ID (TID) for AIX (GH-13624) This is the followup for issue36084 https://bugs.python.org/issue37077 --- Doc/library/_thread.rst | 2 +- Doc/library/threading.rst | 2 +- Include/pythread.h | 2 +- .../2019-05-28-11-47-44.bpo-37077.S1h0Fc.rst | 2 ++ Python/thread_pthread.h | 9 +++++++-- 5 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc.rst diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 5b4fcde669e13b..bd653ab32bb9c4 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -106,7 +106,7 @@ This module defines the following constants and functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX. .. versionadded:: 3.8 diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index b4f4814c4ad37b..2907b65f5bca42 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -82,7 +82,7 @@ This module defines the following functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX. .. versionadded:: 3.8 diff --git a/Include/pythread.h b/Include/pythread.h index 79a9210af3a491..f22e8c42c50277 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -26,7 +26,7 @@ PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); -#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) +#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); #endif diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc.rst new file mode 100644 index 00000000000000..832dfc94ac49e2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-28-11-47-44.bpo-37077.S1h0Fc.rst @@ -0,0 +1,2 @@ +Add :func:`threading.get_native_id` support for AIX. +Patch by M. Felt diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 9b4b23bdc7d7bf..a36d16c19eade5 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -18,8 +18,10 @@ # include /* pthread_getthreadid_np() */ #elif defined(__OpenBSD__) # include /* getthrid() */ -#elif defined(__NetBSD__) /* _lwp_self */ -# include +#elif defined(_AIX) +# include /* thread_self() */ +#elif defined(__NetBSD__) +# include /* _lwp_self() */ #endif /* The POSIX spec requires that use of pthread_attr_setstacksize @@ -330,6 +332,9 @@ PyThread_get_thread_native_id(void) #elif defined(__OpenBSD__) pid_t native_id; native_id = getthrid(); +#elif defined(_AIX) + tid_t native_id; + native_id = thread_self(); #elif defined(__NetBSD__) lwpid_t native_id; native_id = _lwp_self(); From 05f831865545b08c9a21cfb7773af58b76ec64cb Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Fri, 14 Jun 2019 06:54:53 +0100 Subject: [PATCH 407/441] bpo-37269: Correctly optimise conditionals with constant booleans (GH-14071) Fix a regression introduced by af8646c8054d0f4180a2013383039b6a472f9698 that was causing code of the form: if True and False: do_something() to be optimized incorrectly, eliminating the block. --- Lib/test/test_peepholer.py | 7 +++++++ .../2019-06-14-06-32-33.bpo-37269.SjVVAe.rst | 2 ++ Python/peephole.c | 5 +++++ 3 files changed, 14 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 860ceeb003e7b3..5d00240e2595a8 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -414,6 +414,13 @@ def forloop(): pass self.assertEqual(count_instr_recursively(forloop, 'BUILD_LIST'), 0) + def test_condition_with_binop_with_bools(self): + def f(): + if True or False: + return 1 + return 0 + self.assertEqual(f(), 1) + class TestBuglets(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst new file mode 100644 index 00000000000000..b9b79066774f86 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-14-06-32-33.bpo-37269.SjVVAe.rst @@ -0,0 +1,2 @@ +Fix a bug in the peephole optimizer that was not treating correctly constant +conditions with binary operators. Patch by Pablo Galindo. diff --git a/Python/peephole.c b/Python/peephole.c index 6f3e2ed88b2bed..d7b1dfc4d9c141 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -315,6 +315,11 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, fill_nops(codestr, op_start, nexti + 1); cumlc = 0; } else if (is_true == 0) { + if (i > 1 && + (_Py_OPCODE(codestr[i - 1]) == POP_JUMP_IF_TRUE || + _Py_OPCODE(codestr[i - 1]) == POP_JUMP_IF_FALSE)) { + break; + } h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT); tgt = find_op(codestr, codelen, h); fill_nops(codestr, op_start, tgt); From b2f94730d947f25b8507c5f76202e917683e76f7 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 14 Jun 2019 12:37:15 +0200 Subject: [PATCH 408/441] bpo-37249: add declaration of _PyObject_GetMethod (GH-14015) --- Include/cpython/object.h | 3 +++ Objects/call.c | 3 --- Python/ceval.c | 4 ---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index a65aaf6482159c..fd4e77103f01b8 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -318,6 +318,9 @@ PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *); */ PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **); PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, struct _Py_Identifier *, PyObject **); + +PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); diff --git a/Objects/call.c b/Objects/call.c index 578e1b3ab61933..8eae1e10d8c556 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1211,9 +1211,6 @@ object_vacall(PyObject *base, PyObject *callable, va_list vargs) } -/* Private API for the LOAD_METHOD opcode. */ -extern int _PyObject_GetMethod(PyObject *, PyObject *, PyObject **); - PyObject * PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) { diff --git a/Python/ceval.c b/Python/ceval.c index bb0416f4cebacf..60367a665d7d62 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -38,10 +38,6 @@ # error "ceval.c must be build with Py_BUILD_CORE define for best performance" #endif -/* Private API for the LOAD_METHOD opcode. */ -extern int _PyObject_GetMethod(PyObject *, PyObject *, PyObject **); - -typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *); /* Forward declarations */ Py_LOCAL_INLINE(PyObject *) call_function( From 07559450b2d9179e4c99e0af088ce7550e549f94 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Jun 2019 13:02:51 +0200 Subject: [PATCH 409/441] bpo-37278: Fix test_asyncio ProactorLoopCtrlC (GH-14074) Join the thread to prevent leaking a running thread and leaking a reference. Cleanup also the test: * asyncioWindowsProactorEventLoopPolicy became the default policy, there is no need to set it manually. * Only start the thread once the loop is running. * Use a shorter sleep in the thread (100 ms rather than 1 sec). * Use close_loop(loop) rather than loop.close(). * Use longer variable names. --- Lib/test/test_asyncio/test_windows_events.py | 15 ++++++++------- .../2019-06-14-12-21-47.bpo-37278.z0HUOr.rst | 2 ++ 2 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 13aef7cf1f776b..1e1c01d713b5c6 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -45,20 +45,21 @@ class ProactorLoopCtrlC(test_utils.TestCase): def test_ctrl_c(self): def SIGINT_after_delay(): - time.sleep(1) + time.sleep(0.1) signal.raise_signal(signal.SIGINT) - asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) - l = asyncio.get_event_loop() + thread = threading.Thread(target=SIGINT_after_delay) + loop = asyncio.get_event_loop() try: - t = threading.Thread(target=SIGINT_after_delay) - t.start() - l.run_forever() + # only start the loop once the event loop is running + loop.call_soon(thread.start) + loop.run_forever() self.fail("should not fall through 'run_forever'") except KeyboardInterrupt: pass finally: - l.close() + self.close_loop(loop) + thread.join() class ProactorTests(test_utils.TestCase): diff --git a/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst b/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst new file mode 100644 index 00000000000000..3d3011b51c5b1d --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-06-14-12-21-47.bpo-37278.z0HUOr.rst @@ -0,0 +1,2 @@ +Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent leaking a +running thread and leaking a reference. From 431478d5d74d880692817323198b9605af972fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Fri, 14 Jun 2019 16:39:43 +0200 Subject: [PATCH 410/441] Update concurrent.futures.rst (GH-14061) This PR adds missing details in the [`concurrent.futures`](https://docs.python.org/3/library/concurrent.futures.html) documentation: * the mention that `Future.cancel` also returns `False` if the call finished running; * the mention of the states for `Future` that did not complete: pending or running. --- Doc/library/concurrent.futures.rst | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 34905c449d7f8b..d71f2d80c9e2d0 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -306,9 +306,10 @@ The :class:`Future` class encapsulates the asynchronous execution of a callable. .. method:: cancel() - Attempt to cancel the call. If the call is currently being executed and - cannot be cancelled then the method will return ``False``, otherwise the - call will be cancelled and the method will return ``True``. + Attempt to cancel the call. If the call is currently being executed or + finished running and cannot be cancelled then the method will return + ``False``, otherwise the call will be cancelled and the method will + return ``True``. .. method:: cancelled() @@ -423,8 +424,9 @@ Module Functions Wait for the :class:`Future` instances (possibly created by different :class:`Executor` instances) given by *fs* to complete. Returns a named 2-tuple of sets. The first set, named ``done``, contains the futures that - completed (finished or were cancelled) before the wait completed. The second - set, named ``not_done``, contains uncompleted futures. + completed (finished or cancelled futures) before the wait completed. The + second set, named ``not_done``, contains the futures that did not complete + (pending or running futures). *timeout* can be used to control the maximum number of seconds to wait before returning. *timeout* can be an int or float. If *timeout* is not specified @@ -455,7 +457,7 @@ Module Functions Returns an iterator over the :class:`Future` instances (possibly created by different :class:`Executor` instances) given by *fs* that yields futures as - they complete (finished or were cancelled). Any futures given by *fs* that + they complete (finished or cancelled futures). Any futures given by *fs* that are duplicated will be returned once. Any futures that completed before :func:`as_completed` is called will be yielded first. The returned iterator raises a :exc:`concurrent.futures.TimeoutError` if :meth:`~iterator.__next__` From f0749da9a535375f05a2015e8960e8ae54877349 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Fri, 14 Jun 2019 18:26:24 +0300 Subject: [PATCH 411/441] bpo-35998: Avoid TimeoutError in test_asyncio: test_start_tls_server_1() (GH-14080) --- Lib/test/test_asyncio/test_sslproto.py | 37 ++++++++++--------- .../2019-06-14-17-05-49.bpo-35998.yX82oD.rst | 1 + 2 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 4215abf5d8630b..5c861e92b7d67c 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -494,17 +494,14 @@ async def client(addr): def test_start_tls_server_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE + ANSWER = b'answer' server_context = test_utils.simple_server_sslcontext() client_context = test_utils.simple_client_sslcontext() - if sys.platform.startswith('freebsd') or sys.platform.startswith('win'): - # bpo-35031: Some FreeBSD and Windows buildbots fail to run this test - # as the eof was not being received by the server if the payload - # size is not big enough. This behaviour only appears if the - # client is using TLS1.3. - client_context.options |= ssl.OP_NO_TLSv1_3 + answer = None def client(sock, addr): + nonlocal answer sock.settimeout(self.TIMEOUT) sock.connect(addr) @@ -513,33 +510,36 @@ def client(sock, addr): sock.start_tls(client_context) sock.sendall(HELLO_MSG) - - sock.shutdown(socket.SHUT_RDWR) + answer = sock.recv_all(len(ANSWER)) sock.close() class ServerProto(asyncio.Protocol): - def __init__(self, on_con, on_eof, on_con_lost): + def __init__(self, on_con, on_con_lost): self.on_con = on_con - self.on_eof = on_eof self.on_con_lost = on_con_lost self.data = b'' + self.transport = None def connection_made(self, tr): + self.transport = tr self.on_con.set_result(tr) + def replace_transport(self, tr): + self.transport = tr + def data_received(self, data): self.data += data - - def eof_received(self): - self.on_eof.set_result(1) + if len(self.data) >= len(HELLO_MSG): + self.transport.write(ANSWER) def connection_lost(self, exc): + self.transport = None if exc is None: self.on_con_lost.set_result(None) else: self.on_con_lost.set_exception(exc) - async def main(proto, on_con, on_eof, on_con_lost): + async def main(proto, on_con, on_con_lost): tr = await on_con tr.write(HELLO_MSG) @@ -550,16 +550,16 @@ async def main(proto, on_con, on_eof, on_con_lost): server_side=True, ssl_handshake_timeout=self.TIMEOUT) - await on_eof + proto.replace_transport(new_tr) + await on_con_lost self.assertEqual(proto.data, HELLO_MSG) new_tr.close() async def run_main(): on_con = self.loop.create_future() - on_eof = self.loop.create_future() on_con_lost = self.loop.create_future() - proto = ServerProto(on_con, on_eof, on_con_lost) + proto = ServerProto(on_con, on_con_lost) server = await self.loop.create_server( lambda: proto, '127.0.0.1', 0) @@ -568,11 +568,12 @@ async def run_main(): with self.tcp_client(lambda sock: client(sock, addr), timeout=self.TIMEOUT): await asyncio.wait_for( - main(proto, on_con, on_eof, on_con_lost), + main(proto, on_con, on_con_lost), timeout=self.TIMEOUT) server.close() await server.wait_closed() + self.assertEqual(answer, ANSWER) self.loop.run_until_complete(run_main()) diff --git a/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst b/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst new file mode 100644 index 00000000000000..23b6d00f42c5bf --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-06-14-17-05-49.bpo-35998.yX82oD.rst @@ -0,0 +1 @@ +Avoid TimeoutError in test_asyncio: test_start_tls_server_1() From 21a92f8cda525d25a165b773fbe1bfffd303a000 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 14 Jun 2019 08:29:20 -0700 Subject: [PATCH 412/441] Implement Windows release builds in Azure Pipelines (GH-14065) --- .azure-pipelines/windows-release.yml | 96 +++++++++++ .../windows-release/build-steps.yml | 83 +++++++++ .azure-pipelines/windows-release/checkout.yml | 21 +++ .azure-pipelines/windows-release/find-sdk.yml | 17 ++ .../windows-release/layout-command.yml | 20 +++ .../windows-release/mingw-lib.yml | 13 ++ .../windows-release/msi-steps.yml | 142 ++++++++++++++++ .../windows-release/stage-build.yml | 157 ++++++++++++++++++ .../windows-release/stage-layout-embed.yml | 56 +++++++ .../windows-release/stage-layout-full.yml | 62 +++++++ .../windows-release/stage-layout-msix.yml | 86 ++++++++++ .../windows-release/stage-layout-nuget.yml | 44 +++++ .../windows-release/stage-msi.yml | 36 ++++ .../windows-release/stage-pack-msix.yml | 127 ++++++++++++++ .../windows-release/stage-pack-nuget.yml | 41 +++++ .../stage-publish-nugetorg.yml | 28 ++++ .../stage-publish-pythonorg.yml | 34 ++++ .../windows-release/stage-publish-store.yml | 22 +++ .../windows-release/stage-sign.yml | 113 +++++++++++++ .../windows-release/stage-test-embed.yml | 40 +++++ .../windows-release/stage-test-msi.yml | 108 ++++++++++++ .../windows-release/stage-test-nuget.yml | 58 +++++++ Doc/make.bat | 2 +- {Tools/msi/exe => PC}/crtlicense.txt | 0 PC/layout/main.py | 71 ++++---- PC/layout/support/appxmanifest.py | 62 +++---- PC/layout/support/nuspec.py | 66 ++++++++ PC/layout/support/options.py | 9 +- PC/layout/support/pip.py | 26 ++- PC/layout/support/props.py | 20 +-- PC/python_uwp.cpp | 4 +- PCbuild/_tkinter.vcxproj | 2 +- PCbuild/build.bat | 19 ++- PCbuild/pyproject.props | 18 +- PCbuild/python.props | 4 +- PCbuild/python.vcxproj | 21 ++- PCbuild/tcltk.props | 21 ++- Tools/msi/buildrelease.bat | 2 +- Tools/msi/exe/exe.wixproj | 19 --- Tools/msi/exe/exe_files.wxs | 2 +- Tools/msi/make_cat.ps1 | 8 + Tools/msi/msi.props | 3 +- Tools/msi/msi.targets | 10 +- Tools/msi/sign_build.ps1 | 2 +- Tools/msi/tcltk/tcltk.wixproj | 6 +- Tools/msi/uploadrelease.ps1 | 56 +++++-- 46 files changed, 1691 insertions(+), 166 deletions(-) create mode 100644 .azure-pipelines/windows-release.yml create mode 100644 .azure-pipelines/windows-release/build-steps.yml create mode 100644 .azure-pipelines/windows-release/checkout.yml create mode 100644 .azure-pipelines/windows-release/find-sdk.yml create mode 100644 .azure-pipelines/windows-release/layout-command.yml create mode 100644 .azure-pipelines/windows-release/mingw-lib.yml create mode 100644 .azure-pipelines/windows-release/msi-steps.yml create mode 100644 .azure-pipelines/windows-release/stage-build.yml create mode 100644 .azure-pipelines/windows-release/stage-layout-embed.yml create mode 100644 .azure-pipelines/windows-release/stage-layout-full.yml create mode 100644 .azure-pipelines/windows-release/stage-layout-msix.yml create mode 100644 .azure-pipelines/windows-release/stage-layout-nuget.yml create mode 100644 .azure-pipelines/windows-release/stage-msi.yml create mode 100644 .azure-pipelines/windows-release/stage-pack-msix.yml create mode 100644 .azure-pipelines/windows-release/stage-pack-nuget.yml create mode 100644 .azure-pipelines/windows-release/stage-publish-nugetorg.yml create mode 100644 .azure-pipelines/windows-release/stage-publish-pythonorg.yml create mode 100644 .azure-pipelines/windows-release/stage-publish-store.yml create mode 100644 .azure-pipelines/windows-release/stage-sign.yml create mode 100644 .azure-pipelines/windows-release/stage-test-embed.yml create mode 100644 .azure-pipelines/windows-release/stage-test-msi.yml create mode 100644 .azure-pipelines/windows-release/stage-test-nuget.yml rename {Tools/msi/exe => PC}/crtlicense.txt (100%) create mode 100644 PC/layout/support/nuspec.py diff --git a/.azure-pipelines/windows-release.yml b/.azure-pipelines/windows-release.yml new file mode 100644 index 00000000000000..774585792484dd --- /dev/null +++ b/.azure-pipelines/windows-release.yml @@ -0,0 +1,96 @@ +name: Release_$(Build.SourceBranchName)_$(SourceTag)_$(Date:yyyyMMdd)$(Rev:.rr) + +# QUEUE TIME VARIABLES +# variables: +# GitRemote: python +# SourceTag: +# DoPGO: true +# SigningCertificate: 'Python Software Foundation' +# SigningDescription: 'Built: $(Build.BuildNumber)' +# DoLayout: true +# DoMSIX: true +# DoNuget: true +# DoEmbed: true +# DoMSI: true +# DoPublish: false + +trigger: none +pr: none + +stages: +- stage: Build + displayName: Build binaries + jobs: + - template: windows-release/stage-build.yml + +- stage: Sign + displayName: Sign binaries + dependsOn: Build + jobs: + - template: windows-release/stage-sign.yml + +- stage: Layout + displayName: Generate layouts + dependsOn: Sign + jobs: + - template: windows-release/stage-layout-full.yml + - template: windows-release/stage-layout-embed.yml + - template: windows-release/stage-layout-nuget.yml + +- stage: Pack + dependsOn: Layout + jobs: + - template: windows-release/stage-pack-nuget.yml + +- stage: Test + dependsOn: Pack + jobs: + - template: windows-release/stage-test-embed.yml + - template: windows-release/stage-test-nuget.yml + +- stage: Layout_MSIX + displayName: Generate MSIX layouts + dependsOn: Sign + condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) + jobs: + - template: windows-release/stage-layout-msix.yml + +- stage: Pack_MSIX + displayName: Package MSIX + dependsOn: Layout_MSIX + jobs: + - template: windows-release/stage-pack-msix.yml + +- stage: Build_MSI + displayName: Build MSI installer + dependsOn: Sign + condition: and(succeeded(), eq(variables['DoMSI'], 'true')) + jobs: + - template: windows-release/stage-msi.yml + +- stage: Test_MSI + displayName: Test MSI installer + dependsOn: Build_MSI + jobs: + - template: windows-release/stage-test-msi.yml + +- stage: PublishPyDotOrg + displayName: Publish to python.org + dependsOn: ['Test_MSI', 'Test'] + condition: and(succeeded(), eq(variables['DoPublish'], 'true')) + jobs: + - template: windows-release/stage-publish-pythonorg.yml + +- stage: PublishNuget + displayName: Publish to nuget.org + dependsOn: Test + condition: and(succeeded(), eq(variables['DoPublish'], 'true')) + jobs: + - template: windows-release/stage-publish-nugetorg.yml + +- stage: PublishStore + displayName: Publish to Store + dependsOn: Pack_MSIX + condition: and(succeeded(), eq(variables['DoPublish'], 'true')) + jobs: + - template: windows-release/stage-publish-store.yml diff --git a/.azure-pipelines/windows-release/build-steps.yml b/.azure-pipelines/windows-release/build-steps.yml new file mode 100644 index 00000000000000..508d73b0865fee --- /dev/null +++ b/.azure-pipelines/windows-release/build-steps.yml @@ -0,0 +1,83 @@ +parameters: + ShouldPGO: false + +steps: +- template: ./checkout.yml + +- powershell: | + $d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }}; + Write-Host "##vso[task.setvariable variable=VersionText]$($d.PythonVersion)" + Write-Host "##vso[task.setvariable variable=VersionNumber]$($d.PythonVersionNumber)" + Write-Host "##vso[task.setvariable variable=VersionHex]$($d.PythonVersionHex)" + Write-Host "##vso[task.setvariable variable=VersionUnique]$($d.PythonVersionUnique)" + Write-Host "##vso[build.addbuildtag]$($d.PythonVersion)" + Write-Host "##vso[build.addbuildtag]$($d.PythonVersion)-$(Name)" + displayName: 'Extract version numbers' + +- ${{ if eq(parameters.ShouldPGO, 'false') }}: + - powershell: | + $env:SigningCertificate = $null + .\PCbuild\build.bat -v -p $(Platform) -c $(Configuration) + displayName: 'Run build' + env: + IncludeUwp: true + Py_OutDir: '$(Build.BinariesDirectory)\bin' + +- ${{ if eq(parameters.ShouldPGO, 'true') }}: + - powershell: | + $env:SigningCertificate = $null + .\PCbuild\build.bat -v -p $(Platform) --pgo + displayName: 'Run build with PGO' + env: + IncludeUwp: true + Py_OutDir: '$(Build.BinariesDirectory)\bin' + +- powershell: | + $kitroot = (gp 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\').KitsRoot10 + $tool = (gci -r "$kitroot\Bin\*\x64\signtool.exe" | sort FullName -Desc | select -First 1) + if (-not $tool) { + throw "SDK is not available" + } + Write-Host "##vso[task.prependpath]$($tool.Directory)" + displayName: 'Add WinSDK tools to path' + +- powershell: | + $env:SigningCertificate = $null + .\python.bat PC\layout -vv -t "$(Build.BinariesDirectory)\catalog" --catalog "${env:CAT}.cdf" --preset-default + makecat "${env:CAT}.cdf" + del "${env:CAT}.cdf" + if (-not (Test-Path "${env:CAT}.cat")) { + throw "Failed to build catalog file" + } + displayName: 'Generate catalog' + env: + CAT: $(Build.BinariesDirectory)\bin\$(Arch)\python + +- task: PublishBuildArtifacts@1 + displayName: 'Publish binaries' + condition: and(succeeded(), not(and(eq(variables['Configuration'], 'Release'), variables['SigningCertificate']))) + inputs: + PathtoPublish: '$(Build.BinariesDirectory)\bin\$(Arch)' + ArtifactName: bin_$(Name) + +- task: PublishBuildArtifacts@1 + displayName: 'Publish binaries for signing' + condition: and(succeeded(), and(eq(variables['Configuration'], 'Release'), variables['SigningCertificate'])) + inputs: + PathtoPublish: '$(Build.BinariesDirectory)\bin\$(Arch)' + ArtifactName: unsigned_bin_$(Name) + +- task: CopyFiles@2 + displayName: 'Layout Artifact: symbols' + inputs: + sourceFolder: $(Build.BinariesDirectory)\bin\$(Arch) + targetFolder: $(Build.ArtifactStagingDirectory)\symbols\$(Name) + flatten: true + contents: | + **\*.pdb + +- task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: symbols' + inputs: + PathToPublish: '$(Build.ArtifactStagingDirectory)\symbols' + ArtifactName: symbols diff --git a/.azure-pipelines/windows-release/checkout.yml b/.azure-pipelines/windows-release/checkout.yml new file mode 100644 index 00000000000000..d42d55fff08dda --- /dev/null +++ b/.azure-pipelines/windows-release/checkout.yml @@ -0,0 +1,21 @@ +parameters: + depth: 3 + +steps: +- checkout: none + +- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(SourceTag) --single-branch https://github.com/$(GitRemote)/cpython.git . + displayName: 'git clone ($(GitRemote)/$(SourceTag))' + condition: and(succeeded(), and(variables['GitRemote'], variables['SourceTag'])) + +- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(SourceTag) --single-branch $(Build.Repository.Uri) . + displayName: 'git clone (/$(SourceTag))' + condition: and(succeeded(), and(not(variables['GitRemote']), variables['SourceTag'])) + +- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(Build.SourceBranchName) --single-branch https://github.com/$(GitRemote)/cpython.git . + displayName: 'git clone ($(GitRemote)/)' + condition: and(succeeded(), and(variables['GitRemote'], not(variables['SourceTag']))) + +- script: git clone --progress -v --depth ${{ parameters.depth }} --branch $(Build.SourceBranchName) --single-branch $(Build.Repository.Uri) . + displayName: 'git clone' + condition: and(succeeded(), and(not(variables['GitRemote']), not(variables['SourceTag']))) diff --git a/.azure-pipelines/windows-release/find-sdk.yml b/.azure-pipelines/windows-release/find-sdk.yml new file mode 100644 index 00000000000000..e4de78555b3f66 --- /dev/null +++ b/.azure-pipelines/windows-release/find-sdk.yml @@ -0,0 +1,17 @@ +# Locate the Windows SDK and add its binaries directory to PATH +# +# `toolname` can be overridden to use a different marker file. + +parameters: + toolname: signtool.exe + +steps: + - powershell: | + $kitroot = (gp 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots\').KitsRoot10 + $tool = (gci -r "$kitroot\Bin\*\${{ parameters.toolname }}" | sort FullName -Desc | select -First 1) + if (-not $tool) { + throw "SDK is not available" + } + Write-Host "##vso[task.prependpath]$($tool.Directory)" + Write-Host "Adding $($tool.Directory) to PATH" + displayName: 'Add WinSDK tools to path' diff --git a/.azure-pipelines/windows-release/layout-command.yml b/.azure-pipelines/windows-release/layout-command.yml new file mode 100644 index 00000000000000..3ec9b69ad7121c --- /dev/null +++ b/.azure-pipelines/windows-release/layout-command.yml @@ -0,0 +1,20 @@ +steps: +- powershell: > + Write-Host ( + '##vso[task.setvariable variable=LayoutCmd]& + "{0}" + "{1}\PC\layout" + -vv + --source "{1}" + --build "{2}" + --temp "{3}" + --include-cat "{2}\python.cat" + --doc-build "{4}"' + -f ( + "$(PYTHON)", + "$(Build.SourcesDirectory)", + (Split-Path -Parent "$(PYTHON)"), + "$(Build.BinariesDirectory)\layout-temp", + "$(Build.BinariesDirectory)\doc" + )) + displayName: 'Set LayoutCmd' diff --git a/.azure-pipelines/windows-release/mingw-lib.yml b/.azure-pipelines/windows-release/mingw-lib.yml new file mode 100644 index 00000000000000..30f7d34fa61d23 --- /dev/null +++ b/.azure-pipelines/windows-release/mingw-lib.yml @@ -0,0 +1,13 @@ +parameters: + DllToolOpt: -m i386:x86-64 + #DllToolOpt: -m i386 --as-flags=--32 + +steps: +- powershell: | + git clone https://github.com/python/cpython-bin-deps --branch binutils --single-branch --depth 1 --progress -v "binutils" + gci "bin\$(Arch)\python*.dll" | %{ + & "binutils\gendef.exe" $_ | Out-File -Encoding ascii tmp.def + & "binutils\dlltool.exe" --dllname $($_.BaseName).dll --def tmp.def --output-lib "$($_.Directory)\lib$($_.BaseName).a" ${{ parameters.DllToolOpt }} + } + displayName: 'Generate MinGW import library' + workingDirectory: $(Build.BinariesDirectory) diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml new file mode 100644 index 00000000000000..2f80c34eeb7d79 --- /dev/null +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -0,0 +1,142 @@ +steps: + - template: ./checkout.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: doc' + inputs: + artifactName: doc + downloadPath: $(Build.BinariesDirectory) + + - task: CopyFiles@2 + displayName: 'Merge documentation files' + inputs: + sourceFolder: $(Build.BinariesDirectory)\doc + targetFolder: $(Build.SourcesDirectory)\Doc\build + contents: | + htmlhelp\*.chm + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_win32' + inputs: + artifactName: bin_win32 + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_win32_d' + inputs: + artifactName: bin_win32_d + downloadPath: $(Build.BinariesDirectory) + + - task: CopyFiles@2 + displayName: 'Merge win32 debug files' + inputs: + sourceFolder: $(Build.BinariesDirectory)\bin_win32_d + targetFolder: $(Build.BinariesDirectory)\bin_win32 + contents: | + **\*_d.* + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_amd64' + inputs: + artifactName: bin_amd64 + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_amd64_d' + inputs: + artifactName: bin_amd64_d + downloadPath: $(Build.BinariesDirectory) + + - task: CopyFiles@2 + displayName: 'Merge amd64 debug files' + inputs: + sourceFolder: $(Build.BinariesDirectory)\bin_amd64_d + targetFolder: $(Build.BinariesDirectory)\bin_amd64 + contents: | + **\*_d.* + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: tcltk_lib_win32' + inputs: + artifactName: tcltk_lib_win32 + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: tcltk_lib_amd64' + inputs: + artifactName: tcltk_lib_amd64 + downloadPath: $(Build.BinariesDirectory) + + - script: | + ren bin_win32 win32 + ren bin_amd64 amd64 + displayName: 'Correct artifact directory names' + workingDirectory: $(Build.BinariesDirectory) + + - script: | + call Tools\msi\get_externals.bat + call PCbuild\find_python.bat + echo ##vso[task.setvariable variable=PYTHON]%PYTHON% + call PCbuild/find_msbuild.bat + echo ##vso[task.setvariable variable=MSBUILD]%MSBUILD% + displayName: 'Get external dependencies' + + - script: | + %PYTHON% -m pip install blurb + %PYTHON% -m blurb merge -f Misc\NEWS + displayName: 'Merge NEWS file' + + - script: | + %MSBUILD% Tools\msi\launcher\launcher.wixproj + displayName: 'Build launcher installer' + env: + Platform: x86 + Py_OutDir: $(Build.BinariesDirectory) + + - script: | + %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true /p:BuildForRelease=true + %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false /p:BuildForRelease=true + displayName: 'Build win32 installer' + env: + Platform: x86 + Py_OutDir: $(Build.BinariesDirectory) + PYTHON: $(Build.BinariesDirectory)\win32\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_win32 + + - script: | + %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true /p:BuildForRelease=true + %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false /p:BuildForRelease=true + displayName: 'Build amd64 installer' + env: + Platform: x64 + Py_OutDir: $(Build.BinariesDirectory) + PYTHON: $(Build.BinariesDirectory)\amd64\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_amd64 + + - task: CopyFiles@2 + displayName: 'Assemble artifact: msi (1/2)' + inputs: + sourceFolder: $(Build.BinariesDirectory)\win32\en-us + targetFolder: $(Build.ArtifactStagingDirectory)\msi\win32 + contents: | + *.msi + *.cab + *.exe + + - task: CopyFiles@2 + displayName: 'Assemble artifact: msi (2/2)' + inputs: + sourceFolder: $(Build.BinariesDirectory)\amd64\en-us + targetFolder: $(Build.ArtifactStagingDirectory)\msi\amd64 + contents: | + *.msi + *.cab + *.exe + + - task: PublishBuildArtifacts@1 + displayName: 'Publish MSI' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\msi' + ArtifactName: msi diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml new file mode 100644 index 00000000000000..121e4b1a278e0d --- /dev/null +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -0,0 +1,157 @@ +jobs: +- job: Build_Docs + displayName: Docs build + pool: + name: 'Windows Release' + #vmName: win2016-vs2017 + + workspace: + clean: all + + steps: + - template: ./checkout.yml + + - script: Doc\make.bat html + displayName: 'Build HTML docs' + env: + BUILDDIR: $(Build.BinariesDirectory)\Doc + + #- powershell: iwr "https://www.python.org/ftp/python/3.7.3/python373.chm" -OutFile "$(Build.BinariesDirectory)\python390a0.chm" + # displayName: 'Cheat at building CHM docs' + + - script: Doc\make.bat htmlhelp + displayName: 'Build CHM docs' + env: + BUILDDIR: $(Build.BinariesDirectory)\Doc + + - task: CopyFiles@2 + displayName: 'Assemble artifact: Doc' + inputs: + sourceFolder: $(Build.BinariesDirectory)\Doc + targetFolder: $(Build.ArtifactStagingDirectory)\Doc + contents: | + html\**\* + htmlhelp\*.chm + + - task: PublishBuildArtifacts@1 + displayName: 'Publish artifact: doc' + inputs: + PathtoPublish: $(Build.ArtifactStagingDirectory)\Doc + ArtifactName: doc + +- job: Build_Python + displayName: Python build + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + Arch: win32 + Platform: x86 + Configuration: Release + win32_d: + Name: win32_d + Arch: win32 + Platform: x86 + Configuration: Debug + amd64_d: + Name: amd64_d + Arch: amd64 + Platform: x64 + Configuration: Debug + + steps: + - template: ./build-steps.yml + +- job: Build_Python_NonPGO + displayName: Python non-PGO build + condition: and(succeeded(), ne(variables['DoPGO'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + amd64: + Name: amd64 + Arch: amd64 + Platform: x64 + Configuration: Release + + steps: + - template: ./build-steps.yml + + +- job: Build_Python_PGO + displayName: Python PGO build + condition: and(succeeded(), eq(variables['DoPGO'], 'true')) + + pool: + name: 'Windows Release' + + workspace: + clean: all + + strategy: + matrix: + amd64: + Name: amd64 + Arch: amd64 + Platform: x64 + Configuration: Release + + steps: + - template: ./build-steps.yml + parameters: + ShouldPGO: true + + +- job: TclTk_Lib + displayName: Publish Tcl/Tk Library + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + steps: + - template: ./checkout.yml + + - script: PCbuild\get_externals.bat --no-openssl --no-libffi + displayName: 'Get external dependencies' + + - task: MSBuild@1 + displayName: 'Copy Tcl/Tk lib for publish' + inputs: + solution: PCbuild\tcltk.props + platform: x86 + msbuildArguments: /t:CopyTclTkLib /p:OutDir="$(Build.ArtifactStagingDirectory)\tcl_win32" + + - task: MSBuild@1 + displayName: 'Copy Tcl/Tk lib for publish' + inputs: + solution: PCbuild\tcltk.props + platform: x64 + msbuildArguments: /t:CopyTclTkLib /p:OutDir="$(Build.ArtifactStagingDirectory)\tcl_amd64" + + - task: PublishBuildArtifacts@1 + displayName: 'Publish artifact: tcltk_lib_win32' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\tcl_win32' + ArtifactName: tcltk_lib_win32 + + - task: PublishBuildArtifacts@1 + displayName: 'Publish artifact: tcltk_lib_amd64' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\tcl_amd64' + ArtifactName: tcltk_lib_amd64 diff --git a/.azure-pipelines/windows-release/stage-layout-embed.yml b/.azure-pipelines/windows-release/stage-layout-embed.yml new file mode 100644 index 00000000000000..c9d58b6b30a28e --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-embed.yml @@ -0,0 +1,56 @@ +jobs: +- job: Make_Embed_Layout + displayName: Make embeddable layout + condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + amd64: + Name: amd64 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + + steps: + - template: ./checkout.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_$(Name)' + inputs: + artifactName: bin_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - template: ./layout-command.yml + + - powershell: | + $d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }}; + Write-Host "##vso[task.setvariable variable=VersionText]$($d.PythonVersion)" + displayName: 'Extract version numbers' + + - powershell: > + $(LayoutCmd) + --copy "$(Build.ArtifactStagingDirectory)\layout" + --zip "$(Build.ArtifactStagingDirectory)\embed\$(VersionText)-embed-$(Name).zip" + --preset-embed + displayName: 'Generate embeddable layout' + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: layout_embed_$(Name)' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\layout' + ArtifactName: layout_embed_$(Name) + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: embed' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\embed' + ArtifactName: embed diff --git a/.azure-pipelines/windows-release/stage-layout-full.yml b/.azure-pipelines/windows-release/stage-layout-full.yml new file mode 100644 index 00000000000000..3593cf0a3f6943 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-full.yml @@ -0,0 +1,62 @@ +jobs: +- job: Make_Layouts + displayName: Make layouts + condition: and(succeeded(), eq(variables['DoLayout'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + amd64: + Name: amd64 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + + steps: + - template: ./checkout.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_$(Name)' + inputs: + artifactName: bin_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_$(Name)_d' + inputs: + artifactName: bin_$(Name)_d + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: doc' + inputs: + artifactName: doc + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: tcltk_lib_$(Name)' + inputs: + artifactName: tcltk_lib_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - template: ./layout-command.yml + + - powershell: | + $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\layout" --preset-default + displayName: 'Generate full layout' + env: + TCL_LIBRARY: $(Build.BinariesDirectory)\tcltk_lib_$(Name)\tcl8 + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: layout_full_$(Name)' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\layout' + ArtifactName: layout_full_$(Name) diff --git a/.azure-pipelines/windows-release/stage-layout-msix.yml b/.azure-pipelines/windows-release/stage-layout-msix.yml new file mode 100644 index 00000000000000..1a1e0a2fd68510 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-msix.yml @@ -0,0 +1,86 @@ +jobs: +- job: Make_MSIX_Layout + displayName: Make MSIX layout + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + #win32: + # Name: win32 + # Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + # PYTHONHOME: $(Build.SourcesDirectory) + amd64: + Name: amd64 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + + steps: + - template: ./checkout.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_$(Name)' + inputs: + artifactName: bin_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_$(Name)_d' + inputs: + artifactName: bin_$(Name)_d + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: tcltk_lib_$(Name)' + inputs: + artifactName: tcltk_lib_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - template: ./layout-command.yml + + - powershell: | + Remove-Item "$(Build.ArtifactStagingDirectory)\appx-store" -Recurse -Force -EA 0 + $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\appx-store" --preset-appx --precompile + displayName: 'Generate store APPX layout' + env: + TCL_LIBRARY: $(Build.BinariesDirectory)\tcltk_lib_$(Name)\tcl8 + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: layout_appxstore_$(Name)' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\appx-store' + ArtifactName: layout_appxstore_$(Name) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: cert' + condition: and(succeeded(), variables['SigningCertificate']) + inputs: + artifactName: cert + downloadPath: $(Build.BinariesDirectory) + + - powershell: | + $info = (gc "$(Build.BinariesDirectory)\cert\certinfo.json" | ConvertFrom-JSON) + Write-Host "Side-loadable APPX must be signed with '$($info.Subject)'" + Write-Host "##vso[task.setvariable variable=APPX_DATA_PUBLISHER]$($info.Subject)" + Write-Host "##vso[task.setvariable variable=APPX_DATA_SHA256]$($info.SHA256)" + displayName: 'Override signing parameters' + condition: and(succeeded(), variables['SigningCertificate']) + + - powershell: | + Remove-Item "$(Build.ArtifactStagingDirectory)\appx" -Recurse -Force -EA 0 + $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\appx" --preset-appx --precompile --include-symbols --include-tests + displayName: 'Generate sideloading APPX layout' + env: + TCL_LIBRARY: $(Build.BinariesDirectory)\tcltk_lib_$(Name)\tcl8 + APPX_DATA_PUBLISHER: $(APPX_DATA_PUBLISHER) + APPX_DATA_SHA256: $(APPX_DATA_SHA256) + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: layout_appx_$(Name)' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\appx' + ArtifactName: layout_appx_$(Name) diff --git a/.azure-pipelines/windows-release/stage-layout-nuget.yml b/.azure-pipelines/windows-release/stage-layout-nuget.yml new file mode 100644 index 00000000000000..ca4213d9e5c2e8 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-layout-nuget.yml @@ -0,0 +1,44 @@ +jobs: +- job: Make_Nuget_Layout + displayName: Make Nuget layout + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + amd64: + Name: amd64 + Python: $(Build.BinariesDirectory)\bin_$(Name)\python.exe + PYTHONHOME: $(Build.SourcesDirectory) + + steps: + - template: ./checkout.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: bin_$(Name)' + inputs: + artifactName: bin_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - template: ./layout-command.yml + + - powershell: | + $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\nuget" --preset-nuget + displayName: 'Generate nuget layout' + env: + TCL_LIBRARY: $(Build.BinariesDirectory)\bin_$(Name)\tcl\tcl8 + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: layout_nuget_$(Name)' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\nuget' + ArtifactName: layout_nuget_$(Name) diff --git a/.azure-pipelines/windows-release/stage-msi.yml b/.azure-pipelines/windows-release/stage-msi.yml new file mode 100644 index 00000000000000..7afc816a0c6e9c --- /dev/null +++ b/.azure-pipelines/windows-release/stage-msi.yml @@ -0,0 +1,36 @@ +jobs: +- job: Make_MSI + displayName: Make MSI + condition: and(succeeded(), not(variables['SigningCertificate'])) + + pool: + vmName: win2016-vs2017 + + variables: + ReleaseUri: http://www.python.org/{arch} + DownloadUrl: https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi} + Py_OutDir: $(Build.BinariesDirectory) + + workspace: + clean: all + + steps: + - template: msi-steps.yml + +- job: Make_Signed_MSI + displayName: Make signed MSI + condition: and(succeeded(), variables['SigningCertificate']) + + pool: + name: 'Windows Release' + + variables: + ReleaseUri: http://www.python.org/{arch} + DownloadUrl: https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi} + Py_OutDir: $(Build.BinariesDirectory) + + workspace: + clean: all + + steps: + - template: msi-steps.yml diff --git a/.azure-pipelines/windows-release/stage-pack-msix.yml b/.azure-pipelines/windows-release/stage-pack-msix.yml new file mode 100644 index 00000000000000..6f1846e581ef13 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-pack-msix.yml @@ -0,0 +1,127 @@ +jobs: +- job: Pack_MSIX + displayName: Pack MSIX bundles + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + amd64: + Name: amd64 + Artifact: appx + Suffix: + ShouldSign: true + amd64_store: + Name: amd64 + Artifact: appxstore + Suffix: -store + Upload: true + + steps: + - template: ./checkout.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: layout_$(Artifact)_$(Name)' + inputs: + artifactName: layout_$(Artifact)_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: symbols' + inputs: + artifactName: symbols + downloadPath: $(Build.BinariesDirectory) + + - powershell: | + $d = (.\PCbuild\build.bat -V) | %{ if($_ -match '\s+(\w+):\s*(.+)\s*$') { @{$Matches[1] = $Matches[2];} }}; + Write-Host "##vso[task.setvariable variable=VersionText]$($d.PythonVersion)" + Write-Host "##vso[task.setvariable variable=VersionNumber]$($d.PythonVersionNumber)" + Write-Host "##vso[task.setvariable variable=VersionHex]$($d.PythonVersionHex)" + Write-Host "##vso[task.setvariable variable=VersionUnique]$($d.PythonVersionUnique)" + Write-Host "##vso[task.setvariable variable=Filename]python-$($d.PythonVersion)-$(Name)$(Suffix)" + displayName: 'Extract version numbers' + + - powershell: | + ./Tools/msi/make_appx.ps1 -layout "$(Build.BinariesDirectory)\layout_$(Artifact)_$(Name)" -msix "$(Build.ArtifactStagingDirectory)\msix\$(Filename).msix" + displayName: 'Build msix' + + - powershell: | + 7z a -tzip "$(Build.ArtifactStagingDirectory)\msix\$(Filename).appxsym" *.pdb + displayName: 'Build appxsym' + workingDirectory: $(Build.BinariesDirectory)\symbols\$(Name) + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: MSIX' + condition: and(succeeded(), or(ne(variables['ShouldSign'], 'true'), not(variables['SigningCertificate']))) + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\msix' + ArtifactName: msix + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: MSIX' + condition: and(succeeded(), and(eq(variables['ShouldSign'], 'true'), variables['SigningCertificate'])) + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\msix' + ArtifactName: unsigned_msix + + - powershell: | + 7z a -tzip "$(Build.ArtifactStagingDirectory)\msixupload\$(Filename).msixupload" * + displayName: 'Build msixupload' + condition: and(succeeded(), eq(variables['Upload'], 'true')) + workingDirectory: $(Build.ArtifactStagingDirectory)\msix + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: MSIXUpload' + condition: and(succeeded(), eq(variables['Upload'], 'true')) + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\msixupload' + ArtifactName: msixupload + + +- job: Sign_MSIX + displayName: Sign side-loadable MSIX bundles + dependsOn: + - Pack_MSIX + condition: and(succeeded(), variables['SigningCertificate']) + + pool: + name: 'Windows Release' + + workspace: + clean: all + + steps: + - checkout: none + - template: ./find-sdk.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download Artifact: unsigned_msix' + inputs: + artifactName: unsigned_msix + downloadPath: $(Build.BinariesDirectory) + + - powershell: | + $failed = $true + foreach ($retry in 1..3) { + signtool sign /a /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "$(SigningDescription)" (gi *.msix) + if ($?) { + $failed = $false + break + } + sleep 1 + } + if ($failed) { + throw "Failed to sign MSIX" + } + displayName: 'Sign MSIX' + workingDirectory: $(Build.BinariesDirectory)\unsigned_msix + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: MSIX' + inputs: + PathtoPublish: '$(Build.BinariesDirectory)\unsigned_msix' + ArtifactName: msix diff --git a/.azure-pipelines/windows-release/stage-pack-nuget.yml b/.azure-pipelines/windows-release/stage-pack-nuget.yml new file mode 100644 index 00000000000000..5aa394fa48a1c7 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-pack-nuget.yml @@ -0,0 +1,41 @@ +jobs: +- job: Pack_Nuget + displayName: Pack Nuget bundles + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + amd64: + Name: amd64 + win32: + Name: win32 + + steps: + - checkout: none + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: layout_nuget_$(Name)' + inputs: + artifactName: layout_nuget_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - task: NugetToolInstaller@0 + displayName: 'Install Nuget' + inputs: + versionSpec: '>=5.0' + + - powershell: | + nuget pack "$(Build.BinariesDirectory)\layout_nuget_$(Name)\python.nuspec" -OutputDirectory $(Build.ArtifactStagingDirectory) -NoPackageAnalysis -NonInteractive + displayName: 'Create nuget package' + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: nuget' + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)' + ArtifactName: nuget diff --git a/.azure-pipelines/windows-release/stage-publish-nugetorg.yml b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml new file mode 100644 index 00000000000000..7586d850f34095 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-publish-nugetorg.yml @@ -0,0 +1,28 @@ +jobs: +- job: Publish_Nuget + displayName: Publish Nuget packages + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + steps: + - checkout: none + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: nuget' + inputs: + artifactName: nuget + downloadPath: $(Build.BinariesDirectory) + + - task: NuGetCommand@2 + displayName: Push packages + condition: and(succeeded(), eq(variables['SigningCertificate'], 'Python Software Foundation')) + inputs: + command: push + packagesToPush: $(Build.BinariesDirectory)\nuget\*.nupkg' + nuGetFeedType: external + publishFeedCredentials: 'Python on Nuget' diff --git a/.azure-pipelines/windows-release/stage-publish-pythonorg.yml b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml new file mode 100644 index 00000000000000..2215a56d4bc256 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-publish-pythonorg.yml @@ -0,0 +1,34 @@ +jobs: +- job: Publish_Python + displayName: Publish python.org packages + condition: and(succeeded(), and(eq(variables['DoMSI'], 'true'), eq(variables['DoEmbed'], 'true'))) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + steps: + - checkout: none + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: Doc' + inputs: + artifactName: Doc + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: msi' + inputs: + artifactName: msi + downloadPath: $(Build.BinariesDirectory) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: embed' + inputs: + artifactName: embed + downloadPath: $(Build.BinariesDirectory) + + # TODO: eq(variables['SigningCertificate'], 'Python Software Foundation') + # If we are not real-signed, DO NOT PUBLISH diff --git a/.azure-pipelines/windows-release/stage-publish-store.yml b/.azure-pipelines/windows-release/stage-publish-store.yml new file mode 100644 index 00000000000000..06884c4f35b7b7 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-publish-store.yml @@ -0,0 +1,22 @@ +jobs: +- job: Publish_Store + displayName: Publish Store packages + condition: and(succeeded(), eq(variables['DoMSIX'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + steps: + - checkout: none + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: msixupload' + inputs: + artifactName: msixupload + downloadPath: $(Build.BinariesDirectory) + + # TODO: eq(variables['SigningCertificate'], 'Python Software Foundation') + # If we are not real-signed, DO NOT PUBLISH diff --git a/.azure-pipelines/windows-release/stage-sign.yml b/.azure-pipelines/windows-release/stage-sign.yml new file mode 100644 index 00000000000000..3d6ca9457f1c7f --- /dev/null +++ b/.azure-pipelines/windows-release/stage-sign.yml @@ -0,0 +1,113 @@ +jobs: +- job: Sign_Python + displayName: Sign Python binaries + condition: and(succeeded(), variables['SigningCertificate']) + + pool: + name: 'Windows Release' + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + amd64: + Name: amd64 + + steps: + - checkout: none + - template: ./find-sdk.yml + + - powershell: | + Write-Host "##vso[build.addbuildtag]signed" + displayName: 'Add build tags' + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: unsigned_bin_$(Name)' + inputs: + artifactName: unsigned_bin_$(Name) + downloadPath: $(Build.BinariesDirectory) + + - powershell: | + $files = (gi *.exe, *.dll, *.pyd, *.cat -Exclude vcruntime*, libffi*, libcrypto*, libssl*) + signtool sign /a /n "$(SigningCertificate)" /fd sha256 /d "$(SigningDescription)" $files + displayName: 'Sign binaries' + workingDirectory: $(Build.BinariesDirectory)\unsigned_bin_$(Name) + + - powershell: | + $files = (gi *.exe, *.dll, *.pyd, *.cat -Exclude vcruntime*, libffi*, libcrypto*, libssl*) + $failed = $true + foreach ($retry in 1..10) { + signtool timestamp /t http://timestamp.verisign.com/scripts/timestamp.dll $files + if ($?) { + $failed = $false + break + } + sleep 5 + } + if ($failed) { + Write-Host "##vso[task.logissue type=error]Failed to timestamp files" + } + displayName: 'Timestamp binaries' + workingDirectory: $(Build.BinariesDirectory)\unsigned_bin_$(Name) + continueOnError: true + + - task: PublishBuildArtifacts@1 + displayName: 'Publish artifact: bin_$(Name)' + inputs: + PathtoPublish: '$(Build.BinariesDirectory)\unsigned_bin_$(Name)' + ArtifactName: bin_$(Name) + + +- job: Dump_CertInfo + displayName: Capture certificate info + condition: and(succeeded(), variables['SigningCertificate']) + + pool: + name: 'Windows Release' + + steps: + - checkout: none + + - powershell: | + $m = 'CN=$(SigningCertificate)' + $c = ((gci Cert:\CurrentUser\My), (gci Cert:\LocalMachine\My)) | %{ $_ } | ` + ?{ $_.Subject -match $m } | ` + select -First 1 + if (-not $c) { + Write-Host "Failed to find certificate for $(SigningCertificate)" + exit + } + $d = mkdir "$(Build.BinariesDirectory)\tmp" -Force + $cf = "$d\cert.cer" + [IO.File]::WriteAllBytes($cf, $c.Export("Cer")) + $csha = (certutil -dump $cf | sls "Cert Hash\(sha256\): (.+)").Matches.Groups[1].Value + + $info = @{ Subject=$c.Subject; SHA256=$csha; } + + $d = mkdir "$(Build.BinariesDirectory)\cert" -Force + $info | ConvertTo-JSON -Compress | Out-File -Encoding utf8 "$d\certinfo.json" + displayName: "Extract certificate info" + + - task: PublishBuildArtifacts@1 + displayName: 'Publish artifact: cert' + inputs: + PathtoPublish: '$(Build.BinariesDirectory)\cert' + ArtifactName: cert + + +- job: Mark_Unsigned + displayName: Tag unsigned build + condition: and(succeeded(), not(variables['SigningCertificate'])) + + pool: + vmName: win2016-vs2017 + + steps: + - checkout: none + + - powershell: | + Write-Host "##vso[build.addbuildtag]unsigned" + displayName: 'Add build tag' diff --git a/.azure-pipelines/windows-release/stage-test-embed.yml b/.azure-pipelines/windows-release/stage-test-embed.yml new file mode 100644 index 00000000000000..ab377fdfa8c90a --- /dev/null +++ b/.azure-pipelines/windows-release/stage-test-embed.yml @@ -0,0 +1,40 @@ +jobs: +- job: Test_Embed + displayName: Test Embed + condition: and(succeeded(), eq(variables['DoEmbed'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Name: win32 + amd64: + Name: amd64 + + steps: + - checkout: none + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: embed' + inputs: + artifactName: embed + downloadPath: $(Build.BinariesDirectory) + + - powershell: | + Expand-Archive -Path "$(Build.BinariesDirectory)\embed\embed-$(Name).zip" -DestinationPath "$(Build.BinariesDirectory)\Python" + $p = gi "$(Build.BinariesDirectory)\Python\python.exe" + Write-Host "##vso[task.prependpath]$(Split-Path -Parent $p)" + displayName: 'Install Python and add to PATH' + + - script: | + python -c "import sys; print(sys.version)" + displayName: 'Collect version number' + + - script: | + python -m site + displayName: 'Collect site' diff --git a/.azure-pipelines/windows-release/stage-test-msi.yml b/.azure-pipelines/windows-release/stage-test-msi.yml new file mode 100644 index 00000000000000..10039295a18407 --- /dev/null +++ b/.azure-pipelines/windows-release/stage-test-msi.yml @@ -0,0 +1,108 @@ +jobs: +- job: Test_MSI + displayName: Test MSI + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32_User: + ExeMatch: 'python-[\dabrc.]+-webinstall\.exe' + Logs: $(Build.ArtifactStagingDirectory)\logs\win32_User + InstallAllUsers: 0 + win32_Machine: + ExeMatch: 'python-[\dabrc.]+-webinstall\.exe' + Logs: $(Build.ArtifactStagingDirectory)\logs\win32_Machine + InstallAllUsers: 1 + amd64_User: + ExeMatch: 'python-[\dabrc.]+-amd64-webinstall\.exe' + Logs: $(Build.ArtifactStagingDirectory)\logs\amd64_User + InstallAllUsers: 0 + amd64_Machine: + ExeMatch: 'python-[\dabrc.]+-amd64-webinstall\.exe' + Logs: $(Build.ArtifactStagingDirectory)\logs\amd64_Machine + InstallAllUsers: 1 + + steps: + - checkout: none + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: msi' + inputs: + artifactName: msi + downloadPath: $(Build.BinariesDirectory) + + - powershell: | + $p = (gci -r *.exe | ?{ $_.Name -match '$(ExeMatch)' } | select -First 1) + Write-Host "##vso[task.setvariable variable=SetupExe]$($p.FullName)" + Write-Host "##vso[task.setvariable variable=SetupExeName]$($p.Name)" + displayName: 'Find installer executable' + workingDirectory: $(Build.BinariesDirectory)\msi + + - script: > + "$(SetupExe)" + /passive + /log "$(Logs)\install\log.txt" + TargetDir="$(Build.BinariesDirectory)\Python" + Include_debug=1 + Include_symbols=1 + InstallAllUsers=$(InstallAllUsers) + displayName: 'Install Python' + + - powershell: | + $p = gi "$(Build.BinariesDirectory)\Python\python.exe" + Write-Host "##vso[task.prependpath]$(Split-Path -Parent $p)" + displayName: 'Add test Python to PATH' + + - script: | + python -c "import sys; print(sys.version)" + displayName: 'Collect version number' + + - script: | + python -m site + displayName: 'Collect site' + + - powershell: | + gci -r "${env:PROGRAMDATA}\Microsoft\Windows\Start Menu\Programs\Python*" + displayName: 'Capture per-machine Start Menu items' + - powershell: | + gci -r "${env:APPDATA}\Microsoft\Windows\Start Menu\Programs\Python*" + displayName: 'Capture per-user Start Menu items' + + - powershell: | + gci -r "HKLM:\Software\WOW6432Node\Python" + displayName: 'Capture per-machine 32-bit registry' + - powershell: | + gci -r "HKLM:\Software\Python" + displayName: 'Capture per-machine native registry' + - powershell: | + gci -r "HKCU:\Software\Python" + displayName: 'Capture current-user registry' + + - script: | + python -m pip install "azure<0.10" + python -m pip uninstall -y azure python-dateutil six + displayName: 'Test (un)install package' + + - script: | + python -m test -uall -v test_ttk_guionly test_tk test_idle + displayName: 'Test Tkinter and Idle' + + - script: > + "$(SetupExe)" + /passive + /uninstall + /log "$(Logs)\uninstall\log.txt" + displayName: 'Uninstall Python' + + - task: PublishBuildArtifacts@1 + displayName: 'Publish Artifact: logs' + condition: true + continueOnError: true + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)\logs' + ArtifactName: msi_testlogs diff --git a/.azure-pipelines/windows-release/stage-test-nuget.yml b/.azure-pipelines/windows-release/stage-test-nuget.yml new file mode 100644 index 00000000000000..1f8b601d0d023b --- /dev/null +++ b/.azure-pipelines/windows-release/stage-test-nuget.yml @@ -0,0 +1,58 @@ +jobs: +- job: Test_Nuget + displayName: Test Nuget + condition: and(succeeded(), eq(variables['DoNuget'], 'true')) + + pool: + vmName: win2016-vs2017 + + workspace: + clean: all + + strategy: + matrix: + win32: + Package: pythonx86 + amd64: + Package: python + + steps: + - checkout: none + + - task: DownloadBuildArtifacts@0 + displayName: 'Download artifact: nuget' + inputs: + artifactName: nuget + downloadPath: $(Build.BinariesDirectory) + + - task: NugetToolInstaller@0 + inputs: + versionSpec: '>= 5' + + - powershell: > + nuget install + $(Package) + -Source "$(Build.BinariesDirectory)\nuget" + -OutputDirectory "$(Build.BinariesDirectory)\install" + -Prerelease + -ExcludeVersion + -NonInteractive + displayName: 'Install Python' + + - powershell: | + $p = gi "$(Build.BinariesDirectory)\install\$(Package)\tools\python.exe" + Write-Host "##vso[task.prependpath]$(Split-Path -Parent $p)" + displayName: 'Add test Python to PATH' + + - script: | + python -c "import sys; print(sys.version)" + displayName: 'Collect version number' + + - script: | + python -m site + displayName: 'Collect site' + + - script: | + python -m pip install "azure<0.10" + python -m pip uninstall -y azure python-dateutil six + displayName: 'Test (un)install package' diff --git a/Doc/make.bat b/Doc/make.bat index e6604956ea916b..dfc622f66615df 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -117,13 +117,13 @@ if not exist "%BUILDDIR%" mkdir "%BUILDDIR%" rem PY_MISC_NEWS_DIR is also used by our Sphinx extension in tools/extensions/pyspecific.py if not defined PY_MISC_NEWS_DIR set PY_MISC_NEWS_DIR=%BUILDDIR%\%1 +if not exist "%PY_MISC_NEWS_DIR%" mkdir "%PY_MISC_NEWS_DIR%" if exist ..\Misc\NEWS ( echo.Copying Misc\NEWS to %PY_MISC_NEWS_DIR%\NEWS copy ..\Misc\NEWS "%PY_MISC_NEWS_DIR%\NEWS" > nul ) else if exist ..\Misc\NEWS.D ( if defined BLURB ( echo.Merging Misc/NEWS with %BLURB% - if not exist build mkdir build %BLURB% merge -f "%PY_MISC_NEWS_DIR%\NEWS" ) else ( echo.No Misc/NEWS file and Blurb is not available. diff --git a/Tools/msi/exe/crtlicense.txt b/PC/crtlicense.txt similarity index 100% rename from Tools/msi/exe/crtlicense.txt rename to PC/crtlicense.txt diff --git a/PC/layout/main.py b/PC/layout/main.py index 624033e721b73a..c39aab208d3560 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -31,6 +31,7 @@ from .support.options import * from .support.pip import * from .support.props import * +from .support.nuspec import * BDIST_WININST_FILES_ONLY = FileNameSet("wininst-*", "bdist_wininst.py") BDIST_WININST_STUB = "PC/layout/support/distutils.command.bdist_wininst.py" @@ -66,6 +67,7 @@ TOOLS_DIRS = FileNameSet("scripts", "i18n", "pynche", "demo", "parser") TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt") + def copy_if_modified(src, dest): try: dest_stat = os.stat(dest) @@ -73,12 +75,15 @@ def copy_if_modified(src, dest): do_copy = True else: src_stat = os.stat(src) - do_copy = (src_stat.st_mtime != dest_stat.st_mtime or - src_stat.st_size != dest_stat.st_size) + do_copy = ( + src_stat.st_mtime != dest_stat.st_mtime + or src_stat.st_size != dest_stat.st_size + ) if do_copy: shutil.copy2(src, dest) + def get_lib_layout(ns): def _c(f): if f in EXCLUDE_FROM_LIB: @@ -119,7 +124,7 @@ def get_tcltk_lib(ns): except FileNotFoundError: pass if not tcl_lib or not os.path.isdir(tcl_lib): - warn("Failed to find TCL_LIBRARY") + log_warning("Failed to find TCL_LIBRARY") return for dest, src in rglob(Path(tcl_lib).parent, "**/*"): @@ -168,7 +173,7 @@ def in_build(f, dest="", new_name=None): for dest, src in rglob(ns.build, "vcruntime*.dll"): yield dest, src - yield "LICENSE.txt", ns.source / "LICENSE" + yield "LICENSE.txt", ns.build / "LICENSE.txt" for dest, src in rglob(ns.build, ("*.pyd", "*.dll")): if src.stem.endswith("_d") != bool(ns.debug) and src not in REQUIRED_DLLS: @@ -222,15 +227,12 @@ def _c(d): yield dest, src if ns.include_pip: - pip_dir = get_pip_dir(ns) - if not pip_dir.is_dir(): - log_warning("Failed to find {} - pip will not be included", pip_dir) - else: - pkg_root = "packages/{}" if ns.zip_lib else "Lib/site-packages/{}" - for dest, src in rglob(pip_dir, "**/*"): - if src in EXCLUDE_FROM_LIB or src in EXCLUDE_FROM_PACKAGED_LIB: - continue - yield pkg_root.format(dest), src + for dest, src in get_pip_layout(ns): + if isinstance(src, tuple) or not ( + src in EXCLUDE_FROM_LIB or src in EXCLUDE_FROM_PACKAGED_LIB + ): + continue + yield dest, src if ns.include_chm: for dest, src in rglob(ns.doc_build / "htmlhelp", PYTHON_CHM_NAME): @@ -244,6 +246,10 @@ def _c(d): for dest, src in get_props_layout(ns): yield dest, src + if ns.include_nuspec: + for dest, src in get_nuspec_layout(ns): + yield dest, src + for dest, src in get_appx_layout(ns): yield dest, src @@ -287,7 +293,9 @@ def _py_temp_compile(src, ns, dest_dir=None, checked=True): return None dest = (dest_dir or ns.temp) / (src.stem + ".py") - return _compile_one_py(src, dest.with_suffix(".pyc"), dest, optimize=2, checked=checked) + return _compile_one_py( + src, dest.with_suffix(".pyc"), dest, optimize=2, checked=checked + ) def _write_to_zip(zf, dest, src, ns, checked=True): @@ -361,28 +369,9 @@ def generate_source_files(ns): print("# Uncomment to run site.main() automatically", file=f) print("#import site", file=f) - if ns.include_appxmanifest: - log_info("Generating AppxManifest.xml in {}", ns.temp) - ns.temp.mkdir(parents=True, exist_ok=True) - - with open(ns.temp / "AppxManifest.xml", "wb") as f: - f.write(get_appxmanifest(ns)) - - with open(ns.temp / "_resources.xml", "wb") as f: - f.write(get_resources_xml(ns)) - if ns.include_pip: - pip_dir = get_pip_dir(ns) - if not (pip_dir / "pip").is_dir(): - log_info("Extracting pip to {}", pip_dir) - pip_dir.mkdir(parents=True, exist_ok=True) - extract_pip_files(ns) - - if ns.include_props: - log_info("Generating {} in {}", PYTHON_PROPS_NAME, ns.temp) - ns.temp.mkdir(parents=True, exist_ok=True) - with open(ns.temp / PYTHON_PROPS_NAME, "wb") as f: - f.write(get_props(ns)) + log_info("Extracting pip") + extract_pip_files(ns) def _create_zip_file(ns): @@ -427,6 +416,18 @@ def copy_files(files, ns): log_info("Processed {} files", count) log_debug("Processing {!s}", src) + if isinstance(src, tuple): + src, content = src + if ns.copy: + log_debug("Copy {} -> {}", src, ns.copy / dest) + (ns.copy / dest).parent.mkdir(parents=True, exist_ok=True) + with open(ns.copy / dest, "wb") as f: + f.write(content) + if ns.zip: + log_debug("Zip {} into {}", src, ns.zip) + zip_file.writestr(str(dest), content) + continue + if ( ns.precompile and src in PY_FILES diff --git a/PC/layout/support/appxmanifest.py b/PC/layout/support/appxmanifest.py index 49a35fa1f0468e..58fba8443f17ea 100644 --- a/PC/layout/support/appxmanifest.py +++ b/PC/layout/support/appxmanifest.py @@ -17,12 +17,7 @@ from .constants import * -__all__ = [] - - -def public(f): - __all__.append(f.__name__) - return f +__all__ = ["get_appx_layout"] APPX_DATA = dict( @@ -166,9 +161,7 @@ def public(f): "Help": { "Main Python Documentation": { "_condition": lambda ns: ns.include_chm, - "": "[{{AppVPackageRoot}}]\\Doc\\{}".format( - PYTHON_CHM_NAME - ), + "": "[{{AppVPackageRoot}}]\\Doc\\{}".format(PYTHON_CHM_NAME), }, "Local Python Documentation": { "_condition": lambda ns: ns.include_html_doc, @@ -239,31 +232,6 @@ def _fixup_sccd(ns, sccd, new_hash=None): return sccd -@public -def get_appx_layout(ns): - if not ns.include_appxmanifest: - return - - yield "AppxManifest.xml", ns.temp / "AppxManifest.xml" - yield "_resources.xml", ns.temp / "_resources.xml" - icons = ns.source / "PC" / "icons" - yield "_resources/pythonx44.png", icons / "pythonx44.png" - yield "_resources/pythonx44$targetsize-44_altform-unplated.png", icons / "pythonx44.png" - yield "_resources/pythonx50.png", icons / "pythonx50.png" - yield "_resources/pythonx50$targetsize-50_altform-unplated.png", icons / "pythonx50.png" - yield "_resources/pythonx150.png", icons / "pythonx150.png" - yield "_resources/pythonx150$targetsize-150_altform-unplated.png", icons / "pythonx150.png" - yield "_resources/pythonwx44.png", icons / "pythonwx44.png" - yield "_resources/pythonwx44$targetsize-44_altform-unplated.png", icons / "pythonwx44.png" - yield "_resources/pythonwx150.png", icons / "pythonwx150.png" - yield "_resources/pythonwx150$targetsize-150_altform-unplated.png", icons / "pythonwx150.png" - sccd = ns.source / SCCD_FILENAME - if sccd.is_file(): - # This should only be set for side-loading purposes. - sccd = _fixup_sccd(ns, sccd, os.getenv("APPX_DATA_SHA256")) - yield sccd.name, sccd - - def find_or_add(xml, element, attr=None, always_add=False): if always_add: e = None @@ -393,7 +361,6 @@ def disable_registry_virtualization(xml): e = find_or_add(e, "rescap:Capability", ("Name", "unvirtualizedResources")) -@public def get_appxmanifest(ns): for k, v in APPXMANIFEST_NS.items(): ET.register_namespace(k, v) @@ -481,6 +448,29 @@ def get_appxmanifest(ns): return buffer.getbuffer() -@public def get_resources_xml(ns): return RESOURCES_XML_TEMPLATE.encode("utf-8") + + +def get_appx_layout(ns): + if not ns.include_appxmanifest: + return + + yield "AppxManifest.xml", ("AppxManifest.xml", get_appxmanifest(ns)) + yield "_resources.xml", ("_resources.xml", get_resources_xml(ns)) + icons = ns.source / "PC" / "icons" + yield "_resources/pythonx44.png", icons / "pythonx44.png" + yield "_resources/pythonx44$targetsize-44_altform-unplated.png", icons / "pythonx44.png" + yield "_resources/pythonx50.png", icons / "pythonx50.png" + yield "_resources/pythonx50$targetsize-50_altform-unplated.png", icons / "pythonx50.png" + yield "_resources/pythonx150.png", icons / "pythonx150.png" + yield "_resources/pythonx150$targetsize-150_altform-unplated.png", icons / "pythonx150.png" + yield "_resources/pythonwx44.png", icons / "pythonwx44.png" + yield "_resources/pythonwx44$targetsize-44_altform-unplated.png", icons / "pythonwx44.png" + yield "_resources/pythonwx150.png", icons / "pythonwx150.png" + yield "_resources/pythonwx150$targetsize-150_altform-unplated.png", icons / "pythonwx150.png" + sccd = ns.source / SCCD_FILENAME + if sccd.is_file(): + # This should only be set for side-loading purposes. + sccd = _fixup_sccd(ns, sccd, os.getenv("APPX_DATA_SHA256")) + yield sccd.name, sccd diff --git a/PC/layout/support/nuspec.py b/PC/layout/support/nuspec.py new file mode 100644 index 00000000000000..ba26ff337e91e6 --- /dev/null +++ b/PC/layout/support/nuspec.py @@ -0,0 +1,66 @@ +""" +Provides .props file. +""" + +import os + +from .constants import * + +__all__ = ["get_nuspec_layout"] + +PYTHON_NUSPEC_NAME = "python.nuspec" + +NUSPEC_DATA = { + "PYTHON_TAG": VER_DOT, + "PYTHON_VERSION": os.getenv("PYTHON_NUSPEC_VERSION"), + "PYTHON_BITNESS": "64-bit" if IS_X64 else "32-bit", + "PACKAGENAME": os.getenv("PYTHON_NUSPEC_PACKAGENAME"), + "PACKAGETITLE": os.getenv("PYTHON_NUSPEC_PACKAGETITLE"), + "FILELIST": r' ', +} + +if not NUSPEC_DATA["PYTHON_VERSION"]: + if VER_NAME: + NUSPEC_DATA["PYTHON_VERSION"] = "{}.{}-{}{}".format( + VER_DOT, VER_MICRO, VER_NAME, VER_SERIAL + ) + else: + NUSPEC_DATA["PYTHON_VERSION"] = "{}.{}".format(VER_DOT, VER_MICRO) + +if not NUSPEC_DATA["PACKAGETITLE"]: + NUSPEC_DATA["PACKAGETITLE"] = "Python" if IS_X64 else "Python (32-bit)" + +if not NUSPEC_DATA["PACKAGENAME"]: + NUSPEC_DATA["PACKAGENAME"] = "python" if IS_X64 else "pythonx86" + +FILELIST_WITH_PROPS = r""" + """ + +NUSPEC_TEMPLATE = r""" + + + {PACKAGENAME} + {PACKAGETITLE} + {PYTHON_VERSION} + Python Software Foundation + tools\LICENSE.txt + https://www.python.org/ + Installs {PYTHON_BITNESS} Python for use in build scenarios. + https://www.python.org/static/favicon.ico + python + + +{FILELIST} + + +""" + + +def get_nuspec_layout(ns): + if ns.include_all or ns.include_nuspec: + data = NUSPEC_DATA + if ns.include_all or ns.include_props: + data = dict(data) + data["FILELIST"] = FILELIST_WITH_PROPS + nuspec = NUSPEC_TEMPLATE.format_map(data) + yield "python.nuspec", ("python.nuspec", nuspec.encode("utf-8")) diff --git a/PC/layout/support/options.py b/PC/layout/support/options.py index 00f05667ebb7af..c8ae4e30a8c4a6 100644 --- a/PC/layout/support/options.py +++ b/PC/layout/support/options.py @@ -30,6 +30,7 @@ def public(f): "launchers": {"help": "specific launchers"}, "appxmanifest": {"help": "an appxmanifest"}, "props": {"help": "a python.props file"}, + "nuspec": {"help": "a python.nuspec file"}, "chm": {"help": "the CHM documentation"}, "html-doc": {"help": "the HTML documentation"}, } @@ -60,13 +61,11 @@ def public(f): "stable", "distutils", "venv", - "props" + "props", + "nuspec", ], }, - "iot": { - "help": "Windows IoT Core", - "options": ["stable", "pip"], - }, + "iot": {"help": "Windows IoT Core", "options": ["stable", "pip"]}, "default": { "help": "development kit package", "options": [ diff --git a/PC/layout/support/pip.py b/PC/layout/support/pip.py index 369a923ce139fb..eada456655eca7 100644 --- a/PC/layout/support/pip.py +++ b/PC/layout/support/pip.py @@ -11,15 +11,11 @@ import subprocess import sys -__all__ = [] +from .filesets import * +__all__ = ["extract_pip_files", "get_pip_layout"] -def public(f): - __all__.append(f.__name__) - return f - -@public def get_pip_dir(ns): if ns.copy: if ns.zip_lib: @@ -29,10 +25,23 @@ def get_pip_dir(ns): return ns.temp / "packages" -@public +def get_pip_layout(ns): + pip_dir = get_pip_dir(ns) + if not pip_dir.is_dir(): + log_warning("Failed to find {} - pip will not be included", pip_dir) + else: + pkg_root = "packages/{}" if ns.zip_lib else "Lib/site-packages/{}" + for dest, src in rglob(pip_dir, "**/*"): + yield pkg_root.format(dest), src + yield "pip.ini", ("pip.ini", b"[global]\nuser=yes") + + def extract_pip_files(ns): dest = get_pip_dir(ns) - dest.mkdir(parents=True, exist_ok=True) + try: + dest.mkdir(parents=True, exist_ok=False) + except IOError: + return src = ns.source / "Lib" / "ensurepip" / "_bundled" @@ -58,6 +67,7 @@ def extract_pip_files(ns): "--target", str(dest), "--no-index", + "--no-compile", "--no-cache-dir", "-f", str(src), diff --git a/PC/layout/support/props.py b/PC/layout/support/props.py index 3a047d21505834..4d3b06195f6ed2 100644 --- a/PC/layout/support/props.py +++ b/PC/layout/support/props.py @@ -6,13 +6,7 @@ from .constants import * -__all__ = ["PYTHON_PROPS_NAME"] - - -def public(f): - __all__.append(f.__name__) - return f - +__all__ = ["get_props_layout"] PYTHON_PROPS_NAME = "python.props" @@ -97,14 +91,8 @@ def public(f): """ -@public def get_props_layout(ns): if ns.include_all or ns.include_props: - yield "python.props", ns.temp / "python.props" - - -@public -def get_props(ns): - # TODO: Filter contents of props file according to included/excluded items - props = PROPS_TEMPLATE.format_map(PROPS_DATA) - return props.encode("utf-8") + # TODO: Filter contents of props file according to included/excluded items + props = PROPS_TEMPLATE.format_map(PROPS_DATA) + yield "python.props", ("python.props", props.encode("utf-8")) diff --git a/PC/python_uwp.cpp b/PC/python_uwp.cpp index 5c8caa6666c4e0..dd1edde730921b 100644 --- a/PC/python_uwp.cpp +++ b/PC/python_uwp.cpp @@ -182,9 +182,9 @@ wmain(int argc, wchar_t **argv) if (*p++ == L'\\') { if (wcsnicmp(p, L"pip", 3) == 0) { moduleName = L"pip"; + /* No longer required when pip 19.1 is added */ _wputenv_s(L"PIP_USER", L"true"); - } - else if (wcsnicmp(p, L"idle", 4) == 0) { + } else if (wcsnicmp(p, L"idle", 4) == 0) { moduleName = L"idlelib"; } } diff --git a/PCbuild/_tkinter.vcxproj b/PCbuild/_tkinter.vcxproj index fdfa59648aa904..af813b77c1d1c8 100644 --- a/PCbuild/_tkinter.vcxproj +++ b/PCbuild/_tkinter.vcxproj @@ -122,7 +122,7 @@ - + diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 6f0c85e4a45a03..bce599329e73ab 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -76,7 +76,7 @@ if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts -if "%~1"=="-V" shift & goto Version +if "%~1"=="-V" shift & goto :Version rem These use the actual property names used by MSBuild. We could just let rem them in through the environment, but we specify them on the command line rem anyway for visibility so set defaults after this @@ -111,10 +111,16 @@ call "%dir%find_msbuild.bat" %MSBUILD% if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if "%kill%"=="true" call :Kill +if ERRORLEVEL 1 exit /B 3 if "%do_pgo%"=="true" ( set conf=PGInstrument call :Build %1 %2 %3 %4 %5 %6 %7 %8 %9 +) +rem %VARS% are evaluated eagerly, which would lose the ERRORLEVEL +rem value if we didn't split it out here. +if "%do_pgo%"=="true" if ERRORLEVEL 1 exit /B %ERRORLEVEL% +if "%do_pgo%"=="true" ( del /s "%dir%\*.pgc" del /s "%dir%\..\Lib\*.pyc" echo on @@ -124,7 +130,8 @@ if "%do_pgo%"=="true" ( set conf=PGUpdate set target=Build ) -goto Build +goto :Build + :Kill echo on %MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ @@ -132,7 +139,7 @@ echo on /p:KillPython=true @echo off -goto :eof +exit /B %ERRORLEVEL% :Build rem Call on MSBuild to do the work, echo the command. @@ -148,9 +155,11 @@ echo on %1 %2 %3 %4 %5 %6 %7 %8 %9 @echo off -goto :eof +exit /b %ERRORLEVEL% :Version rem Display the current build version information call "%dir%find_msbuild.bat" %MSBUILD% -if not ERRORLEVEL 1 %MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) +%MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 +if ERRORLEVEL 1 exit /b 3 \ No newline at end of file diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 12f07dd51287e7..7c0f50be9ea8ea 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -1,6 +1,8 @@ - - + + + + <__PyProject_Props_Imported>true <_ProjectFileVersion>10.0.30319.1 10.0 $(BuildPath) @@ -29,7 +31,7 @@ $(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories) WIN32;$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions) - + MaxSpeed true true @@ -147,15 +149,15 @@ public override bool Execute() { - + - + @@ -189,8 +191,8 @@ public override bool Execute() { $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot81)\bin\x86 $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86 $(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\ - <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificate)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /q /a /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" - <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificateSha1)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /q /a /sha1 "$(SigningCertificateSha1)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" + <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificate)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /n "$(SigningCertificate)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" + <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificateSha1)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /sha1 "$(SigningCertificateSha1)" /fd sha256 /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" <_MakeCatCommand Condition="Exists($(SdkBinPath))">"$(SdkBinPath)\makecat.exe" diff --git a/PCbuild/python.props b/PCbuild/python.props index e6642fc4818a0a..b13837d394b113 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -1,6 +1,7 @@ - + + <__Python_Props_Imported>true Win32 Release + + + <_TclTkLib Include="$(tcltkdir)\lib\**\*" /> + + + diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 45e189b537f693..b72eedecb23cf2 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -29,7 +29,7 @@ set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename} set D=%~dp0 set PCBUILD=%D%..\..\PCbuild\ -if "%Py_OutDir%"=="" set Py_OutDir=%PCBUILD% +if NOT DEFINED Py_OutDir set Py_OutDir=%PCBUILD% set EXTERNALS=%D%..\..\externals\windows-installer\ set BUILDX86= diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj index 071501ce6e6f57..326766bf2d473f 100644 --- a/Tools/msi/exe/exe.wixproj +++ b/Tools/msi/exe/exe.wixproj @@ -21,25 +21,6 @@ - - - - <_LicenseFiles Include="@(LicenseFiles)"> - $([System.IO.File]::ReadAllText(%(FullPath))) - - - - - - diff --git a/Tools/msi/exe/exe_files.wxs b/Tools/msi/exe/exe_files.wxs index 394b4de473547f..483d06c65b2e57 100644 --- a/Tools/msi/exe/exe_files.wxs +++ b/Tools/msi/exe/exe_files.wxs @@ -3,7 +3,7 @@ - + diff --git a/Tools/msi/make_cat.ps1 b/Tools/msi/make_cat.ps1 index cc3cd4a2b50cda..9ea3ddd495719e 100644 --- a/Tools/msi/make_cat.ps1 +++ b/Tools/msi/make_cat.ps1 @@ -7,6 +7,8 @@ The path to the catalog definition file to compile and sign. It is assumed that the .cat file will be the same name with a new extension. +.Parameter outfile + The path to move the built .cat file to (optional). .Parameter description The description to add to the signature (optional). .Parameter certname @@ -16,6 +18,7 @@ #> param( [Parameter(Mandatory=$true)][string]$catalog, + [string]$outfile, [switch]$sign, [string]$description, [string]$certname, @@ -35,3 +38,8 @@ if (-not $?) { if ($sign) { Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files @($catalog -replace 'cdf$', 'cat') } + +if ($outfile) { + Split-Path -Parent $outfile | ?{ $_ } | %{ mkdir -Force $_; } + Move-Item ($catalog -replace 'cdf$', 'cat') $outfile +} diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index 5da901c0215a2f..3f14501446a15a 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -56,6 +56,7 @@ true $(ExternalsDir)\windows-installer\redist-1\$(Platform) $([System.IO.Path]::GetFullPath($(CRTRedist))) + $(tcltkDir)lib python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm $(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value).0 @@ -121,7 +122,7 @@ src - + tcltk diff --git a/Tools/msi/msi.targets b/Tools/msi/msi.targets index 9283a1ed6c3049..4788a637a5d2d6 100644 --- a/Tools/msi/msi.targets +++ b/Tools/msi/msi.targets @@ -47,7 +47,7 @@ EncodingType= - @@ -76,18 +76,18 @@ EncodingType= - + - + - + - + \ No newline at end of file diff --git a/Tools/msi/sign_build.ps1 b/Tools/msi/sign_build.ps1 index 6668eb33a2d135..d3f750454f522b 100644 --- a/Tools/msi/sign_build.ps1 +++ b/Tools/msi/sign_build.ps1 @@ -16,7 +16,7 @@ #> param( [Parameter(Mandatory=$true)][string]$root, - [string[]]$patterns=@("*.exe", "*.dll", "*.pyd"), + [string[]]$patterns=@("*.exe", "*.dll", "*.pyd", "*.cat"), [string]$description, [string]$certname, [string]$certsha1, diff --git a/Tools/msi/tcltk/tcltk.wixproj b/Tools/msi/tcltk/tcltk.wixproj index fae353f5f50a7d..218f3d15ec88fc 100644 --- a/Tools/msi/tcltk/tcltk.wixproj +++ b/Tools/msi/tcltk/tcltk.wixproj @@ -20,10 +20,10 @@ - - $(tcltkDir) + + $(TclTkLibraryDir) !(bindpath.tcltk) - $(tcltkDir)lib + $(TclTkLibraryDir) tcl\ tcltk_lib diff --git a/Tools/msi/uploadrelease.ps1 b/Tools/msi/uploadrelease.ps1 index 491df80be1e9b0..b6fbeea2981009 100644 --- a/Tools/msi/uploadrelease.ps1 +++ b/Tools/msi/uploadrelease.ps1 @@ -15,6 +15,10 @@ The subdirectory on the host to copy files to. .Parameter tests The path to run download tests in. +.Parameter doc_htmlhelp + Optional path besides -build to locate CHM files. +.Parameter embed + Optional path besides -build to locate ZIP files. .Parameter skipupload Skip uploading .Parameter skippurge @@ -30,6 +34,8 @@ param( [string]$server="python-downloads", [string]$target="/srv/www.python.org/ftp/python", [string]$tests=${env:TEMP}, + [string]$doc_htmlhelp=$null, + [string]$embed=$null, [switch]$skipupload, [switch]$skippurge, [switch]$skiptest, @@ -73,32 +79,45 @@ if (-not $skipupload) { "Upload using $pscp and $plink" "" - pushd $build - $doc = gci python*.chm, python*.chm.asc + if ($doc_htmlhelp) { + pushd $doc_htmlhelp + } else { + pushd $build + } + $chm = gci python*.chm, python*.chm.asc popd $d = "$target/$($p[0])/" & $plink -batch $user@$server mkdir $d & $plink -batch $user@$server chgrp downloads $d & $plink -batch $user@$server chmod g-x,o+rx $d - & $pscp -batch $doc.FullName "$user@${server}:$d" + & $pscp -batch $chm.FullName "$user@${server}:$d" - foreach ($a in gci "$build" -Directory) { + $dirs = gci "$build" -Directory + if ($embed) { + $dirs = ($dirs, (gi $embed)) | %{ $_ } + } + + foreach ($a in $dirs) { "Uploading files from $($a.FullName)" pushd "$($a.FullName)" $exe = gci *.exe, *.exe.asc, *.zip, *.zip.asc $msi = gci *.msi, *.msi.asc, *.msu, *.msu.asc popd - & $pscp -batch $exe.FullName "$user@${server}:$d" + if ($exe) { + & $pscp -batch $exe.FullName "$user@${server}:$d" + } - $sd = "$d$($a.Name)$($p[1])/" - & $plink -batch $user@$server mkdir $sd - & $plink -batch $user@$server chgrp downloads $sd - & $plink -batch $user@$server chmod g-x,o+rx $sd - & $pscp -batch $msi.FullName "$user@${server}:$sd" - & $plink -batch $user@$server chgrp downloads $sd* - & $plink -batch $user@$server chmod g-x,o+r $sd* + if ($msi) { + $sd = "$d$($a.Name)$($p[1])/" + & $plink -batch $user@$server mkdir $sd + & $plink -batch $user@$server chgrp downloads $sd + & $plink -batch $user@$server chmod g-x,o+rx $sd + & $pscp -batch $msi.FullName "$user@${server}:$sd" + & $plink -batch $user@$server chgrp downloads $sd* + & $plink -batch $user@$server chmod g-x,o+r $sd* + } } & $plink -batch $user@$server chgrp downloads $d* @@ -128,7 +147,18 @@ if (-not $skiptest) { if (-not $skiphash) { # Display MD5 hash and size of each downloadable file pushd $build - $hashes = gci python*.chm, *\*.exe, *\*.zip | ` + $files = gci python*.chm, *\*.exe, *\*.zip + if ($doc_htmlhelp) { + cd $doc_htmlhelp + $files = ($files, (gci python*.chm)) | %{ $_ } + } + if ($embed) { + cd $embed + $files = ($files, (gci *.zip)) | %{ $_ } + } + popd + + $hashes = $files | ` Sort-Object Name | ` Format-Table Name, @{Label="MD5"; Expression={(Get-FileHash $_ -Algorithm MD5).Hash}}, Length -AutoSize | ` Out-String -Width 4096 From 9765efcb39fc03d5b1abec3924388974470a8bd5 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 14 Jun 2019 09:53:59 -0600 Subject: [PATCH 413/441] bpo-19865: ctypes.create_unicode_buffer() supports non-BMP strings on Windows (GH-14081) --- Lib/ctypes/__init__.py | 10 +++++++++- Lib/ctypes/test/test_buffers.py | 9 +++++++++ .../Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst | 2 ++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 4107db3e3972d7..128155dbf4f2d9 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -274,7 +274,15 @@ def create_unicode_buffer(init, size=None): """ if isinstance(init, str): if size is None: - size = len(init)+1 + if sizeof(c_wchar) == 2: + # UTF-16 requires a surrogate pair (2 wchar_t) for non-BMP + # characters (outside [U+0000; U+FFFF] range). +1 for trailing + # NUL character. + size = sum(2 if ord(c) > 0xFFFF else 1 for c in init) + 1 + else: + # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for + # trailing NUL character. + size = len(init) + 1 buftype = c_wchar * size buf = buftype() buf.value = init diff --git a/Lib/ctypes/test/test_buffers.py b/Lib/ctypes/test/test_buffers.py index 166faaf4e4b89c..15782be757c853 100644 --- a/Lib/ctypes/test/test_buffers.py +++ b/Lib/ctypes/test/test_buffers.py @@ -60,5 +60,14 @@ def test_unicode_conversion(self): self.assertEqual(b[::2], "ac") self.assertEqual(b[::5], "a") + @need_symbol('c_wchar') + def test_create_unicode_buffer_non_bmp(self): + expected = 5 if sizeof(c_wchar) == 2 else 3 + for s in '\U00010000\U00100000', '\U00010000\U0010ffff': + b = create_unicode_buffer(s) + self.assertEqual(len(b), expected) + self.assertEqual(b[-1], '\0') + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst b/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst new file mode 100644 index 00000000000000..efd1f55c0135b0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-14-08-30-16.bpo-19865.FRGH4I.rst @@ -0,0 +1,2 @@ +:func:`ctypes.create_unicode_buffer()` now also supports non-BMP characters +on platforms with 16-bit :c:type:`wchar_t` (for example, Windows and AIX). From 212646cae6b7c4ddc8d98c8b9b6d39a5f259e864 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Jun 2019 18:03:22 +0200 Subject: [PATCH 414/441] bpo-37261: Document sys.unraisablehook corner cases (GH-14059) Document reference cycle and resurrected objects issues in sys.unraisablehook() and threading.excepthook() documentation. Fix test.support.catch_unraisable_exception(): __exit__() no longer ignores unraisable exceptions. Fix test_io test_writer_close_error_on_close(): use a second catch_unraisable_exception() to catch the BufferedWriter unraisable exception. --- Doc/library/sys.rst | 14 +++++++++++--- Doc/library/test.rst | 10 +++------- Doc/library/threading.rst | 8 ++++++++ Lib/test/support/__init__.py | 15 +++------------ Lib/test/test_io.py | 6 +++++- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 5bde6870717c90..817c3f1e56f91f 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1514,13 +1514,21 @@ always available. * *err_msg*: Error message, can be ``None``. * *object*: Object causing the exception, can be ``None``. - :func:`sys.unraisablehook` can be overridden to control how unraisable - exceptions are handled. - The default hook formats *err_msg* and *object* as: ``f'{err_msg}: {object!r}'``; use "Exception ignored in" error message if *err_msg* is ``None``. + :func:`sys.unraisablehook` can be overridden to control how unraisable + exceptions are handled. + + Storing *exc_value* using a custom hook can create a reference cycle. It + should be cleared explicitly to break the reference cycle when the + exception is no longer needed. + + Storing *object* using a custom hook can resurrect it if it is set to an + object which is being finalized. Avoid storing *object* after the custom + hook completes to avoid resurrecting objects. + See also :func:`excepthook` which handles uncaught exceptions. .. versionadded:: 3.8 diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 0a98c882465d85..920c018084b81c 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1086,17 +1086,13 @@ The :mod:`test.support` module defines the following functions: Context manager catching unraisable exception using :func:`sys.unraisablehook`. - If the *object* attribute of the unraisable hook is set and the object is - being finalized, the object is resurrected because the context manager - stores a strong reference to it (``cm.unraisable.object``). - Storing the exception value (``cm.unraisable.exc_value``) creates a reference cycle. The reference cycle is broken explicitly when the context manager exits. - Exiting the context manager clears the stored unraisable exception. It can - trigger a new unraisable exception (ex: the resurrected object is finalized - again and raises the same exception): it is silently ignored in this case. + Storing the object (``cm.unraisable.object``) can resurrect it if it is set + to an object which is being finalized. Exiting the context manager clears + the stored object. Usage:: diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 2907b65f5bca42..9ffd5cd581793a 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -58,6 +58,14 @@ This module defines the following functions: :func:`threading.excepthook` can be overridden to control how uncaught exceptions raised by :func:`Thread.run` are handled. + Storing *exc_value* using a custom hook can create a reference cycle. It + should be cleared explicitly to break the reference cycle when the + exception is no longer needed. + + Storing *object* using a custom hook can resurrect it if it is set to an + object which is being finalized. Avoid storing *object* after the custom + hook completes to avoid resurrecting objects. + .. seealso:: :func:`sys.excepthook` handles uncaught exceptions. diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 174e0456dc7104..7c0efc783edb2f 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3040,17 +3040,13 @@ class catch_unraisable_exception: """ Context manager catching unraisable exception using sys.unraisablehook. - If the *object* attribute of the unraisable hook is set and the object is - being finalized, the object is resurrected because the context manager - stores a strong reference to it (cm.unraisable.object). - Storing the exception value (cm.unraisable.exc_value) creates a reference cycle. The reference cycle is broken explicitly when the context manager exits. - Exiting the context manager clears the stored unraisable exception. It can - trigger a new unraisable exception (ex: the resurrected object is finalized - again and raises the same exception): it is silently ignored in this case. + Storing the object (cm.unraisable.object) can resurrect it if it is set to + an object which is being finalized. Exiting the context manager clears the + stored object. Usage: @@ -3080,10 +3076,5 @@ def __enter__(self): return self def __exit__(self, *exc_info): - # Clear the unraisable exception to explicitly break a reference cycle. - # It can call _hook() again: ignore the new unraisable exception in - # this case. - self.unraisable = None - sys.unraisablehook = self._old_hook del self.unraisable diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 55686d74398355..fc474c99053df2 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -2072,8 +2072,12 @@ def writer_close(): writer.close = lambda: None writer = None + # Ignore BufferedWriter (of the BufferedRWPair) unraisable exception with support.catch_unraisable_exception(): - pair = None + # Ignore BufferedRWPair unraisable exception + with support.catch_unraisable_exception(): + pair = None + support.gc_collect() support.gc_collect() def test_reader_writer_close_error_on_close(self): From 066e5b1a917ec2134e8997d2cadd815724314252 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Jun 2019 18:55:22 +0200 Subject: [PATCH 415/441] bpo-37266: Daemon threads are now denied in subinterpreters (GH-14049) In a subinterpreter, spawning a daemon thread now raises an exception. Daemon threads were never supported in subinterpreters. Previously, the subinterpreter finalization crashed with a Pyton fatal error if a daemon thread was still running. * Add _thread._is_main_interpreter() * threading.Thread.start() now raises RuntimeError if the thread is a daemon thread and the method is called from a subinterpreter. * The _thread module now uses Argument Clinic for the new function. * Use textwrap.dedent() in test_threading.SubinterpThreadingTests --- Doc/library/threading.rst | 8 +++ Doc/whatsnew/3.9.rst | 8 +++ Lib/_dummy_thread.py | 4 ++ Lib/test/test_threading.py | 66 +++++++++++-------- Lib/threading.py | 6 ++ .../2019-06-13-11-59-52.bpo-37266.goLjef.rst | 4 ++ Modules/_threadmodule.c | 24 +++++++ Modules/clinic/_threadmodule.c.h | 22 +++++++ 8 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rst create mode 100644 Modules/clinic/_threadmodule.c.h diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 9ffd5cd581793a..f80eb22e18fca4 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -280,6 +280,8 @@ since it is impossible to detect the termination of alien threads. base class constructor (``Thread.__init__()``) before doing anything else to the thread. + Daemon threads must not be used in subinterpreters. + .. versionchanged:: 3.3 Added the *daemon* argument. @@ -294,6 +296,12 @@ since it is impossible to detect the termination of alien threads. This method will raise a :exc:`RuntimeError` if called more than once on the same thread object. + Raise a :exc:`RuntimeError` if the thread is a daemon thread and the + method is called from a subinterpreter. + + .. versionchanged:: 3.9 + In a subinterpreter, spawning a daemon thread now raises an exception. + .. method:: run() Method representing the thread's activity. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 999519f0ce0753..ef30743b708dbb 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -86,6 +86,14 @@ New Modules Improved Modules ================ +threading +--------- + +In a subinterpreter, spawning a daemon thread now raises an exception. Daemon +threads were never supported in subinterpreters. Previously, the subinterpreter +finalization crashed with a Pyton fatal error if a daemon thread was still +running. + Optimizations ============= diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py index a2cae54b0580db..2407f9bf5ddc2a 100644 --- a/Lib/_dummy_thread.py +++ b/Lib/_dummy_thread.py @@ -161,3 +161,7 @@ def interrupt_main(): else: global _interrupt _interrupt = True + + +def _is_main_interpreter(): + return True diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 0a0a62bdf9bfaf..a04d496001e3af 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -17,6 +17,7 @@ import os import subprocess import signal +import textwrap from test import lock_tests from test import support @@ -928,14 +929,19 @@ def test_clear_threads_states_after_fork(self): class SubinterpThreadingTests(BaseTestCase): + def pipe(self): + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + if hasattr(os, 'set_blocking'): + os.set_blocking(r, False) + return (r, w) def test_threads_join(self): # Non-daemon threads should be joined at subinterpreter shutdown # (issue #18808) - r, w = os.pipe() - self.addCleanup(os.close, r) - self.addCleanup(os.close, w) - code = r"""if 1: + r, w = self.pipe() + code = textwrap.dedent(r""" import os import random import threading @@ -953,7 +959,7 @@ def f(): threading.Thread(target=f).start() random_sleep() - """ % (w,) + """ % (w,)) ret = test.support.run_in_subinterp(code) self.assertEqual(ret, 0) # The thread was joined properly. @@ -964,10 +970,8 @@ def test_threads_join_2(self): # Python code returned but before the thread state is deleted. # To achieve this, we register a thread-local object which sleeps # a bit when deallocated. - r, w = os.pipe() - self.addCleanup(os.close, r) - self.addCleanup(os.close, w) - code = r"""if 1: + r, w = self.pipe() + code = textwrap.dedent(r""" import os import random import threading @@ -992,34 +996,38 @@ def f(): threading.Thread(target=f).start() random_sleep() - """ % (w,) + """ % (w,)) ret = test.support.run_in_subinterp(code) self.assertEqual(ret, 0) # The thread was joined properly. self.assertEqual(os.read(r, 1), b"x") - @cpython_only - def test_daemon_threads_fatal_error(self): - subinterp_code = r"""if 1: - import os + def test_daemon_thread(self): + r, w = self.pipe() + code = textwrap.dedent(f""" import threading - import time + import sys - def f(): - # Make sure the daemon thread is still running when - # Py_EndInterpreter is called. - time.sleep(10) - threading.Thread(target=f, daemon=True).start() - """ - script = r"""if 1: - import _testcapi + channel = open({w}, "w", closefd=False) + + def func(): + pass + + thread = threading.Thread(target=func, daemon=True) + try: + thread.start() + except RuntimeError as exc: + print("ok: %s" % exc, file=channel, flush=True) + else: + thread.join() + print("fail: RuntimeError not raised", file=channel, flush=True) + """) + ret = test.support.run_in_subinterp(code) + self.assertEqual(ret, 0) - _testcapi.run_in_subinterp(%r) - """ % (subinterp_code,) - with test.support.SuppressCrashReport(): - rc, out, err = assert_python_failure("-c", script) - self.assertIn("Fatal Python error: Py_EndInterpreter: " - "not the last thread", err.decode()) + msg = os.read(r, 100).decode().rstrip() + self.assertEqual("ok: daemon thread are not supported " + "in subinterpreters", msg) class ThreadingExceptionTests(BaseTestCase): diff --git a/Lib/threading.py b/Lib/threading.py index 7c6d404bcd10f6..01a15a6fc075ac 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -34,6 +34,7 @@ _allocate_lock = _thread.allocate_lock _set_sentinel = _thread._set_sentinel get_ident = _thread.get_ident +_is_main_interpreter = _thread._is_main_interpreter try: get_native_id = _thread.get_native_id _HAVE_THREAD_NATIVE_ID = True @@ -846,6 +847,11 @@ def start(self): if self._started.is_set(): raise RuntimeError("threads can only be started once") + + if self.daemon and not _is_main_interpreter(): + raise RuntimeError("daemon thread are not supported " + "in subinterpreters") + with _active_limbo_lock: _limbo[self] = self try: diff --git a/Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rst b/Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rst new file mode 100644 index 00000000000000..f41918185213cf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-13-11-59-52.bpo-37266.goLjef.rst @@ -0,0 +1,4 @@ +In a subinterpreter, spawning a daemon thread now raises an exception. Daemon +threads were never supported in subinterpreters. Previously, the subinterpreter +finalization crashed with a Pyton fatal error if a daemon thread was still +running. diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index d5e40ef999e3d5..9ab8e7a0ceb3c4 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -8,6 +8,14 @@ #include "structmember.h" /* offsetof */ #include "pythread.h" +#include "clinic/_threadmodule.c.h" + +/*[clinic input] +module _thread +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=be8dbe5cc4b16df7]*/ + + static PyObject *ThreadError; static PyObject *str_dict; @@ -1442,6 +1450,21 @@ PyDoc_STRVAR(excepthook_doc, \n\ Handle uncaught Thread.run() exception."); +/*[clinic input] +_thread._is_main_interpreter + +Return True if the current interpreter is the main Python interpreter. +[clinic start generated code]*/ + +static PyObject * +_thread__is_main_interpreter_impl(PyObject *module) +/*[clinic end generated code: output=7dd82e1728339adc input=cc1eb00fd4598915]*/ +{ + _PyRuntimeState *runtime = &_PyRuntime; + PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + return PyBool_FromLong(interp == runtime->interpreters.main); +} + static PyMethodDef thread_methods[] = { {"start_new_thread", (PyCFunction)thread_PyThread_start_new_thread, METH_VARARGS, start_new_doc}, @@ -1471,6 +1494,7 @@ static PyMethodDef thread_methods[] = { METH_NOARGS, _set_sentinel_doc}, {"_excepthook", thread_excepthook, METH_O, excepthook_doc}, + _THREAD__IS_MAIN_INTERPRETER_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/clinic/_threadmodule.c.h b/Modules/clinic/_threadmodule.c.h new file mode 100644 index 00000000000000..07ea08b1750d53 --- /dev/null +++ b/Modules/clinic/_threadmodule.c.h @@ -0,0 +1,22 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_thread__is_main_interpreter__doc__, +"_is_main_interpreter($module, /)\n" +"--\n" +"\n" +"Return True if the current interpreter is the main Python interpreter."); + +#define _THREAD__IS_MAIN_INTERPRETER_METHODDEF \ + {"_is_main_interpreter", (PyCFunction)_thread__is_main_interpreter, METH_NOARGS, _thread__is_main_interpreter__doc__}, + +static PyObject * +_thread__is_main_interpreter_impl(PyObject *module); + +static PyObject * +_thread__is_main_interpreter(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _thread__is_main_interpreter_impl(module); +} +/*[clinic end generated code: output=505840d1b9101789 input=a9049054013a1b77]*/ From 5884043252473ac733aba1d3251d4debe72511e5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Jun 2019 19:31:43 +0200 Subject: [PATCH 416/441] bpo-35537: Rewrite setsid test for os.posix_spawn (GH-11721) bpo-35537, bpo-35876: Fix also test_start_new_session() of test_subprocess: use os.getsid() rather than os.getpgid(). --- Lib/test/test_posix.py | 44 +++++++++++++++++++++++-------------- Lib/test/test_subprocess.py | 9 ++++---- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 0f07a8f2e68db8..afa1398d4edc0d 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -1639,23 +1639,35 @@ def test_setsigmask_wrong_type(self): os.environ, setsigmask=[signal.NSIG, signal.NSIG+1]) - @unittest.skipIf(True, - "FIXME: bpo-35537: test fails is setsid is supported") - def test_start_new_session(self): - # For code coverage of calling setsid(). We don't care if we get an - # EPERM error from it depending on the test execution environment, that - # still indicates that it was called. - code = "import os; print(os.getpgid(os.getpid()))" + def test_setsid(self): + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) try: - self.spawn_func(sys.executable, - [sys.executable, "-c", code], - os.environ, setsid=True) - except NotImplementedError as exc: - self.skipTest("setsid is not supported: %s" % exc) - else: - parent_pgid = os.getpgid(os.getpid()) - child_pgid = int(output) - self.assertNotEqual(parent_pgid, child_pgid) + os.set_inheritable(wfd, True) + + code = textwrap.dedent(f""" + import os + fd = {wfd} + sid = os.getsid(0) + os.write(fd, str(sid).encode()) + """) + + try: + pid = self.spawn_func(sys.executable, + [sys.executable, "-c", code], + os.environ, setsid=True) + except NotImplementedError as exc: + self.skipTest(f"setsid is not supported: {exc!r}") + except PermissionError as exc: + self.skipTest(f"setsid failed with: {exc!r}") + finally: + os.close(wfd) + + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + output = os.read(rfd, 100) + child_sid = int(output) + parent_sid = os.getsid(os.getpid()) + self.assertNotEqual(parent_sid, child_sid) @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index fca3ed62099bde..97d21904b9cecf 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1705,16 +1705,15 @@ def test_start_new_session(self): # still indicates that it was called. try: output = subprocess.check_output( - [sys.executable, "-c", - "import os; print(os.getpgid(os.getpid()))"], + [sys.executable, "-c", "import os; print(os.getsid(0))"], start_new_session=True) except OSError as e: if e.errno != errno.EPERM: raise else: - parent_pgid = os.getpgid(os.getpid()) - child_pgid = int(output) - self.assertNotEqual(parent_pgid, child_pgid) + parent_sid = os.getsid(0) + child_sid = int(output) + self.assertNotEqual(parent_sid, child_sid) def test_run_abort(self): # returncode handles signal termination From bd5798f6d4f6960fd6b49976bdf4326be77f4277 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Jun 2019 19:43:43 +0200 Subject: [PATCH 417/441] Document C API changes in What's New in Python 3.8 (GH-14092) --- Doc/whatsnew/3.8.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 3e607130743df1..b63bcef5de4762 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -955,6 +955,33 @@ Optimizations Build and C API Changes ======================= +* The header files have been reorganized to better separate the different kinds + of APIs: + + * ``Include/*.h`` should be the portable public stable C API. + * ``Include/cpython/*.h`` should be the unstable C API specific to CPython; + public API, with some private API prefixed by ``_Py`` or ``_PY``. + * ``Include/internal/*.h`` is the private internal C API very specific to + CPython. This API comes with no backward compatibility warranty and should + not be used outside CPython. It is only exposed for very specific needs + like debuggers and profiles which has to access to CPython internals + without calling functions. This API is now installed by ``make install``. + + (Contributed by Victor Stinner in :issue:`35134` and :issue:`35081`, + work initiated by Eric Snow in Python 3.7) + +* Some macros have been converted to static inline functions: parameter types + and return type are well defined, they don't have issues specific to macros, + variables have a local scopes. Examples: + + * :c:func:`Py_INCREF`, :c:func:`Py_DECREF` + * :c:func:`Py_XINCREF`, :c:func:`Py_XDECREF` + * :c:func:`PyObject_INIT`, :c:func:`PyObject_INIT_VAR` + * Private functions: :c:func:`_PyObject_GC_TRACK`, + :c:func:`_PyObject_GC_UNTRACK`, :c:func:`_Py_Dealloc` + + (Contributed by Victor Stinner in :issue:`35059`.) + * The :c:func:`PyByteArray_Init` and :c:func:`PyByteArray_Fini` functions have been removed. They did nothing since Python 2.7.4 and Python 3.2.0, were excluded from the limited API (stable ABI), and were not documented. From 749e73065dea1cc3a6d39a830380a2c124f568c2 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 14 Jun 2019 14:19:25 -0700 Subject: [PATCH 418/441] Fix Windows release build issues (GH-14091) * Increase timeout for PGO builds in Windows release * Fix test step failures * Disable MinGW step properly * Fix embeddable distro name --- .azure-pipelines/windows-release/msi-steps.yml | 12 ++++++++---- .azure-pipelines/windows-release/stage-build.yml | 3 +++ .../windows-release/stage-layout-embed.yml | 2 +- .../windows-release/stage-test-embed.yml | 3 ++- Tools/msi/dev/dev.wixproj | 4 ++-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.azure-pipelines/windows-release/msi-steps.yml b/.azure-pipelines/windows-release/msi-steps.yml index 2f80c34eeb7d79..153408271c711e 100644 --- a/.azure-pipelines/windows-release/msi-steps.yml +++ b/.azure-pipelines/windows-release/msi-steps.yml @@ -94,8 +94,8 @@ steps: Py_OutDir: $(Build.BinariesDirectory) - script: | - %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true /p:BuildForRelease=true - %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false /p:BuildForRelease=true + %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true + %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false displayName: 'Build win32 installer' env: Platform: x86 @@ -103,10 +103,12 @@ steps: PYTHON: $(Build.BinariesDirectory)\win32\python.exe PYTHONHOME: $(Build.SourcesDirectory) TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_win32 + BuildForRelease: true + SuppressMinGWLib: true - script: | - %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true /p:BuildForRelease=true - %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false /p:BuildForRelease=true + %MSBUILD% Tools\msi\bundle\releaselocal.wixproj /t:Rebuild /p:RebuildAll=true + %MSBUILD% Tools\msi\bundle\releaseweb.wixproj /t:Rebuild /p:RebuildAll=false displayName: 'Build amd64 installer' env: Platform: x64 @@ -114,6 +116,8 @@ steps: PYTHON: $(Build.BinariesDirectory)\amd64\python.exe PYTHONHOME: $(Build.SourcesDirectory) TclTkLibraryDir: $(Build.BinariesDirectory)\tcltk_lib_amd64 + BuildForRelease: true + SuppressMinGWLib: true - task: CopyFiles@2 displayName: 'Assemble artifact: msi (1/2)' diff --git a/.azure-pipelines/windows-release/stage-build.yml b/.azure-pipelines/windows-release/stage-build.yml index 121e4b1a278e0d..a5093a04f08716 100644 --- a/.azure-pipelines/windows-release/stage-build.yml +++ b/.azure-pipelines/windows-release/stage-build.yml @@ -95,6 +95,9 @@ jobs: displayName: Python PGO build condition: and(succeeded(), eq(variables['DoPGO'], 'true')) + # Allow up to five hours for PGO + timeoutInMinutes: 300 + pool: name: 'Windows Release' diff --git a/.azure-pipelines/windows-release/stage-layout-embed.yml b/.azure-pipelines/windows-release/stage-layout-embed.yml index c9d58b6b30a28e..e2689dbb603d6e 100644 --- a/.azure-pipelines/windows-release/stage-layout-embed.yml +++ b/.azure-pipelines/windows-release/stage-layout-embed.yml @@ -39,7 +39,7 @@ jobs: - powershell: > $(LayoutCmd) --copy "$(Build.ArtifactStagingDirectory)\layout" - --zip "$(Build.ArtifactStagingDirectory)\embed\$(VersionText)-embed-$(Name).zip" + --zip "$(Build.ArtifactStagingDirectory)\embed\python-$(VersionText)-embed-$(Name).zip" --preset-embed displayName: 'Generate embeddable layout' diff --git a/.azure-pipelines/windows-release/stage-test-embed.yml b/.azure-pipelines/windows-release/stage-test-embed.yml index ab377fdfa8c90a..b33176266a20da 100644 --- a/.azure-pipelines/windows-release/stage-test-embed.yml +++ b/.azure-pipelines/windows-release/stage-test-embed.yml @@ -26,7 +26,8 @@ jobs: downloadPath: $(Build.BinariesDirectory) - powershell: | - Expand-Archive -Path "$(Build.BinariesDirectory)\embed\embed-$(Name).zip" -DestinationPath "$(Build.BinariesDirectory)\Python" + $p = gi "$(Build.BinariesDirectory)\embed\python*embed-$(Name).zip" + Expand-Archive -Path $p -DestinationPath "$(Build.BinariesDirectory)\Python" $p = gi "$(Build.BinariesDirectory)\Python\python.exe" Write-Host "##vso[task.prependpath]$(Split-Path -Parent $p)" displayName: 'Install Python and add to PATH' diff --git a/Tools/msi/dev/dev.wixproj b/Tools/msi/dev/dev.wixproj index 4a56cec35722cf..c6e3bcf709c6c4 100644 --- a/Tools/msi/dev/dev.wixproj +++ b/Tools/msi/dev/dev.wixproj @@ -8,7 +8,7 @@ - + $(DefineConstants); IncludeMinGWLib=1; @@ -35,7 +35,7 @@ Inputs="$(BuildPath)$(PyDllName).dll" Outputs="$(BuildPath)lib$(PyDllName).a" AfterTargets="PrepareForBuild" - Condition="$(BuildForRelease)"> + Condition="$(BuildForRelease) and $(SuppressMinGWLib) == ''"> <_DllToolOpts>-m i386 --as-flags=--32 From 7efc526e5cfb929a79c192ac2dcf7eb78d3a4401 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 15 Jun 2019 03:24:41 +0200 Subject: [PATCH 419/441] bpo-36707: Document "m" removal from sys.abiflags (GH-14090) --- Doc/library/sys.rst | 4 ++++ Doc/whatsnew/3.8.rst | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 817c3f1e56f91f..c073431c894817 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -16,6 +16,10 @@ always available. On POSIX systems where Python was built with the standard ``configure`` script, this contains the ABI flags as specified by :pep:`3149`. + .. versionchanged:: 3.8 + Default flags became an empty string (``m`` flag for pymalloc has been + removed). + .. versionadded:: 3.2 diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index b63bcef5de4762..cc3fb76e9c55fc 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -955,6 +955,22 @@ Optimizations Build and C API Changes ======================= +* Default :data:`sys.abiflags` became an empty string: the ``m`` flag for + pymalloc became useless (builds with and without pymalloc are ABI compatible) + and so has been removed. (Contributed by Victor Stinner in :issue:`36707`.) + + Example of changes: + + * Only ``python3.8`` program is installed, ``python3.8m`` program is gone. + * Only ``python3.8-config`` script is installed, ``python3.8m-config`` script + is gone. + * The ``m`` flag has been removed from the suffix of dynamic library + filenames: extension modules in the standard library as well as those + produced and installed by third-party packages, like those downloaded from + PyPI. On Linux, for example, the Python 3.7 suffix + ``.cpython-37m-x86_64-linux-gnu.so`` became + ``.cpython-38-x86_64-linux-gnu.so`` in Python 3.8. + * The header files have been reorganized to better separate the different kinds of APIs: From ef2152354f03a165c5e3adb53e2276934fabd50a Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sat, 15 Jun 2019 14:05:08 +0300 Subject: [PATCH 420/441] bpo-37279: Fix asyncio sendfile support when extra data are sent in fallback mode. (GH-14075) --- Lib/asyncio/base_events.py | 4 ++-- Lib/test/test_asyncio/test_sendfile.py | 3 ++- .../next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index e0025397fa8a85..90de8587a3bb98 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -861,7 +861,7 @@ async def _sock_sendfile_fallback(self, sock, file, offset, count): read = await self.run_in_executor(None, file.readinto, view) if not read: break # EOF - await self.sock_sendall(sock, view) + await self.sock_sendall(sock, view[:read]) total_sent += read return total_sent finally: @@ -1145,7 +1145,7 @@ async def _sendfile_fallback(self, transp, file, offset, count): if not read: return total_sent # EOF await proto.drain() - transp.write(view) + transp.write(view[:read]) total_sent += read finally: if total_sent > 0 and hasattr(file, 'seek'): diff --git a/Lib/test/test_asyncio/test_sendfile.py b/Lib/test/test_asyncio/test_sendfile.py index f148fe27e6ad40..3b7f784c5ee3a0 100644 --- a/Lib/test/test_asyncio/test_sendfile.py +++ b/Lib/test/test_asyncio/test_sendfile.py @@ -86,7 +86,8 @@ async def wait_closed(self): class SendfileBase: - DATA = b"SendfileBaseData" * (1024 * 8) # 128 KiB + # 128 KiB plus small unaligned to buffer chunk + DATA = b"SendfileBaseData" * (1024 * 8 + 1) # Reduce socket buffer size to test on relative small data sets. BUF_SIZE = 4 * 1024 # 4 KiB diff --git a/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst b/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst new file mode 100644 index 00000000000000..d740b9b62b0800 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-14-13-25-56.bpo-37279.OHlW6l.rst @@ -0,0 +1,2 @@ +Fix asyncio sendfile support when sendfile sends extra data in fallback +mode. From 0237265e8287141c40faa8719da3a2d21d511d0d Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sat, 15 Jun 2019 14:05:35 +0300 Subject: [PATCH 421/441] Use threadpool for reading from file in sendfile fallback mode (#14076) --- Lib/asyncio/base_events.py | 2 +- .../next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 90de8587a3bb98..14b80bdda9c039 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1141,7 +1141,7 @@ async def _sendfile_fallback(self, transp, file, offset, count): if blocksize <= 0: return total_sent view = memoryview(buf)[:blocksize] - read = file.readinto(view) + read = await self.run_in_executor(None, file.readinto, view) if not read: return total_sent # EOF await proto.drain() diff --git a/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst b/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst new file mode 100644 index 00000000000000..7cdc56a72ce4f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-14-13-30-47.bpo-37280.Fxur0F.rst @@ -0,0 +1 @@ +Use threadpool for reading from file for sendfile fallback mode. From f475729a714a9fb13672f8989c4abbafb783e09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Ogam?= Date: Sat, 15 Jun 2019 13:33:23 +0200 Subject: [PATCH 422/441] Update weakref.rst (GH-14098) --- Doc/library/weakref.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index a5c4295ef1faf9..c3519e45beb6b1 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -65,8 +65,8 @@ exposed by the :mod:`weakref` module for the benefit of advanced uses. Not all objects can be weakly referenced; those objects which can include class instances, functions written in Python (but not in C), instance methods, sets, -frozensets, some :term:`file objects `, :term:`generator`\s, type -objects, sockets, arrays, deques, regular expression pattern objects, and code +frozensets, some :term:`file objects `, :term:`generators `, +type objects, sockets, arrays, deques, regular expression pattern objects, and code objects. .. versionchanged:: 3.2 @@ -80,9 +80,10 @@ support weak references but can add support through subclassing:: obj = Dict(red=1, green=2, blue=3) # this object is weak referenceable -Other built-in types such as :class:`tuple` and :class:`int` do not support weak -references even when subclassed (This is an implementation detail and may be -different across various Python implementations.). +.. impl-detail:: + + Other built-in types such as :class:`tuple` and :class:`int` do not support weak + references even when subclassed. Extension types can easily be made to support weak references; see :ref:`weakref-support`. From 552ace7498722f1add9f3782751b0d365f4c24c8 Mon Sep 17 00:00:00 2001 From: ubordignon <48903745+ubordignon@users.noreply.github.com> Date: Sat, 15 Jun 2019 13:43:10 +0200 Subject: [PATCH 423/441] Fix typo in Lib/concurrent/futures/thread.py (GH-13953) --- Lib/concurrent/futures/process.py | 2 +- Lib/concurrent/futures/thread.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index cfdcd3ed7ea9df..9e2ab9db64f664 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -505,7 +505,7 @@ def __init__(self, max_workers=None, mp_context=None, worker processes will be created as the machine has processors. mp_context: A multiprocessing context to launch the workers. This object should provide SimpleQueue, Queue and Process. - initializer: An callable used to initialize worker processes. + initializer: A callable used to initialize worker processes. initargs: A tuple of arguments to pass to the initializer. """ _check_system_limits() diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 75d05a76be3f41..d84b3aa7da0c2e 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -125,7 +125,7 @@ def __init__(self, max_workers=None, thread_name_prefix='', max_workers: The maximum number of threads that can be used to execute the given calls. thread_name_prefix: An optional name prefix to give our threads. - initializer: An callable used to initialize worker threads. + initializer: A callable used to initialize worker threads. initargs: A tuple of arguments to pass to the initializer. """ if max_workers is None: From 7d23dbe6d17bb872da5b89a5674cb32a7a1a2b9c Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Sat, 15 Jun 2019 15:41:58 +0200 Subject: [PATCH 424/441] Doc: Bump Sphinx verison. (#13785) To reflect the one we're using in production. --- .azure-pipelines/docs-steps.yml | 2 +- .travis.yml | 2 +- Doc/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.azure-pipelines/docs-steps.yml b/.azure-pipelines/docs-steps.yml index 492e4e34bb2dab..96361961ea75eb 100644 --- a/.azure-pipelines/docs-steps.yml +++ b/.azure-pipelines/docs-steps.yml @@ -12,7 +12,7 @@ steps: inputs: versionSpec: '>=3.6' -- script: python -m pip install sphinx==1.8.2 blurb python-docs-theme +- script: python -m pip install sphinx==2.0.1 blurb python-docs-theme displayName: 'Install build dependencies' - ${{ if ne(parameters.latex, 'true') }}: diff --git a/.travis.yml b/.travis.yml index 02de997750abc8..addff773347977 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,7 +55,7 @@ matrix: # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures. # (Updating the version is fine as long as no warnings are raised by doing so.) # The theme used by the docs is stored separately, so we need to install that as well. - - python -m pip install sphinx==1.8.2 blurb python-docs-theme + - python -m pip install sphinx==2.0.1 blurb python-docs-theme script: - make check suspicious html SPHINXOPTS="-q -W -j4" - name: "Documentation tests" diff --git a/Doc/Makefile b/Doc/Makefile index 6f86728ea834c3..3bcd9f23752b00 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -133,7 +133,7 @@ clean: venv: $(PYTHON) -m venv $(VENVDIR) $(VENVDIR)/bin/python3 -m pip install -U pip setuptools - $(VENVDIR)/bin/python3 -m pip install -U Sphinx blurb python-docs-theme + $(VENVDIR)/bin/python3 -m pip install -U Sphinx==2.0.1 blurb python-docs-theme @echo "The venv has been created in the $(VENVDIR) directory" dist: From 6ef4d323bdb0f910d6e5e4d81a654253d4d1bcd5 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 15 Jun 2019 10:09:36 -0400 Subject: [PATCH 425/441] Update link in colorsys docs to be https (GH-14062) --- Doc/library/colorsys.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/colorsys.rst b/Doc/library/colorsys.rst index 1360c7cc9f1db4..b672a05b39145d 100644 --- a/Doc/library/colorsys.rst +++ b/Doc/library/colorsys.rst @@ -21,7 +21,7 @@ spaces, the coordinates are all between 0 and 1. .. seealso:: More information about color spaces can be found at - http://poynton.ca/ColorFAQ.html and + https://poynton.ca/ColorFAQ.html and https://www.cambridgeincolour.com/tutorials/color-spaces.htm. The :mod:`colorsys` module defines the following functions: From cfa0394b9760941bbdd089913a6420d2af54314a Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Sat, 15 Jun 2019 16:21:37 +0200 Subject: [PATCH 426/441] Doc: Deprecation header: More precise wording. (GH-14109) --- Doc/tools/templates/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index a765a5de8a2dfb..77915c8431b659 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -5,7 +5,7 @@
      {% trans %}This document is for an old version of Python that is no longer supported. You should upgrade, and read the {% endtrans %} - {% trans %} Python documentation for the last stable release {% endtrans %}. + {% trans %} Python documentation for the current stable release {% endtrans %}.
      {%- endif %} {% endblock %} From 7a68f8c28bb78d957555a5001dac4df6345434a0 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 15 Jun 2019 15:58:00 +0100 Subject: [PATCH 427/441] bpo-37289: Remove 'if False' handling in the peephole optimizer (GH-14099) --- Python/peephole.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Python/peephole.c b/Python/peephole.c index d7b1dfc4d9c141..3e56e788b0079b 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -311,18 +311,12 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, } PyObject* cnt = PyList_GET_ITEM(consts, get_arg(codestr, i)); int is_true = PyObject_IsTrue(cnt); + if (is_true == -1) { + goto exitError; + } if (is_true == 1) { fill_nops(codestr, op_start, nexti + 1); cumlc = 0; - } else if (is_true == 0) { - if (i > 1 && - (_Py_OPCODE(codestr[i - 1]) == POP_JUMP_IF_TRUE || - _Py_OPCODE(codestr[i - 1]) == POP_JUMP_IF_FALSE)) { - break; - } - h = get_arg(codestr, nexti) / sizeof(_Py_CODEUNIT); - tgt = find_op(codestr, codelen, h); - fill_nops(codestr, op_start, tgt); } break; From 3a1d50e7e573efb577714146bed5c03b9c95f466 Mon Sep 17 00:00:00 2001 From: Michael Felt Date: Sat, 15 Jun 2019 17:52:29 +0200 Subject: [PATCH 428/441] bpo-28009: Fix uuid SkipUnless logic to be based on platform programs capable of introspection (GH-12777) uuid could try fallback methods that had no chance of working on a particular platform, and this could cause spurious test failures, as well as degraded performance as fallback options were tried and failed. This fixes both the uuid module and its test's SkipUnless logic to use a prefiltered list of techniques that may at least potentially work on that platform. Patch by Michael Felt (aixtools). --- Lib/test/test_uuid.py | 20 +++++---- Lib/uuid.py | 43 ++++++++++++++----- .../2019-04-11-07-59-43.bpo-28009.s85urF.rst | 3 ++ 3 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index 992ef0cbf8048c..92642d239b92cd 100644 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -462,8 +462,7 @@ def test_uuid1_eui64(self): with unittest.mock.patch.multiple( self.uuid, _node=None, # Ignore any cached node value. - _NODE_GETTERS_WIN32=[too_large_getter], - _NODE_GETTERS_UNIX=[too_large_getter], + _GETTERS=[too_large_getter], ): node = self.uuid.getnode() self.assertTrue(0 < node < (1 << 48), '%012x' % node) @@ -673,7 +672,7 @@ class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase): class BaseTestInternals: - uuid = None + _uuid = py_uuid @unittest.skipUnless(os.name == 'posix', 'requires Posix') def test_find_mac(self): @@ -708,27 +707,32 @@ def check_node(self, node, requires=None): self.assertTrue(0 < node < (1 << 48), "%s is not an RFC 4122 node ID" % hex) - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, + "ifconfig is not used for introspection on this platform") def test_ifconfig_getnode(self): node = self.uuid._ifconfig_getnode() self.check_node(node, 'ifconfig') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._ip_getnode in _uuid._GETTERS, + "ip is not used for introspection on this platform") def test_ip_getnode(self): node = self.uuid._ip_getnode() self.check_node(node, 'ip') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._arp_getnode in _uuid._GETTERS, + "arp is not used for introspection on this platform") def test_arp_getnode(self): node = self.uuid._arp_getnode() self.check_node(node, 'arp') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._lanscan_getnode in _uuid._GETTERS, + "lanscan is not used for introspection on this platform") def test_lanscan_getnode(self): node = self.uuid._lanscan_getnode() self.check_node(node, 'lanscan') - @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(_uuid._netstat_getnode in _uuid._GETTERS, + "netstat is not used for introspection on this platform") def test_netstat_getnode(self): node = self.uuid._netstat_getnode() self.check_node(node, 'netstat') diff --git a/Lib/uuid.py b/Lib/uuid.py index ddc63ccd082c0b..7aa01bb5c35506 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -45,6 +45,7 @@ """ import os +import platform import sys from enum import Enum @@ -52,6 +53,12 @@ __author__ = 'Ka-Ping Yee ' +# The recognized platforms - known behaviors +_AIX = platform.system() == 'AIX' +_DARWIN = platform.system() == 'Darwin' +_LINUX = platform.system() == 'Linux' +_WINDOWS = platform.system() == 'Windows' + RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ 'reserved for NCS compatibility', 'specified in RFC 4122', 'reserved for Microsoft compatibility', 'reserved for future definition'] @@ -673,12 +680,31 @@ def _random_getnode(): return random.getrandbits(48) | (1 << 40) -_node = None - -_NODE_GETTERS_WIN32 = [_windll_getnode, _netbios_getnode, _ipconfig_getnode] +# _OS_GETTERS, when known, are targetted for a specific OS or platform. +# The order is by 'common practice' on the specified platform. +# Note: 'posix' and 'windows' _OS_GETTERS are prefixed by a dll/dlload() method +# which, when successful, means none of these "external" methods are called. +# _GETTERS is (also) used by test_uuid.py to SkipUnless(), e.g., +# @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS, ...) +if _LINUX: + _OS_GETTERS = [_ip_getnode, _ifconfig_getnode] +elif _DARWIN: + _OS_GETTERS = [_ifconfig_getnode, _arp_getnode, _netstat_getnode] +elif _WINDOWS: + _OS_GETTERS = [_netbios_getnode, _ipconfig_getnode] +elif _AIX: + _OS_GETTERS = [_netstat_getnode] +else: + _OS_GETTERS = [_ifconfig_getnode, _ip_getnode, _arp_getnode, + _netstat_getnode, _lanscan_getnode] +if os.name == 'posix': + _GETTERS = [_unix_getnode] + _OS_GETTERS +elif os.name == 'nt': + _GETTERS = [_windll_getnode] + _OS_GETTERS +else: + _GETTERS = _OS_GETTERS -_NODE_GETTERS_UNIX = [_unix_getnode, _ifconfig_getnode, _ip_getnode, - _arp_getnode, _lanscan_getnode, _netstat_getnode] +_node = None def getnode(*, getters=None): """Get the hardware address as a 48-bit positive integer. @@ -692,12 +718,7 @@ def getnode(*, getters=None): if _node is not None: return _node - if sys.platform == 'win32': - getters = _NODE_GETTERS_WIN32 - else: - getters = _NODE_GETTERS_UNIX - - for getter in getters + [_random_getnode]: + for getter in _GETTERS + [_random_getnode]: try: _node = getter() except: diff --git a/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst b/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst new file mode 100644 index 00000000000000..233640716d152b --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-04-11-07-59-43.bpo-28009.s85urF.rst @@ -0,0 +1,3 @@ +Modify the test_uuid logic to test when a program is available +AND can be used to obtain a MACADDR as basis for an UUID. +Patch by M. Felt From 8047e0e1c620f69cc21f9ca48b24bf2cdd5c3668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Lapeyre?= Date: Sun, 16 Jun 2019 08:48:57 +0200 Subject: [PATCH 429/441] bpo-35922: Fix RobotFileParser when robots.txt has no relevant crawl delay or request rate (GH-11791) Co-Authored-By: Tal Einat --- Lib/test/test_robotparser.py | 28 +++++++++++-------- Lib/urllib/robotparser.py | 8 ++++-- .../2019-06-11-19-34-29.bpo-35922.rxpzWr.rst | 4 +++ 3 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst diff --git a/Lib/test/test_robotparser.py b/Lib/test/test_robotparser.py index 84a267ad9567ee..77cd7c4d29dfe6 100644 --- a/Lib/test/test_robotparser.py +++ b/Lib/test/test_robotparser.py @@ -97,30 +97,38 @@ class RejectAllRobotsTest(BaseRobotTest, unittest.TestCase): class BaseRequestRateTest(BaseRobotTest): + request_rate = None + crawl_delay = None def test_request_rate(self): + parser = self.parser for url in self.good + self.bad: agent, url = self.get_agent_and_url(url) with self.subTest(url=url, agent=agent): - if self.crawl_delay: - self.assertEqual( - self.parser.crawl_delay(agent), self.crawl_delay - ) - if self.request_rate: + self.assertEqual(parser.crawl_delay(agent), self.crawl_delay) + + parsed_request_rate = parser.request_rate(agent) + self.assertEqual(parsed_request_rate, self.request_rate) + if self.request_rate is not None: self.assertIsInstance( - self.parser.request_rate(agent), + parsed_request_rate, urllib.robotparser.RequestRate ) self.assertEqual( - self.parser.request_rate(agent).requests, + parsed_request_rate.requests, self.request_rate.requests ) self.assertEqual( - self.parser.request_rate(agent).seconds, + parsed_request_rate.seconds, self.request_rate.seconds ) +class EmptyFileTest(BaseRequestRateTest, unittest.TestCase): + robots_txt = '' + good = ['/foo'] + + class CrawlDelayAndRequestRateTest(BaseRequestRateTest, unittest.TestCase): robots_txt = """\ User-agent: figtree @@ -141,10 +149,6 @@ class CrawlDelayAndRequestRateTest(BaseRequestRateTest, unittest.TestCase): class DifferentAgentTest(CrawlDelayAndRequestRateTest): agent = 'FigTree Robot libwww-perl/5.04' - # these are not actually tested, but we still need to parse it - # in order to accommodate the input parameters - request_rate = None - crawl_delay = None class InvalidRequestRateTest(BaseRobotTest, unittest.TestCase): diff --git a/Lib/urllib/robotparser.py b/Lib/urllib/robotparser.py index 7089916a4f81cc..c58565e3945146 100644 --- a/Lib/urllib/robotparser.py +++ b/Lib/urllib/robotparser.py @@ -186,7 +186,9 @@ def crawl_delay(self, useragent): for entry in self.entries: if entry.applies_to(useragent): return entry.delay - return self.default_entry.delay + if self.default_entry: + return self.default_entry.delay + return None def request_rate(self, useragent): if not self.mtime(): @@ -194,7 +196,9 @@ def request_rate(self, useragent): for entry in self.entries: if entry.applies_to(useragent): return entry.req_rate - return self.default_entry.req_rate + if self.default_entry: + return self.default_entry.req_rate + return None def site_maps(self): if not self.sitemaps: diff --git a/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst b/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst new file mode 100644 index 00000000000000..5271a495624d60 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-11-19-34-29.bpo-35922.rxpzWr.rst @@ -0,0 +1,4 @@ +Fix :meth:`RobotFileParser.crawl_delay` and +:meth:`RobotFileParser.request_rate` to return ``None`` rather than +raise :exc:`AttributeError` when no relevant rule is defined in the +robots.txt file. Patch by Rémi Lapeyre. From 552951563cd5968d25e95306362e41f07d661a88 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Sun, 16 Jun 2019 10:25:05 +0200 Subject: [PATCH 430/441] Doc: Remove an ugly space before a dot. (GH-14123) --- Doc/tools/templates/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index 77915c8431b659..17592d74a4eb52 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -5,7 +5,7 @@
      {% trans %}This document is for an old version of Python that is no longer supported. You should upgrade, and read the {% endtrans %} - {% trans %} Python documentation for the current stable release {% endtrans %}. + {% trans %} Python documentation for the current stable release{% endtrans %}.
      {%- endif %} {% endblock %} From 45e0411eee023b21acf1615e995d26058d66c0f1 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 16 Jun 2019 11:06:06 +0100 Subject: [PATCH 431/441] Simplify negativity checks in math.comb and math.perm. (GH-13870) --- Modules/mathmodule.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index ed114767530805..76d821c65b4c8b 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -3056,6 +3056,12 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) "n must be a non-negative integer"); goto error; } + if (Py_SIZE(k) < 0) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + goto error; + } + cmp = PyObject_RichCompareBool(n, k, Py_LT); if (cmp != 0) { if (cmp > 0) { @@ -3072,11 +3078,8 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) LLONG_MAX); goto error; } - else if (overflow < 0 || factors < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "k must be a non-negative integer"); - } + else if (factors == -1) { + /* k is nonnegative, so a return value of -1 can only indicate error */ goto error; } @@ -3176,6 +3179,12 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) "n must be a non-negative integer"); goto error; } + if (Py_SIZE(k) < 0) { + PyErr_SetString(PyExc_ValueError, + "k must be a non-negative integer"); + goto error; + } + /* k = min(k, n - k) */ temp = PyNumber_Subtract(n, k); if (temp == NULL) { @@ -3204,11 +3213,8 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) LLONG_MAX); goto error; } - else if (overflow < 0 || factors < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "k must be a non-negative integer"); - } + if (factors == -1) { + /* k is nonnegative, so a return value of -1 can only indicate error */ goto error; } From 2dfeaa9222e2ed6b6e32faaf08e5b0f77318f0a7 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 16 Jun 2019 17:53:21 +0100 Subject: [PATCH 432/441] Turn math.isqrt assertion into a comment to clarify its purpose. (GH-14131) --- Modules/mathmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 76d821c65b4c8b..82a9a14724f5e1 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1527,10 +1527,10 @@ Here's Python code equivalent to the C implementation below: a = 1 d = 0 for s in reversed(range(c.bit_length())): + # Loop invariant: (a-1)**2 < (n >> 2*(c - d)) < (a+1)**2 e = d d = c >> s a = (a << d - e - 1) + (n >> 2*c - e - d + 1) // a - assert (a-1)**2 < n >> 2*(c - d) < (a+1)**2 return a - (a*a > n) From 5600b5e1b24a3491e83f1b3038a7ea047a34c0bf Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Sun, 16 Jun 2019 19:03:23 +0200 Subject: [PATCH 433/441] bpo-28805: document METH_FASTCALL (GH-14079) --- Doc/c-api/structures.rst | 63 +++++++++++++++---- .../2019-06-14-14-03-51.bpo-28805.qZC0N_.rst | 1 + 2 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 5e0cfd0264f931..5184ad511cd9b1 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -114,10 +114,20 @@ the definition of all other Python objects. .. c:type:: PyCFunctionWithKeywords - Type of the functions used to implement Python callables in C that take - keyword arguments: they take three :c:type:`PyObject\*` parameters and return - one such value. See :c:type:`PyCFunction` above for the meaning of the return - value. + Type of the functions used to implement Python callables in C + with signature :const:`METH_VARARGS | METH_KEYWORDS`. + + +.. c:type:: _PyCFunctionFast + + Type of the functions used to implement Python callables in C + with signature :const:`METH_FASTCALL`. + + +.. c:type:: _PyCFunctionFastWithKeywords + + Type of the functions used to implement Python callables in C + with signature :const:`METH_FASTCALL | METH_KEYWORDS`. .. c:type:: PyMethodDef @@ -149,10 +159,11 @@ specific C type of the *self* object. The :attr:`ml_flags` field is a bitfield which can include the following flags. The individual flags indicate either a calling convention or a binding -convention. Of the calling convention flags, only :const:`METH_VARARGS` and -:const:`METH_KEYWORDS` can be combined. Any of the calling convention flags -can be combined with a binding flag. +convention. +There are four basic calling conventions for positional arguments +and two of them can be combined with :const:`METH_KEYWORDS` to support +also keyword arguments. So there are a total of 6 calling conventions: .. data:: METH_VARARGS @@ -164,13 +175,41 @@ can be combined with a binding flag. using :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_UnpackTuple`. -.. data:: METH_KEYWORDS +.. data:: METH_VARARGS | METH_KEYWORDS Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`. - The function expects three parameters: *self*, *args*, and a dictionary of - all the keyword arguments. The flag must be combined with - :const:`METH_VARARGS`, and the parameters are typically processed using - :c:func:`PyArg_ParseTupleAndKeywords`. + The function expects three parameters: *self*, *args*, *kwargs* where + *kwargs* is a dictionary of all the keyword arguments or possibly *NULL* + if there are no keyword arguments. The parameters are typically processed + using :c:func:`PyArg_ParseTupleAndKeywords`. + + +.. data:: METH_FASTCALL + + Fast calling convention supporting only positional arguments. + The methods have the type :c:type:`_PyCFunctionFast`. + The first parameter is *self*, the second parameter is a C array + of :c:type:`PyObject\*` values indicating the arguments and the third + parameter is the number of arguments (the length of the array). + + This is not part of the :ref:`limited API `. + + .. versionadded:: 3.7 + + +.. data:: METH_FASTCALL | METH_KEYWORDS + + Extension of :const:`METH_FASTCALL` supporting also keyword arguments, + with methods of type :c:type:`_PyCFunctionFastWithKeywords`. + Keyword arguments are passed the same way as in the vectorcall protocol: + there is an additional fourth :c:type:`PyObject\*` parameter + which is a tuple representing the names of the keyword arguments + or possibly *NULL* if there are no keywords. The values of the keyword + arguments are stored in the *args* array, after the positional arguments. + + This is not part of the :ref:`limited API `. + + .. versionadded:: 3.7 .. data:: METH_NOARGS diff --git a/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst b/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst new file mode 100644 index 00000000000000..6d6c4ad4af6072 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-06-14-14-03-51.bpo-28805.qZC0N_.rst @@ -0,0 +1 @@ +The :const:`METH_FASTCALL` calling convention has been documented. From c83356cae2e375324ff4a3fb5d574ebde5c827a9 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Mon, 17 Jun 2019 04:19:19 +0800 Subject: [PATCH 434/441] closes bpo-37300: Remove unnecessary Py_XINCREF in classobject.c. (GH-14120) --- .../Core and Builtins/2019-06-16-02-38-25.bpo-37300.WJkgKV.rst | 1 + Objects/classobject.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-37300.WJkgKV.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-37300.WJkgKV.rst b/Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-37300.WJkgKV.rst new file mode 100644 index 00000000000000..aae278e8498106 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-06-16-02-38-25.bpo-37300.WJkgKV.rst @@ -0,0 +1 @@ +Remove an unnecssary Py_XINCREF in classobject.c. diff --git a/Objects/classobject.c b/Objects/classobject.c index 2415ed14cb1506..f26a85c62371fd 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -110,7 +110,7 @@ PyMethod_New(PyObject *func, PyObject *self) im->im_weakreflist = NULL; Py_INCREF(func); im->im_func = func; - Py_XINCREF(self); + Py_INCREF(self); im->im_self = self; im->vectorcall = method_vectorcall; _PyObject_GC_TRACK(im); From 66d47da86aff15be34adbec02596bb3188684c0d Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 16 Jun 2019 16:33:56 -0400 Subject: [PATCH 435/441] bpo-37220: Fix 2.7 test -R crash on Windows. (GH-13957) The patch needed for 2.7 should make the test more stable on 3.x also. --- Lib/idlelib/idle_test/test_searchbase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/idle_test/test_searchbase.py b/Lib/idlelib/idle_test/test_searchbase.py index e08268fde25799..aee0c4c69929a6 100644 --- a/Lib/idlelib/idle_test/test_searchbase.py +++ b/Lib/idlelib/idle_test/test_searchbase.py @@ -48,7 +48,6 @@ def test_open_and_close(self): self.dialog.default_command = None toplevel = Toplevel(self.root) - self.addCleanup(toplevel.destroy) text = Text(toplevel) self.dialog.open(text) self.assertEqual(self.dialog.top.state(), 'normal') @@ -57,7 +56,8 @@ def test_open_and_close(self): self.dialog.open(text, searchphrase="hello") self.assertEqual(self.dialog.ent.get(), 'hello') - self.dialog.close() + toplevel.update_idletasks() + toplevel.destroy() def test_create_widgets(self): self.dialog.create_entries = Func() From cbca1aec0ec35081b5931bd6ead5c3550aebafa6 Mon Sep 17 00:00:00 2001 From: Jason Saporta Date: Fri, 17 May 2019 17:19:35 -0700 Subject: [PATCH 436/441] Issue 29847 fix with tests. --- Lib/pathlib.py | 10 ++++++++++ Lib/test/test_pathlib.py | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 6369c4b2218d33..256e2903d753ba 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1519,6 +1519,11 @@ class PosixPath(Path, PurePosixPath): """ __slots__ = () + def __new__(cls, *args, **kwargs): + if kwargs: + raise TypeError("keyword arguments provided but ignored") + return super().__new__(cls, *args, **kwargs) + class WindowsPath(Path, PureWindowsPath): """Path subclass for Windows systems. @@ -1526,6 +1531,11 @@ class WindowsPath(Path, PureWindowsPath): """ __slots__ = () + def __new__(cls, *args, **kwargs): + if kwargs: + raise TypeError("keyword arguments provided but ignored") + return super().__new__(cls, *args, **kwargs) + def owner(self): raise NotImplementedError("Path.owner() is unsupported on this system") diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 069467a8459f00..fa5d14865b09ef 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2258,6 +2258,10 @@ def test_handling_bad_descriptor(self): self.fail("Bad file descriptor not handled.") raise + def test_kwargs(self): + with self.assertRaises(TypeError): + self.cls(".", test_kwarg="test") + @only_nt class WindowsPathTest(_BasePathTest, unittest.TestCase): @@ -2328,6 +2332,9 @@ def check(): env['USERPROFILE'] = 'C:\\Users\\alice' check() + def test_kwargs(self): + with self.assertRaises(TypeError): + self.cls(".", test_kwarg="test") if __name__ == "__main__": unittest.main() From 1e4b116bf945cf03e22b25d5fab8dd05c9d5384f Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" Date: Mon, 17 Jun 2019 01:37:26 +0000 Subject: [PATCH 437/441] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by?= =?UTF-8?q?=20blurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst diff --git a/Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst b/Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst new file mode 100644 index 00000000000000..67af7a2c8e2220 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst @@ -0,0 +1 @@ +Subclasses of `pathlib.Path` now raise a `TypeError` when `kwargs` are provided to the constructor. \ No newline at end of file From de3b1a4de8d7a5bdef5ec4cf2b3a20b22087f2d8 Mon Sep 17 00:00:00 2001 From: Jason Saporta Date: Sun, 16 Jun 2019 19:16:58 -0700 Subject: [PATCH 438/441] Update 2019-06-17-01-37-25.bpo-29847.4VTssR.rst --- .../next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst b/Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst index 67af7a2c8e2220..b3803d93bcbcb1 100644 --- a/Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst +++ b/Misc/NEWS.d/next/Library/2019-06-17-01-37-25.bpo-29847.4VTssR.rst @@ -1 +1 @@ -Subclasses of `pathlib.Path` now raise a `TypeError` when `kwargs` are provided to the constructor. \ No newline at end of file +Subclasses of `pathlib.Path` in the standard library now raise a `TypeError` when `kwargs` are provided to the constructor. User-defined subclasses can still use `kwargs` without issue. From 38698233835de3ef82db2f44485c9fe889bd2ccf Mon Sep 17 00:00:00 2001 From: Jason Saporta Date: Sun, 16 Jun 2019 19:23:35 -0700 Subject: [PATCH 439/441] Added test for user-defined subclasses of Path; modified pathlib to make it pass. --- Lib/pathlib.py | 12 ++---------- Lib/test/test_pathlib.py | 6 ++++++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 256e2903d753ba..0b25dec3cf8a7c 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1009,6 +1009,8 @@ class Path(PurePath): def __new__(cls, *args, **kwargs): if cls is Path: cls = WindowsPath if os.name == 'nt' else PosixPath + if cls in (WindowsPath, PosixPath) and kwargs: + raise TypeError("keyword arguments provided but ignored") self = cls._from_parts(args, init=False) if not self._flavour.is_supported: raise NotImplementedError("cannot instantiate %r on your system" @@ -1519,11 +1521,6 @@ class PosixPath(Path, PurePosixPath): """ __slots__ = () - def __new__(cls, *args, **kwargs): - if kwargs: - raise TypeError("keyword arguments provided but ignored") - return super().__new__(cls, *args, **kwargs) - class WindowsPath(Path, PureWindowsPath): """Path subclass for Windows systems. @@ -1531,11 +1528,6 @@ class WindowsPath(Path, PureWindowsPath): """ __slots__ = () - def __new__(cls, *args, **kwargs): - if kwargs: - raise TypeError("keyword arguments provided but ignored") - return super().__new__(cls, *args, **kwargs) - def owner(self): raise NotImplementedError("Path.owner() is unsupported on this system") diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index fa5d14865b09ef..bed192b97320d5 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2112,6 +2112,12 @@ def test_glob_empty_pattern(self): with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'): list(p.glob('')) + def test_kwargs(self): + class MyPath(type(pathlib.Path())): + def __init__(self, *args, foo): + self.foo = foo + path = MyPath('bar', foo=42) + assert path.foo == 42 @only_posix class PosixPathTest(_BasePathTest, unittest.TestCase): From f1cd0a74ec6721ecf300b00e26b2b19a3fb96829 Mon Sep 17 00:00:00 2001 From: Jason Saporta Date: Sun, 16 Jun 2019 19:26:05 -0700 Subject: [PATCH 440/441] Changed name of Path kwargs test. --- Lib/test/test_pathlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index bed192b97320d5..3d369f44146a2a 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2112,7 +2112,7 @@ def test_glob_empty_pattern(self): with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'): list(p.glob('')) - def test_kwargs(self): + def test_user_subclass_kwargs(self): class MyPath(type(pathlib.Path())): def __init__(self, *args, foo): self.foo = foo From 8ca70b6a763ccb1158aae4a88c1ec1cee04303cb Mon Sep 17 00:00:00 2001 From: Jason Saporta Date: Sun, 16 Jun 2019 20:25:21 -0700 Subject: [PATCH 441/441] User subclass test now passing. --- Lib/pathlib.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index ac7738f8bae717..e450f92baf69ba 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1009,8 +1009,6 @@ class Path(PurePath): def __new__(cls, *args, **kwargs): if cls is Path: cls = WindowsPath if os.name == 'nt' else PosixPath - if cls in (WindowsPath, PosixPath) and kwargs: - raise TypeError("keyword arguments provided but ignored") self = cls._from_parts(args, init=False) if not self._flavour.is_supported: raise NotImplementedError("cannot instantiate %r on your system" @@ -1522,7 +1520,7 @@ class PosixPath(Path, PurePosixPath): __slots__ = () def __new__(cls, *args, **kwargs): - if kwargs: + if cls is PosixPath and kwargs: raise TypeError("keyword arguments provided but ignored") return super().__new__(cls, *args, **kwargs) @@ -1534,7 +1532,7 @@ class WindowsPath(Path, PureWindowsPath): __slots__ = () def __new__(cls, *args, **kwargs): - if kwargs: + if cls is WindowsPath and kwargs: raise TypeError("keyword arguments provided but ignored") return super().__new__(cls, *args, **kwargs)