Skip to content

Commit 5d1a198

Browse files
committed
Merge branch 'hpy-import'
2 parents 9d10fb4 + a65d9e7 commit 5d1a198

File tree

12 files changed

+156
-8
lines changed

12 files changed

+156
-8
lines changed

graalpython/com.oracle.graal.python.cext/include/hpy/cpython/autogen_api_impl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,11 +464,21 @@ HPyAPI_FUNC HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h)
464464
return _py2h(PyUnicode_AsUTF8String(_h2py(h)));
465465
}
466466

467+
HPyAPI_FUNC const char *HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size)
468+
{
469+
return PyUnicode_AsUTF8AndSize(_h2py(h), size);
470+
}
471+
467472
HPyAPI_FUNC HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size)
468473
{
469474
return _py2h(PyUnicode_FromWideChar(w, size));
470475
}
471476

477+
HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v)
478+
{
479+
return _py2h(PyUnicode_DecodeFSDefault(v));
480+
}
481+
472482
HPyAPI_FUNC int HPyList_Check(HPyContext *ctx, HPy h)
473483
{
474484
return PyList_Check(_h2py(h));

graalpython/com.oracle.graal.python.cext/include/hpy/runtime/ctx_funcs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
// This file contains the prototypes for all the functions defined in
2929
// hpy/devel/src/runtime/ctx_*.c
3030

31-
#include <Python.h>
3231
#include "hpy.h"
3332

3433
// ctx_bytes.c

graalpython/com.oracle.graal.python.cext/include/hpy/universal/autogen_ctx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,9 @@ struct _HPyContext_s {
226226
HPy (*ctx_Unicode_FromString)(HPyContext *ctx, const char *utf8);
227227
int (*ctx_Unicode_Check)(HPyContext *ctx, HPy h);
228228
HPy (*ctx_Unicode_AsUTF8String)(HPyContext *ctx, HPy h);
229+
const char *(*ctx_Unicode_AsUTF8AndSize)(HPyContext *ctx, HPy h, HPy_ssize_t *size);
229230
HPy (*ctx_Unicode_FromWideChar)(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size);
231+
HPy (*ctx_Unicode_DecodeFSDefault)(HPyContext *ctx, const char *v);
230232
int (*ctx_List_Check)(HPyContext *ctx, HPy h);
231233
HPy (*ctx_List_New)(HPyContext *ctx, HPy_ssize_t len);
232234
int (*ctx_List_Append)(HPyContext *ctx, HPy h_list, HPy h_item);

graalpython/com.oracle.graal.python.cext/include/hpy/universal/autogen_trampolines.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,10 +451,18 @@ HPyAPI_FUNC HPy HPyUnicode_AsUTF8String(HPyContext *ctx, HPy h) {
451451
return WRAP(ctx->ctx_Unicode_AsUTF8String ( ctx, UNWRAP(h) ));
452452
}
453453

454+
HPyAPI_FUNC const char *HPyUnicode_AsUTF8AndSize(HPyContext *ctx, HPy h, HPy_ssize_t *size) {
455+
return ctx->ctx_Unicode_AsUTF8AndSize ( ctx, UNWRAP(h), size );
456+
}
457+
454458
HPyAPI_FUNC HPy HPyUnicode_FromWideChar(HPyContext *ctx, const wchar_t *w, HPy_ssize_t size) {
455459
return WRAP(ctx->ctx_Unicode_FromWideChar ( ctx, w, size ));
456460
}
457461

462+
HPyAPI_FUNC HPy HPyUnicode_DecodeFSDefault(HPyContext *ctx, const char *v) {
463+
return WRAP(ctx->ctx_Unicode_DecodeFSDefault ( ctx, v ));
464+
}
465+
458466
HPyAPI_FUNC int HPyList_Check(HPyContext *ctx, HPy h) {
459467
return ctx->ctx_List_Check ( ctx, UNWRAP(h) );
460468
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11

22
// automatically generated by setup.py:get_scm_config()
3-
#define HPY_VERSION "0.0.3.dev308+ng7d457b4"
4-
#define HPY_GIT_REVISION "7d457b4"
3+
#define HPY_VERSION "0.0.3.dev317+ng8fe1487"
4+
#define HPY_GIT_REVISION "8fe1487"

graalpython/lib-graalpython/modules/hpy.devel.egg-info/PKG-INFO

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Metadata-Version: 2.1
22
Name: hpy.devel
3-
Version: 0.0.3.dev308+ng7d457b4
3+
Version: 0.0.3.dev317+ng8fe1487
44
Summary: UNKNOWN
55
Home-page: UNKNOWN
66
License: UNKNOWN

graalpython/lib-graalpython/modules/hpy/devel/src/runtime/argparse.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,29 @@
7878
* ``d (float) [double]``
7979
* Convert a Python floating point number to a C double.
8080
*
81+
* Strings and buffers
82+
* ~~~~~~~~~~~~~~~~~~~~~~~~
83+
*
84+
* These formats allow accessing an object as a contiguous chunk of memory.
85+
* You don't have to provide raw storage for the returned unicode or bytes
86+
* area.
87+
*
88+
* In general, when a format sets a pointer to a buffer, the pointer is valid
89+
* only until the corresponding HPy handle is closed.
90+
*
91+
* ``s (unicode) [const char*]``
92+
*
93+
* Convert a Unicode object to a C pointer to a character string.
94+
* A pointer to an existing string is stored in the character pointer
95+
* variable whose address you pass. The C string is NUL-terminated.
96+
* The Python string must not contain embedded null code points; if it does,
97+
* a `ValueError` exception is raised. Unicode objects are converted
98+
* to C strings using 'utf-8' encoding. If this conversion fails,
99+
* a `UnicodeError` is raised.
100+
*
101+
* Note: This format does not accept bytes-like objects and is therefore
102+
* not suitable for filesystem paths.
103+
*
81104
* Handles (Python Objects)
82105
* ~~~~~~~~~~~~~~~~~~~~~~~~
83106
*
@@ -361,11 +384,41 @@ parse_item(HPyContext *ctx, HPyTracker *ht, HPy current_arg, int current_arg_tmp
361384
break;
362385
}
363386

364-
default:
387+
case 's': {
388+
const char **output = va_arg(*vl, const char **);
389+
if (!HPyUnicode_Check(ctx, current_arg)) {
390+
set_error(ctx, ctx->h_TypeError, err_fmt, "a str is required");
391+
return 0;
392+
}
393+
HPy_ssize_t size;
394+
const char *data = HPyUnicode_AsUTF8AndSize(ctx, current_arg, &size);
395+
if (data == NULL) {
396+
set_error(ctx, ctx->h_SystemError, err_fmt, "unicode conversion error");
397+
return 0;
398+
}
399+
// loop bounded by size is more robust/paranoid than strlen
400+
HPy_ssize_t i;
401+
for (i = 0; i < size; ++i) {
402+
if (data[i] == '\0') {
403+
set_error(ctx, ctx->h_ValueError, err_fmt, "embedded null character");
404+
return 0;
405+
}
406+
}
407+
if (data[i] != '\0') {
408+
set_error(ctx, ctx->h_SystemError, err_fmt, "missing terminating null character");
409+
return 0;
410+
}
411+
*output = data;
412+
break;
413+
}
414+
415+
default: {
365416
set_error(ctx, ctx->h_SystemError, err_fmt, "unknown arg format code");
366417
return 0;
367418
}
368419

420+
} // switch
421+
369422
return 1;
370423
}
371424

graalpython/lib-graalpython/modules/hpy/devel/version.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@
2222
# SOFTWARE.
2323

2424
# automatically generated by setup.py:get_scm_config()
25-
__version__ = "0.0.3.dev308+ng7d457b4"
26-
__git_revision__ = "7d457b4"
25+
__version__ = "0.0.3.dev317+ng8fe1487"
26+
__git_revision__ = "8fe1487"

graalpython/lib-graalpython/modules/hpy/test/support.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def make_module(self, ExtensionTemplate, main_src, name, extra_sources):
304304
We don't want to unnecessarily modify the global state inside tests:
305305
if you are writing a test which needs a proper import, you should not
306306
use make_module but explicitly use compile_module and import it
307-
manually as requied by your test.
307+
manually as required by your test.
308308
"""
309309
so_filename = self.compile_module(
310310
ExtensionTemplate, main_src, name, extra_sources)

graalpython/lib-graalpython/modules/hpy/test/test_argparse.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,21 @@ def test_b(self):
7979
"function unsigned byte integer is less than minimum"
8080
)
8181

82+
def test_s(self):
83+
import pytest
84+
mod = self.make_parse_item("s", "const char*", "HPyUnicode_FromString")
85+
assert mod.f("hello HPy") == "hello HPy"
86+
with pytest.raises(ValueError) as err:
87+
mod.f(b"hello\0HPy".decode('utf-8'))
88+
assert str(err.value) == (
89+
"function embedded null character"
90+
)
91+
with pytest.raises(TypeError) as err:
92+
mod.f(b"hello HPy")
93+
assert str(err.value) == (
94+
"function a str is required"
95+
)
96+
8297
def test_B(self):
8398
mod = self.make_parse_item("B", "char", "char_to_hpybytes")
8499
assert mod.f(0) == b"\x00"

0 commit comments

Comments
 (0)