diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/autogen_impl.h b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/autogen_impl.h index 387432f48fbfd93d1d1c7e24702d7146f78388cb..17ae3dfc50498a6271f0275b90451e759c00fe6a 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/autogen_impl.h +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/autogen_impl.h @@ -43,6 +43,41 @@ HPyAPI_STORAGE long _HPy_IMPL_NAME(Long_AsLong)(HPyContext ctx, HPy h) return PyLong_AsLong(_h2py(h)); } +HPyAPI_STORAGE unsigned long _HPy_IMPL_NAME(Long_AsUnsignedLong)(HPyContext ctx, HPy h) +{ + return PyLong_AsUnsignedLong(_h2py(h)); +} + +HPyAPI_STORAGE unsigned long _HPy_IMPL_NAME(Long_AsUnsignedLongMask)(HPyContext ctx, HPy h) +{ + return PyLong_AsUnsignedLongMask(_h2py(h)); +} + +HPyAPI_STORAGE long long _HPy_IMPL_NAME(Long_AsLongLong)(HPyContext ctx, HPy h) +{ + return PyLong_AsLongLong(_h2py(h)); +} + +HPyAPI_STORAGE unsigned long long _HPy_IMPL_NAME(Long_AsUnsignedLongLong)(HPyContext ctx, HPy h) +{ + return PyLong_AsUnsignedLongLong(_h2py(h)); +} + +HPyAPI_STORAGE unsigned long long _HPy_IMPL_NAME(Long_AsUnsignedLongLongMask)(HPyContext ctx, HPy h) +{ + return PyLong_AsUnsignedLongLongMask(_h2py(h)); +} + +HPyAPI_STORAGE size_t _HPy_IMPL_NAME(Long_AsSize_t)(HPyContext ctx, HPy h) +{ + return PyLong_AsSize_t(_h2py(h)); +} + +HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME(Long_AsSsize_t)(HPyContext ctx, HPy h) +{ + return PyLong_AsSsize_t(_h2py(h)); +} + HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Float_FromDouble)(HPyContext ctx, double v) { return _py2h(PyFloat_FromDouble(v)); @@ -238,6 +273,11 @@ HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_SetString)(HPyContext ctx, HPy h_type, co PyErr_SetString(_h2py(h_type), message); } +HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_SetObject)(HPyContext ctx, HPy h_type, HPy h_value) +{ + PyErr_SetObject(_h2py(h_type), _h2py(h_value)); +} + HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Err_NoMemory)(HPyContext ctx) { return _py2h(PyErr_NoMemory()); @@ -353,6 +393,16 @@ HPyAPI_STORAGE char *_HPy_IMPL_NAME(Bytes_AS_STRING)(HPyContext ctx, HPy h) return PyBytes_AS_STRING(_h2py(h)); } +HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Bytes_FromString)(HPyContext ctx, const char *v) +{ + return _py2h(PyBytes_FromString(v)); +} + +HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Bytes_FromStringAndSize)(HPyContext ctx, const char *v, HPy_ssize_t len) +{ + return _py2h(PyBytes_FromStringAndSize(v, len)); +} + HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_FromString)(HPyContext ctx, const char *utf8) { return _py2h(PyUnicode_FromString(utf8)); diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/hpytype.h b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/hpytype.h index 34177cb267761c10cea9d49bb7952c5e4b4eb2d0..bf1d69b18f3f0a967414d07ddeaef7c3240743e3 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/hpytype.h +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/hpytype.h @@ -45,11 +45,12 @@ typedef struct { /* All types are dynamically allocated */ #define _Py_TPFLAGS_HEAPTYPE (1UL << 9) +#define _Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18) /* Set if the type allows subclassing */ #define HPy_TPFLAGS_BASETYPE (1UL << 10) -#define HPy_TPFLAGS_DEFAULT _Py_TPFLAGS_HEAPTYPE +#define HPy_TPFLAGS_DEFAULT (_Py_TPFLAGS_HEAPTYPE | _Py_TPFLAGS_HAVE_VERSION_TAG) #define HPy_CAST(ctx, return_type, h) ((return_type *) _HPy_Cast(ctx, h)) diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/runtime/argparse.h b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/runtime/argparse.h index cc6f3f45eaade6359b92641bbaa12f82b5a7709d..8b87ec746410aaa2b113d88decbe06da2726f479 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/runtime/argparse.h +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/runtime/argparse.h @@ -4,10 +4,10 @@ #include "hpy.h" HPyAPI_RUNTIME_FUNC(int) -HPyArg_Parse(HPyContext ctx, HPy *args, HPy_ssize_t nargs, const char *fmt, ...); +HPyArg_Parse(HPyContext ctx, HPyTracker *ht, HPy *args, HPy_ssize_t nargs, const char *fmt, ...); HPyAPI_RUNTIME_FUNC(int) -HPyArg_ParseKeywords(HPyContext ctx, HPy *args, HPy_ssize_t nargs, HPy kw, +HPyArg_ParseKeywords(HPyContext ctx, HPyTracker *ht, HPy *args, HPy_ssize_t nargs, HPy kw, const char *fmt, const char *keywords[], ...); diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/version.h b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/version.h index 7adbd558174eebea27b5865edf9169a35eddad86..3c022d32b5a381ff1b4e88635a6ffc6e63266caf 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/version.h +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/common/version.h @@ -1,4 +1,4 @@ // automatically generated by setup.py:get_scm_config() -#define HPY_VERSION "0.1.dev756+g848192d" -#define HPY_GIT_REVISION "848192d" +#define HPY_VERSION "0.1.dev875+g7c832a2" +#define HPY_GIT_REVISION "7c832a2" diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/cpython/hpy.h b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/cpython/hpy.h index d1573ebe352a957b3dcb5b8f4e5cb8a25980002b..8f97c4be171e9f33237daf57f6556e51d078698c 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/cpython/hpy.h +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/cpython/hpy.h @@ -45,14 +45,77 @@ typedef Py_hash_t HPy_hash_t; // this should maybe autogenerated from public_api.h typedef struct _HPyContext_s { + /* Constants */ HPy h_None; HPy h_True; HPy h_False; + /* Exceptions */ + HPy h_BaseException; HPy h_Exception; - HPy h_ValueError; - HPy h_TypeError; + HPy h_StopAsyncIteration; + HPy h_StopIteration; + HPy h_GeneratorExit; + HPy h_ArithmeticError; + HPy h_LookupError; + HPy h_AssertionError; + HPy h_AttributeError; + HPy h_BufferError; + HPy h_EOFError; + HPy h_FloatingPointError; + HPy h_OSError; + HPy h_ImportError; + HPy h_ModuleNotFoundError; HPy h_IndexError; + HPy h_KeyError; + HPy h_KeyboardInterrupt; + HPy h_MemoryError; + HPy h_NameError; + HPy h_OverflowError; + HPy h_RuntimeError; + HPy h_RecursionError; + HPy h_NotImplementedError; + HPy h_SyntaxError; + HPy h_IndentationError; + HPy h_TabError; + HPy h_ReferenceError; HPy h_SystemError; + HPy h_SystemExit; + HPy h_TypeError; + HPy h_UnboundLocalError; + HPy h_UnicodeError; + HPy h_UnicodeEncodeError; + HPy h_UnicodeDecodeError; + HPy h_UnicodeTranslateError; + HPy h_ValueError; + HPy h_ZeroDivisionError; + HPy h_BlockingIOError; + HPy h_BrokenPipeError; + HPy h_ChildProcessError; + HPy h_ConnectionError; + HPy h_ConnectionAbortedError; + HPy h_ConnectionRefusedError; + HPy h_ConnectionResetError; + HPy h_FileExistsError; + HPy h_FileNotFoundError; + HPy h_InterruptedError; + HPy h_IsADirectoryError; + HPy h_NotADirectoryError; + HPy h_PermissionError; + HPy h_ProcessLookupError; + HPy h_TimeoutError; + /* Warnings */ + HPy h_Warning; + HPy h_UserWarning; + HPy h_DeprecationWarning; + HPy h_PendingDeprecationWarning; + HPy h_SyntaxWarning; + HPy h_RuntimeWarning; + HPy h_FutureWarning; + HPy h_ImportWarning; + HPy h_UnicodeWarning; + HPy h_BytesWarning; + HPy h_ResourceWarning; + /* Types */ HPy h_BaseObjectType; HPy h_TypeType; HPy h_LongType; @@ -80,14 +143,77 @@ _HPyGetContext(void) { if (HPy_IsNull(ctx->h_None)) { // XXX: we need to find a better way to check whether the ctx is // initialized or not + /* Constants */ ctx->h_None = _py2h(Py_None); ctx->h_True = _py2h(Py_True); ctx->h_False = _py2h(Py_False); + /* Exceptions */ + ctx->h_BaseException = _py2h(PyExc_BaseException); ctx->h_Exception = _py2h(PyExc_Exception); - ctx->h_ValueError = _py2h(PyExc_ValueError); - ctx->h_TypeError = _py2h(PyExc_TypeError); + ctx->h_StopAsyncIteration = _py2h(PyExc_StopAsyncIteration); + ctx->h_StopIteration = _py2h(PyExc_StopIteration); + ctx->h_GeneratorExit = _py2h(PyExc_GeneratorExit); + ctx->h_ArithmeticError = _py2h(PyExc_ArithmeticError); + ctx->h_LookupError = _py2h(PyExc_LookupError); + ctx->h_AssertionError = _py2h(PyExc_AssertionError); + ctx->h_AttributeError = _py2h(PyExc_AttributeError); + ctx->h_BufferError = _py2h(PyExc_BufferError); + ctx->h_EOFError = _py2h(PyExc_EOFError); + ctx->h_FloatingPointError = _py2h(PyExc_FloatingPointError); + ctx->h_OSError = _py2h(PyExc_OSError); + ctx->h_ImportError = _py2h(PyExc_ImportError); + ctx->h_ModuleNotFoundError = _py2h(PyExc_ModuleNotFoundError); ctx->h_IndexError = _py2h(PyExc_IndexError); + ctx->h_KeyError = _py2h(PyExc_KeyError); + ctx->h_KeyboardInterrupt = _py2h(PyExc_KeyboardInterrupt); + ctx->h_MemoryError = _py2h(PyExc_MemoryError); + ctx->h_NameError = _py2h(PyExc_NameError); + ctx->h_OverflowError = _py2h(PyExc_OverflowError); + ctx->h_RuntimeError = _py2h(PyExc_RuntimeError); + ctx->h_RecursionError = _py2h(PyExc_RecursionError); + ctx->h_NotImplementedError = _py2h(PyExc_NotImplementedError); + ctx->h_SyntaxError = _py2h(PyExc_SyntaxError); + ctx->h_IndentationError = _py2h(PyExc_IndentationError); + ctx->h_TabError = _py2h(PyExc_TabError); + ctx->h_ReferenceError = _py2h(PyExc_ReferenceError); ctx->h_SystemError = _py2h(PyExc_SystemError); + ctx->h_SystemExit = _py2h(PyExc_SystemExit); + ctx->h_TypeError = _py2h(PyExc_TypeError); + ctx->h_UnboundLocalError = _py2h(PyExc_UnboundLocalError); + ctx->h_UnicodeError = _py2h(PyExc_UnicodeError); + ctx->h_UnicodeEncodeError = _py2h(PyExc_UnicodeEncodeError); + ctx->h_UnicodeDecodeError = _py2h(PyExc_UnicodeDecodeError); + ctx->h_UnicodeTranslateError = _py2h(PyExc_UnicodeTranslateError); + ctx->h_ValueError = _py2h(PyExc_ValueError); + ctx->h_ZeroDivisionError = _py2h(PyExc_ZeroDivisionError); + ctx->h_BlockingIOError = _py2h(PyExc_BlockingIOError); + ctx->h_BrokenPipeError = _py2h(PyExc_BrokenPipeError); + ctx->h_ChildProcessError = _py2h(PyExc_ChildProcessError); + ctx->h_ConnectionError = _py2h(PyExc_ConnectionError); + ctx->h_ConnectionAbortedError = _py2h(PyExc_ConnectionAbortedError); + ctx->h_ConnectionRefusedError = _py2h(PyExc_ConnectionRefusedError); + ctx->h_ConnectionResetError = _py2h(PyExc_ConnectionResetError); + ctx->h_FileExistsError = _py2h(PyExc_FileExistsError); + ctx->h_FileNotFoundError = _py2h(PyExc_FileNotFoundError); + ctx->h_InterruptedError = _py2h(PyExc_InterruptedError); + ctx->h_IsADirectoryError = _py2h(PyExc_IsADirectoryError); + ctx->h_NotADirectoryError = _py2h(PyExc_NotADirectoryError); + ctx->h_PermissionError = _py2h(PyExc_PermissionError); + ctx->h_ProcessLookupError = _py2h(PyExc_ProcessLookupError); + ctx->h_TimeoutError = _py2h(PyExc_TimeoutError); + /* Warnings */ + ctx->h_Warning = _py2h(PyExc_Warning); + ctx->h_UserWarning = _py2h(PyExc_UserWarning); + ctx->h_DeprecationWarning = _py2h(PyExc_DeprecationWarning); + ctx->h_PendingDeprecationWarning = _py2h(PyExc_PendingDeprecationWarning); + ctx->h_SyntaxWarning = _py2h(PyExc_SyntaxWarning); + ctx->h_RuntimeWarning = _py2h(PyExc_RuntimeWarning); + ctx->h_FutureWarning = _py2h(PyExc_FutureWarning); + ctx->h_ImportWarning = _py2h(PyExc_ImportWarning); + ctx->h_UnicodeWarning = _py2h(PyExc_UnicodeWarning); + ctx->h_BytesWarning = _py2h(PyExc_BytesWarning); + ctx->h_ResourceWarning = _py2h(PyExc_ResourceWarning); + /* Types */ ctx->h_BaseObjectType = _py2h((PyObject *)&PyBaseObject_Type); ctx->h_TypeType = _py2h((PyObject *)&PyType_Type); ctx->h_LongType = _py2h((PyObject *)&PyLong_Type); diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_ctx.h b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_ctx.h index c8e1264fb8e437bcbeecd05b969305def859f5f5..044c93ffdf7bdb55844326de5f700b9e07c7f266 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_ctx.h +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_ctx.h @@ -13,11 +13,70 @@ struct _HPyContext_s { HPy h_None; HPy h_True; HPy h_False; + HPy h_BaseException; HPy h_Exception; - HPy h_ValueError; - HPy h_TypeError; + HPy h_StopAsyncIteration; + HPy h_StopIteration; + HPy h_GeneratorExit; + HPy h_ArithmeticError; + HPy h_LookupError; + HPy h_AssertionError; + HPy h_AttributeError; + HPy h_BufferError; + HPy h_EOFError; + HPy h_FloatingPointError; + HPy h_OSError; + HPy h_ImportError; + HPy h_ModuleNotFoundError; HPy h_IndexError; + HPy h_KeyError; + HPy h_KeyboardInterrupt; + HPy h_MemoryError; + HPy h_NameError; + HPy h_OverflowError; + HPy h_RuntimeError; + HPy h_RecursionError; + HPy h_NotImplementedError; + HPy h_SyntaxError; + HPy h_IndentationError; + HPy h_TabError; + HPy h_ReferenceError; HPy h_SystemError; + HPy h_SystemExit; + HPy h_TypeError; + HPy h_UnboundLocalError; + HPy h_UnicodeError; + HPy h_UnicodeEncodeError; + HPy h_UnicodeDecodeError; + HPy h_UnicodeTranslateError; + HPy h_ValueError; + HPy h_ZeroDivisionError; + HPy h_BlockingIOError; + HPy h_BrokenPipeError; + HPy h_ChildProcessError; + HPy h_ConnectionError; + HPy h_ConnectionAbortedError; + HPy h_ConnectionRefusedError; + HPy h_ConnectionResetError; + HPy h_FileExistsError; + HPy h_FileNotFoundError; + HPy h_InterruptedError; + HPy h_IsADirectoryError; + HPy h_NotADirectoryError; + HPy h_PermissionError; + HPy h_ProcessLookupError; + HPy h_TimeoutError; + HPy h_Warning; + HPy h_UserWarning; + HPy h_DeprecationWarning; + HPy h_PendingDeprecationWarning; + HPy h_SyntaxWarning; + HPy h_RuntimeWarning; + HPy h_FutureWarning; + HPy h_ImportWarning; + HPy h_UnicodeWarning; + HPy h_BytesWarning; + HPy h_ResourceWarning; HPy h_BaseObjectType; HPy h_TypeType; HPy h_LongType; @@ -34,6 +93,13 @@ struct _HPyContext_s { HPy (*ctx_Long_FromSize_t)(HPyContext ctx, size_t value); HPy (*ctx_Long_FromSsize_t)(HPyContext ctx, HPy_ssize_t value); long (*ctx_Long_AsLong)(HPyContext ctx, HPy h); + unsigned long (*ctx_Long_AsUnsignedLong)(HPyContext ctx, HPy h); + unsigned long (*ctx_Long_AsUnsignedLongMask)(HPyContext ctx, HPy h); + long long (*ctx_Long_AsLongLong)(HPyContext ctx, HPy h); + unsigned long long (*ctx_Long_AsUnsignedLongLong)(HPyContext ctx, HPy h); + unsigned long long (*ctx_Long_AsUnsignedLongLongMask)(HPyContext ctx, HPy h); + size_t (*ctx_Long_AsSize_t)(HPyContext ctx, HPy h); + HPy_ssize_t (*ctx_Long_AsSsize_t)(HPyContext ctx, HPy h); HPy (*ctx_Float_FromDouble)(HPyContext ctx, double v); double (*ctx_Float_AsDouble)(HPyContext ctx, HPy h); HPy_ssize_t (*ctx_Length)(HPyContext ctx, HPy h); @@ -73,6 +139,7 @@ struct _HPyContext_s { HPy (*ctx_InPlaceXor)(HPyContext ctx, HPy h1, HPy h2); HPy (*ctx_InPlaceOr)(HPyContext ctx, HPy h1, HPy h2); void (*ctx_Err_SetString)(HPyContext ctx, HPy h_type, const char *message); + void (*ctx_Err_SetObject)(HPyContext ctx, HPy h_type, HPy h_value); int (*ctx_Err_Occurred)(HPyContext ctx); HPy (*ctx_Err_NoMemory)(HPyContext ctx); void (*ctx_Err_Clear)(HPyContext ctx); @@ -105,6 +172,8 @@ struct _HPyContext_s { HPy_ssize_t (*ctx_Bytes_GET_SIZE)(HPyContext ctx, HPy h); char *(*ctx_Bytes_AsString)(HPyContext ctx, HPy h); char *(*ctx_Bytes_AS_STRING)(HPyContext ctx, HPy h); + HPy (*ctx_Bytes_FromString)(HPyContext ctx, const char *v); + HPy (*ctx_Bytes_FromStringAndSize)(HPyContext ctx, const char *v, HPy_ssize_t len); HPy (*ctx_Unicode_FromString)(HPyContext ctx, const char *utf8); int (*ctx_Unicode_Check)(HPyContext ctx, HPy h); HPy (*ctx_Unicode_AsUTF8String)(HPyContext ctx, HPy h); diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_trampolines.h b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_trampolines.h index dcb0e99b2645198cf001d64645c33933e9b825ab..1bf0dbaef801a12278995461b18149dfb9b5d0cc 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_trampolines.h +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/include/universal/autogen_trampolines.h @@ -48,6 +48,34 @@ static inline long HPyLong_AsLong(HPyContext ctx, HPy h) { return ctx->ctx_Long_AsLong ( ctx, h ); } +static inline unsigned long HPyLong_AsUnsignedLong(HPyContext ctx, HPy h) { + return ctx->ctx_Long_AsUnsignedLong ( ctx, h ); +} + +static inline unsigned long HPyLong_AsUnsignedLongMask(HPyContext ctx, HPy h) { + return ctx->ctx_Long_AsUnsignedLongMask ( ctx, h ); +} + +static inline long long HPyLong_AsLongLong(HPyContext ctx, HPy h) { + return ctx->ctx_Long_AsLongLong ( ctx, h ); +} + +static inline unsigned long long HPyLong_AsUnsignedLongLong(HPyContext ctx, HPy h) { + return ctx->ctx_Long_AsUnsignedLongLong ( ctx, h ); +} + +static inline unsigned long long HPyLong_AsUnsignedLongLongMask(HPyContext ctx, HPy h) { + return ctx->ctx_Long_AsUnsignedLongLongMask ( ctx, h ); +} + +static inline size_t HPyLong_AsSize_t(HPyContext ctx, HPy h) { + return ctx->ctx_Long_AsSize_t ( ctx, h ); +} + +static inline HPy_ssize_t HPyLong_AsSsize_t(HPyContext ctx, HPy h) { + return ctx->ctx_Long_AsSsize_t ( ctx, h ); +} + static inline HPy HPyFloat_FromDouble(HPyContext ctx, double v) { return ctx->ctx_Float_FromDouble ( ctx, v ); } @@ -204,6 +232,10 @@ static inline void HPyErr_SetString(HPyContext ctx, HPy h_type, const char *mess ctx->ctx_Err_SetString ( ctx, h_type, message ); } +static inline void HPyErr_SetObject(HPyContext ctx, HPy h_type, HPy h_value) { + ctx->ctx_Err_SetObject ( ctx, h_type, h_value ); +} + static inline int HPyErr_Occurred(HPyContext ctx) { return ctx->ctx_Err_Occurred ( ctx ); } @@ -328,6 +360,14 @@ static inline char *HPyBytes_AS_STRING(HPyContext ctx, HPy h) { return ctx->ctx_Bytes_AS_STRING ( ctx, h ); } +static inline HPy HPyBytes_FromString(HPyContext ctx, const char *v) { + return ctx->ctx_Bytes_FromString ( ctx, v ); +} + +static inline HPy HPyBytes_FromStringAndSize(HPyContext ctx, const char *v, HPy_ssize_t len) { + return ctx->ctx_Bytes_FromStringAndSize ( ctx, v, len ); +} + static inline HPy HPyUnicode_FromString(HPyContext ctx, const char *utf8) { return ctx->ctx_Unicode_FromString ( ctx, utf8 ); } diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/src/runtime/argparse.c b/pypy/module/_hpy_universal/_vendored/hpy/devel/src/runtime/argparse.c index 7c0c04db2250631059f8fdac271650c8c396b1fa..3eea13819999de6b56d3b3b59d4a5dcd82821064 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/src/runtime/argparse.c +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/src/runtime/argparse.c @@ -9,59 +9,106 @@ * and handles. More complex types (e.g. buffers) should be retrieved as * handles and then processed further as needed. * - * Supported formatting strings: + * Supported Formatting Strings + * ---------------------------- * * Numbers - * ------- + * ~~~~~~~ * - * i (int) [int] + * ``b (int) [unsigned char]`` + * Convert a nonnegative Python integer to an unsigned tiny int, stored in a C unsigned char. + * + * ``B (int) [unsigned char]`` + * Convert a Python integer to a tiny int without overflow checking, stored in a C unsigned char. + * + * ``h (int) [short int]`` + * Convert a Python integer to a C short int. + * + * ``H (int) [unsigned short int]`` + * Convert a Python integer to a C unsigned short int, without overflow checking. + * + * ``i (int) [int]`` * Convert a Python integer to a plain C int. * - * l (int) [long int] + * ``I (int) [unsigned int]`` + * Convert a Python integer to a C unsigned int, without overflow checking. + * + * ``l (int) [long int]`` * Convert a Python integer to a C long int. * - * d (float) [double] + * ``k (int) [unsigned long]`` + * Convert a Python integer to a C unsigned long without overflow checking. + * + * ``L (int) [long long]`` + * Convert a Python integer to a C long long. + * + * ``K (int) [unsigned long long]`` + * Convert a Python integer to a C unsigned long long without overflow checking. + * + * ``n (int) [HPy_ssize_t]`` + * Convert a Python integer to a C HPy_ssize_t. + * + * ``f (float) [float]`` + * Convert a Python floating point number to a C float. + * + * ``d (float) [double]`` * Convert a Python floating point number to a C double. * - * Handles - * ------- + * Handles (Python Objects) + * ~~~~~~~~~~~~~~~~~~~~~~~~ * - * O (object) [HPy *] - * Returns an existing handle. Not supported by HPyArg_ParseKeywords as - * retrieving an item from the keywords dictionary would require creating - * a new handled. Use O+ instead for this case. + * ``O (object) [HPy]`` + * Store a handle pointing to a generic Python object. * - * O+ (object) [HPy *] - * Returns a new handle. The new handle must be closed if the argument - * parsing returns successfully. + * When using O with HPyArg_ParseKeywords, an HPyTracker is created and + * returned via the parameter `ht`. If HPyArg_ParseKeywords returns + * successfully, you must call HPyTracker_Close on `ht` once the + * returned handles are no longer needed. This will close all the handles + * created during argument parsing. There is no need to call + * `HPyTracker_Close` on failure -- the argument parser does this for you. + * + * Miscellaneous + * ~~~~~~~~~~~~~ + * + * ``p (bool) [int]`` + * Tests the value passed in for truth (a boolean predicate) and converts + * the result to its equivalent C true/false integer value. Sets the int to + * 1 if the expression was true and 0 if it was false. This accepts any + * valid Python value. See + * `Truth Value Testing `_ + * for more information about how Python tests values for truth. * * Options - * ------- + * ~~~~~~~ * - * | + * ``|`` * Indicates that the remaining arguments in the argument list are optional. * The C variables corresponding to optional arguments should be initialized * to their default value — when an optional argument is not specified, the * contents of the corresponding C variable is not modified. * - * $ + * ``$`` * HPyArg_ParseKeywords() only: Indicates that the remaining arguments in * the argument list are keyword-only. Currently, all keyword-only arguments * must also be optional arguments, so | must always be specified before $ * in the format string. * - * : + * ``:`` * The list of format units ends here; the string after the colon is used as * the function name in error messages. : and ; are mutually exclusive and * whichever occurs first takes precedence. * - * ; + * ``;`` * The list of format units ends here; the string after the semicolon is * used as the error message instead of the default error message. : and ; * are mutually exclusive and whichever occurs first takes precedence. * + * API + * --- + * */ +#include #include #include "hpy.h" @@ -94,25 +141,110 @@ set_error(HPyContext ctx, HPy exc, const char *err_fmt, const char *msg) { snprintf(err_buf, _ERR_STRING_MAX_LENGTH, "%.200s() %.256s", err_fmt + 1, msg); } else { - snprintf(err_buf, _ERR_STRING_MAX_LENGTH, "%s", err_fmt + 1); + snprintf(err_buf, _ERR_STRING_MAX_LENGTH, "%s", err_fmt + 1); } HPyErr_SetString(ctx, exc, err_buf); } static int -parse_item(HPyContext ctx, HPy current_arg, const char **fmt, va_list *vl, const char *err_fmt) +parse_item(HPyContext ctx, HPyTracker *ht, HPy current_arg, int current_arg_tmp, const char **fmt, va_list *vl, const char *err_fmt) { switch (*(*fmt)++) { - case 'i': { + + case 'b': { /* unsigned byte -- very short int */ + char *output = va_arg(*vl, char *); + _BREAK_IF_OPTIONAL(current_arg); + long value = HPyLong_AsLong(ctx, current_arg); + if (value == -1 && HPyErr_Occurred(ctx)) + return 0; + if (value < 0) { + set_error(ctx, ctx->h_OverflowError, err_fmt, + "unsigned byte integer is less than minimum"); + return 0; + } + if (value > UCHAR_MAX) { + set_error(ctx, ctx->h_OverflowError, err_fmt, + "unsigned byte integer is greater than maximum"); + return 0; + } + *output = (char) value; + break; + } + + case 'B': { /* byte sized bitfield - both signed and unsigned + values allowed */ + char *output = va_arg(*vl, char *); + _BREAK_IF_OPTIONAL(current_arg); + unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); + if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) + return 0; + *output = (unsigned char) value; + break; + } + + case 'h': { /* signed short int */ + short *output = va_arg(*vl, short *); + _BREAK_IF_OPTIONAL(current_arg); + long value = HPyLong_AsLong(ctx, current_arg); + if (value == -1 && HPyErr_Occurred(ctx)) + return 0; + if (value < SHRT_MIN) { + set_error(ctx, ctx->h_OverflowError, err_fmt, + "signed short integer is less than minimum"); + return 0; + } + if (value > SHRT_MAX) { + set_error(ctx, ctx->h_OverflowError, err_fmt, + "signed short integer is greater than maximum"); + return 0; + } + *output = (short) value; + break; + } + + case 'H': { /* short int sized bitfield, both signed and + unsigned allowed */ + unsigned short *output = va_arg(*vl, unsigned short *); + _BREAK_IF_OPTIONAL(current_arg); + unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); + if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) + return 0; + *output = (unsigned short) value; + break; + } + + case 'i': { /* signed int */ int *output = va_arg(*vl, int *); _BREAK_IF_OPTIONAL(current_arg); long value = HPyLong_AsLong(ctx, current_arg); if (value == -1 && HPyErr_Occurred(ctx)) return 0; + if (value > INT_MAX) { + set_error(ctx, ctx->h_OverflowError, err_fmt, + "signed integer is greater than maximum"); + return 0; + } + if (value < INT_MIN) { + set_error(ctx, ctx->h_OverflowError, err_fmt, + "signed integer is less than minimum"); + return 0; + } *output = (int)value; break; } + + case 'I': { /* int sized bitfield, both signed and + unsigned allowed */ + unsigned int *output = va_arg(*vl, unsigned int *); + _BREAK_IF_OPTIONAL(current_arg); + unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); + if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) + return 0; + *output = (unsigned int) value; + break; + } + case 'l': { long *output = va_arg(*vl, long *); _BREAK_IF_OPTIONAL(current_arg); @@ -122,7 +254,58 @@ parse_item(HPyContext ctx, HPy current_arg, const char **fmt, va_list *vl, const *output = value; break; } - case 'd': { + + case 'k': { /* long sized bitfield */ + unsigned long *output = va_arg(*vl, unsigned long *); + _BREAK_IF_OPTIONAL(current_arg); + unsigned long value = HPyLong_AsUnsignedLongMask(ctx, current_arg); + if (value == (unsigned long)-1 && HPyErr_Occurred(ctx)) + return 0; + *output = value; + break; + } + + case 'L': { /* long long */ + long long *output = va_arg(*vl, long long *); + _BREAK_IF_OPTIONAL(current_arg); + long long value = HPyLong_AsLongLong(ctx, current_arg); + if (value == (long long)-1 && HPyErr_Occurred(ctx)) + return 0; + *output = value; + break; + } + + case 'K': { /* long long sized bitfield */ + unsigned long long *output = va_arg(*vl, unsigned long long *); + _BREAK_IF_OPTIONAL(current_arg); + unsigned long long value = HPyLong_AsUnsignedLongLongMask(ctx, current_arg); + if (value == (unsigned long long)-1 && HPyErr_Occurred(ctx)) + return 0; + *output = value; + break; + } + + case 'n': { /* HPy_ssize_t */ + HPy_ssize_t *output = va_arg(*vl, HPy_ssize_t *); + _BREAK_IF_OPTIONAL(current_arg); + HPy_ssize_t value = HPyLong_AsSsize_t(ctx, current_arg); + if (value == (HPy_ssize_t)-1 && HPyErr_Occurred(ctx)) + return 0; + *output = value; + break; + } + + case 'f': { /* float */ + float *output = va_arg(*vl, float *); + _BREAK_IF_OPTIONAL(current_arg); + double value = HPyFloat_AsDouble(ctx, current_arg); + if (value == -1.0 && HPyErr_Occurred(ctx)) + return 0; + *output = (float) value; + break; + } + + case 'd': { /* double */ double* output = va_arg(*vl, double *); _BREAK_IF_OPTIONAL(current_arg); double value = HPyFloat_AsDouble(ctx, current_arg); @@ -131,33 +314,99 @@ parse_item(HPyContext ctx, HPy current_arg, const char **fmt, va_list *vl, const *output = value; break; } + case 'O': { - if (**fmt == '+') { - (*fmt)++; - HPy *output = va_arg(*vl, HPy *); - _BREAK_IF_OPTIONAL(current_arg); + HPy *output = va_arg(*vl, HPy *); + _BREAK_IF_OPTIONAL(current_arg); + if (current_arg_tmp) { *output = HPy_Dup(ctx, current_arg); - if (HPy_IsNull(*output)) - return 0; - break; + HPyTracker_Add(ctx, *ht, *output); } else { - HPy *output = va_arg(*vl, HPy *); - _BREAK_IF_OPTIONAL(current_arg); *output = current_arg; } break; } + + case 'p': { /* boolean *p*redicate */ + int *output = va_arg(*vl, int *); + int value = HPy_IsTrue(ctx, current_arg); + if (value < 0) + return 0; + *output = (value > 0) ? 1 : 0; + break; + } + default: set_error(ctx, ctx->h_SystemError, err_fmt, "unknown arg format code"); return 0; } + return 1; } +/** + * Parse positional arguments. + * + * :param ctx: + * The execution context. + * :param ht: + * An optional pointer to an HPyTracker. If the format string never + * results in new handles being created, `ht` may be `NULL`. Currently + * no formatting options to this function require an HPyTracker. + * :param args: + * The array of positional arguments to parse. + * :param nargs: + * The number of elements in args. + * :param fmt: + * The format string to use to parse the arguments. + * :param ...: + * A va_list of references to variables in which to store the parsed + * arguments. The number and types of the arguments should match the + * the format strint, `fmt`. + * + * :returns: 0 on failure, 1 on success. + * + * If a `NULL` pointer is passed to `ht` and an `HPyTracker` is required by + * the format string, an exception will be raised. + * + * If a pointer is provided to `ht`, the `HPyTracker` will always be created + * and must be closed with `HPyTracker_Close` if parsing succeeds (after all + * handles returned are no longer needed). If parsing fails, this function + * will close the `HPyTracker` automatically. + * + * Examples: + * + * Using `HPyArg_Parse` without an `HPyTracker`: + * + * .. code-block:: c + * + * long a, b; + * if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) + * return HPy_NULL; + * ... + * + * Using `HPyArg_Parse` with an `HPyTracker`: + * + * .. code-block:: c + * + * long a, b; + * HPyTracker ht; + * if (!HPyArg_Parse(ctx, &ht, args, nargs, "ll", &a, &b)) + * return HPy_NULL; + * ... + * HPyTracker_Close(ctx, ht); + * ... + * + * .. note:: + * + * Currently `HPyArg_Parse` never requires the use of an `HPyTracker`. + * The option exists only to support releasing temporary storage used by + * future format string codes (e.g. for character strings). + */ HPyAPI_RUNTIME_FUNC(int) -HPyArg_Parse(HPyContext ctx, HPy *args, HPy_ssize_t nargs, const char *fmt, ...) +HPyArg_Parse(HPyContext ctx, HPyTracker *ht, HPy *args, HPy_ssize_t nargs, const char *fmt, ...) { const char *fmt1 = fmt; const char *err_fmt = NULL; @@ -169,6 +418,13 @@ HPyArg_Parse(HPyContext ctx, HPy *args, HPy_ssize_t nargs, const char *fmt, ...) fmt_end = parse_err_fmt(fmt, &err_fmt); + if (ht != NULL) { + *ht = HPyTracker_New(ctx, 0); + if (HPy_IsNull(*ht)) { + return 0; + } + } + va_list vl; va_start(vl, fmt); @@ -183,33 +439,103 @@ HPyArg_Parse(HPyContext ctx, HPy *args, HPy_ssize_t nargs, const char *fmt, ...) current_arg = args[i]; } if (!HPy_IsNull(current_arg) || optional) { - if (!parse_item(ctx, current_arg, &fmt1, &vl, err_fmt)) { - va_end(vl); - return 0; + if (!parse_item(ctx, ht, current_arg, 0, &fmt1, &vl, err_fmt)) { + goto error; } } else { set_error(ctx, ctx->h_TypeError, err_fmt, "required positional argument missing"); - va_end(vl); - return 0; + goto error; } i++; } if (i < nargs) { set_error(ctx, ctx->h_TypeError, err_fmt, "mismatched args (too many arguments for fmt)"); - va_end(vl); - return 0; + goto error; } va_end(vl); return 1; + + error: + va_end(vl); + if (ht != NULL) { + HPyTracker_Close(ctx, *ht); + } + return 0; } +/** + * Parse positional and keyword arguments. + * + * :param ctx: + * The execution context. + * :param ht: + * An optional pointer to an HPyTracker. If the format string never + * results in new handles being created, `ht` may be `NULL`. Currently + * only the `O` formatting option to this function requires an HPyTracker. + * :param args: + * The array of positional arguments to parse. + * :param nargs: + * The number of elements in args. + * :param kw: + * A handle to the dictionary of keyword arguments. + * :param fmt: + * The format string to use to parse the arguments. + * :param keywords: + * An `NULL` terminated array of argument names. The number of names + * should match the format string provided. Positional only arguments + * should have the name `""` (i.e. the null-terminated empty string). + * Positional only arguments must preceded all other arguments. + * :param ...: + * A va_list of references to variables in which to store the parsed + * arguments. The number and types of the arguments should match the + * the format strint, `fmt`. + * + * :returns: 0 on failure, 1 on success. + * + * If a `NULL` pointer is passed to `ht` and an `HPyTracker` is required by + * the format string, an exception will be raised. + * + * If a pointer is provided to `ht`, the `HPyTracker` will always be created + * and must be closed with `HPyTracker_Close` if parsing succeeds (after all + * handles returned are no longer needed). If parsing fails, this function + * will close the `HPyTracker` automatically. + * + * Examples: + * + * Using `HPyArg_ParseKeywords` without an `HPyTracker`: + * + * .. code-block:: c + * + * long a, b; + * if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kw, "ll", &a, &b)) + * return HPy_NULL; + * ... + * + * Using `HPyArg_ParseKeywords` with an `HPyTracker`: + * + * .. code-block:: c + * + * HPy a, b; + * HPyTracker ht; + * if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kw, "OO", &a, &b)) + * return HPy_NULL; + * ... + * HPyTracker_Close(ctx, ht); + * ... + * + * .. note:: + * + * Currently `HPyArg_ParseKeywords` only requires the use of an `HPyTracker` + * when the `O` format is used. In future other new format string codes + * (e.g. for character strings) may also require it. + */ HPyAPI_RUNTIME_FUNC(int) -HPyArg_ParseKeywords(HPyContext ctx, HPy *args, HPy_ssize_t nargs, HPy kw, +HPyArg_ParseKeywords(HPyContext ctx, HPyTracker *ht, HPy *args, HPy_ssize_t nargs, HPy kw, const char *fmt, const char *keywords[], ...) { const char *fmt1 = fmt; @@ -221,6 +547,7 @@ HPyArg_ParseKeywords(HPyContext ctx, HPy *args, HPy_ssize_t nargs, HPy kw, HPy_ssize_t i = 0; HPy_ssize_t nkw = 0; HPy current_arg; + int current_arg_needs_closing = 0; fmt_end = parse_err_fmt(fmt, &err_fmt); @@ -238,6 +565,13 @@ HPyArg_ParseKeywords(HPyContext ctx, HPy *args, HPy_ssize_t nargs, HPy kw, nkw++; } + if (ht != NULL) { + *ht = HPyTracker_New(ctx, 0); + if (HPy_IsNull(*ht)) { + return 0; + } + } + va_list vl; va_start(vl, keywords); @@ -253,59 +587,71 @@ HPyArg_ParseKeywords(HPyContext ctx, HPy *args, HPy_ssize_t nargs, HPy kw, fmt1++; continue; } - if (*fmt1 == 'O' && *(fmt1 + 1) != '+') { + if (*fmt1 == 'O' && ht == NULL) { set_error(ctx, ctx->h_SystemError, err_fmt, - "HPyArg_ParseKeywords cannot use the format character 'O'." - " Use 'O+' instead and close the the returned handle if the call" - " returns successfully"); - va_end(vl); - return 0; + "HPyArg_ParseKeywords cannot use the format character 'O' unless" + " an HPyTracker is provided. Please supply an HPyTracker."); + goto error; } if (i >= nkw) { set_error(ctx, ctx->h_TypeError, err_fmt, "mismatched args (too few keywords for fmt)"); - va_end(vl); - return 0; + goto error; } current_arg = HPy_NULL; if (i < nargs) { if (keyword_only) { set_error(ctx, ctx->h_TypeError, err_fmt, "keyword only argument passed as positional argument"); - va_end(vl); - return 0; + goto error; } current_arg = args[i]; } else if (!HPy_IsNull(kw) && *keywords[i]) { current_arg = HPy_GetItem_s(ctx, kw, keywords[i]); - // Clear any KeyError that was raised. If an error was raised - // current_arg will be HPy_NULL and will be handled appropriately - // below depending on whether the current argument is optional or - // not - HPyErr_Clear(ctx); + // Track the handle or lear any KeyError that was raised. If an + // error was raised current_arg will be HPy_NULL and will be + // handled appropriately below depending on whether the current + // argument is optional or not + if (!HPy_IsNull(current_arg)) { + current_arg_needs_closing = 1; + } + else { + HPyErr_Clear(ctx); + } } if (!HPy_IsNull(current_arg) || optional) { - if (!parse_item(ctx, current_arg, &fmt1, &vl, err_fmt)) { - va_end(vl); - return 0; + if (!parse_item(ctx, ht, current_arg, 1, &fmt1, &vl, err_fmt)) { + goto error; } } else { set_error(ctx, ctx->h_TypeError, err_fmt, "no value for required argument"); - va_end(vl); - return 0; + goto error; + } + if (current_arg_needs_closing) { + HPy_Close(ctx, current_arg); + current_arg_needs_closing = 0; } i++; } if (i != nkw) { set_error(ctx, ctx->h_TypeError, err_fmt, "mismatched args (too many keywords for fmt)"); - va_end(vl); - return 0; + goto error; } va_end(vl); return 1; + + error: + va_end(vl); + if (ht != NULL) { + HPyTracker_Close(ctx, *ht); + } + if (current_arg_needs_closing) { + HPy_Close(ctx, current_arg); + } + return 0; } diff --git a/pypy/module/_hpy_universal/_vendored/hpy/devel/version.py b/pypy/module/_hpy_universal/_vendored/hpy/devel/version.py index 5495e545a3e2aac1b5bf60642daba0db2a1bee21..d8b8f5c099eef140ed9cf08094632b3841d8f37e 100644 --- a/pypy/module/_hpy_universal/_vendored/hpy/devel/version.py +++ b/pypy/module/_hpy_universal/_vendored/hpy/devel/version.py @@ -1,4 +1,4 @@ # automatically generated by setup.py:get_scm_config() -__version__ = "0.1.dev756+g848192d" -__git_revision__ = "848192d" +__version__ = "0.1.dev875+g7c832a2" +__git_revision__ = "7c832a2" diff --git a/pypy/module/_hpy_universal/apiset.py b/pypy/module/_hpy_universal/apiset.py index d37136e449c84fff92ad2a27d8cd92d9911960c8..4c20a0cea82b02fd7a7d3fe52bc3ef0585bcc3c3 100644 --- a/pypy/module/_hpy_universal/apiset.py +++ b/pypy/module/_hpy_universal/apiset.py @@ -139,6 +139,15 @@ class APISet(object): """ return rffi.cast(rffi.INT_real, x) + @staticmethod + def cast(typename, x): + """ + Helper method to convert an RPython value into the correct C return + type. + """ + lltype = llapi.cts.gettype(typename) + return rffi.cast(lltype, x) + @staticmethod def ccharp2text(space, ptr): """ diff --git a/pypy/module/_hpy_universal/bridge.py b/pypy/module/_hpy_universal/bridge.py index 1fda4eb98128919caf89e45f9610103e6547b529..77601373fc76e34e146eb56a15b4dc92d3c40533 100644 --- a/pypy/module/_hpy_universal/bridge.py +++ b/pypy/module/_hpy_universal/bridge.py @@ -35,6 +35,7 @@ typedef struct { void * hpy_err_Occurred_rpy; void * hpy_err_Clear; void * _hpy_err_SetString; + void * _hpy_err_SetObject; } _HPyBridge; """) diff --git a/pypy/module/_hpy_universal/handles.py b/pypy/module/_hpy_universal/handles.py index 4ab12dc3fa44a8e88b3658a07ef40be1d087cad0..8f2a63ffde81fc31b09f8bb1c4b827bcffb1b73c 100644 --- a/pypy/module/_hpy_universal/handles.py +++ b/pypy/module/_hpy_universal/handles.py @@ -4,21 +4,84 @@ from rpython.rlib.unroll import unrolling_iterable CONSTANTS = [ ('NULL', lambda space: None), + # Constants ('None', lambda space: space.w_None), - ('False', lambda space: space.w_False), ('True', lambda space: space.w_True), + ('False', lambda space: space.w_False), + # Exceptions + ('BaseException', lambda space: space.w_BaseException), ('Exception', lambda space: space.w_Exception), - ('ValueError', lambda space: space.w_ValueError), - ('TypeError', lambda space: space.w_TypeError), + ('StopAsyncIteration', lambda space: space.w_StopAsyncIteration), + ('StopIteration', lambda space: space.w_StopIteration), + ('GeneratorExit', lambda space: space.w_GeneratorExit), + ('ArithmeticError', lambda space: space.w_ArithmeticError), + ('LookupError', lambda space: space.w_LookupError), + ('AssertionError', lambda space: space.w_AssertionError), + ('AttributeError', lambda space: space.w_AttributeError), + ('BufferError', lambda space: space.w_BufferError), + ('EOFError', lambda space: space.w_EOFError), + ('FloatingPointError', lambda space: space.w_FloatingPointError), + ('OSError', lambda space: space.w_OSError), + ('ImportError', lambda space: space.w_ImportError), + ('ModuleNotFoundError', lambda space: space.w_ModuleNotFoundError), ('IndexError', lambda space: space.w_IndexError), + ('KeyError', lambda space: space.w_KeyError), + ('KeyboardInterrupt', lambda space: space.w_KeyboardInterrupt), + ('MemoryError', lambda space: space.w_MemoryError), + ('NameError', lambda space: space.w_NameError), + ('OverflowError', lambda space: space.w_OverflowError), + ('RuntimeError', lambda space: space.w_RuntimeError), + ('RecursionError', lambda space: space.w_RecursionError), + ('NotImplementedError', lambda space: space.w_NotImplementedError), + ('SyntaxError', lambda space: space.w_SyntaxError), + ('IndentationError', lambda space: space.w_IndentationError), + ('TabError', lambda space: space.w_TabError), + ('ReferenceError', lambda space: space.w_ReferenceError), ('SystemError', lambda space: space.w_SystemError), + ('SystemExit', lambda space: space.w_SystemExit), + ('TypeError', lambda space: space.w_TypeError), + ('UnboundLocalError', lambda space: space.w_UnboundLocalError), + ('UnicodeError', lambda space: space.w_UnicodeError), + ('UnicodeEncodeError', lambda space: space.w_UnicodeEncodeError), + ('UnicodeDecodeError', lambda space: space.w_UnicodeDecodeError), + ('UnicodeTranslateError', lambda space: space.w_UnicodeTranslateError), + ('ValueError', lambda space: space.w_ValueError), + ('ZeroDivisionError', lambda space: space.w_ZeroDivisionError), + ('BlockingIOError', lambda space: space.w_BlockingIOError), + ('BrokenPipeError', lambda space: space.w_BrokenPipeError), + ('ChildProcessError', lambda space: space.w_ChildProcessError), + ('ConnectionError', lambda space: space.w_ConnectionError), + ('ConnectionAbortedError', lambda space: space.w_ConnectionAbortedError), + ('ConnectionRefusedError', lambda space: space.w_ConnectionRefusedError), + ('ConnectionResetError', lambda space: space.w_ConnectionResetError), + ('FileExistsError', lambda space: space.w_FileExistsError), + ('FileNotFoundError', lambda space: space.w_FileNotFoundError), + ('InterruptedError', lambda space: space.w_InterruptedError), + ('IsADirectoryError', lambda space: space.w_IsADirectoryError), + ('NotADirectoryError', lambda space: space.w_NotADirectoryError), + ('PermissionError', lambda space: space.w_PermissionError), + ('ProcessLookupError', lambda space: space.w_ProcessLookupError), + ('TimeoutError', lambda space: space.w_TimeoutError), + # Warnings + ('Warning', lambda space: space.w_Warning), + ('UserWarning', lambda space: space.w_UserWarning), + ('DeprecationWarning', lambda space: space.w_DeprecationWarning), + ('PendingDeprecationWarning', lambda space: space.w_PendingDeprecationWarning), + ('SyntaxWarning', lambda space: space.w_SyntaxWarning), + ('RuntimeWarning', lambda space: space.w_RuntimeWarning), + ('FutureWarning', lambda space: space.w_FutureWarning), + ('ImportWarning', lambda space: space.w_ImportWarning), + ('UnicodeWarning', lambda space: space.w_UnicodeWarning), + ('BytesWarning', lambda space: space.w_BytesWarning), + ('ResourceWarning', lambda space: space.w_ResourceWarning), + # Types ('BaseObjectType', lambda space: space.w_object), ('TypeType', lambda space: space.w_type), ('LongType', lambda space: space.w_int), ('UnicodeType', lambda space: space.w_unicode), ('TupleType', lambda space: space.w_tuple), ('ListType', lambda space: space.w_list), - ] +] class HandleManager: diff --git a/pypy/module/_hpy_universal/interp_bytes.py b/pypy/module/_hpy_universal/interp_bytes.py index ab72270527fdc7ebf28d672f042ded9d7b6224e2..4e0292f763ac885291d6b958ddca53e7c63dc564 100644 --- a/pypy/module/_hpy_universal/interp_bytes.py +++ b/pypy/module/_hpy_universal/interp_bytes.py @@ -30,7 +30,23 @@ def HPyBytes_AsString(space, ctx, h): handles.attach_release_callback(space, h, cb) return llbuf - @API.func("char *HPyBytes_AS_STRING(HPyContext ctx, HPy h)") def HPyBytes_AS_STRING(space, ctx, h): return HPyBytes_AsString(space, ctx, h) + +@API.func("HPy HPyBytes_FromString(HPyContext ctx, const char *v)") +def HPyBytes_FromString(space, ctx, char_p): + s = rffi.constcharp2str(char_p) + w_bytes = space.newbytes(s) + return handles.new(space, w_bytes) + +@API.func("HPy HPyBytes_FromStringAndSize(HPyContext ctx, const char *v, HPy_ssize_t len)") +def HPyBytes_FromStringAndSize(space, ctx, char_p, length): + if not char_p: + raise oefmt( + space.w_ValueError, + "NULL char * passed to HPyBytes_FromStringAndSize" + ) + s = rffi.constcharpsize2str(char_p, length) + w_bytes = space.newbytes(s) + return handles.new(space, w_bytes) diff --git a/pypy/module/_hpy_universal/interp_err.py b/pypy/module/_hpy_universal/interp_err.py index 0f0bcd80d68e2807343fce5b8a3745613240ab7f..fc431ed896eb5234325bc8ef4e5da6e88ecf3c75 100644 --- a/pypy/module/_hpy_universal/interp_err.py +++ b/pypy/module/_hpy_universal/interp_err.py @@ -43,6 +43,11 @@ def _hpy_err_SetString(space, ctx, h_exc_type, utf8): w_exc_type = handles.deref(space, h_exc_type) raise OperationError(w_exc_type, w_obj) +@BRIDGE.func("void _hpy_err_SetObject(HPyContext ctx, HPy type, HPy value)") +def _hpy_err_SetObject(space, ctx, h_exc_type, h_exc_value): + w_exc_type = handles.deref(space, h_exc_type) + w_obj = handles.deref(space, h_exc_value) + raise OperationError(w_exc_type, w_obj) @BRIDGE.func("int hpy_err_Occurred_rpy(void)", error_value=API.int(-1)) def hpy_err_Occurred_rpy(space): @@ -80,5 +85,3 @@ def HPyErr_NoMemory(space, ctx): if NonConstant(False): return -42 raise OperationError(space.w_MemoryError, space.w_None) - - diff --git a/pypy/module/_hpy_universal/interp_long.py b/pypy/module/_hpy_universal/interp_long.py index 4ce479b84b82a037c2d696a2779350b59860944e..e1d2f14033f419ebaf6d4fd1d36a0ddd40d97540 100644 --- a/pypy/module/_hpy_universal/interp_long.py +++ b/pypy/module/_hpy_universal/interp_long.py @@ -36,12 +36,67 @@ def HPyLong_FromSsize_t(space, ctx, v): w_obj = space.newlong_from_rarith_int(v) return handles.new(space, w_obj) -@API.func("long HPyLong_AsLong(HPyContext ctx, HPy h)", error_value=-1) +@API.func("long HPyLong_AsLong(HPyContext ctx, HPy h)", + error_value=API.cast("long", -1)) def HPyLong_AsLong(space, ctx, h): - w_obj = handles.deref(space, h) - #w_obj = space.int(w_obj) --- XXX write a test for this - value = space.int_w(w_obj) - result = rffi.cast(rffi.LONG, value) - #if rffi.cast(lltype.Signed, result) != value: --- XXX on Windows 64 - # ... - return result + w_long = handles.deref(space, h) + return space.int_w(space.int(w_long)) + +@API.func("unsigned long HPyLong_AsUnsignedLong(HPyContext ctx, HPy h)", + error_value=API.cast("unsigned long", -1)) +def HPyLong_AsUnsignedLong(space, ctx, h): + w_long = handles.deref(space, h) + try: + return rffi.cast(rffi.ULONG, space.uint_w(w_long)) + except OperationError as e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise + +@API.func("unsigned long HPyLong_AsUnsignedLongMask(HPyContext ctx, HPy h)", + error_value=API.cast("unsigned long", -1)) +def HPyLong_AsUnsignedLongMask(space, ctx, h): + w_long = handles.deref(space, h) + num = space.bigint_w(w_long) + return num.uintmask() + +@API.func("long long HPyLong_AsLongLong(HPyContext ctx, HPy h)", + error_value=API.cast("long long", -1)) +def HPyLong_AsLongLong(space, ctx, h): + w_long = handles.deref(space, h) + return rffi.cast(rffi.LONGLONG, space.r_longlong_w(w_long)) + +@API.func("unsigned long long HPyLong_AsUnsignedLongLong(HPyContext ctx, HPy h)", + error_value=API.cast("unsigned long long", -1)) +def HPyLong_AsUnsignedLongLong(space, ctx, h): + w_long = handles.deref(space, h) + try: + return rffi.cast(rffi.ULONGLONG, space.r_ulonglong_w(w_long)) + except OperationError as e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise + +@API.func("unsigned long long HPyLong_AsUnsignedLongLongMask(HPyContext ctx, HPy h)", + error_value=API.cast("unsigned long long", -1)) +def HPyLong_AsUnsignedLongLongMask(space, ctx, h): + w_long = handles.deref(space, h) + num = space.bigint_w(w_long) + return num.ulonglongmask() + +@API.func("size_t HPyLong_AsSize_t(HPyContext ctx, HPy h)", + error_value=API.cast("size_t", -1)) +def HPyLong_AsSize_t(space, ctx, h): + w_long = handles.deref(space, h) + try: + return space.uint_w(w_long) + except OperationError as e: + if e.match(space, space.w_ValueError): + e.w_type = space.w_OverflowError + raise + +@API.func("HPy_ssize_t HPyLong_AsSsize_t(HPyContext ctx, HPy h)", + error_value=API.cast("ssize_t", -1)) +def HPyLong_AsSsize_t(space, ctx, h): + w_long = handles.deref(space, h) + return space.int_w(w_long) diff --git a/pypy/module/_hpy_universal/llapi.py b/pypy/module/_hpy_universal/llapi.py index ae7d1af6cbdbc57e16450da76e4e81afa6ded8a2..42cb53e90e3e14d932d528654acf75f0c670bb0f 100644 --- a/pypy/module/_hpy_universal/llapi.py +++ b/pypy/module/_hpy_universal/llapi.py @@ -58,20 +58,84 @@ typedef HPy_ssize_t HPyTracker; struct _HPyContext_s { int ctx_version; + // Constants struct _HPy_s h_None; struct _HPy_s h_True; struct _HPy_s h_False; + // Exceptions + struct _HPy_s h_BaseException; struct _HPy_s h_Exception; - struct _HPy_s h_ValueError; - struct _HPy_s h_TypeError; + struct _HPy_s h_StopAsyncIteration; + struct _HPy_s h_StopIteration; + struct _HPy_s h_GeneratorExit; + struct _HPy_s h_ArithmeticError; + struct _HPy_s h_LookupError; + struct _HPy_s h_AssertionError; + struct _HPy_s h_AttributeError; + struct _HPy_s h_BufferError; + struct _HPy_s h_EOFError; + struct _HPy_s h_FloatingPointError; + struct _HPy_s h_OSError; + struct _HPy_s h_ImportError; + struct _HPy_s h_ModuleNotFoundError; struct _HPy_s h_IndexError; + struct _HPy_s h_KeyError; + struct _HPy_s h_KeyboardInterrupt; + struct _HPy_s h_MemoryError; + struct _HPy_s h_NameError; + struct _HPy_s h_OverflowError; + struct _HPy_s h_RuntimeError; + struct _HPy_s h_RecursionError; + struct _HPy_s h_NotImplementedError; + struct _HPy_s h_SyntaxError; + struct _HPy_s h_IndentationError; + struct _HPy_s h_TabError; + struct _HPy_s h_ReferenceError; struct _HPy_s h_SystemError; + struct _HPy_s h_SystemExit; + struct _HPy_s h_TypeError; + struct _HPy_s h_UnboundLocalError; + struct _HPy_s h_UnicodeError; + struct _HPy_s h_UnicodeEncodeError; + struct _HPy_s h_UnicodeDecodeError; + struct _HPy_s h_UnicodeTranslateError; + struct _HPy_s h_ValueError; + struct _HPy_s h_ZeroDivisionError; + struct _HPy_s h_BlockingIOError; + struct _HPy_s h_BrokenPipeError; + struct _HPy_s h_ChildProcessError; + struct _HPy_s h_ConnectionError; + struct _HPy_s h_ConnectionAbortedError; + struct _HPy_s h_ConnectionRefusedError; + struct _HPy_s h_ConnectionResetError; + struct _HPy_s h_FileExistsError; + struct _HPy_s h_FileNotFoundError; + struct _HPy_s h_InterruptedError; + struct _HPy_s h_IsADirectoryError; + struct _HPy_s h_NotADirectoryError; + struct _HPy_s h_PermissionError; + struct _HPy_s h_ProcessLookupError; + struct _HPy_s h_TimeoutError; + // Warnings + struct _HPy_s h_Warning; + struct _HPy_s h_UserWarning; + struct _HPy_s h_DeprecationWarning; + struct _HPy_s h_PendingDeprecationWarning; + struct _HPy_s h_SyntaxWarning; + struct _HPy_s h_RuntimeWarning; + struct _HPy_s h_FutureWarning; + struct _HPy_s h_ImportWarning; + struct _HPy_s h_UnicodeWarning; + struct _HPy_s h_BytesWarning; + struct _HPy_s h_ResourceWarning; + // Types struct _HPy_s h_BaseObjectType; struct _HPy_s h_TypeType; struct _HPy_s h_LongType; struct _HPy_s h_UnicodeType; struct _HPy_s h_TupleType; struct _HPy_s h_ListType; + // Context void * ctx_Module_Create; void * ctx_Dup; void * ctx_Close; @@ -82,6 +146,13 @@ struct _HPyContext_s { void * ctx_Long_FromSize_t; void * ctx_Long_FromSsize_t; void * ctx_Long_AsLong; + void * ctx_Long_AsUnsignedLong; + void * ctx_Long_AsUnsignedLongMask; + void * ctx_Long_AsLongLong; + void * ctx_Long_AsUnsignedLongLong; + void * ctx_Long_AsUnsignedLongLongMask; + void * ctx_Long_AsSize_t; + void * ctx_Long_AsSsize_t; void * ctx_Float_FromDouble; void * ctx_Float_AsDouble; void * ctx_Length; @@ -121,6 +192,7 @@ struct _HPyContext_s { void * ctx_InPlaceXor; void * ctx_InPlaceOr; void * ctx_Err_SetString; + void * ctx_Err_SetObject; void * ctx_Err_Occurred; void * ctx_Err_NoMemory; void * ctx_Err_Clear; @@ -153,6 +225,8 @@ struct _HPyContext_s { void * ctx_Bytes_GET_SIZE; void * ctx_Bytes_AsString; void * ctx_Bytes_AS_STRING; + void * ctx_Bytes_FromString; + void * ctx_Bytes_FromStringAndSize; void * ctx_Unicode_FromString; void * ctx_Unicode_Check; void * ctx_Unicode_AsUTF8String; @@ -432,6 +506,11 @@ pypy_HPyErr_SetString = rffi.llexternal('pypy_HPyErr_SetString', lltype.Void, compilation_info=eci, _nowrapper=True) +pypy_HPyErr_SetObject = rffi.llexternal('pypy_HPyErr_SetObject', + [HPyContext, HPy, HPy], + lltype.Void, + compilation_info=eci, _nowrapper=True) + pypy_HPyErr_Clear = rffi.llexternal('pypy_HPyErr_Clear', [HPyContext], lltype.Void, diff --git a/pypy/module/_hpy_universal/src/bridge.h b/pypy/module/_hpy_universal/src/bridge.h index a40e3b466db9f33753e040faaa819cff2825960e..276b3a300b7ef2feb3ad0cfbe2634d2b43d20749 100644 --- a/pypy/module/_hpy_universal/src/bridge.h +++ b/pypy/module/_hpy_universal/src/bridge.h @@ -27,11 +27,13 @@ #define hpy_err_Occurred_rpy() (hpy_get_bridge()->hpy_err_Occurred_rpy()) #define hpy_err_Clear() (hpy_get_bridge()->hpy_err_Clear()) #define hpy_err_SetString(a, b, c) (hpy_get_bridge()->_hpy_err_SetString(a, b, c)) +#define hpy_err_SetObject(a, b, c) (hpy_get_bridge()->_hpy_err_SetObject(a, b, c)) typedef struct { int (*hpy_err_Occurred_rpy)(void); void (*hpy_err_Clear)(void); void (*_hpy_err_SetString)(HPyContext ctx, HPy type, const char* message); + void (*_hpy_err_SetObject)(HPyContext ctx, HPy type, HPy value); } _HPyBridge; @@ -46,10 +48,12 @@ RPY_EXTERN _HPyBridge *hpy_get_bridge(void); // see the comment above for why we need this macro #define hpy_err_SetString(ctx, type, message) (_hpy_err_SetString(ctx, type._i, message)) +#define hpy_err_SetObject(ctx, type, value) (_hpy_err_SetObject(ctx, type._i, value._i)) int hpy_err_Occurred_rpy(void); void hpy_err_Clear(void); void _hpy_err_SetString(HPyContext ctx, HPy_ssize_t type, const char *message); +void _hpy_err_SetObject(HPyContext ctx, HPy_ssize_t type, HPy_ssize_t value); #endif /* RPYTHON_LL2CTYPES */ diff --git a/pypy/module/_hpy_universal/src/hpyerr.c b/pypy/module/_hpy_universal/src/hpyerr.c index c7161c708c90737b88822bde2df08881b24a1b3a..3aa76c9802a90888848d6019f4b4fc605122e830 100644 --- a/pypy/module/_hpy_universal/src/hpyerr.c +++ b/pypy/module/_hpy_universal/src/hpyerr.c @@ -35,6 +35,18 @@ void pypy_HPyErr_SetString(HPyContext ctx, HPy type, const char *message) hpy_err_SetString(ctx, type, message); } +void pypy_HPyErr_SetObject(HPyContext ctx, HPy type, HPy value) +{ + #ifndef RPYTHON_LL2CTYPES /* after translation */ + // it is allowed to call this function with an exception set: for now, we + // just ensure that the exception is cleared before setting it again in + // hpy_err_SetString. In the future, we might have to add some logic for + // chaining exceptions. + RPyClearException(); + #endif + hpy_err_SetObject(ctx, type, value); +} + void pypy_HPyErr_Clear(HPyContext ctx) { #ifdef RPYTHON_LL2CTYPES diff --git a/pypy/module/_hpy_universal/src/hpyerr.h b/pypy/module/_hpy_universal/src/hpyerr.h index f0ff1bc6af59ee26038e664e24b60b7ead69fb13..61e97652403b3aa27cddd0935ada83ff9a815e02 100644 --- a/pypy/module/_hpy_universal/src/hpyerr.h +++ b/pypy/module/_hpy_universal/src/hpyerr.h @@ -3,4 +3,5 @@ RPY_EXTERN int pypy_HPyErr_Occurred(HPyContext ctx); RPY_EXTERN void pypy_HPyErr_SetString(HPyContext ctx, HPy type, const char *message); +RPY_EXTERN void pypy_HPyErr_SetObject(HPyContext ctx, HPy type, HPy value); RPY_EXTERN void pypy_HPyErr_Clear(HPyContext ctx); diff --git a/pypy/module/_hpy_universal/state.py b/pypy/module/_hpy_universal/state.py index cee76e4242b46a1c7f01a478171d008d79f6faed..7639f175cc937574c8cb52d7486c6a474a391e96 100644 --- a/pypy/module/_hpy_universal/state.py +++ b/pypy/module/_hpy_universal/state.py @@ -68,6 +68,7 @@ class State: self.ctx.c_ctx_Err_Occurred = rffi.cast(rffi.VOIDP, llapi.pypy_HPyErr_Occurred) self.ctx.c_ctx_Err_SetString = rffi.cast(rffi.VOIDP, llapi.pypy_HPyErr_SetString) + self.ctx.c_ctx_Err_SetObject = rffi.cast(rffi.VOIDP, llapi.pypy_HPyErr_SetObject) self.ctx.c_ctx_Err_Clear = rffi.cast(rffi.VOIDP, llapi.pypy_HPyErr_Clear) def setup_bridge(self): diff --git a/pypy/module/_hpy_universal/test/_vendored/test_argparse.py b/pypy/module/_hpy_universal/test/_vendored/test_argparse.py index f4e409a9d06b33ef1b54f7145989ed53ca599330..a3ce33b61bc43f9662cbd9c092c251b7310c5752 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_argparse.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_argparse.py @@ -12,12 +12,17 @@ from .support import HPyTest class TestParseItem(HPyTest): def make_parse_item(self, fmt, type, hpy_converter): mod = self.make_module(""" + __attribute__((unused)) static inline + HPy char_to_hpybytes(HPyContext ctx, char a) {{ + return HPyBytes_FromStringAndSize(ctx, &a, 1); + }} + HPyDef_METH(f, "f", f_impl, HPyFunc_VARARGS) static HPy f_impl(HPyContext ctx, HPy self, HPy *args, HPy_ssize_t nargs) {{ {type} a; - if (!HPyArg_Parse(ctx, args, nargs, "{fmt}", &a)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "{fmt}", &a)) return HPy_NULL; return {hpy_converter}(ctx, a); }} @@ -26,31 +31,237 @@ class TestParseItem(HPyTest): """.format(fmt=fmt, type=type, hpy_converter=hpy_converter)) return mod + def test_b(self): + import pytest + mod = self.make_parse_item("b", "char", "char_to_hpybytes") + assert mod.f(0) == b"\x00" + assert mod.f(1) == b"\x01" + assert mod.f(255) == b"\xff" + with pytest.raises(OverflowError) as err: + mod.f(256) + assert str(err.value) == ( + "function unsigned byte integer is greater than maximum" + ) + with pytest.raises(OverflowError) as err: + mod.f(-1) + assert str(err.value) == ( + "function unsigned byte integer is less than minimum" + ) + + def test_B(self): + mod = self.make_parse_item("B", "char", "char_to_hpybytes") + assert mod.f(0) == b"\x00" + assert mod.f(1) == b"\x01" + assert mod.f(2**8 - 1) == b"\xff" + assert mod.f(2**8) == b"\x00" + assert mod.f(-1) == b"\xff" + + def test_h(self): + import pytest + mod = self.make_parse_item("h", "short", "HPyLong_FromLong") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == -1 + assert mod.f(2**15 - 1) == 2**15 - 1 + assert mod.f(-2**15) == -2**15 + with pytest.raises(OverflowError) as err: + mod.f(2**15) + assert str(err.value) == ( + "function signed short integer is greater than maximum" + ) + with pytest.raises(OverflowError) as err: + mod.f(-2**15 - 1) + assert str(err.value) == ( + "function signed short integer is less than minimum" + ) + + def test_H_short(self): + mod = self.make_parse_item("H", "short", "HPyLong_FromLong") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == -1 + assert mod.f(2**15 - 1) == 2**15 - 1 + assert mod.f(-2**15) == -2**15 + assert mod.f(2**16 - 1) == -1 + assert mod.f(-2**16 + 1) == 1 + assert mod.f(2**16) == 0 + assert mod.f(-2**16) == 0 + + def test_H_unsigned_short(self): + mod = self.make_parse_item( + "H", "unsigned short", "HPyLong_FromUnsignedLong" + ) + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == 2**16 - 1 + assert mod.f(2**16 - 1) == 2**16 - 1 + assert mod.f(-2**16 + 1) == 1 + assert mod.f(2**16) == 0 + assert mod.f(-2**16) == 0 + def test_i(self): + import pytest mod = self.make_parse_item("i", "int", "HPyLong_FromLong") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == -1 + assert mod.f(2**31 - 1) == 2**31 - 1 + assert mod.f(-2**31) == -2**31 + with pytest.raises(OverflowError) as err: + mod.f(2**31) + assert str(err.value) == ( + "function signed integer is greater than maximum" + ) + with pytest.raises(OverflowError) as err: + mod.f(-2**31 - 1) + assert str(err.value) == ( + "function signed integer is less than minimum" + ) + + def test_I_signed(self): + mod = self.make_parse_item("I", "int", "HPyLong_FromLong") + assert mod.f(0) == 0 assert mod.f(1) == 1 - assert mod.f(-2) == -2 + assert mod.f(-1) == -1 + assert mod.f(2**31 - 1) == 2**31 - 1 + assert mod.f(-2**31) == -2**31 + assert mod.f(2**32 - 1) == -1 + assert mod.f(-2**32 + 1) == 1 + assert mod.f(2**32) == 0 + assert mod.f(-2**32) == 0 + + def test_I_unsigned(self): + mod = self.make_parse_item( + "I", "unsigned int", "HPyLong_FromUnsignedLong" + ) + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == 2**32 - 1 + assert mod.f(2**32 - 1) == 2**32 - 1 + assert mod.f(-2**32 + 1) == 1 + assert mod.f(2**32) == 0 + assert mod.f(-2**32) == 0 def test_l(self): + import pytest mod = self.make_parse_item("l", "long", "HPyLong_FromLong") + assert mod.f(0) == 0 assert mod.f(1) == 1 - assert mod.f(-2) == -2 + assert mod.f(-1) == -1 + assert mod.f(2**63 - 1) == 2**63 - 1 + assert mod.f(-2**63) == -2**63 + with pytest.raises(OverflowError): + mod.f(2**63) + with pytest.raises(OverflowError): + mod.f(-2**63 - 1) + + def test_k_signed(self): + mod = self.make_parse_item("k", "long", "HPyLong_FromLong") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == -1 + assert mod.f(2**63 - 1) == 2**63 - 1 + assert mod.f(-2**63) == -2**63 + assert mod.f(2**64 - 1) == -1 + assert mod.f(-2**64 + 1) == 1 + assert mod.f(2**64) == 0 + assert mod.f(-2**64) == 0 + + def test_k_unsigned(self): + mod = self.make_parse_item( + "k", "unsigned long", "HPyLong_FromUnsignedLong" + ) + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == 2**64 - 1 + assert mod.f(2**64 - 1) == 2**64 - 1 + assert mod.f(-2**64 + 1) == 1 + assert mod.f(2**64) == 0 + assert mod.f(-2**64) == 0 + + def test_L(self): + import pytest + mod = self.make_parse_item("L", "long long", "HPyLong_FromLongLong") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == -1 + assert mod.f(2**63 - 1) == 2**63 - 1 + assert mod.f(-2**63) == -2**63 + with pytest.raises(OverflowError): + mod.f(2**63) + with pytest.raises(OverflowError): + mod.f(-2**63 - 1) + + def test_K_signed(self): + mod = self.make_parse_item("k", "long long", "HPyLong_FromLongLong") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == -1 + assert mod.f(2**63 - 1) == 2**63 - 1 + assert mod.f(-2**63) == -2**63 + assert mod.f(2**64 - 1) == -1 + assert mod.f(-2**64 + 1) == 1 + assert mod.f(2**64) == 0 + assert mod.f(-2**64) == 0 + + def test_K_unsigned(self): + mod = self.make_parse_item( + "k", "unsigned long long", "HPyLong_FromUnsignedLongLong" + ) + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == 2**64 - 1 + assert mod.f(2**64 - 1) == 2**64 - 1 + assert mod.f(-2**64 + 1) == 1 + assert mod.f(2**64) == 0 + assert mod.f(-2**64) == 0 + + def test_n(self): + import pytest + mod = self.make_parse_item("n", "HPy_ssize_t", "HPyLong_FromSsize_t") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == -1 + assert mod.f(2**63 - 1) == 2**63 - 1 + assert mod.f(-2**63) == -2**63 + with pytest.raises(OverflowError): + mod.f(2**63) + with pytest.raises(OverflowError): + mod.f(-2**63 - 1) + + def test_f(self): + import pytest + mod = self.make_parse_item("f", "float", "HPyFloat_FromDouble") + assert mod.f(1.) == 1. + assert mod.f(-2) == -2. + with pytest.raises(TypeError): + mod.f("x") def test_d(self): import pytest mod = self.make_parse_item("d", "double", "HPyFloat_FromDouble") assert mod.f(1.) == 1. assert mod.f(-2) == -2. - with pytest.raises(TypeError) as err: + with pytest.raises(TypeError): mod.f("x") - # PyPy uses a different error message: we need to kill this line upstream - #assert str(err.value) == "must be real number, not str" def test_O(self): mod = self.make_parse_item("O", "HPy", "HPy_Dup") assert mod.f("a") == "a" assert mod.f(5) == 5 + def test_p(self): + mod = self.make_parse_item("p", "int", "HPyLong_FromLong") + assert mod.f(0) == 0 + assert mod.f(1) == 1 + assert mod.f(-1) == 1 + assert mod.f(False) == 0 + assert mod.f(True) == 1 + assert mod.f([]) == 0 + assert mod.f([0]) == 1 + assert mod.f("") == 0 + assert mod.f("0") == 1 + class TestArgParse(HPyTest): def make_two_arg_add(self, fmt="OO"): @@ -62,7 +273,7 @@ class TestArgParse(HPyTest): HPy a; HPy b = HPy_NULL; HPy res; - if (!HPyArg_Parse(ctx, args, nargs, "{fmt}", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "{fmt}", &a, &b)) return HPy_NULL; if (HPy_IsNull(b)) {{ b = HPyLong_FromLong(ctx, 5); @@ -85,7 +296,7 @@ class TestArgParse(HPyTest): HPy *args, HPy_ssize_t nargs) { long a, b, c, d, e; - if (!HPyArg_Parse(ctx, args, nargs, "lllll", + if (!HPyArg_Parse(ctx, NULL, args, nargs, "lllll", &a, &b, &c, &d, &e)) return HPy_NULL; return HPyLong_FromLong(ctx, @@ -103,7 +314,7 @@ class TestArgParse(HPyTest): HPy *args, HPy_ssize_t nargs) { HPy a, b; - if (!HPyArg_Parse(ctx, args, nargs, "OO", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) return HPy_NULL; return HPy_Add(ctx, a, b); } @@ -112,6 +323,25 @@ class TestArgParse(HPyTest): """) assert mod.f("a", "b") == "ab" + def test_supplying_hpy_tracker(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_VARARGS) + static HPy f_impl(HPyContext ctx, HPy self, + HPy *args, HPy_ssize_t nargs) + { + HPy a, b, result; + HPyTracker ht; + if (!HPyArg_Parse(ctx, &ht, args, nargs, "OO", &a, &b)) + return HPy_NULL; + result = HPy_Add(ctx, a, b); + HPyTracker_Close(ctx, ht); + return result; + } + @EXPORT(f) + @INIT + """) + assert mod.f("a", "b") == "ab" + def test_unsupported_fmt(self): import pytest mod = self.make_two_arg_add(fmt="ZZ:two_add") @@ -174,12 +404,16 @@ class TestArgParseKeywords(HPyTest): static HPy f_impl(HPyContext ctx, HPy self, HPy *args, HPy_ssize_t nargs, HPy kw) {{ - HPy a, b; + HPy a, b, result; + HPyTracker ht; static const char *kwlist[] = {{ "a", "b", NULL }}; - if (!HPyArg_ParseKeywords(ctx, args, nargs, kw, "{fmt}", - kwlist, &a, &b)) + if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kw, "{fmt}", + kwlist, &a, &b)) {{ return HPy_NULL; - return HPy_Add(ctx, a, b); + }} + result = HPy_Add(ctx, a, b); + HPyTracker_Close(ctx, ht); + return result; }} @EXPORT(f) @INIT @@ -187,7 +421,7 @@ class TestArgParseKeywords(HPyTest): return mod def test_handle_two_arguments(self): - mod = self.make_two_arg_add("O+O+") + mod = self.make_two_arg_add("OO") assert mod.f("x", b="y") == "xy" def test_handle_reordered_arguments(self): @@ -196,11 +430,15 @@ class TestArgParseKeywords(HPyTest): static HPy f_impl(HPyContext ctx, HPy self, HPy *args, HPy_ssize_t nargs, HPy kw) { - HPy a, b; + HPy a, b, result; + HPyTracker ht; static const char *kwlist[] = { "a", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, args, nargs, kw, "O+O+", kwlist, &a, &b)) + if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kw, "OO", kwlist, &a, &b)) { return HPy_NULL; - return HPy_Add(ctx, a, b); + } + result = HPy_Add(ctx, a, b); + HPyTracker_Close(ctx, ht); + return result; } @EXPORT(f) @INIT @@ -215,16 +453,18 @@ class TestArgParseKeywords(HPyTest): { HPy a; HPy b = HPy_NULL; + HPyTracker ht; HPy res; static const char *kwlist[] = { "a", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, args, nargs, kw, "O+|O+", kwlist, &a, &b)) + if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kw, "O|O", kwlist, &a, &b)) { return HPy_NULL; - if (HPy_IsNull(b)) {{ + } + if (HPy_IsNull(b)) { b = HPyLong_FromLong(ctx, 5); - }} + HPyTracker_Add(ctx, ht, b); + } res = HPy_Add(ctx, a, b); - HPy_Close(ctx, a); - HPy_Close(ctx, b); + HPyTracker_Close(ctx, ht); return res; } @EXPORT(f) @@ -244,21 +484,21 @@ class TestArgParseKeywords(HPyTest): def test_missing_required_argument(self): import pytest - mod = self.make_two_arg_add(fmt="O+O+:add_two") + mod = self.make_two_arg_add(fmt="OO:add_two") with pytest.raises(TypeError) as exc: mod.f(1) assert str(exc.value) == "add_two() no value for required argument" def test_mismatched_args_too_few_keywords(self): import pytest - mod = self.make_two_arg_add(fmt="O+O+O+:add_two") + mod = self.make_two_arg_add(fmt="OOO:add_two") with pytest.raises(TypeError) as exc: mod.f(1, 2) assert str(exc.value) == "add_two() mismatched args (too few keywords for fmt)" def test_mismatched_args_too_many_keywords(self): import pytest - mod = self.make_two_arg_add(fmt="O+:add_two") + mod = self.make_two_arg_add(fmt="O:add_two") with pytest.raises(TypeError) as exc: mod.f(1, 2) assert str(exc.value) == "add_two() mismatched args (too many keywords for fmt)" @@ -270,9 +510,9 @@ class TestArgParseKeywords(HPyTest): static HPy f_impl(HPyContext ctx, HPy self, HPy *args, HPy_ssize_t nargs, HPy kw) { - HPy a, b, c; + long a, b, c; static const char *kwlist[] = { "", "b", "", NULL }; - if (!HPyArg_ParseKeywords(ctx, args, nargs, kw, "NNN", kwlist, + if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kw, "lll", kwlist, &a, &b, &c)) return HPy_NULL; return HPy_Dup(ctx, ctx->h_None); @@ -293,17 +533,18 @@ class TestArgParseKeywords(HPyTest): { HPy a; HPy b = HPy_NULL; + HPyTracker ht; HPy res; static const char *kwlist[] = { "", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, args, nargs, kw, "O+|O+", kwlist, &a, &b)) + if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kw, "O|O", kwlist, &a, &b)) { return HPy_NULL; + } if (HPy_IsNull(b)) { b = HPyLong_FromLong(ctx, 5); - } else { - b = HPy_Dup(ctx, b); + HPyTracker_Add(ctx, ht, b); } res = HPy_Add(ctx, a, b); - HPy_Close(ctx, b); + HPyTracker_Close(ctx, ht); return res; } @EXPORT(f) @@ -318,7 +559,7 @@ class TestArgParseKeywords(HPyTest): def test_keyword_only_argument(self): import pytest - mod = self.make_two_arg_add(fmt="O+$O+") + mod = self.make_two_arg_add(fmt="O$O") assert mod.f(1, b=2) == 3 assert mod.f(a=1, b=2) == 3 with pytest.raises(TypeError) as exc: @@ -328,21 +569,21 @@ class TestArgParseKeywords(HPyTest): def test_error_default_message(self): import pytest - mod = self.make_two_arg_add(fmt="O+O+O+") + mod = self.make_two_arg_add(fmt="OOO") with pytest.raises(TypeError) as exc: mod.f(1, 2) assert str(exc.value) == "function mismatched args (too few keywords for fmt)" def test_error_with_function_name(self): import pytest - mod = self.make_two_arg_add(fmt="O+O+O+:my_func") + mod = self.make_two_arg_add(fmt="OOO:my_func") with pytest.raises(TypeError) as exc: mod.f(1, 2) assert str(exc.value) == "my_func() mismatched args (too few keywords for fmt)" def test_error_with_overridden_message(self): import pytest - mod = self.make_two_arg_add(fmt="O+O+O+;my-error-message") + mod = self.make_two_arg_add(fmt="OOO;my-error-message") with pytest.raises(TypeError) as exc: mod.f(1, 2) assert str(exc.value) == "my-error-message" diff --git a/pypy/module/_hpy_universal/test/_vendored/test_basic.py b/pypy/module/_hpy_universal/test/_vendored/test_basic.py index 7e44d355b750a7a99af976f36a21f5d6a82a8747..1b639e50bff6ced7731c53d6acdc4b013b3d6e94 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_basic.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_basic.py @@ -164,46 +164,7 @@ class TestBasic(HPyTest): mod.f(20) assert str(exc.value) == 'hello world' - def test_exception_occurred(self): - import pytest - mod = self.make_module(""" - HPyDef_METH(f, "f", f_impl, HPyFunc_O) - static HPy f_impl(HPyContext ctx, HPy self, HPy arg) - { - HPyLong_AsLong(ctx, arg); - if (HPyErr_Occurred(ctx)) { - HPyErr_SetString(ctx, ctx->h_ValueError, "hello world"); - return HPy_NULL; - } - return HPyLong_FromLong(ctx, -1002); - } - @EXPORT(f) - @INIT - """) - assert mod.f(-10) == -1002 - with pytest.raises(ValueError) as exc: - mod.f("not an integer") - assert str(exc.value) == 'hello world' - - def test_exception_cleared(self): - import pytest - import sys - mod = self.make_module(""" - HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) - static HPy f_impl(HPyContext ctx, HPy self) - { - HPyErr_SetString(ctx, ctx->h_ValueError, "hello world"); - HPyErr_Clear(ctx); - return HPy_Dup(ctx, ctx->h_None); - } - @EXPORT(f) - @INIT - """) - assert mod.f() is None - assert sys.exc_info() == (None, None, None) - def test_builtin_handles(self): - import pytest mod = self.make_module(""" HPyDef_METH(f, "f", f_impl, HPyFunc_O) static HPy f_impl(HPyContext ctx, HPy self, HPy arg) @@ -271,7 +232,7 @@ class TestBasic(HPyTest): static HPy h_impl(HPyContext ctx, HPy self, HPy *args, HPy_ssize_t nargs) { long a, b; - if (!HPyArg_Parse(ctx, args, nargs, "ll", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &a, &b)) return HPy_NULL; return HPyLong_FromLong(ctx, 10*a + b); } @@ -281,7 +242,7 @@ class TestBasic(HPyTest): { long a, b; static const char *kwlist[] = { "a", "b", NULL }; - if (!HPyArg_ParseKeywords(ctx, args, nargs, kw, "ll", kwlist, &a, &b)) + if (!HPyArg_ParseKeywords(ctx, NULL, args, nargs, kw, "ll", kwlist, &a, &b)) return HPy_NULL; return HPyLong_FromLong(ctx, 10*a + b); } diff --git a/pypy/module/_hpy_universal/test/_vendored/test_hpyerr.py b/pypy/module/_hpy_universal/test/_vendored/test_hpyerr.py index 7af62b9fe5d4ba02ba6896b29fcd975dc02097d9..e9d935dc68532987c47e860850580ecc13e5f644 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_hpyerr.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_hpyerr.py @@ -1,5 +1,8 @@ +import pytest as pytest_collecting + from .support import HPyTest + class TestErr(HPyTest): def test_NoMemory(self): @@ -33,8 +36,313 @@ class TestErr(HPyTest): # Calling mod.f() gives a fatal error, ending in abort(). # How to check that? For now we just check that the above compiles - def test_errorval_returned_by_api_functions_hpy(self): + def test_HPyErr_Occurred(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + HPyLong_AsLong(ctx, arg); + if (HPyErr_Occurred(ctx)) { + HPyErr_SetString(ctx, ctx->h_ValueError, "hello world"); + return HPy_NULL; + } + return HPyLong_FromLong(ctx, -1002); + } + @EXPORT(f) + @INIT + """) + assert mod.f(-10) == -1002 + with pytest.raises(ValueError) as exc: + mod.f("not an integer") + assert str(exc.value) == 'hello world' + + def test_HPyErr_Cleared(self): + import sys + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) + static HPy f_impl(HPyContext ctx, HPy self) + { + HPyErr_SetString(ctx, ctx->h_ValueError, "hello world"); + HPyErr_Clear(ctx); + return HPy_Dup(ctx, ctx->h_None); + } + @EXPORT(f) + @INIT + """) + assert mod.f() is None + assert sys.exc_info() == (None, None, None) + + def test_HPyErr_SetString(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) + static HPy f_impl(HPyContext ctx, HPy self) + { + HPyErr_SetString(ctx, ctx->h_ValueError, "error message"); + return HPy_NULL; + } + @EXPORT(f) + @INIT + """) + with pytest.raises(ValueError) as err: + mod.f() + assert str(err.value) == "error message" + + def test_HPyErr_SetObject(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + HPyErr_SetObject(ctx, ctx->h_ValueError, arg); + return HPy_NULL; + } + @EXPORT(f) + @INIT + """) + with pytest.raises(ValueError) as err: + mod.f(ValueError("error message")) + assert str(err.value) == "error message" + + def test_h_exceptions(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + HPy h_dict, h_err; + h_dict = HPyDict_New(ctx); + HPy_SetItem_s(ctx, h_dict, "BaseException", ctx->h_BaseException); + HPy_SetItem_s(ctx, h_dict, "Exception", ctx->h_Exception); + HPy_SetItem_s(ctx, h_dict, "StopAsyncIteration", ctx->h_StopAsyncIteration); + HPy_SetItem_s(ctx, h_dict, "StopIteration", ctx->h_StopIteration); + HPy_SetItem_s(ctx, h_dict, "GeneratorExit", ctx->h_GeneratorExit); + HPy_SetItem_s(ctx, h_dict, "ArithmeticError", ctx->h_ArithmeticError); + HPy_SetItem_s(ctx, h_dict, "LookupError", ctx->h_LookupError); + HPy_SetItem_s(ctx, h_dict, "AssertionError", ctx->h_AssertionError); + HPy_SetItem_s(ctx, h_dict, "AttributeError", ctx->h_AttributeError); + HPy_SetItem_s(ctx, h_dict, "BufferError", ctx->h_BufferError); + HPy_SetItem_s(ctx, h_dict, "EOFError", ctx->h_EOFError); + HPy_SetItem_s(ctx, h_dict, "FloatingPointError", ctx->h_FloatingPointError); + HPy_SetItem_s(ctx, h_dict, "OSError", ctx->h_OSError); + HPy_SetItem_s(ctx, h_dict, "ImportError", ctx->h_ImportError); + HPy_SetItem_s(ctx, h_dict, "ModuleNotFoundError", ctx->h_ModuleNotFoundError); + HPy_SetItem_s(ctx, h_dict, "IndexError", ctx->h_IndexError); + HPy_SetItem_s(ctx, h_dict, "KeyError", ctx->h_KeyError); + HPy_SetItem_s(ctx, h_dict, "KeyboardInterrupt", ctx->h_KeyboardInterrupt); + HPy_SetItem_s(ctx, h_dict, "MemoryError", ctx->h_MemoryError); + HPy_SetItem_s(ctx, h_dict, "NameError", ctx->h_NameError); + HPy_SetItem_s(ctx, h_dict, "OverflowError", ctx->h_OverflowError); + HPy_SetItem_s(ctx, h_dict, "RuntimeError", ctx->h_RuntimeError); + HPy_SetItem_s(ctx, h_dict, "RecursionError", ctx->h_RecursionError); + HPy_SetItem_s(ctx, h_dict, "NotImplementedError", ctx->h_NotImplementedError); + HPy_SetItem_s(ctx, h_dict, "SyntaxError", ctx->h_SyntaxError); + HPy_SetItem_s(ctx, h_dict, "IndentationError", ctx->h_IndentationError); + HPy_SetItem_s(ctx, h_dict, "TabError", ctx->h_TabError); + HPy_SetItem_s(ctx, h_dict, "ReferenceError", ctx->h_ReferenceError); + HPy_SetItem_s(ctx, h_dict, "SystemError", ctx->h_SystemError); + HPy_SetItem_s(ctx, h_dict, "SystemExit", ctx->h_SystemExit); + HPy_SetItem_s(ctx, h_dict, "TypeError", ctx->h_TypeError); + HPy_SetItem_s(ctx, h_dict, "UnboundLocalError", ctx->h_UnboundLocalError); + HPy_SetItem_s(ctx, h_dict, "ValueError", ctx->h_ValueError); + HPy_SetItem_s(ctx, h_dict, "ZeroDivisionError", ctx->h_ZeroDivisionError); + HPy_SetItem_s(ctx, h_dict, "BlockingIOError", ctx->h_BlockingIOError); + HPy_SetItem_s(ctx, h_dict, "BrokenPipeError", ctx->h_BrokenPipeError); + HPy_SetItem_s(ctx, h_dict, "ChildProcessError", ctx->h_ChildProcessError); + HPy_SetItem_s(ctx, h_dict, "ConnectionError", ctx->h_ConnectionError); + HPy_SetItem_s(ctx, h_dict, "ConnectionAbortedError", ctx->h_ConnectionAbortedError); + HPy_SetItem_s(ctx, h_dict, "ConnectionRefusedError", ctx->h_ConnectionRefusedError); + HPy_SetItem_s(ctx, h_dict, "ConnectionResetError", ctx->h_ConnectionResetError); + HPy_SetItem_s(ctx, h_dict, "FileExistsError", ctx->h_FileExistsError); + HPy_SetItem_s(ctx, h_dict, "FileNotFoundError", ctx->h_FileNotFoundError); + HPy_SetItem_s(ctx, h_dict, "InterruptedError", ctx->h_InterruptedError); + HPy_SetItem_s(ctx, h_dict, "IsADirectoryError", ctx->h_IsADirectoryError); + HPy_SetItem_s(ctx, h_dict, "NotADirectoryError", ctx->h_NotADirectoryError); + HPy_SetItem_s(ctx, h_dict, "PermissionError", ctx->h_PermissionError); + HPy_SetItem_s(ctx, h_dict, "ProcessLookupError", ctx->h_ProcessLookupError); + HPy_SetItem_s(ctx, h_dict, "TimeoutError", ctx->h_TimeoutError); + h_err = HPy_GetItem(ctx, h_dict, arg); + if (HPy_IsNull(h_err)) { + HPy_FatalError(ctx, "missing exception type"); + } + HPyErr_SetString(ctx, h_err, "error message"); + HPy_Close(ctx, h_dict); + HPy_Close(ctx, h_err); + return HPy_NULL; + } + @EXPORT(f) + @INIT + """) + + def check_exception(cls): + with pytest.raises(cls): + mod.f(cls.__name__) + + check_exception(BaseException) + check_exception(Exception) + check_exception(StopAsyncIteration) + check_exception(StopIteration) + check_exception(GeneratorExit) + check_exception(ArithmeticError) + check_exception(LookupError) + check_exception(AssertionError) + check_exception(AttributeError) + check_exception(BufferError) + check_exception(EOFError) + check_exception(FloatingPointError) + check_exception(OSError) + check_exception(ImportError) + check_exception(ModuleNotFoundError) + check_exception(IndexError) + check_exception(KeyError) + check_exception(KeyboardInterrupt) + check_exception(MemoryError) + check_exception(NameError) + check_exception(OverflowError) + check_exception(RuntimeError) + check_exception(RecursionError) + check_exception(NotImplementedError) + check_exception(SyntaxError) + check_exception(IndentationError) + check_exception(TabError) + check_exception(ReferenceError) + check_exception(SystemError) + check_exception(SystemExit) + check_exception(TypeError) + check_exception(UnboundLocalError) + check_exception(ValueError) + check_exception(ZeroDivisionError) + check_exception(BlockingIOError) + check_exception(BrokenPipeError) + check_exception(ChildProcessError) + check_exception(ConnectionError) + check_exception(ConnectionAbortedError) + check_exception(ConnectionRefusedError) + check_exception(ConnectionResetError) + check_exception(FileExistsError) + check_exception(FileNotFoundError) + check_exception(InterruptedError) + check_exception(IsADirectoryError) + check_exception(NotADirectoryError) + check_exception(PermissionError) + check_exception(ProcessLookupError) + check_exception(TimeoutError) + # EnvironmentError and IOError are not explicitly defined by HPy + # but they work because they are actually OSError. + check_exception(EnvironmentError) + check_exception(IOError) + + @pytest_collecting.mark.xfail(True, reason=( + "Creating the unicode exceptions requires something like HPyCall" + " and that isn't implemented yet." + )) + def test_h_unicode_exceptions(self): import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_VARARGS) + static HPy f_impl(HPyContext ctx, HPy self, + HPy *args, HPy_ssize_t nargs) + { + HPy h_key, h_args, h_kw; + HPy h_dict, h_err, h_err_value; + + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOO", &h_key, &h_args, &h_kw)) + return HPy_NULL; + + h_dict = HPyDict_New(ctx); + if (HPy_IsNull(h_dict)) { + return HPy_NULL; + } + HPy_SetItem_s(ctx, h_dict, "UnicodeError", ctx->h_UnicodeError); + HPy_SetItem_s(ctx, h_dict, "UnicodeEncodeError", ctx->h_UnicodeEncodeError); + HPy_SetItem_s(ctx, h_dict, "UnicodeDecodeError", ctx->h_UnicodeDecodeError); + HPy_SetItem_s(ctx, h_dict, "UnicodeTranslateError", ctx->h_UnicodeTranslateError); + + h_err = HPy_GetItem(ctx, h_dict, h_key); + if (HPy_IsNull(h_err)) { + HPy_Close(ctx, h_dict); + return HPy_NULL; + } + h_err_value = HPy_Call(ctx, h_err, h_args, h_kw); + if (HPy_IsNull(h_err_value)) { + HPy_Close(ctx, h_dict); + HPy_Close(ctx, h_err); + return HPy_NULL; + } + + HPyErr_SetObject(ctx, h_err, h_err_value); + HPy_Close(ctx, h_dict); + HPy_Close(ctx, h_err); + HPy_Close(ctx, h_err_value); + return HPy_NULL; + } + @EXPORT(f) + @INIT + """) + + def check_exception(cls, *args, **kw): + with pytest.raises(cls): + mod.f(cls.__name__, args, kw) + + check_exception(UnicodeError) + check_exception( + UnicodeEncodeError, "utf-8", "object", 0, 2, "reason" + ) + check_exception( + UnicodeDecodeError, "utf-8", b"object", 0, 2, "reason" + ) + check_exception(UnicodeTranslateError, "object", 0, 2, "reason") + + def test_h_warnings(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + HPy h_dict, h_err; + h_dict = HPyDict_New(ctx); + HPy_SetItem_s(ctx, h_dict, "Warning", ctx->h_Warning); + HPy_SetItem_s(ctx, h_dict, "UserWarning", ctx->h_UserWarning); + HPy_SetItem_s(ctx, h_dict, "DeprecationWarning", ctx->h_DeprecationWarning); + HPy_SetItem_s(ctx, h_dict, "PendingDeprecationWarning", ctx->h_PendingDeprecationWarning); + HPy_SetItem_s(ctx, h_dict, "SyntaxWarning", ctx->h_SyntaxWarning); + HPy_SetItem_s(ctx, h_dict, "RuntimeWarning", ctx->h_RuntimeWarning); + HPy_SetItem_s(ctx, h_dict, "FutureWarning", ctx->h_FutureWarning); + HPy_SetItem_s(ctx, h_dict, "ImportWarning", ctx->h_ImportWarning); + HPy_SetItem_s(ctx, h_dict, "UnicodeWarning", ctx->h_UnicodeWarning); + HPy_SetItem_s(ctx, h_dict, "BytesWarning", ctx->h_BytesWarning); + HPy_SetItem_s(ctx, h_dict, "ResourceWarning", ctx->h_ResourceWarning); + h_err = HPy_GetItem(ctx, h_dict, arg); + if (HPy_IsNull(h_err)) { + HPy_FatalError(ctx, "missing exception type"); + } + HPyErr_SetString(ctx, h_err, "error message"); + HPy_Close(ctx, h_dict); + HPy_Close(ctx, h_err); + return HPy_NULL; + } + @EXPORT(f) + @INIT + """) + + def check_warning(cls): + with pytest.raises(cls): + mod.f(cls.__name__) + + check_warning(Warning) + check_warning(UserWarning) + check_warning(DeprecationWarning) + check_warning(PendingDeprecationWarning) + check_warning(SyntaxWarning) + check_warning(RuntimeWarning) + check_warning(FutureWarning) + check_warning(ImportWarning) + check_warning(UnicodeWarning) + check_warning(BytesWarning) + check_warning(ResourceWarning) + + def test_errorval_returned_by_api_functions_hpy(self): mod = self.make_module(""" HPyDef_METH(f, "f", f_impl, HPyFunc_VARARGS) static HPy f_impl(HPyContext ctx, HPy self, HPy *args, HPy_ssize_t nargs) @@ -42,7 +350,7 @@ class TestErr(HPyTest): HPy a = HPy_NULL; HPy b = HPy_NULL; HPy res; - if (!HPyArg_Parse(ctx, args, nargs, "OO", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) return HPy_NULL; res = HPy_TrueDivide(ctx, a, b); @@ -61,7 +369,6 @@ class TestErr(HPyTest): assert mod.f(21, 0) == -42 def test_errorval_returned_by_api_functions_int(self): - import pytest mod = self.make_module(""" HPyDef_METH(f, "f", f_impl, HPyFunc_O) static HPy f_impl(HPyContext ctx, HPy self, HPy arg) diff --git a/pypy/module/_hpy_universal/test/_vendored/test_hpylong.py b/pypy/module/_hpy_universal/test/_vendored/test_hpylong.py index 361c75b3232ca4454140644bf39ad8d97a3ee606..df6ea1441dc72734fea3df9645d46069aa432ed0 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_hpylong.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_hpylong.py @@ -1,19 +1,90 @@ from .support import HPyTest + class TestLong(HPyTest): - def test_long_aslong(self): + def test_Long_FromLong(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) + static HPy f_impl(HPyContext ctx, HPy self) + { + long a = 500; + return HPyLong_FromLong(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f() == 500 + + def test_Long_AsLong(self): + import pytest mod = self.make_module(""" HPyDef_METH(f, "f", f_impl, HPyFunc_O) static HPy f_impl(HPyContext ctx, HPy self, HPy arg) { long a = HPyLong_AsLong(ctx, arg); + if (a == -1 && HPyErr_Occurred(ctx)) + return HPy_NULL; return HPyLong_FromLong(ctx, a * 2); } @EXPORT(f) @INIT """) assert mod.f(45) == 90 + with pytest.raises(TypeError): + mod.f("this is not a number") + + def test_Long_FromUnsignedLong(self): + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) + static HPy f_impl(HPyContext ctx, HPy self) + { + unsigned long a = 500; + return HPyLong_FromUnsignedLong(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f() == 500 + + def test_Long_AsUnsignedLong(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + unsigned long a = HPyLong_AsUnsignedLong(ctx, arg); + if ((a == (unsigned long) -1) && HPyErr_Occurred(ctx)) + return HPy_NULL; + return HPyLong_FromUnsignedLong(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f(45) == 45 + with pytest.raises(OverflowError): + mod.f(-91) + with pytest.raises(TypeError): + mod.f("this is not a number") + + def test_Long_AsUnsignedLongMask(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + unsigned long a = HPyLong_AsUnsignedLongMask(ctx, arg); + if ((a == (unsigned long) -1) && HPyErr_Occurred(ctx)) + return HPy_NULL; + return HPyLong_FromUnsignedLong(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f(45) == 45 + assert mod.f(-1) == 2**64 - 1 + with pytest.raises(TypeError): + mod.f("this is not a number") def test_Long_FromLongLong(self): mod = self.make_module(""" @@ -29,6 +100,25 @@ class TestLong(HPyTest): """) assert mod.f() == 2147483648 + def test_Long_AsLongLong(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + long long a = HPyLong_AsLongLong(ctx, arg); + if ((a == (long long) -1) && HPyErr_Occurred(ctx)) + return HPy_NULL; + return HPyLong_FromLongLong(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f(2147483648) == 2147483648 + assert mod.f(-2147483648) == -2147483648 + with pytest.raises(TypeError): + mod.f("this is not a number") + def test_Long_FromUnsignedLongLong(self): mod = self.make_module(""" HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) @@ -43,20 +133,79 @@ class TestLong(HPyTest): """) assert mod.f() == 4294967296 + def test_Long_AsUnsignedLongLong(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + unsigned long long a = HPyLong_AsUnsignedLongLong(ctx, arg); + if ((a == (unsigned long long) -1) && HPyErr_Occurred(ctx)) + return HPy_NULL; + return HPyLong_FromUnsignedLongLong(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f(4294967296) == 4294967296 + with pytest.raises(OverflowError): + mod.f(-4294967296) + with pytest.raises(TypeError): + mod.f("this is not a number") + + def test_Long_AsUnsignedLongLongMask(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + unsigned long long a = HPyLong_AsUnsignedLongLongMask(ctx, arg); + if ((a == (unsigned long) -1) && HPyErr_Occurred(ctx)) + return HPy_NULL; + return HPyLong_FromUnsignedLongLong(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f(45) == 45 + assert mod.f(-1) == 2**64 - 1 + with pytest.raises(TypeError): + mod.f("this is not a number") + def test_Long_FromSize_t(self): mod = self.make_module(""" HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) static HPy f_impl(HPyContext ctx, HPy self) { // take a value which doesn't fit in 32 bit - size_t val = 2147483648; - return HPyLong_FromSize_t(ctx, val); + size_t a = 2147483648; + return HPyLong_FromSize_t(ctx, a); } @EXPORT(f) @INIT """) assert mod.f() == 2147483648 + def test_Long_AsSize_t(self): + import pytest + mod = self.make_module(""" + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + size_t a = HPyLong_AsSize_t(ctx, arg); + if ((a == (size_t) -1) && HPyErr_Occurred(ctx)) + return HPy_NULL; + return HPyLong_FromSize_t(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f(2147483648) == 2147483648 + with pytest.raises(OverflowError): + mod.f(-2147483648) + with pytest.raises(TypeError): + mod.f("this is not a number") + def test_Long_FromSsize_t(self): mod = self.make_module(""" // include ssize_t type: @@ -64,10 +213,31 @@ class TestLong(HPyTest): HPyDef_METH(f, "f", f_impl, HPyFunc_NOARGS) static HPy f_impl(HPyContext ctx, HPy self) { - ssize_t val = -42; - return HPyLong_FromSsize_t(ctx, val); + ssize_t a = -42; + return HPyLong_FromSsize_t(ctx, a); } @EXPORT(f) @INIT """) assert mod.f() == -42 + + def test_Long_AsSsize_t(self): + import pytest + mod = self.make_module(""" + // include ssize_t type: + #include + HPyDef_METH(f, "f", f_impl, HPyFunc_O) + static HPy f_impl(HPyContext ctx, HPy self, HPy arg) + { + ssize_t a = HPyLong_AsSsize_t(ctx, arg); + if ((a == (ssize_t) -1) && HPyErr_Occurred(ctx)) + return HPy_NULL; + return HPyLong_FromSsize_t(ctx, a); + } + @EXPORT(f) + @INIT + """) + assert mod.f(41) == 41 + assert mod.f(-41) == -41 + with pytest.raises(TypeError): + mod.f("this is not a number") diff --git a/pypy/module/_hpy_universal/test/_vendored/test_hpytype.py b/pypy/module/_hpy_universal/test/_vendored/test_hpytype.py index c1a2e593c84e949933e1a804ade79354d6436efd..8ccec4e1912e1a2e6fd7b9206ffc663a0649a8e0 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_hpytype.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_hpytype.py @@ -32,7 +32,7 @@ class PointTemplate(DefaultExtensionTemplate): HPy_ssize_t nargs, HPy kw) { long x, y; - if (!HPyArg_Parse(ctx, args, nargs, "ll", &x, &y)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &x, &y)) return HPy_NULL; PointObject *point; HPy h_point = HPy_New(ctx, cls, &point); diff --git a/pypy/module/_hpy_universal/test/_vendored/test_importing.py b/pypy/module/_hpy_universal/test/_vendored/test_importing.py index d7cd1bd6cea9a07bd3f1e579606569c0d41a3cd8..7d0e7cecab7b82a6030496bb75d91c7a37e00e2a 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_importing.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_importing.py @@ -1,4 +1,5 @@ -import pytest +import pytest as pytest_collecting + from .support import HPyTest # this function should probably goes somewhere into hpy.universal and/or and @@ -16,7 +17,7 @@ def import_module_properly(mod): class TestImporting(HPyTest): - @pytest.mark.xfail + @pytest_collecting.mark.xfail def test_importing_attributes(self): import sys modname = 'mytest' diff --git a/pypy/module/_hpy_universal/test/_vendored/test_number.py b/pypy/module/_hpy_universal/test/_vendored/test_number.py index dce24d467d1a6f284aca5c161e865a55de4785c5..78d622e7a47686865121d1ed99a277ede4802159 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_number.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_number.py @@ -56,7 +56,7 @@ class TestNumber(HPyTest): HPy *args, HPy_ssize_t nargs) { HPy a, b; - if (!HPyArg_Parse(ctx, args, nargs, "OO", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) return HPy_NULL; return HPy_%s(ctx, a, b); } @@ -73,7 +73,7 @@ class TestNumber(HPyTest): HPy *args, HPy_ssize_t nargs) { HPy a, b, c; - if (!HPyArg_Parse(ctx, args, nargs, "OOO", &a, &b, &c)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOO", &a, &b, &c)) return HPy_NULL; return HPy_Power(ctx, a, b, c); } @@ -95,7 +95,7 @@ class TestNumber(HPyTest): HPy *args, HPy_ssize_t nargs) { HPy a, b; - if (!HPyArg_Parse(ctx, args, nargs, "OO", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) return HPy_NULL; return HPy_MatrixMultiply(ctx, a, b); } @@ -125,7 +125,7 @@ class TestNumber(HPyTest): HPy *args, HPy_ssize_t nargs) { HPy a, b; - if (!HPyArg_Parse(ctx, args, nargs, "OO", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) return HPy_NULL; return HPy_InPlace%s(ctx, a, b); } @@ -145,7 +145,7 @@ class TestNumber(HPyTest): HPy *args, HPy_ssize_t nargs) { HPy a, b, c; - if (!HPyArg_Parse(ctx, args, nargs, "OOO", &a, &b, &c)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOO", &a, &b, &c)) return HPy_NULL; return HPy_InPlacePower(ctx, a, b, c); } @@ -174,7 +174,7 @@ class TestNumber(HPyTest): HPy *args, HPy_ssize_t nargs) { HPy a, b; - if (!HPyArg_Parse(ctx, args, nargs, "OO", &a, &b)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b)) return HPy_NULL; return HPy_InPlaceMatrixMultiply(ctx, a, b); } diff --git a/pypy/module/_hpy_universal/test/_vendored/test_slots.py b/pypy/module/_hpy_universal/test/_vendored/test_slots.py index 70b896d2616bb30fe10c7f35a3dc276c7652c3e9..a20a6c489a0e1a5bc261209967cf7b74543f42e4 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_slots.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_slots.py @@ -16,7 +16,7 @@ class TestSlots(HPyTest): HPy_ssize_t nargs, HPy kw) { long x, y; - if (!HPyArg_Parse(ctx, args, nargs, "ll", &x, &y)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "ll", &x, &y)) return -1; PointObject *p = HPy_CAST(ctx, PointObject, self); diff --git a/pypy/module/_hpy_universal/test/_vendored/test_tracker.py b/pypy/module/_hpy_universal/test/_vendored/test_tracker.py index f5672ea04b4f908e7802dc56743dffebd83ae868..7a795a615e4bc3ae92a72f48decffe3be1baefce 100644 --- a/pypy/module/_hpy_universal/test/_vendored/test_tracker.py +++ b/pypy/module/_hpy_universal/test/_vendored/test_tracker.py @@ -10,7 +10,7 @@ from .support import HPyTest class TestHPyTracker(HPyTest): - def hpytracker_module(self, ops, new="HPyTracker_New(ctx, 0)"): + def hpytracker_module(self, ops, size=0): return self.make_module(""" HPyDef_METH(f, "f", f_impl, HPyFunc_VARARGS) static HPy f_impl(HPyContext ctx, HPy self, @@ -18,7 +18,7 @@ class TestHPyTracker(HPyTest): {{ HPyTracker ht; HPy result = HPy_NULL; - ht = {new}; + ht = HPyTracker_New(ctx, {size}); if HPy_IsNull(ht) {{ return HPy_NULL; }} @@ -30,15 +30,14 @@ class TestHPyTracker(HPyTest): }} @EXPORT(f) @INIT - """.format(ops=ops, new=new)) + """.format(ops=ops, size=size)) def test_new_and_free(self): mod = self.hpytracker_module(ops="") mod.f() def test_new_with_size_and_free(self): - mod = self.hpytracker_module( - ops="", new="HPyTracker_New(ctx, 10)") + mod = self.hpytracker_module(ops="", size=10) mod.f() def test_add_and_free(self): @@ -73,7 +72,7 @@ class TestHPyTracker(HPyTest): HPy key, value; HPyTracker ht; - if (!HPyArg_Parse(ctx, args, nargs, "l|l", &n, &n_err)) + if (!HPyArg_Parse(ctx, NULL, args, nargs, "l|l", &n, &n_err)) return HPy_NULL; ht = HPyTracker_New(ctx, 0); // track key-value pairs diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py index 1445ba8d98cc100511241398a24b8e300b4f72d8..52314609cbc074baf5cf22ce6f5a257375ac0705 100644 --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -464,8 +464,15 @@ class FakeObjSpace(ObjSpace): def setup(space): + from pypy.module.exceptions import interp_exceptions + obj_space_exceptions = [] + for name, exc in interp_exceptions.__dict__.items(): + if (isinstance(exc, type) and + issubclass(exc, interp_exceptions.W_BaseException)): + obj_space_exceptions.append(name.replace("W_", "")) + for name in (ObjSpace.ConstantTable + - ObjSpace.ExceptionTable + + obj_space_exceptions + BUILTIN_TYPES): if name != "str": setattr(space, 'w_' + name, w_some_obj())