ansible-core 2.20.0b1__py3-none-any.whl → 2.20.0rc1__py3-none-any.whl
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.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/cli/doc.py +3 -1
- ansible/collections/list.py +4 -2
- ansible/executor/process/worker.py +17 -11
- ansible/executor/task_queue_manager.py +43 -1
- ansible/galaxy/collection/__init__.py +7 -4
- ansible/galaxy/dependency_resolution/__init__.py +10 -9
- ansible/galaxy/dependency_resolution/dataclasses.py +86 -60
- ansible/galaxy/dependency_resolution/providers.py +53 -132
- ansible/galaxy/dependency_resolution/versioning.py +2 -4
- ansible/module_utils/ansible_release.py +1 -1
- ansible/module_utils/six/__init__.py +8 -0
- ansible/modules/known_hosts.py +7 -1
- ansible/parsing/dataloader.py +2 -2
- ansible/playbook/block.py +1 -3
- ansible/playbook/helpers.py +15 -13
- ansible/playbook/play.py +2 -12
- ansible/plugins/action/fetch.py +1 -1
- ansible/plugins/test/falsy.yml +1 -1
- ansible/plugins/test/truthy.yml +1 -1
- ansible/release.py +1 -1
- ansible/vars/manager.py +1 -2
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/METADATA +2 -2
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/RECORD +50 -50
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/requirements/ansible-test.txt +1 -1
- ansible_test/_data/requirements/ansible.txt +1 -1
- ansible_test/_data/requirements/sanity.ansible-doc.txt +2 -2
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.import.txt +1 -1
- ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +5 -5
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +1 -1
- ansible_test/_data/requirements/sanity.validate-modules.txt +2 -2
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_internal/commands/sanity/pylint.py +11 -0
- ansible_test/_internal/coverage_util.py +1 -1
- ansible_test/_internal/python_requirements.py +1 -1
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +48 -45
- ansible_test/_util/controller/sanity/pylint/plugins/string_format.py +9 -7
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +25 -14
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/WHEEL +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/licenses/licenses/BSD-3-Clause.txt +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.20.0b1.dist-info → ansible_core-2.20.0rc1.dist-info}/top_level.txt +0 -0
|
@@ -11,9 +11,11 @@ import functools
|
|
|
11
11
|
import pathlib
|
|
12
12
|
import re
|
|
13
13
|
|
|
14
|
-
import astroid
|
|
15
|
-
import astroid.
|
|
14
|
+
import astroid.bases
|
|
15
|
+
import astroid.exceptions
|
|
16
|
+
import astroid.nodes
|
|
16
17
|
import astroid.typing
|
|
18
|
+
import astroid.util
|
|
17
19
|
|
|
18
20
|
import pylint.lint
|
|
19
21
|
import pylint.checkers
|
|
@@ -42,7 +44,7 @@ class DeprecationCallArgs:
|
|
|
42
44
|
|
|
43
45
|
def all_args_dynamic(self) -> bool:
|
|
44
46
|
"""True if all args are dynamic or None, otherwise False."""
|
|
45
|
-
return all(arg is None or isinstance(arg, astroid.NodeNG) for arg in dataclasses.asdict(self).values())
|
|
47
|
+
return all(arg is None or isinstance(arg, astroid.nodes.NodeNG) for arg in dataclasses.asdict(self).values())
|
|
46
48
|
|
|
47
49
|
|
|
48
50
|
class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
@@ -177,7 +179,7 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
177
179
|
def __init__(self, *args, **kwargs) -> None:
|
|
178
180
|
super().__init__(*args, **kwargs)
|
|
179
181
|
|
|
180
|
-
self.module_cache: dict[str, astroid.Module] = {}
|
|
182
|
+
self.module_cache: dict[str, astroid.nodes.Module] = {}
|
|
181
183
|
|
|
182
184
|
@functools.cached_property
|
|
183
185
|
def collection_name(self) -> str | None:
|
|
@@ -226,7 +228,7 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
226
228
|
return None
|
|
227
229
|
|
|
228
230
|
@pylint.checkers.utils.only_required_for_messages(*(msgs.keys()))
|
|
229
|
-
def visit_call(self, node: astroid.Call) -> None:
|
|
231
|
+
def visit_call(self, node: astroid.nodes.Call) -> None:
|
|
230
232
|
"""Visit a call node."""
|
|
231
233
|
if inferred := self.infer(node.func):
|
|
232
234
|
name = self.get_fully_qualified_name(inferred)
|
|
@@ -234,50 +236,50 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
234
236
|
if args := self.DEPRECATION_FUNCTIONS.get(name):
|
|
235
237
|
self.check_call(node, name, args)
|
|
236
238
|
|
|
237
|
-
def infer(self, node: astroid.NodeNG) -> astroid.NodeNG | None:
|
|
239
|
+
def infer(self, node: astroid.nodes.NodeNG) -> astroid.nodes.NodeNG | None:
|
|
238
240
|
"""Return the inferred node from the given node, or `None` if it cannot be unambiguously inferred."""
|
|
239
241
|
names: list[str] = []
|
|
240
|
-
target: astroid.NodeNG | None = node
|
|
242
|
+
target: astroid.nodes.NodeNG | None = node
|
|
241
243
|
inferred: astroid.typing.InferenceResult | None = None
|
|
242
244
|
|
|
243
245
|
while target:
|
|
244
246
|
if inferred := astroid.util.safe_infer(target):
|
|
245
247
|
break
|
|
246
248
|
|
|
247
|
-
if isinstance(target, astroid.Call):
|
|
249
|
+
if isinstance(target, astroid.nodes.Call):
|
|
248
250
|
inferred = self.infer(target.func)
|
|
249
251
|
break
|
|
250
252
|
|
|
251
|
-
if isinstance(target, astroid.FunctionDef):
|
|
253
|
+
if isinstance(target, astroid.nodes.FunctionDef):
|
|
252
254
|
inferred = target
|
|
253
255
|
break
|
|
254
256
|
|
|
255
|
-
if isinstance(target, astroid.Name):
|
|
257
|
+
if isinstance(target, astroid.nodes.Name):
|
|
256
258
|
target = self.infer_name(target)
|
|
257
|
-
elif isinstance(target, astroid.AssignName) and isinstance(target.parent, astroid.Assign):
|
|
259
|
+
elif isinstance(target, astroid.nodes.AssignName) and isinstance(target.parent, astroid.nodes.Assign):
|
|
258
260
|
target = target.parent.value
|
|
259
|
-
elif isinstance(target, astroid.Attribute):
|
|
261
|
+
elif isinstance(target, astroid.nodes.Attribute):
|
|
260
262
|
names.append(target.attrname)
|
|
261
263
|
target = target.expr
|
|
262
264
|
else:
|
|
263
265
|
break
|
|
264
266
|
|
|
265
267
|
for name in reversed(names):
|
|
266
|
-
if isinstance(inferred, astroid.Instance):
|
|
268
|
+
if isinstance(inferred, astroid.bases.Instance):
|
|
267
269
|
try:
|
|
268
270
|
attr = next(iter(inferred.getattr(name)), None)
|
|
269
|
-
except astroid.AttributeInferenceError:
|
|
271
|
+
except astroid.exceptions.AttributeInferenceError:
|
|
270
272
|
break
|
|
271
273
|
|
|
272
|
-
if isinstance(attr, astroid.AssignAttr):
|
|
274
|
+
if isinstance(attr, astroid.nodes.AssignAttr):
|
|
273
275
|
inferred = self.get_ansible_module(attr)
|
|
274
276
|
continue
|
|
275
277
|
|
|
276
|
-
if isinstance(attr, astroid.FunctionDef):
|
|
278
|
+
if isinstance(attr, astroid.nodes.FunctionDef):
|
|
277
279
|
inferred = attr
|
|
278
280
|
continue
|
|
279
281
|
|
|
280
|
-
if not isinstance(inferred, (astroid.Module, astroid.ClassDef)):
|
|
282
|
+
if not isinstance(inferred, (astroid.nodes.Module, astroid.nodes.ClassDef)):
|
|
281
283
|
inferred = None
|
|
282
284
|
break
|
|
283
285
|
|
|
@@ -288,15 +290,15 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
288
290
|
else:
|
|
289
291
|
inferred = self.infer(inferred)
|
|
290
292
|
|
|
291
|
-
if isinstance(inferred, astroid.FunctionDef) and isinstance(inferred.parent, astroid.ClassDef):
|
|
292
|
-
inferred = astroid.BoundMethod(inferred, inferred.parent)
|
|
293
|
+
if isinstance(inferred, astroid.nodes.FunctionDef) and isinstance(inferred.parent, astroid.nodes.ClassDef):
|
|
294
|
+
inferred = astroid.bases.BoundMethod(inferred, inferred.parent)
|
|
293
295
|
|
|
294
296
|
return inferred
|
|
295
297
|
|
|
296
|
-
def infer_name(self, node: astroid.Name) -> astroid.NodeNG | None:
|
|
298
|
+
def infer_name(self, node: astroid.nodes.Name) -> astroid.nodes.NodeNG | None:
|
|
297
299
|
"""Infer the node referenced by the given name, or `None` if it cannot be unambiguously inferred."""
|
|
298
300
|
scope = node.scope()
|
|
299
|
-
inferred: astroid.NodeNG | None = None
|
|
301
|
+
inferred: astroid.nodes.NodeNG | None = None
|
|
300
302
|
name = node.name
|
|
301
303
|
|
|
302
304
|
while scope:
|
|
@@ -306,12 +308,12 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
306
308
|
scope = scope.parent.scope() if scope.parent else None
|
|
307
309
|
continue
|
|
308
310
|
|
|
309
|
-
if isinstance(assignment, astroid.AssignName) and isinstance(assignment.parent, astroid.Assign):
|
|
311
|
+
if isinstance(assignment, astroid.nodes.AssignName) and isinstance(assignment.parent, astroid.nodes.Assign):
|
|
310
312
|
inferred = assignment.parent.value
|
|
311
313
|
elif (
|
|
312
|
-
isinstance(scope, astroid.FunctionDef)
|
|
313
|
-
and isinstance(assignment, astroid.AssignName)
|
|
314
|
-
and isinstance(assignment.parent, astroid.Arguments)
|
|
314
|
+
isinstance(scope, astroid.nodes.FunctionDef)
|
|
315
|
+
and isinstance(assignment, astroid.nodes.AssignName)
|
|
316
|
+
and isinstance(assignment.parent, astroid.nodes.Arguments)
|
|
315
317
|
and assignment.parent.annotations
|
|
316
318
|
):
|
|
317
319
|
idx, _node = assignment.parent.find_argname(name)
|
|
@@ -322,12 +324,12 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
322
324
|
except IndexError:
|
|
323
325
|
pass
|
|
324
326
|
else:
|
|
325
|
-
if isinstance(annotation, astroid.Name):
|
|
327
|
+
if isinstance(annotation, astroid.nodes.Name):
|
|
326
328
|
name = annotation.name
|
|
327
329
|
continue
|
|
328
|
-
elif isinstance(assignment, astroid.ClassDef):
|
|
330
|
+
elif isinstance(assignment, astroid.nodes.ClassDef):
|
|
329
331
|
inferred = assignment
|
|
330
|
-
elif isinstance(assignment, astroid.ImportFrom):
|
|
332
|
+
elif isinstance(assignment, astroid.nodes.ImportFrom):
|
|
331
333
|
if module := self.get_module(assignment):
|
|
332
334
|
name = assignment.real_name(name)
|
|
333
335
|
scope = module.scope()
|
|
@@ -337,7 +339,7 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
337
339
|
|
|
338
340
|
return inferred
|
|
339
341
|
|
|
340
|
-
def get_module(self, node: astroid.ImportFrom) -> astroid.Module | None:
|
|
342
|
+
def get_module(self, node: astroid.nodes.ImportFrom) -> astroid.nodes.Module | None:
|
|
341
343
|
"""Import the requested module if possible and cache the result."""
|
|
342
344
|
module_name = pylint.checkers.utils.get_import_name(node, node.modname)
|
|
343
345
|
|
|
@@ -357,21 +359,21 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
357
359
|
return module
|
|
358
360
|
|
|
359
361
|
@staticmethod
|
|
360
|
-
def get_fully_qualified_name(node: astroid.NodeNG) -> str | None:
|
|
362
|
+
def get_fully_qualified_name(node: astroid.nodes.NodeNG) -> str | None:
|
|
361
363
|
"""Return the fully qualified name of the given inferred node."""
|
|
362
364
|
parent = node.parent
|
|
363
365
|
parts: tuple[str, ...] | None
|
|
364
366
|
|
|
365
|
-
if isinstance(node, astroid.FunctionDef) and isinstance(parent, astroid.Module):
|
|
367
|
+
if isinstance(node, astroid.nodes.FunctionDef) and isinstance(parent, astroid.nodes.Module):
|
|
366
368
|
parts = (parent.name, node.name)
|
|
367
|
-
elif isinstance(node, astroid.BoundMethod) and isinstance(parent, astroid.ClassDef) and isinstance(parent.parent, astroid.Module):
|
|
369
|
+
elif isinstance(node, astroid.bases.BoundMethod) and isinstance(parent, astroid.nodes.ClassDef) and isinstance(parent.parent, astroid.nodes.Module):
|
|
368
370
|
parts = (parent.parent.name, parent.name, node.name)
|
|
369
371
|
else:
|
|
370
372
|
parts = None
|
|
371
373
|
|
|
372
374
|
return '.'.join(parts) if parts else None
|
|
373
375
|
|
|
374
|
-
def check_call(self, node: astroid.Call, name: str, args: tuple[str, ...]) -> None:
|
|
376
|
+
def check_call(self, node: astroid.nodes.Call, name: str, args: tuple[str, ...]) -> None:
|
|
375
377
|
"""Check the given deprecation call node for valid arguments."""
|
|
376
378
|
call_args = self.get_deprecation_call_args(node, args)
|
|
377
379
|
|
|
@@ -400,7 +402,7 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
400
402
|
self.check_version(node, name, call_args)
|
|
401
403
|
|
|
402
404
|
@staticmethod
|
|
403
|
-
def get_deprecation_call_args(node: astroid.Call, args: tuple[str, ...]) -> DeprecationCallArgs:
|
|
405
|
+
def get_deprecation_call_args(node: astroid.nodes.Call, args: tuple[str, ...]) -> DeprecationCallArgs:
|
|
404
406
|
"""Get the deprecation call arguments from the given node."""
|
|
405
407
|
fields: dict[str, object] = {}
|
|
406
408
|
|
|
@@ -413,12 +415,12 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
413
415
|
fields[keyword.arg] = keyword.value
|
|
414
416
|
|
|
415
417
|
for key, value in fields.items():
|
|
416
|
-
if isinstance(value, astroid.Const):
|
|
418
|
+
if isinstance(value, astroid.nodes.Const):
|
|
417
419
|
fields[key] = value.value
|
|
418
420
|
|
|
419
421
|
return DeprecationCallArgs(**fields)
|
|
420
422
|
|
|
421
|
-
def check_collection_name(self, node: astroid.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
423
|
+
def check_collection_name(self, node: astroid.nodes.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
422
424
|
"""Check the collection name provided to the given call node."""
|
|
423
425
|
deprecator_requirement = self.is_deprecator_required()
|
|
424
426
|
|
|
@@ -459,14 +461,14 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
459
461
|
if args.collection_name and args.collection_name != expected_collection_name:
|
|
460
462
|
self.add_message('wrong-collection-deprecated', node=node, args=(args.collection_name, name))
|
|
461
463
|
|
|
462
|
-
def check_version(self, node: astroid.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
464
|
+
def check_version(self, node: astroid.nodes.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
463
465
|
"""Check the version provided to the given call node."""
|
|
464
466
|
if self.collection_name:
|
|
465
467
|
self.check_collection_version(node, name, args)
|
|
466
468
|
else:
|
|
467
469
|
self.check_core_version(node, name, args)
|
|
468
470
|
|
|
469
|
-
def check_core_version(self, node: astroid.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
471
|
+
def check_core_version(self, node: astroid.nodes.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
470
472
|
"""Check the core version provided to the given call node."""
|
|
471
473
|
try:
|
|
472
474
|
if not isinstance(args.version, str) or not args.version:
|
|
@@ -480,7 +482,7 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
480
482
|
if self.ANSIBLE_VERSION >= strict_version:
|
|
481
483
|
self.add_message('ansible-deprecated-version', node=node, args=(args.version, name))
|
|
482
484
|
|
|
483
|
-
def check_collection_version(self, node: astroid.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
485
|
+
def check_collection_version(self, node: astroid.nodes.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
484
486
|
"""Check the collection version provided to the given call node."""
|
|
485
487
|
try:
|
|
486
488
|
if not isinstance(args.version, str) or not args.version:
|
|
@@ -497,7 +499,7 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
497
499
|
if semantic_version.major != 0 and (semantic_version.minor != 0 or semantic_version.patch != 0):
|
|
498
500
|
self.add_message('removal-version-must-be-major', node=node, args=(args.version,))
|
|
499
501
|
|
|
500
|
-
def check_date(self, node: astroid.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
502
|
+
def check_date(self, node: astroid.nodes.Call, name: str, args: DeprecationCallArgs) -> None:
|
|
501
503
|
"""Check the date provided to the given call node."""
|
|
502
504
|
try:
|
|
503
505
|
date_parsed = self.parse_isodate(args.date)
|
|
@@ -515,18 +517,19 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
|
515
517
|
|
|
516
518
|
raise TypeError(type(value))
|
|
517
519
|
|
|
518
|
-
def get_ansible_module(self, node: astroid.AssignAttr) -> astroid.Instance | None:
|
|
520
|
+
def get_ansible_module(self, node: astroid.nodes.AssignAttr) -> astroid.bases.Instance | None:
|
|
519
521
|
"""Infer an AnsibleModule instance node from the given assignment."""
|
|
520
|
-
if isinstance(node.parent, astroid.Assign) and isinstance(node.parent.type_annotation, astroid.Name):
|
|
522
|
+
if isinstance(node.parent, astroid.nodes.Assign) and isinstance(node.parent.type_annotation, astroid.nodes.Name):
|
|
521
523
|
inferred = self.infer_name(node.parent.type_annotation)
|
|
522
|
-
elif isinstance(node.parent, astroid.Assign) and isinstance(node.parent.parent, astroid.FunctionDef) and
|
|
524
|
+
elif (isinstance(node.parent, astroid.nodes.Assign) and isinstance(node.parent.parent, astroid.nodes.FunctionDef) and
|
|
525
|
+
isinstance(node.parent.value, astroid.nodes.Name)):
|
|
523
526
|
inferred = self.infer_name(node.parent.value)
|
|
524
|
-
elif isinstance(node.parent, astroid.AnnAssign) and isinstance(node.parent.annotation, astroid.Name):
|
|
527
|
+
elif isinstance(node.parent, astroid.nodes.AnnAssign) and isinstance(node.parent.annotation, astroid.nodes.Name):
|
|
525
528
|
inferred = self.infer_name(node.parent.annotation)
|
|
526
529
|
else:
|
|
527
530
|
inferred = None
|
|
528
531
|
|
|
529
|
-
if isinstance(inferred, astroid.ClassDef) and inferred.name == 'AnsibleModule':
|
|
532
|
+
if isinstance(inferred, astroid.nodes.ClassDef) and inferred.name == 'AnsibleModule':
|
|
530
533
|
return inferred.instantiate_class()
|
|
531
534
|
|
|
532
535
|
return None
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
# -*- coding: utf-8 -*-
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
import astroid
|
|
8
|
+
import astroid.bases
|
|
9
|
+
import astroid.exceptions
|
|
10
|
+
import astroid.nodes
|
|
9
11
|
|
|
10
12
|
try:
|
|
11
13
|
from pylint.checkers.utils import check_messages
|
|
@@ -39,22 +41,22 @@ class AnsibleStringFormatChecker(BaseChecker):
|
|
|
39
41
|
def visit_call(self, node):
|
|
40
42
|
"""Visit a call node."""
|
|
41
43
|
func = utils.safe_infer(node.func)
|
|
42
|
-
if (isinstance(func, astroid.BoundMethod)
|
|
43
|
-
and isinstance(func.bound, astroid.Instance)
|
|
44
|
+
if (isinstance(func, astroid.bases.BoundMethod)
|
|
45
|
+
and isinstance(func.bound, astroid.bases.Instance)
|
|
44
46
|
and func.bound.name in ('str', 'unicode', 'bytes')):
|
|
45
47
|
if func.name == 'format':
|
|
46
48
|
self._check_new_format(node, func)
|
|
47
49
|
|
|
48
50
|
def _check_new_format(self, node, func):
|
|
49
51
|
""" Check the new string formatting """
|
|
50
|
-
if (isinstance(node.func, astroid.Attribute)
|
|
51
|
-
and not isinstance(node.func.expr, astroid.Const)):
|
|
52
|
+
if (isinstance(node.func, astroid.nodes.Attribute)
|
|
53
|
+
and not isinstance(node.func.expr, astroid.nodes.Const)):
|
|
52
54
|
return
|
|
53
55
|
try:
|
|
54
56
|
strnode = next(func.bound.infer())
|
|
55
|
-
except astroid.InferenceError:
|
|
57
|
+
except astroid.exceptions.InferenceError:
|
|
56
58
|
return
|
|
57
|
-
if not isinstance(strnode, astroid.Const):
|
|
59
|
+
if not isinstance(strnode, astroid.nodes.Const):
|
|
58
60
|
return
|
|
59
61
|
|
|
60
62
|
if isinstance(strnode.value, bytes):
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import functools
|
|
5
6
|
import os
|
|
6
7
|
import typing as t
|
|
7
8
|
|
|
8
|
-
import astroid
|
|
9
|
+
import astroid.exceptions
|
|
10
|
+
import astroid.nodes
|
|
9
11
|
|
|
10
12
|
from pylint.checkers import BaseChecker
|
|
11
13
|
|
|
@@ -108,10 +110,6 @@ class AnsibleUnwantedChecker(BaseChecker):
|
|
|
108
110
|
'Iterator',
|
|
109
111
|
)
|
|
110
112
|
),
|
|
111
|
-
|
|
112
|
-
'ansible.module_utils.six': UnwantedEntry(
|
|
113
|
-
'the Python standard library equivalent'
|
|
114
|
-
),
|
|
115
113
|
}
|
|
116
114
|
|
|
117
115
|
unwanted_functions = {
|
|
@@ -136,21 +134,34 @@ class AnsibleUnwantedChecker(BaseChecker):
|
|
|
136
134
|
modules_only=True),
|
|
137
135
|
}
|
|
138
136
|
|
|
139
|
-
def
|
|
137
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
138
|
+
super().__init__(*args, **kwargs)
|
|
139
|
+
# ansible.module_utils.six is deprecated and collections can still use it until it is removed
|
|
140
|
+
if self.is_ansible_core:
|
|
141
|
+
self.unwanted_imports['ansible.module_utils.six'] = UnwantedEntry(
|
|
142
|
+
'the Python standard library equivalent'
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
@functools.cached_property
|
|
146
|
+
def is_ansible_core(self) -> bool:
|
|
147
|
+
"""True if ansible-core is being tested."""
|
|
148
|
+
return not self.linter.config.collection_name
|
|
149
|
+
|
|
150
|
+
def visit_import(self, node: astroid.nodes.Import) -> None:
|
|
140
151
|
"""Visit an import node."""
|
|
141
152
|
for name in node.names:
|
|
142
153
|
self._check_import(node, name[0])
|
|
143
154
|
|
|
144
|
-
def visit_importfrom(self, node
|
|
155
|
+
def visit_importfrom(self, node: astroid.nodes.ImportFrom) -> None:
|
|
145
156
|
"""Visit an import from node."""
|
|
146
157
|
self._check_importfrom(node, node.modname, node.names)
|
|
147
158
|
|
|
148
|
-
def visit_attribute(self, node
|
|
159
|
+
def visit_attribute(self, node: astroid.nodes.Attribute) -> None:
|
|
149
160
|
"""Visit an attribute node."""
|
|
150
161
|
last_child = node.last_child()
|
|
151
162
|
|
|
152
163
|
# this is faster than using type inference and will catch the most common cases
|
|
153
|
-
if not isinstance(last_child, astroid.
|
|
164
|
+
if not isinstance(last_child, astroid.nodes.Name):
|
|
154
165
|
return
|
|
155
166
|
|
|
156
167
|
module = last_child.name
|
|
@@ -161,13 +172,13 @@ class AnsibleUnwantedChecker(BaseChecker):
|
|
|
161
172
|
if entry.applies_to(self.linter.current_file, node.attrname):
|
|
162
173
|
self.add_message(self.BAD_IMPORT_FROM, args=(node.attrname, entry.alternative, module), node=node)
|
|
163
174
|
|
|
164
|
-
def visit_call(self, node
|
|
175
|
+
def visit_call(self, node: astroid.nodes.Call) -> None:
|
|
165
176
|
"""Visit a call node."""
|
|
166
177
|
try:
|
|
167
178
|
for i in node.func.inferred():
|
|
168
179
|
func = None
|
|
169
180
|
|
|
170
|
-
if isinstance(i, astroid.
|
|
181
|
+
if isinstance(i, astroid.nodes.FunctionDef) and isinstance(i.parent, astroid.nodes.Module):
|
|
171
182
|
func = '%s.%s' % (i.parent.name, i.name)
|
|
172
183
|
|
|
173
184
|
if not func:
|
|
@@ -180,7 +191,7 @@ class AnsibleUnwantedChecker(BaseChecker):
|
|
|
180
191
|
except astroid.exceptions.InferenceError:
|
|
181
192
|
pass
|
|
182
193
|
|
|
183
|
-
def _check_import(self, node
|
|
194
|
+
def _check_import(self, node: astroid.nodes.Import, modname: str) -> None:
|
|
184
195
|
"""Check the imports on the specified import node."""
|
|
185
196
|
self._check_module_import(node, modname)
|
|
186
197
|
|
|
@@ -192,7 +203,7 @@ class AnsibleUnwantedChecker(BaseChecker):
|
|
|
192
203
|
if entry.applies_to(self.linter.current_file):
|
|
193
204
|
self.add_message(self.BAD_IMPORT, args=(entry.alternative, modname), node=node)
|
|
194
205
|
|
|
195
|
-
def _check_importfrom(self, node
|
|
206
|
+
def _check_importfrom(self, node: astroid.nodes.ImportFrom, modname: str, names: list[tuple[str, str | None]]) -> None:
|
|
196
207
|
"""Check the imports on the specified import from node."""
|
|
197
208
|
self._check_module_import(node, modname)
|
|
198
209
|
|
|
@@ -205,7 +216,7 @@ class AnsibleUnwantedChecker(BaseChecker):
|
|
|
205
216
|
if entry.applies_to(self.linter.current_file, name[0]):
|
|
206
217
|
self.add_message(self.BAD_IMPORT_FROM, args=(name[0], entry.alternative, modname), node=node)
|
|
207
218
|
|
|
208
|
-
def _check_module_import(self, node
|
|
219
|
+
def _check_module_import(self, node: astroid.nodes.Import | astroid.nodes.ImportFrom, modname: str) -> None:
|
|
209
220
|
"""Check the module import on the given import or import from node."""
|
|
210
221
|
if not is_module_path(self.linter.current_file):
|
|
211
222
|
return
|
|
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
|