Skip to content

Commit 393eb36

Browse files
timfelfangerer
authored andcommitted
make the java builtin module a virtual package that provides access to Java types
1 parent df48c8d commit 393eb36

File tree

3 files changed

+113
-3
lines changed

3 files changed

+113
-3
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ private static final String[] initializeCoreFiles() {
230230
"mmap",
231231
"_queue",
232232
"_ast",
233+
"java",
233234
"_contextvars"));
234235

235236
return coreFiles.toArray(new String[coreFiles.size()]);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
44+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
45+
4346
import java.util.List;
4447

4548
import com.oracle.graal.python.builtins.Builtin;
@@ -49,6 +52,7 @@
4952
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5053
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5154
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
55+
import com.oracle.graal.python.runtime.PythonCore;
5256
import com.oracle.graal.python.runtime.exception.PythonErrorType;
5357
import com.oracle.truffle.api.TruffleLanguage.Env;
5458
import com.oracle.truffle.api.dsl.Fallback;
@@ -57,16 +61,19 @@
5761
import com.oracle.truffle.api.dsl.Specialization;
5862
import com.oracle.truffle.api.interop.TruffleObject;
5963

60-
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
61-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
62-
6364
@CoreFunctions(defineModule = "java")
6465
public class JavaModuleBuiltins extends PythonBuiltins {
6566
@Override
6667
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
6768
return JavaModuleBuiltinsFactory.getFactories();
6869
}
6970

71+
@Override
72+
public void initialize(PythonCore core) {
73+
super.initialize(core);
74+
builtinConstants.put("__path__", "java!");
75+
}
76+
7077
@Builtin(name = "type", minNumOfPositionalArgs = 1)
7178
@GenerateNodeFactory
7279
abstract static class TypeNode extends PythonUnaryBuiltinNode {

graalpython/lib-graalpython/java.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Copyright (c) 2019, 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+
import sys
40+
import _frozen_importlib
41+
42+
43+
class JavaPackageLoader:
44+
@staticmethod
45+
def _make_getattr(modname):
46+
if modname.startswith("java."):
47+
modname_wo = modname[len("java."):] + "."
48+
else:
49+
modname_wo = None
50+
modname = modname + "."
51+
def __getattr__(key, default=None):
52+
try:
53+
return type(modname + key)
54+
except KeyError:
55+
pass
56+
if modname_wo:
57+
try:
58+
return type(modname_wo + key)
59+
except KeyError:
60+
pass
61+
raise AttributeError(key)
62+
return __getattr__
63+
64+
@staticmethod
65+
def create_module(spec):
66+
newmod = _frozen_importlib._new_module(spec.name)
67+
newmod.__getattr__ = JavaPackageLoader._make_getattr(spec.name)
68+
newmod.__path__ = __path__
69+
return newmod
70+
71+
@staticmethod
72+
def exec_module(module):
73+
pass
74+
75+
76+
class JavaTypeLoader:
77+
@staticmethod
78+
def create_module(spec):
79+
pass
80+
81+
@staticmethod
82+
def exec_module(module):
83+
try:
84+
sys.modules[module.__name__] = type(module.__name__)
85+
except KeyError:
86+
if module.__name__.startswith("java."):
87+
sys.modules[module.__name__] = type(module.__name__[len("java."):])
88+
else:
89+
raise
90+
91+
92+
class JavaImportFinder:
93+
@staticmethod
94+
def find_spec(fullname, path, target=None):
95+
if path and path == __path__:
96+
if fullname.rpartition('.')[2].islower():
97+
return _frozen_importlib.ModuleSpec(fullname, JavaPackageLoader, is_package=True)
98+
else:
99+
return _frozen_importlib.ModuleSpec(fullname, JavaTypeLoader, is_package=False)
100+
101+
102+
sys.meta_path.append(JavaImportFinder)

0 commit comments

Comments
 (0)