or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

exceptions.mdindex.mdinitialization.mdmemory-management.mdmodules.mdobjects.mdutilities.md

modules.mddocs/

0

# Module and Import System

1

2

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.

3

4

## Capabilities

5

6

### Module Creation and Management

7

8

Functions for creating and managing Python module objects.

9

10

```java { .api }

11

/**

12

* Create new module with object name

13

* @param name - Module name as PyObject

14

* @return New module object, or NULL on error

15

*/

16

public static native PyObject PyModule_NewObject(PyObject name);

17

18

/**

19

* Create new module with string name

20

* @param name - Module name as C string

21

* @return New module object, or NULL on error

22

*/

23

public static native PyObject PyModule_New(String name);

24

25

/**

26

* Get module's dictionary (namespace)

27

* @param module - Module object

28

* @return Module's __dict__ attribute (borrowed reference)

29

*/

30

public static native PyObject PyModule_GetDict(PyObject module);

31

32

/**

33

* Get module name as object

34

* @param module - Module object

35

* @return Module name object, or NULL on error

36

*/

37

public static native PyObject PyModule_GetNameObject(PyObject module);

38

39

/**

40

* Get module name as C string

41

* @param module - Module object

42

* @return Module name string, or NULL on error

43

*/

44

public static native String PyModule_GetName(PyObject module);

45

46

/**

47

* Get module filename object

48

* @param module - Module object

49

* @return Module filename object, or NULL on error

50

*/

51

public static native PyObject PyModule_GetFilenameObject(PyObject module);

52

53

/**

54

* Get module definition structure

55

* @param module - Module object

56

* @return Module definition, or NULL if not applicable

57

*/

58

public static native PyModuleDef PyModule_GetDef(PyObject module);

59

60

/**

61

* Get module state pointer

62

* @param module - Module object

63

* @return Module state pointer, or NULL on error

64

*/

65

public static native Pointer PyModule_GetState(PyObject module);

66

```

67

68

**Usage Example:**

69

70

```java

71

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

72

73

// Create a new module

74

PyObject myModule = PyModule_New("mymodule");

75

if (myModule != null) {

76

// Get module dictionary for adding attributes

77

PyObject moduleDict = PyModule_GetDict(myModule);

78

79

// Add objects to module (see adding objects section below)

80

81

// Get module name

82

String name = PyModule_GetName(myModule);

83

System.out.println("Created module: " + name);

84

}

85

```

86

87

### Adding Objects to Modules

88

89

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

90

91

```java { .api }

92

/**

93

* Add object to module (increments reference)

94

* @param module - Module object

95

* @param name - Attribute name

96

* @param value - Object to add

97

* @return 0 on success, -1 on error

98

*/

99

public static native int PyModule_AddObjectRef(PyObject module, String name, PyObject value);

100

101

/**

102

* Add object to module (convenience function)

103

* @param module - Module object

104

* @param name - Attribute name

105

* @param value - Object to add

106

* @return 0 on success, -1 on error

107

*/

108

public static native int PyModule_Add(PyObject module, String name, PyObject value);

109

110

/**

111

* Add object to module (steals reference)

112

* @param module - Module object

113

* @param name - Attribute name

114

* @param value - Object to add (reference stolen)

115

* @return 0 on success, -1 on error

116

*/

117

public static native int PyModule_AddObject(PyObject module, String name, PyObject value);

118

119

/**

120

* Add integer constant to module

121

* @param module - Module object

122

* @param name - Constant name

123

* @param value - Integer value

124

* @return 0 on success, -1 on error

125

*/

126

public static native int PyModule_AddIntConstant(PyObject module, String name, long value);

127

128

/**

129

* Add string constant to module

130

* @param module - Module object

131

* @param name - Constant name

132

* @param value - String value

133

* @return 0 on success, -1 on error

134

*/

135

public static native int PyModule_AddStringConstant(PyObject module, String name, String value);

136

```

137

138

**Usage Example:**

139

140

```java

141

// Create module and add various objects

142

PyObject module = PyModule_New("example");

143

144

// Add integer constant

145

PyModule_AddIntConstant(module, "VERSION", 100);

146

147

// Add string constant

148

PyModule_AddStringConstant(module, "AUTHOR", "Java Application");

149

150

// Add Python object

151

PyObject myList = PyList_New(0);

152

PyModule_AddObjectRef(module, "data", myList);

153

154

// Add function (assuming you have a function object)

155

PyObject myFunction = createPythonFunction();

156

PyModule_Add(module, "process", myFunction);

157

```

158

159

### Import System

160

161

Functions for importing and managing Python modules and packages.

162

163

