Skip to content

Commit 10976de

Browse files
committed
intrinsified python_cext._PyModule_CreateInitialized_PyModule_New and _imp.create_dynamic
1 parent 1347710 commit 10976de

File tree

4 files changed

+68
-35
lines changed

4 files changed

+68
-35
lines changed

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@
7777
import com.oracle.graal.python.builtins.objects.object.PythonObject;
7878
import com.oracle.graal.python.builtins.objects.str.PString;
7979
import com.oracle.graal.python.lib.PyObjectLookupAttr;
80+
import com.oracle.graal.python.lib.PyObjectStrAsJavaStringNode;
8081
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode;
8182
import com.oracle.graal.python.nodes.attributes.SetAttributeNode;
8283
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
8384
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
8485
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
8586
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
8687
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
88+
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
8789
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
8890
import com.oracle.graal.python.parser.sst.SerializationUtils;
8991
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
@@ -105,6 +107,9 @@ public class ImpModuleBuiltins extends PythonBuiltins {
105107

106108
static final String HPY_SUFFIX = ".hpy.so";
107109

110+
// the full module name for package imports
111+
public String pyPackageContext;
112+
108113
@Override
109114
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
110115
return ImpModuleBuiltinsFactory.getFactories();
@@ -192,7 +197,7 @@ protected byte[] getMagicNumberBytes(VirtualFrame frame) {
192197

193198
@Builtin(name = "__create_dynamic__", minNumOfPositionalArgs = 2)
194199
@GenerateNodeFactory
195-
public abstract static class CreateDynamic extends PythonBuiltinNode {
200+
public abstract static class CreateDynamic extends PythonBinaryBuiltinNode {
196201

197202
@Child private CheckFunctionResultNode checkResultNode;
198203
@Child private HPyCheckFunctionResultNode checkHPyResultNode;
@@ -436,4 +441,28 @@ Object run() {
436441
}
437442
}
438443

444+
@Builtin(name = "create_dynamic", minNumOfPositionalArgs = 2, declaresExplicitSelf = true, parameterNames = {"$self", "moduleSpec", "fileName"})
445+
@GenerateNodeFactory
446+
public abstract static class CreateDynamicNode extends PythonTernaryBuiltinNode {
447+
@Specialization(guards = "isNoValue(fileName)")
448+
Object runNoFileName(VirtualFrame frame, PythonModule self, PythonObject moduleSpec, @SuppressWarnings("unused") PNone fileName,
449+
@Cached CreateDynamic createDynamicNode) {
450+
return run(frame, self, moduleSpec, PNone.NONE, createDynamicNode);
451+
}
452+
453+
@Specialization(guards = "!isNoValue(fileName)")
454+
Object run(VirtualFrame frame, PythonModule self, PythonObject moduleSpec, Object fileName,
455+
@Cached CreateDynamic createDynamicNode) {
456+
ImpModuleBuiltins impBuiltins = (ImpModuleBuiltins) self.getBuiltins();
457+
String oldPackageContext = impBuiltins.pyPackageContext;
458+
impBuiltins.pyPackageContext = PyObjectStrAsJavaStringNode.getUncached().execute(frame,
459+
PyObjectLookupAttr.getUncached().execute(frame, moduleSpec, "name"));
460+
try {
461+
return createDynamicNode.execute(frame, moduleSpec, fileName);
462+
} finally {
463+
impBuiltins.pyPackageContext = oldPackageContext;
464+
}
465+
}
466+
}
467+
439468
}

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@
235235
import com.oracle.graal.python.nodes.PNodeWithContext;
236236
import com.oracle.graal.python.nodes.PRaiseNode;
237237
import com.oracle.graal.python.nodes.SpecialAttributeNames;
238+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__PACKAGE__;
238239
import com.oracle.graal.python.nodes.SpecialMethodNames;
239240
import com.oracle.graal.python.nodes.WriteUnraisableNode;
240241
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode.CreateAndCheckArgumentsNode;
@@ -274,6 +275,7 @@
274275
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
275276
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
276277
import com.oracle.graal.python.nodes.object.GetClassNode;
278+
import com.oracle.graal.python.nodes.statement.AbstractImportNode;
277279
import com.oracle.graal.python.nodes.truffle.PythonTypes;
278280
import com.oracle.graal.python.nodes.util.CannotCastException;
279281
import com.oracle.graal.python.nodes.util.CastToByteNode;
@@ -496,6 +498,42 @@ Object run(String name) {
496498
}
497499
}
498500

501+
@Builtin(name = "_PyModule_CreateInitialized_PyModule_New", parameterNames = {"name"})
502+
@ArgumentClinic(name = "name", conversion = ClinicConversion.String)
503+
@GenerateNodeFactory
504+
public abstract static class PyModuleCreateInitializedNewNode extends PythonUnaryClinicBuiltinNode {
505+
506+
@Override
507+
protected ArgumentClinicProvider getArgumentClinic() {
508+
return PythonCextBuiltinsClinicProviders.PyModuleCreateInitializedNewNodeClinicProviderGen.INSTANCE;
509+
}
510+
511+
@Specialization
512+
Object run(VirtualFrame frame, String name,
513+
@Cached ObjectBuiltins.SetattrNode setattrNode) {
514+
// see CPython's Objects/moduleobject.c - _PyModule_CreateInitialized for
515+
// comparison how they handle _Py_PackageContext
516+
PythonModule imp = (PythonModule) AbstractImportNode.importModule("_imp");
517+
ImpModuleBuiltins impBuiltins = (ImpModuleBuiltins) imp.getBuiltins();
518+
String newModuleName = name;
519+
if (impBuiltins.pyPackageContext != null && impBuiltins.pyPackageContext.endsWith(newModuleName)) {
520+
newModuleName = impBuiltins.pyPackageContext;
521+
impBuiltins.pyPackageContext = null;
522+
}
523+
PythonModule newModule = newModule(newModuleName, getCore(), factory());
524+
// TODO: (tfel) I don't think this is the right place to set it, but somehow
525+
// at least in the import of sklearn.neighbors.dist_metrics through
526+
// sklearn.neighbors.ball_tree the __package__ attribute seems to be already
527+
// set in CPython. To not produce a warning, I'm setting it here, although I
528+
// could not find what CPython really does
529+
int idx = newModuleName.indexOf(".");
530+
if (idx > -1) {
531+
setattrNode.execute(frame, newModule, __PACKAGE__, newModuleName.substring(0, idx));
532+
}
533+
return newModule;
534+
}
535+
}
536+
499537
private static PythonModule newModule(String name, Python3Core core, PythonObjectFactory factory) {
500538
PythonModule sysModule = core.lookupBuiltinModule("sys");
501539
PDict sysModules = (PDict) sysModule.getAttribute("modules");

graalpython/lib-graalpython/_imp.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,6 @@
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
3939

40-
# Package context -- the full module name for package imports
41-
_py_package_context = None
42-
43-
@__graalpython__.builtin
44-
def create_dynamic(module_spec, filename=None):
45-
global _py_package_context
46-
old_package_context = _py_package_context
47-
_py_package_context = str(module_spec.name)
48-
try:
49-
return __create_dynamic__(module_spec, filename)
50-
finally:
51-
_py_package_context = old_package_context
52-
53-
5440
@__graalpython__.builtin
5541
def init_frozen(name):
5642
return None

graalpython/lib-graalpython/python_cext.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
3939

40-
import _imp
4140
import sys
4241
import _thread
4342

@@ -52,25 +51,6 @@ def decorator(fun):
5251
return make_may_raise_wrapper(fun, error_result)
5352
return decorator
5453

55-
moduletype = type(sys)
56-
57-
def _PyModule_CreateInitialized_PyModule_New(name):
58-
# see CPython's Objects/moduleobject.c - _PyModule_CreateInitialized for
59-
# comparison how they handle _Py_PackageContext
60-
if _imp._py_package_context:
61-
if _imp._py_package_context.endswith(name):
62-
name = _imp._py_package_context
63-
_imp._py_package_context = None
64-
new_module = moduletype(name)
65-
# TODO: (tfel) I don't think this is the right place to set it, but somehow
66-
# at least in the import of sklearn.neighbors.dist_metrics through
67-
# sklearn.neighbors.ball_tree the __package__ attribute seems to be already
68-
# set in CPython. To not produce a warning, I'm setting it here, although I
69-
# could not find what CPython really does
70-
if "." in name:
71-
new_module.__package__ = name.rpartition('.')[0]
72-
return new_module
73-
7454
##################### ABSTRACT
7555

7656
@may_raise(-1)

0 commit comments

Comments
 (0)