custom module deadlock import fix (#1077)

pull/1080/head
Chris Caron 9 months ago committed by GitHub
parent b4798e31b3
commit d5cbab19ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -365,67 +365,66 @@ class PluginManager(metaclass=Singleton):
# end of _import_module()
return
with self._lock:
for _path in paths:
path = os.path.abspath(os.path.expanduser(_path))
if (cache and path in self._paths_previously_scanned) \
or not os.path.exists(path):
# We're done as we've already scanned this
continue
for _path in paths:
path = os.path.abspath(os.path.expanduser(_path))
if (cache and path in self._paths_previously_scanned) \
or not os.path.exists(path):
# We're done as we've already scanned this
continue
# Store our path as a way of hashing it has been handled
self._paths_previously_scanned.add(path)
# Store our path as a way of hashing it has been handled
self._paths_previously_scanned.add(path)
if os.path.isdir(path) and not \
os.path.isfile(os.path.join(path, '__init__.py')):
if os.path.isdir(path) and not \
os.path.isfile(os.path.join(path, '__init__.py')):
logger.debug('Scanning for custom plugins in: %s', path)
for entry in os.listdir(path):
re_match = module_re.match(entry)
if not re_match:
# keep going
logger.trace('Plugin Scan: Ignoring %s', entry)
continue
logger.debug('Scanning for custom plugins in: %s', path)
for entry in os.listdir(path):
re_match = module_re.match(entry)
if not re_match:
# keep going
logger.trace('Plugin Scan: Ignoring %s', entry)
continue
new_path = os.path.join(path, entry)
if os.path.isdir(new_path):
# Update our path
new_path = os.path.join(path, entry, '__init__.py')
if not os.path.isfile(new_path):
logger.trace(
'Plugin Scan: Ignoring %s',
os.path.join(path, entry))
continue
if not cache or \
(cache and new_path not in
self._paths_previously_scanned):
# Load our module
_import_module(new_path)
# Add our subdir path
self._paths_previously_scanned.add(new_path)
else:
if os.path.isdir(path):
# This logic is safe to apply because we already
# validated the directories state above; update our
# path
path = os.path.join(path, '__init__.py')
if cache and path in self._paths_previously_scanned:
new_path = os.path.join(path, entry)
if os.path.isdir(new_path):
# Update our path
new_path = os.path.join(path, entry, '__init__.py')
if not os.path.isfile(new_path):
logger.trace(
'Plugin Scan: Ignoring %s',
os.path.join(path, entry))
continue
self._paths_previously_scanned.add(path)
if not cache or \
(cache and new_path not in
self._paths_previously_scanned):
# Load our module
_import_module(new_path)
# directly load as is
re_match = module_re.match(os.path.basename(path))
# must be a match and must have a .py extension
if not re_match or not re_match.group(1):
# keep going
logger.trace('Plugin Scan: Ignoring %s', path)
# Add our subdir path
self._paths_previously_scanned.add(new_path)
else:
if os.path.isdir(path):
# This logic is safe to apply because we already
# validated the directories state above; update our
# path
path = os.path.join(path, '__init__.py')
if cache and path in self._paths_previously_scanned:
continue
# Load our module
_import_module(path)
self._paths_previously_scanned.add(path)
# directly load as is
re_match = module_re.match(os.path.basename(path))
# must be a match and must have a .py extension
if not re_match or not re_match.group(1):
# keep going
logger.trace('Plugin Scan: Ignoring %s', path)
continue
# Load our module
_import_module(path)
return None

@ -615,6 +615,68 @@ def test_apprise_cli_nux_env(tmpdir):
assert result.exit_code == 0
def test_apprise_cli_modules(tmpdir):
"""
CLI: --plugin (-P)
"""
runner = CliRunner()
#
# Loading of modules works correctly
#
notify_cmod_base = tmpdir.mkdir('cli_modules')
notify_cmod = notify_cmod_base.join('hook.py')
notify_cmod.write(cleandoc("""
from apprise.decorators import notify
@notify(on="climod")
def mywrapper(body, title, notify_type, *args, **kwargs):
pass
"""))
result = runner.invoke(cli.main, [
'--plugin-path', str(notify_cmod),
'-t', 'title',
'-b', 'body',
'climod://',
])
assert result.exit_code == 0
# Test -P
result = runner.invoke(cli.main, [
'-P', str(notify_cmod),
'-t', 'title',
'-b', 'body',
'climod://',
])
assert result.exit_code == 0
# Test double hooks
notify_cmod2 = notify_cmod_base.join('hook2.py')
notify_cmod2.write(cleandoc("""
from apprise.decorators import notify
@notify(on="climod2")
def mywrapper(body, title, notify_type, *args, **kwargs):
pass
"""))
result = runner.invoke(cli.main, [
'--plugin-path', str(notify_cmod),
'--plugin-path', str(notify_cmod2),
'-t', 'title',
'-b', 'body',
'climod://',
'climod2://',
])
assert result.exit_code == 0
def test_apprise_cli_details(tmpdir):
"""
CLI: --details (-l)

Loading…
Cancel
Save