```java { .api }

164

/**

165

* Import module by name (equivalent to 'import name')

166

* @param name - Module name

167

* @return Module object, or NULL on error

168

*/

169

public static native PyObject PyImport_ImportModule(String name);

170

171

/**

172

* Import module with full control (equivalent to __import__)

173

* @param name - Module name

174

* @param globals - Global namespace (or NULL)

175

* @param locals - Local namespace (or NULL)

176

* @param fromlist - From-list for relative imports (or NULL)

177

* @param level - Import level (0=absolute, >0=relative)

178

* @return Module object, or NULL on error

179

*/

180

public static native PyObject PyImport_ImportModuleLevel(String name, PyObject globals,

181

PyObject locals, PyObject fromlist, int level);

182

183

/**

184

* Import module using name object

185

* @param name - Module name as PyObject

186

* @return Module object, or NULL on error

187

*/

188

public static native PyObject PyImport_Import(PyObject name);

189

190

/**

191

* Reload existing module

192

* @param module - Module object to reload

193

* @return Reloaded module object, or NULL on error

194

*/

195

public static native PyObject PyImport_ReloadModule(PyObject module);

196

197

/**

198

* Import module without blocking on import lock

199

* @param name - Module name

200

* @return Module object, or NULL on error

201

*/

202

public static native PyObject PyImport_ImportModuleNoBlock(String name);

203

204

/**

205

* Import module from file path

206

* @param name - Module name

207

* @param pathname - Path to module file

208

* @param file - File object (or NULL)

209

* @return Module object, or NULL on error

210

*/

211

public static native PyObject PyImport_ImportModuleEx(String name, PyObject globals,

212

PyObject locals, PyObject fromlist);

213

```

214

215

**Usage Example:**

216

217

```java

218

// Import standard modules

219

PyObject sysModule = PyImport_ImportModule("sys");

220

PyObject osModule = PyImport_ImportModule("os");

221

222

if (sysModule != null) {

223

// Use sys module

224

PyObject sysPath = PyObject_GetAttrString(sysModule, "path");

225

System.out.println("Python sys.path imported successfully");

226

}

227

228

// Import with from-list (equivalent to 'from os import path')

229

PyObject fromList = PyList_New(1);

230

PyList_SetItem(fromList, 0, PyUnicode_FromString("path"));

231

PyObject osPath = PyImport_ImportModuleLevel("os", null, null, fromList, 0);

232

233

// Relative import (equivalent to 'from . import submodule')

234

PyObject relativeModule = PyImport_ImportModuleLevel("submodule",

235

null, null, null, 1);

236

```

237

238

### Import System State

239

240

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

241

242

```java { .api }

243

/**

244

* Get dictionary of imported modules (sys.modules)

245

* @return Dictionary of all imported modules

246

*/

247

public static native PyObject PyImport_GetModuleDict();

248

249

/**

250

* Import frozen module (built-in module)

251

* @param name - Frozen module name

252

* @return 1 if imported, 0 if not found, -1 on error

253

*/

254

public static native int PyImport_ImportFrozenModule(String name);

255

256

/**

257

* Get import library file for dynamic loading

258

* @param name - Module name

259

* @return Module file path, or NULL if not found

260

*/

261

public static native String PyImport_GetMagicTag();

262

263

/**

264

* Execute module as script (__main__)

265

* @param module - Module object to execute

266

* @return 0 on success, -1 on error

267

*/

268

public static native int PyImport_ExecCodeModule(String name, PyObject co);

269

270

/**

271

* Execute module as script with filename

272

* @param name - Module name

273

* @param co - Code object to execute

274

* @param pathname - Path to module file

275

* @return Module object, or NULL on error

276

*/

277

public static native PyObject PyImport_ExecCodeModuleEx(String name, PyObject co, String pathname);

278

```

279

280

### Module Definition Structures

281

282

Key structures used for defining modules and their contents.

283

284

```java { .api }

285

/**

286

* Module definition structure

287

*/

288

class PyModuleDef extends Pointer {

289

// Contains:

290

// - Module name

291

// - Module documentation

292

// - Module size (-1 for single-phase init)

293

// - Method definitions

294

// - Slot definitions

295

// - Traverse function

296

// - Clear function

297

// - Free function

298

}

299

300

/**

301

* Base module definition structure

302

*/

303

class PyModuleDef_Base extends Pointer {

304

// Base fields for all module definitions

305

}

306

307

/**

308

* Module definition slot

309

*/

310

class PyModuleDef_Slot extends Pointer {

311

// Slot identifier and value for module initialization

312

}

313

314

/**

315

* Method definition structure

316

*/

317

class PyMethodDef extends Pointer {

318

// Contains:

319

// - Method name

320

// - Function pointer

321

// - Flags (METH_VARARGS, etc.)

322

// - Documentation string

323

}

324

```

325

326

