Skip to content

Commit

Permalink
Fixed loading of modules from subfolders. Fixed delegation of dotted …
Browse files Browse the repository at this point in the history
…module name to Jython's imp module in import.c. Also implemented public API functions PyImport_Import and PyImport_ReloadModule in import.c.
  • Loading branch information
Stewori committed Apr 14, 2016
1 parent df5f3b8 commit 66a74e0
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 39 deletions.
6 changes: 5 additions & 1 deletion JyNI-C/include/JythonObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,13 @@ extern jclass pyBufferClass;
extern jclass pyMemoryViewClass;

extern jclass __builtin__Class;
extern jmethodID __builtin__Import;
//extern jmethodID __builtin__Import;
extern jmethodID __builtin__ImportLevel;

extern jclass impClass;
extern jmethodID imp_importName;
extern jmethodID imp_reload;

extern jclass threadStateCurExcInfoClass;
extern jfieldID threadStateCurExcInfo_curexc_type;
extern jfieldID threadStateCurExcInfo_curexc_value;
Expand Down
21 changes: 16 additions & 5 deletions JyNI-C/src/JyNI.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobject JyNI_loadModule(JNIEnv *env, jclass class, jstring moduleName, jstring m
//jputs("JyNI_loadModule...");
//JyNI_jprintJ(moduleName);
// jputsLong(tstate);
ENTER_JyNI
RE_ENTER_JyNI
if (PyErr_Occurred()) jputs("PyErrOccured01 (beginning of JyNI_loadModule)");//this should never happen!
const char* utf_string;
utf_string = (*env)->GetStringUTFChars(env, moduleName, NULL);
Expand Down Expand Up @@ -93,7 +93,7 @@ jobject JyNI_loadModule(JNIEnv *env, jclass class, jstring moduleName, jstring m
// Attempt to load a module statically linked into JyNI.so:
er = _PyImport_LoadDynamicModuleJy(mName, NULL, NULL);

LEAVE_JyNI
RE_LEAVE_JyNI
return er;
}

Expand Down Expand Up @@ -3371,9 +3371,13 @@ jclass pyBufferClass;
jclass pyMemoryViewClass;

jclass __builtin__Class;
jmethodID __builtin__Import;
//jmethodID __builtin__Import;
jmethodID __builtin__ImportLevel;

jclass impClass;
jmethodID imp_importName;
jmethodID imp_reload;

jclass exceptionsClass;
jmethodID exceptionsKeyError;
jmethodID exceptionsKeyError__str__;
Expand Down Expand Up @@ -4329,9 +4333,16 @@ inline jint initJythonObjects(JNIEnv *env)
if (__builtin__ClassLocal == NULL) { return JNI_ERR;}
__builtin__Class = (jclass) (*env)->NewWeakGlobalRef(env, __builtin__ClassLocal);
(*env)->DeleteLocalRef(env, __builtin__ClassLocal);
__builtin__Import = (*env)->GetStaticMethodID(env, __builtin__Class, "__import__", "(Ljava/lang/String;)Lorg/python/core/PyObject;");
//__builtin__Import = (*env)->GetStaticMethodID(env, __builtin__Class, "__import__", "(Ljava/lang/String;)Lorg/python/core/PyObject;");
__builtin__ImportLevel = (*env)->GetStaticMethodID(env, __builtin__Class, "__import__", "(Ljava/lang/String;Lorg/python/core/PyObject;Lorg/python/core/PyObject;Lorg/python/core/PyObject;I)Lorg/python/core/PyObject;");

jclass impClassLocal = (*env)->FindClass(env, "org/python/core/imp");
if (!impClassLocal) return JNI_ERR;
impClass = (jclass) (*env)->NewWeakGlobalRef(env, impClassLocal);
(*env)->DeleteLocalRef(env, impClassLocal);
imp_importName = (*env)->GetStaticMethodID(env, impClass, "importName", "(Ljava/lang/String;Z)Lorg/python/core/PyObject;");
imp_reload = (*env)->GetStaticMethodID(env, impClass, "reload", "(Lorg/python/core/PyModule;)Lorg/python/core/PyObject;");

jclass exceptionsClassLocal = (*env)->FindClass(env, "org/python/core/exceptions");
if (exceptionsClassLocal == NULL) { return JNI_ERR;}
exceptionsClass = (jclass) (*env)->NewWeakGlobalRef(env, exceptionsClassLocal);
Expand Down Expand Up @@ -4444,7 +4455,7 @@ int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */
int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
int Py_FrozenFlag; /* Needed by getpath.c */
int Py_UnicodeFlag = 0; /* Needed by compile.c */
int Py_OptimizeFlag = 0; /* Usually in compile.c */
int Py_OptimizeFlag = 0; /* Originally hosted in compile.c */
int Py_IgnoreEnvironmentFlag = 0; /* e.g. PYTHONPATH, PYTHONHOME */
/* _XXX Py_QnewFlag should go away in 2.3. It's true iff -Qnew is passed,
on the command line, and is used in 2.2 by ceval.c to make all "/" divisions
Expand Down
68 changes: 39 additions & 29 deletions JyNI-C/src/Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -2167,10 +2167,15 @@ PyImport_AddModule(const char *name)
PyObject *
PyImport_ImportModule(const char *name)
{
// jputs(__FUNCTION__);
// jputs(name);
env(NULL);
return JyNI_PyObject_FromJythonPyObject(
(*env)->CallStaticObjectMethod(env, __builtin__Class,
__builtin__Import, (*env)->NewStringUTF(env, name)));
PyObject* result = JyNI_PyObject_FromJythonPyObject(
(*env)->CallStaticObjectMethod(env, impClass,
imp_importName, (*env)->NewStringUTF(env, name), JNI_FALSE));
// if (!result) jputs("Result is NULL");
// else jputs(PyModule_GetName(result));
return result;
// PyObject *pname;
// PyObject *result;
//
Expand Down Expand Up @@ -2767,14 +2772,18 @@ PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
//
// return m;
//}
//
//
///* Re-import a module of any kind and return its module object, WITH
// INCREMENTED REFERENCE COUNT */
//
//PyObject *
//PyImport_ReloadModule(PyObject *m)
//{


/* Re-import a module of any kind and return its module object, WITH
INCREMENTED REFERENCE COUNT */

PyObject *
PyImport_ReloadModule(PyObject *m)
{
env(NULL);
return JyNI_PyObject_FromJythonPyObject(
(*env)->CallObjectMethod(env, impClass, imp_reload,
JyNI_JythonPyObject_FromPyObject(m)));
// PyInterpreterState *interp = PyThreadState_Get()->interp;
// PyObject *modules_reloading = interp->modules_reloading;
// PyObject *modules = PyImport_GetModuleDict();
Expand Down Expand Up @@ -2872,21 +2881,22 @@ PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
// imp_modules_reloading_clear();
// PyMem_FREE(buf);
// return newm;
//}
//
//
///* Higher-level import emulator which emulates the "import" statement
// more accurately -- it invokes the __import__() function from the
// builtins of the current globals. This means that the import is
// done using whatever import hooks are installed in the current
// environment, e.g. by "rexec".
// A dummy list ["__doc__"] is passed as the 4th argument so that
// e.g. PyImport_Import(PyString_FromString("win32com.client.gencache"))
// will return <module "gencache"> instead of <module "win32com">. */
//
//PyObject *
//PyImport_Import(PyObject *module_name)
//{
}


/* Higher-level import emulator which emulates the "import" statement
more accurately -- it invokes the __import__() function from the
builtins of the current globals. This means that the import is
done using whatever import hooks are installed in the current
environment, e.g. by "rexec".
A dummy list ["__doc__"] is passed as the 4th argument so that
e.g. PyImport_Import(PyString_FromString("win32com.client.gencache"))
will return <module "gencache"> instead of <module "win32com">. */

PyObject *
PyImport_Import(PyObject *module_name)
{
return PyImport_ImportModule(PyString_AS_STRING(module_name));
// static PyObject *silly_list = NULL;
// static PyObject *builtins_str = NULL;
// static PyObject *import_str = NULL;
Expand Down Expand Up @@ -2949,9 +2959,9 @@ PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
// Py_XDECREF(import);
//
// return r;
//}
//
//
}


///* Module 'imp' provides Python access to the primitives used for
// importing modules.
//*/
Expand Down
24 changes: 21 additions & 3 deletions JyNI-Java/src/JyNI/JyNIImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public PyObject find_module(String name) {
* otherwise
*/
public PyObject find_module(String name, PyObject path) {
// System.out.println("find... "+name);
// System.out.println("JyNI find... "+name);
if (dynModules.containsKey(name)) return this;
/*Py.writeDebug("import", "trying " + name
+ " in packagemanager for path " + path);
Expand All @@ -130,9 +130,22 @@ public PyObject find_module(String name, PyObject path) {
Py.writeComment("import", "'" + name + "' as java package");
return this;
}*/
String subPath;
String modname;
int lastDot = name.lastIndexOf('.');
if (lastDot == -1) {
subPath = null;
modname = name;
} else {
subPath = name.substring(0, lastDot);
modname = name.substring(lastDot+1);
subPath = subPath.replace('.', File.separatorChar);
}
String suf = "."+getSystemDependendDynamicLibraryExtension();
for (String s : libPaths)
{
// System.out.println("JyNI look in "+s+File.separatorChar+subPath);
if (subPath != null) s = s+File.separatorChar+subPath;
File fl = new File(s);
//if (fl.exists())
String[] ch = fl.list();
Expand All @@ -142,7 +155,7 @@ public PyObject find_module(String name, PyObject path) {
{
//System.out.println("Check: "+m);
//if (m.equals(name+suf))
if (m.startsWith(name+".") && m.endsWith(suf))
if (m.startsWith(modname+".") && m.endsWith(suf))
{
//System.out.println("CPythonExtensionImporter found extension "+name);
//System.out.println("Extension-Path: "+s+File.separatorChar+m);
Expand All @@ -159,7 +172,7 @@ public PyObject find_module(String name, PyObject path) {
}

public PyObject load_module(String name) {
// System.out.println("load... "+name);
// System.out.println("JyNI load... "+name);
// This stuff should move to JyNIInitializer, but there it currently
// breaks sysconfig.py. Will be fixed for Jython 2.7.2.
PySystemState sysState = Py.getSystemState();
Expand All @@ -181,6 +194,11 @@ public PyObject load_module(String name) {
//CPython also works as usual if an ordinary script is called foo.so.
//System.out.println("JyNIImporter.load module: "+name);
JyNIModuleInfo inf = dynModules.get(name);
// if (inf == null) {
// System.out.println("inf null: "+name);
// for (String key: dynModules.keySet())
// System.out.println(key);
// }
if (inf.module == null)
{
inf.module = JyNI.loadModule(name, inf.path, JyTState.prepareNativeThreadState(Py.getThreadState()));
Expand Down
2 changes: 1 addition & 1 deletion JyNI-Java/src/JyNI/JyNIModuleInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class JyNIModuleInfo {
PyModule module;
String name;
String path;

public JyNIModuleInfo(String name, String path, PyModule module)
{
this.name = name;
Expand Down

0 comments on commit 66a74e0

Please sign in to comment.