From f2e02e2a7c2e7579827d3b0a4d1539b0a95be525 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Mon, 25 Apr 2022 21:24:58 +0300 Subject: [PATCH] #896 Restrict including routers with strings (#897) * #896 Restrict including routers with strings * Remove imports util, bump dependencies --- CHANGES/896.misc.rst | 1 + aiogram/dispatcher/router.py | 3 --- aiogram/utils/imports.py | 23 ---------------------- poetry.lock | 14 +++++++------- pyproject.toml | 4 ++-- tests/test_dispatcher/test_router.py | 7 +------ tests/test_utils/test_imports.py | 29 ---------------------------- 7 files changed, 11 insertions(+), 70 deletions(-) create mode 100644 CHANGES/896.misc.rst delete mode 100644 aiogram/utils/imports.py delete mode 100644 tests/test_utils/test_imports.py diff --git a/CHANGES/896.misc.rst b/CHANGES/896.misc.rst new file mode 100644 index 00000000..9dbd6db4 --- /dev/null +++ b/CHANGES/896.misc.rst @@ -0,0 +1 @@ +Restrict including routers with strings diff --git a/aiogram/dispatcher/router.py b/aiogram/dispatcher/router.py index a1a20fba..9f1c0f77 100644 --- a/aiogram/dispatcher/router.py +++ b/aiogram/dispatcher/router.py @@ -4,7 +4,6 @@ import warnings from typing import Any, Dict, Generator, List, Optional, Set, Union from ..types import TelegramObject -from ..utils.imports import import_module from ..utils.warnings import CodeHasNoEffect from .event.bases import REJECTED, UNHANDLED from .event.event import EventObserver @@ -211,8 +210,6 @@ class Router: :param router: :return: """ - if isinstance(router, str): # Resolve import string - router = import_module(router) if not isinstance(router, Router): raise ValueError( f"router should be instance of Router not {type(router).__class__.__name__}" diff --git a/aiogram/utils/imports.py b/aiogram/utils/imports.py deleted file mode 100644 index edc0a6a0..00000000 --- a/aiogram/utils/imports.py +++ /dev/null @@ -1,23 +0,0 @@ -import importlib -from typing import Any - - -def import_module(target: str) -> Any: - if not isinstance(target, str): - raise ValueError(f"Target should be string not {type(target).__class__.__name__}") - - module_name, _, attr_name = target.partition(":") - if not module_name or not attr_name: - raise ValueError(f'Import string "{target}" must be in format ":"') - - try: - module = importlib.import_module(module_name) - except ImportError: - raise ValueError(f'Could not import module "{module_name}".') - - try: - attribute = getattr(module, attr_name) - except AttributeError: - raise ValueError(f'Module "{module_name}" has no attribute "{attr_name}"') - - return attribute diff --git a/poetry.lock b/poetry.lock index 0ac8ef45..e3ebed69 100644 --- a/poetry.lock +++ b/poetry.lock @@ -503,7 +503,7 @@ tornado = {version = "*", markers = "python_version > \"2.7\""} [[package]] name = "magic-filter" -version = "1.0.6" +version = "1.0.7" description = "This package provides magic filter based on dynamic attribute getter" category = "main" optional = false @@ -794,7 +794,7 @@ diagrams = ["railroad-diagrams", "jinja2"] [[package]] name = "pytest" -version = "7.1.1" +version = "7.1.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false @@ -1398,7 +1398,7 @@ redis = ["redis"] [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "610623143deda7ddf0a604a0447178549a89c8914509d2c1bff4367917e8aaa1" +content-hash = "d3a0b716a9dcb5353de9ef0587a49025da4351eb68a4327c0b3c8a24791251ee" [metadata.files] aiofiles = [ @@ -1759,8 +1759,8 @@ livereload = [ {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, ] magic-filter = [ - {file = "magic-filter-1.0.6.tar.gz", hash = "sha256:dd022b088df644b94fd087b4ef8bb3eabb7d96dfc93f59ae9a859ca26881ef61"}, - {file = "magic_filter-1.0.6-py3-none-any.whl", hash = "sha256:499a76a4c023fd6e90e49c4fca6edaf338725c3a923987a6dcdb52fdf4d93ed9"}, + {file = "magic-filter-1.0.7.tar.gz", hash = "sha256:b00fbe7321719290443a9c72a30314a4c29d8e676d42abfe228b41c5dc4e5d2f"}, + {file = "magic_filter-1.0.7-py3-none-any.whl", hash = "sha256:cf591b7f8c4a5037e162fb054ff84e6a7f6db05eb36f312f60b8bfefddc12294"}, ] markdown = [ {file = "Markdown-3.3.6-py3-none-any.whl", hash = "sha256:9923332318f843411e9932237530df53162e29dc7a4e2b91e35764583c46c9a3"}, @@ -2019,8 +2019,8 @@ pyparsing = [ {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, ] pytest = [ - {file = "pytest-7.1.1-py3-none-any.whl", hash = "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea"}, - {file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"}, + {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"}, + {file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"}, ] pytest-aiohttp = [ {file = "pytest-aiohttp-1.0.4.tar.gz", hash = "sha256:39ff3a0d15484c01d1436cbedad575c6eafbf0f57cdf76fb94994c97b5b8c5a4"}, diff --git a/pyproject.toml b/pyproject.toml index 8e85e24d..14cdfc3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ classifiers = [ [tool.poetry.dependencies] python = "^3.8" -magic-filter = "^1.0.6" +magic-filter = "^1.0.7" aiohttp = "^3.8.1" pydantic = "^1.9.0" aiofiles = "^0.8.0" @@ -69,7 +69,7 @@ black = "^22.1.0" isort = "^5.10.1" flake8 = "^4.0.1" mypy = "^0.942" -pytest = "^7.0.1" +pytest = "^7.1.2" pytest-html = "^3.1.1" pytest-asyncio = "^0.18.1" pytest-lazy-fixture = "^0.6.3" diff --git a/tests/test_dispatcher/test_router.py b/tests/test_dispatcher/test_router.py index 56821f46..7f98e971 100644 --- a/tests/test_dispatcher/test_router.py +++ b/tests/test_dispatcher/test_router.py @@ -5,7 +5,6 @@ from aiogram.dispatcher.router import Router from aiogram.utils.warnings import CodeHasNoEffect pytestmark = pytest.mark.asyncio -importable_router = Router() class TestRouter: @@ -46,14 +45,10 @@ class TestRouter: with pytest.warns(CodeHasNoEffect): assert router1.include_router(router2) - def test_include_router_by_string(self): - router = Router() - router.include_router("tests.test_dispatcher.test_router:importable_router") - def test_include_router_by_string_bad_type(self): router = Router() with pytest.raises(ValueError, match=r"router should be instance of Router"): - router.include_router("tests.test_dispatcher.test_router:TestRouter") + router.include_router(self) def test_set_parent_router_bad_type(self): router = Router() diff --git a/tests/test_utils/test_imports.py b/tests/test_utils/test_imports.py deleted file mode 100644 index e877201c..00000000 --- a/tests/test_utils/test_imports.py +++ /dev/null @@ -1,29 +0,0 @@ -import pytest - -import aiogram -from aiogram.utils.imports import import_module - - -class TestImports: - def test_bad_type(self): - with pytest.raises(ValueError, match=r"Target should be string not"): - import_module(42) - - @pytest.mark.parametrize("value", ["module", "module:", ":attribute"]) - def test_bad_format(self, value): - with pytest.raises(ValueError, match='must be in format ":"'): - import_module(value) - - @pytest.mark.parametrize("value", ["module", "aiogram.KABOOM", "aiogram.KABOOM.TEST"]) - def test_bad_value(self, value): - with pytest.raises(ValueError, match="Could not import module"): - import_module(f"{value}:attribute") - - def test_has_no_attribute(self): - with pytest.raises(ValueError, match="has no attribute"): - import_module("aiogram:KABOOM") - - def test_imported(self): - value = import_module("aiogram:__version__") - isinstance(value, str) - assert value == aiogram.__version__