lapsed 2.7.0__tar.gz → 2.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lapsed-2.7.0 → lapsed-2.7.2}/.gitignore +0 -3
- {lapsed-2.7.0 → lapsed-2.7.2}/PKG-INFO +2 -8
- {lapsed-2.7.0 → lapsed-2.7.2}/README.md +1 -7
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/find_python_filenames.py +5 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/parse_tach_config.py +41 -3
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/visitor/dead_code_visitor.py +1 -1
- {lapsed-2.7.0 → lapsed-2.7.2}/pyproject.toml +1 -1
- {lapsed-2.7.0 → lapsed-2.7.2}/LICENSE +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/__init__.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/__init__.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/find_unused_names.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/fix_or_show_unused_code.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/get_unused_names_error_message.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/merge_overlaping_file_parts.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/parse_abstract_syntax_tree.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/parse_arguments.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/actions/remove_file_parts_from_content.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/cli.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/constants.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/data_types.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/utils/__init__.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/utils/add_colors_to_diff.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/utils/base_test_case.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/utils/fix_indent.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/utils/flatten_lists.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/utils/nested_scopes.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/utils/print_ast.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/visitor/__init__.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/visitor/code_item.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/visitor/ignore.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/visitor/lines.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/visitor/noqa.py +0 -0
- {lapsed-2.7.0 → lapsed-2.7.2}/deadcode/visitor/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lapsed
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.2
|
|
4
4
|
Summary: Find and remove dead code.
|
|
5
5
|
Project-URL: homepage, https://github.com/albertas/deadcode
|
|
6
6
|
Project-URL: documentation, https://deadcode.readthedocs.io/
|
|
@@ -94,7 +94,7 @@ Create a `.pre-commit-config.yaml` file in the root of your project directory, i
|
|
|
94
94
|
# See https://pre-commit.com/hooks.html for more hooks
|
|
95
95
|
repos:
|
|
96
96
|
- repo: https://github.com/albertas/deadcode
|
|
97
|
-
rev: 2.
|
|
97
|
+
rev: 2.6.0
|
|
98
98
|
hooks:
|
|
99
99
|
- id: deadcode
|
|
100
100
|
```
|
|
@@ -227,12 +227,6 @@ code base is implemented in.
|
|
|
227
227
|
- [ ] Investigate ways of extracting and backporting Python3.10+ `ast` implementation to lower Python versions.
|
|
228
228
|
|
|
229
229
|
## Release notes
|
|
230
|
-
- v2.7.0:
|
|
231
|
-
- Treat `pytest_*` functions defined in `conftest.py` (e.g. `pytest_configure`,
|
|
232
|
-
`pytest_collection_modifyitems`, `pytest_addoption`) as pytest hooks, which pytest
|
|
233
|
-
calls automatically by name, and never report them as unused.
|
|
234
|
-
- Treat methods decorated with `@typing.override` (or `@typing_extensions.override`)
|
|
235
|
-
as used, since they are called via the base class they override, not by their own name.
|
|
236
230
|
- v2.6.0:
|
|
237
231
|
- Add `--ignore-class-attributes` option to not report unused attributes assigned directly
|
|
238
232
|
in a class body (e.g. `THING = "blah"` inside `class Foo:`), since such attributes may
|
|
@@ -66,7 +66,7 @@ Create a `.pre-commit-config.yaml` file in the root of your project directory, i
|
|
|
66
66
|
# See https://pre-commit.com/hooks.html for more hooks
|
|
67
67
|
repos:
|
|
68
68
|
- repo: https://github.com/albertas/deadcode
|
|
69
|
-
rev: 2.
|
|
69
|
+
rev: 2.6.0
|
|
70
70
|
hooks:
|
|
71
71
|
- id: deadcode
|
|
72
72
|
```
|
|
@@ -199,12 +199,6 @@ code base is implemented in.
|
|
|
199
199
|
- [ ] Investigate ways of extracting and backporting Python3.10+ `ast` implementation to lower Python versions.
|
|
200
200
|
|
|
201
201
|
## Release notes
|
|
202
|
-
- v2.7.0:
|
|
203
|
-
- Treat `pytest_*` functions defined in `conftest.py` (e.g. `pytest_configure`,
|
|
204
|
-
`pytest_collection_modifyitems`, `pytest_addoption`) as pytest hooks, which pytest
|
|
205
|
-
calls automatically by name, and never report them as unused.
|
|
206
|
-
- Treat methods decorated with `@typing.override` (or `@typing_extensions.override`)
|
|
207
|
-
as used, since they are called via the base class they override, not by their own name.
|
|
208
202
|
- v2.6.0:
|
|
209
203
|
- Add `--ignore-class-attributes` option to not report unused attributes assigned directly
|
|
210
204
|
in a class body (e.g. `THING = "blah"` inside `class Foo:`), since such attributes may
|
|
@@ -22,6 +22,11 @@ def find_python_filenames(args: Args) -> List[str]:
|
|
|
22
22
|
logger.info(f'Ignoring: {path}')
|
|
23
23
|
continue
|
|
24
24
|
|
|
25
|
+
if tach_index.is_outside_source_roots(path):
|
|
26
|
+
if args.verbose:
|
|
27
|
+
logger.info(f'Ignoring (outside tach source roots): {path}')
|
|
28
|
+
continue
|
|
29
|
+
|
|
25
30
|
if path.is_file() and path.suffix == '.py' and tach_index.is_unchecked(path):
|
|
26
31
|
if args.verbose:
|
|
27
32
|
logger.info(f'Ignoring (unchecked tach module): {path}')
|
|
@@ -28,6 +28,7 @@ class TachModule:
|
|
|
28
28
|
@dataclass
|
|
29
29
|
class TachConfig:
|
|
30
30
|
source_roots: List[Path]
|
|
31
|
+
project_root: Optional[Path] = None
|
|
31
32
|
modules: List[TachModule] = field(default_factory=list)
|
|
32
33
|
interfaces: List[TachInterface] = field(default_factory=list)
|
|
33
34
|
|
|
@@ -38,6 +39,31 @@ class TachIndex:
|
|
|
38
39
|
def __init__(self, configs: List[TachConfig]) -> None:
|
|
39
40
|
self._configs = configs
|
|
40
41
|
|
|
42
|
+
def is_outside_source_roots(self, path: Path) -> bool:
|
|
43
|
+
"""True if `path` belongs to a tach project (is its project root or nested under it)
|
|
44
|
+
|
|
45
|
+
but falls outside every one of that project's `source_roots`, and outside them for
|
|
46
|
+
every other tach project it might also belong to. Paths unrelated to any tach project
|
|
47
|
+
(e.g. an explicitly provided directory that lives elsewhere entirely) are unaffected.
|
|
48
|
+
"""
|
|
49
|
+
path = path.resolve()
|
|
50
|
+
|
|
51
|
+
related_to_any_config = False
|
|
52
|
+
for config in self._configs:
|
|
53
|
+
if config.project_root is None:
|
|
54
|
+
continue
|
|
55
|
+
relation = _relation_to_project_root(path, config.project_root)
|
|
56
|
+
if relation == 'unrelated':
|
|
57
|
+
continue
|
|
58
|
+
related_to_any_config = True
|
|
59
|
+
if relation == 'ancestor':
|
|
60
|
+
# `path` is still above the project root, so it must be walked into to reach it.
|
|
61
|
+
return False
|
|
62
|
+
if any(_within_or_towards_source_root(path, source_root) for source_root in config.source_roots):
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
return related_to_any_config
|
|
66
|
+
|
|
41
67
|
def is_unchecked(self, file: Path) -> bool:
|
|
42
68
|
for config in self._configs:
|
|
43
69
|
module_path = _dotted_module_path(file, config.source_roots)
|
|
@@ -54,7 +80,7 @@ class TachIndex:
|
|
|
54
80
|
if module_path is None:
|
|
55
81
|
continue
|
|
56
82
|
for interface in config.interfaces:
|
|
57
|
-
adopts_interface = interface.from_patterns is None or
|
|
83
|
+
adopts_interface = interface.from_patterns is None or _match_any_dotted_glob(
|
|
58
84
|
interface.from_patterns, module_path
|
|
59
85
|
)
|
|
60
86
|
if adopts_interface and _match_any_regex(interface.expose, name):
|
|
@@ -77,11 +103,11 @@ def _parse_tach_toml(path: Path) -> TachConfig:
|
|
|
77
103
|
with open(path, 'rb') as f:
|
|
78
104
|
data = tomllib.load(f)
|
|
79
105
|
|
|
80
|
-
project_root = path.parent
|
|
106
|
+
project_root = path.parent.resolve()
|
|
81
107
|
raw_source_roots = data.get('source_roots') or ['.']
|
|
82
108
|
source_roots = [(project_root / root).resolve() for root in raw_source_roots]
|
|
83
109
|
|
|
84
|
-
config = TachConfig(source_roots=source_roots)
|
|
110
|
+
config = TachConfig(source_roots=source_roots, project_root=project_root)
|
|
85
111
|
config.modules.extend(_extract_modules(data))
|
|
86
112
|
config.interfaces.extend(_extract_interfaces(data))
|
|
87
113
|
|
|
@@ -180,6 +206,18 @@ def _dotted_module_path(file: Path, source_roots: List[Path]) -> Optional[str]:
|
|
|
180
206
|
return '.'.join(parts) if parts else None
|
|
181
207
|
|
|
182
208
|
|
|
209
|
+
def _relation_to_project_root(path: Path, project_root: Path) -> str:
|
|
210
|
+
if path == project_root or project_root in path.parents:
|
|
211
|
+
return 'inside'
|
|
212
|
+
if path in project_root.parents:
|
|
213
|
+
return 'ancestor'
|
|
214
|
+
return 'unrelated'
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def _within_or_towards_source_root(path: Path, source_root: Path) -> bool:
|
|
218
|
+
return path == source_root or source_root in path.parents or path in source_root.parents
|
|
219
|
+
|
|
220
|
+
|
|
183
221
|
def _dotted_glob_to_regex(pattern: str) -> re.Pattern[str]:
|
|
184
222
|
regex_segments = [
|
|
185
223
|
'.*' if segment == '**' else re.escape(segment).replace(r'\*', '[^.]*') for segment in pattern.split('.')
|
|
@@ -287,7 +287,7 @@ class DeadCodeVisitor(ast.NodeVisitor):
|
|
|
287
287
|
|
|
288
288
|
self.scopes.add(code_item)
|
|
289
289
|
|
|
290
|
-
if ignored(
|
|
290
|
+
if ignored(last_node.lineno, type_=type_):
|
|
291
291
|
self._log(f'Ignoring {type_} "{name}"')
|
|
292
292
|
else:
|
|
293
293
|
collection.append(code_item)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|