Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable exact type checks with HPy_TypeCheck #309

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hpy/debug/src/_debugmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ HPyDef_SLOT(DebugHandle_cmp, DebugHandle_cmp_impl, HPy_tp_richcompare)
static UHPy DebugHandle_cmp_impl(HPyContext *uctx, UHPy self, UHPy o, HPy_RichCmpOp op)
{
UHPy T = HPy_Type(uctx, self);
if (!HPy_TypeCheck(uctx, o, T))
if (!HPy_TypeCheck(uctx, o, T, 0))
return HPy_Dup(uctx, uctx->h_NotImplemented);
DebugHandleObject *dh_self = DebugHandleObject_AsStruct(uctx, self);
DebugHandleObject *dh_o = DebugHandleObject_AsStruct(uctx, o);
Expand Down
2 changes: 1 addition & 1 deletion hpy/debug/src/autogen_debug_ctx_init.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions hpy/debug/src/autogen_debug_wrappers.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion hpy/devel/include/hpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ extern "C" {

- PyPy: ._i is an index into a list

- GraalPython: ???
- GraalPython: _i is an index into a list (may be optimized to a direct
reference depending on the runtime options and control flow)

- Debug mode: _i is a pointer to a DebugHandle, which contains a
another HPy among other stuff
Expand Down
4 changes: 2 additions & 2 deletions hpy/devel/include/hpy/cpython/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ HPyAPI_FUNC void _HPy_Dump(HPyContext *ctx, HPy h)
ctx_Dump(ctx, h);
}

HPyAPI_FUNC int HPy_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type)
HPyAPI_FUNC int HPy_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type, int exact)
{
return ctx_TypeCheck(ctx, h_obj, h_type);
return ctx_TypeCheck(ctx, h_obj, h_type, exact);
}

HPyAPI_FUNC int HPy_Is(HPyContext *ctx, HPy h_obj, HPy h_other)
Expand Down
2 changes: 1 addition & 1 deletion hpy/devel/include/hpy/runtime/ctx_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ _HPy_HIDDEN HPy ctx_Module_Create(HPyContext *ctx, HPyModuleDef *hpydef);

// ctx_object.c
_HPy_HIDDEN void ctx_Dump(HPyContext *ctx, HPy h);
_HPy_HIDDEN int ctx_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type);
_HPy_HIDDEN int ctx_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type, int exact);
_HPy_HIDDEN int ctx_Is(HPyContext *ctx, HPy h_obj, HPy h_other);
_HPy_HIDDEN HPy ctx_GetItem_i(HPyContext *ctx, HPy obj, HPy_ssize_t idx);
_HPy_HIDDEN HPy ctx_GetItem_s(HPyContext *ctx, HPy obj, const char *key);
Expand Down
2 changes: 1 addition & 1 deletion hpy/devel/include/hpy/universal/autogen_ctx.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions hpy/devel/include/hpy/universal/autogen_trampolines.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion hpy/devel/src/runtime/ctx_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ ctx_Dump(HPyContext *ctx, HPy h)
do the check only in debug mode.
*/
_HPy_HIDDEN int
ctx_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type)
ctx_TypeCheck(HPyContext *ctx, HPy h_obj, HPy h_type, int exact)
{
PyObject *type= _h2py(h_type);
assert(type != NULL);
if (!PyType_Check(type)) {
Py_FatalError("HPy_TypeCheck arg 2 must be a type");
}
if (exact) {
return Py_TYPE(_h2py(h_obj)) == (PyTypeObject*)type;
}
return PyObject_TypeCheck(_h2py(h_obj), (PyTypeObject*)type);
}

Expand Down
2 changes: 1 addition & 1 deletion hpy/tools/autogen/public_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ int HPy_SetItem_s(HPyContext *ctx, HPy obj, const char *key, HPy value);

HPy HPy_Type(HPyContext *ctx, HPy obj);
// WARNING: HPy_TypeCheck could be tweaked/removed in the future, see issue #160
int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type);
int HPy_TypeCheck(HPyContext *ctx, HPy obj, HPy type, int exact);

int HPy_Is(HPyContext *ctx, HPy obj, HPy other);

Expand Down
15 changes: 10 additions & 5 deletions test/test_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,19 +546,24 @@ def test_typecheck(self):
static HPy f_impl(HPyContext *ctx, HPy self, HPy *args, HPy_ssize_t nargs)
{
HPy a, b;
if (!HPyArg_Parse(ctx, NULL, args, nargs, "OO", &a, &b))
int exact;
if (!HPyArg_Parse(ctx, NULL, args, nargs, "OOi", &a, &b, &exact))
return HPy_NULL;
int res = HPy_TypeCheck(ctx, a, b);
int res = HPy_TypeCheck(ctx, a, b, exact);
return HPyBool_FromLong(ctx, res);
}
@EXPORT(f)
@INIT
""")
class MyStr(str):
pass
assert mod.f('hello', str)
assert not mod.f('hello', int)
assert mod.f(MyStr('hello'), str)
assert mod.f('hello', str, False)
assert not mod.f('hello', int, False)
assert mod.f(MyStr('hello'), str, False)

assert mod.f('hello', str, True)
assert not mod.f('hello', int, True)
assert not mod.f(MyStr('hello'), str, True)

def test_is(self):
mod = self.make_module("""
Expand Down