CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-bytedeco--cpython

JavaCPP bindings for CPython 3.13.5 enabling Java applications to embed Python interpreters and interact with Python objects through the Python C API

Pending
Overview
Eval results
Files

modules.mddocs/

Module and Import System

Python module loading, creation, and import system access. This enables Java applications to work with Python modules and packages, create new modules, and manage the Python import system from Java code.

Capabilities

Module Creation and Management

Functions for creating and managing Python module objects.

/**
 * Create new module with object name
 * @param name - Module name as PyObject
 * @return New module object, or NULL on error
 */
public static native PyObject PyModule_NewObject(PyObject name);

/**
 * Create new module with string name
 * @param name - Module name as C string
 * @return New module object, or NULL on error
 */
public static native PyObject PyModule_New(String name);

/**
 * Get module's dictionary (namespace)
 * @param module - Module object
 * @return Module's __dict__ attribute (borrowed reference)
 */
public static native PyObject PyModule_GetDict(PyObject module);

/**
 * Get module name as object
 * @param module - Module object
 * @return Module name object, or NULL on error
 */
public static native PyObject PyModule_GetNameObject(PyObject module);

/**
 * Get module name as C string
 * @param module - Module object
 * @return Module name string, or NULL on error
 */
public static native String PyModule_GetName(PyObject module);

/**
 * Get module filename object
 * @param module - Module object
 * @return Module filename object, or NULL on error
 */
public static native PyObject PyModule_GetFilenameObject(PyObject module);

/**
 * Get module definition structure
 * @param module - Module object
 * @return Module definition, or NULL if not applicable
 */
public static native PyModuleDef PyModule_GetDef(PyObject module);

/**
 * Get module state pointer
 * @param module - Module object
 * @return Module state pointer, or NULL on error
 */
public static native Pointer PyModule_GetState(PyObject module);

Usage Example:

import static org.bytedeco.cpython.global.python.*;

// Create a new module
PyObject myModule = PyModule_New("mymodule");
if (myModule != null) {
    // Get module dictionary for adding attributes
    PyObject moduleDict = PyModule_GetDict(myModule);
    
    // Add objects to module (see adding objects section below)
    
    // Get module name
    String name = PyModule_GetName(myModule);
    System.out.println("Created module: " + name);
}

Adding Objects to Modules

Functions for populating modules with attributes, functions, and constants.

/**
 * Add object to module (increments reference)
 * @param module - Module object
 * @param name - Attribute name
 * @param value - Object to add
 * @return 0 on success, -1 on error
 */
public static native int PyModule_AddObjectRef(PyObject module, String name, PyObject value);

/**
 * Add object to module (convenience function)
 * @param module - Module object
 * @param name - Attribute name
 * @param value - Object to add
 * @return 0 on success, -1 on error
 */
public static native int PyModule_Add(PyObject module, String name, PyObject value);

/**
 * Add object to module (steals reference)
 * @param module - Module object
 * @param name - Attribute name
 * @param value - Object to add (reference stolen)
 * @return 0 on success, -1 on error
 */
public static native int PyModule_AddObject(PyObject module, String name, PyObject value);

/**
 * Add integer constant to module
 * @param module - Module object
 * @param name - Constant name
 * @param value - Integer value
 * @return 0 on success, -1 on error
 */
public static native int PyModule_AddIntConstant(PyObject module, String name, long value);

/**
 * Add string constant to module
 * @param module - Module object
 * @param name - Constant name
 * @param value - String value
 * @return 0 on success, -1 on error
 */
public static native int PyModule_AddStringConstant(PyObject module, String name, String value);

Usage Example:

// Create module and add various objects
PyObject module = PyModule_New("example");

// Add integer constant
PyModule_AddIntConstant(module, "VERSION", 100);

// Add string constant  
PyModule_AddStringConstant(module, "AUTHOR", "Java Application");

// Add Python object
PyObject myList = PyList_New(0);
PyModule_AddObjectRef(module, "data", myList);

// Add function (assuming you have a function object)
PyObject myFunction = createPythonFunction();
PyModule_Add(module, "process", myFunction);

Import System

Functions for importing and managing Python modules and packages.

/**
 * Import module by name (equivalent to 'import name')
 * @param name - Module name
 * @return Module object, or NULL on error
 */
