Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to create a Python extension with multiple files? #647

Open
sk-uma opened this issue Mar 30, 2025 · 4 comments
Open

How to create a Python extension with multiple files? #647

sk-uma opened this issue Mar 30, 2025 · 4 comments

Comments

@sk-uma
Copy link

sk-uma commented Mar 30, 2025

Hi! Thanks for the great project.

I'm trying to create a Python package using Codon. I've written a small example that uses multiple files, but I'm confused about how to build it correctly.

Here's my file structure:

mymodule/
├── __init__.py
└── main.py
setup.py

__init__.py

from .main import MyClass, ack
print("Hello, Codon! in __init__.py")

main.py

print("Hello, Codon! in main.py")

@dataclass(python=True)
class MyClass:
    def __init__(self):
        print("MyClass initialized")

    def say_hello(self):
        print("Hello, Codon!")

def ack(m: int, n: int) -> int:
    if m == 0:
        return n + 1
    elif n == 0:
        return ack(m - 1, 1)
    else:
        return ack(m - 1, ack(m, n - 1))

I followed the documentation and created a setup.py that builds the extension using Codon.
However, when I try to import MyClass or ack, I get an ImportError. It seems that only the file specified in the extension (__init__.py) is being compiled.

What's the proper way to build a Codon-based Python extension that includes multiple files?

The full example is here:
👉 https://github.com/sk-uma/codon-pyext-example

Thanks in advance for any help!

@elisbyberi
Copy link

Make sure not to run test.py in the same folder as the uncompiled Codon mymodule module.

Your example works:

# test.py
import mymodule

Result:

Hello, Codon! in main.py
Hello, Codon! in __init__.py

@sk-uma
Copy link
Author

sk-uma commented Mar 31, 2025

@elisbyberi

Thank you!

Do you know how to import the functions and classes defined in main.py?
As shown in the standard output, main.py is being executed, but when I try to import ack or MyClass, I get an error like this:

>>> from mymodule import ack
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'ack' from 'mymodule'

@elisbyberi
Copy link

ImportError: cannot import name 'ack' from 'mymodule'

You’ve exposed MyClass and ack in __init__.py, but the file doesn’t actually export any class definitions or functions. In a well-structured modular design, nested modules should remain encapsulated.

Python intentionally avoids enforcing such constraints, following its ‘we’re all consenting adults’ philosophy. However, Codon’s static nature makes this approach a poor fit—we should prioritize explicit encapsulation.

@sk-uma
Copy link
Author

sk-uma commented Mar 31, 2025

Thank you, this helped me understand Codon better.
I'll consolidate the public functions into __init__.py.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants