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 slot HPy_tp_descr_get. #468

Merged
merged 5 commits into from
Jan 29, 2024
Merged
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
8 changes: 0 additions & 8 deletions docs/api-reference/builder.rst

This file was deleted.

23 changes: 23 additions & 0 deletions docs/api-reference/hpy-sequence.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
HPy Lists and Tuples
====================

Building Tuples and Lists
-------------------------

.. autocmodule:: autogen/public_api.h
:members: HPyTupleBuilder_New,HPyTupleBuilder_Set,HPyTupleBuilder_Build,HPyTupleBuilder_Cancel

.. autocmodule:: autogen/public_api.h
:members: HPyListBuilder_New,HPyListBuilder_Set,HPyListBuilder_Build,HPyListBuilder_Cancel

Tuples
------

.. autocmodule:: autogen/public_api.h
:members: HPyTuple_Check,HPyTuple_FromArray

Lists
-----

.. autocmodule:: autogen/public_api.h
:members: HPyList_Check,HPyList_New,HPyList_Append,HPyList_Insert
2 changes: 1 addition & 1 deletion docs/api-reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ between the modes.
hpy-field
hpy-global
hpy-dict
hpy-sequence
hpy-gil
hpy-err
builder
hpy-eval
public-api

Expand Down
3 changes: 2 additions & 1 deletion docs/porting-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,8 @@ If an error occurs during building the list or tuple, it is necessary to call
:c:func:`HPyListBuilder_Cancel` or :c:func:`HPyTupleBuilder_Cancel`,
respectively, to avoid memory leaks.

For details, see the API reference documentation :doc:`api-reference/builder`.
For details, see the API reference documentation
:doc:`api-reference/hpy-sequence`.

Buffers
-------
Expand Down
2 changes: 2 additions & 0 deletions hpy/devel/include/hpy/autogen_hpyslot.h

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

21 changes: 21 additions & 0 deletions hpy/tools/autogen/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pycparser
from packaging import version

if version.parse(pycparser.__version__) < version.parse('2.21'):
raise ImportError('You need pycparser>=2.21 to run autogen')

from .parse import HPyAPI, AUTOGEN_H


def generate(generators, *gen_args):
"""
Takes a sequence of autogen generators that will have access to the parse
tree of 'public_api.c' and can then generate files or whatever.
:param generators: A sequence (e.g. tuple) of classes or callables that
will produce objects with a 'write' method. The 'gen_args' will be passed
to the 'write' method on invocation.
:param gen_args: Arguments for the autogen generator instances.
"""
api = HPyAPI.parse(AUTOGEN_H)
for cls in generators:
cls(api).write(*gen_args)
50 changes: 24 additions & 26 deletions hpy/tools/autogen/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import py
import pycparser
from packaging import version

if version.parse(pycparser.__version__) < version.parse('2.21'):
raise ImportError('You need pycparser>=2.21 to run autogen')

from .parse import HPyAPI, AUTOGEN_H
from . import generate
from .ctx import (autogen_ctx_h,
autogen_ctx_def_h,
cpython_autogen_ctx_h)
Expand All @@ -30,38 +31,35 @@
from .doc import (autogen_function_index,
autogen_doc_api_mapping)

DEFAULT_GENERATORS = (autogen_ctx_h,
autogen_ctx_def_h,
cpython_autogen_ctx_h,
autogen_trampolines_h,
cpython_autogen_api_impl_h,
universal_autogen_ctx_impl_h,
autogen_hpyfunc_declare_h,
autogen_hpyfunc_trampoline_h,
autogen_ctx_call_i,
autogen_cpython_hpyfunc_trampoline_h,
autogen_hpyslot_h,
autogen_debug_ctx_init_h,
autogen_debug_wrappers,
autogen_debug_ctx_call_i,
autogen_tracer_ctx_init_h,
autogen_tracer_wrappers,
autogen_trace_func_table_c,
autogen_pypy_txt,
autogen_function_index,
autogen_doc_api_mapping)


def main():
if len(sys.argv) != 2:
print('Usage: python -m hpy.tools.autogen OUTDIR')
sys.exit(1)
outdir = py.path.local(sys.argv[1])

api = HPyAPI.parse(AUTOGEN_H)
## for func in api.functions:
## print(func)

for cls in (autogen_ctx_h,
autogen_ctx_def_h,
cpython_autogen_ctx_h,
autogen_trampolines_h,
cpython_autogen_api_impl_h,
universal_autogen_ctx_impl_h,
autogen_hpyfunc_declare_h,
autogen_hpyfunc_trampoline_h,
autogen_ctx_call_i,
autogen_cpython_hpyfunc_trampoline_h,
autogen_hpyslot_h,
autogen_debug_ctx_init_h,
autogen_debug_wrappers,
autogen_debug_ctx_call_i,
autogen_tracer_ctx_init_h,
autogen_tracer_wrappers,
autogen_trace_func_table_c,
autogen_pypy_txt,
autogen_function_index,
autogen_doc_api_mapping):
cls(api).write(outdir)
generate(DEFAULT_GENERATORS, outdir)