public static native PyObject PyImport_ImportModule(String name);

/**
 * Import module with full control (equivalent to __import__)
 * @param name - Module name
 * @param globals - Global namespace (or NULL)
 * @param locals - Local namespace (or NULL)  
 * @param fromlist - From-list for relative imports (or NULL)
 * @param level - Import level (0=absolute, >0=relative)
 * @return Module object, or NULL on error
 */
public static native PyObject PyImport_ImportModuleLevel(String name, PyObject globals, 
                                                       PyObject locals, PyObject fromlist, int level);

/**
 * Import module using name object
 * @param name - Module name as PyObject
 * @return Module object, or NULL on error
 */
public static native PyObject PyImport_Import(PyObject name);

/**
 * Reload existing module
 * @param module - Module object to reload
 * @return Reloaded module object, or NULL on error
 */
public static native PyObject PyImport_ReloadModule(PyObject module);

/**
 * Import module without blocking on import lock
 * @param name - Module name
 * @return Module object, or NULL on error
 */
public static native PyObject PyImport_ImportModuleNoBlock(String name);

/**
 * Import module from file path
 * @param name - Module name
 * @param pathname - Path to module file
 * @param file - File object (or NULL)
 * @return Module object, or NULL on error
 */
public static native PyObject PyImport_ImportModuleEx(String name, PyObject globals, 
                                                    PyObject locals, PyObject fromlist);

Usage Example:

// Import standard modules
PyObject sysModule = PyImport_ImportModule("sys");
PyObject osModule = PyImport_ImportModule("os");

if (sysModule != null) {
    // Use sys module
    PyObject sysPath = PyObject_GetAttrString(sysModule, "path");
    System.out.println("Python sys.path imported successfully");
}

// Import with from-list (equivalent to 'from os import path')
PyObject fromList = PyList_New(1);
PyList_SetItem(fromList, 0, PyUnicode_FromString("path"));
PyObject osPath = PyImport_ImportModuleLevel("os", null, null, fromList, 0);

// Relative import (equivalent to 'from . import submodule')
PyObject relativeModule = PyImport_ImportModuleLevel("submodule", 
                                                   null, null, null, 1);

Import System State

Functions for accessing and managing the import system's internal state.

/**
 * Get dictionary of imported modules (sys.modules)
 * @return Dictionary of all imported modules
 */
public static native PyObject PyImport_GetModuleDict();

/**
 * Import frozen module (built-in module)
 * @param name - Frozen module name
 * @return 1 if imported, 0 if not found, -1 on error
 */
public static native int PyImport_ImportFrozenModule(String name);

/**
 * Get import library file for dynamic loading
 * @param name - Module name
 * @return Module file path, or NULL if not found
 */
public static native String PyImport_GetMagicTag();

/**
 * Execute module as script (__main__)
 * @param module - Module object to execute
 * @return 0 on success, -1 on error
 */
public static native int PyImport_ExecCodeModule(String name, PyObject co);

/**
 * Execute module as script with filename
 * @param name - Module name
 * @param co - Code object to execute
 * @param pathname - Path to module file
 * @return Module object, or NULL on error
 */
public static native PyObject PyImport_ExecCodeModuleEx(String name, PyObject co, String pathname);

Module Definition Structures

Key structures used for defining modules and their contents.

/**
 * Module definition structure
 */
class PyModuleDef extends Pointer {
    // Contains:
    // - Module name
    // - Module documentation
    // - Module size (-1 for single-phase init)
    // - Method definitions
    // - Slot definitions
    // - Traverse function
    // - Clear function
    // - Free function
}

/**
 * Base module definition structure
 */
class PyModuleDef_Base extends Pointer {
    // Base fields for all module definitions
}

/**
 * Module definition slot
 */
class PyModuleDef_Slot extends Pointer {
    // Slot identifier and value for module initialization
}

/**
 * Method definition structure
 */
class PyMethodDef extends Pointer {
    // Contains:
    // - Method name
    // - Function pointer
    // - Flags (METH_VARARGS, etc.)
    // - Documentation string
}

Advanced Module Management

Module Search and Discovery

public class ModuleDiscovery {
    
    public static boolean isModuleAvailable(String moduleName) {
        // Try to import module
        PyObject module = PyImport_ImportModule(moduleName);
        
        if (module != null) {
            return true;
        } else {
            // Clear any import error
            PyErr_Clear();
            return false;
        }
    }
    
