diff --git a/my/core/__main__.py b/my/core/__main__.py index 5bef2fb..15c20bf 100644 --- a/my/core/__main__.py +++ b/my/core/__main__.py @@ -223,6 +223,7 @@ def modules_check(*, verbose: bool, list_all: bool, quick: bool, for_modules: Li from .util import get_stats, HPIModule from .stats import guess_stats + from .error import warn_my_config_import_error mods: Iterable[HPIModule] if len(for_modules) == 0: @@ -243,14 +244,10 @@ def modules_check(*, verbose: bool, list_all: bool, quick: bool, for_modules: Li except Exception as e: # todo more specific command? error(f'{click.style("FAIL", fg="red")}: {m:<50} loading failed{vw}') - if isinstance(e, ImportError): - em = re.match(r"cannot import name '(\w+)' from 'my.config'", str(e)) - if em is not None: - section_name = em.group(1) - eprint(click.style(f"""\ - You're likely missing '{section_name}' section from your config. - See https://github.com/karlicoss/HPI/blob/master/doc/SETUP.org#private-configuration-myconfig\ -""", fg='yellow')) + # check that this is an import error in particular, not because + # of a ModuleNotFoundError because some dependency wasnt installed + if type(e) == ImportError: + warn_my_config_import_error(e) if verbose: tb(e) continue diff --git a/my/core/error.py b/my/core/error.py index 5e358dc..04c3e9f 100644 --- a/my/core/error.py +++ b/my/core/error.py @@ -150,6 +150,25 @@ def error_to_json(e: Exception) -> Json: return {'error': estr} +def warn_my_config_import_error(err: ImportError) -> None: + """ + If the user tried to import something from my.config but it failed, + possibly due to missing the config block in my.config? + """ + import re + import click + if err.name != 'my.config': + return + # parse name that user attempted to import + em = re.match(r"cannot import name '(\w+)' from 'my.config'", str(err)) + if em is not None: + section_name = em.group(1) + click.echo(click.style(f"""\ + You may be missing the '{section_name}' section from your config. + See https://github.com/karlicoss/HPI/blob/master/doc/SETUP.org#private-configuration-myconfig\ +""", fg='yellow'), err=True) + + def test_datetime_errors() -> None: import pytz dt_notz = datetime.now() diff --git a/my/core/source.py b/my/core/source.py index 3748e4d..e3325a7 100644 --- a/my/core/source.py +++ b/my/core/source.py @@ -4,7 +4,7 @@ and yielding nothing (or a default) when its not available """ from typing import Any, Iterator, TypeVar, Callable, Optional, Iterable, Any -from my.core.warnings import warn +from my.core.warnings import medium, warn from functools import wraps # The factory function may produce something that has data @@ -43,20 +43,26 @@ def import_source( try: res = factory_func(**kwargs) yield from res - except ModuleNotFoundError: + except ImportError as err: from . import core_config as CC + from .error import warn_my_config_import_error suppressed_in_conf = False if module_name is not None and CC.config._is_module_active(module_name) is False: suppressed_in_conf = True if not suppressed_in_conf: if module_name is None: - warn(f"Module {factory_func.__qualname__} could not be imported, or isn't configured properly") + medium(f"Module {factory_func.__qualname__} could not be imported, or isn't configured properly") else: - warn(f"""Module {module_name} ({factory_func.__qualname__}) could not be imported, or isn't configured properly\nTo hide this message, add {module_name} to your core config disabled_classes, like: + medium(f"Module {module_name} ({factory_func.__qualname__}) could not be imported, or isn't configured properly") + warn(f"""To hide this message, add {module_name} to your core config disabled_classes, like: class core: disabled_modules = [{repr(module_name)}] """) + # explicitly check if this is a ImportError, and didn't fail + # due to a module not being installed + if type(err) == ImportError: + warn_my_config_import_error(err) yield from default return wrapper return decorator