Skip to content

Commit 6171b1f

Browse files
committed
[GR-57219] Add custom class registry for foreign objects
PullRequest: graalpython/3467
2 parents f159944 + 70de2e5 commit 6171b1f

File tree

20 files changed

+1133
-148
lines changed

20 files changed

+1133
-148
lines changed

Diff for: graalpython/com.oracle.graal.python.benchmarks/python/harness.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ def __init__(self, bench_file, bench_args=None, iterations=1, warmup=-1, warmup_
267267

268268
@staticmethod
269269
def get_bench_module(bench_file):
270-
name = bench_file.rpartition("/")[2].partition(".")[0].replace('.py', '')
271-
directory = bench_file.rpartition("/")[0]
270+
name = bench_file.rpartition(os.sep)[2].partition(".")[0].replace('.py', '')
271+
directory = bench_file.rpartition(os.sep)[0]
272272
pkg = []
273273
while any(f.endswith("__init__.py") for f in os.listdir(directory)):
274274
directory, slash, postfix = directory.rpartition("/")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
41+
# This benchmark hits the GetRegisteredClassNodes as much as possible with one registration
42+
43+
import polyglot
44+
from java.util import LinkedList
45+
from java.util import List
46+
47+
48+
49+
@polyglot.interop_type(List)
50+
class JList:
51+
def append(self, value):
52+
self.add(value)
53+
54+
def __getitem__(self, item):
55+
return self.get(item)
56+
57+
def get_value(self):
58+
return sum(self)
59+
60+
def length(self):
61+
return self.size()
62+
63+
64+
# igv: function_root_create_list_at
65+
def create_list(num: int, l: JList):
66+
for i in range(num):
67+
l.add(LinkedList())
68+
for j in range(i):
69+
l[i].add(j)
70+
71+
for index, li in enumerate(l):
72+
assert li.length() * (li.length() - 1) / 2 == li.get_value()
73+
74+
75+
def measure(num):
76+
j_list = LinkedList()
77+
create_list(num, j_list)
78+
79+
80+
def __benchmark__(num=2_000):
81+
measure(num)
82+
83+
if __name__ == '__main__':
84+
__benchmark__()

Diff for: graalpython/com.oracle.graal.python.frozen/freeze_modules.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66
"""Freeze specified modules
77
"""
88

9-
from collections import namedtuple
9+
import argparse
1010
import marshal
11-
import os
1211
import ntpath
12+
import os
1313
import posixpath
14-
import sys
15-
import argparse
1614
import shutil
17-
15+
import sys
1816
from _sha256 import sha256
17+
from collections import namedtuple
1918

2019
FROZEN_ONLY = os.path.join(os.path.dirname(__file__), "flag.py")
2120

@@ -111,7 +110,7 @@ def add_graalpython_core():
111110
l.append(f"{modname} : {modname} = {modpath}")
112111
for name in [
113112
"__graalpython__",
114-
"_interop_behavior",
113+
"_polyglot",
115114
"_sre",
116115
"_sysconfig",
117116
"_weakref",

Diff for: graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_interop_behavior.py

+31-3
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@
3838
# SOFTWARE.
3939

4040
import sys
41-
from unittest import skipIf
42-
from . import CPyExtType
41+
from unittest import skipIf, TestCase
4342

43+
from . import CPyExtType
4444

4545
if sys.implementation.name == "graalpy":
4646
import polyglot
4747
from __graalpython__ import is_native
4848
is_windows = sys.platform == "win32"
4949

50-
class TestPyStructNumericSequenceTypes(object):
50+
class TestPyStructNumericSequenceTypes(TestCase):
5151

5252
@skipIf(is_native, "not supported in native mode")
5353
def test_interop_assertions(self):
@@ -131,6 +131,34 @@ def test_native_object_interop_behavior_extension(self):
131131
# print("Error : ", e)
132132
assert False
133133

134+
@skipIf(is_native, "not supported in native mode")
135+
def test_decorator_usage(self):
136+
class MyType(object):
137+
data = 100000000000
138+
139+
t = MyType()
140+
with self.assertRaises(ValueError):
141+
# Fail, because argument is not a type
142+
@polyglot.interop_behavior(t)
143+
class MyTypeBehavior:
144+
@staticmethod
145+
def is_number(_):
146+
return True
147+
148+
with self.assertRaises(ValueError):
149+
# Fail, because method decorated
150+
@polyglot.interop_behavior(MyType)
151+
def is_number(_):
152+
return True
153+
154+
# multiple decorator and custom CPyExtType should work
155+
@polyglot.interop_behavior(CPyExtType("dummy", ""))
156+
@polyglot.interop_behavior(MyType)
157+
class MyTypeBehavior:
158+
@staticmethod
159+
def is_number(_):
160+
return True
161+
134162
@skipIf(is_windows, "GR-51663: fails on windows")
135163
def test_native_sequence_interop(self):
136164
MySequenceNativeType = CPyExtType("MySequenceNativeType",

0 commit comments

Comments
 (0)