## Advanced Module Management

327

328

### Module Search and Discovery

329

330

```java

331

public class ModuleDiscovery {

332

333

public static boolean isModuleAvailable(String moduleName) {

334

// Try to import module

335

PyObject module = PyImport_ImportModule(moduleName);

336

337

if (module != null) {

338

return true;

339

} else {

340

// Clear any import error

341

PyErr_Clear();

342

return false;

343

}

344

}

345

346

public static PyObject findModule(String name) {

347

// Check if already imported

348

PyObject modules = PyImport_GetModuleDict();

349

PyObject nameObj = PyUnicode_FromString(name);

350

PyObject existing = PyDict_GetItem(modules, nameObj);

351

352

if (existing != null) {

353

return existing; // Already imported

354

}

355

356

// Try to import

357

return PyImport_ImportModule(name);

358

}

359

}

360

```

361

362

### Dynamic Module Creation

363

364

```java

365

public class DynamicModule {

366

367

public static PyObject createCalculatorModule() {

368

// Create module

369

PyObject module = PyModule_New("calculator");

370

371

if (module == null) return null;

372

373

try {

374

// Add constants

375

PyModule_AddIntConstant(module, "PI_TIMES_100", 314);

376

PyModule_AddStringConstant(module, "VERSION", "1.0");

377

378

// Add data structures

379

PyObject operations = PyList_New(0);

380

PyList_Append(operations, PyUnicode_FromString("add"));

381

PyList_Append(operations, PyUnicode_FromString("subtract"));

382

PyModule_AddObjectRef(module, "operations", operations);

383

384

// Add to sys.modules so it can be imported later

385

PyObject modules = PyImport_GetModuleDict();

386

PyObject nameObj = PyUnicode_FromString("calculator");

387

PyDict_SetItem(modules, nameObj, module);

388

389

return module;

390

391

} catch (Exception e) {

392

return null;

393

}

394

}

395

}

396

```

397

398

### Module Reloading and Hot Updates

399

400

```java

401

public class ModuleReloader {

402

403

public static boolean reloadModule(String moduleName) {

404

// Get existing module

405

PyObject modules = PyImport_GetModuleDict();

406

PyObject nameObj = PyUnicode_FromString(moduleName);

407

PyObject existingModule = PyDict_GetItem(modules, nameObj);

408

409

if (existingModule == null) {

410

// Module not loaded, just import it

411

PyObject newModule = PyImport_ImportModule(moduleName);

412

return newModule != null;

413

}

414

415

// Reload existing module

416

PyObject reloaded = PyImport_ReloadModule(existingModule);

417

return reloaded != null;

418

}

419

420

public static void hotUpdateModule(String moduleName) {

421

// Remove from sys.modules to force reimport

422

PyObject modules = PyImport_GetModuleDict();

423

PyObject nameObj = PyUnicode_FromString(moduleName);

424

425

if (PyDict_Contains(modules, nameObj)) {

426

PyDict_DelItem(modules, nameObj);

427

}

428

429

// Re-import fresh copy

430

PyObject fresh = PyImport_ImportModule(moduleName);

431

432

if (fresh == null) {

433

System.err.println("Failed to hot update module: " + moduleName);

434

PyErr_Clear();

435

}

436

}

437

}

438

```

439

440

### Package and Namespace Management

441

442

```java

443

public class PackageManager {

444

445

public static PyObject createPackage(String packageName, String[] submodules) {

446

// Create main package module

447

PyObject package = PyModule_New(packageName);

448

if (package == null) return null;

449

450

// Set __path__ attribute for package

451

PyObject path = PyList_New(0);

452

PyModule_AddObjectRef(package, "__path__", path);

453

454

// Add to sys.modules

455

PyObject modules = PyImport_GetModuleDict();

456

PyObject nameObj = PyUnicode_FromString(packageName);

457

PyDict_SetItem(modules, nameObj, package);

458

459

// Create submodules

460

for (String submoduleName : submodules) {

461

String fullName = packageName + "." + submoduleName;

462

PyObject submodule = PyModule_New(fullName);

463

464

if (submodule != null) {

465

// Set __package__ attribute

466

PyModule_AddStringConstant(submodule, "__package__", packageName);

467

468

// Add to sys.modules

469

PyObject subNameObj = PyUnicode_FromString(fullName);

470

PyDict_SetItem(modules, subNameObj, submodule);

471

472

// Add reference in parent package

473

PyModule_AddObjectRef(package, submoduleName, submodule);

474

}

475

}

476

477

return package;

478

}

479

480

public static boolean importFromPackage(String packageName, String itemName) {

481

// Equivalent to 'from package import item'

482

PyObject fromList = PyList_New(1);

483

PyList_SetItem(fromList, 0, PyUnicode_FromString(itemName));

484

485

PyObject result = PyImport_ImportModuleLevel(packageName,

486

null, null, fromList, 0);

487

488

boolean success = (result != null);

489

if (!success) {

490

PyErr_Clear();

491

}

492

493

return success;

494

}

495

}

496

```

