From 21979b72d0dc366da0659c1286869f9798ef27cc Mon Sep 17 00:00:00 2001 From: Sebastian Brodehl Date: Tue, 22 Dec 2020 23:12:45 +0100 Subject: [PATCH 01/26] Run pytest suite. --- .github/workflows/linting-python.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/linting-python.yml b/.github/workflows/linting-python.yml index ee8ccdc7..967af88c 100644 --- a/.github/workflows/linting-python.yml +++ b/.github/workflows/linting-python.yml @@ -39,3 +39,5 @@ jobs: flake8 tests --count --ignore E501 --statistics pylint -d W0511 -d C0114 -d C0116 -d C0115 -d C0301 -d C0103 -d R0913 -d R0914 -d R0902 -d R0912 -d R0801 -d W0212 -d W0223 -d E1101 -d W0221 -d E1102 `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` pylint --exit-zero `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` + - name: Pytest + run: pytest From 2b1ef1eeb982a6db9812aa35e50f5aaa6935805d Mon Sep 17 00:00:00 2001 From: Sebastian Brodehl Date: Tue, 22 Dec 2020 23:16:42 +0100 Subject: [PATCH 02/26] Create pytest.yml --- .github/workflows/pytest.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/pytest.yml diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 00000000..950b85fe --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,34 @@ +name: Testing + +on: [push] + +jobs: + Pytest: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.x + uses: actions/setup-python@v2 + with: + python-version: 3.x + - name: Install dependencies + run: | + python -m pip install --upgrade pip wheel + python -m pip install flake8 pylint pytest + # install deps for pylint + python -m pip install colored + # build and install the package itself + python -m pip install . + - name: Syntax Check of Tests + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 tests --count --select=E9,F63,F7,F82 --show-source --statistics + - name: Static Analysis of Tests (Modules) + run: | + flake8 tests --count --ignore E501 --statistics + pylint -d W0511 -d C0114 -d C0116 -d C0115 -d C0301 -d C0103 -d R0913 -d R0914 -d R0902 -d R0912 -d R0801 -d W0212 -d W0223 -d E1101 -d W0221 -d E1102 `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` + pylint --exit-zero `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` + - name: Pytest + run: pytest From 7bc5647cfa215ef68c0e24b66281aeb0ca32caf5 Mon Sep 17 00:00:00 2001 From: Sebastian Brodehl Date: Tue, 22 Dec 2020 23:17:26 +0100 Subject: [PATCH 03/26] Remove testing from linter. --- .github/workflows/linting-python.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/linting-python.yml b/.github/workflows/linting-python.yml index 967af88c..71ef4bef 100644 --- a/.github/workflows/linting-python.yml +++ b/.github/workflows/linting-python.yml @@ -16,7 +16,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip wheel - python -m pip install flake8 pylint pytest + python -m pip install flake8 pylint # install deps for pylint python -m pip install colored # build and install the package itself @@ -39,5 +39,3 @@ jobs: flake8 tests --count --ignore E501 --statistics pylint -d W0511 -d C0114 -d C0116 -d C0115 -d C0301 -d C0103 -d R0913 -d R0914 -d R0902 -d R0912 -d R0801 -d W0212 -d W0223 -d E1101 -d W0221 -d E1102 `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` pylint --exit-zero `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` - - name: Pytest - run: pytest From 4496f85f860a9cad4b89ea384144170a83ec5708 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Mon, 7 Dec 2020 16:47:28 +0100 Subject: [PATCH 04/26] remove default keyword for any module names --- src/miniflask/miniflask.py | 26 ++++------------------ src/miniflask/modules/settings/__init__.py | 5 +---- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index 92804616..210f47d6 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -230,15 +230,10 @@ def getModuleId(self, module_id): module_ids = self.modules_avail.keys() module = module_id.replace(".", r"\.(.*\.)*") - # first search for a default module - r = re.compile(r"^(.*\.)?%s(\..*)?\.(default|%s)$" % (module, module_id.split(".")[-1])) + # first, try direct identifier + r = re.compile(r"^(.*\.)?%s$" % module) found_modules = list(filter(r.match, module_ids)) - # if no default module found, check for direct identifier - if len(found_modules) == 0: - r = re.compile(r"^(.*\.)?%s$" % module) - found_modules = list(filter(r.match, module_ids)) - # if no default module found, check for related identifier if len(found_modules) == 0: r = re.compile(r"^(.*\.)?%s(\..*)?$" % module) @@ -266,10 +261,6 @@ def getModuleShortId(self, module): raise ValueError(highlight_error() + "Module '%s' not known." % highlight_module(module)) uniqueId = self.modules_avail[module]["id"].split(".") - # modA.default -> modA - if uniqueId[-1] == "default": - uniqueId = uniqueId[:-1] - # find the shortest substring to match a module uniquely for i in range(len(uniqueId) - 1, 0, -1): shortid = ".".join(uniqueId[i:]) @@ -283,17 +274,8 @@ def getModuleShortId(self, module): # maps 'folder.subfolder.module.list.of.vars' to 'folder.subfoldder.module' def _getModuleIdFromVarId(self, varid, varid_list=None, scope=None): # noqa: C901 too-complex - # try to use scope.default as module id + # try to use scope as module id if scope is not None: - try: - module_id = self.getModuleId(scope + ".default") - if varid.startswith(scope): - varid = varid[len(scope) + 1:] - return module_id, varid - except ValueError: - pass - - # try to use scope as module id try: module_id = self.getModuleId(scope) if varid.startswith(scope): @@ -339,7 +321,7 @@ def load(self, module_name, verbose=True, auto_query=True, loading_text=highligh raise ValueError(highlight_error() + "Module '%s' not known." % highlight_module(module_name)) # check if already loaded - if module_name + ".default" in self.modules_loaded or module_name in self.modules_loaded and as_id is None: + if module_name in self.modules_loaded and as_id is None: return # load module diff --git a/src/miniflask/modules/settings/__init__.py b/src/miniflask/modules/settings/__init__.py index 976b5cc2..af7f64d0 100644 --- a/src/miniflask/modules/settings/__init__.py +++ b/src/miniflask/modules/settings/__init__.py @@ -43,10 +43,7 @@ def listsettings(state, asciicodes=True): if len(k) > 1: k_hidden = [" " * len(ki) if ki == ki2 and asciicodes else ki for ki, ki2 in zip_longest(k, last_k) if ki is not None] last_k = k - if k_hidden[-2] == "default": - k_hidden[-3] = color_name(k_hidden[-3]) - else: - k_hidden[-2] = color_name(k_hidden[-2]) + k_hidden[-2] = color_name(k_hidden[-2]) k_hidden[-1] = color_module(k_hidden[-1]) else: k_hidden = k From e451f5fac5e94303b594d5a14396093d5f445cd6 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Mon, 7 Dec 2020 17:38:54 +0100 Subject: [PATCH 05/26] [modules] print also submodules --- src/miniflask/miniflask.py | 21 +++++++++++++++------ src/miniflask/modules/modules/__init__.py | 3 +-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index 210f47d6..991a0458 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -169,7 +169,10 @@ def getModuleEvents(self, module, dummy=None): return dummy.getEvents() # pretty print of all available modules - def showModules(self, directory=None, prepend="", id_pre=None, with_event=True): # noqa: C901 too-complex + def showModules(self, directory=None, prepend="", id_pre=None, with_event=True, direct_print=True): # noqa: C901 too-complex pylint: disable=inconsistent-return-statements + out = "" + any_module_found = False + if not directory: for basename, loop_directory in self.module_dirs.items(): self.showModules(loop_directory, prepend=prepend, id_pre=basename if id_pre is None else id_pre + "." + basename, with_event=with_event) @@ -178,8 +181,8 @@ def showModules(self, directory=None, prepend="", id_pre=None, with_event=True): if id_pre is None: id_pre = path.basename(directory) if len(prepend) == 0: - print() - print(highlight_name(path.basename(id_pre))) + out += "\n" + out += highlight_name(path.basename(id_pre)) + "\n" dirs = [d for d in listdir(directory) if path.isdir(path.join(directory, d)) and not d.startswith("_")] for i, d in enumerate(dirs): if d.startswith("."): @@ -192,6 +195,7 @@ def showModules(self, directory=None, prepend="", id_pre=None, with_event=True): is_lowpriority_module = path.exists(path.join(directory, d, ".lowpriority")) if is_module: shortestid = self.getModuleShortId(module_id) + any_module_found = True has_shortid = is_module and shortestid == d if i == len(dirs) - 1: @@ -202,7 +206,7 @@ def showModules(self, directory=None, prepend="", id_pre=None, with_event=True): is_last = False append = " " + fg('blue') + "(" + shortestid + ")" + attr('reset') if is_module and not has_shortid else "" append += attr('dim') + " (low-priority module)" + attr('reset') if is_lowpriority_module else "" - print(prepend + tree_symb + (highlight_name(d) if is_module else d) + append) + out += prepend + tree_symb + (highlight_name(d) if is_module else d) + append + "\n" tree_symb_next = " " if is_last else "│ " if is_module: @@ -212,8 +216,13 @@ def showModules(self, directory=None, prepend="", id_pre=None, with_event=True): for e in events: unique_flag = "!" if e[1] else ">" print(prepend + tree_symb_next + unique_flag + " " + highlight_event(e[0])) - continue - self.showModules(path.join(directory, d), prepend=prepend + tree_symb_next, id_pre=module_id, with_event=with_event) + out_sub, module_found_sub = self.showModules(path.join(directory, d), prepend=prepend + tree_symb_next, id_pre=module_id, with_event=with_event, direct_print=False) + if module_found_sub: + out += out_sub + if direct_print: + print(out) + return + return out, any_module_found # pretty print loaded modules def __str__(self): diff --git a/src/miniflask/modules/modules/__init__.py b/src/miniflask/modules/modules/__init__.py index 8b511844..78893521 100644 --- a/src/miniflask/modules/modules/__init__.py +++ b/src/miniflask/modules/modules/__init__.py @@ -1,6 +1,5 @@ def showModules(state, event): - event._mf.showModules(with_event=state.all["events"]) - print() + print(event._mf.showModules(with_event=state.all["events"])) def register(mf): From 5336e32675e95d5846fd6656647cabc5d22b4361 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Mon, 7 Dec 2020 18:25:27 +0100 Subject: [PATCH 06/26] changed offset of relative module paths --- src/miniflask/miniflask.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index 991a0458..2e6bd03e 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -784,7 +784,7 @@ def __init__(self, module_name, mf): # pylint: disable=super-init-not-called self._recently_loaded = [] self._defined_events = {} - def _get_relative_module_id(self, module_name, offset=0): + def _get_relative_module_id(self, module_name, offset=1): was_relative = False m = relative_import_re.match(module_name) if m is not None: @@ -857,7 +857,7 @@ def load(self, module_name, as_id=None, auto_query=True, **kwargs): if as_id: if as_id.endswith("."): as_id += module_name.split(".")[-1] - as_id, _ = self._get_relative_module_id(as_id, offset=1) + as_id, _ = self._get_relative_module_id(as_id) # parse relative imports first module_name, was_relative = self._get_relative_module_id(module_name) From f10c484c8f9ffccbd67d1b031362e21cdedd01f9 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 22 Dec 2020 19:46:06 +0100 Subject: [PATCH 07/26] tests: added basic import tests --- .../test_import/modules/otherdir/__init__.py | 0 .../modules/otherdir/module2/.module | 0 .../modules/otherdir/module2/__init__.py | 3 + .../test_import/modules/parentdir/__init__.py | 0 .../modules/parentdir/module1/.module | 0 .../modules/parentdir/module1/__init__.py | 3 + .../modules/parentdir/module2/.module | 0 .../modules/parentdir/module2/__init__.py | 3 + tests/test_import/test_basic_import.py | 79 +++++++++++++++++++ 9 files changed, 88 insertions(+) create mode 100644 tests/test_import/modules/otherdir/__init__.py create mode 100644 tests/test_import/modules/otherdir/module2/.module create mode 100644 tests/test_import/modules/otherdir/module2/__init__.py create mode 100644 tests/test_import/modules/parentdir/__init__.py create mode 100644 tests/test_import/modules/parentdir/module1/.module create mode 100644 tests/test_import/modules/parentdir/module1/__init__.py create mode 100644 tests/test_import/modules/parentdir/module2/.module create mode 100644 tests/test_import/modules/parentdir/module2/__init__.py create mode 100644 tests/test_import/test_basic_import.py diff --git a/tests/test_import/modules/otherdir/__init__.py b/tests/test_import/modules/otherdir/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/otherdir/module2/.module b/tests/test_import/modules/otherdir/module2/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/otherdir/module2/__init__.py b/tests/test_import/modules/otherdir/module2/__init__.py new file mode 100644 index 00000000..99e6408b --- /dev/null +++ b/tests/test_import/modules/otherdir/module2/__init__.py @@ -0,0 +1,3 @@ + +def register(mf): + mf.register_event("main", lambda: print("tests")) diff --git a/tests/test_import/modules/parentdir/__init__.py b/tests/test_import/modules/parentdir/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/parentdir/module1/.module b/tests/test_import/modules/parentdir/module1/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/parentdir/module1/__init__.py b/tests/test_import/modules/parentdir/module1/__init__.py new file mode 100644 index 00000000..99e6408b --- /dev/null +++ b/tests/test_import/modules/parentdir/module1/__init__.py @@ -0,0 +1,3 @@ + +def register(mf): + mf.register_event("main", lambda: print("tests")) diff --git a/tests/test_import/modules/parentdir/module2/.module b/tests/test_import/modules/parentdir/module2/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/parentdir/module2/__init__.py b/tests/test_import/modules/parentdir/module2/__init__.py new file mode 100644 index 00000000..99e6408b --- /dev/null +++ b/tests/test_import/modules/parentdir/module2/__init__.py @@ -0,0 +1,3 @@ + +def register(mf): + mf.register_event("main", lambda: print("tests")) diff --git a/tests/test_import/test_basic_import.py b/tests/test_import/test_basic_import.py new file mode 100644 index 00000000..fe93a966 --- /dev/null +++ b/tests/test_import/test_basic_import.py @@ -0,0 +1,79 @@ +from pathlib import Path +import pytest +import miniflask # noqa: E402 + + +def init_mf(): + return miniflask.init(module_dirs=str(Path(__file__).parent / "modules"), debug=True) + + +def test_shortid(): + mf = init_mf() + mf.run(modules=["module1"]) + assert "modules.parentdir.module1" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_partial_id(): + mf = init_mf() + mf.run(modules=["modules.module1"]) + assert "modules.parentdir.module1" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_partial_id_2(): + mf = init_mf() + mf.run(modules=["parentdir.module1"]) + assert "modules.parentdir.module1" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_full_id(): + mf = init_mf() + mf.run(modules=["modules.parentdir.module1"]) + assert "modules.parentdir.module1" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_shortid_error(): + mf = init_mf() + with pytest.raises(ValueError) as excinfo: + mf.run(modules=["module2"]) + assert "is not unique" in str(excinfo.value) + assert len(mf.modules_loaded) == 0 + + +def test_partial_id_error(): + mf = init_mf() + with pytest.raises(ValueError) as excinfo: + mf.run(modules=["modules.module2"]) + assert "is not unique" in str(excinfo.value) + assert len(mf.modules_loaded) == 0 + + +def test_partial_id_3(): + mf = init_mf() + mf.run(modules=["modules.otherdir.module2"]) + assert "modules.otherdir.module2" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_partial_id_4(): + mf = init_mf() + mf.run(modules=["modules.otherdir.module2"]) + assert "modules.otherdir.module2" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_partial_id_5(): + mf = init_mf() + mf.run(modules=["parentdir.module2"]) + assert "modules.parentdir.module2" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_partial_id_6(): + mf = init_mf() + mf.run(modules=["parentdir.module2"]) + assert "modules.parentdir.module2" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 From 185b202e3e604ad1fc934866e6c191dc8a448b94 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 22 Dec 2020 19:54:50 +0100 Subject: [PATCH 08/26] tests: added relative import tests --- .../modules/parentdir/module3/.module | 0 .../modules/parentdir/module3/__init__.py | 4 ++ .../parentdir/module3/submodule/.module | 0 .../parentdir/module3/submodule/__init__.py | 3 ++ .../modules/parentdir/module4/.module | 0 .../modules/parentdir/module4/__init__.py | 4 ++ .../modules/parentdir/module5/.module | 0 .../modules/parentdir/module5/__init__.py | 4 ++ tests/test_import/test_relative_import.py | 38 +++++++++++++++++++ 9 files changed, 53 insertions(+) create mode 100644 tests/test_import/modules/parentdir/module3/.module create mode 100644 tests/test_import/modules/parentdir/module3/__init__.py create mode 100644 tests/test_import/modules/parentdir/module3/submodule/.module create mode 100644 tests/test_import/modules/parentdir/module3/submodule/__init__.py create mode 100644 tests/test_import/modules/parentdir/module4/.module create mode 100644 tests/test_import/modules/parentdir/module4/__init__.py create mode 100644 tests/test_import/modules/parentdir/module5/.module create mode 100644 tests/test_import/modules/parentdir/module5/__init__.py create mode 100644 tests/test_import/test_relative_import.py diff --git a/tests/test_import/modules/parentdir/module3/.module b/tests/test_import/modules/parentdir/module3/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/parentdir/module3/__init__.py b/tests/test_import/modules/parentdir/module3/__init__.py new file mode 100644 index 00000000..a25af9b5 --- /dev/null +++ b/tests/test_import/modules/parentdir/module3/__init__.py @@ -0,0 +1,4 @@ + +def register(mf): + mf.load(".submodule") + mf.register_event("main", lambda: print("tests")) diff --git a/tests/test_import/modules/parentdir/module3/submodule/.module b/tests/test_import/modules/parentdir/module3/submodule/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/parentdir/module3/submodule/__init__.py b/tests/test_import/modules/parentdir/module3/submodule/__init__.py new file mode 100644 index 00000000..99e6408b --- /dev/null +++ b/tests/test_import/modules/parentdir/module3/submodule/__init__.py @@ -0,0 +1,3 @@ + +def register(mf): + mf.register_event("main", lambda: print("tests")) diff --git a/tests/test_import/modules/parentdir/module4/.module b/tests/test_import/modules/parentdir/module4/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/parentdir/module4/__init__.py b/tests/test_import/modules/parentdir/module4/__init__.py new file mode 100644 index 00000000..b3d7ee39 --- /dev/null +++ b/tests/test_import/modules/parentdir/module4/__init__.py @@ -0,0 +1,4 @@ + +def register(mf): + mf.load("..module3") + mf.register_event("main", lambda: print("tests")) diff --git a/tests/test_import/modules/parentdir/module5/.module b/tests/test_import/modules/parentdir/module5/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_import/modules/parentdir/module5/__init__.py b/tests/test_import/modules/parentdir/module5/__init__.py new file mode 100644 index 00000000..0a2abf96 --- /dev/null +++ b/tests/test_import/modules/parentdir/module5/__init__.py @@ -0,0 +1,4 @@ + +def register(mf): + mf.load("...otherdir.module2") + mf.register_event("main", lambda: print("tests")) diff --git a/tests/test_import/test_relative_import.py b/tests/test_import/test_relative_import.py new file mode 100644 index 00000000..390546f7 --- /dev/null +++ b/tests/test_import/test_relative_import.py @@ -0,0 +1,38 @@ +from pathlib import Path +import miniflask # noqa: E402 + + +def init_mf(): + return miniflask.init(module_dirs=str(Path(__file__).parent / "modules"), debug=True) + + +def test_passive_submodule_import(): + mf = init_mf() + mf.run(modules=["module3"]) + assert "modules.parentdir.module3" in mf.modules_loaded + assert "modules.parentdir.module3.submodule" in mf.modules_loaded + assert len(mf.modules_loaded) == 2 + + +def test_active_submodule_import(): + mf = init_mf() + mf.run(modules=["submodule"]) + assert "modules.parentdir.module3.submodule" in mf.modules_loaded + assert len(mf.modules_loaded) == 1 + + +def test_relative_import(): + mf = init_mf() + mf.run(modules=["module4"]) + assert "modules.parentdir.module4" in mf.modules_loaded + assert "modules.parentdir.module3" in mf.modules_loaded + assert "modules.parentdir.module3.submodule" in mf.modules_loaded + assert len(mf.modules_loaded) == 3 + + +def test_relative_import_2(): + mf = init_mf() + mf.run(modules=["module5"]) + assert "modules.parentdir.module5" in mf.modules_loaded + assert "modules.otherdir.module2" in mf.modules_loaded + assert len(mf.modules_loaded) == 2 From adfe1ae22cd1f40bdd5b6651bf2ef2dd7bf5d241 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Mon, 7 Dec 2020 16:15:56 +0100 Subject: [PATCH 09/26] remove single dash arguments again (introduced in v1.26) --- src/miniflask/miniflask.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index 2e6bd03e..d67e377f 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -623,17 +623,17 @@ def parse_args(self, # noqa: C901 too-complex pylint: disable=too-many-stateme argv.remove("--help") print_help = True - # split --varname=value expressions - argv = [v for val in argv for v in (val.split("=", 1) if val.startswith("--") or val.startswith("-") and not val[1:].isnumeric() else [val])] + # split `--varname=value` expressions to `--varname value` + # (argparse does only allow the `key=value`-syntax for single-dash definitions) + argv = [v for val in argv for v in (val.split("=", 1) if val.startswith("--") else [val])] # pylint: disable=superfluous-parens # remember varids from user-args & fuzzy matching the settings user_varids = {} for i, varid in enumerate(argv): + + # no need to process actual values if not varid.startswith("--"): - if varid.startswith("-") and not varid[1:].replace('.', '', 1).isdigit(): - varid = argv[i] = "-" + argv[i] - else: - continue + continue # extract varid from argument varid = varid[2:] From 92fa1895afc13758564868957519bf2189257bcd Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 22 Dec 2020 19:10:31 +0100 Subject: [PATCH 10/26] tests: added argparse tests --- tests/test_argparse/modules/module1/.module | 0 .../test_argparse/modules/module1/__init__.py | 50 +++++ .../test_argparse/test_argparse_overwrites.py | 175 +++++++++++++++++ tests/test_argparse/test_argparse_types.py | 31 +++ .../modules/module1/.module | 0 .../modules/module1/__init__.py | 50 +++++ .../test_argparse_list_overwrites.py | 177 ++++++++++++++++++ .../test_argparse_list_overwrites_multiple.py | 177 ++++++++++++++++++ .../test_argparse_list_types.py | 31 +++ .../modules/module1/.module | 0 .../modules/module1/__init__.py | 50 +++++ .../test_argparse_required_overwrites.py | 91 +++++++++ .../test_argparse_required_types.py | 34 ++++ 13 files changed, 866 insertions(+) create mode 100644 tests/test_argparse/modules/module1/.module create mode 100644 tests/test_argparse/modules/module1/__init__.py create mode 100644 tests/test_argparse/test_argparse_overwrites.py create mode 100644 tests/test_argparse/test_argparse_types.py create mode 100644 tests/test_argparse_list/modules/module1/.module create mode 100644 tests/test_argparse_list/modules/module1/__init__.py create mode 100644 tests/test_argparse_list/test_argparse_list_overwrites.py create mode 100644 tests/test_argparse_list/test_argparse_list_overwrites_multiple.py create mode 100644 tests/test_argparse_list/test_argparse_list_types.py create mode 100644 tests/test_argparse_required/modules/module1/.module create mode 100644 tests/test_argparse_required/modules/module1/__init__.py create mode 100644 tests/test_argparse_required/test_argparse_required_overwrites.py create mode 100644 tests/test_argparse_required/test_argparse_required_types.py diff --git a/tests/test_argparse/modules/module1/.module b/tests/test_argparse/modules/module1/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_argparse/modules/module1/__init__.py b/tests/test_argparse/modules/module1/__init__.py new file mode 100644 index 00000000..0fd9f36f --- /dev/null +++ b/tests/test_argparse/modules/module1/__init__.py @@ -0,0 +1,50 @@ +from enum import Enum + + +class SIZE(Enum): + SMALL = 0 + MEDIUM = 1 + LARGE = 2 + + +def print_all(state): + print("int1:", state["int1"]) + print("int2:", state["int2"]) + print("float1:", state["float1"]) + print("float2:", state["float2"]) + print("float3:", state["float3"]) + print("float4:", state["float4"]) + print("float5:", state["float5"]) + print("float6:", state["float6"]) + print("bool1:", state["bool1"]) + print("bool2:", state["bool2"]) + print("enum1:", state["enum1"]) + print("str1:", state["str1"]) + print("str2:", state["str2"]) + print("str3:", state["str3"]) + + +def print_bool(state): + print("bool1:", state["bool1"]) + print("bool2:", state["bool2"]) + + +def register(mf): + mf.register_defaults({ + "int1": 42, + "int2": -42, + "float1": 2.345, + "float2": -2.345, + "float3": 0.0, + "float4": -0.0, + "float5": 1e7, + "float6": -1e7, + "bool1": True, + "bool2": False, + "enum1": SIZE.MEDIUM, + "str1": "", + "str2": "abcd1234", + "str3": "αβγδ∀⇐Γ∂", + }) + mf.register_event('print_all', print_all) + mf.register_event('print_bool', print_bool) diff --git a/tests/test_argparse/test_argparse_overwrites.py b/tests/test_argparse/test_argparse_overwrites.py new file mode 100644 index 00000000..9b90de7b --- /dev/null +++ b/tests/test_argparse/test_argparse_overwrites.py @@ -0,0 +1,175 @@ +from pathlib import Path + +import miniflask # noqa: E402 + + +def test_space(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1", "1337", + "--int2", "-1337", + "--float1", "1.234", + "--float2", "-1.234", + "--float3", "-0.0", + "--float4", "0.0", + "--float5", "3e5", + "--float6", "-3e5", + "--bool1", "False", + "--bool2", "True", + "--enum1", "small", + "--str1", "abcd1234", + "--str2", "αβγδ∀⇐Γ∂", + "--str3", "" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: 1337 +int2: -1337 +float1: 1.234 +float2: -1.234 +float3: -0.0 +float4: 0.0 +float5: 300000.0 +float6: -300000.0 +bool1: False +bool2: True +enum1: SIZE.SMALL +str1: abcd1234 +str2: αβγδ∀⇐Γ∂ +str3: \n""".lstrip() + + +def test_equal(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1=1337", + "--int2=-1337", + "--float1=1.234", + "--float2=-1.234", + "--float3=-0.0", + "--float4=0.0", + "--float5=3e5", + "--float6=-3e5", + "--bool1=False", + "--bool2=True", + "--enum1=small", + "--str1=abcd1234", + "--str2=αβγδ∀⇐Γ∂", + "--str3=" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: 1337 +int2: -1337 +float1: 1.234 +float2: -1.234 +float3: -0.0 +float4: 0.0 +float5: 300000.0 +float6: -300000.0 +bool1: False +bool2: True +enum1: SIZE.SMALL +str1: abcd1234 +str2: αβγδ∀⇐Γ∂ +str3: \n""".lstrip() + + +def test_bool_int(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=0", + "--bool2=1", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: False +bool2: True +""".lstrip() + + +def test_bool_yesno(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=no", + "--bool2=yes", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: False +bool2: True +""".lstrip() + + +def test_bool_tf(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=f", + "--bool2=t", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: False +bool2: True +""".lstrip() + + +def test_bool_truefalse(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=false", + "--bool2=true", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: False +bool2: True +""".lstrip() diff --git a/tests/test_argparse/test_argparse_types.py b/tests/test_argparse/test_argparse_types.py new file mode 100644 index 00000000..3a94fb2b --- /dev/null +++ b/tests/test_argparse/test_argparse_types.py @@ -0,0 +1,31 @@ +from pathlib import Path + +import miniflask # noqa: E402 + +mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True +) + + +def test_types(capsys): + with capsys.disabled(): + mf.load("module1") + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: 42 +int2: -42 +float1: 2.345 +float2: -2.345 +float3: 0.0 +float4: -0.0 +float5: 10000000.0 +float6: -10000000.0 +bool1: True +bool2: False +enum1: SIZE.MEDIUM +str1: """.lstrip() + """ +str2: abcd1234 +str3: αβγδ∀⇐Γ∂ +""" diff --git a/tests/test_argparse_list/modules/module1/.module b/tests/test_argparse_list/modules/module1/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_argparse_list/modules/module1/__init__.py b/tests/test_argparse_list/modules/module1/__init__.py new file mode 100644 index 00000000..8dc0a921 --- /dev/null +++ b/tests/test_argparse_list/modules/module1/__init__.py @@ -0,0 +1,50 @@ +from enum import Enum + + +class SIZE(Enum): + SMALL = 0 + MEDIUM = 1 + LARGE = 2 + + +def print_all(state): + print("int1:", state["int1"]) + print("int2:", state["int2"]) + print("float1:", state["float1"]) + print("float2:", state["float2"]) + print("float3:", state["float3"]) + print("float4:", state["float4"]) + print("float5:", state["float5"]) + print("float6:", state["float6"]) + print("bool1:", state["bool1"]) + print("bool2:", state["bool2"]) + print("enum1:", state["enum1"]) + print("str1:", state["str1"]) + print("str2:", state["str2"]) + print("str3:", state["str3"]) + + +def print_bool(state): + print("bool1:", state["bool1"]) + print("bool2:", state["bool2"]) + + +def register(mf): + mf.register_defaults({ + "int1": [42], + "int2": [-42], + "float1": [2.345], + "float2": [-2.345], + "float3": [0.0], + "float4": [-0.0], + "float5": [1e7], + "float6": [-1e7], + "bool1": [True], + "bool2": [False], + "enum1": [SIZE.MEDIUM], + "str1": [""], + "str2": ["abcd1234"], + "str3": ["αβγδ∀⇐Γ∂"], + }) + mf.register_event('print_all', print_all) + mf.register_event('print_bool', print_bool) diff --git a/tests/test_argparse_list/test_argparse_list_overwrites.py b/tests/test_argparse_list/test_argparse_list_overwrites.py new file mode 100644 index 00000000..bea74de4 --- /dev/null +++ b/tests/test_argparse_list/test_argparse_list_overwrites.py @@ -0,0 +1,177 @@ +from pathlib import Path + +import miniflask # noqa: [E402] + + +def test_space(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1", "1337", + "--int2", "-1337", + "--float1", "1.234", + "--float2", "-1.234", + "--float3", "-0.0", + "--float4", "0.0", + "--float5", "3e5", + "--float6", "-3e5", + "--bool1", "False", + "--bool2", "True", + "--enum1", "small", + "--str1", "abcd1234", + "--str2", "αβγδ∀⇐Γ∂", + "--str3", "" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: [1337] +int2: [-1337] +float1: [1.234] +float2: [-1.234] +float3: [-0.0] +float4: [0.0] +float5: [300000.0] +float6: [-300000.0] +bool1: [False] +bool2: [True] +enum1: [] +str1: ['abcd1234'] +str2: ['αβγδ∀⇐Γ∂'] +str3: [''] +""".lstrip() + + +def test_equal(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1=1337", + "--int2=-1337", + "--float1=1.234", + "--float2=-1.234", + "--float3=-0.0", + "--float4=0.0", + "--float5=3e5", + "--float6=-3e5", + "--bool1=False", + "--bool2=True", + "--enum1=small", + "--str1=abcd1234", + "--str2=αβγδ∀⇐Γ∂", + "--str3=" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: [1337] +int2: [-1337] +float1: [1.234] +float2: [-1.234] +float3: [-0.0] +float4: [0.0] +float5: [300000.0] +float6: [-300000.0] +bool1: [False] +bool2: [True] +enum1: [] +str1: ['abcd1234'] +str2: ['αβγδ∀⇐Γ∂'] +str3: [''] +""".lstrip() + + +def test_bool_int(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=0", + "--bool2=1", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() + + +def test_bool_yesno(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=no", + "--bool2=yes", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() + + +def test_bool_tf(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=f", + "--bool2=t", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() + + +def test_bool_truefalse(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=false", + "--bool2=true", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() diff --git a/tests/test_argparse_list/test_argparse_list_overwrites_multiple.py b/tests/test_argparse_list/test_argparse_list_overwrites_multiple.py new file mode 100644 index 00000000..77999505 --- /dev/null +++ b/tests/test_argparse_list/test_argparse_list_overwrites_multiple.py @@ -0,0 +1,177 @@ +from pathlib import Path + +import miniflask # noqa: [E402] + + +def test_space(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1", + "--int2", "-1337", "1234", + "--float1", + "--float2", "-1.234", + "--float3", "-0.0", "-0.0", + "--float4", "0.0", "0.0", "0.0", + "--float5", "3e5", "4e4", "5e3", "6e2", + "--float6", "-3e5", "-4e4", "-5e3", "-6e2", + "--bool1", + "--bool2", "True", "False", + "--enum1", "large", "medium", "small", + "--str1", "abcd", "1234", + "--str2", "αβγδ", "∀⇐", "Γ∂", + "--str3", "" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: [] +int2: [-1337, 1234] +float1: [] +float2: [-1.234] +float3: [-0.0, -0.0] +float4: [0.0, 0.0, 0.0] +float5: [300000.0, 40000.0, 5000.0, 600.0] +float6: [-300000.0, -40000.0, -5000.0, -600.0] +bool1: [] +bool2: [True, False] +enum1: [, , ] +str1: ['abcd', '1234'] +str2: ['αβγδ', '∀⇐', 'Γ∂'] +str3: [''] +""".lstrip() + + +def test_equal(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1=1337", + "--int2=-1337", + "--float1=1.234", + "--float2=-1.234", + "--float3=-0.0", + "--float4=0.0", + "--float5=3e5", + "--float6=-3e5", + "--bool1=False", + "--bool2=True", + "--enum1=small", + "--str1=abcd1234", + "--str2=αβγδ∀⇐Γ∂", + "--str3=" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: [1337] +int2: [-1337] +float1: [1.234] +float2: [-1.234] +float3: [-0.0] +float4: [0.0] +float5: [300000.0] +float6: [-300000.0] +bool1: [False] +bool2: [True] +enum1: [] +str1: ['abcd1234'] +str2: ['αβγδ∀⇐Γ∂'] +str3: [''] +""".lstrip() + + +def test_bool_int(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=0", + "--bool2=1", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() + + +def test_bool_yesno(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=no", + "--bool2=yes", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() + + +def test_bool_tf(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=f", + "--bool2=t", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() + + +def test_bool_truefalse(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--bool1=false", + "--bool2=true", + ]) + captured = capsys.readouterr() + + mf.event.print_bool() + captured = capsys.readouterr() + assert captured.out == """ +bool1: [False] +bool2: [True] +""".lstrip() diff --git a/tests/test_argparse_list/test_argparse_list_types.py b/tests/test_argparse_list/test_argparse_list_types.py new file mode 100644 index 00000000..a6846c4d --- /dev/null +++ b/tests/test_argparse_list/test_argparse_list_types.py @@ -0,0 +1,31 @@ +from pathlib import Path + +import miniflask # noqa: [E402] + +mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True +) + + +def test_types(capsys): + with capsys.disabled(): + mf.load("module1") + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: [42] +int2: [-42] +float1: [2.345] +float2: [-2.345] +float3: [0.0] +float4: [-0.0] +float5: [10000000.0] +float6: [-10000000.0] +bool1: [True] +bool2: [False] +enum1: [] +str1: [''] +str2: ['abcd1234'] +str3: ['αβγδ∀⇐Γ∂'] +""".lstrip() diff --git a/tests/test_argparse_required/modules/module1/.module b/tests/test_argparse_required/modules/module1/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_argparse_required/modules/module1/__init__.py b/tests/test_argparse_required/modules/module1/__init__.py new file mode 100644 index 00000000..2f7f47b8 --- /dev/null +++ b/tests/test_argparse_required/modules/module1/__init__.py @@ -0,0 +1,50 @@ +from enum import Enum + + +class SIZE(Enum): + SMALL = 0 + MEDIUM = 1 + LARGE = 2 + + +def print_all(state): + print("int1:", state["int1"]) + print("int2:", state["int2"]) + print("float1:", state["float1"]) + print("float2:", state["float2"]) + print("float3:", state["float3"]) + print("float4:", state["float4"]) + print("float5:", state["float5"]) + print("float6:", state["float6"]) + print("bool1:", state["bool1"]) + print("bool2:", state["bool2"]) + print("enum1:", state["enum1"]) + print("str1:", state["str1"]) + print("str2:", state["str2"]) + print("str3:", state["str3"]) + + +def print_bool(state): + print("bool1:", state["bool1"]) + print("bool2:", state["bool2"]) + + +def register(mf): + mf.register_defaults({ + "int1": int, + "int2": int, + "float1": float, + "float2": float, + "float3": float, + "float4": float, + "float5": float, + "float6": float, + "bool1": bool, + "bool2": bool, + "enum1": SIZE, + "str1": str, + "str2": str, + "str3": str, + }) + mf.register_event('print_all', print_all) + mf.register_event('print_bool', print_bool) diff --git a/tests/test_argparse_required/test_argparse_required_overwrites.py b/tests/test_argparse_required/test_argparse_required_overwrites.py new file mode 100644 index 00000000..b2c74c46 --- /dev/null +++ b/tests/test_argparse_required/test_argparse_required_overwrites.py @@ -0,0 +1,91 @@ +from pathlib import Path + +import miniflask # noqa: E402 + + +def test_space(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1", "1337", + "--int2", "-1337", + "--float1", "1.234", + "--float2", "-1.234", + "--float3", "-0.0", + "--float4", "0.0", + "--float5", "3e5", + "--float6", "-3e5", + "--bool1", "False", + "--bool2", "True", + "--enum1", "small", + "--str1", "abcd1234", + "--str2", "αβγδ∀⇐Γ∂", + "--str3", "" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: 1337 +int2: -1337 +float1: 1.234 +float2: -1.234 +float3: -0.0 +float4: 0.0 +float5: 300000.0 +float6: -300000.0 +bool1: False +bool2: True +enum1: SIZE.SMALL +str1: abcd1234 +str2: αβγδ∀⇐Γ∂ +str3: \n""".lstrip() + + +def test_equal(capsys): + mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True + ) + + mf.load("module1") + mf.parse_args([ + "--int1=1337", + "--int2=-1337", + "--float1=1.234", + "--float2=-1.234", + "--float3=-0.0", + "--float4=0.0", + "--float5=3e5", + "--float6=-3e5", + "--bool1=False", + "--bool2=True", + "--enum1=small", + "--str1=abcd1234", + "--str2=αβγδ∀⇐Γ∂", + "--str3=" + ]) + captured = capsys.readouterr() + + mf.event.print_all() + captured = capsys.readouterr() + assert captured.out == """ +int1: 1337 +int2: -1337 +float1: 1.234 +float2: -1.234 +float3: -0.0 +float4: 0.0 +float5: 300000.0 +float6: -300000.0 +bool1: False +bool2: True +enum1: SIZE.SMALL +str1: abcd1234 +str2: αβγδ∀⇐Γ∂ +str3: \n""".lstrip() diff --git a/tests/test_argparse_required/test_argparse_required_types.py b/tests/test_argparse_required/test_argparse_required_types.py new file mode 100644 index 00000000..195fdc68 --- /dev/null +++ b/tests/test_argparse_required/test_argparse_required_types.py @@ -0,0 +1,34 @@ +from pathlib import Path +import pytest + +import miniflask # noqa: E402 + +mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True +) + + +def test_types(capsys): + mf.load("module1") + error_message = """ +The following argument is required: --modules.module1.int1 +The following argument is required: --modules.module1.int2 +The following argument is required: --modules.module1.float1 +The following argument is required: --modules.module1.float2 +The following argument is required: --modules.module1.float3 +The following argument is required: --modules.module1.float4 +The following argument is required: --modules.module1.float5 +The following argument is required: --modules.module1.float6 +The following argument is required: --modules.module1.enum1 +The following argument is required: --modules.module1.str1 +The following argument is required: --modules.module1.str2 +The following argument is required: --modules.module1.str3 +""".strip() + with pytest.raises(SystemExit) as excinfo: + mf.parse_args() + captured = capsys.readouterr() + assert excinfo.value.args[0] == 2 + + # we allow any order of the messages "The following argument is required ..." + assert all(message in captured.err for message in error_message.split("\n")) From 6c7a385ee5de664bf4815ddb8e1f3ec9ec983f2d Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 22 Dec 2020 19:11:24 +0100 Subject: [PATCH 11/26] argparse: quickfix for missing argparse support of negative scientific notation --- src/miniflask/miniflask.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index d67e377f..bcdd024d 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -633,6 +633,13 @@ def parse_args(self, # noqa: C901 too-complex pylint: disable=too-many-stateme # no need to process actual values if not varid.startswith("--"): + + # special case: negative scientific notation currently does not work for argparse + if varid.startswith("-") and "e" in varid and varid[1:].replace("e", "").isnumeric(): + try: + argv[i] = str(float(varid)) + except ValueError: + pass continue # extract varid from argument From e311134913bb3771d9abcfe9b1ae765ff1f7bfb7 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 22 Dec 2020 19:12:26 +0100 Subject: [PATCH 12/26] bugfix: boolean list defaults did not work --- src/miniflask/miniflask.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index bcdd024d..3bc39fa5 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -461,7 +461,7 @@ def _settings_parser_add(self, varname, val, caller_traceback, nargs=None, defau if argtype == Enum: kwarg["action"] = EnumAction kwarg["type"] = val if isinstance(val, EnumMeta) else type(val) - elif argtype == str2bool and nargs != '+': # pylint: disable=comparison-with-callable + elif argtype == str2bool and nargs != '*': # pylint: disable=comparison-with-callable kwarg["nargs"] = '?' kwarg["const"] = True @@ -473,7 +473,7 @@ def _settings_parser_add(self, varname, val, caller_traceback, nargs=None, defau # for bool: enable --no-varname as alternative for --varname false # Note: this has to be defined AFTER --varname - if argtype == str2bool and nargs != '+': # pylint: disable=comparison-with-callable + if argtype == str2bool and nargs != '*': # pylint: disable=comparison-with-callable self.settings_parser.add_argument('--no-' + varname, dest=varname, action='store_false') # remember the varname also for fuzzy searching From 28551e949529ab0908762efa93d93b1648111b3e Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Mon, 28 Dec 2020 10:28:54 +0100 Subject: [PATCH 13/26] tests: speedtest: deactivated & fixed pylint errors --- tests/speedtest/test_mf_python.py | 21 ------------------- .../speedtest/modules/modulenomfargs/.module | 0 .../modules/modulenomfargs/__init__.py | 0 .../speedtest/modules/modulenonunique/.module | 0 .../modules/modulenonunique/__init__.py | 0 .../speedtest/modules/moduleunique/.module | 0 .../modules/moduleunique/__init__.py | 8 +++++++ .../speedtest/test_mf_class.py | 4 ++-- .../speedtest/test_mf_event.py | 2 +- .../speedtest/test_mf_event_nomfargs.py | 2 +- .../speedtest/test_mf_event_nonunique.py | 2 +- tests_deact/speedtest/test_mf_python.py | 18 ++++++++++++++++ .../speedtest/test_mf_state.py | 2 +- .../speedtest/test_mf_state_fuzzy.py | 2 +- .../speedtest/test_python.py | 2 +- 15 files changed, 34 insertions(+), 29 deletions(-) delete mode 100755 tests/speedtest/test_mf_python.py rename {tests => tests_deact}/speedtest/modules/modulenomfargs/.module (100%) rename {tests => tests_deact}/speedtest/modules/modulenomfargs/__init__.py (100%) rename {tests => tests_deact}/speedtest/modules/modulenonunique/.module (100%) rename {tests => tests_deact}/speedtest/modules/modulenonunique/__init__.py (100%) rename {tests => tests_deact}/speedtest/modules/moduleunique/.module (100%) rename {tests => tests_deact}/speedtest/modules/moduleunique/__init__.py (63%) rename {tests => tests_deact}/speedtest/test_mf_class.py (77%) rename {tests => tests_deact}/speedtest/test_mf_event.py (89%) rename {tests => tests_deact}/speedtest/test_mf_event_nomfargs.py (90%) rename {tests => tests_deact}/speedtest/test_mf_event_nonunique.py (90%) create mode 100755 tests_deact/speedtest/test_mf_python.py rename {tests => tests_deact}/speedtest/test_mf_state.py (90%) rename {tests => tests_deact}/speedtest/test_mf_state_fuzzy.py (90%) rename {tests => tests_deact}/speedtest/test_python.py (71%) diff --git a/tests/speedtest/test_mf_python.py b/tests/speedtest/test_mf_python.py deleted file mode 100755 index 89d9b5dc..00000000 --- a/tests/speedtest/test_mf_python.py +++ /dev/null @@ -1,21 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -def test_mf_python(): - - mf.load("module1") - from modules.module1 import func as func2 # noqa: F401,E402 - - def func(x): - return x - - a = 0 - for i in range(10000000): - a += func(42) diff --git a/tests/speedtest/modules/modulenomfargs/.module b/tests_deact/speedtest/modules/modulenomfargs/.module similarity index 100% rename from tests/speedtest/modules/modulenomfargs/.module rename to tests_deact/speedtest/modules/modulenomfargs/.module diff --git a/tests/speedtest/modules/modulenomfargs/__init__.py b/tests_deact/speedtest/modules/modulenomfargs/__init__.py similarity index 100% rename from tests/speedtest/modules/modulenomfargs/__init__.py rename to tests_deact/speedtest/modules/modulenomfargs/__init__.py diff --git a/tests/speedtest/modules/modulenonunique/.module b/tests_deact/speedtest/modules/modulenonunique/.module similarity index 100% rename from tests/speedtest/modules/modulenonunique/.module rename to tests_deact/speedtest/modules/modulenonunique/.module diff --git a/tests/speedtest/modules/modulenonunique/__init__.py b/tests_deact/speedtest/modules/modulenonunique/__init__.py similarity index 100% rename from tests/speedtest/modules/modulenonunique/__init__.py rename to tests_deact/speedtest/modules/modulenonunique/__init__.py diff --git a/tests/speedtest/modules/moduleunique/.module b/tests_deact/speedtest/modules/moduleunique/.module similarity index 100% rename from tests/speedtest/modules/moduleunique/.module rename to tests_deact/speedtest/modules/moduleunique/.module diff --git a/tests/speedtest/modules/moduleunique/__init__.py b/tests_deact/speedtest/modules/moduleunique/__init__.py similarity index 63% rename from tests/speedtest/modules/moduleunique/__init__.py rename to tests_deact/speedtest/modules/moduleunique/__init__.py index 45d4e526..1f69d1aa 100644 --- a/tests/speedtest/modules/moduleunique/__init__.py +++ b/tests_deact/speedtest/modules/moduleunique/__init__.py @@ -8,6 +8,14 @@ def before_func(state, event, *args, **kwargs): return args, kwargs +def get_state_var(state, varname): + return state[varname] + + def register(mf): mf.register_event('func', func, unique=True, call_before_after=True) mf.register_event('before_func', before_func) + mf.register_event('get_state_var', get_state_var, unique=True) + mf.register_defaults({ + "a": 42 + }) diff --git a/tests/speedtest/test_mf_class.py b/tests_deact/speedtest/test_mf_class.py similarity index 77% rename from tests/speedtest/test_mf_class.py rename to tests_deact/speedtest/test_mf_class.py index 7b04b1a3..2795bba6 100755 --- a/tests/speedtest/test_mf_class.py +++ b/tests_deact/speedtest/test_mf_class.py @@ -8,7 +8,7 @@ ) -class event(): +class event(): # pylint: disable=too-few-public-methods @classmethod def func(cls, x): @@ -20,5 +20,5 @@ def test_mf_class(): mf.load("moduleunique") a = 0 - for i in range(10000000): + for _ in range(10000000): a += event.func(42) diff --git a/tests/speedtest/test_mf_event.py b/tests_deact/speedtest/test_mf_event.py similarity index 89% rename from tests/speedtest/test_mf_event.py rename to tests_deact/speedtest/test_mf_event.py index c15d3c96..f1740967 100755 --- a/tests/speedtest/test_mf_event.py +++ b/tests_deact/speedtest/test_mf_event.py @@ -13,5 +13,5 @@ def test_mf_event(): mf.load("moduleunique") a = 0 - for i in range(10000000): + for _ in range(10000000): a += event.func(42) diff --git a/tests/speedtest/test_mf_event_nomfargs.py b/tests_deact/speedtest/test_mf_event_nomfargs.py similarity index 90% rename from tests/speedtest/test_mf_event_nomfargs.py rename to tests_deact/speedtest/test_mf_event_nomfargs.py index 50d18b6b..6f7695e8 100755 --- a/tests/speedtest/test_mf_event_nomfargs.py +++ b/tests_deact/speedtest/test_mf_event_nomfargs.py @@ -13,5 +13,5 @@ def test_mf_event_nomfargs(): mf.load("modulenomfargs") a = 0 - for i in range(10000000): + for _ in range(10000000): a += event.func(42) diff --git a/tests/speedtest/test_mf_event_nonunique.py b/tests_deact/speedtest/test_mf_event_nonunique.py similarity index 90% rename from tests/speedtest/test_mf_event_nonunique.py rename to tests_deact/speedtest/test_mf_event_nonunique.py index e25e55b1..4f5f5bd9 100755 --- a/tests/speedtest/test_mf_event_nonunique.py +++ b/tests_deact/speedtest/test_mf_event_nonunique.py @@ -13,5 +13,5 @@ def test_mf_event_nonunique(): mf.load("modulenonunique") a = 0 - for i in range(10000000): + for _ in range(10000000): a += event.func(42)[0] diff --git a/tests_deact/speedtest/test_mf_python.py b/tests_deact/speedtest/test_mf_python.py new file mode 100755 index 00000000..b78e6a57 --- /dev/null +++ b/tests_deact/speedtest/test_mf_python.py @@ -0,0 +1,18 @@ +from pathlib import Path + +import miniflask # noqa: E402 + +mf = miniflask.init( + module_dirs=str(Path(__file__).parent / "modules"), + debug=True +) + + +def test_mf_python(): + + mf.load("moduleunique") + from modules.moduleunique import func # noqa: F401,E402 # pylint: disable=import-outside-toplevel + + a = 0 + for _ in range(10000000): + a += func(mf.event, mf.state, 42) diff --git a/tests/speedtest/test_mf_state.py b/tests_deact/speedtest/test_mf_state.py similarity index 90% rename from tests/speedtest/test_mf_state.py rename to tests_deact/speedtest/test_mf_state.py index 47c94343..d79dae21 100755 --- a/tests/speedtest/test_mf_state.py +++ b/tests_deact/speedtest/test_mf_state.py @@ -13,5 +13,5 @@ def test_mf_state(): event = mf.event a = 0 - for i in range(10000000): + for _ in range(10000000): a += event.get_state_var("a") diff --git a/tests/speedtest/test_mf_state_fuzzy.py b/tests_deact/speedtest/test_mf_state_fuzzy.py similarity index 90% rename from tests/speedtest/test_mf_state_fuzzy.py rename to tests_deact/speedtest/test_mf_state_fuzzy.py index 21f928bb..0ab7c031 100755 --- a/tests/speedtest/test_mf_state_fuzzy.py +++ b/tests_deact/speedtest/test_mf_state_fuzzy.py @@ -13,5 +13,5 @@ def test_mf_state_fuzzy(): event = mf.event a = 0 - for i in range(10000000): + for _ in range(10000000): a += event.get_state_var(".moduleunique.a") diff --git a/tests/speedtest/test_python.py b/tests_deact/speedtest/test_python.py similarity index 71% rename from tests/speedtest/test_python.py rename to tests_deact/speedtest/test_python.py index e3643499..f18eda53 100755 --- a/tests/speedtest/test_python.py +++ b/tests_deact/speedtest/test_python.py @@ -4,5 +4,5 @@ def func(): def test_python(): a = 0 - for i in range(10000000): + for _ in range(10000000): a += func() From 1ab019d4d0a609f70aeefe0e562ea95cc364c34e Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Mon, 28 Dec 2020 11:03:47 +0100 Subject: [PATCH 14/26] .gitignore: added tests/*/miniflask (links to this very miniflask version during development) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0e802c5b..db790d23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +tests/*/miniflask .idea # Byte-compiled / optimized / DLL files __pycache__/ From b22e72be322c41532c7f5e387e9b0cf6c63e5283 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Mon, 28 Dec 2020 17:13:49 +0100 Subject: [PATCH 15/26] import_module: bugfix for case where module exists, but __init__ is inaccessible --- src/miniflask/miniflask.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index 3bc39fa5..34e1790a 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -151,7 +151,7 @@ def import_module(self, module_name): return parent_module spec = find_spec(module_spec["importname"], package=parent_module) - if spec is None: + if spec is None or spec.loader is None: raise ValueError("Module named '%s' (defined in '%s') could not be imported." % (module_spec["id"], module_spec["importpath"])) return spec.loader.load_module() From e352d4a302baa88339ff116a74f6db3ad558eef5 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 29 Dec 2020 11:55:44 +0100 Subject: [PATCH 16/26] tests: replaced pip install with link to current version --- .github/workflows/pytest.yml | 2 -- .gitignore | 1 - tests/enums/miniflask | 1 + tests/exception_event/miniflask | 1 + tests/exception_register/miniflask | 1 + tests/features/miniflask | 1 + tests/outervar/miniflask | 1 + tests/test_import/miniflask | 1 + 8 files changed, 6 insertions(+), 3 deletions(-) create mode 120000 tests/enums/miniflask create mode 120000 tests/exception_event/miniflask create mode 120000 tests/exception_register/miniflask create mode 120000 tests/features/miniflask create mode 120000 tests/outervar/miniflask create mode 120000 tests/test_import/miniflask diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 950b85fe..d677b855 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -19,8 +19,6 @@ jobs: python -m pip install flake8 pylint pytest # install deps for pylint python -m pip install colored - # build and install the package itself - python -m pip install . - name: Syntax Check of Tests run: | # stop the build if there are Python syntax errors or undefined names diff --git a/.gitignore b/.gitignore index db790d23..0e802c5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -tests/*/miniflask .idea # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/tests/enums/miniflask b/tests/enums/miniflask new file mode 120000 index 00000000..f3e4f4fd --- /dev/null +++ b/tests/enums/miniflask @@ -0,0 +1 @@ +../../src/miniflask \ No newline at end of file diff --git a/tests/exception_event/miniflask b/tests/exception_event/miniflask new file mode 120000 index 00000000..f3e4f4fd --- /dev/null +++ b/tests/exception_event/miniflask @@ -0,0 +1 @@ +../../src/miniflask \ No newline at end of file diff --git a/tests/exception_register/miniflask b/tests/exception_register/miniflask new file mode 120000 index 00000000..f3e4f4fd --- /dev/null +++ b/tests/exception_register/miniflask @@ -0,0 +1 @@ +../../src/miniflask \ No newline at end of file diff --git a/tests/features/miniflask b/tests/features/miniflask new file mode 120000 index 00000000..f3e4f4fd --- /dev/null +++ b/tests/features/miniflask @@ -0,0 +1 @@ +../../src/miniflask \ No newline at end of file diff --git a/tests/outervar/miniflask b/tests/outervar/miniflask new file mode 120000 index 00000000..f3e4f4fd --- /dev/null +++ b/tests/outervar/miniflask @@ -0,0 +1 @@ +../../src/miniflask \ No newline at end of file diff --git a/tests/test_import/miniflask b/tests/test_import/miniflask new file mode 120000 index 00000000..f3e4f4fd --- /dev/null +++ b/tests/test_import/miniflask @@ -0,0 +1 @@ +../../src/miniflask \ No newline at end of file From 1148e1743bc8981287df672016d3f31b3577c10e Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 29 Dec 2020 12:03:20 +0100 Subject: [PATCH 17/26] tests: removing deactivated tests from repository --- .gitignore | 1 + .../speedtest/modules/modulenomfargs/.module | 0 .../modules/modulenomfargs/__init__.py | 7 ------ .../speedtest/modules/modulenonunique/.module | 0 .../modules/modulenonunique/__init__.py | 7 ------ .../speedtest/modules/moduleunique/.module | 0 .../modules/moduleunique/__init__.py | 21 ---------------- tests_deact/speedtest/test_mf_class.py | 24 ------------------- tests_deact/speedtest/test_mf_event.py | 17 ------------- .../speedtest/test_mf_event_nomfargs.py | 17 ------------- .../speedtest/test_mf_event_nonunique.py | 17 ------------- tests_deact/speedtest/test_mf_python.py | 18 -------------- tests_deact/speedtest/test_mf_state.py | 17 ------------- tests_deact/speedtest/test_mf_state_fuzzy.py | 17 ------------- tests_deact/speedtest/test_python.py | 8 ------- 15 files changed, 1 insertion(+), 170 deletions(-) delete mode 100644 tests_deact/speedtest/modules/modulenomfargs/.module delete mode 100644 tests_deact/speedtest/modules/modulenomfargs/__init__.py delete mode 100644 tests_deact/speedtest/modules/modulenonunique/.module delete mode 100644 tests_deact/speedtest/modules/modulenonunique/__init__.py delete mode 100644 tests_deact/speedtest/modules/moduleunique/.module delete mode 100644 tests_deact/speedtest/modules/moduleunique/__init__.py delete mode 100755 tests_deact/speedtest/test_mf_class.py delete mode 100755 tests_deact/speedtest/test_mf_event.py delete mode 100755 tests_deact/speedtest/test_mf_event_nomfargs.py delete mode 100755 tests_deact/speedtest/test_mf_event_nonunique.py delete mode 100755 tests_deact/speedtest/test_mf_python.py delete mode 100755 tests_deact/speedtest/test_mf_state.py delete mode 100755 tests_deact/speedtest/test_mf_state_fuzzy.py delete mode 100755 tests_deact/speedtest/test_python.py diff --git a/.gitignore b/.gitignore index 0e802c5b..a68945cb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +tests_deact .idea # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/tests_deact/speedtest/modules/modulenomfargs/.module b/tests_deact/speedtest/modules/modulenomfargs/.module deleted file mode 100644 index e69de29b..00000000 diff --git a/tests_deact/speedtest/modules/modulenomfargs/__init__.py b/tests_deact/speedtest/modules/modulenomfargs/__init__.py deleted file mode 100644 index ab96bfac..00000000 --- a/tests_deact/speedtest/modules/modulenomfargs/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -def func(x, **kwargs): - del kwargs # unused - return x - - -def register(mf): - mf.register_event('func', func, unique=True) diff --git a/tests_deact/speedtest/modules/modulenonunique/.module b/tests_deact/speedtest/modules/modulenonunique/.module deleted file mode 100644 index e69de29b..00000000 diff --git a/tests_deact/speedtest/modules/modulenonunique/__init__.py b/tests_deact/speedtest/modules/modulenonunique/__init__.py deleted file mode 100644 index 0dbee48f..00000000 --- a/tests_deact/speedtest/modules/modulenonunique/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -def func(state, event, x): - del state, event # unused - return x - - -def register(mf): - mf.register_event('func', func, unique=False) diff --git a/tests_deact/speedtest/modules/moduleunique/.module b/tests_deact/speedtest/modules/moduleunique/.module deleted file mode 100644 index e69de29b..00000000 diff --git a/tests_deact/speedtest/modules/moduleunique/__init__.py b/tests_deact/speedtest/modules/moduleunique/__init__.py deleted file mode 100644 index 1f69d1aa..00000000 --- a/tests_deact/speedtest/modules/moduleunique/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -def func(state, event, x): - del state, event # unused - return x - - -def before_func(state, event, *args, **kwargs): - del state, event # unused - return args, kwargs - - -def get_state_var(state, varname): - return state[varname] - - -def register(mf): - mf.register_event('func', func, unique=True, call_before_after=True) - mf.register_event('before_func', before_func) - mf.register_event('get_state_var', get_state_var, unique=True) - mf.register_defaults({ - "a": 42 - }) diff --git a/tests_deact/speedtest/test_mf_class.py b/tests_deact/speedtest/test_mf_class.py deleted file mode 100755 index 2795bba6..00000000 --- a/tests_deact/speedtest/test_mf_class.py +++ /dev/null @@ -1,24 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -class event(): # pylint: disable=too-few-public-methods - - @classmethod - def func(cls, x): - return x - - -def test_mf_class(): - - mf.load("moduleunique") - - a = 0 - for _ in range(10000000): - a += event.func(42) diff --git a/tests_deact/speedtest/test_mf_event.py b/tests_deact/speedtest/test_mf_event.py deleted file mode 100755 index f1740967..00000000 --- a/tests_deact/speedtest/test_mf_event.py +++ /dev/null @@ -1,17 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -def test_mf_event(): - event = mf.event - mf.load("moduleunique") - - a = 0 - for _ in range(10000000): - a += event.func(42) diff --git a/tests_deact/speedtest/test_mf_event_nomfargs.py b/tests_deact/speedtest/test_mf_event_nomfargs.py deleted file mode 100755 index 6f7695e8..00000000 --- a/tests_deact/speedtest/test_mf_event_nomfargs.py +++ /dev/null @@ -1,17 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -def test_mf_event_nomfargs(): - event = mf.event - mf.load("modulenomfargs") - - a = 0 - for _ in range(10000000): - a += event.func(42) diff --git a/tests_deact/speedtest/test_mf_event_nonunique.py b/tests_deact/speedtest/test_mf_event_nonunique.py deleted file mode 100755 index 4f5f5bd9..00000000 --- a/tests_deact/speedtest/test_mf_event_nonunique.py +++ /dev/null @@ -1,17 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -def test_mf_event_nonunique(): - event = mf.event - mf.load("modulenonunique") - - a = 0 - for _ in range(10000000): - a += event.func(42)[0] diff --git a/tests_deact/speedtest/test_mf_python.py b/tests_deact/speedtest/test_mf_python.py deleted file mode 100755 index b78e6a57..00000000 --- a/tests_deact/speedtest/test_mf_python.py +++ /dev/null @@ -1,18 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -def test_mf_python(): - - mf.load("moduleunique") - from modules.moduleunique import func # noqa: F401,E402 # pylint: disable=import-outside-toplevel - - a = 0 - for _ in range(10000000): - a += func(mf.event, mf.state, 42) diff --git a/tests_deact/speedtest/test_mf_state.py b/tests_deact/speedtest/test_mf_state.py deleted file mode 100755 index d79dae21..00000000 --- a/tests_deact/speedtest/test_mf_state.py +++ /dev/null @@ -1,17 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -def test_mf_state(): - mf.load("moduleunique") - event = mf.event - - a = 0 - for _ in range(10000000): - a += event.get_state_var("a") diff --git a/tests_deact/speedtest/test_mf_state_fuzzy.py b/tests_deact/speedtest/test_mf_state_fuzzy.py deleted file mode 100755 index 0ab7c031..00000000 --- a/tests_deact/speedtest/test_mf_state_fuzzy.py +++ /dev/null @@ -1,17 +0,0 @@ -from pathlib import Path - -import miniflask # noqa: E402 - -mf = miniflask.init( - module_dirs=str(Path(__file__).parent / "modules"), - debug=True -) - - -def test_mf_state_fuzzy(): - mf.load("moduleunique") - event = mf.event - - a = 0 - for _ in range(10000000): - a += event.get_state_var(".moduleunique.a") diff --git a/tests_deact/speedtest/test_python.py b/tests_deact/speedtest/test_python.py deleted file mode 100755 index f18eda53..00000000 --- a/tests_deact/speedtest/test_python.py +++ /dev/null @@ -1,8 +0,0 @@ -def func(): - return 42 - - -def test_python(): - a = 0 - for _ in range(10000000): - a += func() From 22c68aa8ba03d57d7d6592fc2edacf0162d470d6 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 29 Dec 2020 12:41:03 +0100 Subject: [PATCH 18/26] tests: minor pylint fix --- tests/used_case1/modules/datasets/__init__.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/used_case1/modules/datasets/__init__.py b/tests/used_case1/modules/datasets/__init__.py index 055b2879..0144ce1a 100644 --- a/tests/used_case1/modules/datasets/__init__.py +++ b/tests/used_case1/modules/datasets/__init__.py @@ -1,8 +1,3 @@ def register(mf): + del mf print("data") - pass - # mf.load(["cifar10","main_loop"]) - # defaults = { - # "num_runs": 2 - # } - # mf.register_defaults(defaults) From e63fbfaa052c84e3f27fa8a1d96a38fe0027b71b Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 29 Dec 2020 12:42:54 +0100 Subject: [PATCH 19/26] .github/workflows/pytest: let pylint use current version & check all tests by itself --- .github/workflows/pytest.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index d677b855..97be71be 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -26,7 +26,7 @@ jobs: - name: Static Analysis of Tests (Modules) run: | flake8 tests --count --ignore E501 --statistics - pylint -d W0511 -d C0114 -d C0116 -d C0115 -d C0301 -d C0103 -d R0913 -d R0914 -d R0902 -d R0912 -d R0801 -d W0212 -d W0223 -d E1101 -d W0221 -d E1102 `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` - pylint --exit-zero `find tests -type f -name '.module' -printf '%h\0' | sort -zu | sed -z 's/$/\n/'` + PYTHONPATH=$(pwd)/src find tests -type d -exec test -e '{}'/.module \; -exec pylint -d W0511 -d C0114 -d C0116 -d C0115 -d C0301 -d C0103 -d R0913 -d R0914 -d R0902 -d R0912 -d R0801 -d W0212 -d W0223 -d E1101 -d W0221 -d E1102 '{}' + + PYTHONPATH=$(pwd)/src find tests -type d -exec test -e '{}'/.module \; -exec pylint --exit-zero '{}' + - name: Pytest run: pytest From 55e48a650097c46c5c9b623dd287326568219bcc Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 29 Dec 2020 15:59:32 +0100 Subject: [PATCH 20/26] tests: fixed missing ignore of sys.argv to all tests --- .pre-commit-config.yaml | 6 +++--- .../test_argparse_required_types.py | 2 +- tests/test_import/test_basic_import.py | 20 +++++++++---------- tests/test_import/test_relative_import.py | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8e84a95a..8184a07f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,12 +7,12 @@ repos: - id: check-yaml - id: check-added-large-files - id: flake8 - args: [--count,--ignore,E501,--statistics,--exclude,.git,__pycache__] + args: [--count,--ignore,E501,--statistics,--exclude,.git] - repo: local hooks: - id: pylint name: pylint - entry: pylint + entry: bash -c "PYTHONPATH=$(pwd)/src find tests -type d -exec test -e '{}'/.module \; -exec pylint -d W0511 -d C0114 -d C0116 -d C0115 -d C0301 -d C0103 -d R0913 -d R0914 -d R0902 -d R0912 -d R0801 -d W0212 -d W0223 -d E1101 -d W0221 -d E1102 '{}' +" language: system types: [python] - args: [ -d W0511 , -d C0114 , -d C0116 , -d C0115 , -d C0301 , -d C0103 , -d R0913 , -d R0914 , -d R0902 , -d R0912 , -d R0801 , -d W0212 , -d W0223 , -d E1101 , -d W0221 , -d E1102, -d E0611 ] + args: [ ] diff --git a/tests/test_argparse_required/test_argparse_required_types.py b/tests/test_argparse_required/test_argparse_required_types.py index 195fdc68..a306f5cb 100644 --- a/tests/test_argparse_required/test_argparse_required_types.py +++ b/tests/test_argparse_required/test_argparse_required_types.py @@ -26,7 +26,7 @@ def test_types(capsys): The following argument is required: --modules.module1.str3 """.strip() with pytest.raises(SystemExit) as excinfo: - mf.parse_args() + mf.parse_args(argv=[]) captured = capsys.readouterr() assert excinfo.value.args[0] == 2 diff --git a/tests/test_import/test_basic_import.py b/tests/test_import/test_basic_import.py index fe93a966..77474660 100644 --- a/tests/test_import/test_basic_import.py +++ b/tests/test_import/test_basic_import.py @@ -9,28 +9,28 @@ def init_mf(): def test_shortid(): mf = init_mf() - mf.run(modules=["module1"]) + mf.run(argv=[], modules=["module1"]) assert "modules.parentdir.module1" in mf.modules_loaded assert len(mf.modules_loaded) == 1 def test_partial_id(): mf = init_mf() - mf.run(modules=["modules.module1"]) + mf.run(argv=[], modules=["modules.module1"]) assert "modules.parentdir.module1" in mf.modules_loaded assert len(mf.modules_loaded) == 1 def test_partial_id_2(): mf = init_mf() - mf.run(modules=["parentdir.module1"]) + mf.run(argv=[], modules=["parentdir.module1"]) assert "modules.parentdir.module1" in mf.modules_loaded assert len(mf.modules_loaded) == 1 def test_full_id(): mf = init_mf() - mf.run(modules=["modules.parentdir.module1"]) + mf.run(argv=[], modules=["modules.parentdir.module1"]) assert "modules.parentdir.module1" in mf.modules_loaded assert len(mf.modules_loaded) == 1 @@ -38,7 +38,7 @@ def test_full_id(): def test_shortid_error(): mf = init_mf() with pytest.raises(ValueError) as excinfo: - mf.run(modules=["module2"]) + mf.run(argv=[], modules=["module2"]) assert "is not unique" in str(excinfo.value) assert len(mf.modules_loaded) == 0 @@ -46,34 +46,34 @@ def test_shortid_error(): def test_partial_id_error(): mf = init_mf() with pytest.raises(ValueError) as excinfo: - mf.run(modules=["modules.module2"]) + mf.run(argv=[], modules=["modules.module2"]) assert "is not unique" in str(excinfo.value) assert len(mf.modules_loaded) == 0 def test_partial_id_3(): mf = init_mf() - mf.run(modules=["modules.otherdir.module2"]) + mf.run(argv=[], modules=["modules.otherdir.module2"]) assert "modules.otherdir.module2" in mf.modules_loaded assert len(mf.modules_loaded) == 1 def test_partial_id_4(): mf = init_mf() - mf.run(modules=["modules.otherdir.module2"]) + mf.run(argv=[], modules=["modules.otherdir.module2"]) assert "modules.otherdir.module2" in mf.modules_loaded assert len(mf.modules_loaded) == 1 def test_partial_id_5(): mf = init_mf() - mf.run(modules=["parentdir.module2"]) + mf.run(argv=[], modules=["parentdir.module2"]) assert "modules.parentdir.module2" in mf.modules_loaded assert len(mf.modules_loaded) == 1 def test_partial_id_6(): mf = init_mf() - mf.run(modules=["parentdir.module2"]) + mf.run(argv=[], modules=["parentdir.module2"]) assert "modules.parentdir.module2" in mf.modules_loaded assert len(mf.modules_loaded) == 1 diff --git a/tests/test_import/test_relative_import.py b/tests/test_import/test_relative_import.py index 390546f7..349bf6cf 100644 --- a/tests/test_import/test_relative_import.py +++ b/tests/test_import/test_relative_import.py @@ -8,7 +8,7 @@ def init_mf(): def test_passive_submodule_import(): mf = init_mf() - mf.run(modules=["module3"]) + mf.run(argv=[], modules=["module3"]) assert "modules.parentdir.module3" in mf.modules_loaded assert "modules.parentdir.module3.submodule" in mf.modules_loaded assert len(mf.modules_loaded) == 2 @@ -16,14 +16,14 @@ def test_passive_submodule_import(): def test_active_submodule_import(): mf = init_mf() - mf.run(modules=["submodule"]) + mf.run(argv=[], modules=["submodule"]) assert "modules.parentdir.module3.submodule" in mf.modules_loaded assert len(mf.modules_loaded) == 1 def test_relative_import(): mf = init_mf() - mf.run(modules=["module4"]) + mf.run(argv=[], modules=["module4"]) assert "modules.parentdir.module4" in mf.modules_loaded assert "modules.parentdir.module3" in mf.modules_loaded assert "modules.parentdir.module3.submodule" in mf.modules_loaded @@ -32,7 +32,7 @@ def test_relative_import(): def test_relative_import_2(): mf = init_mf() - mf.run(modules=["module5"]) + mf.run(argv=[], modules=["module5"]) assert "modules.parentdir.module5" in mf.modules_loaded assert "modules.otherdir.module2" in mf.modules_loaded assert len(mf.modules_loaded) == 2 From ef8f991a1c35d9fdbfe61098d7f3059413412565 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 29 Dec 2020 16:12:27 +0100 Subject: [PATCH 21/26] bugfix: add package_prefix to all modules to ensure multiple instances do not interfere --- src/miniflask/miniflask.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index 34e1790a..c1de1d60 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -11,6 +11,7 @@ from enum import Enum, EnumMeta from argparse import ArgumentParser, REMAINDER as ARGPARSE_REMAINDER from typing import List +import random from colored import fg, attr @@ -44,6 +45,7 @@ def get_default_args(func): # ================ # class miniflask(): def __init__(self, module_dirs, debug=False): + self._instance_id = str(random.getrandbits(128)) self.debug = debug if not module_dirs: return @@ -144,13 +146,19 @@ def import_module(self, module_name): raise ValueError("Module named '%s' (defined in '%s') could not be imported." % (module_spec["id"], module_spec["importpath"])) if spec.loader is None: raise ValueError("Could not import parent Module named '%s'. This is needed for module named '%s' (defined in '%s'). Did you maybe miss to define a `__init__.py` file in any subfolder?" % (parent_module_name, module_spec["id"], module_spec["importpath"])) + + # ensure sys.modules does not cache different miniflask instances + package_prefix = "miniflask." + self._instance_id + "." + spec.loader.name = package_prefix + spec.loader.name + + # import parent module (repository base) parent_module = spec.loader.load_module() # if importing top-level package in repository, we are done if not rest: return parent_module - spec = find_spec(module_spec["importname"], package=parent_module) + spec = find_spec(package_prefix + module_spec["importname"], package=parent_module) if spec is None or spec.loader is None: raise ValueError("Module named '%s' (defined in '%s') could not be imported." % (module_spec["id"], module_spec["importpath"])) return spec.loader.load_module() From f6b13062b9e8767baeef4e2a5d802f8c0ecaae3e Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Wed, 30 Dec 2020 15:09:15 +0100 Subject: [PATCH 22/26] enabled PosixPath for miniflask.init(module_dirs=...) --- src/miniflask/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miniflask/util.py b/src/miniflask/util.py index db794278..7df8d5c6 100644 --- a/src/miniflask/util.py +++ b/src/miniflask/util.py @@ -12,7 +12,7 @@ def getModulesAvail(module_dirs, f=None): f = {} for base_module_name, directory in module_dirs.items(): base_module_name = base_module_name.replace(".", "_") - # basename_dir = path.basename(directory) + directory = str(directory) # in case directory is given as PosixPath etc. for (dirpath, dirnames, filenames) in walk(directory): local_import_name = dirpath[len(directory) + 1:].replace(path.sep, ".") module_name_id = base_module_name + "." + local_import_name From 0a85fc167d0d16fc852458f084781a065814fa4a Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Tue, 29 Dec 2020 17:55:40 +0100 Subject: [PATCH 23/26] rename mf.redefine_scope(new_id) -> mf.register_as(new_id) --- src/miniflask/miniflask.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index c1de1d60..99ee146a 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -824,11 +824,11 @@ def hooked(*args, **kwargs): return hooked return orig_attr - def redefine_scope(self, new_module_name): + def register_as(self, new_module_name): old_module_name = self.module_id new_module_name = self.set_scope(new_module_name) if new_module_name in self.modules_avail: - raise ValueError("Scope `%s` already used. Cannot define multiple modules using `redefine_scope`. Did you maybe mean to use `set_scope`?" % new_module_name) + raise ValueError("Scope `%s` already used. Cannot define multiple modules using `register_as`. Did you maybe mean to use `set_scope`?" % new_module_name) m = self.modules_avail[old_module_name] del self.modules_avail[old_module_name] m["id"] = new_module_name From b6c10c54007766ae14a0e8a3eb539a6aeca3ef40 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Wed, 30 Dec 2020 15:05:03 +0100 Subject: [PATCH 24/26] tests: added tests for register_as --- tests/test_register_as/miniflask | 1 + .../test_register_as/modules/main/__init__.py | 0 .../modules/main/module_loads_other/.module | 0 .../main/module_loads_other/__init__.py | 5 ++ .../main/module_with_submodule/.module | 0 .../main/module_with_submodule/__init__.py | 5 ++ .../module_with_submodule/submodule/.module | 0 .../submodule/__init__.py | 5 ++ .../modules/replace/__init__.py | 0 .../replace/module_loads_other/.module | 0 .../replace/module_loads_other/__init__.py | 6 ++ .../replace/module_with_submodule/.module | 0 .../replace/module_with_submodule/__init__.py | 6 ++ .../module_with_submodule/submodule/.module | 0 .../submodule/__init__.py | 9 ++ .../modules/replace2/__init__.py | 0 .../replace2/module_loads_other/.module | 0 .../replace2/module_loads_other/__init__.py | 5 ++ .../replace2/module_with_submodule/.module | 0 .../module_with_submodule/__init__.py | 6 ++ .../module_with_submodule/submodule/.module | 0 .../submodule/__init__.py | 9 ++ tests/test_register_as/test_register_as.py | 89 +++++++++++++++++++ 23 files changed, 146 insertions(+) create mode 120000 tests/test_register_as/miniflask create mode 100644 tests/test_register_as/modules/main/__init__.py create mode 100644 tests/test_register_as/modules/main/module_loads_other/.module create mode 100644 tests/test_register_as/modules/main/module_loads_other/__init__.py create mode 100644 tests/test_register_as/modules/main/module_with_submodule/.module create mode 100644 tests/test_register_as/modules/main/module_with_submodule/__init__.py create mode 100644 tests/test_register_as/modules/main/module_with_submodule/submodule/.module create mode 100644 tests/test_register_as/modules/main/module_with_submodule/submodule/__init__.py create mode 100644 tests/test_register_as/modules/replace/__init__.py create mode 100644 tests/test_register_as/modules/replace/module_loads_other/.module create mode 100644 tests/test_register_as/modules/replace/module_loads_other/__init__.py create mode 100644 tests/test_register_as/modules/replace/module_with_submodule/.module create mode 100644 tests/test_register_as/modules/replace/module_with_submodule/__init__.py create mode 100644 tests/test_register_as/modules/replace/module_with_submodule/submodule/.module create mode 100644 tests/test_register_as/modules/replace/module_with_submodule/submodule/__init__.py create mode 100644 tests/test_register_as/modules/replace2/__init__.py create mode 100644 tests/test_register_as/modules/replace2/module_loads_other/.module create mode 100644 tests/test_register_as/modules/replace2/module_loads_other/__init__.py create mode 100644 tests/test_register_as/modules/replace2/module_with_submodule/.module create mode 100644 tests/test_register_as/modules/replace2/module_with_submodule/__init__.py create mode 100644 tests/test_register_as/modules/replace2/module_with_submodule/submodule/.module create mode 100644 tests/test_register_as/modules/replace2/module_with_submodule/submodule/__init__.py create mode 100644 tests/test_register_as/test_register_as.py diff --git a/tests/test_register_as/miniflask b/tests/test_register_as/miniflask new file mode 120000 index 00000000..f3e4f4fd --- /dev/null +++ b/tests/test_register_as/miniflask @@ -0,0 +1 @@ +../../src/miniflask \ No newline at end of file diff --git a/tests/test_register_as/modules/main/__init__.py b/tests/test_register_as/modules/main/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/main/module_loads_other/.module b/tests/test_register_as/modules/main/module_loads_other/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/main/module_loads_other/__init__.py b/tests/test_register_as/modules/main/module_loads_other/__init__.py new file mode 100644 index 00000000..07f8c0a3 --- /dev/null +++ b/tests/test_register_as/modules/main/module_loads_other/__init__.py @@ -0,0 +1,5 @@ + +def register(mf): + file = __file__ + mf.load(["submodule", "module_with_submodule"]) + mf.register_event("main", lambda: print(file)) diff --git a/tests/test_register_as/modules/main/module_with_submodule/.module b/tests/test_register_as/modules/main/module_with_submodule/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/main/module_with_submodule/__init__.py b/tests/test_register_as/modules/main/module_with_submodule/__init__.py new file mode 100644 index 00000000..a37434ff --- /dev/null +++ b/tests/test_register_as/modules/main/module_with_submodule/__init__.py @@ -0,0 +1,5 @@ + +def register(mf): + file = __file__ + mf.load("submodule") + mf.register_event("main", lambda: print(file)) diff --git a/tests/test_register_as/modules/main/module_with_submodule/submodule/.module b/tests/test_register_as/modules/main/module_with_submodule/submodule/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/main/module_with_submodule/submodule/__init__.py b/tests/test_register_as/modules/main/module_with_submodule/submodule/__init__.py new file mode 100644 index 00000000..9f125c0b --- /dev/null +++ b/tests/test_register_as/modules/main/module_with_submodule/submodule/__init__.py @@ -0,0 +1,5 @@ + +def register(mf): + file = __file__ + mf.load("..") + mf.register_event("main", lambda: print(file)) diff --git a/tests/test_register_as/modules/replace/__init__.py b/tests/test_register_as/modules/replace/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace/module_loads_other/.module b/tests/test_register_as/modules/replace/module_loads_other/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace/module_loads_other/__init__.py b/tests/test_register_as/modules/replace/module_loads_other/__init__.py new file mode 100644 index 00000000..2d217888 --- /dev/null +++ b/tests/test_register_as/modules/replace/module_loads_other/__init__.py @@ -0,0 +1,6 @@ + +def register(mf): + file = __file__ + mf.register_as("main.module_loads_other") + mf.load(["submodule", "module_with_submodule"]) + mf.register_event("main", lambda: print(file)) diff --git a/tests/test_register_as/modules/replace/module_with_submodule/.module b/tests/test_register_as/modules/replace/module_with_submodule/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace/module_with_submodule/__init__.py b/tests/test_register_as/modules/replace/module_with_submodule/__init__.py new file mode 100644 index 00000000..e4c6fb80 --- /dev/null +++ b/tests/test_register_as/modules/replace/module_with_submodule/__init__.py @@ -0,0 +1,6 @@ + +def register(mf): + file = __file__ + mf.register_as("main.module_with_submodule") + mf.load("submodule") + mf.register_event("main", lambda: print(file)) diff --git a/tests/test_register_as/modules/replace/module_with_submodule/submodule/.module b/tests/test_register_as/modules/replace/module_with_submodule/submodule/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace/module_with_submodule/submodule/__init__.py b/tests/test_register_as/modules/replace/module_with_submodule/submodule/__init__.py new file mode 100644 index 00000000..b5701d74 --- /dev/null +++ b/tests/test_register_as/modules/replace/module_with_submodule/submodule/__init__.py @@ -0,0 +1,9 @@ + +def register(mf): + file = __file__ + mf.register_as("main.module_with_submodule.submodule") + mf.load("..") + mf.register_event("main", lambda: print(file)) + + +register_parents = False diff --git a/tests/test_register_as/modules/replace2/__init__.py b/tests/test_register_as/modules/replace2/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace2/module_loads_other/.module b/tests/test_register_as/modules/replace2/module_loads_other/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace2/module_loads_other/__init__.py b/tests/test_register_as/modules/replace2/module_loads_other/__init__.py new file mode 100644 index 00000000..07f8c0a3 --- /dev/null +++ b/tests/test_register_as/modules/replace2/module_loads_other/__init__.py @@ -0,0 +1,5 @@ + +def register(mf): + file = __file__ + mf.load(["submodule", "module_with_submodule"]) + mf.register_event("main", lambda: print(file)) diff --git a/tests/test_register_as/modules/replace2/module_with_submodule/.module b/tests/test_register_as/modules/replace2/module_with_submodule/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace2/module_with_submodule/__init__.py b/tests/test_register_as/modules/replace2/module_with_submodule/__init__.py new file mode 100644 index 00000000..77911b12 --- /dev/null +++ b/tests/test_register_as/modules/replace2/module_with_submodule/__init__.py @@ -0,0 +1,6 @@ + +def register(mf): + file = __file__ + mf.register_as("main.module_with_submodule") + mf.load("submodule", repo="replace2") + mf.register_event("main", lambda: print(file)) diff --git a/tests/test_register_as/modules/replace2/module_with_submodule/submodule/.module b/tests/test_register_as/modules/replace2/module_with_submodule/submodule/.module new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_register_as/modules/replace2/module_with_submodule/submodule/__init__.py b/tests/test_register_as/modules/replace2/module_with_submodule/submodule/__init__.py new file mode 100644 index 00000000..b5701d74 --- /dev/null +++ b/tests/test_register_as/modules/replace2/module_with_submodule/submodule/__init__.py @@ -0,0 +1,9 @@ + +def register(mf): + file = __file__ + mf.register_as("main.module_with_submodule.submodule") + mf.load("..") + mf.register_event("main", lambda: print(file)) + + +register_parents = False diff --git a/tests/test_register_as/test_register_as.py b/tests/test_register_as/test_register_as.py new file mode 100644 index 00000000..ed7968c8 --- /dev/null +++ b/tests/test_register_as/test_register_as.py @@ -0,0 +1,89 @@ +from pathlib import Path +import miniflask # noqa: E402 + + +def init_mf(): + base_path = Path(__file__).parent / "modules" + return miniflask.init(module_dirs=[base_path / "main", base_path / "replace", base_path / "replace2"], debug=True) + + +def check(check, out, mf): + assert check in out, "Checking for string '%s' in output: '%s'" % (check, out) + + +def test_register_as_setup(capsys): + mf = init_mf() + mf.run(argv=[], modules=["main.module_loads_other"], call="off") + capsys.readouterr() + mf.event.main() + assert len(mf.modules_loaded) == 3 + captured = capsys.readouterr() + out = captured.out + check("main/module_loads_other", out, mf) + check("main/module_with_submodule", out, mf) + check("main/module_with_submodule/submodule", out, mf) + + +def test_register_as_replace_module_loader_module(capsys): + mf = init_mf() + mf.run(argv=[], modules=["replace.module_loads_other", "main.module_loads_other"], call="off") + capsys.readouterr() + mf.event.main() + assert len(mf.modules_loaded) == 3 + captured = capsys.readouterr() + out = captured.out + check("replace/module_loads_other", out, mf) + check("main/module_with_submodule", out, mf) + check("main/module_with_submodule/submodule", out, mf) + + +def test_register_as_replace_module_loader_module_test_reload(capsys): + mf = init_mf() + mf.run(argv=[], modules=["replace.module_loads_other", "main.module_loads_other"], call="off") + capsys.readouterr() + mf.event.main() + assert len(mf.modules_loaded) == 3 + captured = capsys.readouterr() + out = captured.out + check("replace/module_loads_other", out, mf) + check("main/module_with_submodule", out, mf) + check("main/module_with_submodule/submodule", out, mf) + + +def test_register_as_replace_submodule(capsys): + mf = init_mf() + mf.run(argv=[], modules=["replace.submodule", "main.module_loads_other"], call="off") + capsys.readouterr() + mf.event.main() + assert len(mf.modules_loaded) == 3 + captured = capsys.readouterr() + out = captured.out + check("main/module_loads_other", out, mf) + check("main/module_with_submodule", out, mf) + check("replace/module_with_submodule/submodule", out, mf) + + +def test_register_as_replace_module(capsys): + mf = init_mf() + mf.run(argv=[], modules=["replace.module_with_submodule", "main.module_loads_other"], call="off") + capsys.readouterr() + mf.event.main() + assert len(mf.modules_loaded) == 3 + captured = capsys.readouterr() + out = captured.out + check("main/module_loads_other", out, mf) + check("replace/module_with_submodule", out, mf) + check("main/module_with_submodule/submodule", out, mf) + + +def test_register_as_replace_module_and_submodule(capsys): + mf = init_mf() + mf.run(argv=[], modules=["replace2.module_with_submodule", "main.module_loads_other"], call="off") + capsys.readouterr() + mf.event.main() + assert len(mf.modules_loaded) == 3 + captured = capsys.readouterr() + out = captured.out + check("main/module_loads_other", out, mf) + check("replace2/module_with_submodule", out, mf) + check("replace2/module_with_submodule/submodule", out, mf) From 0854fff1b0ab640bd263327fd52dea58087feacd Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Wed, 30 Dec 2020 15:06:04 +0100 Subject: [PATCH 25/26] bugfix: event[module_id] was wrong if module name changes during register() --- src/miniflask/miniflask.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index 99ee146a..e6fbdf90 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -355,8 +355,9 @@ def load(self, module_name, verbose=True, auto_query=True, loading_text=highligh # register events mod.register(mod.miniflask_obj) - self.event[module_name] = mod.miniflask_obj._defined_events - self.event.optional[module_name] = mod.miniflask_obj._defined_events + module_id = mod.miniflask_obj.module_id + self.event[module_id] = mod.miniflask_obj._defined_events + self.event.optional[module_id] = mod.miniflask_obj._defined_events # loading message if verbose: From 4d8c5ef239522bf8148fbc9c030c399f23dc95d9 Mon Sep 17 00:00:00 2001 From: David Hartmann Date: Wed, 30 Dec 2020 15:08:00 +0100 Subject: [PATCH 26/26] rework register_as and the internal use of the repository name --- src/miniflask/miniflask.py | 61 +++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/src/miniflask/miniflask.py b/src/miniflask/miniflask.py index e6fbdf90..1860bf08 100644 --- a/src/miniflask/miniflask.py +++ b/src/miniflask/miniflask.py @@ -794,23 +794,29 @@ def __init__(self, module_name, mf): # pylint: disable=super-init-not-called self.module_id = module_name self.module_id_initial = module_name self.module_name = module_name.split(".")[-1] - self.module_base = module_name.split(".")[0] + self.module_repository, self.module_relative_id = module_name.split(".", 1) self.wrapped_class = mf.wrapped_class if hasattr(mf, 'wrapped_class') else mf self.state = state(module_name, self.wrapped_class.state, self.wrapped_class.state_default) self._recently_loaded = [] self._defined_events = {} - def _get_relative_module_id(self, module_name, offset=1): + def _get_absolute_module_id(self, module_query, offset=1, repo="same"): was_relative = False - m = relative_import_re.match(module_name) + module_middle = [module_query] + module_name = [] + repo = [self.module_repository] if repo == "same" else [] if not repo else [repo] + + m = relative_import_re.match(module_query) if m is not None: upmodule = len(m[1]) - relative_module = m[2] - if upmodule == offset: - module_name = self.module_id + ("." + relative_module if relative_module else "") + module_name = [m[2]] if m[2] else [] + if upmodule != offset: + module_middle = self.module_relative_id.split(".")[:-upmodule + offset] else: - module_name = ".".join(self.module_id.split(".")[:-upmodule + offset]) + ("." + relative_module if relative_module else "") + module_middle = [self.module_relative_id] was_relative = True + + module_name = ".".join(repo + module_middle + module_name) return module_name, was_relative def __getattr__(self, name): @@ -825,21 +831,20 @@ def hooked(*args, **kwargs): return hooked return orig_attr - def register_as(self, new_module_name): - old_module_name = self.module_id - new_module_name = self.set_scope(new_module_name) - if new_module_name in self.modules_avail: - raise ValueError("Scope `%s` already used. Cannot define multiple modules using `register_as`. Did you maybe mean to use `set_scope`?" % new_module_name) - m = self.modules_avail[old_module_name] - del self.modules_avail[old_module_name] - m["id"] = new_module_name - self.modules_avail[new_module_name] = m - - def set_scope(self, new_module_name): - new_module_name, was_relative = self._get_relative_module_id(new_module_name) - if not was_relative: - new_module_name = self.module_base + "." + new_module_name + def register_as(self, new_module_id): + old_module_id = self.module_repository + "." + self.module_relative_id + new_module_repo, new_module_name = new_module_id.split(".", 1) + new_module_id = self.set_scope(new_module_name, repo=new_module_repo) + if new_module_id in self.modules_loaded: + raise ValueError("Scope `%s` already used. Cannot define multiple modules using `register_as`. Did you maybe mean to use `set_scope`?" % new_module_id) + m = self.modules_loaded[old_module_id] + del self.modules_loaded[old_module_id] + self.modules_loaded[new_module_id] = m + + def set_scope(self, new_module_name, repo="same"): + new_module_name, _ = self._get_absolute_module_id(new_module_name, repo=repo) self.module_id = new_module_name + self.module_repository, self.module_relative_id = new_module_name.split(".", 1) self.state.module_id = new_module_name return new_module_name @@ -847,7 +852,7 @@ def set_scope(self, new_module_name): def like(self, varname, alt, scope="."): scope_name = scope if scope is not None: - scope, _ = self._get_relative_module_id(scope) + scope, _ = self._get_absolute_module_id(scope) return like(varname, alt, scope=scope, scope_name=scope_name) # loads module dependencies as child module @@ -855,7 +860,7 @@ def load_as_child(self, module_name, **kwargs): self.load(module_name, as_id='.', bind_events=False, **kwargs) # enables relative imports - def load(self, module_name, as_id=None, auto_query=True, **kwargs): + def load(self, module_name, as_id=None, auto_query=True, repo="same", **kwargs): # if nothing given, ignore if module_name is None: @@ -866,17 +871,17 @@ def load(self, module_name, as_id=None, auto_query=True, **kwargs): module_name = module_name.split(",") if isinstance(module_name, list): for mname in module_name: - self.load(mname, as_id=as_id, auto_query=auto_query, **kwargs) + self.load(mname, as_id=as_id, auto_query=auto_query, repo=repo, **kwargs) return # if as_id given, determine new module_name if as_id: if as_id.endswith("."): as_id += module_name.split(".")[-1] - as_id, _ = self._get_relative_module_id(as_id) + as_id, _ = self._get_absolute_module_id(as_id, repo=repo) # parse relative imports first - module_name, was_relative = self._get_relative_module_id(module_name) + module_name, was_relative = self._get_absolute_module_id(module_name, repo=repo) auto_query = not was_relative # call load (but ensure no querying is made if relative imports were given) @@ -891,8 +896,8 @@ def register_event(self, name, fn, **kwargs): def register_defaults(self, defaults, scope=None, **kwargs): # default behaviour is to use current module-name if scope is None: - scope = self.module_id - scope, _ = self._get_relative_module_id(scope, offset=1) + scope = self.module_relative_id + scope, _ = self._get_absolute_module_id(scope) super().register_defaults(defaults, scope=scope, **kwargs) # helper variables are not added to argument parser