    public static PyObject findModule(String name) {
        // Check if already imported
        PyObject modules = PyImport_GetModuleDict();
        PyObject nameObj = PyUnicode_FromString(name);
        PyObject existing = PyDict_GetItem(modules, nameObj);
        
        if (existing != null) {
            return existing; // Already imported
        }
        
        // Try to import
        return PyImport_ImportModule(name);
    }
}

Dynamic Module Creation

public class DynamicModule {
    
    public static PyObject createCalculatorModule() {
        // Create module
        PyObject module = PyModule_New("calculator");
        
        if (module == null) return null;
        
        try {
            // Add constants
            PyModule_AddIntConstant(module, "PI_TIMES_100", 314);
            PyModule_AddStringConstant(module, "VERSION", "1.0");
            
            // Add data structures
            PyObject operations = PyList_New(0);
            PyList_Append(operations, PyUnicode_FromString("add"));
            PyList_Append(operations, PyUnicode_FromString("subtract"));
            PyModule_AddObjectRef(module, "operations", operations);
            
            // Add to sys.modules so it can be imported later
            PyObject modules = PyImport_GetModuleDict();
            PyObject nameObj = PyUnicode_FromString("calculator");
            PyDict_SetItem(modules, nameObj, module);
            
            return module;
            
        } catch (Exception e) {
            return null;
        }
    }
}

Module Reloading and Hot Updates

public class ModuleReloader {
    
    public static boolean reloadModule(String moduleName) {
        // Get existing module
        PyObject modules = PyImport_GetModuleDict();
        PyObject nameObj = PyUnicode_FromString(moduleName);
        PyObject existingModule = PyDict_GetItem(modules, nameObj);
        
        if (existingModule == null) {
            // Module not loaded, just import it
            PyObject newModule = PyImport_ImportModule(moduleName);
            return newModule != null;
        }
        
        // Reload existing module
        PyObject reloaded = PyImport_ReloadModule(existingModule);
        return reloaded != null;
    }
    
    public static void hotUpdateModule(String moduleName) {
        // Remove from sys.modules to force reimport
        PyObject modules = PyImport_GetModuleDict();
        PyObject nameObj = PyUnicode_FromString(moduleName);
        
        if (PyDict_Contains(modules, nameObj)) {
            PyDict_DelItem(modules, nameObj);
        }
        
        // Re-import fresh copy
        PyObject fresh = PyImport_ImportModule(moduleName);
        
        if (fresh == null) {
            System.err.println("Failed to hot update module: " + moduleName);
            PyErr_Clear();
        }
    }
}

Package and Namespace Management

public class PackageManager {
    
    public static PyObject createPackage(String packageName, String[] submodules) {
        // Create main package module
        PyObject package = PyModule_New(packageName);
        if (package == null) return null;
        
        // Set __path__ attribute for package
        PyObject path = PyList_New(0);
        PyModule_AddObjectRef(package, "__path__", path);
        
        // Add to sys.modules
        PyObject modules = PyImport_GetModuleDict();
        PyObject nameObj = PyUnicode_FromString(packageName);
        PyDict_SetItem(modules, nameObj, package);
        
        // Create submodules
        for (String submoduleName : submodules) {
            String fullName = packageName + "." + submoduleName;
            PyObject submodule = PyModule_New(fullName);
            
            if (submodule != null) {
                // Set __package__ attribute
                PyModule_AddStringConstant(submodule, "__package__", packageName);
                
                // Add to sys.modules
                PyObject subNameObj = PyUnicode_FromString(fullName);
                PyDict_SetItem(modules, subNameObj, submodule);
                
                // Add reference in parent package
                PyModule_AddObjectRef(package, submoduleName, submodule);
            }
        }
        
        return package;
    }
    
    public static boolean importFromPackage(String packageName, String itemName) {
        // Equivalent to 'from package import item'
        PyObject fromList = PyList_New(1);
        PyList_SetItem(fromList, 0, PyUnicode_FromString(itemName));
        
        PyObject result = PyImport_ImportModuleLevel(packageName, 
                                                   null, null, fromList, 0);
        
        boolean success = (result != null);
        if (!success) {
            PyErr_Clear();
        }
        
        return success;
    }
}

