facebookincubator / xar

executable archive format
Other
1.57k stars 55 forks source link

Imports of modules in parent directory not working. #16

Closed c-goosen closed 5 years ago

c-goosen commented 6 years ago

Lets start with very cool project. Been playing around with it and see lots of cases where I needed this in the past.

(venv) api goose$ python setup.py install && python setup.py bdist_xar

(venv) api goose$ ./dist/api.xar
Directories/modules found:  ['ctrl_api', 'setup', 'api', 'compare_api_mappings', 'ctrl_decorators', 'ctrl_logging', 'dev_code', 'endpoints', 'providers', 'settings', 'test_xar', 'tests']
Traceback (most recent call last):
  File "/mnt/xarfuse/uid-501/5348637a/__run_xar_main__.py", line 32, in <module>
    __invoke_main()
  File "/mnt/xarfuse/uid-501/5348637a/__run_xar_main__.py", line 29, in __invoke_main
    runpy._run_module_as_main(module, False)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/mnt/xarfuse/uid-501/5348637a/ctrl_api/api.py", line 11, in <module>
    from providers.auth.authenticate import (
ModuleNotFoundError: No module named 'providers'

So what seems to work best is:

try:
    from providers.auth.authenticate import (
        authenticate,
        retrieve_refresh_token
    )
except ImportError:
    from .providers.auth.authenticate import (
        authenticate,
        retrieve_refresh_token
    )

Seems relative imports is the default.

I looked quick and didn't see it mentioned in the docs.

Perhaps mention the relative imports of this is the expected behaviour?

cooperlees commented 6 years ago

Thanks for bringing this up and awesome you're finding XAR useful.

We'll look into it, I feel both importing methods should work. Will see if we can get a fix out or at least work out the root cause as to why this is not working.

c-goosen commented 6 years ago

Ive looked at this from a couple of angles. Tried doing a raw directory too, but haven't given it enough tries.

Let me know if you need more debug info. Could even replicate this in a seperate project.

Thanks CG

terrelln commented 6 years ago

Hi @c-goosen, I'm looking into reproducing your failure. I have a test repo https://github.com/terrelln/xar_test, could you take a look and tell me what I need to change to reproduce your problem?

c-goosen commented 6 years ago

Thanks @terrelln , will fork and try and reproduce tomorrow.

c-goosen commented 6 years ago

@terrelln I have looked at this a couple of ways.

Just some quick debug info: MacOSX Darwin Kernel Version 17.7.0 Python: python3.7 (had a quicklook at 2.7 and seems like the same behaviour). Directory structure: 8 -rw-r--r-- 1 goose staff 140 Aug 7 17:35 README.md 0 drwxr-xr-x 4 goose staff 128 Aug 13 23:46 build 0 drwxr-xr-x 6 goose staff 192 Aug 13 23:48 dist 8 -rw-r--r-- 1 goose staff 802 Aug 13 23:48 setup.py 0 drwxr-xr-x 7 goose staff 224 Aug 7 17:38 venv 0 drwxr-xr-x 7 goose staff 224 Aug 13 23:10 venv2_7 0 drwxr-xr-x 11 goose staff 352 Aug 13 23:48 xar_test 0 drwxr-xr-x 7 goose staff 224 Aug 13 23:46 xar_test.egg-info

So following your example the XARs work 100%, tested in a couple of different ways.

So I think where the problem comes in running python normally vs XARs. Works: goose:xar_test goose$ ./dist/test.xar xar_test.submodule.foo:foo xar_test.bar:bar xar_test.test:main

Doesn't work: goose:xar_test goose$ venv/bin/python xar_test/test.py Traceback (most recent call last): File "xar_test/test.py", line 1, in from xar_test.submodule.foo import foo ModuleNotFoundError: No module named 'xar_test'

or

goose:xar_test goose$ ../venv/bin/python test.py Traceback (most recent call last): File "test.py", line 1, in from xar_test.submodule.foo import foo ModuleNotFoundError: No module named 'xar_test'

Am I missing something here?

Will do some more testing tomorrow.

I also copied the mounted squashfs directory so that I can have a look at how the python script gets called.

c-goosen commented 6 years ago

Just to add some info.

Workdir of XAR: $(pwd) Workdir of python: $(pwd)/test_xar

We could add to the path?

terrelln commented 6 years ago

@c-goosen it seems like you want to be able to run test.py as both a script, and as an entry point in a package.

test.py won't work as a script, since it has imports from the module root xar_test.submodule. If you only use relative imports (import .submodule) it should work both ways you invoke it.

c-goosen commented 6 years ago

The problem I have is this would not really work with an existing project like an API.

Using pycharm as an example, its syntax lynting complains about the imports, but it works in a xar.

So to move an existing project, I would need to change all imports to how the xar requires.

cooperlees commented 5 years ago

I don't see how to implement a fix to your needs. Please reopen if you have a suggestion.