Remove EGG_MODULES to rely only on imported module path
This commit is contained in:
+2
-2
@@ -33,7 +33,7 @@ if options.coroutine:
|
||||
from gevent import monkey
|
||||
monkey.patch_all()
|
||||
|
||||
from trytond.modules import get_module_info, get_module_list
|
||||
from trytond.modules import get_module_info, get_modules
|
||||
from trytond.pool import Pool
|
||||
# Import trytond things after it is configured
|
||||
from trytond.wsgi import app
|
||||
@@ -67,7 +67,7 @@ with commandline.pidfile(options):
|
||||
else:
|
||||
ssl_args = {}
|
||||
if options.dev and not options.coroutine:
|
||||
for module in get_module_list():
|
||||
for module in get_modules():
|
||||
info = get_module_info(module)
|
||||
for ext in ['xml',
|
||||
'fodt', 'odt', 'fodp', 'odp', 'fods', 'ods', 'fodg', 'odg',
|
||||
|
||||
@@ -25,8 +25,8 @@ def database_completer(parsed_args, **kwargs):
|
||||
|
||||
|
||||
def module_completer(**kwargs):
|
||||
from trytond.modules import get_module_list
|
||||
return get_module_list()
|
||||
from trytond.modules import get_modules
|
||||
return get_modules()
|
||||
|
||||
|
||||
def language_completer(**kwargs):
|
||||
|
||||
@@ -239,7 +239,7 @@ class Lang(DeactivableMixin, ModelSQL, ModelView):
|
||||
modules = Module.search([
|
||||
('state', '=', 'activated'),
|
||||
])
|
||||
modules = [m.name for m in modules]
|
||||
modules = {m.name for m in modules}
|
||||
for node in create_graph(modules):
|
||||
load_translations(pool, node, codes)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import ModelSQL, ModelView, Unique, fields, sequence_ordered
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.modules import get_module_info, get_module_list
|
||||
from trytond.modules import get_module_info, get_modules
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Eval
|
||||
from trytond.rpc import RPC
|
||||
@@ -243,7 +243,7 @@ class Module(ModelSQL, ModelView):
|
||||
"Update the list of available modules"
|
||||
pool = Pool()
|
||||
Dependency = pool.get('ir.module.dependency')
|
||||
module_names = get_module_list(with_test=Pool.test)
|
||||
module_names = get_modules(with_test=Pool.test)
|
||||
for sub_module_names in grouped_slice(module_names):
|
||||
cls.delete(cls.search([
|
||||
('state', '!=', 'activated'),
|
||||
|
||||
@@ -221,9 +221,9 @@ class View(ModelSQL, ModelView):
|
||||
|
||||
@property
|
||||
def _module_index(self):
|
||||
from trytond.modules import create_graph, get_module_list
|
||||
from trytond.modules import create_graph, get_modules
|
||||
if self.__class__.__module_index is None:
|
||||
graph = create_graph(get_module_list(with_test=Pool.test))
|
||||
graph = create_graph(get_modules(with_test=Pool.test))
|
||||
modules = [m.name for m in graph]
|
||||
self.__class__.__module_index = {
|
||||
m: i for i, m in enumerate(reversed(modules))}
|
||||
|
||||
@@ -5,10 +5,13 @@ import importlib
|
||||
import itertools
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from glob import iglob
|
||||
from importlib.machinery import SOURCE_SUFFIXES, FileFinder, SourceFileLoader
|
||||
|
||||
try:
|
||||
import pkg_resources
|
||||
except ImportError:
|
||||
pkg_resources = None
|
||||
|
||||
from sql import Table
|
||||
from sql.functions import CurrentTimestamp
|
||||
@@ -45,40 +48,6 @@ def update_egg_modules():
|
||||
update_egg_modules()
|
||||
|
||||
|
||||
def import_module(name, fullname=None):
|
||||
if fullname is None:
|
||||
fullname = 'trytond.modules.' + name
|
||||
try:
|
||||
module = importlib.import_module(fullname)
|
||||
except ImportError:
|
||||
if name not in EGG_MODULES:
|
||||
raise
|
||||
ep = EGG_MODULES[name]
|
||||
# Can not use ep.load because modules are declared in an importable
|
||||
# path and it can not import submodule.
|
||||
path = os.path.join(
|
||||
ep.dist.location, *ep.module_name.split('.')[:-1])
|
||||
if not os.path.isdir(path):
|
||||
# Find module in path
|
||||
for path in sys.path:
|
||||
path = os.path.join(
|
||||
path, *ep.module_name.split('.')[:-1])
|
||||
if os.path.isdir(os.path.join(path, name)):
|
||||
break
|
||||
else:
|
||||
# When testing modules from setuptools location is the
|
||||
# module directory
|
||||
path = os.path.dirname(ep.dist.location)
|
||||
spec = FileFinder(
|
||||
path, (SourceFileLoader, SOURCE_SUFFIXES)
|
||||
).find_spec(fullname)
|
||||
if spec.loader:
|
||||
module = spec.loader.load_module()
|
||||
else:
|
||||
raise
|
||||
return module
|
||||
|
||||
|
||||
def get_module_info(name):
|
||||
"Return the content of the tryton.cfg"
|
||||
module_config = configparser.ConfigParser()
|
||||
@@ -139,20 +108,19 @@ class Node(list):
|
||||
super(Node, self).append(node)
|
||||
|
||||
|
||||
def create_graph(module_list):
|
||||
module_list = set(module_list)
|
||||
def create_graph(modules):
|
||||
all_deps = set()
|
||||
graph = Graph()
|
||||
for module in module_list:
|
||||
for module in modules:
|
||||
info = get_module_info(module)
|
||||
deps = info.get('depends', []) + [
|
||||
d for d in info.get('extras_depend', []) if d in module_list]
|
||||
d for d in info.get('extras_depend', []) if d in modules]
|
||||
node = graph.add(module, deps)
|
||||
assert node.info is None
|
||||
node.info = info
|
||||
all_deps.update(deps)
|
||||
|
||||
missing = all_deps - module_list
|
||||
missing = all_deps - modules
|
||||
if missing:
|
||||
raise MissingDependenciesException(list(missing))
|
||||
return graph
|
||||
@@ -323,8 +291,8 @@ def load_module_graph(graph, pool, update=None, lang=None):
|
||||
logger.info('all modules loaded')
|
||||
|
||||
|
||||
def get_module_list(with_test=False):
|
||||
module_list = set()
|
||||
def get_modules(with_test=False):
|
||||
modules = {'ir', 'res'}
|
||||
if os.path.exists(MODULES_PATH) and os.path.isdir(MODULES_PATH):
|
||||
for file in os.listdir(MODULES_PATH):
|
||||
if file.startswith('.'):
|
||||
@@ -332,14 +300,13 @@ def get_module_list(with_test=False):
|
||||
if file == '__pycache__':
|
||||
continue
|
||||
if os.path.isdir(OPJ(MODULES_PATH, file)):
|
||||
module_list.add(file)
|
||||
update_egg_modules()
|
||||
module_list.update(EGG_MODULES.keys())
|
||||
module_list.add('ir')
|
||||
module_list.add('res')
|
||||
modules.add(file)
|
||||
if pkg_resources:
|
||||
for ep in pkg_resources.iter_entry_points('trytond.modules'):
|
||||
modules.add(ep.name)
|
||||
if with_test:
|
||||
module_list.add('tests')
|
||||
return list(module_list)
|
||||
modules.add('tests')
|
||||
return modules
|
||||
|
||||
|
||||
def register_classes(with_test=False):
|
||||
@@ -354,19 +321,19 @@ def register_classes(with_test=False):
|
||||
import trytond.tests
|
||||
trytond.tests.register()
|
||||
|
||||
for node in create_graph(get_module_list(with_test=with_test)):
|
||||
module = node.name
|
||||
logger.info('%s:registering classes', module)
|
||||
for node in create_graph(get_modules(with_test=with_test)):
|
||||
module_name = node.name
|
||||
logger.info('%s:registering classes', module_name)
|
||||
|
||||
if module in ('ir', 'res', 'tests'):
|
||||
MODULES.append(module)
|
||||
if module_name in ('ir', 'res', 'tests'):
|
||||
MODULES.append(module_name)
|
||||
continue
|
||||
|
||||
the_module = import_module(module)
|
||||
module = importlib.import_module(f'trytond.modules.{module_name}')
|
||||
# Some modules register nothing in the Pool
|
||||
if hasattr(the_module, 'register'):
|
||||
the_module.register()
|
||||
MODULES.append(module)
|
||||
if hasattr(module, 'register'):
|
||||
module.register()
|
||||
MODULES.append(module_name)
|
||||
|
||||
|
||||
def load_modules(
|
||||
@@ -392,12 +359,12 @@ def load_modules(
|
||||
cursor.execute(*ir_module.select(ir_module.name,
|
||||
where=ir_module.state.in_(('activated', 'to upgrade',
|
||||
'to remove'))))
|
||||
module_list = [name for (name,) in cursor]
|
||||
modules = {name for (name,) in cursor}
|
||||
graph = None
|
||||
while graph is None:
|
||||
module_list += update
|
||||
modules.update(update)
|
||||
try:
|
||||
graph = create_graph(module_list)
|
||||
graph = create_graph(modules)
|
||||
except MissingDependenciesException as e:
|
||||
if not activatedeps:
|
||||
raise
|
||||
|
||||
@@ -8,7 +8,6 @@ import importlib
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import types
|
||||
import unicodedata
|
||||
import warnings
|
||||
@@ -32,7 +31,6 @@ def file_open(name, mode="r", subdir='modules', encoding=None):
|
||||
|
||||
def find_path(name, subdir='modules', _test=os.path.isfile):
|
||||
"Return path from the root directory, using subdir folder"
|
||||
from trytond.modules import EGG_MODULES
|
||||
root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
def secure_join(root, *paths):
|
||||
@@ -43,45 +41,31 @@ def find_path(name, subdir='modules', _test=os.path.isfile):
|
||||
raise IOError("Permission denied: %s" % name)
|
||||
return path
|
||||
|
||||
egg_name = False
|
||||
if subdir == 'modules':
|
||||
module_name = name.split(os.sep)[0]
|
||||
if module_name in EGG_MODULES:
|
||||
epoint = EGG_MODULES[module_name]
|
||||
location = os.path.dirname(epoint.load().__file__)
|
||||
mod_path = os.path.join(location,
|
||||
*epoint.module_name.split('.')[:-1])
|
||||
mod_path = os.path.abspath(mod_path)
|
||||
egg_name = secure_join(mod_path, name)
|
||||
if not _test(egg_name):
|
||||
# Find module in path
|
||||
for path in sys.path:
|
||||
mod_path = os.path.join(path,
|
||||
*epoint.module_name.split('.')[:-1])
|
||||
mod_path = os.path.abspath(mod_path)
|
||||
egg_name = secure_join(mod_path, name)
|
||||
if _test(egg_name):
|
||||
break
|
||||
if not _test(egg_name):
|
||||
# When testing modules from setuptools location is the
|
||||
# module directory
|
||||
egg_name = secure_join(
|
||||
os.path.dirname(location), name)
|
||||
|
||||
if subdir:
|
||||
if (subdir == 'modules'
|
||||
and (name.startswith('ir' + os.sep)
|
||||
or name.startswith('res' + os.sep)
|
||||
or name.startswith('tests' + os.sep))):
|
||||
name = secure_join(root_path, name)
|
||||
if subdir == 'modules':
|
||||
try:
|
||||
module_name, module_path = name.split(os.sep, 1)
|
||||
except ValueError:
|
||||
module_name, module_path = name, None
|
||||
if module_name in {'ir', 'res', 'tests'}:
|
||||
path = secure_join(root_path, module_name, module_path)
|
||||
else:
|
||||
try:
|
||||
module = importlib.import_module(
|
||||
f'trytond.modules.{module_name}')
|
||||
except ModuleNotFoundError:
|
||||
path = secure_join(root_path, subdir, name)
|
||||
else:
|
||||
path = os.path.dirname(module.__file__)
|
||||
if module_path:
|
||||
path = secure_join(path, module_path)
|
||||
else:
|
||||
name = secure_join(root_path, subdir, name)
|
||||
path = secure_join(root_path, subdir, name)
|
||||
else:
|
||||
name = secure_join(root_path, name)
|
||||
path = secure_join(root_path, name)
|
||||
|
||||
for path in [name, egg_name]:
|
||||
if path and _test(path):
|
||||
return path
|
||||
if _test(path):
|
||||
return path
|
||||
else:
|
||||
raise FileNotFoundError("No such file or directory: %r" % name)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user