497

498

### Module Introspection

499

500

```java

501

public class ModuleIntrospection {

502

503

public static void inspectModule(PyObject module) {

504

if (module == null) return;

505

506

// Get module name

507

String name = PyModule_GetName(module);

508

System.out.println("Module: " + name);

509

510

// Get module dictionary

511

PyObject moduleDict = PyModule_GetDict(module);

512

513

// Get all attributes

514

PyObject keys = PyDict_Keys(moduleDict);

515

long keyCount = PyList_Size(keys);

516

517

System.out.println("Attributes (" + keyCount + "):");

518

for (long i = 0; i < keyCount; i++) {

519

PyObject key = PyList_GetItem(keys, i);

520

PyObject value = PyDict_GetItem(moduleDict, key);

521

522

String keyStr = PyUnicode_AsUTF8(key);

523

String typeStr = PyObject_GetAttrString(Py_TYPE(value), "__name__");

524

525

System.out.println(" " + keyStr + ": " + typeStr);

526

}

527

}

528

529

public static String[] getModuleAttributes(PyObject module) {

530

PyObject moduleDict = PyModule_GetDict(module);

531

PyObject keys = PyDict_Keys(moduleDict);

532

long count = PyList_Size(keys);

533

534

String[] attributes = new String[(int)count];

535

for (int i = 0; i < count; i++) {

536

PyObject key = PyList_GetItem(keys, i);

537

attributes[i] = PyUnicode_AsUTF8(key);

538

}

539

540

return attributes;

541

}

542

}

543

```

544

545

## Error Handling and Best Practices

546

547

### Safe Module Operations

548

549

```java

550

public class SafeModuleOperations {

551

552

public static PyObject safeImport(String moduleName) {

553

PyObject module = PyImport_ImportModule(moduleName);

554

555

if (module == null) {

556

// Handle import error

557

if (PyErr_Occurred() != null) {

558

System.err.println("Failed to import " + moduleName);

559

PyErr_Clear();

560

}

561

return null;

562

}

563

564

return module;

565

}

566

567

public static boolean safeAddToModule(PyObject module, String name, PyObject value) {

568

if (module == null || value == null) {

569

return false;

570

}

571

572

int result = PyModule_AddObjectRef(module, name, value);

573

574

if (result < 0) {

575

System.err.println("Failed to add " + name + " to module");

576

if (PyErr_Occurred() != null) {

577

PyErr_Clear();

578

}

579

return false;

580

}

581

582

return true;

583

}

584

}

585

```

586

587

### Module Cleanup

588

589

```java

590

public class ModuleCleanup {

591

592

public static void cleanupModule(String moduleName) {

593

// Remove from sys.modules

594

PyObject modules = PyImport_GetModuleDict();

595

PyObject nameObj = PyUnicode_FromString(moduleName);

596

597

if (PyDict_Contains(modules, nameObj)) {

598

PyDict_DelItem(modules, nameObj);

599

}

600

601

// Force garbage collection to clean up circular references

602

PyRun_SimpleString("import gc; gc.collect()");

603

}

604

}

605

```

606

607

## Integration Patterns

608

609

### Java-Python Module Bridge

610

611

```java

612

public class JavaPythonBridge {

613

614

public static PyObject createBridgeModule(String name, Object javaObject) {

615

PyObject module = PyModule_New(name);

616

617

if (module != null) {

618

// Add Java object wrapper

619

// This would typically involve creating Python objects

620

// that wrap Java functionality

621

622

// Add module metadata

623

PyModule_AddStringConstant(module, "__java_class__",

624

javaObject.getClass().getName());

625

626

// Add to Python's module system

627

PyObject modules = PyImport_GetModuleDict();

628

PyObject nameObj = PyUnicode_FromString(name);

629

PyDict_SetItem(modules, nameObj, module);

630

}

631

632

return module;

633

}

634

}

635

```

636

637

## Important Notes

638

639

### Reference Management

640

641

- `PyModule_AddObjectRef()` increments the reference count

642

- `PyModule_AddObject()` steals a reference

643

- Module dictionaries return borrowed references via `PyModule_GetDict()`

644

645

### Thread Safety

646

647

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

648

649

### Performance Considerations

650

651

- Module imports can be expensive - cache imported modules when possible

652

- Use `PyImport_GetModuleDict()` to check if a module is already loaded

653

- Consider lazy loading for modules that may not always be needed

654

655

### Namespace Management

656

657

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