Skip to content

Commit 0142449

Browse files
committed
refactor: remove custom logging implementation
BRAEKING CHANGE
1 parent 1573c6a commit 0142449

9 files changed

Lines changed: 50 additions & 150 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- [Configuration file](#configuration-file)
2222
- [Cache](#cache)
2323
- [Using `Twyn` as a library](#using-twyn-as-a-library)
24+
- [Logging level](#logging-level)
2425

2526
## Overview
2627
`Twyn` is a security tool that compares the name of your dependencies against a set of the most popular ones,
@@ -214,3 +215,10 @@ for typo in typos.errors:
214215
print(f"Did you mean any of [{','.join(typo.similars)}]")
215216

216217
```
218+
### Logging level
219+
To override the logging level when using `Twyn` as a 3rd party library, simply override it like:
220+
221+
```python
222+
logging.basicConfig(level=logging.DEBUG)
223+
logging.getLogger("twyn").setLevel(logging.DEBUG)
224+
```

src/twyn/base/constants.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
from enum import Enum
43
from typing import TYPE_CHECKING, Literal
54

65
from twyn import dependency_parser
@@ -30,10 +29,3 @@
3029
DEFAULT_TWYN_TOML_FILE = "twyn.toml"
3130
DEFAULT_TOP_PYPI_PACKAGES = "https://hugovk.github.io/top-pypi-packages/top-pypi-packages.min.json"
3231
DEFAULT_USE_CACHE = True
33-
34-
35-
class AvailableLoggingLevels(Enum):
36-
none = "NONE"
37-
debug = "DEBUG"
38-
info = "INFO"
39-
warning = "WARNING"

src/twyn/base/exceptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import click
55

6-
logger = logging.getLogger("twyn.errors")
6+
logger = logging.getLogger("twyn")
77

88

99
class TwynError(Exception):

src/twyn/cli.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
DEFAULT_PROJECT_TOML_FILE,
1212
DEPENDENCY_FILE_MAPPING,
1313
SELECTOR_METHOD_MAPPING,
14-
AvailableLoggingLevels,
1514
)
1615
from twyn.base.exceptions import CliError, TwynError
1716
from twyn.config.config_handler import ConfigHandler
@@ -101,11 +100,9 @@ def run(
101100
json: bool,
102101
) -> int:
103102
if vv:
104-
verbosity = AvailableLoggingLevels.debug
103+
logger.setLevel(logging.DEBUG)
105104
elif v:
106-
verbosity = AvailableLoggingLevels.info
107-
else:
108-
verbosity = AvailableLoggingLevels.none
105+
logger.setLevel(logging.INFO)
109106

110107
if dependency and dependency_file:
111108
raise click.UsageError(
@@ -121,9 +118,8 @@ def run(
121118
dependencies=set(dependency) or None,
122119
config_file=config,
123120
dependency_file=dependency_file,
124-
verbosity=verbosity,
125121
use_cache=not no_cache if no_cache is not None else no_cache,
126-
use_track=False if json else not no_track,
122+
show_progress_bar=False if json else not no_track,
127123
load_config_from_file=True,
128124
)
129125
except TwynError as e:

src/twyn/config/config_handler.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
DEFAULT_TWYN_TOML_FILE,
1414
DEFAULT_USE_CACHE,
1515
SELECTOR_METHOD_KEYS,
16-
AvailableLoggingLevels,
1716
)
1817
from twyn.config.exceptions import (
1918
AllowlistPackageAlreadyExistsError,
@@ -34,7 +33,6 @@ class TwynConfiguration:
3433

3534
dependency_file: Optional[str]
3635
selector_method: str
37-
logging_level: AvailableLoggingLevels
3836
allowlist: set[str]
3937
pypi_reference: str
4038
use_cache: bool
@@ -46,7 +44,6 @@ class ReadTwynConfiguration:
4644

4745
dependency_file: Optional[str] = None
4846
selector_method: Optional[str] = None
49-
logging_level: Optional[AvailableLoggingLevels] = None
5047
allowlist: set[str] = field(default_factory=set)
5148
pypi_reference: Optional[str] = None
5249
use_cache: Optional[bool] = None
@@ -62,7 +59,6 @@ def resolve_config(
6259
self,
6360
selector_method: Optional[str] = None,
6461
dependency_file: Optional[str] = None,
65-
verbosity: AvailableLoggingLevels = AvailableLoggingLevels.none,
6662
use_cache: Optional[bool] = None,
6763
) -> TwynConfiguration:
6864
"""Resolve the configuration for Twyn.
@@ -99,7 +95,6 @@ def resolve_config(
9995
return TwynConfiguration(
10096
dependency_file=dependency_file or read_config.dependency_file,
10197
selector_method=final_selector_method,
102-
logging_level=_get_logging_level(verbosity, read_config.logging_level),
10398
allowlist=read_config.allowlist,
10499
pypi_reference=read_config.pypi_reference or DEFAULT_TOP_PYPI_PACKAGES,
105100
use_cache=final_use_cache,
@@ -133,7 +128,6 @@ def _get_read_config(self, toml: TOMLDocument) -> ReadTwynConfiguration:
133128
return ReadTwynConfiguration(
134129
dependency_file=twyn_config_data.get("dependency_file"),
135130
selector_method=twyn_config_data.get("selector_method"),
136-
logging_level=twyn_config_data.get("logging_level"),
137131
allowlist=set(twyn_config_data.get("allowlist", set())),
138132
pypi_reference=twyn_config_data.get("pypi_reference"),
139133
use_cache=twyn_config_data.get("use_cache"),
@@ -179,20 +173,6 @@ def get_default_config_file_path() -> str:
179173
return DEFAULT_PROJECT_TOML_FILE
180174

181175

182-
def _get_logging_level(
183-
cli_verbosity: AvailableLoggingLevels,
184-
config_logging_level: Optional[str],
185-
) -> AvailableLoggingLevels:
186-
"""Return the appropriate logging level, considering that the one in config has less priority than the one passed directly."""
187-
if cli_verbosity is AvailableLoggingLevels.none:
188-
if config_logging_level:
189-
return AvailableLoggingLevels[config_logging_level.lower()]
190-
else:
191-
# default logging level
192-
return AvailableLoggingLevels.warning
193-
return cli_verbosity
194-
195-
196176
def _serialize_config(x: Any) -> Union[Any, str, list[Any]]:
197177
def _value_to_for_config(v: Any) -> Union[str, list[Any], Any]:
198178
if isinstance(v, Enum):

src/twyn/main.py

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from twyn.base.constants import (
77
SELECTOR_METHOD_MAPPING,
8-
AvailableLoggingLevels,
98
SelectorMethod,
109
)
1110
from twyn.base.utils import normalize_packages
@@ -22,45 +21,42 @@
2221
)
2322

2423
logger = logging.getLogger("twyn")
24+
logger.addHandler(logging.NullHandler())
2525

2626

2727
def check_dependencies(
2828
selector_method: Union[SelectorMethod, None] = None,
2929
config_file: Optional[str] = None,
3030
dependency_file: Optional[str] = None,
3131
dependencies: Optional[set[str]] = None,
32-
verbosity: AvailableLoggingLevels = AvailableLoggingLevels.none,
3332
use_cache: Optional[bool] = True,
34-
use_track: bool = False,
33+
show_progress_bar: bool = False,
3534
load_config_from_file: bool = False,
3635
) -> TyposquatCheckResultList:
3736
"""Check if dependencies could be typosquats."""
3837
config = get_config(
3938
load_config_from_file=load_config_from_file,
4039
config_file=config_file,
41-
verbosity=verbosity,
4240
selector_method=selector_method,
4341
dependency_file=dependency_file,
4442
use_cache=use_cache,
4543
)
4644

47-
_set_logging_level(config.logging_level)
48-
4945
cache_handler = CacheHandler() if config.use_cache else None
5046

5147
trusted_packages = TrustedPackages(
5248
names=TopPyPiReference(source=config.pypi_reference, cache_handler=cache_handler).get_packages(),
5349
algorithm=EditDistance(),
54-
selector=get_candidate_selector(config.selector_method),
50+
selector=_get_candidate_selector(config.selector_method),
5551
threshold_class=SimilarityThreshold,
5652
)
5753
normalized_allowlist_packages = normalize_packages(config.allowlist)
58-
dependencies = dependencies if dependencies else get_parsed_dependencies_from_file(config.dependency_file)
54+
dependencies = dependencies if dependencies else _get_parsed_dependencies_from_file(config.dependency_file)
5955
normalized_dependencies = normalize_packages(dependencies)
6056

6157
typos_list = TyposquatCheckResultList()
6258
dependencies_list = (
63-
track(normalized_dependencies, description="Processing...") if use_track else normalized_dependencies
59+
track(normalized_dependencies, description="Processing...") if show_progress_bar else normalized_dependencies
6460
)
6561
for dependency in dependencies_list:
6662
if dependency in normalized_allowlist_packages:
@@ -77,7 +73,6 @@ def check_dependencies(
7773
def get_config(
7874
load_config_from_file: bool,
7975
config_file: Optional[str],
80-
verbosity: AvailableLoggingLevels,
8176
selector_method: Union[SelectorMethod, None],
8277
dependency_file: Optional[str],
8378
use_cache: Optional[bool],
@@ -87,26 +82,20 @@ def get_config(
8782
else:
8883
config_file_handler = None
8984
return ConfigHandler(config_file_handler).resolve_config(
90-
verbosity=verbosity,
9185
selector_method=selector_method,
9286
dependency_file=dependency_file,
9387
use_cache=use_cache,
9488
)
9589

9690

97-
def _set_logging_level(logging_level: AvailableLoggingLevels) -> None:
98-
logger.setLevel(logging_level.value)
99-
logger.debug("Logging level: %s", logging_level.value)
100-
101-
102-
def get_candidate_selector(selector_method_name: str) -> AbstractSelector:
91+
def _get_candidate_selector(selector_method_name: str) -> AbstractSelector:
10392
logger.debug("Selector method received %s", selector_method_name)
10493
selector_method = SELECTOR_METHOD_MAPPING[selector_method_name]()
10594
logger.debug("Instantiated %s selector", selector_method)
10695
return selector_method
10796

10897

109-
def get_parsed_dependencies_from_file(dependency_file: Optional[str] = None) -> set[str]:
98+
def _get_parsed_dependencies_from_file(dependency_file: Optional[str] = None) -> set[str]:
11099
dependency_parser = DependencySelector(dependency_file).get_dependency_parser()
111100
dependencies = dependency_parser.parse()
112101
logger.debug("Successfully parsed local dependencies file.")

tests/config/test_config_handler.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
DEFAULT_SELECTOR_METHOD,
1212
DEFAULT_TOP_PYPI_PACKAGES,
1313
DEFAULT_TWYN_TOML_FILE,
14-
AvailableLoggingLevels,
1514
)
1615
from twyn.config.config_handler import ConfigHandler, ReadTwynConfiguration, TwynConfiguration
1716
from twyn.config.exceptions import (
@@ -40,7 +39,6 @@ def test_no_enforce_file_on_non_existent_file(self, mock_is_file: Mock) -> None:
4039
assert config == TwynConfiguration(
4140
dependency_file=None,
4241
selector_method="all",
43-
logging_level=AvailableLoggingLevels.warning,
4442
allowlist=set(),
4543
pypi_reference=DEFAULT_TOP_PYPI_PACKAGES,
4644
use_cache=True,
@@ -54,7 +52,6 @@ def test_read_config_values(self, pyproject_toml_file: Path) -> None:
5452
config = ConfigHandler(file_handler=FileHandler(pyproject_toml_file)).resolve_config()
5553
assert config.dependency_file == "my_file.txt"
5654
assert config.selector_method == "all"
57-
assert config.logging_level == AvailableLoggingLevels.debug
5855
assert config.allowlist == {"boto4", "boto2"}
5956
assert config.use_cache is False
6057

@@ -66,7 +63,6 @@ def test_get_twyn_data_from_file(self, pyproject_toml_file: Path) -> None:
6663
assert twyn_data == ReadTwynConfiguration(
6764
dependency_file="my_file.txt",
6865
selector_method="all",
69-
logging_level="debug",
7066
allowlist={"boto4", "boto2"},
7167
pypi_reference=None,
7268
use_cache=False,
@@ -105,7 +101,6 @@ def test_write_toml(self, pyproject_toml_file: Path) -> None:
105101
"twyn": {
106102
"dependency_file": "my_file.txt",
107103
"selector_method": "all",
108-
"logging_level": "debug",
109104
"allowlist": {},
110105
"pypi_reference": DEFAULT_TOP_PYPI_PACKAGES,
111106
"use_cache": False,
@@ -146,7 +141,6 @@ def test_no_load_config_from_cache(self, pyproject_toml_file: Path) -> None:
146141

147142
assert config.allowlist == set()
148143
assert config.dependency_file is None
149-
assert config.logging_level == AvailableLoggingLevels.warning
150144
assert config.use_cache is True
151145
assert config.selector_method == DEFAULT_SELECTOR_METHOD
152146
assert config.pypi_reference == DEFAULT_TOP_PYPI_PACKAGES

tests/main/test_cli.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import pytest
55
from click.testing import CliRunner
66
from twyn import cli
7-
from twyn.base.constants import AvailableLoggingLevels
87
from twyn.base.exceptions import TwynError
98
from twyn.trusted_packages.cache_handler import CacheEntry, CacheHandler
109
from twyn.trusted_packages.trusted_packages import TyposquatCheckResult, TyposquatCheckResultList
@@ -88,9 +87,8 @@ def test_click_arguments_dependency_file(self, mock_check_dependencies: Mock) ->
8887
dependency_file="requirements.txt",
8988
dependencies=None,
9089
selector_method="first-letter",
91-
verbosity=AvailableLoggingLevels.debug,
9290
use_cache=None,
93-
use_track=True,
91+
show_progress_bar=True,
9492
load_config_from_file=True,
9593
)
9694
]
@@ -112,9 +110,8 @@ def test_click_arguments_dependency_file_in_different_path(self, mock_check_depe
112110
dependency_file="/path/requirements.txt",
113111
dependencies=None,
114112
selector_method=None,
115-
verbosity=AvailableLoggingLevels.none,
116113
use_cache=None,
117-
use_track=True,
114+
show_progress_bar=True,
118115
load_config_from_file=True,
119116
)
120117
]
@@ -135,9 +132,8 @@ def test_click_arguments_single_dependency_cli(self, mock_check_dependencies: Mo
135132
dependency_file=None,
136133
dependencies={"reqests"},
137134
selector_method=None,
138-
verbosity=AvailableLoggingLevels.none,
139135
use_cache=None,
140-
use_track=True,
136+
show_progress_bar=True,
141137
load_config_from_file=True,
142138
)
143139
]
@@ -170,9 +166,8 @@ def test_click_arguments_multiple_dependencies(self, mock_check_dependencies: Mo
170166
dependency_file=None,
171167
dependencies={"reqests", "reqeusts"},
172168
selector_method=None,
173-
verbosity=AvailableLoggingLevels.none,
174169
use_cache=None,
175-
use_track=True,
170+
show_progress_bar=True,
176171
load_config_from_file=True,
177172
)
178173
]
@@ -188,9 +183,8 @@ def test_click_arguments_default(self, mock_check_dependencies: Mock) -> None:
188183
dependency_file=None,
189184
selector_method=None,
190185
dependencies=None,
191-
verbosity=AvailableLoggingLevels.none,
192186
use_cache=None,
193-
use_track=True,
187+
show_progress_bar=True,
194188
load_config_from_file=True,
195189
)
196190
]

0 commit comments

Comments
 (0)