if __name__ == '__main__':
Expand Down
76 changes: 74 additions & 2 deletions hpy/tools/autogen/public_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,10 +666,52 @@ HPy_ID(256)
HPy HPyUnicode_Substring(HPyContext *ctx, HPy str, HPy_ssize_t start, HPy_ssize_t end);

/* listobject.h */

/**
* Tests if an object is an instance of a Python list.
*
* :param ctx:
* The execution context.
* :param h:
* A handle to an arbitrary object (must not be ``HPy_NULL``).
*
* :returns:
* Non-zero if object ``h`` is an instance of type ``list`` or an instance
* of a subtype of ``list``, and ``0`` otherwise.
*/
HPy_ID(198)
int HPyList_Check(HPyContext *ctx, HPy h);

/**
* Creates a new list instance with length ``len``.
*
* :param ctx:
* The execution context.
* :param len:
* A Python list object (must not be ``HPy_NULL``). Otherwise, a
* ``SystemError`` will be raised.
*
* :returns:
* The new list instance on success, or ``HPy_NULL`` on failure.
*/
HPy_ID(199)
HPy HPyList_New(HPyContext *ctx, HPy_ssize_t len);

/**
* Append item ``h_item`` to list ``h_list``.
*
* :param ctx:
* The execution context.
* :param h_list:
* A Python list object (must not be ``HPy_NULL``). Otherwise, a
* ``SystemError`` will be raised.
* :param h_item:
* The item to append (must not be ``HPy_NULL``).
*
* :returns:
* Return ``0`` if successful; return ``-1`` and set an exception if
* unsuccessful.
*/
HPy_ID(200)
int HPyList_Append(HPyContext *ctx, HPy h_list, HPy h_item);

Expand Down Expand Up @@ -763,11 +805,41 @@ HPy_ID(258)
HPy HPyDict_Copy(HPyContext *ctx, HPy h);

/* tupleobject.h */

/**
* Tests if an object is an instance of a Python tuple.
*
* :param ctx:
* The execution context.
* :param h:
* A handle to an arbitrary object (must not be ``HPy_NULL``).
*
* :returns:
* Non-zero if object ``h`` is an instance of type ``tuple`` or an instance
* of a subtype of ``tuple``, and ``0`` otherwise.
*/
HPy_ID(203)
int HPyTuple_Check(HPyContext *ctx, HPy h);

/**
* Create a tuple from an array.
*
* Note: Consider to use the convenience function :c:func:`HPyTuple_Pack` to
* create a tuple.
*
* :param ctx:
* The execution context.
* :param items:
* An array of items to use for initialization of the tuple.
* :param n:
* The number of elements in array ``items``.
*
* :return:
* A new tuple with ``n`` elements or ``HPy_NULL`` in case of an error
* occurred.
*/
HPy_ID(204)
HPy HPyTuple_FromArray(HPyContext *ctx, const HPy items[], HPy_ssize_t n);
// note: HPyTuple_Pack is implemented as a macro in common/macros.h

/* sliceobject.h */

Expand Down Expand Up @@ -1299,7 +1371,7 @@ typedef enum {
//HPy_tp_clear = SLOT(51, HPyFunc_X), NOT SUPPORTED, use tp_traverse
//HPy_tp_dealloc = SLOT(52, HPyFunc_X), NOT SUPPORTED
//HPy_tp_del = SLOT(53, HPyFunc_X),
//HPy_tp_descr_get = SLOT(54, HPyFunc_X),
HPy_tp_descr_get = SLOT(54, HPyFunc_TERNARYFUNC),
//HPy_tp_descr_set = SLOT(55, HPyFunc_X),
//HPy_tp_doc = SLOT(56, HPyFunc_X),
//HPy_tp_getattr = SLOT(57, HPyFunc_X),
Expand Down
24 changes: 24 additions & 0 deletions test/test_slots.py
Original file line number Diff line number Diff line change
Expand Up @@ -807,3 +807,27 @@ def test_tp_richcompare(self):
#
assert not p1 >= p2
assert p1 >= p1

def test_tp_descr_get(self):
mod = self.make_module("""
@DEFINE_PointObject
@DEFINE_Point_new

HPyDef_SLOT(Point_get, HPy_tp_descr_get);
static HPy
Point_get_impl(HPyContext *ctx, HPy self, HPy obj, HPy type)
{
if (HPy_IsNull(obj) || HPy_Is(ctx, self, ctx->h_None)) {
return HPy_Dup(ctx, self);
}
return HPyLong_FromLong(ctx, 123);
}

@EXPORT_POINT_TYPE(&Point_new, &Point_get)
@INIT
""")
p = mod.Point(10, 10)
class Dummy:
point_func = p
assert Dummy.point_func is p
assert Dummy().point_func == 123
Loading