-
Notifications
You must be signed in to change notification settings - Fork 513
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
Import: option to disable package tree traversal #1182
Comments
With this tree structure :
and this in <!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="/src/brython.js"></script>
</head>
<body onLoad="brython(1)">
<script type="text/python">
import testa.testb.testc
</script>
</body>
</html> the only Ajax calls when loading
I am suprised by so many tries for .js files. What is your tree structure ? |
thank you for looking into this.
|
proposed change to
so the desired functionality for #1182 : would be expressed as per-path config entry : <body onload="brython({
debug : 1,
pythonpath_config : {
'/import' : { use_js: false, use_pyc: false, use_init: false, use_tree: false }
}
})"> |
alternatively, new api in python: brython = globals('__BRYTHON__')
brython.pythonpath_config = {
'/import' : dict( use_js=False, use_pyc=False, use_init=False, use_tree=False )
} |
Files with extension |
when there is a convention: then there is no need for package tree traversal
|
With the commit above, the number of useless Ajax calls is now reduced to the minimum. There still are useless calls, but apart from annoying messages in the browser console, their impact on performance is minimum. As you certainly know, the standard solution to improve importing is to build The use case you describe (only empty |
thank you for thinking about this, and let me try to address your concerns:
well, their impact on my performance is maximum - annoying messages are a major work disruption
that would destroy the initial attractiveness of
well, since this feature requires active opt-in, the responsibility stays with the developer
sure, but this scenario only means that the convention was broken, again,
current interface is not much different from the proposed: current interface: <body onload="brython({ debug:1, pythonpath:[ '/import' ] })"> proposed interface in <body onload="brython({ debug:1, pythonpath_config: { '/import': {use_tree=false} } })"> proposed interface in brython = globals('__BRYTHON__')
brython.pythonpath_config = {
'/import' : dict( use_tree=False )
} |
If I understand your message correctly, the useless Ajax calls have no impact on the response time of your application (this is what I mean with "performance"), it's just that you would prefer not to see them in the console. Am I correct ? |
yes, correct |
Instead of adding a new option to Here is an example of a path finder that does the same as the current default finder, but written in Python (I had to make a few changes in commit 561b452 to make it work): import sys
from browser import ajax
req = ajax.Ajax()
class Finder:
"""Meta path finder, searches Python modules or packages in the
application directory."""
@classmethod
def find_spec(cls, fullname, path=None):
url = fullname.replace(".", "/")
for end in ["", "/__init__"]:
# blocking Ajax call
req.open("GET", url + end + ".py", False)
req.send()
if req.readyState == 4 and req.status == 200:
spec = ModuleSpec(fullname, Finder)
spec.cached = False
spec.has_location = True
spec.loader_state = {
"req": req,
"path": fullname,
"is_package": end != ""
}
spec.origin = url
spec.parent = fullname
spec.submodule_search_locations = None
return spec
@classmethod
def create_module(cls, spec):
pass
@classmethod
def exec_module(cls, module):
spec = module.__spec__
if spec.loader_state["is_package"]:
module.__path__ = [spec.loader_state["path"]]
sys.modules[spec.name] = module
ns = {}
# execute source code of Python module
exec(spec.loader_state["req"].responseText, ns)
for key, value in ns.items():
setattr(module, key, value)
class ModuleSpec:
def __init__(self, name, loader):
self.name = name
self.loader = loader
# replace default path finder
sys.meta_path[-1] = Finder You can adapt it to avoid searching |
|
You can avoid importing sys and replace sys.modules[spec.name] = module by __BRYTHON__.imported[spec.name] = module but I'm afraid you will still have an objection ;-) |
no, no objection (for now), sorry! :-) looking forward for the release to try this out |
This is included in release 3.7.5. Can we close the issue ? |
yes, thank you |
when there is a convention:
a) all user provided
__init__.py
are emptyb)
import a.b.c
only meansGET /a/b/c.py
c)
stdlib
is pre-loaded and is not subject to thisthen there is no need for package tree traversal and endless
404
:py_import.js
, etc, there seems no easy way to have that functionality:https://github.com/brython-dev/brython/blob/master/www/src/py_import.js
The text was updated successfully, but these errors were encountered: