Reputation: 388
I have a structure like the following:
package/
setup.py
...
package/
__init__.py
_foo.py
subpackage/
__init__.py
bar.py
I am trying to import _foo
from inside bar
:
# bar.py
from .._foo import baz
def myfunc():
baz()
# stuff
while running bar.py
as a script (for example, in a Jupyter Notebook, or even with python bar.py
. If I run this as a module using python -m package.subpackage.bar
it works, but I want to find ways around this). I can't get it to work:
>>> from . import _foo
ImportError: cannot import name '_foo' from '__main__' (unknown location)
# changing __name__ to 'package' doesn't work etiher
>>> from ._foo import baz
ModuleNotFoundError: No module named '__main__._foo'; '__main__' is not a package
>>> from .. import _foo
ValueError: attempted relative import beyond top-level package
>>> sys.path.append(os.getcwd())
>>> from .._foo import baz
ValueError: attempted relative import beyond top-level package
>>> from ._foo import baz
ModuleNotFoundError: No module named 'package'
I intend this to be released for public use, so tricks that only work for my machine are not really useful for me (referring to some sys.path
or PYTHONPATH
tricks I found).
Upvotes: 2
Views: 938
Reputation: 363476
Running scripts from within a package is not supported in Python, because Guido considered that an antipattern.
Existing solutions are running bar as a module:
python -m package.subpackage.bar
Or creating a console_scripts
entrypoint:
# in setup.py
from setuptools import setup
setup(
...
entry_points={
"console_scripts": [
"mybarscript=package.subpackage.bar:myfunc",
]
}
)
When package
is installed, a Python script called mybarscript
will be autogenerated. It will hook into the callable myfunc
defined in bar.py
.
Upvotes: 3