Module Introspection

public class ModuleIntrospection {
    
    public static void inspectModule(PyObject module) {
        if (module == null) return;
        
        // Get module name
        String name = PyModule_GetName(module);
        System.out.println("Module: " + name);
        
        // Get module dictionary
        PyObject moduleDict = PyModule_GetDict(module);
        
        // Get all attributes
        PyObject keys = PyDict_Keys(moduleDict);
        long keyCount = PyList_Size(keys);
        
        System.out.println("Attributes (" + keyCount + "):");
        for (long i = 0; i < keyCount; i++) {
            PyObject key = PyList_GetItem(keys, i);
            PyObject value = PyDict_GetItem(moduleDict, key);
            
            String keyStr = PyUnicode_AsUTF8(key);
            String typeStr = PyObject_GetAttrString(Py_TYPE(value), "__name__");
            
            System.out.println("  " + keyStr + ": " + typeStr);
        }
    }
    
    public static String[] getModuleAttributes(PyObject module) {
        PyObject moduleDict = PyModule_GetDict(module);
        PyObject keys = PyDict_Keys(moduleDict);
        long count = PyList_Size(keys);
        
        String[] attributes = new String[(int)count];
        for (int i = 0; i < count; i++) {
            PyObject key = PyList_GetItem(keys, i);
            attributes[i] = PyUnicode_AsUTF8(key);
        }
        
        return attributes;
    }
}

Error Handling and Best Practices

Safe Module Operations

public class SafeModuleOperations {
    
    public static PyObject safeImport(String moduleName) {
        PyObject module = PyImport_ImportModule(moduleName);
        
        if (module == null) {
            // Handle import error
            if (PyErr_Occurred() != null) {
                System.err.println("Failed to import " + moduleName);
                PyErr_Clear();
            }
            return null;
        }
        
        return module;
    }
    
    public static boolean safeAddToModule(PyObject module, String name, PyObject value) {
        if (module == null || value == null) {
            return false;
        }
        
        int result = PyModule_AddObjectRef(module, name, value);
        
        if (result < 0) {
            System.err.println("Failed to add " + name + " to module");
            if (PyErr_Occurred() != null) {
                PyErr_Clear();
            }
            return false;
        }
        
        return true;
    }
}

Module Cleanup

public class ModuleCleanup {
    
    public static void cleanupModule(String moduleName) {
        // Remove from sys.modules
        PyObject modules = PyImport_GetModuleDict();
        PyObject nameObj = PyUnicode_FromString(moduleName);
        
        if (PyDict_Contains(modules, nameObj)) {
            PyDict_DelItem(modules, nameObj);
        }
        
        // Force garbage collection to clean up circular references
        PyRun_SimpleString("import gc; gc.collect()");
    }
}

Integration Patterns

Java-Python Module Bridge

public class JavaPythonBridge {
    
    public static PyObject createBridgeModule(String name, Object javaObject) {
        PyObject module = PyModule_New(name);
        
        if (module != null) {
            // Add Java object wrapper
            // This would typically involve creating Python objects
            // that wrap Java functionality
            
            // Add module metadata
            PyModule_AddStringConstant(module, "__java_class__", 
                                     javaObject.getClass().getName());
            
            // Add to Python's module system
            PyObject modules = PyImport_GetModuleDict();
            PyObject nameObj = PyUnicode_FromString(name);
            PyDict_SetItem(modules, nameObj, module);
        }
        
        return module;
    }
}

Important Notes

Reference Management

  • PyModule_AddObjectRef() increments the reference count
  • PyModule_AddObject() steals a reference
  • Module dictionaries return borrowed references via PyModule_GetDict()

Thread Safety

Module import operations are thread-safe, but module modification should be done carefully in multi-threaded environments.

Performance Considerations

  • Module imports can be expensive - cache imported modules when possible
  • Use PyImport_GetModuleDict() to check if a module is already loaded
  • Consider lazy loading for modules that may not always be needed

Namespace Management

Modules added to sys.modules become available for import by Python code. Remove entries carefully to avoid breaking dependencies.

Install with Tessl CLI

npx tessl i tessl/maven-org-bytedeco--cpython

docs

exceptions.md

index.md

initialization.md

memory-management.md

modules.md

objects.md

utilities.md

tile.json