When fetching code from a server, Brython can't handle namespace package
shlomil opened this issue · comments
As of Python 3.3 package no longer require __init__.py
. A namespace package will be created.
When you fetch code from the server with Brython using import, namespace package will not be detected.
Steps to reproduce:
# in commandline:
> mkdir namespace_mod
> echo "def some_func(): return 'some func'" > namespace_mod/some_module.py
> echo "from namespace_mod.some_module import some_func;print(some_func())" > import_ns_mod.py
> python3 import_ns_mod.py
some func
Now try to run in Brython, adding an HTML with
<script id="main" type="text/python" src="import_ns_mod.py"></script>
# This will try to import and finally throw ModuleNotFoundError
if you convert the package to a regular package by adding an empty __init__.py
:
> touch namespace_mod/__init__.py
In this case Brython will work.
I have read PEP 420 and I'm afraid that it can't be supported by Brython.
In CPython, if a script is in a directory, and this directory has a subdirectory "subdir" (even empty), PEP 420 allows import subdir
, making subdir
a namespace package. The import machinery supports this by detecting that there is a subdirectory "subdir".
In Brython it is impossible to detect if a url corresponds to a directory. An Ajax request to the url (eg host/script_dir/subdir) might return the directory listing, or the content of a file index.html
if it exists, or return an error message, depending on the server configuration.
Unless there is a solution that I don't see at the moment, we will have to add this feature to the list of differences between standard Python and Brython.
I thought it might be tricky or impossible. So this bug should be delth through documentation I guess.
Thanks you Pierre!
Now that I think about it, another fix to the problem may be to provide an additional option to __BRYTHON__.brython()
which will provide the structure of the filesystem at given search path. The option may be a string containing the output of find . -name *.py
and will provide hints to the import system about the file existence and location. This could also avoid other issues i.e when you try to fetch "mymod.py" and get a 404 before trying and finally succeeding to fetch mymod/__init__.py
, for example. It could speed up the execution in such cases.
I think that implementing that will pave the way to implement namespace packages in Brython.