diff --git a/.github/workflows/lint-action.yml b/.github/workflows/lint-action.yml index 6f177667129..9dc4be360e3 100644 --- a/.github/workflows/lint-action.yml +++ b/.github/workflows/lint-action.yml @@ -23,7 +23,7 @@ jobs: if: ${{ contains(fromJSON('["push", "schedule", "workflow_dispatch"]'), github.event_name) || fromJSON(inputs.changed-files)['salt'] || fromJSON(inputs.changed-files)['lint'] }} container: - image: ghcr.io/saltstack/salt-ci-containers/python:3.8 + image: ghcr.io/saltstack/salt-ci-containers/python:3.9 steps: - name: Install System Deps diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b402fd7e93c..2b170f88ef3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1370,23 +1370,6 @@ repos: # <---- Doc CI Requirements ---------------------------------------------------------------------------------------- # ----- Lint CI Requirements --------------------------------------------------------------------------------------> - - id: pip-tools-compile - alias: compile-ci-lint-3.7-requirements - name: Lint CI Py3.7 Requirements - files: ^requirements/((base|zeromq)\.txt|static/(pkg/linux\.in|ci/(linux\.in|common\.in|lint\.in|py3\.7/linux\.txt)))$ - pass_filenames: false - args: - - -v - - --build-isolation - - --py-version=3.7 - - --platform=linux - - --include=requirements/base.txt - - --include=requirements/zeromq.txt - - --include=requirements/static/pkg/linux.in - - --include=requirements/static/ci/linux.in - - --include=requirements/static/ci/common.in - - --no-emit-index-url - - requirements/static/ci/lint.in - id: pip-tools-compile alias: compile-ci-lint-3.8-requirements @@ -1762,7 +1745,7 @@ repos: - types-attrs - types-pyyaml - types-requests - - python-tools-scripts>=0.20.0 + - python-tools-scripts==0.20.0 - repo: https://github.com/saltstack/mirrors-nox rev: v2021.6.12 @@ -1770,7 +1753,7 @@ repos: - id: nox alias: lint-salt name: Lint Salt - files: ^((setup|noxfile)|(salt|tasks|tools)/.*)\.py$ + files: ^((setup|noxfile)|(salt|tools)/.*)\.py$ exclude: > (?x)^( templates/.*| diff --git a/.pylintrc b/.pylintrc index 04fa981c375..d9e7af58eae 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,25 +1,77 @@ -[MASTER] +[MAIN] + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Clear in-memory caches upon conclusion of linting. Useful if running pylint +# in a server-like mode. +clear-cache-post-run=no + +# Load and enable all available extensions. Use --list-extensions to see a list +# all available extensions. +#enable-all-extensions= + +# In error mode, messages with a category besides ERROR or FATAL are +# suppressed, and no reports are done by default. Error mode is compatible with +# disabling specific errors. +#errors-only= + +# Always return a 0 (non-error) status code, even if lint errors are found. +# This is primarily useful in continuous integration scripts. +#exit-zero= # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code. +extension-pkg-allow-list= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. (This is an alternative name to extension-pkg-allow-list +# for backward compatibility.) extension-pkg-whitelist= -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS, - ext, +# Return non-zero exit code if any of these messages/categories are detected, +# even if score is above --fail-under value. Syntax same as enable. Messages +# specified are enabled, while categories only check already-enabled messages. +fail-on= -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns=salt.ext.* +# Specify a score threshold under which the program will exit with error. +fail-under=10 + +# Interpret the stdin as a python script, whose filename needs to be passed as +# the module_or_package argument. +#from-stdin= + +# Files or directories to be skipped. They should be base names, not paths. +ignore=CVS + +# Add files or directories matching the regular expressions patterns to the +# ignore-list. The regex matches against paths and can be in Posix or Windows +# format. Because '\\' represents the directory delimiter on Windows systems, +# it can't be used as an escape character. +ignore-paths= + +# Files or directories matching the regular expression patterns are skipped. +# The regex matches against base names, not paths. The default value ignores +# Emacs file locks +ignore-patterns=^\.# + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis). It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. +# number of processors available to use, and will cap the count on Windows to +# avoid hangs. jobs=1 # Control the amount of potential inferred values when inferring a single @@ -29,12 +81,8 @@ limit-inference-results=100 # List of plugins (as comma separated values of python module names) to load, # usually to register additional checkers. -load-plugins=saltpylint.pep8, - saltpylint.strings, - saltpylint.fileperms, - saltpylint.py3modernize, +load-plugins=saltpylint.fileperms, saltpylint.smartup, - saltpylint.minpyver, saltpylint.blacklist, saltpylint.thirdparty, saltpylint.dunder_del @@ -42,8 +90,18 @@ load-plugins=saltpylint.pep8, # Pickle collected data for later comparisons. persistent=no -# Specify a configuration file. -#rcfile= +# Minimum Python version to use for version dependent checks. Will default to +# the version used to run pylint. +py-version=3.9 + +# Discover python modules and packages in the file system subtree. +recursive=no + +# Add paths to the list of the source roots. Supports globbing patterns. The +# source root is an absolute path or a path relative to the current working +# directory used to determine a package namespace for modules located under the +# source root. +source-roots= # When enabled, pylint would attempt to guess common misconfiguration and emit # user-friendly hints instead of false-positive error messages. @@ -53,125 +111,215 @@ suggestion-mode=yes # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=R, - locally-disabled, - file-ignored, - unexpected-special-method-signature, - import-error, - no-member, - unsubscriptable-object, - un-indexed-curly-braces-error, - whitespace-before-colon, - indentation-is-not-a-multiple-of-four-comment, - blacklisted-name, - invalid-name, - missing-docstring, - empty-docstring, - misplaced-comparison-constant, - unidiomatic-typecheck, - wrong-import-order, - ungrouped-imports, - wrong-import-position, - bad-mcs-method-argument, - bad-mcs-classmethod-argument, - line-too-long, - too-many-lines, - bad-continuation, - exec-used, - attribute-defined-outside-init, - protected-access, - reimported, - fixme, - global-statement, - unused-variable, - unused-argument, - redefined-outer-name, - redefined-builtin, - undefined-loop-variable, - logging-format-interpolation, - invalid-format-index, - line-too-long, - unexpected-indentation-comment, - continuation-line-indentation-is-not-a-multiple-of-four, - continuation-line-missing-indentation-or-outdented, - closing-bracket-does-not-match-indentation-of-opening-brackets-line, - closing-bracket-does-not-match-visual-indentation, - continuation-line-does-not-distinguish-itself-from-next-logical-line, - continuation-line-over-indented-for-hanging-indent, - continuation-line-over-indented-for-visual-indent, - continuation-line-under-indented-for-visual-indent, - visually-indented-line-with-same-indent-as-next-logical-line, - unaligned-for-hanging-indent, - block-comment-should-start-with-cardinal-space, - too-many-leading-hastag-for-block-comment, - module-level-import-not-at-top-of-file, - do-not-assign-a-lambda-expression-use-a-def, - 3rd-party-local-module-not-gated, - pep8-reserved-keywords, - import-outside-toplevel, - deprecated-method, - repr-flag-used-in-string, - keyword-arg-before-vararg, - incompatible-py3-code - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member, - literal-comparison +# In verbose mode, extra non-checker-related info will be displayed. +#verbose= -[REPORTS] +[BASIC] -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'error', 'warning', 'refactor', and 'convention' -# which contain the number of messages in each category, as well as 'statement' -# which is the total number of statements analyzed. This score is used by the -# global evaluation report (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) +# Naming style matching correct argument names. +argument-naming-style=snake_case -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} +# Regular expression matching correct argument names. Overrides argument- +# naming-style. If left empty, argument names will be checked with the set +# naming style. +#argument-rgx= -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=parseable +# Naming style matching correct attribute names. +attr-naming-style=snake_case -# Tells whether to display a full report or only the messages. -reports=no +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. If left empty, attribute names will be checked with the set naming +# style. +#attr-rgx= -# Activate the evaluation score. -score=yes +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Bad variable names regexes, separated by a comma. If names match any regex, +# they will always be refused +bad-names-rgxs= + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. If left empty, class attribute names will be checked +# with the set naming style. +#class-attribute-rgx= + +# Naming style matching correct class constant names. +class-const-naming-style=UPPER_CASE + +# Regular expression matching correct class constant names. Overrides class- +# const-naming-style. If left empty, class constant names will be checked with +# the set naming style. +#class-const-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. If left empty, class names will be checked with the set naming style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. If left empty, constant names will be checked with the set naming +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. If left empty, function names will be checked with the set +# naming style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=exc, + Run, + _ + +# Good variable names regexes, separated by a comma. If names match any regex, +# they will always be accepted +good-names-rgxs= + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. If left empty, inline iteration names will be checked +# with the set naming style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. If left empty, method names will be checked with the set naming style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. If left empty, module names will be checked with the set naming style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Regular expression matching correct type alias names. If left empty, type +# alias names will be checked with the set naming style. +#typealias-rgx= + +# Regular expression matching correct type variable names. If left empty, type +# variable names will be checked with the set naming style. +#typevar-rgx= + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. If left empty, variable names will be checked with the set +# naming style. +#variable-rgx= -[REFACTORING] +[CLASSES] -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 +# Warn about protected attribute access inside special methods +check-protected-access-in-special-methods=no -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp, + asyncSetUp, + __post_init__ + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[DESIGN] + +# List of regular expressions of class ancestor names to ignore when counting +# public methods (see R0903) +exclude-too-few-public-methods= + +# List of qualified class names to ignore when counting class parents (see +# R0901) +ignored-parents= + +# Maximum number of arguments for function / method. +max-args=35 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=48 + +# Maximum number of locals for function / method body. +max-locals=40 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=100 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when caught. +overgeneral-exceptions=builtins.BaseException,builtins.Exception [FORMAT] @@ -195,13 +343,6 @@ max-line-length=120 # Maximum number of lines in a module. max-module-lines=3000 -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator - # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no @@ -211,141 +352,296 @@ single-line-class-stmt=no single-line-if-stmt=no +[IMPORTS] + +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= + +# Allow explicit reexports by alias from a package __init__. +allow-reexport-from-package=no + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules= + +# Output a graph (.gv or any supported image format) of external dependencies +# to the given file (report RP0402 must not be disabled). +ext-import-graph= + +# Output a graph (.gv or any supported image format) of all (i.e. internal and +# external) dependencies to the given file (report RP0402 must not be +# disabled). +import-graph= + +# Output a graph (.gv or any supported image format) of internal dependencies +# to the given file (report RP0402 must not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= + + +[LOGGING] + +# The type of string formatting that logging methods do. `old` means using % +# formatting, `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, +# UNDEFINED. +confidence=HIGH, + CONTROL_FLOW, + INFERENCE, + INFERENCE_FAILURE, + UNDEFINED + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then re-enable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=R, + deprecated-pragma, + file-ignored, + locally-disabled, + suppressed-message, + use-implicit-booleaness-not-comparison-to-string, + use-implicit-booleaness-not-comparison-to-zero, + use-implicit-booleaness-not-comparison, + use-symbolic-message-instead, + useless-suppression, + 3rd-party-local-module-not-gated, + attribute-defined-outside-init, + bad-continuation, + bad-mcs-classmethod-argument, + bad-mcs-method-argument, + blacklisted-name, + deprecated-method, + empty-docstring, + exec-used, + file-ignored, + fixme, + global-statement, + import-error, + import-outside-toplevel, + invalid-format-index, + invalid-name, + keyword-arg-before-vararg, + line-too-long, + locally-disabled, + logging-format-interpolation, + missing-docstring, + no-member, + protected-access, + raw-checker-failed, + redefined-builtin, + redefined-outer-name, + reimported, + too-many-lines, + undefined-loop-variable, + unexpected-special-method-signature, + ungrouped-imports, + unidiomatic-typecheck, + unsubscriptable-object, + unused-argument, + unused-variable, + wrong-import-order, + wrong-import-position, + consider-using-f-string, + raise-missing-from, + broad-exception-raised, + consider-using-dict-items + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable= + + +[METHOD_ARGS] + +# List of qualified names (i.e., library.method) which require a timeout +# parameter e.g. 'requests.api.get,requests.api.post' +timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request + + [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME, - FIX, XXX, TODO +# Regular expression of note tags to take in consideration. +notes-rgx= -[BASIC] -# Naming style matching correct argument names. -argument-naming-style=snake_case +[REFACTORING] -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -argument-rgx=[a-z_][a-z0-9_]{2,30}$ +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 -# Naming style matching correct attribute names. -attr-naming-style=snake_case +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit,argparse.parse_error -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -attr-rgx=[a-z_][a-z0-9_]{2,30}$ -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata +[REPORTS] -# Naming style matching correct class attribute names. -class-attribute-naming-style=any +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'fatal', 'error', 'warning', 'refactor', +# 'convention', and 'info' which contain the number of messages in each +# category, as well as 'statement' which is the total number of statements +# analyzed. This score is used by the global evaluation report (RP0004). +evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +msg-template= -# Naming style matching correct class names. -class-naming-style=PascalCase +# Set the output format. Available formats are: text, parseable, colorized, +# json2 (improved json format), json (old json format) and msvs (visual +# studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=parseable -# Regular expression matching correct class names. Overrides class-naming- -# style. -class-rgx=[A-Z_][a-zA-Z0-9]+$ +# Tells whether to display a full report or only the messages. +reports=no -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE +# Activate the evaluation score. +score=yes -# Regular expression matching correct constant names. Overrides const-naming- -# style. -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 +[SIMILARITIES] -# Naming style matching correct function names. -function-naming-style=snake_case +# Comments are removed from the similarity computation +ignore-comments=yes -# Regular expression matching correct function names. Overrides function- -# naming-style. -function-rgx=[a-z_][a-z0-9_]{2,30}$ +# Docstrings are removed from the similarity computation +ignore-docstrings=yes -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - k, - ex, - Run, - _, - log +# Imports are removed from the similarity computation +ignore-imports=yes -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=yes +# Signatures are removed from the similarity computation +ignore-signatures=yes -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any +# Minimum lines number of a similarity. +min-similarity-lines=4 -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ -# Naming style matching correct method names. -method-naming-style=snake_case +[SPELLING] -# Regular expression matching correct method names. Overrides method-naming- -# style. -method-rgx=[a-z_][a-z0-9_]{2,30}$ +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 -# Naming style matching correct module names. -module-naming-style=snake_case +# Spelling dictionary name. No available dictionaries : You need to install +# both the python package and the system dependency for enchant to work. +spelling-dict= -# Regular expression matching correct module names. Overrides module-naming- -# style. -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ +# List of comma separated words that should be considered directives if they +# appear at the beginning of a comment and should not be checked. +spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= +# List of comma separated words that should not be checked. +spelling-ignore-words= -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=__.*__ +# A path to a file that contains the private dictionary; one word per line. +spelling-private-dict-file= -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -variable-rgx=[a-z_][a-z0-9_]{2,30}$ +# Tells whether to store unknown words to the private dictionary (see the +# --spelling-private-dict-file option) instead of raising a message. +spelling-store-unknown-words=no [STRING] -# This flag controls whether the implicit-str-concat-in-sequence should -# generate a warning on implicit string concatenation in sequences defined over -# several lines. +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=no + +# This flag controls whether the implicit-str-concat should generate a warning +# on implicit string concatenation in sequences defined over several lines. check-str-concat-over-line-jumps=no -# Enforce string formatting over string substitution -enforce-string-formatting-over-substitution=yes -# Force string substitution usage on strings to always be an error. -string-substitutions-usage-is-an-error=yes +[TYPECHECK] -# Force un-indexed curly braces on a 'string.format()' call to always be an -# error. -un-indexed-curly-braces-always-error=no +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of symbolic message names to ignore for Mixin members. +ignored-checks-for-mixins=no-member, + not-async-context-manager, + not-context-manager, + attribute-defined-outside-init + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# Regex pattern to define which classes are considered mixins. +mixin-class-rgx=.*[Mm]ixin + +# List of decorators that change the signature of a decorated function. +signature-mutators= [VARIABLES] @@ -379,6 +675,9 @@ additional-builtins=__opts__, # Tells whether unused global variables should be treated as a violation. allow-global-unused-variables=yes +# List of names allowed to shadow builtins +allowed-redefined-builtins= + # List of strings which can identify a callback function by name. A callback # name must start or end with one of those strings. callbacks=cb_, @@ -386,128 +685,17 @@ callbacks=cb_, # A regular expression matching the name of dummy variables (i.e. expected to # not be used). -dummy-variables-rgx=_|dummy +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.* +# Argument names that match this expression will be ignored. +ignored-argument-names=_.*|^ignored_|^unused_ # Tells whether we should check for unused import in __init__ files. init-import=no # List of qualified module names which can have objects that can redefine # builtins. -redefining-builtins-modules=six.moves, - salt.ext.six.moves, - past.builtins, - future.builtins, - builtins, - io - - -[LOGGING] - -# Format style used to check logging format string. `old` means using % -# formatting, `new` is for `{}` formatting,and `fstr` is for f-strings. -logging-format-style=old - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules= - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it work, -# install the python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains the private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -spelling-store-unknown-words=no - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members=REQUEST, - acl_users, - aq_parent - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=SQLObject - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis). It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules=salt.ext.six.moves, - six.moves, - _MovedItems, - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - -# List of decorators that change the signature of a decorated function. -signature-mutators= - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io [FILEPERMS] @@ -518,135 +706,6 @@ fileperms-default=0644 # File paths to ignore file permission. Glob patterns allowed. fileperms-ignore-paths=setup.py,noxfile.py,tests/runtests.py,tests/jenkins*.py,tests/saltsh.py,tests/buildpackage.py,tests/unit/files/rosters/ansible/roster.py - -[MODERNIZE] - -# Fix up doctests only -modernize-doctests-only=no - -# Each FIX specifies a transformation; "default" includes default fixes. -modernize-fix= - -# Use 'from __future__ import unicode_literals' (only useful for Python 2.6+). -modernize-future-unicode=no - -# Exclude fixes that depend on the six package. -modernize-no-six=no - -# Comma separated list of fixer names not to fix. -modernize-nofix= - -# Modify the grammar so that print() is a function. -modernize-print-function=yes - -# Wrap unicode literals in six.u(). -modernize-six-unicode=no - - -[MININUM-PYTHON-VERSION] - -# The desired minimum python version to enforce. Default: 2.6 -minimum-python-version=2.7 - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[DESIGN] - -# Maximum number of arguments for function / method. -max-args=35 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=48 - -# Maximum number of locals for function / method body. -max-locals=40 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=100 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[IMPORTS] - -# List of modules that can be imported at any level, not just the top level -# one. -allow-any-import-level= - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=yes - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=yes - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules=regsub, - TERMIOS, - Bastion, - rexec - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled). -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled). -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Couples of modules and preferred modules, separated by a comma. -preferred-modules= - - [BLACKLISTED-FUNCTIONS] # List of blacklisted functions and suggested replacements @@ -700,11 +759,5 @@ allowed-3rd-party-modules=msgpack, looseversion, pytestskipmarkers, cryptography, + aiohttp, pytest_timeout - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "BaseException, Exception". -overgeneral-exceptions=BaseException, - Exception diff --git a/noxfile.py b/noxfile.py index 2ed8e4d0a00..1a78e4628ae 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1300,7 +1300,7 @@ def decompress_dependencies(session): # Let's try to fix shebang's try: fpath = pathlib.Path(path) - contents = fpath.read_text().splitlines() + contents = fpath.read_text(encoding="utf-8").splitlines() if ( contents[0].startswith("#!") and contents[0].endswith("python") @@ -1310,7 +1310,9 @@ def decompress_dependencies(session): "Fixing broken shebang in %r", str(fpath.relative_to(REPO_ROOT)), ) - fpath.write_text("\n".join([fixed_shebang] + contents[1:])) + fpath.write_text( + "\n".join([fixed_shebang] + contents[1:]), encoding="utf-8" + ) except UnicodeDecodeError: pass @@ -1467,48 +1469,26 @@ class Tee: return self._first.fileno() -def _lint( - session, rcfile, flags, paths, tee_output=True, upgrade_setuptools_and_pip=True -): +def _lint(session, rcfile, flags, paths, upgrade_setuptools_and_pip=True): if _upgrade_pip_setuptools_and_wheel(session, upgrade=upgrade_setuptools_and_pip): - requirements_file = os.path.join( + base_requirements_file = os.path.join( + "requirements", "static", "ci", _get_pydir(session), "linux.txt" + ) + lint_requirements_file = os.path.join( "requirements", "static", "ci", _get_pydir(session), "lint.txt" ) - install_command = ["--progress-bar=off", "-r", requirements_file] + install_command = [ + "--progress-bar=off", + "-r", + base_requirements_file, + "-r", + lint_requirements_file, + ] session.install(*install_command, silent=PIP_INSTALL_SILENT) - if tee_output: - session.run("pylint", "--version") - pylint_report_path = os.environ.get("PYLINT_REPORT") - cmd_args = ["pylint", "--rcfile={}".format(rcfile)] + list(flags) + list(paths) - cmd_kwargs = {"env": {"PYTHONUNBUFFERED": "1"}} - - if tee_output: - stdout = tempfile.TemporaryFile(mode="w+b") - cmd_kwargs["stdout"] = Tee(stdout, sys.__stdout__) - - lint_failed = False - try: - session.run(*cmd_args, **cmd_kwargs) - except CommandFailed: - lint_failed = True - raise - finally: - if tee_output: - stdout.seek(0) - contents = stdout.read() - if contents: - contents = contents.decode("utf-8") - sys.stdout.write(contents) - sys.stdout.flush() - if pylint_report_path: - # Write report - with open(pylint_report_path, "w") as wfh: - wfh.write(contents) - session.log("Report file written to %r", pylint_report_path) - stdout.close() + session.run(*cmd_args, **cmd_kwargs) def _lint_pre_commit(session, rcfile, flags, paths): @@ -1527,26 +1507,17 @@ def _lint_pre_commit(session, rcfile, flags, paths): from nox.virtualenv import VirtualEnv # Let's patch nox to make it run inside the pre-commit virtualenv - try: - session._runner.venv = VirtualEnv( # pylint: disable=unexpected-keyword-arg - os.environ["VIRTUAL_ENV"], - interpreter=session._runner.func.python, - reuse_existing=True, - venv=True, - ) - except TypeError: - # This is still nox-py2 - session._runner.venv = VirtualEnv( - os.environ["VIRTUAL_ENV"], - interpreter=session._runner.func.python, - reuse_existing=True, - ) + session._runner.venv = VirtualEnv( + os.environ["VIRTUAL_ENV"], + interpreter=session._runner.func.python, + reuse_existing=True, + venv=True, + ) _lint( session, rcfile, flags, paths, - tee_output=False, upgrade_setuptools_and_pip=False, ) @@ -1554,7 +1525,7 @@ def _lint_pre_commit(session, rcfile, flags, paths): @nox.session(python="3") def lint(session): """ - Run PyLint against Salt and it's test suite. Set PYLINT_REPORT to a path to capture output. + Run PyLint against Salt and it's test suite. """ session.notify("lint-salt-{}".format(session.python)) session.notify("lint-tests-{}".format(session.python)) @@ -1563,21 +1534,21 @@ def lint(session): @nox.session(python="3", name="lint-salt") def lint_salt(session): """ - Run PyLint against Salt. Set PYLINT_REPORT to a path to capture output. + Run PyLint against Salt. """ flags = ["--disable=I"] if session.posargs: paths = session.posargs else: # TBD replace paths entries when implement pyproject.toml - paths = ["setup.py", "noxfile.py", "salt/"] + paths = ["setup.py", "noxfile.py", "salt/", "tools/"] _lint(session, ".pylintrc", flags, paths) @nox.session(python="3", name="lint-tests") def lint_tests(session): """ - Run PyLint against Salt and it's test suite. Set PYLINT_REPORT to a path to capture output. + Run PyLint against Salt and it's test suite. """ flags = ["--disable=I"] if session.posargs: @@ -1590,20 +1561,20 @@ def lint_tests(session): @nox.session(python=False, name="lint-salt-pre-commit") def lint_salt_pre_commit(session): """ - Run PyLint against Salt. Set PYLINT_REPORT to a path to capture output. + Run PyLint against Salt. """ flags = ["--disable=I"] if session.posargs: paths = session.posargs else: - paths = ["setup.py", "noxfile.py", "salt/"] + paths = ["setup.py", "noxfile.py", "salt/", "tools/"] _lint_pre_commit(session, ".pylintrc", flags, paths) @nox.session(python=False, name="lint-tests-pre-commit") def lint_tests_pre_commit(session): """ - Run PyLint against Salt and it's test suite. Set PYLINT_REPORT to a path to capture output. + Run PyLint against Salt and it's test suite. """ flags = ["--disable=I"] if session.posargs: @@ -1960,8 +1931,8 @@ def ci_test_onedir_pkgs(session): + cmd_args[:] + [ "--no-install", - f"--junitxml=artifacts/xml-unittests-output/test-results-install.xml", - f"--log-file=artifacts/logs/runtests-install.log", + "--junitxml=artifacts/xml-unittests-output/test-results-install.xml", + "--log-file=artifacts/logs/runtests-install.log", ] + session.posargs ) @@ -1978,8 +1949,8 @@ def ci_test_onedir_pkgs(session): + cmd_args[:] + [ "--no-install", - f"--junitxml=artifacts/xml-unittests-output/test-results-install-rerun.xml", - f"--log-file=artifacts/logs/runtests-install-rerun.log", + "--junitxml=artifacts/xml-unittests-output/test-results-install-rerun.xml", + "--log-file=artifacts/logs/runtests-install-rerun.log", "--lf", ] + session.posargs diff --git a/requirements/static/ci/lint.in b/requirements/static/ci/lint.in index 86ed3a61c28..977c91fcd47 100644 --- a/requirements/static/ci/lint.in +++ b/requirements/static/ci/lint.in @@ -2,6 +2,6 @@ --constraint=./py{py_version}/{platform}.txt docker -pylint==2.4.4 -SaltPyLint>=2023.3.8 +pylint~=3.1.0 +SaltPyLint>=2024.2.2 toml diff --git a/requirements/static/ci/py3.10/lint.txt b/requirements/static/ci/py3.10/lint.txt index fbcaa9b1269..3841c2aad37 100644 --- a/requirements/static/ci/py3.10/lint.txt +++ b/requirements/static/ci/py3.10/lint.txt @@ -33,7 +33,7 @@ asn1crypto==1.3.0 # -c requirements/static/ci/py3.10/linux.txt # certvalidator # oscrypto -astroid==2.3.3 +astroid==3.1.0 # via pylint async-timeout==4.0.2 # via @@ -145,6 +145,8 @@ cryptography==42.0.3 # paramiko # pyopenssl # vcert +dill==0.3.8 + # via pylint distlib==0.3.2 # via # -c requirements/static/ci/py3.10/linux.txt @@ -285,8 +287,6 @@ kubernetes==3.0.0 # via # -c requirements/static/ci/py3.10/linux.txt # -r requirements/static/ci/common.in -lazy-object-proxy==1.4.3 - # via astroid libnacl==1.7.1 ; sys_platform != "win32" and sys_platform != "darwin" # via # -c requirements/static/ci/py3.10/linux.txt @@ -320,8 +320,6 @@ mercurial==6.0.1 # via # -c requirements/static/ci/py3.10/linux.txt # -r requirements/static/ci/linux.in -modernize==0.5 - # via saltpylint more-itertools==5.0.0 # via # -c requirements/static/ci/../pkg/py3.10/linux.txt @@ -385,6 +383,7 @@ pathtools==0.1.2 platformdirs==2.2.0 # via # -c requirements/static/ci/py3.10/linux.txt + # pylint # virtualenv portend==2.4 # via @@ -405,8 +404,6 @@ pyasn1==0.4.8 # -c requirements/static/ci/py3.10/linux.txt # pyasn1-modules # rsa -pycodestyle==2.5.0 - # via saltpylint pycparser==2.21 ; python_version >= "3.9" # via # -c requirements/static/ci/../pkg/py3.10/linux.txt @@ -435,7 +432,7 @@ pyjwt==2.4.0 # via # -c requirements/static/ci/py3.10/linux.txt # twilio -pylint==2.4.4 +pylint==3.1.0 # via # -r requirements/static/ci/lint.in # saltpylint @@ -571,7 +568,7 @@ s3transfer==0.5.2 # via # -c requirements/static/ci/py3.10/linux.txt # boto3 -saltpylint==2023.8.3 +saltpylint==2024.2.5 # via -r requirements/static/ci/lint.in scp==0.13.2 # via @@ -591,7 +588,6 @@ six==1.16.0 # -c requirements/static/ci/../pkg/py3.10/linux.txt # -c requirements/static/ci/py3.10/linux.txt # apscheduler - # astroid # cassandra-driver # cheroot # etcd3-py @@ -646,6 +642,12 @@ toml==0.10.2 # -c requirements/static/ci/py3.10/linux.txt # -r requirements/static/ci/common.in # -r requirements/static/ci/lint.in +tomli==2.0.1 + # via + # -c requirements/static/ci/py3.10/linux.txt + # pylint +tomlkit==0.12.3 + # via pylint tornado==6.1 # via # -c requirements/static/ci/py3.10/linux.txt @@ -658,6 +660,10 @@ twilio==7.9.2 # via # -c requirements/static/ci/py3.10/linux.txt # -r requirements/static/ci/linux.in +typing-extensions==4.8.0 + # via + # -c requirements/static/ci/py3.10/linux.txt + # astroid tzlocal==3.0 # via # -c requirements/static/ci/py3.10/linux.txt @@ -696,8 +702,6 @@ werkzeug==3.0.1 # via # -c requirements/static/ci/py3.10/linux.txt # moto -wrapt==1.11.1 - # via astroid xmltodict==0.12.0 # via # -c requirements/static/ci/py3.10/linux.txt diff --git a/requirements/static/ci/py3.11/lint.txt b/requirements/static/ci/py3.11/lint.txt index e1b74f92032..19dbac9d26f 100644 --- a/requirements/static/ci/py3.11/lint.txt +++ b/requirements/static/ci/py3.11/lint.txt @@ -33,7 +33,7 @@ asn1crypto==1.3.0 # -c requirements/static/ci/py3.11/linux.txt # certvalidator # oscrypto -astroid==2.3.3 +astroid==3.1.0 # via pylint attrs==23.1.0 # via @@ -141,6 +141,8 @@ cryptography==42.0.3 # paramiko # pyopenssl # vcert +dill==0.3.8 + # via pylint distlib==0.3.2 # via # -c requirements/static/ci/py3.11/linux.txt @@ -276,8 +278,6 @@ kubernetes==3.0.0 # via # -c requirements/static/ci/py3.11/linux.txt # -r requirements/static/ci/common.in -lazy-object-proxy==1.4.3 - # via astroid libnacl==1.7.1 ; sys_platform != "win32" and sys_platform != "darwin" # via # -c requirements/static/ci/py3.11/linux.txt @@ -306,8 +306,6 @@ mercurial==6.0.1 # via # -c requirements/static/ci/py3.11/linux.txt # -r requirements/static/ci/linux.in -modernize==0.5 - # via saltpylint more-itertools==5.0.0 # via # -c requirements/static/ci/../pkg/py3.11/linux.txt @@ -360,6 +358,7 @@ pathtools==0.1.2 platformdirs==2.2.0 # via # -c requirements/static/ci/py3.11/linux.txt + # pylint # virtualenv portend==2.4 # via @@ -380,8 +379,6 @@ pyasn1==0.4.8 # -c requirements/static/ci/py3.11/linux.txt # pyasn1-modules # rsa -pycodestyle==2.5.0 - # via saltpylint pycparser==2.21 ; python_version >= "3.9" # via # -c requirements/static/ci/../pkg/py3.11/linux.txt @@ -410,7 +407,7 @@ pyjwt==2.4.0 # via # -c requirements/static/ci/py3.11/linux.txt # twilio -pylint==2.4.4 +pylint==3.1.0 # via # -r requirements/static/ci/lint.in # saltpylint @@ -536,7 +533,7 @@ s3transfer==0.5.2 # via # -c requirements/static/ci/py3.11/linux.txt # boto3 -saltpylint==2023.8.3 +saltpylint==2024.2.5 # via -r requirements/static/ci/lint.in semantic-version==2.9.0 # via @@ -552,7 +549,6 @@ six==1.16.0 # -c requirements/static/ci/../pkg/py3.11/linux.txt # -c requirements/static/ci/py3.11/linux.txt # apscheduler - # astroid # cassandra-driver # cheroot # etcd3-py @@ -604,6 +600,8 @@ toml==0.10.2 # -c requirements/static/ci/py3.11/linux.txt # -r requirements/static/ci/common.in # -r requirements/static/ci/lint.in +tomlkit==0.12.3 + # via pylint tornado==6.1 # via # -c requirements/static/ci/py3.11/linux.txt @@ -650,8 +648,6 @@ werkzeug==3.0.1 # via # -c requirements/static/ci/py3.11/linux.txt # moto -wrapt==1.11.1 - # via astroid xmltodict==0.12.0 # via # -c requirements/static/ci/py3.11/linux.txt diff --git a/requirements/static/ci/py3.12/lint.txt b/requirements/static/ci/py3.12/lint.txt index 777079138cc..0f9d5f8f2b3 100644 --- a/requirements/static/ci/py3.12/lint.txt +++ b/requirements/static/ci/py3.12/lint.txt @@ -33,7 +33,7 @@ asn1crypto==1.3.0 # -c requirements/static/ci/py3.12/linux.txt # certvalidator # oscrypto -astroid==2.3.3 +astroid==3.1.0 # via pylint attrs==23.1.0 # via @@ -141,6 +141,8 @@ cryptography==42.0.3 # paramiko # pyopenssl # vcert +dill==0.3.8 + # via pylint distlib==0.3.2 # via # -c requirements/static/ci/py3.12/linux.txt @@ -276,8 +278,6 @@ kubernetes==3.0.0 # via # -c requirements/static/ci/py3.12/linux.txt # -r requirements/static/ci/common.in -lazy-object-proxy==1.4.3 - # via astroid libnacl==1.7.1 ; sys_platform != "win32" and sys_platform != "darwin" # via # -c requirements/static/ci/py3.12/linux.txt @@ -306,8 +306,6 @@ mercurial==6.0.1 # via # -c requirements/static/ci/py3.12/linux.txt # -r requirements/static/ci/linux.in -modernize==0.5 - # via saltpylint more-itertools==5.0.0 # via # -c requirements/static/ci/../pkg/py3.12/linux.txt @@ -360,6 +358,7 @@ pathtools==0.1.2 platformdirs==2.2.0 # via # -c requirements/static/ci/py3.12/linux.txt + # pylint # virtualenv portend==2.4 # via @@ -380,8 +379,6 @@ pyasn1==0.4.8 # -c requirements/static/ci/py3.12/linux.txt # pyasn1-modules # rsa -pycodestyle==2.5.0 - # via saltpylint pycparser==2.21 ; python_version >= "3.9" # via # -c requirements/static/ci/../pkg/py3.12/linux.txt @@ -410,7 +407,7 @@ pyjwt==2.4.0 # via # -c requirements/static/ci/py3.12/linux.txt # twilio -pylint==2.4.4 +pylint==3.1.0 # via # -r requirements/static/ci/lint.in # saltpylint @@ -536,7 +533,7 @@ s3transfer==0.5.2 # via # -c requirements/static/ci/py3.12/linux.txt # boto3 -saltpylint==2023.8.3 +saltpylint==2024.2.5 # via -r requirements/static/ci/lint.in semantic-version==2.9.0 # via @@ -552,7 +549,6 @@ six==1.16.0 # -c requirements/static/ci/../pkg/py3.12/linux.txt # -c requirements/static/ci/py3.12/linux.txt # apscheduler - # astroid # cassandra-driver # cheroot # etcd3-py @@ -604,6 +600,8 @@ toml==0.10.2 # -c requirements/static/ci/py3.12/linux.txt # -r requirements/static/ci/common.in # -r requirements/static/ci/lint.in +tomlkit==0.12.3 + # via pylint tornado==6.1 # via # -c requirements/static/ci/py3.12/linux.txt @@ -650,8 +648,6 @@ werkzeug==3.0.1 # via # -c requirements/static/ci/py3.12/linux.txt # moto -wrapt==1.11.1 - # via astroid xmltodict==0.12.0 # via # -c requirements/static/ci/py3.12/linux.txt diff --git a/requirements/static/ci/py3.7/lint.txt b/requirements/static/ci/py3.7/lint.txt deleted file mode 100644 index bc9fea72e56..00000000000 --- a/requirements/static/ci/py3.7/lint.txt +++ /dev/null @@ -1,796 +0,0 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile --no-emit-index-url --output-file=requirements/static/ci/py3.7/lint.txt requirements/base.txt requirements/static/ci/common.in requirements/static/ci/lint.in requirements/static/ci/linux.in requirements/static/pkg/linux.in requirements/zeromq.txt -# -aiohttp==3.8.6 - # via - # -c requirements/static/ci/py3.7/linux.txt - # etcd3-py -aiosignal==1.2.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp -apache-libcloud==2.5.0 ; sys_platform != "win32" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -apscheduler==3.6.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # python-telegram-bot -asn1crypto==1.3.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # certvalidator - # oscrypto -astroid==2.3.3 - # via pylint -async-timeout==4.0.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp -asynctest==0.13.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp -attrs==23.1.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp - # jsonschema -backports.entry-points-selectable==1.1.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # virtualenv -backports.zoneinfo==0.2.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # tzlocal -bcrypt==4.1.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # paramiko -boto3==1.21.46 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # moto -boto==2.49.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -botocore==1.24.46 - # via - # -c requirements/static/ci/py3.7/linux.txt - # boto3 - # moto - # s3transfer -cached-property==1.5.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # pygit2 -cachetools==4.2.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # google-auth - # python-telegram-bot -cassandra-driver==3.23.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -certifi==2023.07.22 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # kubernetes - # python-telegram-bot - # requests -certvalidator==0.11.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # vcert -cffi==1.14.6 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # cryptography - # napalm - # pygit2 - # pynacl -charset-normalizer==3.2.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp - # requests -cheetah3==3.2.6.post2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -cheroot==8.5.2 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # cherrypy -cherrypy==18.6.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # -r requirements/static/pkg/linux.in -ciscoconfparse==1.5.19 - # via - # -c requirements/static/ci/py3.7/linux.txt - # napalm -click==7.1.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # geomet -clustershell==1.8.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -colorama==0.4.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # ciscoconfparse -contextvars==2.4 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt -croniter==0.3.29 ; sys_platform != "win32" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -cryptography==42.0.3 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in - # etcd3-py - # moto - # paramiko - # pyopenssl - # vcert -distlib==0.3.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # virtualenv -distro==1.5.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt -dnspython==1.16.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # ciscoconfparse - # python-etcd -docker==6.1.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/lint.in -etcd3-py==0.1.6 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -filelock==3.0.12 - # via - # -c requirements/static/ci/py3.7/linux.txt - # virtualenv -frozenlist==1.3.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp - # aiosignal -future==0.18.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # napalm - # textfsm -genshi==0.7.5 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -geomet==0.1.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # cassandra-driver -gitdb==4.0.7 - # via - # -c requirements/static/ci/py3.7/linux.txt - # gitpython -gitpython==3.1.41 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -google-auth==2.1.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # kubernetes -hglib==2.6.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -idna==3.2 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # etcd3-py - # requests - # yarl -immutables==0.15 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # contextvars -importlib-metadata==4.6.4 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in - # attrs - # backports.entry-points-selectable - # jsonschema - # mako - # moto - # virtualenv -ipaddress==1.0.22 - # via - # -c requirements/static/ci/py3.7/linux.txt - # kubernetes -isort==4.3.21 - # via pylint -jaraco.classes==3.2.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # jaraco.collections -jaraco.collections==3.4.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # cherrypy -jaraco.functools==2.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # cheroot - # jaraco.text - # tempora -jaraco.text==3.5.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # jaraco.collections -jinja2==3.1.3 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt - # junos-eznc - # moto - # napalm -jmespath==1.0.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt - # -r requirements/static/ci/common.in - # boto3 - # botocore -jsonschema==3.2.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -junos-eznc==2.4.0 ; sys_platform != "win32" and python_version <= "3.10" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # napalm -jxmlease==1.0.1 ; sys_platform != "win32" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -kazoo==2.6.1 ; sys_platform != "win32" and sys_platform != "darwin" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -keyring==5.7.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -kubernetes==3.0.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -lazy-object-proxy==1.4.3 - # via astroid -libnacl==1.7.1 ; sys_platform != "win32" and sys_platform != "darwin" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -looseversion==1.0.2 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt -lxml==4.9.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc - # napalm - # ncclient -mako==1.2.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -markupsafe==2.1.2 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt - # jinja2 - # mako - # moto - # werkzeug -mccabe==0.6.1 - # via pylint -mercurial==6.0.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -modernize==0.5 - # via saltpylint -more-itertools==5.0.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # cheroot - # cherrypy - # jaraco.classes - # jaraco.functools -moto==3.0.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -msgpack==1.0.2 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt -multidict==6.0.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp - # yarl -napalm==3.1.0 ; sys_platform != "win32" and python_version < "3.10" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -ncclient==0.6.4 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc -netaddr==0.7.19 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc - # napalm - # pyeapi -netmiko==3.2.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # napalm -ntc-templates==1.4.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc -oscrypto==1.2.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # certvalidator -packaging==22.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt - # docker -paramiko==3.4.0 ; sys_platform != "win32" and sys_platform != "darwin" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # junos-eznc - # napalm - # ncclient - # netmiko - # scp -passlib==1.7.4 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # ciscoconfparse -pathspec==0.9.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # yamllint -pathtools==0.1.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # watchdog -platformdirs==2.2.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # virtualenv -portend==2.4 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # cherrypy -psutil==5.8.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt -pyasn1-modules==0.2.4 - # via - # -c requirements/static/ci/py3.7/linux.txt - # google-auth -pyasn1==0.4.8 - # via - # -c requirements/static/ci/py3.7/linux.txt - # pyasn1-modules - # rsa -pycodestyle==2.5.0 - # via saltpylint -pycparser==2.17 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # cffi -pycryptodomex==3.19.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/crypto.txt -pyeapi==0.8.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # napalm -pygit2==1.10.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -pyiface==0.0.11 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -pyinotify==0.9.6 ; sys_platform != "win32" and sys_platform != "darwin" and platform_system != "openbsd" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -pyjwt==2.4.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # twilio -pylint==2.4.4 - # via - # -r requirements/static/ci/lint.in - # saltpylint -pymysql==1.0.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -pynacl==1.5.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # paramiko -pyopenssl==24.0.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in - # etcd3-py -pyparsing==3.0.9 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc -pyrsistent==0.17.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # jsonschema -pyserial==3.4 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc - # netmiko -python-consul==1.1.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -python-dateutil==2.8.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in - # botocore - # croniter - # kubernetes - # moto - # vcert -python-etcd==0.4.5 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -python-gnupg==0.4.8 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in -python-telegram-bot==13.7 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -pytz==2022.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # apscheduler - # moto - # python-telegram-bot - # tempora - # twilio -pyvmomi==6.7.1.2018.12 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -pyyaml==6.0.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt - # clustershell - # junos-eznc - # kubernetes - # napalm - # yamllint - # yamlordereddictloader -pyzmq==23.2.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/zeromq.txt -redis-py-cluster==2.1.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -redis==3.5.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # redis-py-cluster -requests==2.31.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/base.txt - # -r requirements/static/ci/common.in - # apache-libcloud - # docker - # etcd3-py - # kubernetes - # moto - # napalm - # python-consul - # pyvmomi - # responses - # twilio - # vcert -responses==0.10.6 - # via - # -c requirements/static/ci/py3.7/linux.txt - # moto -rfc3987==1.3.8 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -rpm-vercmp==0.1.2 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in -rsa==4.7.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # google-auth -s3transfer==0.5.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # boto3 -saltpylint==2023.8.3 - # via -r requirements/static/ci/lint.in -scp==0.13.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc - # napalm - # netmiko -semantic-version==2.9.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # etcd3-py -setproctitle==1.3.2 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in -six==1.16.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # apscheduler - # astroid - # cassandra-driver - # cheroot - # etcd3-py - # genshi - # geomet - # jsonschema - # junos-eznc - # kazoo - # kubernetes - # more-itertools - # ncclient - # python-consul - # python-dateutil - # pyvmomi - # responses - # textfsm - # transitions - # vcert - # virtualenv - # websocket-client -slack-bolt==1.15.5 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -slack-sdk==3.19.5 - # via - # -c requirements/static/ci/py3.7/linux.txt - # slack-bolt -smmap==4.0.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # gitdb -sqlparse==0.4.4 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -strict-rfc3339==0.7 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -tempora==4.1.1 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # portend -terminal==0.4.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # ntc-templates -textfsm==1.1.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # napalm - # netmiko - # ntc-templates -timelib==0.2.5 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/pkg/linux.in -toml==0.10.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in - # -r requirements/static/ci/lint.in -tornado==6.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # python-telegram-bot -transitions==0.8.9 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc -twilio==7.9.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -typed-ast==1.4.1 - # via astroid -typing-extensions==3.10.0.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp - # async-timeout - # gitpython - # importlib-metadata - # yarl -tzlocal==3.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # apscheduler -urllib3==1.26.18 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # botocore - # docker - # kubernetes - # python-etcd - # requests -vcert==0.7.4 ; sys_platform != "win32" - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -virtualenv==20.7.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -watchdog==0.10.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -websocket-client==0.40.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # docker - # kubernetes -wempy==0.2.1 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/common.in -werkzeug==2.2.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # moto -wrapt==1.11.1 - # via astroid -xmltodict==0.12.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # moto -yamllint==1.26.3 - # via - # -c requirements/static/ci/py3.7/linux.txt - # -r requirements/static/ci/linux.in -yamlordereddictloader==0.4.0 - # via - # -c requirements/static/ci/py3.7/linux.txt - # junos-eznc -yarl==1.7.2 - # via - # -c requirements/static/ci/py3.7/linux.txt - # aiohttp -zc.lockfile==1.4 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # cherrypy -zipp==3.5.0 - # via - # -c requirements/static/ci/../pkg/py3.7/linux.txt - # -c requirements/static/ci/py3.7/linux.txt - # importlib-metadata - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/requirements/static/ci/py3.8/lint.txt b/requirements/static/ci/py3.8/lint.txt index f230eca7800..114395d2fbe 100644 --- a/requirements/static/ci/py3.8/lint.txt +++ b/requirements/static/ci/py3.8/lint.txt @@ -25,7 +25,7 @@ asn1crypto==1.3.0 # -c requirements/static/ci/py3.8/linux.txt # certvalidator # oscrypto -astroid==2.3.3 +astroid==3.1.0 # via pylint async-timeout==4.0.2 # via @@ -149,6 +149,8 @@ cryptography==42.0.3 # paramiko # pyopenssl # vcert +dill==0.3.8 + # via pylint distlib==0.3.2 # via # -c requirements/static/ci/py3.8/linux.txt @@ -296,8 +298,6 @@ kubernetes==3.0.0 # via # -c requirements/static/ci/py3.8/linux.txt # -r requirements/static/ci/common.in -lazy-object-proxy==1.4.3 - # via astroid libnacl==1.7.1 ; sys_platform != "win32" and sys_platform != "darwin" # via # -c requirements/static/ci/py3.8/linux.txt @@ -332,8 +332,6 @@ mercurial==6.0.1 # via # -c requirements/static/ci/py3.8/linux.txt # -r requirements/static/ci/linux.in -modernize==0.5 - # via saltpylint more-itertools==5.0.0 # via # -c requirements/static/ci/../pkg/py3.8/linux.txt @@ -413,6 +411,7 @@ pathtools==0.1.2 platformdirs==2.2.0 # via # -c requirements/static/ci/py3.8/linux.txt + # pylint # virtualenv portend==2.4 # via @@ -433,8 +432,6 @@ pyasn1==0.4.8 # -c requirements/static/ci/py3.8/linux.txt # pyasn1-modules # rsa -pycodestyle==2.5.0 - # via saltpylint pycparser==2.17 # via # -c requirements/static/ci/../pkg/py3.8/linux.txt @@ -465,7 +462,7 @@ pyjwt==2.4.0 # via # -c requirements/static/ci/py3.8/linux.txt # twilio -pylint==2.4.4 +pylint==3.1.0 # via # -r requirements/static/ci/lint.in # saltpylint @@ -599,7 +596,7 @@ s3transfer==0.5.2 # via # -c requirements/static/ci/py3.8/linux.txt # boto3 -saltpylint==2023.8.3 +saltpylint==2024.2.5 # via -r requirements/static/ci/lint.in scp==0.13.2 # via @@ -621,7 +618,6 @@ six==1.16.0 # -c requirements/static/ci/../pkg/py3.8/linux.txt # -c requirements/static/ci/py3.8/linux.txt # apscheduler - # astroid # cassandra-driver # cheroot # etcd3-py @@ -687,6 +683,12 @@ toml==0.10.2 # -c requirements/static/ci/py3.8/linux.txt # -r requirements/static/ci/common.in # -r requirements/static/ci/lint.in +tomli==2.0.1 + # via + # -c requirements/static/ci/py3.8/linux.txt + # pylint +tomlkit==0.12.3 + # via pylint tornado==6.1 # via # -c requirements/static/ci/py3.8/linux.txt @@ -699,6 +701,11 @@ twilio==7.9.2 # via # -c requirements/static/ci/py3.8/linux.txt # -r requirements/static/ci/linux.in +typing-extensions==4.8.0 + # via + # -c requirements/static/ci/py3.8/linux.txt + # astroid + # pylint tzlocal==3.0 # via # -c requirements/static/ci/py3.8/linux.txt @@ -737,8 +744,6 @@ werkzeug==3.0.1 # via # -c requirements/static/ci/py3.8/linux.txt # moto -wrapt==1.11.1 - # via astroid xmltodict==0.12.0 # via # -c requirements/static/ci/py3.8/linux.txt diff --git a/requirements/static/ci/py3.9/lint.txt b/requirements/static/ci/py3.9/lint.txt index eac557ef05f..5c47a8a493e 100644 --- a/requirements/static/ci/py3.9/lint.txt +++ b/requirements/static/ci/py3.9/lint.txt @@ -25,7 +25,7 @@ asn1crypto==1.3.0 # -c requirements/static/ci/py3.9/linux.txt # certvalidator # oscrypto -astroid==2.3.3 +astroid==3.1.0 # via pylint async-timeout==4.0.2 # via @@ -145,6 +145,8 @@ cryptography==42.0.3 # paramiko # pyopenssl # vcert +dill==0.3.8 + # via pylint distlib==0.3.2 # via # -c requirements/static/ci/py3.9/linux.txt @@ -292,8 +294,6 @@ kubernetes==3.0.0 # via # -c requirements/static/ci/py3.9/linux.txt # -r requirements/static/ci/common.in -lazy-object-proxy==1.4.3 - # via astroid libnacl==1.7.1 ; sys_platform != "win32" and sys_platform != "darwin" # via # -c requirements/static/ci/py3.9/linux.txt @@ -328,8 +328,6 @@ mercurial==6.0.1 # via # -c requirements/static/ci/py3.9/linux.txt # -r requirements/static/ci/linux.in -modernize==0.5 - # via saltpylint more-itertools==5.0.0 # via # -c requirements/static/ci/../pkg/py3.9/linux.txt @@ -409,6 +407,7 @@ pathtools==0.1.2 platformdirs==2.2.0 # via # -c requirements/static/ci/py3.9/linux.txt + # pylint # virtualenv portend==2.4 # via @@ -429,8 +428,6 @@ pyasn1==0.4.8 # -c requirements/static/ci/py3.9/linux.txt # pyasn1-modules # rsa -pycodestyle==2.5.0 - # via saltpylint pycparser==2.21 ; python_version >= "3.9" # via # -c requirements/static/ci/../pkg/py3.9/linux.txt @@ -463,7 +460,7 @@ pyjwt==2.4.0 # via # -c requirements/static/ci/py3.9/linux.txt # twilio -pylint==2.4.4 +pylint==3.1.0 # via # -r requirements/static/ci/lint.in # saltpylint @@ -597,7 +594,7 @@ s3transfer==0.5.2 # via # -c requirements/static/ci/py3.9/linux.txt # boto3 -saltpylint==2023.8.3 +saltpylint==2024.2.5 # via -r requirements/static/ci/lint.in scp==0.13.2 # via @@ -619,7 +616,6 @@ six==1.16.0 # -c requirements/static/ci/../pkg/py3.9/linux.txt # -c requirements/static/ci/py3.9/linux.txt # apscheduler - # astroid # cassandra-driver # cheroot # etcd3-py @@ -685,6 +681,12 @@ toml==0.10.2 # -c requirements/static/ci/py3.9/linux.txt # -r requirements/static/ci/common.in # -r requirements/static/ci/lint.in +tomli==2.0.1 + # via + # -c requirements/static/ci/py3.9/linux.txt + # pylint +tomlkit==0.12.3 + # via pylint tornado==6.1 # via # -c requirements/static/ci/py3.9/linux.txt @@ -697,6 +699,11 @@ twilio==7.9.2 # via # -c requirements/static/ci/py3.9/linux.txt # -r requirements/static/ci/linux.in +typing-extensions==4.8.0 + # via + # -c requirements/static/ci/py3.9/linux.txt + # astroid + # pylint tzlocal==3.0 # via # -c requirements/static/ci/py3.9/linux.txt @@ -735,8 +742,6 @@ werkzeug==3.0.1 # via # -c requirements/static/ci/py3.9/linux.txt # moto -wrapt==1.11.1 - # via astroid xmltodict==0.12.0 # via # -c requirements/static/ci/py3.9/linux.txt diff --git a/salt/_logging/impl.py b/salt/_logging/impl.py index 2bcc27a0761..9ffa5320301 100644 --- a/salt/_logging/impl.py +++ b/salt/_logging/impl.py @@ -169,7 +169,7 @@ class SaltLoggingClass(LOGGING_LOGGER_CLASS, metaclass=LoggingMixinMeta): logging.getLogger(__name__) """ - instance = super().__new__(cls) + instance = super().__new__(cls) # pylint: disable=no-value-for-parameter try: max_logger_length = len( diff --git a/salt/auth/pki.py b/salt/auth/pki.py index f33e3ccf00c..1c9d6f205a2 100644 --- a/salt/auth/pki.py +++ b/salt/auth/pki.py @@ -84,11 +84,10 @@ def auth(username, password, **kwargs): if cert.verify(cacert.get_pubkey()): log.info("Successfully authenticated certificate: %s", pem) return True - else: - log.info("Failed to authenticate certificate: %s", pem) - return False + log.info("Failed to authenticate certificate: %s", pem) + return False - c = OpenSSL.crypto + c = OpenSSL.crypto # pylint: disable=used-before-assignment cert = c.load_certificate(c.FILETYPE_PEM, pem) with salt.utils.files.fopen(cacert_file) as f: @@ -101,7 +100,7 @@ def auth(username, password, **kwargs): cert_asn1 = c.dump_certificate(c.FILETYPE_ASN1, cert) # Decode the certificate - der = asn1.DerSequence() + der = asn1.DerSequence() # pylint: disable=used-before-assignment der.decode(cert_asn1) # The certificate has three parts: diff --git a/salt/channel/client.py b/salt/channel/client.py index 499041d0c73..8d43406728e 100644 --- a/salt/channel/client.py +++ b/salt/channel/client.py @@ -225,7 +225,7 @@ class AsyncReqChannel: if HAS_M2: aes = key.private_decrypt(ret["key"], RSA.pkcs1_oaep_padding) else: - cipher = PKCS1_OAEP.new(key) + cipher = PKCS1_OAEP.new(key) # pylint: disable=used-before-assignment aes = cipher.decrypt(ret["key"]) # Decrypt using the public key. diff --git a/salt/channel/server.py b/salt/channel/server.py index 4d7cd23fc29..e4eabd40076 100644 --- a/salt/channel/server.py +++ b/salt/channel/server.py @@ -206,7 +206,7 @@ class ReqServerChannel: if HAS_M2: pret["key"] = pub.public_encrypt(key, RSA.pkcs1_oaep_padding) else: - cipher = PKCS1_OAEP.new(pub) + cipher = PKCS1_OAEP.new(pub) # pylint: disable=used-before-assignment pret["key"] = cipher.encrypt(key) if ret is False: ret = {} diff --git a/salt/cli/batch.py b/salt/cli/batch.py index 8e1547c61d4..ca1f464a8d4 100644 --- a/salt/cli/batch.py +++ b/salt/cli/batch.py @@ -90,7 +90,10 @@ class Batch: """ Return the active number of minions to maintain """ - partition = lambda x: float(x) / 100.0 * len(self.minions) + + def partition(x): + return float(x) / 100.0 * len(self.minions) + try: if isinstance(self.opts["batch"], str) and "%" in self.opts["batch"]: res = partition(float(self.opts["batch"].strip("%"))) diff --git a/salt/cli/cp.py b/salt/cli/cp.py index 457be4b044e..42ebfd9d515 100644 --- a/salt/cli/cp.py +++ b/salt/cli/cp.py @@ -68,7 +68,7 @@ class SaltCP: except OSError as exc: if exc.errno == errno.ENOENT: # Path does not exist - sys.stderr.write("{} does not exist\n".format(path)) + sys.stderr.write(f"{path} does not exist\n") sys.exit(42) elif exc.errno in (errno.EINVAL, errno.ENOTDIR): # Path is a file (EINVAL on Windows, ENOTDIR otherwise) @@ -97,7 +97,7 @@ class SaltCP: Take a path and return the contents of the file as a string """ if not os.path.isfile(fn_): - err = "The referenced file, {} is not available.".format(fn_) + err = f"The referenced file, {fn_} is not available." sys.stderr.write(err + "\n") sys.exit(42) with salt.utils.files.fopen(fn_, "r") as fp_: @@ -211,12 +211,10 @@ class SaltCP: log.debug( "Copying %s to %starget '%s' as %s%s", fn_, - "{} ".format(selected_target_option) - if selected_target_option - else "", + f"{selected_target_option} " if selected_target_option else "", tgt, remote_path, - " (chunk #{})".format(index) if append else "", + f" (chunk #{index})" if append else "", ) args = [ tgt, @@ -261,11 +259,7 @@ class SaltCP: log.debug( "Creating empty dir %s on %starget '%s'", dirname, - "{} ".format( - selected_target_option - ) # pylint: disable=str-format-in-logging - if selected_target_option - else "", + f"{selected_target_option} " if selected_target_option else "", tgt, ) args = [tgt, "cp.recv_chunked", [remote_path, None], timeout] diff --git a/salt/client/__init__.py b/salt/client/__init__.py index ebfbea48e7a..cfda90d5782 100644 --- a/salt/client/__init__.py +++ b/salt/client/__init__.py @@ -8,7 +8,6 @@ The data structure needs to be: 'key': ''} """ - import logging # The components here are simple, and they need to be and stay simple, we @@ -1296,7 +1295,7 @@ class LocalClient: except KeyError as exc: # This is a safe pass. We're just using the try/except to # avoid having to deep-check for keys. - missing_key = exc.__str__().strip("'\"") + missing_key = str(exc).strip("'\"") if missing_key == "retcode": log.debug("retcode missing from client return") else: diff --git a/salt/client/ssh/__init__.py b/salt/client/ssh/__init__.py index e24c0b45344..a5f681569d1 100644 --- a/salt/client/ssh/__init__.py +++ b/salt/client/ssh/__init__.py @@ -559,7 +559,7 @@ class SSH(MultiprocessingStateMixin): try: retcode = int(retcode) except (TypeError, ValueError): - log.warning(f"Got an invalid retcode for host '{host}': '{retcode}'") + log.warning("Got an invalid retcode for host '%s': '%s'", host, retcode) retcode = 1 # This job is done, yield try: @@ -573,7 +573,9 @@ class SSH(MultiprocessingStateMixin): retcode = int(remote_retcode) except (TypeError, ValueError): log.warning( - f"Host '{host}' reported an invalid retcode: '{remote_retcode}'" + "Host '%s' reported an invalid retcode: '%s'", + host, + remote_retcode, ) retcode = max(retcode, 1) except (KeyError, TypeError): @@ -599,7 +601,7 @@ class SSH(MultiprocessingStateMixin): """ que = multiprocessing.Queue() running = {} - target_iter = self.targets.__iter__() + target_iter = iter(self.targets) returned = set() rets = set() init = False @@ -829,7 +831,7 @@ class SSH(MultiprocessingStateMixin): for ret, retcode in self.handle_ssh(): host = next(iter(ret)) if not isinstance(retcode, int): - log.warning(f"Host '{host}' returned an invalid retcode: {retcode}") + log.warning("Host '%s' returned an invalid retcode: %s", host, retcode) retcode = 1 final_exit = max(final_exit, retcode) @@ -1784,7 +1786,7 @@ def ssh_version(): ["ssh", "-V"], stdout=subprocess.PIPE, stderr=subprocess.PIPE ).communicate() try: - version_parts = ret[1].split(b",")[0].split(b"_")[1] + version_parts = ret[1].split(b",", maxsplit=1)[0].split(b"_")[1] parts = [] for part in version_parts: try: diff --git a/salt/client/ssh/ssh_py_shim.py b/salt/client/ssh/ssh_py_shim.py index 9b8f9e0f658..f0b697d0ac4 100644 --- a/salt/client/ssh/ssh_py_shim.py +++ b/salt/client/ssh/ssh_py_shim.py @@ -41,7 +41,6 @@ ARGS = None # The below line is where OPTIONS can be redefined with internal options # (rather than cli arguments) when the shim is bundled by # client.ssh.Single._cmd_str() -# pylint: disable=block-comment-should-start-with-cardinal-space #%%OPTS @@ -230,7 +229,9 @@ def get_executable(): Find executable which matches supported python version in the thin """ pymap = {} - with open(os.path.join(OPTIONS.saltdir, "supported-versions")) as _fp: + with open( + os.path.join(OPTIONS.saltdir, "supported-versions"), encoding="utf-8" + ) as _fp: for line in _fp.readlines(): ns, v_maj, v_min = line.strip().split(":") pymap[ns] = (int(v_maj), int(v_min)) @@ -314,7 +315,7 @@ def main(argv): # pylint: disable=W0613 ) ) need_deployment() - with open(code_checksum_path, "r") as vpo: + with open(code_checksum_path, "r", encoding="utf-8") as vpo: cur_code_cs = vpo.readline().strip() if cur_code_cs != OPTIONS.code_checksum: sys.stderr.write( @@ -330,7 +331,7 @@ def main(argv): # pylint: disable=W0613 sys.stderr.write('ERROR: thin is missing "{0}"\n'.format(salt_call_path)) need_deployment() - with open(os.path.join(OPTIONS.saltdir, "minion"), "w") as config: + with open(os.path.join(OPTIONS.saltdir, "minion"), "w", encoding="utf-8") as config: config.write(OPTIONS.config + "\n") if OPTIONS.ext_mods: ext_path = os.path.join(OPTIONS.saltdir, EXT_ARCHIVE) @@ -340,7 +341,7 @@ def main(argv): # pylint: disable=W0613 version_path = os.path.join(OPTIONS.saltdir, "ext_version") if not os.path.exists(version_path) or not os.path.isfile(version_path): need_ext() - with open(version_path, "r") as vpo: + with open(version_path, "r", encoding="utf-8") as vpo: cur_version = vpo.readline().strip() if cur_version != OPTIONS.ext_mods: need_ext() diff --git a/salt/client/ssh/wrapper/grains.py b/salt/client/ssh/wrapper/grains.py index bbacdb4ea4f..92446f4018e 100644 --- a/salt/client/ssh/wrapper/grains.py +++ b/salt/client/ssh/wrapper/grains.py @@ -23,21 +23,28 @@ def _serial_sanitizer(instr): return "{}{}".format(instr[:index], "X" * (length - index)) -_FQDN_SANITIZER = lambda x: "MINION.DOMAINNAME" -_HOSTNAME_SANITIZER = lambda x: "MINION" -_DOMAINNAME_SANITIZER = lambda x: "DOMAINNAME" +def _fqdn_sanitizer(x): + return "MINION.DOMAINNAME" + + +def _hostname_sanitizer(x): + return "MINION" + + +def _domainname_sanitizer(x): + return "DOMAINNAME" # A dictionary of grain -> function mappings for sanitizing grain output. This # is used when the 'sanitize' flag is given. _SANITIZERS = { "serialnumber": _serial_sanitizer, - "domain": _DOMAINNAME_SANITIZER, - "fqdn": _FQDN_SANITIZER, - "id": _FQDN_SANITIZER, - "host": _HOSTNAME_SANITIZER, - "localhost": _HOSTNAME_SANITIZER, - "nodename": _HOSTNAME_SANITIZER, + "domain": _domainname_sanitizer, + "fqdn": _fqdn_sanitizer, + "id": _fqdn_sanitizer, + "host": _hostname_sanitizer, + "localhost": _hostname_sanitizer, + "nodename": _hostname_sanitizer, } diff --git a/salt/client/ssh/wrapper/pillar.py b/salt/client/ssh/wrapper/pillar.py index bc1b625d5cb..f085771614c 100644 --- a/salt/client/ssh/wrapper/pillar.py +++ b/salt/client/ssh/wrapper/pillar.py @@ -12,7 +12,9 @@ try: from collections.abc import Mapping except ImportError: # We still allow Py2 import because this could be executed in a machine with Py2. - from collections import Mapping # pylint: disable=no-name-in-module + from collections import ( # pylint: disable=no-name-in-module,deprecated-class + Mapping, + ) def get(key, default="", merge=False, delimiter=DEFAULT_TARGET_DELIM): diff --git a/salt/cloud/cli.py b/salt/cloud/cli.py index f458e975c63..c633dce3b77 100644 --- a/salt/cloud/cli.py +++ b/salt/cloud/cli.py @@ -174,11 +174,11 @@ class SaltCloud(salt.utils.parsers.SaltCloudParser): msg = "The following virtual machines are set to be destroyed:\n" names = set() for alias, drivers in matching.items(): - msg += " {}:\n".format(alias) + msg += f" {alias}:\n" for driver, vms in drivers.items(): - msg += " {}:\n".format(driver) + msg += f" {driver}:\n" for name in vms: - msg += " {}\n".format(name) + msg += f" {name}\n" names.add(name) try: if self.print_confirm(msg): @@ -212,7 +212,7 @@ class SaltCloud(salt.utils.parsers.SaltCloudParser): key, value = name.split("=", 1) kwargs[key] = value else: - msg += " {}\n".format(name) + msg += f" {name}\n" machines.append(name) names = machines @@ -255,7 +255,7 @@ class SaltCloud(salt.utils.parsers.SaltCloudParser): elif self.options.set_password: username = self.credential_username - provider_name = "salt.cloud.provider.{}".format(self.credential_provider) + provider_name = f"salt.cloud.provider.{self.credential_provider}" # TODO: check if provider is configured # set the password salt.utils.cloud.store_password_in_keyring(provider_name, username) @@ -275,7 +275,7 @@ class SaltCloud(salt.utils.parsers.SaltCloudParser): # display profile errors msg += "Found the following errors:\n" for profile_name, error in dmap["errors"].items(): - msg += " {}: {}\n".format(profile_name, error) + msg += f" {profile_name}: {error}\n" sys.stderr.write(msg) sys.stderr.flush() @@ -283,17 +283,17 @@ class SaltCloud(salt.utils.parsers.SaltCloudParser): if "existing" in dmap: msg += "The following virtual machines already exist:\n" for name in dmap["existing"]: - msg += " {}\n".format(name) + msg += f" {name}\n" if dmap["create"]: msg += "The following virtual machines are set to be created:\n" for name in dmap["create"]: - msg += " {}\n".format(name) + msg += f" {name}\n" if "destroy" in dmap: msg += "The following virtual machines are set to be destroyed:\n" for name in dmap["destroy"]: - msg += " {}\n".format(name) + msg += f" {name}\n" if not dmap["create"] and not dmap.get("destroy", None): if not dmap.get("existing", None): @@ -382,19 +382,17 @@ class SaltCloud(salt.utils.parsers.SaltCloudParser): # This is a salt cloud system exit if exc.exit_code > 0: # the exit code is bigger than 0, it's an error - msg = "Error: {}".format(msg) + msg = f"Error: {msg}" self.exit(exc.exit_code, msg.format(exc).rstrip() + "\n") # It's not a system exit but it's an error we can # handle self.error(msg.format(exc)) # This is a generic exception, log it, include traceback if # debug logging is enabled and exit. - # pylint: disable=str-format-in-logging log.error( msg.format(exc), # Show the traceback if the debug logging level is # enabled exc_info_on_loglevel=logging.DEBUG, ) - # pylint: enable=str-format-in-logging self.exit(salt.defaults.exitcodes.EX_GENERIC) diff --git a/salt/cloud/clouds/aliyun.py b/salt/cloud/clouds/aliyun.py index 9b1b318885b..572f0cfde96 100644 --- a/salt/cloud/clouds/aliyun.py +++ b/salt/cloud/clouds/aliyun.py @@ -798,7 +798,7 @@ def query(params=None): signature = _compute_signature(parameters, access_key_secret) parameters["Signature"] = signature - request = requests.get(path, params=parameters, verify=True) + request = requests.get(path, params=parameters, verify=True, timeout=120) if request.status_code != 200: raise SaltCloudSystemExit( "An error occurred while querying aliyun ECS. HTTP Code: {} " diff --git a/salt/cloud/clouds/clc.py b/salt/cloud/clouds/clc.py index c111c49a481..88ed72b1295 100644 --- a/salt/cloud/clouds/clc.py +++ b/salt/cloud/clouds/clc.py @@ -308,7 +308,7 @@ def get_build_status(req_id, nodename): counter = 0 req_id = str(req_id) while counter < 10: - queue = clc.v1.Blueprint.GetStatus(request_id=(req_id)) + queue = clc.v1.Blueprint.GetStatus(request_id=req_id) if queue["PercentComplete"] == 100: server_name = queue["Servers"][0] creds = get_creds() diff --git a/salt/cloud/clouds/digitalocean.py b/salt/cloud/clouds/digitalocean.py index 8c3cf54f05f..7f843f22ab1 100644 --- a/salt/cloud/clouds/digitalocean.py +++ b/salt/cloud/clouds/digitalocean.py @@ -474,9 +474,14 @@ def create(vm_): dns_hostname, dns_domain, ) - __add_dns_addr__ = lambda t, d: post_dns_record( - dns_domain=dns_domain, name=dns_hostname, record_type=t, record_data=d - ) + + def __add_dns_addr__(t, d): + return post_dns_record( + dns_domain=dns_domain, + name=dns_hostname, + record_type=t, + record_data=d, + ) log.debug("create_dns_record: %s", __add_dns_addr__) else: @@ -639,6 +644,7 @@ def query( "Authorization": "Bearer " + personal_access_token, "Content-Type": "application/json", }, + timeout=120, ) if request.status_code > 299: raise SaltCloudSystemExit( diff --git a/salt/cloud/clouds/ec2.py b/salt/cloud/clouds/ec2.py index 3c8ea286bce..571b0c04674 100644 --- a/salt/cloud/clouds/ec2.py +++ b/salt/cloud/clouds/ec2.py @@ -403,7 +403,7 @@ def query( log.trace("EC2 Request Parameters: %s", params_with_headers) try: result = requests.get( - requesturl, headers=headers, params=params_with_headers + requesturl, headers=headers, params=params_with_headers, timeout=120 ) log.debug( "EC2 Response Status Code: %s", @@ -1198,9 +1198,9 @@ def get_imageid(vm_): "Filter.0.Value.0": image, } # Query AWS, sort by 'creationDate' and get the last imageId - _t = lambda x: datetime.datetime.strptime( - x["creationDate"], "%Y-%m-%dT%H:%M:%S.%fZ" - ) + def _t(x): + return datetime.datetime.strptime(x["creationDate"], "%Y-%m-%dT%H:%M:%S.%fZ") + image_id = sorted( aws.query( params, diff --git a/salt/cloud/clouds/joyent.py b/salt/cloud/clouds/joyent.py index 58b853b3f00..cd68508f43a 100644 --- a/salt/cloud/clouds/joyent.py +++ b/salt/cloud/clouds/joyent.py @@ -1168,8 +1168,8 @@ def query(action=None, command=None, args=None, method="GET", location=None, dat digest = md.final() signed = rsa_key.sign(digest, algo="sha256") else: - rsa_ = PKCS1_v1_5.new(rsa_key) - hash_ = SHA256.new() + rsa_ = PKCS1_v1_5.new(rsa_key) # pylint: disable=used-before-assignment + hash_ = SHA256.new() # pylint: disable=used-before-assignment hash_.update(timestamp.encode(__salt_system_encoding__)) signed = rsa_.sign(hash_) signed = base64.b64encode(signed) diff --git a/salt/cloud/clouds/linode.py b/salt/cloud/clouds/linode.py index 72c985f148e..99850b3936a 100644 --- a/salt/cloud/clouds/linode.py +++ b/salt/cloud/clouds/linode.py @@ -530,7 +530,9 @@ class LinodeAPIv4(LinodeAPI): attempt = 0 while True: try: - result = requests.request(method, url, json=data, headers=headers) + result = requests.request( + method, url, json=data, headers=headers, timeout=120 + ) log.debug("Linode API response status code: %d", result.status_code) log.trace("Linode API response body: %s", result.text) @@ -1092,7 +1094,9 @@ class LinodeAPIv4(LinodeAPI): "entity.type": entity, } last_event = None - condition = lambda event: self._check_event_status(event, status) + + def condition(event): + return self._check_event_status(event, status) while True: if last_event is not None: @@ -1965,8 +1969,8 @@ class LinodeAPIv3(LinodeAPI): for key, val in ips.items(): if key == linode_id: - this_node["private_ips"] = val["private_ips"] - this_node["public_ips"] = val["public_ips"] + this_node["private_ips"] = val[1] + this_node["public_ips"] = val[0] if full: this_node["extra"] = node diff --git a/salt/cloud/clouds/proxmox.py b/salt/cloud/clouds/proxmox.py index e293ad4067f..61340f0928f 100644 --- a/salt/cloud/clouds/proxmox.py +++ b/salt/cloud/clouds/proxmox.py @@ -137,7 +137,9 @@ def _authenticate(): connect_data = {"username": username, "password": passwd} full_url = "https://{}:{}/api2/json/access/ticket".format(url, port) - response = requests.post(full_url, verify=verify_ssl, data=connect_data) + response = requests.post( + full_url, verify=verify_ssl, data=connect_data, timeout=120 + ) response.raise_for_status() returned_data = response.json() @@ -171,6 +173,7 @@ def query(conn_type, option, post_data=None): data=post_data, cookies=ticket, headers=httpheaders, + timeout=120, ) elif conn_type == "put": httpheaders["CSRFPreventionToken"] = csrf @@ -180,6 +183,7 @@ def query(conn_type, option, post_data=None): data=post_data, cookies=ticket, headers=httpheaders, + timeout=120, ) elif conn_type == "delete": httpheaders["CSRFPreventionToken"] = csrf @@ -189,9 +193,12 @@ def query(conn_type, option, post_data=None): data=post_data, cookies=ticket, headers=httpheaders, + timeout=120, ) elif conn_type == "get": - response = requests.get(full_url, verify=verify_ssl, cookies=ticket) + response = requests.get( + full_url, verify=verify_ssl, cookies=ticket, timeout=120 + ) try: response.raise_for_status() @@ -862,7 +869,7 @@ def _import_api(): """ global api full_url = "https://{}:{}/pve-docs/api-viewer/apidoc.js".format(url, port) - returned_data = requests.get(full_url, verify=verify_ssl) + returned_data = requests.get(full_url, verify=verify_ssl, timeout=120) re_filter = re.compile(" (?:pveapi|apiSchema) = (.*)^;", re.DOTALL | re.MULTILINE) api_json = re_filter.findall(returned_data.text)[0] diff --git a/salt/cloud/clouds/qingcloud.py b/salt/cloud/clouds/qingcloud.py index b684f6bc9d8..fd2f179b758 100644 --- a/salt/cloud/clouds/qingcloud.py +++ b/salt/cloud/clouds/qingcloud.py @@ -179,7 +179,7 @@ def query(params=None): # print('parameters:') # pprint.pprint(real_parameters) - request = requests.get(path, params=real_parameters, verify=verify_ssl) + request = requests.get(path, params=real_parameters, verify=verify_ssl, timeout=120) # print('url:') # print(request.url) @@ -439,7 +439,7 @@ def _get_size(vm_): if not vm_size: raise SaltCloudNotFound("No size specified for this instance.") - if vm_size in sizes.keys(): + if vm_size in sizes: return vm_size raise SaltCloudNotFound( diff --git a/salt/cloud/clouds/vmware.py b/salt/cloud/clouds/vmware.py index 68fa1c821ab..72dcac96c20 100644 --- a/salt/cloud/clouds/vmware.py +++ b/salt/cloud/clouds/vmware.py @@ -1628,7 +1628,7 @@ def _get_snapshots(snapshot_list, current_snapshot=None, parent_snapshot_path="" snapshots[snapshot_path] = { "name": snapshot.name, "description": snapshot.description, - "created": str(snapshot.createTime).split(".")[0], + "created": str(snapshot.createTime).split(".", maxsplit=1)[0], "state": snapshot.state, "path": snapshot_path, } diff --git a/salt/config/schemas/common.py b/salt/config/schemas/common.py index f8d164abfed..9105ed39266 100644 --- a/salt/config/schemas/common.py +++ b/salt/config/schemas/common.py @@ -47,7 +47,7 @@ class MinionDefaultInclude(DefaultIncludeConfig): class MasterDefaultInclude(DefaultIncludeConfig): __target__ = "master" - __confd_directory = "master.d" + __confd_directory = "master.d" # pylint: disable=unused-private-member class IncludeConfig(Schema): diff --git a/salt/engines/slack.py b/salt/engines/slack.py index 969a6bcd1f2..b6c868c0dbb 100644 --- a/salt/engines/slack.py +++ b/salt/engines/slack.py @@ -890,8 +890,6 @@ class SlackClient: if cmd in runner_functions: runner = salt.runner.RunnerClient(__opts__) log.debug("Command %s will run via runner_functions", cmd) - # pylint is tripping - # pylint: disable=missing-whitespace-after-comma job_id_dict = runner.asynchronous(cmd, {"arg": args, "kwarg": kwargs}) job_id = job_id_dict["jid"] diff --git a/salt/engines/slack_bolt_engine.py b/salt/engines/slack_bolt_engine.py index 75eb0909e48..ca4f1791371 100644 --- a/salt/engines/slack_bolt_engine.py +++ b/salt/engines/slack_bolt_engine.py @@ -995,8 +995,6 @@ class SlackClient: if cmd in runner_functions: runner = salt.runner.RunnerClient(__opts__) log.debug("Command %s will run via runner_functions", cmd) - # pylint is tripping - # pylint: disable=missing-whitespace-after-comma job_id_dict = runner.asynchronous(cmd, {"arg": args, "kwarg": kwargs}) job_id = job_id_dict["jid"] diff --git a/salt/ext/backports_abc.py b/salt/ext/backports_abc.py index da4cb329832..64669416f3e 100644 --- a/salt/ext/backports_abc.py +++ b/salt/ext/backports_abc.py @@ -87,7 +87,7 @@ def mk_gen(): return True return NotImplemented - generator = type((lambda: (yield))()) + generator = type((lambda: (yield))()) # pylint: disable=unnecessary-direct-lambda-call Generator.register(generator) return Generator diff --git a/salt/ext/ipaddress.py b/salt/ext/ipaddress.py index 9ce8ba83d88..f1ee6bcaf38 100644 --- a/salt/ext/ipaddress.py +++ b/salt/ext/ipaddress.py @@ -2162,8 +2162,7 @@ class IPv6Interface(IPv6Address): return x def __str__(self): - return '%s/%d' % (super().__str__(), - self._prefixlen) + return '%s/%d' % (super(), self._prefixlen) def __eq__(self, other): address_equal = IPv6Address.__eq__(self, other) diff --git a/salt/ext/tornado/platform/auto.pyi b/salt/ext/tornado/platform/auto.pyi index a1c97228a43..03eb7d1bf20 100644 --- a/salt/ext/tornado/platform/auto.pyi +++ b/salt/ext/tornado/platform/auto.pyi @@ -1,4 +1,4 @@ # auto.py is full of patterns mypy doesn't like, so for type checking # purposes we replace it with interface.py. -from .interface import * +from .interface import * # pylint: disable=unused-wildcard-import,wildcard-import diff --git a/salt/fileserver/s3fs.py b/salt/fileserver/s3fs.py index d013ea3b193..f946eb2019b 100644 --- a/salt/fileserver/s3fs.py +++ b/salt/fileserver/s3fs.py @@ -726,7 +726,7 @@ def _get_file_from_s3(metadata, saltenv, bucket_name, path, cached_file_path): if cached_md5 == file_md5: return else: - log.info(f"found different hash for file {path}, updating...") + log.info("found different hash for file %s, updating...", path) else: cached_file_stat = os.stat(cached_file_path) cached_file_size = cached_file_stat.st_size @@ -762,6 +762,7 @@ def _get_file_from_s3(metadata, saltenv, bucket_name, path, cached_file_path): https_enable=https_enable, ) if ret is not None: + s3_file_mtime = s3_file_size = None for header_name, header_value in ret["headers"].items(): name = header_name.strip() value = header_value.strip() @@ -771,9 +772,8 @@ def _get_file_from_s3(metadata, saltenv, bucket_name, path, cached_file_path): ) elif str(name).lower() == "content-length": s3_file_size = int(value) - if ( - cached_file_size == s3_file_size - and cached_file_mtime > s3_file_mtime + if (s3_file_size and cached_file_size == s3_file_size) and ( + s3_file_mtime and cached_file_mtime > s3_file_mtime ): log.info( "%s - %s : %s skipped download since cached file size " diff --git a/salt/grains/core.py b/salt/grains/core.py index df53ccddd45..2edbcde420b 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -2910,8 +2910,8 @@ def ip_fqdn(): if not ret["ipv" + ipv_num]: ret[key] = [] else: + start_time = datetime.datetime.utcnow() try: - start_time = datetime.datetime.utcnow() info = socket.getaddrinfo(_fqdn, None, socket_type) ret[key] = list({item[4][0] for item in info}) except (OSError, UnicodeError): diff --git a/salt/loader/lazy.py b/salt/loader/lazy.py index 8198b4f62e9..5ad3c6c6d0b 100644 --- a/salt/loader/lazy.py +++ b/salt/loader/lazy.py @@ -15,7 +15,7 @@ import time import traceback import types from collections.abc import MutableMapping -from zipimport import zipimporter +from zipimport import zipimporter # pylint: disable=no-name-in-module import salt.config import salt.defaults.events diff --git a/salt/master.py b/salt/master.py index e91ab24e2bb..2dbf519d1dd 100644 --- a/salt/master.py +++ b/salt/master.py @@ -769,7 +769,9 @@ class Master(SMaster): mod = ".".join(proc.split(".")[:-1]) cls = proc.split(".")[-1] _tmp = __import__(mod, globals(), locals(), [cls], -1) - cls = _tmp.__getattribute__(cls) + cls = _tmp.__getattribute__( # pylint: disable=unnecessary-dunder-call + cls + ) name = "ExtProcess({})".format(cls.__qualname__) self.process_manager.add_process(cls, args=(self.opts,), name=name) except Exception: # pylint: disable=broad-except diff --git a/salt/modules/aptpkg.py b/salt/modules/aptpkg.py index 58a6fa85f68..d143cdcee07 100644 --- a/salt/modules/aptpkg.py +++ b/salt/modules/aptpkg.py @@ -239,7 +239,7 @@ if not HAS_APT: opts = _get_opts(self.line) self.architectures.extend(opts["arch"]["value"]) self.signedby = opts["signedby"]["value"] - for opt in opts.keys(): + for opt in opts: opt = opts[opt]["full"] if opt: try: @@ -1609,9 +1609,11 @@ def _get_upgradable(dist_upgrade=True, **kwargs): # rexp parses lines that look like the following: # Conf libxfont1 (1:1.4.5-1 Debian:testing [i386]) - rexp = re.compile("(?m)^Conf " "([^ ]+) " r"\(([^ ]+)") # Package name # Version + rexp = re.compile(r"(?m)^Conf ([^ ]+) \(([^ ]+)") # Package name # Version keys = ["name", "version"] - _get = lambda l, k: l[keys.index(k)] + + def _get(line, k): + return line[keys.index(k)] upgrades = rexp.findall(out) @@ -1685,7 +1687,10 @@ def version_cmp(pkg1, pkg2, ignore_epoch=False, **kwargs): salt '*' pkg.version_cmp '0.2.4-0ubuntu1' '0.2.4.1-0ubuntu1' """ - normalize = lambda x: str(x).split(":", 1)[-1] if ignore_epoch else str(x) + + def normalize(x): + return str(x).split(":", 1)[-1] if ignore_epoch else str(x) + # both apt_pkg.version_compare and _cmd_quote need string arguments. pkg1 = normalize(pkg1) pkg2 = normalize(pkg2) diff --git a/salt/modules/archive.py b/salt/modules/archive.py index 3f91cd9cefe..e7be041bc66 100644 --- a/salt/modules/archive.py +++ b/salt/modules/archive.py @@ -380,7 +380,7 @@ def list_( dirs, files, links = func(name, cached, *args) except OSError as exc: raise CommandExecutionError( - "Failed to list contents of {}: {}".format(name, exc.__str__()) + "Failed to list contents of {}: {}".format(name, exc) ) except CommandExecutionError as exc: raise @@ -395,9 +395,7 @@ def list_( log.debug("Cleaned cached archive %s", cached) except OSError as exc: if exc.errno != errno.ENOENT: - log.warning( - "Failed to clean cached archive %s: %s", cached, exc.__str__() - ) + log.warning("Failed to clean cached archive %s: %s", cached, exc) if strip_components: for item in (dirs, files, links): @@ -796,8 +794,8 @@ def zip_(zip_file, sources, template=None, cwd=None, runas=None, zip64=False): os.setegid(uinfo["gid"]) os.seteuid(uinfo["uid"]) + exc = None try: - exc = None archived_files = [] with contextlib.closing( zipfile.ZipFile(zip_file, "w", zipfile.ZIP_DEFLATED, zip64) @@ -1203,7 +1201,7 @@ def is_encrypted(name, clean=False, saltenv="base", source_hash=None, use_etag=F "{} is not a ZIP file".format(name), info=archive_info ) except Exception as exc: # pylint: disable=broad-except - raise CommandExecutionError(exc.__str__(), info=archive_info) + raise CommandExecutionError(exc, info=archive_info) else: ret = False @@ -1213,9 +1211,7 @@ def is_encrypted(name, clean=False, saltenv="base", source_hash=None, use_etag=F log.debug("Cleaned cached archive %s", cached) except OSError as exc: if exc.errno != errno.ENOENT: - log.warning( - "Failed to clean cached archive %s: %s", cached, exc.__str__() - ) + log.warning("Failed to clean cached archive %s: %s", cached, exc) return ret diff --git a/salt/modules/boto3_route53.py b/salt/modules/boto3_route53.py index 32c971356c2..88a9b1b2cfc 100644 --- a/salt/modules/boto3_route53.py +++ b/salt/modules/boto3_route53.py @@ -946,7 +946,7 @@ def _aws_decode(x): if "\\" in x: return x.decode("unicode_escape") - if type(x) == bytes: + if isinstance(x, bytes): return x.decode("idna") return x diff --git a/salt/modules/boto3_sns.py b/salt/modules/boto3_sns.py index 65ab6283f51..46026693b54 100644 --- a/salt/modules/boto3_sns.py +++ b/salt/modules/boto3_sns.py @@ -137,7 +137,7 @@ def topic_exists(name, region=None, key=None, keyid=None, profile=None): salt myminion boto3_sns.topic_exists mytopic region=us-east-1 """ topics = list_topics(region=region, key=key, keyid=keyid, profile=profile) - return name in list(topics.values() + topics.keys()) + return name in list(topics.values()) + list(topics) def create_topic(Name, region=None, key=None, keyid=None, profile=None): diff --git a/salt/modules/btrfs.py b/salt/modules/btrfs.py index 4b02eb21afa..6adf421009b 100644 --- a/salt/modules/btrfs.py +++ b/salt/modules/btrfs.py @@ -223,7 +223,10 @@ def _usage_specific(raw): """ Parse usage/specific. """ - get_key = lambda val: dict([tuple(val.split(":"))]) + + def get_key(val): + return dict([tuple(val.split(":"))]) + raw = raw.split("\n") section, size, used = raw[0].split(" ") section = section.replace(",", "_").replace(":", "").lower() diff --git a/salt/modules/consul.py b/salt/modules/consul.py index 205cfb202bd..dfcf84c0ab8 100644 --- a/salt/modules/consul.py +++ b/salt/modules/consul.py @@ -75,7 +75,7 @@ def _query( data = None else: if data is not None: - if type(data) != str: + if not isinstance(data, str): data = salt.utils.json.dumps(data) else: data = salt.utils.json.dumps({}) diff --git a/salt/modules/cp.py b/salt/modules/cp.py index 64666aefa5d..07554808386 100644 --- a/salt/modules/cp.py +++ b/salt/modules/cp.py @@ -115,7 +115,7 @@ def recv_chunked(dest, chunk, append=False, compressed=True, mode=None): if os.path.isfile(dest): return "Path exists and is a file" else: - return _error(exc.__str__()) + return _error(str(exc)) return True chunk = base64.b64decode(chunk) @@ -126,12 +126,12 @@ def recv_chunked(dest, chunk, append=False, compressed=True, mode=None): except OSError as exc: if exc.errno != errno.ENOENT: # Parent dir does not exist, we need to create it - return _error(exc.__str__()) + return _error(str(exc)) try: os.makedirs(os.path.dirname(dest)) except OSError as makedirs_exc: # Failed to make directory - return _error(makedirs_exc.__str__()) + return _error(str(makedirs_exc)) fh_ = salt.utils.files.fopen(dest, open_mode) # pylint: disable=W8470 try: @@ -139,7 +139,7 @@ def recv_chunked(dest, chunk, append=False, compressed=True, mode=None): fh_.write(salt.utils.gzip_util.uncompress(chunk) if compressed else chunk) except OSError as exc: # Write failed - return _error(exc.__str__()) + return _error(str(exc)) else: # Write successful if not append and mode is not None: @@ -149,7 +149,7 @@ def recv_chunked(dest, chunk, append=False, compressed=True, mode=None): try: os.chmod(dest, mode) except OSError: - return _error(exc.__str__()) + return _error(str(exc)) return True finally: try: diff --git a/salt/modules/cryptdev.py b/salt/modules/cryptdev.py index 40c28d17f10..ec195245ccb 100644 --- a/salt/modules/cryptdev.py +++ b/salt/modules/cryptdev.py @@ -263,7 +263,10 @@ def set_crypttab( criteria = entry.pick(match_on) except KeyError: - filterFn = lambda key: key not in _crypttab_entry.crypttab_keys + + def filterFn(key): + return key not in _crypttab_entry.crypttab_keys + invalid_keys = filter(filterFn, match_on) msg = 'Unrecognized keys in match_on: "{}"'.format(invalid_keys) diff --git a/salt/modules/csf.py b/salt/modules/csf.py index 1ab12cab941..63b3cb01ba6 100644 --- a/salt/modules/csf.py +++ b/salt/modules/csf.py @@ -29,7 +29,7 @@ def _temp_exists(method, ip): """ _type = method.replace("temp", "").upper() cmd = ( - "csf -t | awk -v code=1 -v type=_type -v ip=ip '$1==type && $2==ip {{code=0}}" + "csf -t | awk -v code=1 -v type={_type} -v ip={ip} '$1==type && $2==ip {{code=0}}" " END {{exit code}}'".format(_type=_type, ip=ip) ) exists = __salt__["cmd.run_all"](cmd) diff --git a/salt/modules/datadog_api.py b/salt/modules/datadog_api.py index 57ce01953f6..7a18f903b45 100644 --- a/salt/modules/datadog_api.py +++ b/salt/modules/datadog_api.py @@ -157,7 +157,9 @@ def cancel_downtime(api_key=None, app_key=None, scope=None, id=None): elif scope: params = {"api_key": api_key, "application_key": app_key, "scope": scope} response = requests.post( - "https://app.datadoghq.com/api/v1/downtime/cancel/by_scope", params=params + "https://app.datadoghq.com/api/v1/downtime/cancel/by_scope", + params=params, + timeout=120, ) if response.status_code == 200: ret["result"] = True diff --git a/salt/modules/dig.py b/salt/modules/dig.py index ea0463075d4..a78e4875ded 100644 --- a/salt/modules/dig.py +++ b/salt/modules/dig.py @@ -314,7 +314,7 @@ def MX(domain, resolve=False, nameserver=None): stdout = [x.split() for x in cmd["stdout"].split("\n")] if resolve: - return [(lambda x: [x[0], A(x[1], nameserver)[0]])(x) for x in stdout] + return [[x[0], A(x[1], nameserver)[0]] for x in stdout] return stdout diff --git a/salt/modules/disk.py b/salt/modules/disk.py index fb78906b18f..c7e5f905c07 100644 --- a/salt/modules/disk.py +++ b/salt/modules/disk.py @@ -49,7 +49,7 @@ def _parse_numbers(text): "Z": "10E21", "Y": "10E24", } - if text[-1] in postPrefixes.keys(): + if text[-1] in postPrefixes: v = decimal.Decimal(text[:-1]) v = v * decimal.Decimal(postPrefixes[text[-1]]) return v diff --git a/salt/modules/dockermod.py b/salt/modules/dockermod.py index f9ffd2dda9e..49036f0f756 100644 --- a/salt/modules/dockermod.py +++ b/salt/modules/dockermod.py @@ -399,7 +399,6 @@ def _get_client(timeout=NOTSET, **kwargs): docker_machine_tls["ClientKeyPath"], ), ca_cert=docker_machine_tls["CaCertPath"], - assert_hostname=False, verify=True, ) except Exception as exc: # pylint: disable=broad-except @@ -690,9 +689,9 @@ def _client_wrapper(attr, *args, **kwargs): raise except docker.errors.DockerException as exc: # More general docker exception (catches InvalidVersion, etc.) - raise CommandExecutionError(exc.__str__()) + raise CommandExecutionError(str(exc)) except Exception as exc: # pylint: disable=broad-except - err = exc.__str__() + err = str(exc) else: return ret @@ -1333,7 +1332,10 @@ def compare_networks(first, second, ignore="Name,Id,Created,Containers"): if bool(subval1) is bool(subval2) is False: continue elif subkey == "Config": - kvsort = lambda x: (list(x.keys()), list(x.values())) + + def kvsort(x): + return (list(x.keys()), list(x.values())) + config1 = sorted(val1["Config"], key=kvsort) config2 = sorted(val2.get("Config", []), key=kvsort) if config1 != config2: @@ -3312,7 +3314,7 @@ def create( except CommandExecutionError as exc: raise CommandExecutionError( "Failed to start container after creation", - info={"response": response, "error": exc.__str__()}, + info={"response": response, "error": str(exc)}, ) else: response["Started"] = True @@ -3502,7 +3504,7 @@ def run_container( f"Failed to auto_remove container: {rm_exc}" ) # Raise original exception with additional info - raise CommandExecutionError(exc.__str__(), info=exc_info) + raise CommandExecutionError(str(exc), info=exc_info) # Start the container output = [] @@ -3554,7 +3556,7 @@ def run_container( # it to other_errors as a fallback. exc_info.setdefault("other_errors", []).append(exc.info) # Re-raise with all of the available additional info - raise CommandExecutionError(exc.__str__(), info=exc_info) + raise CommandExecutionError(str(exc), info=exc_info) return ret @@ -4286,7 +4288,7 @@ def dangling(prune=False, force=False): try: ret.setdefault(image, {})["Removed"] = rmi(image, force=force) except Exception as exc: # pylint: disable=broad-except - err = exc.__str__() + err = str(exc) log.error(err) ret.setdefault(image, {})["Comment"] = err ret[image]["Removed"] = False @@ -4606,7 +4608,7 @@ def pull( except Exception as exc: # pylint: disable=broad-except raise CommandExecutionError( f"Unable to interpret API event: '{event}'", - info={"Error": exc.__str__()}, + info={"Error": str(exc)}, ) try: event_type = next(iter(event)) @@ -4700,7 +4702,7 @@ def push( except Exception as exc: # pylint: disable=broad-except raise CommandExecutionError( f"Unable to interpret API event: '{event}'", - info={"Error": exc.__str__()}, + info={"Error": str(exc)}, ) try: event_type = next(iter(event)) @@ -5496,7 +5498,7 @@ def disconnect_all_containers_from_network(network_id): disconnect_container_from_network(cname, network_id) ret.append(cname) except CommandExecutionError as exc: - msg = exc.__str__() + msg = str(exc) if "404" not in msg: # If 404 was in the error, then the container no longer exists, # so to avoid a race condition we won't consider 404 errors to diff --git a/salt/modules/ebuildpkg.py b/salt/modules/ebuildpkg.py index 0e8fd851066..1b268fa7476 100644 --- a/salt/modules/ebuildpkg.py +++ b/salt/modules/ebuildpkg.py @@ -148,9 +148,9 @@ def _process_emerge_err(stdout, stderr): if slot_conflicts: ret["slot conflicts"] = slot_conflicts - blocked = re.compile( - r"(?m)^\[blocks .+\] " r"([^ ]+/[^ ]+-[0-9]+[^ ]+)" r".*$" - ).findall(stdout) + blocked = re.compile(r"(?m)^\[blocks .+\] ([^ ]+/[^ ]+-[0-9]+[^ ]+).*$").findall( + stdout + ) unsatisfied = re.compile(r"Error: The above package list contains").findall(stderr) @@ -331,7 +331,9 @@ def _get_upgradable(backtrack=3): r".*$" ) keys = ["name", "version"] - _get = lambda l, k: l[keys.index(k)] + + def _get(line, k): + return line[keys.index(k)] upgrades = rexp.findall(out) diff --git a/salt/modules/file.py b/salt/modules/file.py index 69d7992f5ab..d65d3e9a15f 100644 --- a/salt/modules/file.py +++ b/salt/modules/file.py @@ -4027,7 +4027,7 @@ def readlink(path, canonicalize=False): except OSError as exc: if exc.errno == errno.EINVAL: raise CommandExecutionError("Not a symbolic link: {}".format(path)) - raise CommandExecutionError(exc.__str__()) + raise CommandExecutionError(str(exc)) def readdir(path): @@ -5927,7 +5927,7 @@ def get_diff( continue paths.append(cached_path) except MinionError as exc: - errors.append(salt.utils.stringutils.to_unicode(exc.__str__())) + errors.append(salt.utils.stringutils.to_unicode(str(exc))) continue if errors: diff --git a/salt/modules/freebsdjail.py b/salt/modules/freebsdjail.py index fc3c3ce04f3..1c2343195c7 100644 --- a/salt/modules/freebsdjail.py +++ b/salt/modules/freebsdjail.py @@ -38,7 +38,7 @@ def start(jail=""): salt '*' jail.start [] """ - cmd = "service jail onestart {}".format(jail) + cmd = f"service jail onestart {jail}" return not __salt__["cmd.retcode"](cmd) @@ -52,7 +52,7 @@ def stop(jail=""): salt '*' jail.stop [] """ - cmd = "service jail onestop {}".format(jail) + cmd = f"service jail onestop {jail}" return not __salt__["cmd.retcode"](cmd) @@ -66,7 +66,7 @@ def restart(jail=""): salt '*' jail.restart [] """ - cmd = "service jail onerestart {}".format(jail) + cmd = f"service jail onerestart {jail}" return not __salt__["cmd.retcode"](cmd) @@ -126,9 +126,7 @@ def show_config(jail): """ ret = {} if subprocess.call(["jls", "-nq", "-j", jail]) == 0: - jls = subprocess.check_output( - ["jls", "-nq", "-j", jail] - ) # pylint: disable=minimum-python-version + jls = subprocess.check_output(["jls", "-nq", "-j", jail]) jailopts = salt.utils.args.shlex_split(salt.utils.stringutils.to_unicode(jls)) for jailopt in jailopts: if "=" not in jailopt: @@ -145,7 +143,7 @@ def show_config(jail): line = salt.utils.stringutils.to_unicode(line) if not line.strip(): continue - if not line.startswith("jail_{}_".format(jail)): + if not line.startswith(f"jail_{jail}_"): continue key, value = line.split("=") ret[key.split("_", 2)[2]] = value.split('"')[1] diff --git a/salt/modules/git.py b/salt/modules/git.py index 62dd7028994..4af2e548de7 100644 --- a/salt/modules/git.py +++ b/salt/modules/git.py @@ -1067,7 +1067,7 @@ def clone( url, https_user, https_pass, https_only=True ) except ValueError as exc: - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) command = ["git"] + _format_git_opts(git_opts) command.append("clone") @@ -3044,7 +3044,7 @@ def ls_remote( remote, https_user, https_pass, https_only=True ) except ValueError as exc: - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) command = ["git"] + _format_git_opts(git_opts) command.append("ls-remote") command.extend(_format_opts(opts)) @@ -4051,7 +4051,7 @@ def remote_refs( ) ) except ValueError as exc: - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) if filter_: command.append(filter_) output = _git_run( @@ -4185,7 +4185,7 @@ def remote_set( url, https_user, https_pass, https_only=True ) except ValueError as exc: - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) command = ["git", "remote", "add", remote, url] _git_run( command, diff --git a/salt/modules/glassfish.py b/salt/modules/glassfish.py index 637264e7331..558db0809e5 100644 --- a/salt/modules/glassfish.py +++ b/salt/modules/glassfish.py @@ -126,6 +126,7 @@ def _api_get(path, server=None): auth=_get_auth(server["user"], server["password"]), headers=_get_headers(), verify=True, + timeout=120, ) return _api_response(response) @@ -141,6 +142,7 @@ def _api_post(path, data, server=None): headers=_get_headers(), data=salt.utils.json.dumps(data), verify=True, + timeout=120, ) return _api_response(response) @@ -156,6 +158,7 @@ def _api_delete(path, data, server=None): headers=_get_headers(), params=data, verify=True, + timeout=120, ) return _api_response(response) diff --git a/salt/modules/grains.py b/salt/modules/grains.py index 9c474a94a64..a7040e00b32 100644 --- a/salt/modules/grains.py +++ b/salt/modules/grains.py @@ -40,7 +40,9 @@ __outputter__ = { } # http://stackoverflow.com/a/12414913/127816 -_infinitedict = lambda: collections.defaultdict(_infinitedict) +def _infinitedict(): + return collections.defaultdict(_infinitedict) + _non_existent_key = "NonExistentValueMagicNumberSpK3hnufdHfeBUXCfqVK" @@ -54,21 +56,28 @@ def _serial_sanitizer(instr): return "{}{}".format(instr[:index], "X" * (length - index)) -_FQDN_SANITIZER = lambda x: "MINION.DOMAINNAME" -_HOSTNAME_SANITIZER = lambda x: "MINION" -_DOMAINNAME_SANITIZER = lambda x: "DOMAINNAME" +def _fqdn_sanitizer(x): + return "MINION.DOMAINNAME" + + +def _hostname_sanitizer(x): + return "MINION" + + +def _domainname_sanitizer(x): + return "DOMAINNAME" # A dictionary of grain -> function mappings for sanitizing grain output. This # is used when the 'sanitize' flag is given. _SANITIZERS = { "serialnumber": _serial_sanitizer, - "domain": _DOMAINNAME_SANITIZER, - "fqdn": _FQDN_SANITIZER, - "id": _FQDN_SANITIZER, - "host": _HOSTNAME_SANITIZER, - "localhost": _HOSTNAME_SANITIZER, - "nodename": _HOSTNAME_SANITIZER, + "domain": _domainname_sanitizer, + "fqdn": _fqdn_sanitizer, + "id": _fqdn_sanitizer, + "host": _hostname_sanitizer, + "localhost": _hostname_sanitizer, + "nodename": _hostname_sanitizer, } diff --git a/salt/modules/heat.py b/salt/modules/heat.py index 40540fe7cf0..c4ea3a5e9e1 100644 --- a/salt/modules/heat.py +++ b/salt/modules/heat.py @@ -241,9 +241,15 @@ def _poll_for_events( """ if action: stop_status = ("{}_FAILED".format(action), "{}_COMPLETE".format(action)) - stop_check = lambda a: a in stop_status + + def stop_check(a): + return a in stop_status + else: - stop_check = lambda a: a.endswith("_COMPLETE") or a.endswith("_FAILED") + + def stop_check(a): + return a.endswith("_COMPLETE") or a.endswith("_FAILED") + timeout_sec = timeout * 60 no_event_polls = 0 msg_template = "\n Stack %(name)s %(status)s \n" diff --git a/salt/modules/inspectlib/fsdb.py b/salt/modules/inspectlib/fsdb.py index b834b8f6783..787be0c0252 100644 --- a/salt/modules/inspectlib/fsdb.py +++ b/salt/modules/inspectlib/fsdb.py @@ -16,15 +16,12 @@ """ :codeauthor: Bo Maryniuk """ - - import csv import datetime import gzip import os import re import shutil -import sys from salt.utils.odict import OrderedDict @@ -182,12 +179,15 @@ class CsvDB: :param obj: :return: """ - get_type = lambda item: str(type(item)).split("'")[1] + + def get_type(item): + return str(type(item)).split("'")[1] + if not os.path.exists(os.path.join(self.db_path, obj._TABLE)): with gzip.open(os.path.join(self.db_path, obj._TABLE), "wt") as table_file: csv.writer(table_file).writerow( [ - "{col}:{type}".format(col=elm[0], type=get_type(elm[1])) + f"{elm[0]}:{get_type(elm[1])}" for elm in tuple(obj.__dict__.items()) ] ) @@ -270,7 +270,7 @@ class CsvDB: def _validate_object(self, obj): descr = self._tables.get(obj._TABLE) if descr is None: - raise Exception("Table {} not found.".format(obj._TABLE)) + raise Exception(f"Table {obj._TABLE} not found.") return obj._serialize(self._tables[obj._TABLE]) def __criteria(self, obj, matches=None, mt=None, lt=None, eq=None): @@ -333,14 +333,10 @@ class CsvDB: return objects def _to_type(self, data, type): - if type == "int": + if type in ("int", "long"): data = int(data) elif type == "float": data = float(data) - elif type == "long": - # pylint: disable=undefined-variable,incompatible-py3-code - data = sys.version_info[0] == 2 and long(data) or int(data) - # pylint: enable=undefined-variable,incompatible-py3-code else: data = str(data) return data diff --git a/salt/modules/inspectlib/query.py b/salt/modules/inspectlib/query.py index 54494d6a104..4ba5417a185 100644 --- a/salt/modules/inspectlib/query.py +++ b/salt/modules/inspectlib/query.py @@ -480,11 +480,13 @@ class Query(EnvLoader): raise InspectorQueryException( 'Unknown "{}" value for parameter "time"'.format(timeformat) ) - tfmt = ( - lambda param: timeformat == "tz" - and time.strftime("%b %d %Y %H:%M:%S", time.gmtime(param)) - or int(param) - ) + + def tfmt(param): + return ( + timeformat == "tz" + and time.strftime("%b %d %Y %H:%M:%S", time.gmtime(param)) + or int(param) + ) size_fmt = kwargs.get("size") if size_fmt is not None and size_fmt.lower() not in ["b", "kb", "mb", "gb"]: @@ -525,9 +527,9 @@ class Query(EnvLoader): pld_files.append(pld_data.path) else: pld_files[pld_data.path] = { - "uid": self._id_resolv(pld_data.uid, named=(owners == "id")), + "uid": self._id_resolv(pld_data.uid, named=owners == "id"), "gid": self._id_resolv( - pld_data.gid, named=(owners == "id"), uid=False + pld_data.gid, named=owners == "id", uid=False ), "size": _size_format(pld_data.p_size, fmt=size_fmt), "mode": oct(pld_data.mode), diff --git a/salt/modules/iptables.py b/salt/modules/iptables.py index 0b1177f1f54..986005b1f71 100644 --- a/salt/modules/iptables.py +++ b/salt/modules/iptables.py @@ -25,11 +25,11 @@ master config. The configuration is read using :py:func:`config.get - "-A FORWARD" """ +import argparse import logging import os import re import string -import sys import uuid import salt.utils.args @@ -73,7 +73,7 @@ def _has_option(option, family="ipv4"): _has_option('--wait') _has_option('--check', family='ipv6') """ - cmd = "{} --help".format(_iptables_cmd(family)) + cmd = f"{_iptables_cmd(family)} --help" if option in __salt__["cmd.run_stdout"](cmd, output_loglevel="quiet"): return True return False @@ -192,7 +192,7 @@ def version(family="ipv4"): IPv6: salt '*' iptables.version family=ipv6 """ - cmd = "{} --version".format(_iptables_cmd(family)) + cmd = f"{_iptables_cmd(family)} --version" out = __salt__["cmd.run_stdout"](cmd).split() return out[1] @@ -204,7 +204,7 @@ def build_rule( position="", full=None, family="ipv4", - **kwargs + **kwargs, ): """ Build a well-formatted iptables rule based on kwargs. A `table` and `chain` @@ -316,7 +316,7 @@ def build_rule( if not isinstance(match_value, list): match_value = match_value.split(",") for match in match_value: - rule.append("-m {}".format(match)) + rule.append(f"-m {match}") if "name_" in kwargs and match.strip() in ("pknock", "quota2", "recent"): rule.append("--name {}".format(kwargs["name_"])) del kwargs["name_"] @@ -335,7 +335,7 @@ def build_rule( if match_set.startswith("!") or match_set.startswith("not"): negative_match_set = "! " match_set = re.sub(bang_not_pat, "", match_set) - rule.append("-m set {}--match-set {}".format(negative_match_set, match_set)) + rule.append(f"-m set {negative_match_set}--match-set {match_set}") del kwargs["match-set"] if "connstate" in kwargs: @@ -382,7 +382,7 @@ def build_rule( else: dports = mp_value - rule.append("--{} {}".format(multiport_arg, dports)) + rule.append(f"--{multiport_arg} {dports}") del kwargs[multiport_arg] if "comment" in kwargs: @@ -526,11 +526,11 @@ def build_rule( if after_jump_argument in kwargs: value = kwargs[after_jump_argument] if value in (None, ""): # options without arguments - after_jump.append("--{}".format(after_jump_argument)) + after_jump.append(f"--{after_jump_argument}") elif any(ws_char in str(value) for ws_char in string.whitespace): - after_jump.append('--{} "{}"'.format(after_jump_argument, value)) + after_jump.append(f'--{after_jump_argument} "{value}"') else: - after_jump.append("--{} {}".format(after_jump_argument, value)) + after_jump.append(f"--{after_jump_argument} {value}") del kwargs[after_jump_argument] for key in kwargs: @@ -539,8 +539,8 @@ def build_rule( # the value in the kwargs, thus we need to fetch it after that has run value = kwargs[key] flag = "-" if len(key) == 1 else "--" - value = "" if value in (None, "") else " {}".format(value) - rule.append("{}{}{}{}".format(negation, flag, key, value)) + value = "" if value in (None, "") else f" {value}" + rule.append(f"{negation}{flag}{key}{value}") rule += after_jump @@ -704,7 +704,7 @@ def save(filename=None, family="ipv4"): parent_dir = os.path.dirname(filename) if not os.path.isdir(parent_dir): os.makedirs(parent_dir) - cmd = "{}-save".format(_iptables_cmd(family)) + cmd = f"{_iptables_cmd(family)}-save" ipt = __salt__["cmd.run_stdout"](cmd) # regex out the output if configured with filters @@ -743,26 +743,24 @@ def check(table="filter", chain=None, rule=None, family="ipv4"): ipt_cmd = _iptables_cmd(family) if _has_option("--check", family): - cmd = "{} -t {} -C {} {}".format(ipt_cmd, table, chain, rule) + cmd = f"{ipt_cmd} -t {table} -C {chain} {rule}" __salt__["cmd.run_stderr"](cmd, output_loglevel="quiet") return not __context__["retcode"] else: _chain_name = hex(uuid.getnode()) # Create temporary table - __salt__["cmd.run"]("{} -t {} -N {}".format(ipt_cmd, table, _chain_name)) - __salt__["cmd.run"]( - "{} -t {} -A {} {}".format(ipt_cmd, table, _chain_name, rule) - ) + __salt__["cmd.run"](f"{ipt_cmd} -t {table} -N {_chain_name}") + __salt__["cmd.run"](f"{ipt_cmd} -t {table} -A {_chain_name} {rule}") - out = __salt__["cmd.run_stdout"]("{}-save".format(ipt_cmd)) + out = __salt__["cmd.run_stdout"](f"{ipt_cmd}-save") # Clean up temporary table - __salt__["cmd.run"]("{} -t {} -F {}".format(ipt_cmd, table, _chain_name)) - __salt__["cmd.run"]("{} -t {} -X {}".format(ipt_cmd, table, _chain_name)) + __salt__["cmd.run"](f"{ipt_cmd} -t {table} -F {_chain_name}") + __salt__["cmd.run"](f"{ipt_cmd} -t {table} -X {_chain_name}") for i in out.splitlines(): - if i.startswith("-A {}".format(_chain_name)): + if i.startswith(f"-A {_chain_name}"): if i.replace(_chain_name, chain) in out.splitlines(): return True @@ -792,8 +790,8 @@ def check_chain(table="filter", chain=None, family="ipv4"): if not chain: return "Error: Chain needs to be specified" - cmd = "{}-save -t {}".format(_iptables_cmd(family), table) - out = __salt__["cmd.run_stdout"](cmd).find(":{} ".format(chain)) + cmd = f"{_iptables_cmd(family)}-save -t {table}" + out = __salt__["cmd.run_stdout"](cmd).find(f":{chain} ") if out != -1: out = True @@ -823,7 +821,7 @@ def new_chain(table="filter", chain=None, family="ipv4"): return "Error: Chain needs to be specified" wait = "--wait" if _has_option("--wait", family) else "" - cmd = "{} {} -t {} -N {}".format(_iptables_cmd(family), wait, table, chain) + cmd = f"{_iptables_cmd(family)} {wait} -t {table} -N {chain}" out = __salt__["cmd.run_stderr"](cmd) if not out: @@ -851,7 +849,7 @@ def delete_chain(table="filter", chain=None, family="ipv4"): return "Error: Chain needs to be specified" wait = "--wait" if _has_option("--wait", family) else "" - cmd = "{} {} -t {} -X {}".format(_iptables_cmd(family), wait, table, chain) + cmd = f"{_iptables_cmd(family)} {wait} -t {table} -X {chain}" out = __salt__["cmd.run_stderr"](cmd) if not out: @@ -889,7 +887,7 @@ def append(table="filter", chain=None, rule=None, family="ipv4"): returnCheck = check(table, chain, rule, family) if isinstance(returnCheck, bool) and returnCheck: return False - cmd = "{} {} -t {} -A {} {}".format(_iptables_cmd(family), wait, table, chain, rule) + cmd = f"{_iptables_cmd(family)} {wait} -t {table} -A {chain} {rule}" out = __salt__["cmd.run_stderr"](cmd) return not out @@ -977,7 +975,7 @@ def delete(table, chain=None, position=None, rule=None, family="ipv4"): rule = position wait = "--wait" if _has_option("--wait", family) else "" - cmd = "{} {} -t {} -D {} {}".format(_iptables_cmd(family), wait, table, chain, rule) + cmd = f"{_iptables_cmd(family)} {wait} -t {table} -D {chain} {rule}" out = __salt__["cmd.run_stderr"](cmd) return out @@ -998,7 +996,7 @@ def flush(table="filter", chain="", family="ipv4"): """ wait = "--wait" if _has_option("--wait", family) else "" - cmd = "{} {} -t {} -F {}".format(_iptables_cmd(family), wait, table, chain) + cmd = f"{_iptables_cmd(family)} {wait} -t {table} -F {chain}" out = __salt__["cmd.run_stderr"](cmd) return out @@ -1016,7 +1014,7 @@ def _parse_conf(conf_file=None, in_mem=False, family="ipv4"): with salt.utils.files.fopen(conf_file, "r") as ifile: rules = ifile.read() elif in_mem: - cmd = "{}-save".format(_iptables_cmd(family)) + cmd = f"{_iptables_cmd(family)}-save" rules = __salt__["cmd.run_stdout"](cmd) else: raise SaltException("A file was not found to parse") @@ -1057,7 +1055,7 @@ def _parse_conf(conf_file=None, in_mem=False, family="ipv4"): and args[index + 1] != "!" and not args[index + 1].startswith("-") ): - args[index] += " {}".format(args.pop(index + 1)) + args[index] += f" {args.pop(index + 1)}" index += 1 if args[-1].startswith("-"): args.append("") @@ -1082,17 +1080,8 @@ def _parser(): iptables(8) and iptables-extensions(8) man pages. They will not all be used by all parts of the module; use them intelligently and appropriately. """ - add_arg = None - if sys.version.startswith("2.6"): - import optparse - - parser = optparse.OptionParser() - add_arg = parser.add_option - else: - import argparse # pylint: disable=minimum-python-version - - parser = argparse.ArgumentParser() - add_arg = parser.add_argument + parser = argparse.ArgumentParser() + add_arg = parser.add_argument # COMMANDS add_arg("-A", "--append", dest="append", action="append") diff --git a/salt/modules/iwtools.py b/salt/modules/iwtools.py index aec30a8390c..353fea5ea28 100644 --- a/salt/modules/iwtools.py +++ b/salt/modules/iwtools.py @@ -112,7 +112,7 @@ def _valid_iface(iface): Validate the specified interface """ ifaces = list_interfaces() - if iface in ifaces.keys(): + if iface in ifaces: return True return False diff --git a/salt/modules/k8s.py b/salt/modules/k8s.py index 3368a1d547b..c62d1c79ebc 100644 --- a/salt/modules/k8s.py +++ b/salt/modules/k8s.py @@ -581,7 +581,7 @@ def _source_encode(source, saltenv): try: source_url = urllib.parse.urlparse(source) except TypeError: - return "", {}, "Invalid format for source parameter" + return "", {} protos = ("salt", "http", "https", "ftp", "swift", "s3", "file") diff --git a/salt/modules/kubernetesmod.py b/salt/modules/kubernetesmod.py index 4755d4cf212..d66120925d5 100644 --- a/salt/modules/kubernetesmod.py +++ b/salt/modules/kubernetesmod.py @@ -154,7 +154,7 @@ def _setup_conn_old(**kwargs): or kubernetes.client.configuration.password != password ): # Recreates API connection if settings are changed - kubernetes.client.configuration.__init__() + kubernetes.client.configuration.__init__() # pylint: disable=unnecessary-dunder-call kubernetes.client.configuration.host = host kubernetes.client.configuration.user = username diff --git a/salt/modules/ldap3.py b/salt/modules/ldap3.py index a065b306b6d..2313b024bb9 100644 --- a/salt/modules/ldap3.py +++ b/salt/modules/ldap3.py @@ -32,7 +32,9 @@ log = logging.getLogger(__name__) def __virtual__(): """Only load this module if the Python ldap module is present""" - return bool(len(available_backends)) + if available_backends: + return True + return False class LDAPError(Exception): diff --git a/salt/modules/mac_softwareupdate.py b/salt/modules/mac_softwareupdate.py index 0b5df536210..3cb894e258c 100644 --- a/salt/modules/mac_softwareupdate.py +++ b/salt/modules/mac_softwareupdate.py @@ -176,7 +176,7 @@ def list_ignored(): # "Safari6.1.2MountainLion-6.1.2", # or: # Safari6.1.2MountainLion-6.1.2 - rexp = re.compile('(?m)^ ["]?' r'([^,|\s].*[^"|\n|,])[,|"]?') + rexp = re.compile(r'(?m)^ ["]?([^,|\s].*[^"|\n|,])[,|"]?') return rexp.findall(out) diff --git a/salt/modules/mine.py b/salt/modules/mine.py index f8d55464019..f25e894740f 100644 --- a/salt/modules/mine.py +++ b/salt/modules/mine.py @@ -186,7 +186,7 @@ def update(clear=False, mine_functions=None): res = salt.utils.functools.call_function( __salt__[function_name or function_alias], *function_args, - **function_kwargs + **function_kwargs, ) except Exception: # pylint: disable=broad-except trace = traceback.format_exc() @@ -309,17 +309,8 @@ def get(tgt, fun, tgt_type="glob", exclude_minion=False): # Load from local minion's cache if __opts__["file_client"] == "local": ret = {} - is_target = { - "glob": __salt__["match.glob"], - "pcre": __salt__["match.pcre"], - "list": __salt__["match.list"], - "grain": __salt__["match.grain"], - "grain_pcre": __salt__["match.grain_pcre"], - "ipcidr": __salt__["match.ipcidr"], - "compound": __salt__["match.compound"], - "pillar": __salt__["match.pillar"], - "pillar_pcre": __salt__["match.pillar_pcre"], - }[tgt_type](tgt) + + is_target = __salt__[f"match.{tgt_type}"](tgt) if not is_target: return ret diff --git a/salt/modules/mount.py b/salt/modules/mount.py index 869c6f2016d..aedc8dc79f2 100644 --- a/salt/modules/mount.py +++ b/salt/modules/mount.py @@ -866,7 +866,10 @@ def set_fstab( criteria = entry.pick(match_on) except KeyError: - filterFn = lambda key: key not in _fstab_entry.fstab_keys + + def filterFn(key): + return key not in _fstab_entry.fstab_keys + invalid_keys = filter(filterFn, match_on) msg = 'Unrecognized keys in match_on: "{}"'.format(invalid_keys) @@ -996,7 +999,10 @@ def set_vfstab( criteria = entry.pick(match_on) except KeyError: - filterFn = lambda key: key not in _vfstab_entry.vfstab_keys + + def filterFn(key): + return key not in _vfstab_entry.vfstab_keys + invalid_keys = filter(filterFn, match_on) msg = 'Unrecognized keys in match_on: "{}"'.format(invalid_keys) @@ -1878,7 +1884,10 @@ def set_filesystems( criteria = entry_ip.pick(match_on) except KeyError: - filterFn = lambda key: key not in _FileSystemsEntry.compatibility_keys + + def filterFn(key): + return key not in _FileSystemsEntry.compatibility_keys + invalid_keys = filter(filterFn, match_on) raise CommandExecutionError( 'Unrecognized keys in match_on: "{}"'.format(invalid_keys) diff --git a/salt/modules/mysql.py b/salt/modules/mysql.py index c9c6ad69fe7..4d8f5e07e8b 100644 --- a/salt/modules/mysql.py +++ b/salt/modules/mysql.py @@ -2394,7 +2394,7 @@ def __grant_generate( if dbc != "*": # _ and % are authorized on GRANT queries and should get escaped # on the db name, but only if not requesting a table level grant - dbc = quote_identifier(dbc, for_grants=(table == "*")) + dbc = quote_identifier(dbc, for_grants=table == "*") if table != "*": table = quote_identifier(table) # identifiers cannot be used as values, and same thing for grants @@ -2663,7 +2663,7 @@ def grant_revoke( if dbc != "*": # _ and % are authorized on GRANT queries and should get escaped # on the db name, but only if not requesting a table level grant - s_database = quote_identifier(dbc, for_grants=(table == "*")) + s_database = quote_identifier(dbc, for_grants=table == "*") if dbc == "*": # add revoke for *.* # before the modification query send to mysql will looks like @@ -2764,11 +2764,13 @@ def __do_query_into_hash(conn, sql_str): rtn_results = [] + cursor = None try: cursor = conn.cursor() except MySQLdb.MySQLError: log.error("%s: Can't get cursor for SQL->%s", mod, sql_str) - cursor.close() + if cursor: + cursor.close() log.debug("%s-->", mod) return rtn_results diff --git a/salt/modules/network.py b/salt/modules/network.py index 524b1b74faf..c72230f3335 100644 --- a/salt/modules/network.py +++ b/salt/modules/network.py @@ -2015,7 +2015,7 @@ def iphexval(ip): salt '*' network.iphexval 10.0.0.1 """ a = ip.split(".") - hexval = ["%02X" % int(x) for x in a] # pylint: disable=E1321 + hexval = ["%02X" % int(x) for x in a] return "".join(hexval) diff --git a/salt/modules/openscap.py b/salt/modules/openscap.py index 762796cce47..3f3ff6dffd8 100644 --- a/salt/modules/openscap.py +++ b/salt/modules/openscap.py @@ -2,24 +2,12 @@ Module for OpenSCAP Management """ - - +import argparse import shlex import shutil import tempfile from subprocess import PIPE, Popen -ArgumentParser = object - -try: - import argparse # pylint: disable=minimum-python-version - - ArgumentParser = argparse.ArgumentParser - HAS_ARGPARSE = True -except ImportError: # python 2.6 - HAS_ARGPARSE = False - - _XCCDF_MAP = { "eval": { "parser_arguments": [(("--profile",), {"required": True})], @@ -32,15 +20,10 @@ _XCCDF_MAP = { } -def __virtual__(): - return HAS_ARGPARSE, "argparse module is required." - - -class _ArgumentParser(ArgumentParser): +class _ArgumentParser(argparse.ArgumentParser): def __init__(self, action=None, *args, **kwargs): super().__init__(*args, prog="oscap", **kwargs) self.add_argument("action", choices=["eval"]) - add_arg = None for params, kwparams in _XCCDF_MAP["eval"]["parser_arguments"]: self.add_argument(*params, **kwparams) diff --git a/salt/modules/opkg.py b/salt/modules/opkg.py index 98882c85e96..72e7bcbb411 100644 --- a/salt/modules/opkg.py +++ b/salt/modules/opkg.py @@ -1222,7 +1222,10 @@ def version_cmp( salt '*' pkg.version_cmp '0.2.4-0' '0.2.4.1-0' """ - normalize = lambda x: str(x).split(":", 1)[-1] if ignore_epoch else str(x) + + def normalize(x): + return str(x).split(":", 1)[-1] if ignore_epoch else str(x) + pkg1 = normalize(pkg1) pkg2 = normalize(pkg2) diff --git a/salt/modules/opsgenie.py b/salt/modules/opsgenie.py index 18539b80654..7ed014042a0 100644 --- a/salt/modules/opsgenie.py +++ b/salt/modules/opsgenie.py @@ -99,6 +99,7 @@ def post_data( "Content-Type": "application/json", "Authorization": "GenieKey " + api_key, }, + timeout=120, ) else: response = requests.post( @@ -108,6 +109,7 @@ def post_data( "Content-Type": "application/json", "Authorization": "GenieKey " + api_key, }, + timeout=120, ) return response.status_code, response.text diff --git a/salt/modules/oracle.py b/salt/modules/oracle.py index bc80943d480..bb79063533f 100644 --- a/salt/modules/oracle.py +++ b/salt/modules/oracle.py @@ -180,9 +180,12 @@ def version(*dbs): salt '*' oracle.version my_db """ pillar_dbs = __salt__["pillar.get"]("oracle:dbs") - get_version = lambda x: [ - r[0] for r in run_query(x, "select banner from v$version order by banner") - ] + + def get_version(x): + return [ + r[0] for r in run_query(x, "select banner from v$version order by banner") + ] + result = {} if dbs: log.debug("get db versions for: %s", dbs) diff --git a/salt/modules/pagerduty_util.py b/salt/modules/pagerduty_util.py index 642e2ce2a5a..10114b3e4bb 100644 --- a/salt/modules/pagerduty_util.py +++ b/salt/modules/pagerduty_util.py @@ -174,6 +174,7 @@ def _query( params=params, data=salt.utils.json.dumps(data), verify=verify_ssl, + timeout=120, ) if result.text is None or result.text == "": @@ -196,6 +197,7 @@ def _query( params=params, data=data, # Already serialized above, don't do it again verify=verify_ssl, + timeout=120, ).json() offset = next_page_results["offset"] limit = next_page_results["limit"] diff --git a/salt/modules/pkg_resource.py b/salt/modules/pkg_resource.py index a6fa5eecd3f..578e53da30d 100644 --- a/salt/modules/pkg_resource.py +++ b/salt/modules/pkg_resource.py @@ -26,7 +26,9 @@ def _repack_pkgs(pkgs, normalize=True): if normalize and "pkg.normalize_name" in __salt__: _normalize_name = __salt__["pkg.normalize_name"] else: - _normalize_name = lambda pkgname: pkgname + + def _normalize_name(pkgname): + return pkgname repacked_pkgs = { _normalize_name(str(x)): str(y) if y is not None else y @@ -71,7 +73,9 @@ def pack_sources(sources, normalize=True): if normalize and "pkg.normalize_name" in __salt__: _normalize_name = __salt__["pkg.normalize_name"] else: - _normalize_name = lambda pkgname: pkgname + + def _normalize_name(pkgname): + return pkgname if isinstance(sources, str): try: diff --git a/salt/modules/portage_config.py b/salt/modules/portage_config.py index 9cf937f9406..15c0ad983da 100644 --- a/salt/modules/portage_config.py +++ b/salt/modules/portage_config.py @@ -88,7 +88,7 @@ def _get_config_file(conf, atom): # parts.repo will be empty if there is no repo part relative_path = parts.repo or "gentoo" elif str(parts.cp).endswith("/*"): - relative_path = str(parts.cp).split("/")[0] + "_" + relative_path = str(parts.cp).split("/", maxsplit=1)[0] + "_" else: relative_path = os.path.join( *[x for x in os.path.split(parts.cp) if x != "*"] diff --git a/salt/modules/postgres.py b/salt/modules/postgres.py index f73959a92ed..d9664ac840a 100644 --- a/salt/modules/postgres.py +++ b/salt/modules/postgres.py @@ -35,10 +35,6 @@ To prevent Postgres commands from running arbitrarily long, a timeout (in second postgres.bins_dir: '/usr/pgsql-9.5/bin/' """ -# This pylint error is popping up where there are no colons? -# pylint: disable=E8203 - - import base64 import datetime import hashlib @@ -1007,7 +1003,8 @@ def user_list( return False # will return empty string if return_password = False - _x = lambda s: s if return_password else "" + def _x(s): + return s if return_password else "" query = "".join( [ diff --git a/salt/modules/quota.py b/salt/modules/quota.py index 931ae63d0ab..eb99d67a4f6 100644 --- a/salt/modules/quota.py +++ b/salt/modules/quota.py @@ -105,7 +105,7 @@ def set_(device, **kwargs): "file-hard-limit": 0, } - current = None + current = ret = None cmd = "setquota" if "user" in kwargs: cmd += " -u {} ".format(kwargs["user"]) diff --git a/salt/modules/rabbitmq.py b/salt/modules/rabbitmq.py index e0a9304bd54..a11fc4a3ede 100644 --- a/salt/modules/rabbitmq.py +++ b/salt/modules/rabbitmq.py @@ -165,7 +165,9 @@ def _output_to_dict(cmdoutput, values_mapper=None): ret = {} if values_mapper is None: - values_mapper = lambda string: string.split("\t") + + def values_mapper(string): + return string.split("\t") # remove first and last line: Listing ... - ...done data_rows = _strip_listing_to_done(cmdoutput.splitlines()) @@ -237,11 +239,11 @@ def list_users(runas=None): ) # func to get tags from string such as "[admin, monitoring]" - func = ( - lambda string: [x.strip() for x in string[1:-1].split(",")] - if "," in string - else [x for x in string[1:-1].split(" ")] - ) + def func(string): + if "," in string: + return [x.strip() for x in string[1:-1].split(",")] + return [x for x in string[1:-1].split(" ")] + return _output_to_dict(res, func) diff --git a/salt/modules/rpm_lowpkg.py b/salt/modules/rpm_lowpkg.py index 4cd137c258f..7bf45780f0c 100644 --- a/salt/modules/rpm_lowpkg.py +++ b/salt/modules/rpm_lowpkg.py @@ -710,7 +710,10 @@ def version_cmp(ver1, ver2, ignore_epoch=False): salt '*' pkg.version_cmp '0.2-001' '0.2.0.1-002' """ - normalize = lambda x: str(x).split(":", 1)[-1] if ignore_epoch else str(x) + + def normalize(x): + return str(x).split(":", 1)[-1] if ignore_epoch else str(x) + ver1 = normalize(ver1) ver2 = normalize(ver2) diff --git a/salt/modules/saltcheck.py b/salt/modules/saltcheck.py index 79113bb71c4..99672a3c133 100644 --- a/salt/modules/saltcheck.py +++ b/salt/modules/saltcheck.py @@ -476,7 +476,7 @@ def run_state_tests(state, saltenv=None, check_all=False, only_fails=False): # Check for situations to disable parallization if parallel: - if type(num_proc) == float: + if isinstance(num_proc, float): num_proc = int(num_proc) if multiprocessing.cpu_count() < 2: diff --git a/salt/modules/selinux.py b/salt/modules/selinux.py index c12db3d9e19..552ec282ff2 100644 --- a/salt/modules/selinux.py +++ b/salt/modules/selinux.py @@ -375,7 +375,7 @@ def _validate_filetype(filetype): Checks if the given filetype is a valid SELinux filetype specification. Throws an SaltInvocationError if it isn't. """ - if filetype not in _SELINUX_FILETYPES.keys(): + if filetype not in _SELINUX_FILETYPES: raise SaltInvocationError("Invalid filetype given: {}".format(filetype)) return True diff --git a/salt/modules/sensehat.py b/salt/modules/sensehat.py index 71c5630703c..d5ba0b5f1f1 100644 --- a/salt/modules/sensehat.py +++ b/salt/modules/sensehat.py @@ -39,6 +39,7 @@ def __virtual__(): """ if has_sense_hat: try: + global _sensehat _sensehat = SenseHat() except OSError: return ( diff --git a/salt/modules/serverdensity_device.py b/salt/modules/serverdensity_device.py index 27a4c0b0a32..f55815fb07a 100644 --- a/salt/modules/serverdensity_device.py +++ b/salt/modules/serverdensity_device.py @@ -89,6 +89,7 @@ def create(name, **params): "https://api.serverdensity.io/inventory/devices/", params={"token": get_sd_auth("api_token")}, data=params, + timeout=120, ) log.debug("Server Density API Response: %s", api_response) log.debug("Server Density API Response content: %s", api_response.content) @@ -120,6 +121,7 @@ def delete(device_id): api_response = requests.delete( "https://api.serverdensity.io/inventory/devices/" + device_id, params={"token": get_sd_auth("api_token")}, + timeout=120, ) log.debug("Server Density API Response: %s", api_response) log.debug("Server Density API Response content: %s", api_response.content) @@ -171,6 +173,7 @@ def ls(**params): "token": get_sd_auth("api_token"), "filter": salt.utils.json.dumps(params), }, + timeout=120, ) log.debug("Server Density API Response: %s", api_response) log.debug("Server Density API Response content: %s", api_response.content) @@ -209,6 +212,7 @@ def update(device_id, **params): "https://api.serverdensity.io/inventory/devices/" + device_id, params={"token": get_sd_auth("api_token")}, data=params, + timeout=120, ) log.debug("Server Density API Response: %s", api_response) log.debug("Server Density API Response content: %s", api_response.content) diff --git a/salt/modules/smartos_imgadm.py b/salt/modules/smartos_imgadm.py index 5d5cb75e750..cfa74f055bc 100644 --- a/salt/modules/smartos_imgadm.py +++ b/salt/modules/smartos_imgadm.py @@ -37,13 +37,16 @@ def _exit_status(retcode, stderr=None): """ Translate exit status of imgadm """ - ret = { - 0: "Successful completion.", - 1: "An error occurred." if not stderr else stderr, - 2: "Usage error.", - 3: "Image not installed.", - }[retcode] - return ret + if retcode == 0: + return "Successful completion." + if retcode == 1: + if stderr: + return stderr + return "An error occurred." + if retcode == 2: + return "Usage error." + if retcode == 3: + return "Image not installed." def _parse_image_meta(image=None, detail=False): diff --git a/salt/modules/smartos_vmadm.py b/salt/modules/smartos_vmadm.py index 3ef9c3d5b6a..308d41d0294 100644 --- a/salt/modules/smartos_vmadm.py +++ b/salt/modules/smartos_vmadm.py @@ -43,10 +43,12 @@ def _exit_status(retcode): """ Translate exit status of vmadm """ - ret = {0: "Successful completion.", 1: "An error occurred.", 2: "Usage error."}[ - retcode - ] - return ret + if retcode == 0: + return "Successful completion." + if retcode == 1: + return "An error occurred." + if retcode == 2: + return "Usage error." def _create_update_from_file(mode="create", uuid=None, path=None): diff --git a/salt/modules/solaris_shadow.py b/salt/modules/solaris_shadow.py index 65d20f2e9e1..9441ecea293 100644 --- a/salt/modules/solaris_shadow.py +++ b/salt/modules/solaris_shadow.py @@ -114,7 +114,7 @@ def info(name): } try: - data = pwd.getpwnam(name) + data = pwd.getpwnam(name) # pylint: disable=used-before-assignment ret.update({"name": name}) except KeyError: return ret diff --git a/salt/modules/splunk_search.py b/salt/modules/splunk_search.py index 560874cd23e..be9a50c28e5 100644 --- a/salt/modules/splunk_search.py +++ b/salt/modules/splunk_search.py @@ -162,7 +162,7 @@ def create(name, profile="splunk", **kwargs): _req_url = "{}/servicesNS/{}/search/saved/searches/{}/acl".format( url, config.get("username"), urllib.parse.quote(name) ) - requests.post(_req_url, auth=auth, verify=True, data=data) + requests.post(_req_url, auth=auth, verify=True, data=data, timeout=120) return _get_splunk_search_props(search) diff --git a/salt/modules/status.py b/salt/modules/status.py index 4b0a3b0d400..8489256f0b5 100644 --- a/salt/modules/status.py +++ b/salt/modules/status.py @@ -186,10 +186,10 @@ def custom(): try: ret[item] = vals[item] except KeyError: - log.warning(f"val {item} not in return of {func}") + log.warning("val %s not in return of %s", item, func) ret[item] = "UNKNOWN" except KeyError: - log.warning(f"custom status {func} isn't loaded") + log.warning("custom status %s isn't loaded", func) return ret @@ -1361,7 +1361,10 @@ def netdev(): """ freebsd specific implementation of netdev """ - _dict_tree = lambda: collections.defaultdict(_dict_tree) + + def _dict_tree(): + return collections.defaultdict(_dict_tree) + ret = _dict_tree() netstat = __salt__["cmd.run"]("netstat -i -n -4 -b -d").splitlines() netstat += __salt__["cmd.run"]("netstat -i -n -6 -b -d").splitlines()[1:] diff --git a/salt/modules/statuspage.py b/salt/modules/statuspage.py index 0a38e84102b..0bfbd2798e0 100644 --- a/salt/modules/statuspage.py +++ b/salt/modules/statuspage.py @@ -110,7 +110,7 @@ def _http_request(url, method="GET", headers=None, data=None): """ Make the HTTP request and return the body as python object. """ - req = requests.request(method, url, headers=headers, data=data) + req = requests.request(method, url, headers=headers, data=data, timeout=120) ret = _default_ret() ok_status = METHOD_OK_STATUS.get(method, 200) if req.status_code != ok_status: diff --git a/salt/modules/swarm.py b/salt/modules/swarm.py index fb0d1e273e6..48d49130274 100644 --- a/salt/modules/swarm.py +++ b/salt/modules/swarm.py @@ -374,7 +374,7 @@ def node_ls(server=str): try: salt_return = {} client = docker.APIClient(base_url="unix://var/run/docker.sock") - service = client.nodes(filters=({"name": server})) + service = client.nodes(filters={"name": server}) getdata = salt.utils.json.dumps(service) dump = salt.utils.json.loads(getdata) for items in dump: diff --git a/salt/modules/sysrc.py b/salt/modules/sysrc.py index 2f7952d5959..67a2ce2faf0 100644 --- a/salt/modules/sysrc.py +++ b/salt/modules/sysrc.py @@ -93,14 +93,14 @@ def set_(name, value, **kwargs): # YES, NO, Yes, No, True, False, etc. to boolean types. However, in this case, # we will check to see if that happened and replace it with "YES" or "NO" because # those items are accepted in sysrc. - if type(value) == bool: + if isinstance(value, bool): if value: value = "YES" else: value = "NO" # This is here for the same reason, except for numbers - if type(value) == int: + if isinstance(value, int): value = str(value) cmd += " " + name + '="' + value + '"' diff --git a/salt/modules/systemd_service.py b/salt/modules/systemd_service.py index 52c17ba6074..dd27106afd0 100644 --- a/salt/modules/systemd_service.py +++ b/salt/modules/systemd_service.py @@ -55,9 +55,6 @@ VALID_UNIT_TYPES = ( # Define the module's virtual name __virtualname__ = "service" -# Disable check for string substitution -# pylint: disable=E1321 - def __virtual__(): """ diff --git a/salt/modules/telegram.py b/salt/modules/telegram.py index 79230b5e049..e0f2f969045 100644 --- a/salt/modules/telegram.py +++ b/salt/modules/telegram.py @@ -113,7 +113,7 @@ def _post_message(message, chat_id, token): parameters["text"] = message try: - response = requests.post(url, data=parameters) + response = requests.post(url, data=parameters, timeout=120) result = response.json() log.debug("Raw response of the telegram request is %s", response) diff --git a/salt/modules/telemetry.py b/salt/modules/telemetry.py index 20dcf08c185..c55c94668ca 100644 --- a/salt/modules/telemetry.py +++ b/salt/modules/telemetry.py @@ -101,7 +101,7 @@ def _retrieve_channel_id(email, profile="telemetry"): _get_telemetry_base(profile) + "/notification-channels?_type=EmailNotificationChannel" ) - response = requests.get(get_url, headers=auth) + response = requests.get(get_url, headers=auth, timeout=120) if response.status_code == 200: cache_result = {} @@ -140,7 +140,7 @@ def get_alert_config( get_url = _get_telemetry_base(profile) + "/alerts?deployment={}".format( deployment_id ) - response = requests.get(get_url, headers=auth) + response = requests.get(get_url, headers=auth, timeout=120) except requests.exceptions.RequestException as e: log.error(str(e)) return False @@ -197,7 +197,7 @@ def get_notification_channel_id(notify_channel, profile="telemetry"): "email": notify_channel, } response = requests.post( - post_url, data=salt.utils.json.dumps(data), headers=auth + post_url, data=salt.utils.json.dumps(data), headers=auth, timeout=120 ) if response.status_code == 200: log.info( @@ -236,6 +236,7 @@ def get_alarms(deployment_id, profile="telemetry"): _get_telemetry_base(profile) + "/alerts?deployment={}".format(deployment_id), headers=auth, + timeout=120, ) except requests.exceptions.RequestException as e: log.error(str(e)) @@ -293,7 +294,10 @@ def create_alarm(deployment_id, metric_name, data, api_key=None, profile="teleme try: response = requests.post( - request_uri, data=salt.utils.json.dumps(post_body), headers=auth + request_uri, + data=salt.utils.json.dumps(post_body), + headers=auth, + timeout=120, ) except requests.exceptions.RequestException as e: # TODO: May be we should retry? @@ -364,7 +368,10 @@ def update_alarm(deployment_id, metric_name, data, api_key=None, profile="teleme try: response = requests.put( - request_uri, data=salt.utils.json.dumps(post_body), headers=auth + request_uri, + data=salt.utils.json.dumps(post_body), + headers=auth, + timeout=120, ) except requests.exceptions.RequestException as e: log.error("Update failed: %s", e) @@ -429,7 +436,7 @@ def delete_alarms( delete_url = _get_telemetry_base(profile) + "/alerts/{}".format(id) try: - response = requests.delete(delete_url, headers=auth) + response = requests.delete(delete_url, headers=auth, timeout=120) if metric_name: log.debug( "updating cache and delete %s key from %s", diff --git a/salt/modules/tomcat.py b/salt/modules/tomcat.py index 46451508c50..d9f9f28e276 100644 --- a/salt/modules/tomcat.py +++ b/salt/modules/tomcat.py @@ -630,17 +630,14 @@ def passwd(passwd, user="", alg="sha1", realm=None): salt '*' tomcat.passwd secret tomcat sha1 salt '*' tomcat.passwd secret tomcat sha1 'Protected Realm' """ + # pylint: disable=no-value-for-parameter + # we call the first parameter the same as the function! + # Shouldn't it be SHA265 instead of SHA1? - digest = hasattr(hashlib, alg) and getattr(hashlib, alg) or None - if digest: + digest = getattr(hashlib, alg, None) + if digest is not None: if realm: - digest.update( - "{}:{}:{}".format( - user, - realm, - passwd, - ) - ) + digest.update(f"{user}:{realm}:{passwd}") else: digest.update(passwd) diff --git a/salt/modules/uptime.py b/salt/modules/uptime.py index 8e40717fa8a..294e91aeee4 100644 --- a/salt/modules/uptime.py +++ b/salt/modules/uptime.py @@ -49,7 +49,9 @@ def create(name, **params): application_url = _get_application_url() log.debug("[uptime] trying PUT request") params.update(url=name) - req = requests.put("{}/api/checks".format(application_url), data=params) + req = requests.put( + "{}/api/checks".format(application_url), data=params, timeout=120 + ) if not req.ok: raise CommandExecutionError("request to uptime failed : {}".format(req.reason)) log.debug("[uptime] PUT request successful") @@ -72,9 +74,11 @@ def delete(name): raise CommandExecutionError(msg) application_url = _get_application_url() log.debug("[uptime] trying DELETE request") - jcontent = requests.get("{}/api/checks".format(application_url)).json() + jcontent = requests.get("{}/api/checks".format(application_url), timeout=120).json() url_id = [x["_id"] for x in jcontent if x["url"] == name][0] - req = requests.delete("{}/api/checks/{}".format(application_url, url_id)) + req = requests.delete( + "{}/api/checks/{}".format(application_url, url_id), timeout=120 + ) if not req.ok: raise CommandExecutionError("request to uptime failed : {}".format(req.reason)) log.debug("[uptime] DELETE request successful") @@ -106,7 +110,7 @@ def checks_list(): """ application_url = _get_application_url() log.debug("[uptime] get checks") - jcontent = requests.get("{}/api/checks".format(application_url)).json() + jcontent = requests.get("{}/api/checks".format(application_url), timeout=120).json() return [x["url"] for x in jcontent] diff --git a/salt/modules/vbox_guest.py b/salt/modules/vbox_guest.py index 56c576ed211..d6dbce68602 100644 --- a/salt/modules/vbox_guest.py +++ b/salt/modules/vbox_guest.py @@ -90,19 +90,19 @@ def _return_mount_error(f): def _additions_install_program_path(mount_point): - return os.path.join( - mount_point, - { - "Linux": "VBoxLinuxAdditions.run", - "Solaris": "VBoxSolarisAdditions.pkg", - "Windows": "VBoxWindowsAdditions.exe", - }[__grains__.get("kernel", "")], - ) + kernel = __grains__.get("kernel", "") + if kernel == "Linux": + exe = "VBoxLinuxAdditions.run" + elif kernel == "Solaris": + exe = "VBoxSolarisAdditions.pkg" + elif kernel == "Windows": + exe = "VBoxWindowsAdditions.exe" + return os.path.join(mount_point, exe) def _additions_install_opensuse(**kwargs): kernel_type = re.sub(r"^(\d|\.|-)*", "", __grains__.get("kernelrelease", "")) - kernel_devel = "kernel-{}-devel".format(kernel_type) + kernel_devel = f"kernel-{kernel_type}-devel" return __states__["pkg.installed"](None, pkgs=["make", "gcc", kernel_devel]) @@ -279,7 +279,7 @@ def additions_version(): except OSError: return False if d and len(os.listdir(d)) > 0: - return re.sub(r"^{}-".format(_additions_dir_prefix), "", os.path.basename(d)) + return re.sub(rf"^{_additions_dir_prefix}-", "", os.path.basename(d)) return False diff --git a/salt/modules/virt.py b/salt/modules/virt.py index 1e671621c25..0f11dbde206 100644 --- a/salt/modules/virt.py +++ b/salt/modules/virt.py @@ -298,9 +298,7 @@ def _get_domain(conn, *vms, **kwargs): if vms: for name in vms: if name not in all_vms: - raise CommandExecutionError( - 'The VM "{name}" is not present'.format(name=name) - ) + raise CommandExecutionError(f'The VM "{name}" is not present') else: lookup_vms.append(name) else: @@ -515,7 +513,7 @@ def _get_disks(conn, dom): disk_type = elem.get("type") def _get_disk_volume_data(pool_name, volume_name): - qemu_target = "{}/{}".format(pool_name, volume_name) + qemu_target = f"{pool_name}/{volume_name}" pool = conn.storagePoolLookupByName(pool_name) extra_properties = {} try: @@ -526,12 +524,15 @@ def _get_disks(conn, dom): "disk size": vol_info[2], } + _nodes = elem.findall( # pylint: disable=cell-var-from-loop + ".//backingStore[source]" + ) backing_files = [ { "file": node.find("source").get("file"), "file format": node.find("format").get("type"), } - for node in elem.findall(".//backingStore[source]") + for node in _nodes ] if backing_files: @@ -570,7 +571,7 @@ def _get_disks(conn, dom): disks[target.get("dev")] = {"file": qemu_target, "zfs": True} continue - if qemu_target in all_volumes.keys(): + if qemu_target in all_volumes: # If the qemu_target is a known path, output a volume volume = all_volumes[qemu_target] qemu_target, extra_properties = _get_disk_volume_data( @@ -605,7 +606,7 @@ def _get_disks(conn, dom): elif disk_type == "block": qemu_target = source.get("dev", "") # If the qemu_target is a known path, output a volume - if qemu_target in all_volumes.keys(): + if qemu_target in all_volumes: volume = all_volumes[qemu_target] qemu_target, extra_properties = _get_disk_volume_data( volume["pool"], volume["name"] @@ -614,7 +615,7 @@ def _get_disks(conn, dom): qemu_target = source.get("protocol") source_name = source.get("name") if source_name: - qemu_target = "{}:{}".format(qemu_target, source_name) + qemu_target = f"{qemu_target}:{source_name}" # Reverse the magic for the rbd and gluster pools if source.get("protocol") in ["rbd", "gluster"]: @@ -622,7 +623,7 @@ def _get_disks(conn, dom): pool_i_xml = ElementTree.fromstring(pool_i.XMLDesc()) name_node = pool_i_xml.find("source/name") if name_node is not None and source_name.startswith( - "{}/".format(name_node.text) + f"{name_node.text}/" ): qemu_target = "{}{}".format( pool_i.name(), source_name[len(name_node.text) :] @@ -638,7 +639,7 @@ def _get_disks(conn, dom): qemu_target = urllib.parse.urlunparse( ( source.get("protocol"), - "{}:{}".format(hostname, port) if port else hostname, + f"{hostname}:{port}" if port else hostname, source_name, "", saxutils.unescape(source.get("query", "")), @@ -743,9 +744,7 @@ def _migrate(dom, dst_uri, **kwargs): try: bandwidth_value = int(max_bandwidth) except ValueError: - raise SaltInvocationError( - "Invalid max_bandwidth value: {}".format(max_bandwidth) - ) + raise SaltInvocationError(f"Invalid max_bandwidth value: {max_bandwidth}") dom.migrateSetMaxSpeed(bandwidth_value) max_downtime = kwargs.get("max_downtime") @@ -753,9 +752,7 @@ def _migrate(dom, dst_uri, **kwargs): try: downtime_value = int(max_downtime) except ValueError: - raise SaltInvocationError( - "Invalid max_downtime value: {}".format(max_downtime) - ) + raise SaltInvocationError(f"Invalid max_downtime value: {max_downtime}") dom.migrateSetMaxDowntime(downtime_value) if kwargs.get("offline") is True: @@ -782,7 +779,7 @@ def _migrate(dom, dst_uri, **kwargs): try: params[param_key] = int(comp_option_value) except ValueError: - raise SaltInvocationError("Invalid {} value".format(comp_option)) + raise SaltInvocationError(f"Invalid {comp_option} value") parallel_connections = kwargs.get("parallel_connections") if parallel_connections: @@ -888,7 +885,7 @@ def _disk_from_pool(conn, pool, pool_xml, volume_name): # Gluster and RBD need pool/volume name name_node = pool_xml.find("./source/name") if name_node is not None: - disk_context["volume"] = "{}/{}".format(name_node.text, volume_name) + disk_context["volume"] = f"{name_node.text}/{volume_name}" # Copy the authentication if any for RBD auth_node = pool_xml.find("./source/auth") if auth_node is not None: @@ -947,7 +944,7 @@ def _gen_xml( consoles=None, stop_on_reboot=False, host_devices=None, - **kwargs + **kwargs, ): """ Generate the XML string to define a libvirt VM @@ -1013,7 +1010,7 @@ def _gen_xml( efi_value = context["boot"].get("efi", None) if boot else None if efi_value is True: context["boot"]["os_attrib"] = "firmware='efi'" - elif efi_value is not None and type(efi_value) != bool: + elif efi_value is not None and not isinstance(efi_value, bool): raise SaltInvocationError("Invalid efi value") if os_type == "xen": @@ -1391,7 +1388,7 @@ def _zfs_image_create( ) ) - destination_fs = os.path.join(pool, "{}.{}".format(vm_name, disk_name)) + destination_fs = os.path.join(pool, f"{vm_name}.{disk_name}") log.debug("Image destination will be %s", destination_fs) existing_disk = __salt__["zfs.list"](name=pool) @@ -1423,9 +1420,7 @@ def _zfs_image_create( sparse=sparse_volume, ) - blockdevice_path = os.path.join( - "/dev/zvol", pool, "{}.{}".format(vm_name, disk_name) - ) + blockdevice_path = os.path.join("/dev/zvol", pool, f"{vm_name}.{disk_name}") log.debug("Image path will be %s", blockdevice_path) return blockdevice_path @@ -1458,7 +1453,7 @@ def _qemu_image_create(disk, create_overlay=False, saltenv="base"): qcow2 = False if salt.utils.path.which("qemu-img"): - res = __salt__["cmd.run"]('qemu-img info "{}"'.format(sfn)) + res = __salt__["cmd.run"](f'qemu-img info "{sfn}"') imageinfo = salt.utils.yaml.safe_load(res) qcow2 = imageinfo["file format"] == "qcow2" try: @@ -1477,9 +1472,7 @@ def _qemu_image_create(disk, create_overlay=False, saltenv="base"): if disk_size and qcow2: log.debug("Resize qcow2 image to %sM", disk_size) - __salt__["cmd.run"]( - 'qemu-img resize "{}" {}M'.format(img_dest, disk_size) - ) + __salt__["cmd.run"](f'qemu-img resize "{img_dest}" {disk_size}M') log.debug("Apply umask and remove exec bit") mode = (0o0777 ^ mask) & 0o0666 @@ -1487,7 +1480,7 @@ def _qemu_image_create(disk, create_overlay=False, saltenv="base"): except OSError as err: raise CommandExecutionError( - "Problem while copying image. {} - {}".format(disk_image, err) + f"Problem while copying image. {disk_image} - {err}" ) else: @@ -1514,7 +1507,7 @@ def _qemu_image_create(disk, create_overlay=False, saltenv="base"): except OSError as err: raise CommandExecutionError( - "Problem while creating volume {} - {}".format(img_dest, err) + f"Problem while creating volume {img_dest} - {err}" ) return img_dest @@ -1730,7 +1723,7 @@ def _fill_disk_filename(conn, vm_name, disk, hypervisor, pool_caps): index = min( idx for idx in range(1, max(indexes) + 2) if idx not in indexes ) - disk["filename"] = "{}{}".format(os.path.basename(device), index) + disk["filename"] = f"{os.path.basename(device)}{index}" # Is the user wanting to reuse an existing volume? if disk.get("source_file"): @@ -1965,7 +1958,7 @@ def _handle_efi_param(boot, desc): return True # check the case that loader tag might be present. This happens after the vm ran - elif type(efi_value) == bool and os_attrib == {}: + elif isinstance(efi_value, bool) and os_attrib == {}: if efi_value is True and parent_tag.find("loader") is None: parent_tag.set("firmware", "efi") return True @@ -1973,7 +1966,7 @@ def _handle_efi_param(boot, desc): parent_tag.remove(parent_tag.find("loader")) parent_tag.remove(parent_tag.find("nvram")) return True - elif type(efi_value) != bool: + elif not isinstance(efi_value, bool): raise SaltInvocationError("Invalid efi value") return False @@ -2006,7 +1999,7 @@ def init( consoles=None, stop_on_reboot=False, host_devices=None, - **kwargs + **kwargs, ): """ Initialize a new vm @@ -2912,7 +2905,7 @@ def init( consoles, stop_on_reboot, host_devices, - **kwargs + **kwargs, ) log.debug("New virtual machine definition: %s", vm_xml) conn.defineXML(vm_xml) @@ -3112,7 +3105,7 @@ def _get_disk_target(targets, disks_count, prefix): :param prefix: the prefix of the target name, i.e. "hd" """ for i in range(disks_count): - ret = "{}{}".format(prefix, string.ascii_lowercase[i]) + ret = f"{prefix}{string.ascii_lowercase[i]}" if ret not in targets: return ret return None @@ -3294,8 +3287,8 @@ def _compute_device_changes(old_xml, new_xml, to_skip): changes[dev_type] = {} if not to_skip[dev_type]: old = devices_node.findall(dev_type) - new = new_xml.findall("devices/{}".format(dev_type)) - changes[dev_type] = globals()["_diff_{}_lists".format(dev_type)](old, new) + new = new_xml.findall(f"devices/{dev_type}") + changes[dev_type] = globals()[f"_diff_{dev_type}_lists"](old, new) return changes @@ -3499,7 +3492,7 @@ def update( stop_on_reboot=False, host_devices=None, autostart=False, - **kwargs + **kwargs, ): """ Update the definition of an existing domain. @@ -3761,7 +3754,7 @@ def update( consoles=consoles, stop_on_reboot=stop_on_reboot, host_devices=host_devices, - **kwargs + **kwargs, ) ) set_autostart(name, "on" if autostart else "off") @@ -3796,7 +3789,7 @@ def update( # _handle_unit treats bytes as invalid unit for the purpose of consistency unit = unit if unit != "bytes" else "b" value = node.get("memory") or node.get("size") or node.text - return _handle_unit("{}{}".format(value, unit)) if value else None + return _handle_unit(f"{value}{unit}") if value else None def _set_vcpu(node, value): node.text = str(value) @@ -4063,32 +4056,32 @@ def update( for timer in timer_names: params_mapping += [ xmlutil.attribute( - "clock:timers:{}:track".format(timer), - "clock/timer[@name='{}']".format(timer), + f"clock:timers:{timer}:track", + f"clock/timer[@name='{timer}']", "track", ["name"], ), xmlutil.attribute( - "clock:timers:{}:tickpolicy".format(timer), - "clock/timer[@name='{}']".format(timer), + f"clock:timers:{timer}:tickpolicy", + f"clock/timer[@name='{timer}']", "tickpolicy", ["name"], ), xmlutil.int_attribute( - "clock:timers:{}:frequency".format(timer), - "clock/timer[@name='{}']".format(timer), + f"clock:timers:{timer}:frequency", + f"clock/timer[@name='{timer}']", "frequency", ["name"], ), xmlutil.attribute( - "clock:timers:{}:mode".format(timer), - "clock/timer[@name='{}']".format(timer), + f"clock:timers:{timer}:mode", + f"clock/timer[@name='{timer}']", "mode", ["name"], ), _yesno_attribute( - "clock:timers:{}:present".format(timer), - "clock/timer[@name='{}']".format(timer), + f"clock:timers:{timer}:present", + f"clock/timer[@name='{timer}']", "present", ["name"], ), @@ -4096,8 +4089,8 @@ def update( for attr in ["slew", "threshold", "limit"]: params_mapping.append( xmlutil.int_attribute( - "clock:timers:{}:{}".format(timer, attr), - "clock/timer[@name='{}']/catchup".format(timer), + f"clock:timers:{timer}:{attr}", + f"clock/timer[@name='{timer}']/catchup", attr, ) ) @@ -5490,7 +5483,7 @@ def migrate(vm_, target, **kwargs): if not urllib.parse.urlparse(target).scheme: proto = "qemu" - dst_uri = "{}://{}/system".format(proto, target) + dst_uri = f"{proto}://{target}/system" else: dst_uri = target @@ -5779,7 +5772,7 @@ def get_hypervisor(): result = [ hyper for hyper in hypervisors - if getattr(sys.modules[__name__], "_is_{}_hyper".format(hyper))() + if getattr(sys.modules[__name__], f"_is_{hyper}_hyper")() ] return result[0] if result else None @@ -5862,7 +5855,7 @@ def vm_cputime(vm_=None, **kwargs): cputime_percent = (1.0e-7 * cputime / host_cpus) / vcpus return { "cputime": int(raw[4]), - "cputime_percent": int("{:.0f}".format(cputime_percent)), + "cputime_percent": int(f"{cputime_percent:.0f}"), } info = {} @@ -6134,7 +6127,7 @@ def snapshot(domain, name=None, suffix=None, **kwargs): ) if suffix: - name = "{name}-{suffix}".format(name=name, suffix=suffix) + name = f"{name}-{suffix}" doc = ElementTree.Element("domainsnapshot") n_name = ElementTree.SubElement(doc, "name") @@ -6258,7 +6251,7 @@ def revert_snapshot(name, vm_snapshot=None, cleanup=False, **kwargs): conn.close() raise CommandExecutionError( snapshot - and 'Snapshot "{}" not found'.format(vm_snapshot) + and f'Snapshot "{vm_snapshot}" not found' or "No more previous snapshots available" ) elif snap.isCurrent(): @@ -6363,7 +6356,7 @@ def _parse_caps_cell(cell): if mem_node is not None: unit = mem_node.get("unit", "KiB") memory = mem_node.text - result["memory"] = "{} {}".format(memory, unit) + result["memory"] = f"{memory} {unit}" pages = [ { @@ -6425,7 +6418,7 @@ def _parse_caps_bank(bank): minimum = control.get("min") if minimum: - result_control["min"] = "{} {}".format(minimum, unit) + result_control["min"] = f"{minimum} {unit}" controls.append(result_control) if controls: result["controls"] = controls @@ -6848,11 +6841,9 @@ def cpu_baseline(full=False, migratable=False, out="libvirt", **kwargs): ] if not cpu_specs: - raise ValueError("Model {} not found in CPU map".format(cpu_model)) + raise ValueError(f"Model {cpu_model} not found in CPU map") elif len(cpu_specs) > 1: - raise ValueError( - "Multiple models {} found in CPU map".format(cpu_model) - ) + raise ValueError(f"Multiple models {cpu_model} found in CPU map") cpu_specs = cpu_specs[0] @@ -6892,7 +6883,7 @@ def network_define( addresses=None, physical_function=None, dns=None, - **kwargs + **kwargs, ): """ Create libvirt network. @@ -7191,7 +7182,7 @@ def network_update( physical_function=None, dns=None, test=False, - **kwargs + **kwargs, ): """ Update a virtual network if needed. @@ -7658,14 +7649,12 @@ def _parse_pools_caps(doc): } for option_kind in ["pool", "vol"]: options = {} - default_format_node = pool.find( - "{}Options/defaultFormat".format(option_kind) - ) + default_format_node = pool.find(f"{option_kind}Options/defaultFormat") if default_format_node is not None: options["default_format"] = default_format_node.get("type") options_enums = { enum.get("name"): [value.text for value in enum.findall("value")] - for enum in pool.findall("{}Options/enum".format(option_kind)) + for enum in pool.findall(f"{option_kind}Options/enum") } if options_enums: options.update(options_enums) @@ -7888,7 +7877,7 @@ def pool_define( source_format=None, transient=False, start=True, # pylint: disable=redefined-outer-name - **kwargs + **kwargs, ): """ Create libvirt pool. @@ -8076,9 +8065,9 @@ def _pool_set_secret( # Create secret if needed if not secret: - description = "Passphrase for {} pool created by Salt".format(pool_name) + description = f"Passphrase for {pool_name} pool created by Salt" if not usage: - usage = "pool_{}".format(pool_name) + usage = f"pool_{pool_name}" secret_xml = _gen_secret_xml(secret_type, usage, description) if not test: secret = conn.secretDefineXML(secret_xml) @@ -8114,7 +8103,7 @@ def pool_update( source_name=None, source_format=None, test=False, - **kwargs + **kwargs, ): """ Update a libvirt storage pool if needed. @@ -8487,7 +8476,7 @@ def pool_undefine(name, **kwargs): } secret_type = auth_types[auth_node.get("type")] secret_usage = auth_node.find("secret").get("usage") - if secret_type and "pool_{}".format(name) == secret_usage: + if secret_type and f"pool_{name}" == secret_usage: secret = conn.secretLookupByUsage(secret_type, secret_usage) secret.undefine() @@ -8809,7 +8798,7 @@ def volume_define( permissions=None, backing_store=None, nocow=False, - **kwargs + **kwargs, ): """ Create libvirt volume. @@ -8910,7 +8899,7 @@ def _volume_upload(conn, pool, volume, file, offset=0, length=0, sparse=False): inData = False eof = os.lseek(fd, 0, os.SEEK_END) if eof < cur: - raise RuntimeError("Current position in file after EOF: {}".format(cur)) + raise RuntimeError(f"Current position in file after EOF: {cur}") sectionLen = eof - cur else: if data > cur: @@ -8963,16 +8952,14 @@ def _volume_upload(conn, pool, volume, file, offset=0, length=0, sparse=False): if stream: stream.abort() if ret: - raise CommandExecutionError( - "Failed to close file: {}".format(err.strerror) - ) + raise CommandExecutionError(f"Failed to close file: {err.strerror}") if stream: try: stream.finish() except libvirt.libvirtError as err: if ret: raise CommandExecutionError( - "Failed to finish stream: {}".format(err.get_error_message()) + f"Failed to finish stream: {err.get_error_message()}" ) return ret diff --git a/salt/modules/win_iis.py b/salt/modules/win_iis.py index 42ec335bf32..3a2500d637b 100644 --- a/salt/modules/win_iis.py +++ b/salt/modules/win_iis.py @@ -1454,7 +1454,7 @@ def set_container_setting(name, container, settings): # Map to numeric to support server 2008 if ( setting == "processModel.identityType" - and settings[setting] in identityType_map2numeric.keys() + and settings[setting] in identityType_map2numeric ): value = identityType_map2numeric[settings[setting]] @@ -1488,7 +1488,7 @@ def set_container_setting(name, container, settings): # map identity type from numeric to string for comparing if ( setting == "processModel.identityType" - and settings[setting] in identityType_map2string.keys() + and settings[setting] in identityType_map2string ): settings[setting] = identityType_map2string[settings[setting]] diff --git a/salt/modules/win_lgpo.py b/salt/modules/win_lgpo.py index 324d49bcba3..1875edad440 100644 --- a/salt/modules/win_lgpo.py +++ b/salt/modules/win_lgpo.py @@ -8687,8 +8687,8 @@ def get_policy_info(policy_name, policy_class, adml_language="en-US"): } policy_class = policy_class.title() policy_data = _policy_info() - if policy_class not in policy_data.policies.keys(): - policy_classes = ", ".join(policy_data.policies.keys()) + if policy_class not in policy_data.policies: + policy_classes = ", ".join(policy_data.policies) ret["message"] = ( 'The requested policy class "{}" is invalid, ' "policy_class should be one of: {}" @@ -9712,7 +9712,7 @@ def get_policy( raise SaltInvocationError("policy_class must be defined") policy_class = policy_class.title() policy_data = _policy_info() - if policy_class not in policy_data.policies.keys(): + if policy_class not in policy_data.policies: policy_classes = ", ".join(policy_data.policies.keys()) raise CommandExecutionError( 'The requested policy class "{}" is invalid, policy_class should ' diff --git a/salt/modules/win_lgpo_reg.py b/salt/modules/win_lgpo_reg.py index e84d0dc2ffe..b3e1fef58e4 100644 --- a/salt/modules/win_lgpo_reg.py +++ b/salt/modules/win_lgpo_reg.py @@ -373,16 +373,16 @@ def set_value( if found_key: if found_name: if "**del." in found_name: - log.debug(f"LGPO_REG Mod: Found disabled name: {found_name}") + log.debug("LGPO_REG Mod: Found disabled name: %s", found_name) pol_data[found_key][v_name] = pol_data[found_key].pop(found_name) found_name = v_name - log.debug(f"LGPO_REG Mod: Updating value: {found_name}") + log.debug("LGPO_REG Mod: Updating value: %s", found_name) pol_data[found_key][found_name] = {"data": v_data, "type": v_type} else: - log.debug(f"LGPO_REG Mod: Setting new value: {found_name}") + log.debug("LGPO_REG Mod: Setting new value: %s", found_name) pol_data[found_key][v_name] = {"data": v_data, "type": v_type} else: - log.debug(f"LGPO_REG Mod: Adding new key and value: {found_name}") + log.debug("LGPO_REG Mod: Adding new key and value: %s", found_name) pol_data[key] = {v_name: {"data": v_data, "type": v_type}} success = True @@ -462,20 +462,22 @@ def disable_value(key, v_name, policy_class="machine"): if found_key: if found_name: if "**del." in found_name: - log.debug(f"LGPO_REG Mod: Already disabled: {v_name}") + log.debug("LGPO_REG Mod: Already disabled: %s", v_name) return None - log.debug(f"LGPO_REG Mod: Disabling value name: {v_name}") + log.debug("LGPO_REG Mod: Disabling value name: %s", v_name) pol_data[found_key].pop(found_name) found_name = "**del.{}".format(found_name) pol_data[found_key][found_name] = {"data": " ", "type": "REG_SZ"} else: - log.debug(f"LGPO_REG Mod: Setting new disabled value name: {v_name}") + log.debug("LGPO_REG Mod: Setting new disabled value name: %s", v_name) pol_data[found_key]["**del.{}".format(v_name)] = { "data": " ", "type": "REG_SZ", } else: - log.debug(f"LGPO_REG Mod: Adding new key and disabled value name: {found_name}") + log.debug( + "LGPO_REG Mod: Adding new key and disabled value name: %s", found_name + ) pol_data[key] = {"**del.{}".format(v_name): {"data": " ", "type": "REG_SZ"}} success = True @@ -553,16 +555,16 @@ def delete_value(key, v_name, policy_class="Machine"): if found_key: if found_name: - log.debug(f"LGPO_REG Mod: Removing value name: {found_name}") + log.debug("LGPO_REG Mod: Removing value name: %s", found_name) pol_data[found_key].pop(found_name) else: - log.debug(f"LGPO_REG Mod: Value name not found: {v_name}") + log.debug("LGPO_REG Mod: Value name not found: %s", v_name) return None if len(pol_data[found_key]) == 0: - log.debug(f"LGPO_REG Mod: Removing empty key: {found_key}") + log.debug("LGPO_REG Mod: Removing empty key: %s", found_key) pol_data.pop(found_key) else: - log.debug(f"LGPO_REG Mod: Key not found: {key}") + log.debug("LGPO_REG Mod: Key not found: %s", key) return None success = True diff --git a/salt/modules/win_pkg.py b/salt/modules/win_pkg.py index e8fdf22e419..fec5ab56a9c 100644 --- a/salt/modules/win_pkg.py +++ b/salt/modules/win_pkg.py @@ -1656,7 +1656,7 @@ def install(name=None, refresh=False, pkgs=None, **kwargs): # single files if cache_dir and installer.startswith("salt:"): path, _ = os.path.split(installer) - log.debug(f"PKG: Caching directory: {path}") + log.debug("PKG: Caching directory: %s", path) try: __salt__["cp.cache_dir"]( path=path, @@ -1673,7 +1673,7 @@ def install(name=None, refresh=False, pkgs=None, **kwargs): # Check to see if the cache_file is cached... if passed if cache_file and cache_file.startswith("salt:"): cache_file_hash = __salt__["cp.hash_file"](cache_file, saltenv) - log.debug(f"PKG: Caching file: {cache_file}") + log.debug("PKG: Caching file: %s", cache_file) try: cached_file = __salt__["cp.cache_file"]( cache_file, @@ -1703,7 +1703,7 @@ def install(name=None, refresh=False, pkgs=None, **kwargs): # file if the source_hash doesn't match, which only works on # files hosted on "salt://". If the http/https url supports # etag, it should also verify that information before caching - log.debug(f"PKG: Caching file: {installer}") + log.debug("PKG: Caching file: %s", installer) try: cached_pkg = __salt__["cp.cache_file"]( installer, @@ -2102,7 +2102,7 @@ def remove(name=None, pkgs=None, **kwargs): if cache_dir and uninstaller.startswith("salt:"): path, _ = os.path.split(uninstaller) - log.debug(f"PKG: Caching dir: {path}") + log.debug("PKG: Caching dir: %s", path) try: __salt__["cp.cache_dir"]( path=path, @@ -2126,7 +2126,7 @@ def remove(name=None, pkgs=None, **kwargs): # only works on files hosted on "salt://". If the http/https # url supports etag, it should also verify that information # before caching - log.debug(f"PKG: Caching file: {uninstaller}") + log.debug("PKG: Caching file: %s", uninstaller) try: cached_pkg = __salt__["cp.cache_file"]( uninstaller, diff --git a/salt/modules/win_pki.py b/salt/modules/win_pki.py index defb92e9d8b..c90af40dd1b 100644 --- a/salt/modules/win_pki.py +++ b/salt/modules/win_pki.py @@ -124,7 +124,7 @@ def get_stores(): salt '*' win_pki.get_stores """ ret = dict() - cmd = r"Get-ChildItem -Path 'Cert:\' | " r"Select-Object LocationName, StoreNames" + cmd = r"Get-ChildItem -Path 'Cert:\' | Select-Object LocationName, StoreNames" items = _cmd_run(cmd=cmd, as_json=True) diff --git a/salt/modules/win_shortcut.py b/salt/modules/win_shortcut.py index c11cc1c64d1..97048b45560 100644 --- a/salt/modules/win_shortcut.py +++ b/salt/modules/win_shortcut.py @@ -82,7 +82,9 @@ def get(path): # This will load the existing shortcut with salt.utils.winapi.Com(): - shell = win32com.client.Dispatch("WScript.Shell") + shell = win32com.client.Dispatch( # pylint: disable=used-before-assignment + "WScript.Shell" + ) shortcut = shell.CreateShortcut(path) arguments = "" diff --git a/salt/modules/win_status.py b/salt/modules/win_status.py index fad2323a43b..033af16e063 100644 --- a/salt/modules/win_status.py +++ b/salt/modules/win_status.py @@ -147,9 +147,6 @@ def __virtual__(): if not HAS_PSUTIL: return False, "win_status.py: Requires psutil" - # Namespace modules from `status.py` - global ping_master, time_ - return __virtualname__ @@ -525,9 +522,7 @@ def master(master=None, connected=True): """ remotes = set() try: - data = subprocess.check_output( - ["netstat", "-n", "-p", "TCP"] - ) # pylint: disable=minimum-python-version + data = subprocess.check_output(["netstat", "-n", "-p", "TCP"]) except subprocess.CalledProcessError: log.error("Failed netstat") raise diff --git a/salt/modules/win_task.py b/salt/modules/win_task.py index 8c9f2718dbd..2e8750ddb97 100644 --- a/salt/modules/win_task.py +++ b/salt/modules/win_task.py @@ -227,7 +227,7 @@ def _get_date_value(date): :rtype: str """ try: - return "{}".format(date) + return f"{date}" except ValueError: return "Never" @@ -245,7 +245,7 @@ def _reverse_lookup(dictionary, value): """ value_index = -1 for idx, dict_value in enumerate(dictionary.values()): - if type(dict_value) == list: + if isinstance(dict_value, list): if value in dict_value: value_index = idx break @@ -269,7 +269,7 @@ def _lookup_first(dictionary, key): :rtype: str """ value = dictionary[key] - if type(value) == list: + if isinstance(value, list): return value[0] else: return value @@ -323,11 +323,11 @@ def _save_task_definition( try: failure_code = fc[exc[5]] except KeyError: - failure_code = "Unknown Failure: {}".format(error) + failure_code = f"Unknown Failure: {error}" log.debug("Failed to modify task: %s", failure_code) - return "Failed to modify task: {}".format(failure_code) + return f"Failed to modify task: {failure_code}" def list_tasks(location="\\"): @@ -363,7 +363,7 @@ def list_tasks(location="\\"): try: task_folder = task_service.GetFolder(location) except pywintypes.com_error: - msg = "Unable to load location: {}".format(location) + msg = f"Unable to load location: {location}" log.error(msg) raise CommandExecutionError(msg) @@ -551,7 +551,7 @@ def create_task( # Check for existing task if name in list_tasks(location) and not force: # Connect to an existing task definition - return "{} already exists".format(name) + return f"{name} already exists" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -566,7 +566,7 @@ def create_task( task_definition=task_definition, user_name=user_name, password=password, - **kwargs + **kwargs, ) # Add Action @@ -642,7 +642,7 @@ def create_task_from_xml( # Check for existing task if name in list_tasks(location): # Connect to an existing task definition - return "{} already exists".format(name) + return f"{name} already exists" if not xml_text and not xml_path: raise ArgumentValueError("Must specify either xml_text or xml_path") @@ -731,7 +731,7 @@ def create_task_from_xml( try: failure_code = fc[error_code] except KeyError: - failure_code = "Unknown Failure: {}".format(error_code) + failure_code = f"Unknown Failure: {error_code}" finally: log.debug("Failed to create task: %s", failure_code) raise CommandExecutionError(failure_code) @@ -767,7 +767,7 @@ def create_folder(name, location="\\"): # Check for existing folder if name in list_folders(location): # Connect to an existing task definition - return "{} already exists".format(name) + return f"{name} already exists" # Create the task service object with salt.utils.winapi.Com(): @@ -812,7 +812,7 @@ def edit_task( force_stop=None, delete_after=None, multiple_instances=None, - **kwargs + **kwargs, ): r""" Edit the parameters of a task. Triggers and Actions cannot be edited yet. @@ -1016,7 +1016,7 @@ def edit_task( else: # Not found and create_new not set, return not found - return "{} not found".format(name) + return f"{name} not found" # General Information if save_definition: @@ -1183,7 +1183,7 @@ def delete_task(name, location="\\"): """ # Check for existing task if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -1224,7 +1224,7 @@ def delete_folder(name, location="\\"): """ # Check for existing folder if name not in list_folders(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -1266,7 +1266,7 @@ def run(name, location="\\"): """ # Check for existing folder if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -1309,7 +1309,7 @@ def run_wait(name, location="\\"): """ # Check for existing folder if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -1370,7 +1370,7 @@ def stop(name, location="\\"): """ # Check for existing folder if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -1419,7 +1419,7 @@ def status(name, location="\\"): """ # Check for existing folder if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -1458,7 +1458,7 @@ def info(name, location="\\"): """ # Check for existing folder if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # connect to the task scheduler with salt.utils.winapi.Com(): @@ -1714,7 +1714,7 @@ def add_action(name=None, location="\\", action_type="Execute", **kwargs): else: # Not found and create_new not set, return not found - return "{} not found".format(name) + return f"{name} not found" # Action Settings task_action = task_definition.Actions.Create(action_types[action_type]) @@ -1808,7 +1808,7 @@ def _clear_actions(name, location="\\"): # TODO: action. # Check for existing task if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # Create the task service object with salt.utils.winapi.Com(): @@ -1848,7 +1848,7 @@ def add_trigger( repeat_stop_at_duration_end=False, execution_time_limit=None, delay=None, - **kwargs + **kwargs, ): r""" Add a trigger to a Windows Scheduled task @@ -2303,7 +2303,7 @@ def add_trigger( else: # Not found and create_new not set, return not found - return "{} not found".format(name) + return f"{name} not found" # Create a New Trigger trigger = task_definition.Triggers.Create(trigger_types[trigger_type]) @@ -2481,7 +2481,7 @@ def clear_triggers(name, location="\\"): """ # Check for existing task if name not in list_tasks(location): - return "{} not found in {}".format(name, location) + return f"{name} not found in {location}" # Create the task service object with salt.utils.winapi.Com(): diff --git a/salt/modules/x509_v2.py b/salt/modules/x509_v2.py index ba26d7b6b2e..f0b9b40130e 100644 --- a/salt/modules/x509_v2.py +++ b/salt/modules/x509_v2.py @@ -1907,7 +1907,7 @@ def _query_remote(ca_server, signing_policy, kwargs, get_signing_policy_only=Fal ) result = result[next(iter(result))] if not isinstance(result, dict) or "data" not in result: - log.error(f"Received invalid return value from ca_server: {result}") + log.error("Received invalid return value from ca_server: %s", result) raise CommandExecutionError( "Received invalid return value from ca_server. See minion log for details" ) diff --git a/salt/modules/xapi_virt.py b/salt/modules/xapi_virt.py index 489a5b2ed4a..2d03d231ffb 100644 --- a/salt/modules/xapi_virt.py +++ b/salt/modules/xapi_virt.py @@ -17,6 +17,7 @@ Useful documentation: """ import contextlib +import importlib import os import sys @@ -26,15 +27,6 @@ import salt.utils.path import salt.utils.stringutils from salt.exceptions import CommandExecutionError -try: - import importlib # pylint: disable=minimum-python-version - - HAS_IMPORTLIB = True -except ImportError: - # Python < 2.7 does not have importlib - HAS_IMPORTLIB = False - - # Define the module's virtual name __virtualname__ = "virt" @@ -50,14 +42,12 @@ def _check_xenapi(): if os.path.isfile(debian_xen_version): # __salt__ is not available in __virtual__ xenversion = salt.modules.cmdmod._run_quiet(debian_xen_version) - xapipath = "/usr/lib/xen-{}/lib/python".format(xenversion) + xapipath = f"/usr/lib/xen-{xenversion}/lib/python" if os.path.isdir(xapipath): sys.path.append(xapipath) try: - if HAS_IMPORTLIB: - return importlib.import_module("xen.xm.XenAPI") - return __import__("xen.xm.XenAPI").xm.XenAPI + return importlib.import_module("xen.xm.XenAPI") except (ImportError, AttributeError): return False @@ -156,7 +146,7 @@ def _get_metrics_record(xapi, rectype, record): Internal, returns metrics record for a rectype """ metrics_id = record["metrics"] - return getattr(xapi, "{}_metrics".format(rectype)).get_record(metrics_id) + return getattr(xapi, f"{rectype}_metrics").get_record(metrics_id) def _get_val(record, keys): @@ -507,10 +497,10 @@ def vcpu_pin(vm_, vcpu, cpus): if cpus == "all": cpumap = cpu_make_map("0-63") else: - cpumap = cpu_make_map("{}".format(cpus)) + cpumap = cpu_make_map(f"{cpus}") try: - xapi.VM.add_to_VCPUs_params_live(vm_uuid, "cpumap{}".format(vcpu), cpumap) + xapi.VM.add_to_VCPUs_params_live(vm_uuid, f"cpumap{vcpu}", cpumap) return True # VM.add_to_VCPUs_params_live() implementation in xend 4.1+ has # a bug which makes the client call fail. @@ -518,7 +508,7 @@ def vcpu_pin(vm_, vcpu, cpus): # for that particular one, fallback to xm / xl instead. except Exception: # pylint: disable=broad-except return __salt__["cmd.run"]( - "{} vcpu-pin {} {} {}".format(_get_xtool(), vm_, vcpu, cpus), + f"{_get_xtool()} vcpu-pin {vm_} {vcpu} {cpus}", python_shell=False, ) @@ -641,9 +631,7 @@ def start(config_): # This function does NOT use the XenAPI. Instead, it use good old xm / xl. # On Xen Source, creating a virtual machine using XenAPI is really painful. # XCP / XS make it really easy using xapi.Async.VM.start instead. Anyone? - return __salt__["cmd.run"]( - "{} create {}".format(_get_xtool(), config_), python_shell=False - ) + return __salt__["cmd.run"](f"{_get_xtool()} create {config_}", python_shell=False) def reboot(vm_): @@ -816,7 +804,7 @@ def vm_cputime(vm_=None): cputime_percent = (1.0e-7 * cputime / host_cpus) / vcpus return { "cputime": int(cputime), - "cputime_percent": int("{:.0f}".format(cputime_percent)), + "cputime_percent": int(f"{cputime_percent:.0f}"), } info = {} diff --git a/salt/modules/xfs.py b/salt/modules/xfs.py index 04b104f9967..b506cd965e7 100644 --- a/salt/modules/xfs.py +++ b/salt/modules/xfs.py @@ -319,7 +319,10 @@ def _blkid_output(out): """ Parse blkid output. """ - flt = lambda data: [el for el in data if el.strip()] + + def flt(data): + return [el for el in data if el.strip()] + data = {} for dev_meta in flt(out.split("\n\n")): dev = {} @@ -439,11 +442,13 @@ def mkfs( salt '*' xfs.mkfs /dev/sda1 dso='su=32k,sw=6' lso='logdev=/dev/sda2,size=10000b' """ - getopts = lambda args: dict( - (args and ("=" in args) and args or None) - and [kw.split("=") for kw in args.split(",")] - or [] - ) + def getopts(args): + return dict( + (args and ("=" in args) and args or None) + and [kw.split("=") for kw in args.split(",")] + or [] + ) + cmd = ["mkfs.xfs"] if label: cmd.append("-L") diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py index f794389c861..fa8e0eeffe3 100644 --- a/salt/modules/yumpkg.py +++ b/salt/modules/yumpkg.py @@ -397,7 +397,7 @@ def _get_yum_config_value(name, strict_config=True): Look for a specific config variable and return its value """ conf = _get_yum_config(strict_config) - if name in conf.keys(): + if name in conf: return conf.get(name) return None @@ -3135,7 +3135,9 @@ def mod_repo(repo, basedir=None, **kwargs): if key in filerepos[repo].copy().keys(): del filerepos[repo][key] - _bool_to_str = lambda x: "1" if x else "0" + def _bool_to_str(x): + return "1" if x else "0" + # Old file or new, write out the repos(s) filerepos[repo].update(repo_opts) content = header diff --git a/salt/modules/zcbuildout.py b/salt/modules/zcbuildout.py index 99b9202011e..3552d580890 100644 --- a/salt/modules/zcbuildout.py +++ b/salt/modules/zcbuildout.py @@ -287,7 +287,7 @@ def _Popen( directory = os.path.abspath(directory) if isinstance(command, list): command = " ".join(command) - LOG.debug("Running {}".format(command)) # pylint: disable=str-format-in-logging + LOG.debug(f"Running {command}") if not loglevel: loglevel = "debug" ret = __salt__["cmd.run_all"]( @@ -499,7 +499,7 @@ def upgrade_bootstrap( else: buildout_ver = _get_buildout_ver(directory) booturl = _get_bootstrap_url(directory) - LOG.debug("Using {}".format(booturl)) # pylint: disable=str-format-in-logging + LOG.debug(f"Using {booturl}") # try to download an up-to-date bootstrap # set defaulttimeout # and add possible content @@ -792,9 +792,7 @@ def run_buildout( cmds, outputs = [], [] if parts: for part in parts: - LOG.info( - "Installing single part: {}".format(part) - ) # pylint: disable=str-format-in-logging + LOG.info(f"Installing single part: {part}") cmd = "{} -c {} {} install {}".format(bcmd, config, " ".join(argv), part) cmds.append(cmd) outputs.append( @@ -960,9 +958,7 @@ def buildout( salt '*' buildout.buildout /srv/mybuildout """ - LOG.info( - "Running buildout in {} ({})".format(directory, config) - ) # pylint: disable=str-format-in-logging + LOG.info(f"Running buildout in {directory} ({config})") boot_ret = bootstrap( directory, config=config, diff --git a/salt/netapi/rest_cherrypy/__init__.py b/salt/netapi/rest_cherrypy/__init__.py index fbc85c9ff60..4580c6dc81b 100644 --- a/salt/netapi/rest_cherrypy/__init__.py +++ b/salt/netapi/rest_cherrypy/__init__.py @@ -28,7 +28,7 @@ cpy_min = "3.2.2" def __virtual__(): - short_name = __name__.rsplit(".")[-1] + short_name = __name__.rsplit(".", maxsplit=1)[-1] mod_opts = __opts__.get(short_name, {}) if mod_opts: diff --git a/salt/netapi/rest_cherrypy/app.py b/salt/netapi/rest_cherrypy/app.py index e65bca8f2d9..3a4571968b4 100644 --- a/salt/netapi/rest_cherrypy/app.py +++ b/salt/netapi/rest_cherrypy/app.py @@ -711,9 +711,9 @@ def salt_api_acl_tool(username, request): :param request: Cherrypy request to check against the API. :type request: cherrypy.request """ - failure_str = "[api_acl] Authentication failed for " "user %s from IP %s" + failure_str = "[api_acl] Authentication failed for user %s from IP %s" success_str = "[api_acl] Authentication successful for user %s from IP %s" - pass_str = "[api_acl] Authentication not checked for " "user %s from IP %s" + pass_str = "[api_acl] Authentication not checked for user %s from IP %s" acl = None # Salt Configuration @@ -777,7 +777,7 @@ def salt_auth_tool(): Redirect all unauthenticated requests to the login page """ # Redirect to the login page if the session hasn't been authed - if "token" not in cherrypy.session: # pylint: disable=W8601 + if "token" not in cherrypy.session: raise cherrypy.HTTPError(401) # Session is authenticated; inform caches @@ -1145,7 +1145,7 @@ for hook, tool_list in tools_config.items(): for idx, tool_config in enumerate(tool_list): tool_name, tool_fn = tool_config setattr( - cherrypy.tools, tool_name, cherrypy.Tool(hook, tool_fn, priority=(50 + idx)) + cherrypy.tools, tool_name, cherrypy.Tool(hook, tool_fn, priority=50 + idx) ) diff --git a/salt/netapi/rest_tornado/saltnado.py b/salt/netapi/rest_tornado/saltnado.py index 6d47de1446a..a0697bbc3fc 100644 --- a/salt/netapi/rest_tornado/saltnado.py +++ b/salt/netapi/rest_tornado/saltnado.py @@ -333,12 +333,12 @@ class EventListener: Get an event (asynchronous of course) return a future that will get it later """ future = Future() + _loop = salt.ext.tornado.ioloop.IOLoop.current() + assert _loop if callback is not None: def handle_future(future): - salt.ext.tornado.ioloop.IOLoop.current().add_callback( - callback, future - ) # pylint: disable=E1102 + _loop.add_callback(callback, future) # pylint: disable=not-callable future.add_done_callback(handle_future) # add this tag and future to the callbacks @@ -346,7 +346,7 @@ class EventListener: self.request_map[request].append((tag, matcher, future)) if timeout: - timeout_future = salt.ext.tornado.ioloop.IOLoop.current().call_later( + timeout_future = _loop.call_later( timeout, self._timeout_future, tag, matcher, future ) self.timeout_map[future] = timeout_future diff --git a/salt/output/pony.py b/salt/output/pony.py index 908b8b29392..f1d6d1e3d9a 100644 --- a/salt/output/pony.py +++ b/salt/output/pony.py @@ -66,6 +66,4 @@ def output(data, **kwargs): # pylint: disable=unused-argument Mane function """ high_out = __salt__["highstate"](data) - return subprocess.check_output( - ["ponysay", salt.utils.data.decode(high_out)] - ) # pylint: disable=E0598 + return subprocess.check_output(["ponysay", salt.utils.data.decode(high_out)]) diff --git a/salt/pillar/__init__.py b/salt/pillar/__init__.py index 9ad3c485fdf..dde097a209a 100644 --- a/salt/pillar/__init__.py +++ b/salt/pillar/__init__.py @@ -259,8 +259,8 @@ class AsyncRemotePillar(RemotePillarMixin): load["clean_cache"] = self.clean_cache if self.ext: load["ext"] = self.ext + start = time.monotonic() try: - start = time.monotonic() ret_pillar = yield self.channel.crypted_transfer_decode_dictentry( load, dictkey="pillar", @@ -357,8 +357,8 @@ class RemotePillar(RemotePillarMixin): if self.ext: load["ext"] = self.ext + start = time.monotonic() try: - start = time.monotonic() ret_pillar = self.channel.crypted_transfer_decode_dictentry( load, dictkey="pillar", @@ -1217,7 +1217,7 @@ class Pillar: errors.append( "Failed to load ext_pillar {}: {}".format( key, - exc.__str__(), + exc, ) ) log.error( diff --git a/salt/pillar/foreman.py b/salt/pillar/foreman.py index 62ae03072f2..298aae1ef20 100644 --- a/salt/pillar/foreman.py +++ b/salt/pillar/foreman.py @@ -111,6 +111,7 @@ def ext_pillar(minion_id, pillar, key=None, only=()): # pylint: disable=W0613 headers=headers, verify=verify, cert=(certfile, keyfile), + timeout=120, ) result = resp.json() diff --git a/salt/pillar/pepa.py b/salt/pillar/pepa.py index a35ebb47a09..842a14d49a3 100644 --- a/salt/pillar/pepa.py +++ b/salt/pillar/pepa.py @@ -291,7 +291,7 @@ except ImportError: # Only used when called from a terminal log = None if __name__ == "__main__": - import argparse # pylint: disable=minimum-python-version + import argparse parser = argparse.ArgumentParser() parser.add_argument("hostname", help="Hostname") @@ -611,11 +611,11 @@ if __name__ == "__main__": log.info("Authenticate REST API") auth = {"username": username, "password": password, "eauth": "pam"} - request = requests.post(args.url + "/login", auth) + request = requests.post(args.url + "/login", auth, timeout=120) if not request.ok: raise RuntimeError( - "Failed to authenticate to SaltStack REST API: {}".format(request.text) + f"Failed to authenticate to SaltStack REST API: {request.text}" ) response = request.json() @@ -623,7 +623,9 @@ if __name__ == "__main__": log.info("Request Grains from REST API") headers = {"X-Auth-Token": token, "Accept": "application/json"} - request = requests.get(args.url + "/minions/" + args.hostname, headers=headers) + request = requests.get( + args.url + "/minions/" + args.hostname, headers=headers, timeout=120 + ) result = request.json().get("return", [{}])[0] if args.hostname not in result: @@ -651,8 +653,8 @@ if __name__ == "__main__": if __opts__["pepa_validate"]: validate(result, __opts__["ext_pillar"][loc]["pepa"]["resource"]) + orig_ignore = salt.utils.yaml.SafeOrderedDumper.ignore_aliases try: - orig_ignore = salt.utils.yaml.SafeOrderedDumper.ignore_aliases salt.utils.yaml.SafeOrderedDumper.ignore_aliases = lambda x, y: True def _print_result(result): diff --git a/salt/pillar/vault.py b/salt/pillar/vault.py index 3e7d06b6f78..6388ab923dd 100644 --- a/salt/pillar/vault.py +++ b/salt/pillar/vault.py @@ -241,5 +241,5 @@ def _get_paths(path_pattern, minion_id, pillar): except KeyError: log.warning("Could not resolve pillar path pattern %s", path_pattern) - log.debug(f"{minion_id} vault pillar paths: {paths}") + log.debug("%s vault pillar paths: %s", minion_id, paths) return paths diff --git a/salt/pillar/vmware_pillar.py b/salt/pillar/vmware_pillar.py index cb93efed0da..41fd89a771d 100644 --- a/salt/pillar/vmware_pillar.py +++ b/salt/pillar/vmware_pillar.py @@ -483,5 +483,5 @@ def _serializer(obj): if isinstance(obj, datetime.datetime): if obj.utcoffset() is not None: obj = obj - obj.utcoffset() - return obj.__str__() + return str(obj) return obj diff --git a/salt/platform/win.py b/salt/platform/win.py index 694238e4fc0..fff1010039b 100644 --- a/salt/platform/win.py +++ b/salt/platform/win.py @@ -15,6 +15,7 @@ import logging import os from ctypes import wintypes +# pylint: disable=3rd-party-module-not-gated import ntsecuritycon import psutil import win32api @@ -23,6 +24,8 @@ import win32process import win32security import win32service +# pylint: enable=3rd-party-module-not-gated + # Set up logging log = logging.getLogger(__name__) @@ -398,7 +401,7 @@ class ContiguousUnicode(ctypes.Structure): @classmethod def from_address_copy(cls, address, size=None): - x = ctypes.Structure.__new__(cls) + x = ctypes.Structure.__new__(cls) # pylint: disable=no-value-for-parameter if size is not None: ctypes.resize(x, size) ctypes.memmove(ctypes.byref(x), address, ctypes.sizeof(x)) diff --git a/salt/proxy/dummy.py b/salt/proxy/dummy.py index d470c1082a7..8656be31d93 100644 --- a/salt/proxy/dummy.py +++ b/salt/proxy/dummy.py @@ -95,7 +95,7 @@ def init(opts): __context__["dummy_proxy"] = {"id": opts["id"]} log.debug("dummy proxy init() called...") with _loaded_state(opts) as state: - state["initialized"] = True + state["initialized"] = True # pylint: disable=unsupported-assignment-operation def initialized(): @@ -113,12 +113,12 @@ def grains(): Make up some grains """ with _loaded_state(__opts__) as state: - if "grains_cache" not in state: - state["grains_cache"] = { - "dummy_grain_1": "one", - "dummy_grain_2": "two", - "dummy_grain_3": "three", - } + # pylint: disable=unsupported-assignment-operation,unsupported-membership-test + state["grains_cache"] = { + "dummy_grain_1": "one", + "dummy_grain_2": "two", + "dummy_grain_3": "three", + } return state["grains_cache"] @@ -127,7 +127,7 @@ def grains_refresh(): Refresh the grains """ with _loaded_state(__opts__) as state: - if "grains_cache" in state: + if "grains_cache" in state: # pylint: disable=unsupported-membership-test state.pop("grains_cache") return grains() @@ -262,7 +262,7 @@ def shutdown(opts): """ log.debug("dummy proxy shutdown() called...") with _loaded_state(__opts__) as state: - if "filename" in state: + if "filename" in state: # pylint: disable=unsupported-membership-test os.unlink(state["filename"]) diff --git a/salt/proxy/philips_hue.py b/salt/proxy/philips_hue.py index 9b846baf096..d3400e3f66a 100644 --- a/salt/proxy/philips_hue.py +++ b/salt/proxy/philips_hue.py @@ -117,9 +117,9 @@ def _query(lamp_id, state, action="", method="GET"): # Because salt.utils.query is that dreadful... :( err = None - url = "{}/lights{}".format( - CONFIG["uri"], lamp_id and "/{}".format(lamp_id) or "" - ) + (action and "/{}".format(action) or "") + url = "{}/lights{}".format(CONFIG["uri"], lamp_id and f"/{lamp_id}" or "") + ( + action and f"/{action}" or "" + ) conn = http.client.HTTPConnection(CONFIG["host"]) if method == "PUT": conn.request(method, url, salt.utils.json.dumps(state)) @@ -130,7 +130,7 @@ def _query(lamp_id, state, action="", method="GET"): if resp.status == http.client.OK: res = salt.utils.json.loads(resp.read()) else: - err = "HTTP error: {}, {}".format(resp.status, resp.reason) + err = f"HTTP error: {resp.status}, {resp.reason}" conn.close() if err: raise CommandExecutionError(err) @@ -175,7 +175,7 @@ def _get_devices(params): raise CommandExecutionError("Parameter ID is required.") return ( - type(params["id"]) == int + isinstance(params["id"], int) and [params["id"]] or [int(dev) for dev in params["id"].split(",")] ) diff --git a/salt/renderers/genshi.py b/salt/renderers/genshi.py index 206cce5a3fe..9a9e57b6711 100644 --- a/salt/renderers/genshi.py +++ b/salt/renderers/genshi.py @@ -4,7 +4,9 @@ Genshi Renderer for Salt try: - from genshi.template import MarkupTemplate, NewTextTemplate, OldTextTemplate + from genshi.template import MarkupTemplate # pylint: disable=no-name-in-module + from genshi.template import NewTextTemplate # pylint: disable=no-name-in-module + from genshi.template import OldTextTemplate # pylint: disable=no-name-in-module HAS_LIBS = True except ImportError: diff --git a/salt/renderers/stateconf.py b/salt/renderers/stateconf.py index 3b0348633af..c93a564f0ed 100644 --- a/salt/renderers/stateconf.py +++ b/salt/renderers/stateconf.py @@ -65,7 +65,7 @@ STATE_FUNC = STATE_NAME = "" def __init__(opts): global STATE_NAME, STATE_FUNC STATE_FUNC = __opts__["stateconf_state_func"] - STATE_NAME = STATE_FUNC.split(".")[0] + STATE_NAME = STATE_FUNC.split(".", maxsplit=1)[0] MOD_BASENAME = os.path.basename(__file__) diff --git a/salt/returners/etcd_return.py b/salt/returners/etcd_return.py index fbac0e169df..fe1d1e4cf22 100644 --- a/salt/returners/etcd_return.py +++ b/salt/returners/etcd_return.py @@ -232,7 +232,7 @@ def get_fun(fun): client, path = _get_conn(__opts__) items = client.get("/".join((path, "minions")), recurse=True) for id, jid in items.items(): - id = str(id).split("/")[-1] + id = str(id).rsplit("/", maxsplit=1)[-1] efun = salt.utils.json.loads( client.get("/".join((path, "jobs", str(jid), id, "fun"))) ) @@ -251,7 +251,7 @@ def get_jids(): items = client.get("/".join((path, "jobs")), recurse=True) for key, value in items.items(): if isinstance(value, dict): # dict means directory - jid = str(key).split("/")[-1] + jid = str(key).rsplit("/", maxsplit=1)[-1] ret.append(jid) return ret @@ -265,7 +265,7 @@ def get_minions(): client, path = _get_conn(__opts__) items = client.get("/".join((path, "minions")), recurse=True) for id, _ in items.items(): - id = str(id).split("/")[-1] + id = str(id).rsplit("/", maxsplit=1)[-1] ret.append(id) return ret diff --git a/salt/returners/influxdb_return.py b/salt/returners/influxdb_return.py index 645218242aa..ff78d2b02d4 100644 --- a/salt/returners/influxdb_return.py +++ b/salt/returners/influxdb_return.py @@ -109,7 +109,7 @@ def _get_version(host, port, user, password): # check the InfluxDB version via the HTTP API try: result = requests.get( - "http://{}:{}/ping".format(host, port), auth=(user, password) + "http://{}:{}/ping".format(host, port), auth=(user, password), timeout=120 ) if influxDBVersionHeader in result.headers: version = result.headers[influxDBVersionHeader] diff --git a/salt/returners/local_cache.py b/salt/returners/local_cache.py index 1530d94ddfc..632e11c22e9 100644 --- a/salt/returners/local_cache.py +++ b/salt/returners/local_cache.py @@ -287,6 +287,7 @@ def get_load(jid): ret = {} load_p = os.path.join(jid_dir, LOAD_P) num_tries = 5 + exc = None for index in range(1, num_tries + 1): with salt.utils.files.fopen(load_p, "rb") as rfh: try: @@ -297,7 +298,8 @@ def get_load(jid): time.sleep(0.25) else: log.critical("Failed to unpack %s", load_p) - raise exc + if exc is not None: + raise exc if ret is None: ret = {} minions_cache = [os.path.join(jid_dir, MINIONS_P)] diff --git a/salt/returners/mysql.py b/salt/returners/mysql.py index 67b44004acf..6ad64bebb36 100644 --- a/salt/returners/mysql.py +++ b/salt/returners/mysql.py @@ -148,10 +148,6 @@ import salt.utils.data import salt.utils.job import salt.utils.json -# Let's not allow PyLint complain about string substitution -# pylint: disable=W1321,E1321 - - try: # Trying to import MySQLdb import MySQLdb @@ -274,7 +270,7 @@ def _get_serv(ret=None, commit=False): pass except OperationalError as exc: raise salt.exceptions.SaltMasterError( - "MySQL returner could not connect to database: {exc}".format(exc=exc) + f"MySQL returner could not connect to database: {exc}" ) cursor = conn.cursor() diff --git a/salt/returners/pgjsonb.py b/salt/returners/pgjsonb.py index d47e9cce8d6..86fd63b7441 100644 --- a/salt/returners/pgjsonb.py +++ b/salt/returners/pgjsonb.py @@ -170,10 +170,6 @@ import salt.returners import salt.utils.data import salt.utils.job -# Let's not allow PyLint complain about string substitution -# pylint: disable=W1321,E1321 - - try: import psycopg2 import psycopg2.extras @@ -225,7 +221,7 @@ def _get_options(ret=None): } _options = salt.returners.get_returner_options( - "returner.{}".format(__virtualname__), + f"returner.{__virtualname__}", ret, attrs, __salt__=__salt__, @@ -258,11 +254,11 @@ def _get_serv(ret=None, commit=False): dbname=_options.get("db"), user=_options.get("user"), password=_options.get("pass"), - **ssl_options + **ssl_options, ) except psycopg2.OperationalError as exc: raise salt.exceptions.SaltMasterError( - "pgjsonb returner could not connect to database: {exc}".format(exc=exc) + f"pgjsonb returner could not connect to database: {exc}" ) if conn.server_version is not None and conn.server_version >= 90500: diff --git a/salt/returners/splunk.py b/salt/returners/splunk.py index df3414bcacf..5e11a550e59 100644 --- a/salt/returners/splunk.py +++ b/salt/returners/splunk.py @@ -210,6 +210,7 @@ class http_event_collector: data=salt.utils.json.dumps(data), headers=headers, verify=self.verify_ssl, + timeout=120, ) # Print debug info if flag set diff --git a/salt/roster/cache.py b/salt/roster/cache.py index a6a117d2d8e..ebae66ba2d5 100644 --- a/salt/roster/cache.py +++ b/salt/roster/cache.py @@ -199,15 +199,21 @@ def _data_lookup(ref, lookup): def _minion_lookup(minion_id, key, minion): grains, pillar, addrs, mine = minion + def _data_lookup_ref(data_id): + if data_id == "pillar": + return pillar + if data_id == "grains": + return grains + if data_id == "mine": + return mine + if key == "id": # Just paste in the minion ID return minion_id elif isinstance(key, dict): # Lookup the key in the dict for data_id, lookup in key.items(): - ref = {"pillar": pillar, "grain": grains, "mine": mine}[data_id] - - for k in _data_lookup(ref, lookup): + for k in _data_lookup(_data_lookup_ref(data_id), lookup): if k: return k @@ -220,7 +226,7 @@ def _minion_lookup(minion_id, key, minion): try: net = ipaddress.ip_network(key, strict=True) except ValueError: - log.error("%s is an invalid CIDR network", net) + log.error("%s is an invalid CIDR network", key) return None for addr in addrs[net.version]: diff --git a/salt/runners/asam.py b/salt/runners/asam.py index 81e547b784b..6014429c792 100644 --- a/salt/runners/asam.py +++ b/salt/runners/asam.py @@ -146,7 +146,7 @@ def _get_asam_configuration(driver_url=""): def _make_post_request(url, data, auth, verify=True): - r = requests.post(url, data=data, auth=auth, verify=verify) + r = requests.post(url, data=data, auth=auth, verify=verify, timeout=120) if r.status_code != requests.codes.ok: r.raise_for_status() else: diff --git a/salt/runners/launchd.py b/salt/runners/launchd.py index ce9be4e3a9c..268668a79a1 100644 --- a/salt/runners/launchd.py +++ b/salt/runners/launchd.py @@ -51,8 +51,8 @@ def write_launchd_plist(program): sys.stderr.write("Supported programs: '{}'\n".format(supported_programs)) sys.exit(-1) - return plist_sample_text.format( - program=program, - python=sys.executable, - script=os.path.join(os.path.dirname(sys.executable), program), - ) + return plist_sample_text.format( + program=program, + python=sys.executable, + script=os.path.join(os.path.dirname(sys.executable), program), + ) diff --git a/salt/runners/pkg.py b/salt/runners/pkg.py index 6a4a06e6109..5d084b45032 100644 --- a/salt/runners/pkg.py +++ b/salt/runners/pkg.py @@ -40,7 +40,7 @@ def list_upgrades(jid, style="group", outputter="nested", ext_source=None): for minion in data: results = data[minion]["return"] for pkg, pkgver in results.items(): - if pkg not in pkgs.keys(): + if pkg not in pkgs: pkgs[pkg] = {pkgver: {"hosts": []}} if pkgver not in pkgs[pkg].keys(): diff --git a/salt/runners/state.py b/salt/runners/state.py index 3baf1b86346..e0e41a659ba 100644 --- a/salt/runners/state.py +++ b/salt/runners/state.py @@ -106,7 +106,9 @@ def orchestrate( orig_user = __opts__["user"] __opts__["user"] = __user__ log.debug( - f"changed opts user from original '{orig_user}' to global user '{__user__}'" + "changed opts user from original '%s' to global user '%s'", + orig_user, + __user__, ) except NameError: log.debug("unable to find global user __user__") diff --git a/salt/runners/vault.py b/salt/runners/vault.py index f7c5ce37f10..12225aea361 100644 --- a/salt/runners/vault.py +++ b/salt/runners/vault.py @@ -84,7 +84,7 @@ def generate_token( if namespace is not None: headers = {"X-Vault-Namespace": namespace} response = requests.post( - url, headers=headers, json=payload, verify=verify + url, headers=headers, json=payload, verify=verify, timeout=120 ) if response.status_code != 200: return {"error": response.reason} @@ -117,7 +117,9 @@ def generate_token( return {"error": "No policies matched minion"} log.trace("Sending token creation request to Vault") - response = requests.post(url, headers=headers, json=payload, verify=verify) + response = requests.post( + url, headers=headers, json=payload, verify=verify, timeout=120 + ) if response.status_code != 200: return {"error": response.reason} @@ -346,7 +348,7 @@ def _selftoken_expired(): # Add Vault namespace to headers if Vault Enterprise enabled if namespace is not None: headers["X-Vault-Namespace"] = namespace - response = requests.get(url, headers=headers, verify=verify) + response = requests.get(url, headers=headers, verify=verify, timeout=120) if response.status_code != 200: return True return False diff --git a/salt/scripts.py b/salt/scripts.py index 176cab56366..3c74fb5a3ef 100644 --- a/salt/scripts.py +++ b/salt/scripts.py @@ -483,16 +483,14 @@ def salt_cloud(): """ The main function for salt-cloud """ - # Define 'salt' global so we may use it after ImportError. Otherwise, - # UnboundLocalError will be raised. - global salt # pylint: disable=W0602 - try: # Late-imports for CLI performance import salt.cloud import salt.cloud.cli except ImportError as e: # No salt cloud on Windows + import salt.defaults.exitcodes + log.error("Error importing salt cloud: %s", e) print("salt-cloud is not available in this system") sys.exit(salt.defaults.exitcodes.EX_UNAVAILABLE) diff --git a/salt/serializers/msgpack.py b/salt/serializers/msgpack.py index 93a3fddeb3a..afcf93c3a39 100644 --- a/salt/serializers/msgpack.py +++ b/salt/serializers/msgpack.py @@ -5,109 +5,42 @@ Implements MsgPack serializer. """ - -import copy import logging import salt.utils.msgpack from salt.serializers import DeserializationError, SerializationError log = logging.getLogger(__name__) -available = salt.utils.msgpack.HAS_MSGPACK -if not available: +__all__ = ["deserialize", "serialize", "available"] - def _fail(): - raise RuntimeError("msgpack is not available") - - def _serialize(obj, **options): - _fail() - - def _deserialize(stream_or_string, **options): - _fail() - -elif salt.utils.msgpack.version >= (1, 0, 0): - - def _serialize(obj, **options): - try: - return salt.utils.msgpack.dumps(obj, **options) - except Exception as error: # pylint: disable=broad-except - raise SerializationError(error) - - def _deserialize(stream_or_string, **options): - try: - options.setdefault("use_list", True) - options.setdefault("raw", False) - return salt.utils.msgpack.loads(stream_or_string, **options) - except Exception as error: # pylint: disable=broad-except - raise DeserializationError(error) - -elif salt.utils.msgpack.version >= (0, 2, 0): - - def _serialize(obj, **options): - try: - return salt.utils.msgpack.dumps(obj, **options) - except Exception as error: # pylint: disable=broad-except - raise SerializationError(error) - - def _deserialize(stream_or_string, **options): - try: - options.setdefault("use_list", True) - options.setdefault("encoding", "utf-8") - return salt.utils.msgpack.loads(stream_or_string, **options) - except Exception as error: # pylint: disable=broad-except - raise DeserializationError(error) - -else: # msgpack.version < 0.2.0 - - def _encoder(obj): - """ - Since OrderedDict is identified as a dictionary, we can't make use of - msgpack custom types, we will need to convert by hand. - - This means iterating through all elements of dictionaries, lists and - tuples. - """ - if isinstance(obj, dict): - data = [(key, _encoder(value)) for key, value in obj.items()] - return dict(data) - elif isinstance(obj, (list, tuple)): - return [_encoder(value) for value in obj] - return copy.copy(obj) - - def _decoder(obj): - return obj - - def _serialize(obj, **options): - try: - obj = _encoder(obj) - return salt.utils.msgpack.dumps(obj, **options) - except Exception as error: # pylint: disable=broad-except - raise SerializationError(error) - - def _deserialize(stream_or_string, **options): - options.setdefault("use_list", True) - try: - obj = salt.utils.msgpack.loads(stream_or_string) - return _decoder(obj) - except Exception as error: # pylint: disable=broad-except - raise DeserializationError(error) +available = True -serialize = _serialize -deserialize = _deserialize - -serialize.__doc__ = """ +def serialize(obj, **options): + """ Serialize Python data to MsgPack. :param obj: the data structure to serialize :param options: options given to lower msgpack module. -""" + """ + try: + return salt.utils.msgpack.dumps(obj, **options) + except Exception as error: # pylint: disable=broad-except + raise SerializationError(error) -deserialize.__doc__ = """ + +def deserialize(stream_or_string, **options): + """ Deserialize any string of stream like object into a Python data structure. :param stream_or_string: stream or string to deserialize. :param options: options given to lower msgpack module. -""" + """ + try: + options.setdefault("use_list", True) + options.setdefault("raw", False) + return salt.utils.msgpack.loads(stream_or_string, **options) + except Exception as error: # pylint: disable=broad-except + raise DeserializationError(error) diff --git a/salt/serializers/yaml.py b/salt/serializers/yaml.py index e8a5e85e4b5..dc1099db448 100644 --- a/salt/serializers/yaml.py +++ b/salt/serializers/yaml.py @@ -90,7 +90,7 @@ class EncryptedString(str): @staticmethod def yaml_dumper(dumper, data): - return dumper.represent_scalar(EncryptedString.yaml_tag, data.__str__()) + return dumper.represent_scalar(EncryptedString.yaml_tag, str(data)) class Loader(BaseLoader): # pylint: disable=W0232 diff --git a/salt/state.py b/salt/state.py index 2e00933c0a4..9cd31e6ab8b 100644 --- a/salt/state.py +++ b/salt/state.py @@ -126,11 +126,9 @@ STATE_INTERNAL_KEYWORDS = STATE_REQUISITE_KEYWORDS.union( ).union(STATE_RUNTIME_KEYWORDS) -def _odict_hashable(self): - return id(self) - - -OrderedDict.__hash__ = _odict_hashable +class HashableOrderedDict(OrderedDict): + def __hash__(self): + return id(self) def split_low_tag(tag): @@ -448,7 +446,7 @@ class Compiler: errors = [] if not isinstance(high, dict): errors.append("High data is not a dictionary and is invalid") - reqs = OrderedDict() + reqs = HashableOrderedDict() if not errors: for name, body in high.items(): try: @@ -1490,7 +1488,7 @@ class State: errors = [] if not isinstance(high, dict): errors.append("High data is not a dictionary and is invalid") - reqs = OrderedDict() + reqs = HashableOrderedDict() for name, body in high.items(): try: if name.startswith("__"): @@ -1570,7 +1568,7 @@ class State: # It is a list, verify that the members of the # list are all single key dicts. else: - reqs[name] = OrderedDict(state=state) + reqs[name] = HashableOrderedDict(state=state) for req in arg[argfirst]: if isinstance(req, str): req = {"id": req} @@ -1945,7 +1943,7 @@ class State: # Not a use requisite_in found = False if name not in extend: - extend[name] = OrderedDict() + extend[name] = HashableOrderedDict() if "." in _state: errors.append( "Invalid requisite in {}: {} for " @@ -2033,7 +2031,7 @@ class State: if key == "prereq_in": # Add prerequired to origin if id_ not in extend: - extend[id_] = OrderedDict() + extend[id_] = HashableOrderedDict() if state not in extend[id_]: extend[id_][state] = [] extend[id_][state].append( @@ -2046,7 +2044,7 @@ class State: ) for ext_id, _req_state in ext_ids: if ext_id not in extend: - extend[ext_id] = OrderedDict() + extend[ext_id] = HashableOrderedDict() if _req_state not in extend[ext_id]: extend[ext_id][_req_state] = [] extend[ext_id][_req_state].append( @@ -2064,7 +2062,7 @@ class State: continue ext_args = state_args(ext_id, _state, high) if ext_id not in extend: - extend[ext_id] = OrderedDict() + extend[ext_id] = HashableOrderedDict() if _req_state not in extend[ext_id]: extend[ext_id][_req_state] = [] ignore_args = req_in_all.union(ext_args) @@ -2093,7 +2091,7 @@ class State: continue loc_args = state_args(id_, state, high) if id_ not in extend: - extend[id_] = OrderedDict() + extend[id_] = HashableOrderedDict() if state not in extend[id_]: extend[id_][state] = [] ignore_args = req_in_all.union(loc_args) @@ -2113,7 +2111,7 @@ class State: continue found = False if name not in extend: - extend[name] = OrderedDict() + extend[name] = HashableOrderedDict() if _state not in extend[name]: extend[name][_state] = [] extend[name]["__env__"] = body["__env__"] @@ -2948,7 +2946,7 @@ class State: " with name [{}]".format(req_key, chunk["name"]) ) except TypeError: - # On Python 2, the above req_val, being an OrderedDict, will raise a KeyError, + # On Python 2, the above req_val, being an HashableOrderedDict, will raise a KeyError, # however on Python 3 it will raise a TypeError # This was found when running tests.unit.test_state.StateCompilerTestCase.test_render_error_on_invalid_requisite raise SaltRenderError( @@ -3070,11 +3068,13 @@ class State: self.opts.get("state_events", True) or fire_event ): if not self.opts.get("master_uri"): - ev_func = ( - lambda ret, tag, preload=None: salt.utils.event.get_master_event( + + def ev_func(ret, tag, preload=None): + with salt.utils.event.get_master_event( self.opts, self.opts["sock_dir"], listen=False - ).fire_event(ret, tag) - ) + ) as _evt: + _evt.fire_event(ret, tag) + else: ev_func = self.functions["event.fire_master"] @@ -3738,8 +3738,8 @@ class LazyAvailStates: def items(self): self._fill() ret = [] - for saltenv, states in self._avail.items(): - ret.append((saltenv, self.__getitem__(saltenv))) + for saltenv in self._avail: + ret.append((saltenv, self[saltenv])) return ret @@ -3756,7 +3756,7 @@ class BaseHighState: self.opts = self.__gen_opts(opts) self.iorder = 10000 self.avail = self.__gather_avail() - self.building_highstate = OrderedDict() + self.building_highstate = HashableOrderedDict() def __gather_avail(self): """ @@ -3990,10 +3990,10 @@ class BaseHighState: environment from the top file will be considered, and it too will be ignored if that environment was defined in the "base" top file. """ - top = DefaultOrderedDict(OrderedDict) + top = DefaultOrderedDict(HashableOrderedDict) # Check base env first as it is authoritative - base_tops = tops.pop("base", DefaultOrderedDict(OrderedDict)) + base_tops = tops.pop("base", DefaultOrderedDict(HashableOrderedDict)) for ctop in base_tops: for saltenv, targets in ctop.items(): if saltenv == "include": @@ -4046,7 +4046,7 @@ class BaseHighState: sections matching a given saltenv, which appear in a different saltenv's top file, will be ignored. """ - top = DefaultOrderedDict(OrderedDict) + top = DefaultOrderedDict(HashableOrderedDict) for cenv, ctops in tops.items(): if all([x == {} for x in ctops]): # No top file found in this env, check the default_top @@ -4127,7 +4127,7 @@ class BaseHighState: states.append(item) return match_type, states - top = DefaultOrderedDict(OrderedDict) + top = DefaultOrderedDict(HashableOrderedDict) for ctops in tops.values(): for ctop in ctops: for saltenv, targets in ctop.items(): @@ -4223,7 +4223,7 @@ class BaseHighState: Returns: {'saltenv': ['state1', 'state2', ...]} """ - matches = DefaultOrderedDict(OrderedDict) + matches = DefaultOrderedDict(HashableOrderedDict) # pylint: disable=cell-var-from-loop for saltenv, body in top.items(): if self.opts["saltenv"]: diff --git a/salt/states/archive.py b/salt/states/archive.py index f3405b6ea0a..8de42988764 100644 --- a/salt/states/archive.py +++ b/salt/states/archive.py @@ -119,7 +119,7 @@ def _update_checksum(path): log.warning( "Failed to update checksum for %s: %s", path, - exc.__str__(), + exc, exc_info=True, ) @@ -1066,7 +1066,7 @@ def extracted( ) except Exception as exc: # pylint: disable=broad-except msg = "Failed to cache {}: {}".format( - salt.utils.url.redact_http_basic_auth(source_match), exc.__str__() + salt.utils.url.redact_http_basic_auth(source_match), exc ) log.exception(msg) ret["comment"] = msg @@ -1208,7 +1208,7 @@ def extracted( else: ret["comment"] = ( "Failed to check for existence of if_missing path " - "({}): {}".format(if_missing, exc.__str__()) + "({}): {}".format(if_missing, exc) ) return ret else: @@ -1237,7 +1237,7 @@ def extracted( # that dir will raise an ENOTDIR OSError. So we # expect these and will only abort here if the # error code is something else. - ret["comment"] = exc.__str__() + ret["comment"] = str(exc) return ret if incorrect_type: @@ -1288,7 +1288,7 @@ def extracted( extraction_needed = True except OSError as exc: if exc.errno != errno.ENOENT: - errors.append(exc.__str__()) + errors.append(str(exc)) if errors: msg = ( "One or more paths existed by were the incorrect " @@ -1369,7 +1369,7 @@ def extracted( ret["changes"].setdefault("removed", []).append(full_path) except OSError as exc: if exc.errno != errno.ENOENT: - errors.append(exc.__str__()) + errors.append(str(exc)) if errors: msg = ( diff --git a/salt/states/boto3_route53.py b/salt/states/boto3_route53.py index 3edbc57a870..56f93256fbe 100644 --- a/salt/states/boto3_route53.py +++ b/salt/states/boto3_route53.py @@ -61,7 +61,6 @@ passed in as a dict, or as a string to pull from pillars or minion config: """ # keep lint from choking # pylint: disable=W0106 -# pylint: disable=E1320 import logging @@ -71,7 +70,7 @@ import salt.utils.data import salt.utils.dictupdate from salt.exceptions import SaltInvocationError -log = logging.getLogger(__name__) # pylint: disable=W1699 +log = logging.getLogger(__name__) def __virtual__(): diff --git a/salt/states/docker_container.py b/salt/states/docker_container.py index 17e11ed2ed7..da18c2c6d17 100644 --- a/salt/states/docker_container.py +++ b/salt/states/docker_container.py @@ -1686,7 +1686,7 @@ def running( if exc.info is not None: return _format_comments(ret, exc.info) else: - ret["comment"] = exc.__str__() + ret["comment"] = str(exc) return ret comments = [] @@ -1753,7 +1753,7 @@ def running( return _format_comments(ret, comments) except Exception as exc: # pylint: disable=broad-except ret["result"] = False - msg = exc.__str__() + msg = str(exc) if ( isinstance(exc, CommandExecutionError) and isinstance(exc.info, dict) @@ -1810,7 +1810,7 @@ def running( # of the network's subnet. An exception will be raised once # you try to start the container, however. ret["result"] = False - comments.append(exc.__str__()) + comments.append(str(exc)) return _format_comments(ret, comments) post_net_connect = __salt__["docker.inspect_container"](temp_container_name) @@ -1943,7 +1943,7 @@ def running( ) disconnected = True except CommandExecutionError as exc: - errors.append(exc.__str__()) + errors.append(str(exc)) if net_name in networks: try: @@ -1952,7 +1952,7 @@ def running( ) connected = True except CommandExecutionError as exc: - errors.append(exc.__str__()) + errors.append(str(exc)) if disconnected: # We succeeded in disconnecting but failed # to reconnect. This can happen if the @@ -2205,7 +2205,7 @@ def run( if exc.info is not None: return _format_comments(ret, exc.info) else: - ret["comment"] = exc.__str__() + ret["comment"] = str(exc) return ret if __opts__["test"]: diff --git a/salt/states/docker_image.py b/salt/states/docker_image.py index 10bca898c3e..6dbce1b7cac 100644 --- a/salt/states/docker_image.py +++ b/salt/states/docker_image.py @@ -247,7 +247,7 @@ def present( try: image_info = __salt__["docker.inspect_image"](full_image) except CommandExecutionError as exc: - msg = exc.__str__() + msg = str(exc) if "404" in msg: # Image not present image_info = None @@ -355,7 +355,7 @@ def present( try: __salt__["docker.inspect_image"](full_image) except CommandExecutionError as exc: - msg = exc.__str__() + msg = str(exc) if "404" not in msg: error = "Failed to inspect image '{}' after it was {}: {}".format( full_image, action, msg diff --git a/salt/states/docker_network.py b/salt/states/docker_network.py index 38e9027a1a2..94ca9696649 100644 --- a/salt/states/docker_network.py +++ b/salt/states/docker_network.py @@ -523,7 +523,7 @@ def present( try: network = __salt__["docker.inspect_network"](name) except CommandExecutionError as exc: - msg = exc.__str__() + msg = str(exc) if "404" in msg: # Network not present network = None @@ -578,7 +578,7 @@ def present( **__utils__["args.clean_kwargs"](**kwargs) ) except Exception as exc: # pylint: disable=broad-except - ret["comment"] = exc.__str__() + ret["comment"] = str(exc) return ret # Separate out the IPAM config options and build the IPAM config dict @@ -607,7 +607,7 @@ def present( *ipam_pools, **ipam_kwargs ) except Exception as exc: # pylint: disable=broad-except - ret["comment"] = exc.__str__() + ret["comment"] = str(exc) return ret # We'll turn this off if we decide below that creating the network is not @@ -662,7 +662,7 @@ def present( ) except CommandExecutionError as exc: ret["comment"] = "Failed to create temp network for comparison: {}".format( - exc.__str__() + str(exc) ) return ret else: @@ -674,9 +674,7 @@ def present( try: temp_net_info = __salt__["docker.inspect_network"](temp_net_name) except CommandExecutionError as exc: - ret["comment"] = "Failed to inspect temp network: {}".format( - exc.__str__() - ) + ret["comment"] = "Failed to inspect temp network: {}".format(str(exc)) return ret else: temp_net_info["EnableIPv6"] = bool(enable_ipv6) @@ -690,9 +688,8 @@ def present( existing_pool_count = len(network["IPAM"]["Config"]) desired_pool_count = len(temp_net_info["IPAM"]["Config"]) - is_default_pool = ( - lambda x: True if sorted(x) == ["Gateway", "Subnet"] else False - ) + def is_default_pool(x): + return True if sorted(x) == ["Gateway", "Subnet"] else False if ( desired_pool_count == 0 @@ -776,9 +773,7 @@ def present( __salt__["docker.remove_network"](temp_net_name) except CommandExecutionError as exc: ret.setdefault("warnings", []).append( - "Failed to remove temp network '{}': {}.".format( - temp_net_name, exc.__str__() - ) + "Failed to remove temp network '{}': {}.".format(temp_net_name, exc) ) if create_network: @@ -803,9 +798,7 @@ def present( **kwargs ) except Exception as exc: # pylint: disable=broad-except - ret["comment"] = "Failed to create network '{}': {}".format( - name, exc.__str__() - ) + ret["comment"] = "Failed to create network '{}': {}".format(name, exc) return ret else: action = "recreated" if network is not None else "created" @@ -859,14 +852,14 @@ def present( ) except CommandExecutionError as exc: if not connect_kwargs: - errors.append(exc.__str__()) + errors.append(str(exc)) else: # We failed to reconnect with the container's old IP # configuration. Reconnect using automatic IP config. try: __salt__["docker.connect_container_to_network"](cid, name) except CommandExecutionError as exc: - errors.append(exc.__str__()) + errors.append(str(exc)) else: ret["changes"].setdefault( "reconnected" @@ -917,7 +910,7 @@ def absent(name): try: network = __salt__["docker.inspect_network"](name) except CommandExecutionError as exc: - msg = exc.__str__() + msg = str(exc) if "404" in msg: # Network not present network = None diff --git a/salt/states/environ.py b/salt/states/environ.py index fb495d1af44..c561fb899d4 100644 --- a/salt/states/environ.py +++ b/salt/states/environ.py @@ -131,6 +131,7 @@ def setenv( r" Manager\Environment" ) + # pylint: disable=cell-var-from-loop out = __utils__["reg.read_value"]( permanent_hive, permanent_key, _norm_key(key) ) diff --git a/salt/states/file.py b/salt/states/file.py index e36db6f2468..3c6b28ad163 100644 --- a/salt/states/file.py +++ b/salt/states/file.py @@ -567,6 +567,8 @@ def _gen_keep_files(name, require, walk_d=None): like directory or recurse has a clean. """ + walk_ret = set() + def _is_child(path, directory): """ Check whether ``path`` is child of ``directory`` @@ -1233,7 +1235,9 @@ def _shortcut_check( if os.path.isfile(name): with salt.utils.winapi.Com(): - shell = win32com.client.Dispatch("WScript.Shell") + shell = win32com.client.Dispatch( # pylint: disable=used-before-assignment + "WScript.Shell" + ) scut = shell.CreateShortcut(name) state_checks = [scut.TargetPath.lower() == target.lower()] if arguments is not None: @@ -9063,7 +9067,7 @@ def cached( name, saltenv=saltenv, source_hash=source_sum.get("hsum"), use_etag=use_etag ) except Exception as exc: # pylint: disable=broad-except - ret["comment"] = salt.utils.url.redact_http_basic_auth(exc.__str__()) + ret["comment"] = salt.utils.url.redact_http_basic_auth(str(exc)) return ret if not local_copy: @@ -9150,7 +9154,7 @@ def not_cached(name, saltenv="base"): try: os.remove(local_copy) except Exception as exc: # pylint: disable=broad-except - ret["comment"] = "Failed to delete {}: {}".format(local_copy, exc.__str__()) + ret["comment"] = "Failed to delete {}: {}".format(local_copy, exc) else: ret["result"] = True ret["changes"]["deleted"] = True diff --git a/salt/states/git.py b/salt/states/git.py index 0f3f977442e..32a597ec74d 100644 --- a/salt/states/git.py +++ b/salt/states/git.py @@ -144,7 +144,7 @@ def _strip_exc(exc): def _uptodate(ret, target, comments=None, local_changes=False): - ret["comment"] = "Repository {} is up-to-date".format(target) + ret["comment"] = f"Repository {target} is up-to-date" if local_changes: ret["comment"] += ( ", but with uncommitted changes. Set 'force_reset' to True to " @@ -177,7 +177,7 @@ def _fail(ret, msg, comments=None): def _already_cloned(ret, target, branch=None, comments=None): ret["result"] = True ret["comment"] = "Repository already exists at {}{}".format( - target, " and is checked out to branch '{}'".format(branch) if branch else "" + target, f" and is checked out to branch '{branch}'" if branch else "" ) if comments: ret["comment"] += "\n\nChanges {}made: {}".format( @@ -234,10 +234,8 @@ def _not_fast_forward( ret, "Repository would be updated {}{}, but {}. Set 'force_reset' to " "True{} to force this update{}.{}".format( - "from {} to {}".format(pre, post) - if local_changes and pre != post - else "to {}".format(post), - " (after checking out local branch '{}')".format(branch) + f"from {pre} to {post}" if local_changes and pre != post else f"to {post}", + f" (after checking out local branch '{branch}')" if _need_branch_change(branch, local_branch) else "", "this is not a fast-forward merge" @@ -276,7 +274,7 @@ def latest( refspec_branch="*", refspec_tag="*", output_encoding=None, - **kwargs + **kwargs, ): """ Make sure the repository is cloned to the given directory and is @@ -619,9 +617,7 @@ def latest( return _fail(ret, "'target' argument is required") if not rev: - return _fail( - ret, "'{}' is not a valid value for the 'rev' argument".format(rev) - ) + return _fail(ret, f"'{rev}' is not a valid value for the 'rev' argument") if force_reset not in (True, False, "remote-changes"): return _fail( @@ -635,7 +631,7 @@ def latest( if not isinstance(target, str): target = str(target) if not os.path.isabs(target): - return _fail(ret, "target '{}' is not an absolute path".format(target)) + return _fail(ret, f"target '{target}' is not an absolute path") if branch is not None and not isinstance(branch, str): branch = str(branch) if user is not None and not isinstance(user, str): @@ -656,13 +652,9 @@ def latest( ident_path = __salt__["cp.cache_file"](ident_path, __env__) except OSError as exc: log.exception("Failed to cache %s", ident_path) - return _fail( - ret, "identity '{}' does not exist.".format(ident_path) - ) + return _fail(ret, f"identity '{ident_path}' does not exist.") if not os.path.isabs(ident_path): - return _fail( - ret, "identity '{}' is not an absolute path".format(ident_path) - ) + return _fail(ret, f"identity '{ident_path}' is not an absolute path") if https_user is not None and not isinstance(https_user, str): https_user = str(https_user) if https_pass is not None and not isinstance(https_pass, str): @@ -681,7 +673,7 @@ def latest( if os.path.isfile(target): return _fail( ret, - "Target '{}' exists and is a regular file, cannot proceed".format(target), + f"Target '{target}' exists and is a regular file, cannot proceed", ) try: @@ -689,7 +681,7 @@ def latest( name, https_user, https_pass, https_only=True ) except ValueError as exc: - return _fail(ret, exc.__str__()) + return _fail(ret, str(exc)) redacted_fetch_url = salt.utils.url.redact_http_basic_auth(desired_fetch_url) @@ -731,7 +723,7 @@ def latest( output_encoding=output_encoding, ) except CommandExecutionError as exc: - return _fail(ret, "Failed to check remote refs: {}".format(_strip_exc(exc))) + return _fail(ret, f"Failed to check remote refs: {_strip_exc(exc)}") if "HEAD" in all_remote_refs: head_rev = all_remote_refs["HEAD"] @@ -825,7 +817,7 @@ def latest( # remote repo. return _fail( ret, - "No revision matching '{}' exists in the remote repository".format(rev), + f"No revision matching '{rev}' exists in the remote repository", ) git_ver = Version(__salt__["git.version"](versioninfo=False)) @@ -1067,6 +1059,7 @@ def latest( if (not revs_match and not update_head) and ( branch is None or branch == local_branch ): + # pylint: disable=used-before-assignment ret["comment"] = ( "{} is already present and local HEAD ({}) does not " "match, but update_head=False. HEAD has not been " @@ -1200,9 +1193,7 @@ def latest( output_encoding=output_encoding, ) if fetch_url is None: - comments.append( - "Remote '{}' set to {}".format(remote, redacted_fetch_url) - ) + comments.append(f"Remote '{remote}' set to {redacted_fetch_url}") ret["changes"]["new"] = name + " => " + remote else: comments.append( @@ -1217,7 +1208,7 @@ def latest( if __opts__["test"]: actions = [] if not has_remote_rev: - actions.append("Remote '{}' would be fetched".format(remote)) + actions.append(f"Remote '{remote}' would be fetched") if (not revs_match) and ( update_head or (branch is not None and branch != local_branch) ): @@ -1418,7 +1409,7 @@ def latest( else: if fetch_changes: comments.append( - "{} was fetched, resulting in updated refs".format(name) + f"{name} was fetched, resulting in updated refs" ) try: @@ -1518,7 +1509,7 @@ def latest( "as a starting point".format(branch, remote_loc) ) else: - comments.append("'{}' was checked out".format(checkout_rev)) + comments.append(f"'{checkout_rev}' was checked out") if fast_forward is False: __salt__["git.reset"]( @@ -1527,14 +1518,12 @@ def latest( user=user, password=password, output_encoding=output_encoding, - **lfs_opts + **lfs_opts, ) ret["changes"]["forced update"] = True if local_changes: comments.append("Uncommitted changes were discarded") - comments.append( - "Repository was hard-reset to {}".format(remote_loc) - ) + comments.append(f"Repository was hard-reset to {remote_loc}") elif ( fast_forward is True and local_changes and force_reset is not False ): @@ -1595,10 +1584,10 @@ def latest( user=user, password=password, output_encoding=output_encoding, - **lfs_opts + **lfs_opts, ) comments.append( - "Repository was fast-forwarded to {}".format(remote_loc) + f"Repository was fast-forwarded to {remote_loc}" ) else: return _fail( @@ -1615,11 +1604,9 @@ def latest( user=user, password=password, output_encoding=output_encoding, - **lfs_opts - ) - comments.append( - "Repository was reset to {} (fast-forward)".format(rev) + **lfs_opts, ) + comments.append(f"Repository was reset to {rev} (fast-forward)") # TODO: Figure out how to add submodule update info to # test=True return data, and changes dict. @@ -1639,7 +1626,7 @@ def latest( return _failed_submodule_update(ret, exc, comments) elif bare: if __opts__["test"]: - msg = "Bare repository at {} would be fetched".format(target) + msg = f"Bare repository at {target} would be fetched" if ret["changes"]: return _neutral_test(ret, msg) else: @@ -1724,9 +1711,7 @@ def latest( if exc.errno != errno.ENOENT: removal_errors[target_path] = exc if removal_errors: - err_strings = [ - " {}\n {}".format(k, v) for k, v in removal_errors.items() - ] + err_strings = [f" {k}\n {v}" for k, v in removal_errors.items()] return _fail( ret, "Unable to remove\n{}".format("\n".join(err_strings)), @@ -1747,9 +1732,7 @@ def latest( log.debug("Target %s is not found, 'git clone' is required", target) if __opts__["test"]: ret["changes"]["new"] = name + " => " + target - return _neutral_test( - ret, "Repository {} would be cloned to {}".format(name, target) - ) + return _neutral_test(ret, f"Repository {name} would be cloned to {target}") try: clone_opts = ["--mirror"] if mirror else ["--bare"] if bare else [] if remote != "origin": @@ -1774,7 +1757,7 @@ def latest( output_encoding=output_encoding, ) except CommandExecutionError as exc: - msg = "Clone failed: {}".format(_strip_exc(exc)) + msg = f"Clone failed: {_strip_exc(exc)}" return _fail(ret, msg, comments) ret["changes"]["new"] = name + " => " + target @@ -1799,9 +1782,7 @@ def latest( ) log.error(msg, name) # Disable check for string substitution - return _fail( - ret, msg % "Repository", comments - ) # pylint: disable=E1321 + return _fail(ret, msg % "Repository", comments) else: if remote_rev_type == "tag" and rev not in __salt__[ "git.list_tags" @@ -1813,7 +1794,7 @@ def latest( ): return _fail( ret, - "Revision '{}' does not exist in clone".format(rev), + f"Revision '{rev}' does not exist in clone", comments, ) @@ -1872,7 +1853,7 @@ def latest( password=password, output_encoding=output_encoding, ) - comments.append("Repository was reset to {}".format(remote_loc)) + comments.append(f"Repository was reset to {remote_loc}") try: upstream = __salt__["git.rev_parse"]( @@ -2110,7 +2091,7 @@ def present( else: salt.utils.files.rm_rf(name) except OSError as exc: - return _fail(ret, "Unable to remove {}: {}".format(name, exc)) + return _fail(ret, f"Unable to remove {name}: {exc}") else: ret["changes"]["forced init"] = True elif os.listdir(name): @@ -2142,9 +2123,9 @@ def present( actions = ["Initialized {}repository in {}".format("bare " if bare else "", name)] if template: - actions.append("Template directory set to {}".format(template)) + actions.append(f"Template directory set to {template}") if separate_git_dir: - actions.append("Gitdir set to {}".format(separate_git_dir)) + actions.append(f"Gitdir set to {separate_git_dir}") message = ". ".join(actions) if len(actions) > 1: message += "." @@ -2170,7 +2151,7 @@ def detached( https_user=None, https_pass=None, output_encoding=None, - **kwargs + **kwargs, ): """ .. versionadded:: 2016.3.0 @@ -2261,14 +2242,10 @@ def detached( return _fail(ret, salt.utils.args.invalid_kwargs(kwargs, raise_exc=False)) if not rev: - return _fail( - ret, "'{}' is not a valid value for the 'rev' argument".format(rev) - ) + return _fail(ret, f"'{rev}' is not a valid value for the 'rev' argument") if not target: - return _fail( - ret, "'{}' is not a valid value for the 'target' argument".format(rev) - ) + return _fail(ret, f"'{rev}' is not a valid value for the 'target' argument") # Ensure that certain arguments are strings to ensure that comparisons work if not isinstance(rev, str): @@ -2277,7 +2254,7 @@ def detached( if not isinstance(target, str): target = str(target) if not os.path.isabs(target): - return _fail(ret, "Target '{}' is not an absolute path".format(target)) + return _fail(ret, f"Target '{target}' is not an absolute path") if user is not None and not isinstance(user, str): user = str(user) if remote is not None and not isinstance(remote, str): @@ -2294,13 +2271,9 @@ def detached( ident_path = __salt__["cp.cache_file"](ident_path) except OSError as exc: log.error("Failed to cache %s: %s", ident_path, exc) - return _fail( - ret, "Identity '{}' does not exist.".format(ident_path) - ) + return _fail(ret, f"Identity '{ident_path}' does not exist.") if not os.path.isabs(ident_path): - return _fail( - ret, "Identity '{}' is not an absolute path".format(ident_path) - ) + return _fail(ret, f"Identity '{ident_path}' is not an absolute path") if https_user is not None and not isinstance(https_user, str): https_user = str(https_user) if https_pass is not None and not isinstance(https_pass, str): @@ -2309,7 +2282,7 @@ def detached( if os.path.isfile(target): return _fail( ret, - "Target '{}' exists and is a regular file, cannot proceed".format(target), + f"Target '{target}' exists and is a regular file, cannot proceed", ) try: @@ -2317,7 +2290,7 @@ def detached( name, https_user, https_pass, https_only=True ) except ValueError as exc: - return _fail(ret, exc.__str__()) + return _fail(ret, str(exc)) redacted_fetch_url = salt.utils.url.redact_http_basic_auth(desired_fetch_url) @@ -2377,9 +2350,7 @@ def detached( current_fetch_url = remotes[remote]["fetch"] if __opts__["test"]: - return _neutral_test( - ret, "Remote {} would be set to {}".format(remote, name) - ) + return _neutral_test(ret, f"Remote {remote} would be set to {name}") __salt__["git.remote_set"]( target, @@ -2427,9 +2398,7 @@ def detached( if exc.errno != errno.ENOENT: removal_errors[target_path] = exc if removal_errors: - err_strings = [ - " {}\n {}".format(k, v) for k, v in removal_errors.items() - ] + err_strings = [f" {k}\n {v}" for k, v in removal_errors.items()] return _fail( ret, "Unable to remove\n{}".format("\n".join(err_strings)), @@ -2449,9 +2418,7 @@ def detached( log.debug("Target %s is not found, 'git clone' is required", target) if __opts__["test"]: - return _neutral_test( - ret, "Repository {} would be cloned to {}".format(name, target) - ) + return _neutral_test(ret, f"Repository {name} would be cloned to {target}") try: clone_opts = ["--no-checkout"] if remote != "origin": @@ -2469,7 +2436,7 @@ def detached( saltenv=__env__, output_encoding=output_encoding, ) - comments.append("{} cloned to {}".format(name, target)) + comments.append(f"{name} cloned to {target}") except Exception as exc: # pylint: disable=broad-except log.error("Unexpected exception in git.detached state", exc_info=True) @@ -2481,7 +2448,7 @@ def detached( # Repository exists and is ready for fetch/checkout refspecs = [ - "refs/heads/*:refs/remotes/{}/*".format(remote), + f"refs/heads/*:refs/remotes/{remote}/*", "+refs/tags/*:refs/tags/*", ] if hash_exists_locally or fetch_remote is False: @@ -2489,9 +2456,7 @@ def detached( else: # Fetch refs from remote if __opts__["test"]: - return _neutral_test( - ret, "Repository remote {} would be fetched".format(remote) - ) + return _neutral_test(ret, f"Repository remote {remote} would be fetched") try: fetch_changes = __salt__["git.fetch"]( target, @@ -2511,7 +2476,7 @@ def detached( else: if fetch_changes: comments.append( - "Remote {} was fetched, resulting in updated refs".format(remote) + f"Remote {remote} was fetched, resulting in updated refs" ) # get refs and checkout @@ -2522,7 +2487,7 @@ def detached( ): checkout_commit_id = rev else: - return _fail(ret, "Revision '{}' does not exist".format(rev)) + return _fail(ret, f"Revision '{rev}' does not exist") else: try: all_remote_refs = __salt__["git.remote_refs"]( @@ -2543,17 +2508,15 @@ def detached( elif "refs/tags/" + rev in all_remote_refs: checkout_commit_id = all_remote_refs["refs/tags/" + rev] else: - return _fail(ret, "Revision '{}' does not exist".format(rev)) + return _fail(ret, f"Revision '{rev}' does not exist") except CommandExecutionError as exc: - return _fail( - ret, "Failed to list refs for {}: {}".format(remote, _strip_exc(exc)) - ) + return _fail(ret, f"Failed to list refs for {remote}: {_strip_exc(exc)}") if hard_reset: if __opts__["test"]: return _neutral_test( - ret, "Hard reset to HEAD would be performed on {}".format(target) + ret, f"Hard reset to HEAD would be performed on {target}" ) __salt__["git.reset"]( target, @@ -2585,9 +2548,7 @@ def detached( password=password, output_encoding=output_encoding, ) - comments.append( - "Commit ID {} was checked out at {}".format(checkout_commit_id, target) - ) + comments.append(f"Commit ID {checkout_commit_id} was checked out at {target}") try: new_rev = __salt__["git.revision"]( @@ -2734,7 +2695,7 @@ def cloned( comment = "{} would be cloned to {}{}".format( name, target, - " with branch '{}'".format(branch) if branch is not None else "", + f" with branch '{branch}'" if branch is not None else "", ) return _neutral_test(ret, comment) clone_opts = ["--branch", branch] if branch is not None else None @@ -2751,14 +2712,14 @@ def cloned( output_encoding=output_encoding, ) except CommandExecutionError as exc: - msg = "Clone failed: {}".format(_strip_exc(exc)) + msg = f"Clone failed: {_strip_exc(exc)}" return _fail(ret, msg, comments) comments.append( "{} cloned to {}{}".format( name, target, - " with branch '{}'".format(branch) if branch is not None else "", + f" with branch '{branch}'" if branch is not None else "", ) ) _clone_changes(ret) @@ -2777,9 +2738,7 @@ def cloned( else: if __opts__["test"]: _branch_changes(ret, current_branch, branch) - return _neutral_test( - ret, "Branch would be changed to '{}'".format(branch) - ) + return _neutral_test(ret, f"Branch would be changed to '{branch}'") try: __salt__["git.rev_parse"]( target, @@ -2809,10 +2768,10 @@ def cloned( output_encoding=output_encoding, ) except CommandExecutionError as exc: - msg = "Failed to change branch to '{}': {}".format(branch, exc) + msg = f"Failed to change branch to '{branch}': {exc}" return _fail(ret, msg, comments) else: - comments.append("Branch changed to '{}'".format(branch)) + comments.append(f"Branch changed to '{branch}'") _branch_changes(ret, current_branch, branch) ret["comment"] = _format_comments(comments) ret["result"] = True @@ -2826,7 +2785,7 @@ def config_unset( user=None, password=None, output_encoding=None, - **kwargs + **kwargs, ): r""" .. versionadded:: 2015.8.0 @@ -2951,7 +2910,7 @@ def config_unset( password=password, ignore_retcode=True, output_encoding=output_encoding, - **{"global": global_} + **{"global": global_}, ) if not pre_matches: @@ -2984,7 +2943,7 @@ def config_unset( if __opts__["test"]: ret["changes"] = pre_matches return _neutral_test( - ret, "{} key(s) would have value(s) unset".format(len(pre_matches)) + ret, f"{len(pre_matches)} key(s) would have value(s) unset" ) if value_regex is None: @@ -3000,7 +2959,7 @@ def config_unset( password=password, ignore_retcode=True, output_encoding=output_encoding, - **{"global": global_} + **{"global": global_}, ) failed = [] @@ -3016,10 +2975,10 @@ def config_unset( user=user, password=password, output_encoding=output_encoding, - **{"global": global_} + **{"global": global_}, ) except CommandExecutionError as exc: - msg = "Failed to unset '{}'".format(key_name) + msg = f"Failed to unset '{key_name}'" if value_regex is not None: msg += " using value_regex '{1}'" msg += ": " + _strip_exc(exc) @@ -3041,7 +3000,7 @@ def config_unset( password=password, ignore_retcode=True, output_encoding=output_encoding, - **{"global": global_} + **{"global": global_}, ) for key_name in pre: @@ -3062,7 +3021,7 @@ def config_unset( password=password, ignore_retcode=True, output_encoding=output_encoding, - **{"global": global_} + **{"global": global_}, ) if post_matches: @@ -3081,7 +3040,7 @@ def config_set( user=None, password=None, output_encoding=None, - **kwargs + **kwargs, ): """ .. versionadded:: 2014.7.0 @@ -3219,7 +3178,7 @@ def config_set( password=password, ignore_retcode=True, output_encoding=output_encoding, - **{"all": True, "global": global_} + **{"all": True, "global": global_}, ) if desired == pre: @@ -3248,7 +3207,7 @@ def config_set( user=user, password=password, output_encoding=output_encoding, - **{"global": global_} + **{"global": global_}, ) except CommandExecutionError as exc: return _fail( diff --git a/salt/states/gpg.py b/salt/states/gpg.py index 4329e6685a6..bde4b3beeda 100644 --- a/salt/states/gpg.py +++ b/salt/states/gpg.py @@ -76,7 +76,7 @@ def present( keys = [keys] for key in keys: - if key in current_keys.keys(): + if key in current_keys: if trust: if trust in _VALID_TRUST_VALUES: if current_keys[key]["trust"] != TRUST_MAP[trust]: diff --git a/salt/states/grafana_dashboard.py b/salt/states/grafana_dashboard.py index a23d0f084e3..0ba2b5f7622 100644 --- a/salt/states/grafana_dashboard.py +++ b/salt/states/grafana_dashboard.py @@ -459,6 +459,7 @@ def _update(dashboard, profile): request_url, headers={"Authorization": "Bearer {}".format(profile.get("grafana_token"))}, json=payload, + timeout=120, ) return response.json() diff --git a/salt/states/grains.py b/salt/states/grains.py index 9e6399dd57f..fadc518a254 100644 --- a/salt/states/grains.py +++ b/salt/states/grains.py @@ -296,7 +296,7 @@ def list_absent(name, value, delimiter=DEFAULT_TARGET_DELIM): comments.append( "Value {1} in grain {0} is set to be deleted".format(name, val) ) - if "deleted" not in ret["changes"].keys(): + if "deleted" not in ret["changes"]: ret["changes"] = {"deleted": []} ret["changes"]["deleted"].append(val) elif val in grain: @@ -304,7 +304,7 @@ def list_absent(name, value, delimiter=DEFAULT_TARGET_DELIM): comments.append( "Value {1} was deleted from grain {0}".format(name, val) ) - if "deleted" not in ret["changes"].keys(): + if "deleted" not in ret["changes"]: ret["changes"] = {"deleted": []} ret["changes"]["deleted"].append(val) ret["comment"] = "\n".join(comments) diff --git a/salt/states/ldap.py b/salt/states/ldap.py index 227182b828b..9b88c96918f 100644 --- a/salt/states/ldap.py +++ b/salt/states/ldap.py @@ -314,6 +314,7 @@ def managed(name, entries, connect_spec=None): o = old.get(dn, {}) n = new.get(dn, {}) + op = None try: # perform the operation if o: diff --git a/salt/states/netsnmp.py b/salt/states/netsnmp.py index 54dbf7887d3..a0f0d50b5f5 100644 --- a/salt/states/netsnmp.py +++ b/salt/states/netsnmp.py @@ -116,7 +116,7 @@ def _clear_community_details(community_details): _mode = community_details.get["mode"] = community_details.get("mode").lower() - if _mode in _COMMUNITY_MODE_MAP.keys(): + if _mode in _COMMUNITY_MODE_MAP: community_details["mode"] = _COMMUNITY_MODE_MAP.get(_mode) if community_details["mode"] not in ["ro", "rw"]: @@ -201,7 +201,7 @@ def _create_diff_action(diff, diff_key, key, value): DRY to build diff parts (added, removed, updated). """ - if diff_key not in diff.keys(): + if diff_key not in diff: diff[diff_key] = {} diff[diff_key][key] = value diff --git a/salt/states/pip_state.py b/salt/states/pip_state.py index 9430ea457ce..f8447ec350c 100644 --- a/salt/states/pip_state.py +++ b/salt/states/pip_state.py @@ -355,7 +355,10 @@ def _pep440_version_cmp(pkg1, pkg2, ignore_epoch=False): "The pkg_resources packages was not loaded. Please install setuptools." ) return None - normalize = lambda x: str(x).split("!", 1)[-1] if ignore_epoch else str(x) + + def normalize(x): + return str(x).split("!", 1)[-1] if ignore_epoch else str(x) + pkg1 = normalize(pkg1) pkg2 = normalize(pkg2) @@ -368,7 +371,7 @@ def _pep440_version_cmp(pkg1, pkg2, ignore_epoch=False): return 1 except Exception as exc: # pylint: disable=broad-except logger.exception( - f'Comparison of package versions "{pkg1}" and "{pkg2}" failed: {exc}' + 'Comparison of package versions "%s" and "%s" failed: %s', pkg1, pkg2, exc ) return None @@ -735,11 +738,13 @@ def installed( # prepro = lambda pkg: pkg if type(pkg) == str else \ # ' '.join((pkg.items()[0][0], pkg.items()[0][1].replace(',', ';'))) # pkgs = ','.join([prepro(pkg) for pkg in pkgs]) - prepro = ( - lambda pkg: pkg - if isinstance(pkg, str) - else " ".join((pkg.items()[0][0], pkg.items()[0][1])) - ) + def prepro(pkg): + return ( + pkg + if isinstance(pkg, str) + else " ".join((pkg.items()[0][0], pkg.items()[0][1])) + ) + pkgs = [prepro(pkg) for pkg in pkgs] ret = {"name": ";".join(pkgs), "result": None, "comment": "", "changes": {}} @@ -862,7 +867,8 @@ def installed( # If we fail, then just send False, and we'll try again in the next function call except Exception as exc: # pylint: disable=broad-except logger.exception( - f"Pre-caching of PIP packages during states.pip.installed failed by exception from pip.list: {exc}" + "Pre-caching of PIP packages during states.pip.installed failed by exception from pip.list: %s", + exc, ) pip_list = False diff --git a/salt/states/pkg.py b/salt/states/pkg.py index 08ddd83b82e..908d3711b07 100644 --- a/salt/states/pkg.py +++ b/salt/states/pkg.py @@ -3943,7 +3943,7 @@ def unheld(name, version=None, pkgs=None, all=False, **kwargs): (pkg_name, pkg_ver) = next(iter(pkg.items())) dpkgs.update({pkg_name: pkg_ver}) else: - dpkgs.update({pkg: None}) + dpkgs.update({pkg: None}) # pylint: disable=unhashable-member ret = {"name": name, "changes": {}, "result": True, "comment": ""} comments = [] diff --git a/salt/states/probes.py b/salt/states/probes.py index 2b5c566caf0..6adc6183f4e 100644 --- a/salt/states/probes.py +++ b/salt/states/probes.py @@ -80,7 +80,7 @@ def _expand_probes(probes, defaults): expected_probes = {} for probe_name, probe_test in probes.items(): - if probe_name not in expected_probes.keys(): + if probe_name not in expected_probes: expected_probes[probe_name] = {} probe_defaults = probe_test.pop("defaults", {}) for test_name, test_details in probe_test.items(): @@ -97,7 +97,7 @@ def _expand_probes(probes, defaults): expected_test_details.update( test_details ) # update with the actual config of the test - if test_name not in expected_probes[probe_name].keys(): + if test_name not in expected_probes[probe_name]: expected_probes[probe_name][test_name] = expected_test_details return expected_probes @@ -167,12 +167,12 @@ def _compare_probes(configured_probes, expected_probes): # new tests for common probes for test_name in new_tests_keys_set: - if probe_name not in new_probes.keys(): + if probe_name not in new_probes: new_probes[probe_name] = {} new_probes[probe_name].update({test_name: probe_tests.pop(test_name)}) # old tests for common probes for test_name in remove_tests_keys_set: - if probe_name not in remove_probes.keys(): + if probe_name not in remove_probes: remove_probes[probe_name] = {} remove_probes[probe_name].update( {test_name: configured_probe_tests.pop(test_name)} @@ -182,7 +182,7 @@ def _compare_probes(configured_probes, expected_probes): configured_test_params = configured_probe_tests.get(test_name, {}) # if test params are different, probe goes to update probes dict! if test_params != configured_test_params: - if probe_name not in update_probes.keys(): + if probe_name not in update_probes: update_probes[probe_name] = {} update_probes[probe_name].update({test_name: test_params}) diff --git a/salt/states/saltmod.py b/salt/states/saltmod.py index 386c5811ceb..d904da011d0 100644 --- a/salt/states/saltmod.py +++ b/salt/states/saltmod.py @@ -782,7 +782,9 @@ def runner(name, **kwargs): try: kwargs["__pub_user"] = __user__ log.debug( - f"added __pub_user to kwargs using dunder user '{__user__}', kwargs '{kwargs}'" + "added __pub_user to kwargs using dunder user '%s', kwargs '%s'", + __user__, + kwargs, ) except NameError: log.warning("unable to find user for fire args event due to missing __user__") diff --git a/salt/states/win_iis.py b/salt/states/win_iis.py index 773f7e7b3ad..4d1162680bd 100644 --- a/salt/states/win_iis.py +++ b/salt/states/win_iis.py @@ -502,7 +502,7 @@ def container_setting(name, container, settings=None): # map identity type from numeric to string for comparing if ( setting == "processModel.identityType" - and settings[setting] in identityType_map2string.keys() + and settings[setting] in identityType_map2string ): settings[setting] = identityType_map2string[settings[setting]] diff --git a/salt/utils/ansible.py b/salt/utils/ansible.py index b91c931dff6..e0f35146999 100644 --- a/salt/utils/ansible.py +++ b/salt/utils/ansible.py @@ -12,7 +12,7 @@ __virtualname__ = "ansible" log = logging.getLogger(__name__) -def __virtual__(): # pylint: disable=expected-2-blank-lines-found-0 +def __virtual__(): if salt.utils.path.which("ansible-inventory"): return __virtualname__ return (False, "Install `ansible` to use inventory") @@ -24,7 +24,7 @@ def targets(inventory="/etc/ansible/hosts", yaml=False, export=False): Default: /etc/salt/roster """ if not os.path.isfile(inventory): - raise CommandExecutionError("Inventory file not found: {}".format(inventory)) + raise CommandExecutionError(f"Inventory file not found: {inventory}") if not os.path.isabs(inventory): raise CommandExecutionError("Path to inventory file must be an absolute path") @@ -44,6 +44,4 @@ def targets(inventory="/etc/ansible/hosts", yaml=False, export=False): try: return salt.utils.json.loads(salt.utils.stringutils.to_str(inv)) except ValueError: - raise CommandExecutionError( - "Error processing the inventory: {}".format(inv) - ) + raise CommandExecutionError(f"Error processing the inventory: {inv}") diff --git a/salt/utils/args.py b/salt/utils/args.py index 536aea38166..dbc6e7e4081 100644 --- a/salt/utils/args.py +++ b/salt/utils/args.py @@ -49,7 +49,7 @@ def invalid_kwargs(invalid_kwargs, raise_exc=True): """ if invalid_kwargs: if isinstance(invalid_kwargs, dict): - new_invalid = ["{}={}".format(x, y) for x, y in invalid_kwargs.items()] + new_invalid = [f"{x}={y}" for x, y in invalid_kwargs.items()] invalid_kwargs = new_invalid msg = "The following keyword arguments are not valid: {}".format( ", ".join(invalid_kwargs) @@ -236,7 +236,7 @@ def get_function_argspec(func, is_class_method=None): the argspec unless ``is_class_method`` is True. """ if not callable(func): - raise TypeError("{} is not a callable".format(func)) + raise TypeError(f"{func} is not a callable") while hasattr(func, "__wrapped__"): func = func.__wrapped__ @@ -244,7 +244,7 @@ def get_function_argspec(func, is_class_method=None): try: sig = inspect.signature(func) except TypeError: - raise TypeError("Cannot inspect argument list for '{}'".format(func)) + raise TypeError(f"Cannot inspect argument list for '{func}'") # Build a namedtuple which looks like the result of a Python 2 argspec _ArgSpec = namedtuple("ArgSpec", "args varargs keywords defaults") @@ -345,7 +345,10 @@ def split_input(val, mapper=None): Take an input value and split it into a list, returning the resulting list """ if mapper is None: - mapper = lambda x: x + + def mapper(x): + return x + if isinstance(val, list): return list(map(mapper, val)) try: @@ -466,18 +469,18 @@ def format_call( # In case this is being called for a state module "full", # Not a state module, build the name - "{}.{}".format(fun.__module__, fun.__name__), + f"{fun.__module__}.{fun.__name__}", ), ) else: msg = "{} and '{}' are invalid keyword arguments for '{}'".format( - ", ".join(["'{}'".format(e) for e in extra][:-1]), + ", ".join([f"'{e}'" for e in extra][:-1]), list(extra.keys())[-1], ret.get( # In case this is being called for a state module "full", # Not a state module, build the name - "{}.{}".format(fun.__module__, fun.__name__), + f"{fun.__module__}.{fun.__name__}", ), ) @@ -529,7 +532,8 @@ def parse_function(s): key = None word = [] elif token in "]})": - if not brackets or token != {"[": "]", "{": "}", "(": ")"}[brackets.pop()]: + _brackets = {"[": "]", "{": "}", "(": ")"} + if not brackets or token != _brackets[brackets.pop()]: break word.append(token) elif token == "=" and not brackets: diff --git a/salt/utils/atomicfile.py b/salt/utils/atomicfile.py index 574797b77e3..59f7e273715 100644 --- a/salt/utils/atomicfile.py +++ b/salt/utils/atomicfile.py @@ -14,8 +14,12 @@ import salt.utils.win_dacl CAN_RENAME_OPEN_FILE = False if os.name == "nt": # pragma: no cover - _rename = lambda src, dst: False # pylint: disable=C0103 - _rename_atomic = lambda src, dst: False # pylint: disable=C0103 + + def _rename(src, dst): + return False + + def _rename_atomic(src, dst): + return False try: import ctypes diff --git a/salt/utils/aws.py b/salt/utils/aws.py index fead9cf7ac6..1231661d970 100644 --- a/salt/utils/aws.py +++ b/salt/utils/aws.py @@ -240,7 +240,14 @@ def assumed_creds(prov_dict, role_arn, location=None): requesturl="https://sts.amazonaws.com/", ) headers["Accept"] = "application/json" - result = requests.request("GET", requesturl, headers=headers, data="", verify=True) + result = requests.request( + "GET", + requesturl, + headers=headers, + data="", + verify=True, + timeout=AWS_METADATA_TIMEOUT, + ) if result.status_code >= 400: log.info("AssumeRole response: %s", result.content) @@ -511,7 +518,10 @@ def query( log.trace("AWS Request Parameters: %s", params_with_headers) try: result = requests.get( - requesturl, headers=headers, params=params_with_headers + requesturl, + headers=headers, + params=params_with_headers, + timeout=AWS_METADATA_TIMEOUT, ) log.debug("AWS Response Status Code: %s", result.status_code) log.trace("AWS Response Text: %s", result.text) diff --git a/salt/utils/cache.py b/salt/utils/cache.py index 88e7fa24000..02c89b28bba 100644 --- a/salt/utils/cache.py +++ b/salt/utils/cache.py @@ -99,7 +99,7 @@ class CacheDisk(CacheDict): return if time.time() - self._key_cache_time[key] > self._ttl: del self._key_cache_time[key] - self._dict.__delitem__(key) + del self._dict[key] def __contains__(self, key): self._enforce_ttl_key(key) @@ -365,7 +365,7 @@ def verify_cache_version(cache_path): file.seek(0) data = "\n".join(file.readlines()) if data != salt.version.__version__: - log.warning(f"Cache version mismatch clearing: {repr(cache_path)}") + log.warning("Cache version mismatch clearing: %s", repr(cache_path)) file.truncate(0) file.write(salt.version.__version__) for item in os.listdir(cache_path): diff --git a/salt/utils/cloud.py b/salt/utils/cloud.py index 3e026a0bb57..5a1660cfd6a 100644 --- a/salt/utils/cloud.py +++ b/salt/utils/cloud.py @@ -2120,9 +2120,7 @@ def _exec_ssh_cmd(cmd, error_msg=None, allow_failure=False, **kwargs): return proc.exitstatus except salt.utils.vt.TerminalException as err: trace = traceback.format_exc() - log.error( - error_msg.format(cmd, err, trace) - ) # pylint: disable=str-format-in-logging + log.error(error_msg.format(cmd, err, trace)) finally: proc.close(terminate=True, kill=True) # Signal an error @@ -2969,7 +2967,7 @@ def update_bootstrap(config, url=None): "Python requests library to be installed" ) } - req = requests.get(url) + req = requests.get(url, timeout=120) if req.status_code != 200: return { "error": ( diff --git a/salt/utils/compat.py b/salt/utils/compat.py index 0579a7f5e62..d9313e1b408 100644 --- a/salt/utils/compat.py +++ b/salt/utils/compat.py @@ -38,12 +38,10 @@ def deepcopy_bound(name): """ def _deepcopy_method(x, memo): - # pylint: disable=incompatible-py3-code return type(x)(x.im_func, copy.deepcopy(x.im_self, memo), x.im_class) - # pylint: enable=incompatible-py3-code + pre_dispatch = copy._deepcopy_dispatch try: - pre_dispatch = copy._deepcopy_dispatch copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method ret = copy.deepcopy(name) finally: diff --git a/salt/utils/configparser.py b/salt/utils/configparser.py index 6a3b1e689ea..10e3c889ef0 100644 --- a/salt/utils/configparser.py +++ b/salt/utils/configparser.py @@ -3,18 +3,12 @@ Custom configparser classes """ import re +from collections import OrderedDict from configparser import * # pylint: disable=no-name-in-module,wildcard-import,unused-wildcard-import import salt.utils.stringutils -try: - from collections import OrderedDict as _default_dict -except ImportError: - # fallback for setup.py which hasn't yet built _collections - _default_dict = dict - -# pylint: disable=string-substitution-usage-error class GitConfigParser(RawConfigParser): """ Custom ConfigParser which reads and writes git config files. @@ -47,7 +41,7 @@ class GitConfigParser(RawConfigParser): def __init__( self, defaults=None, - dict_type=_default_dict, + dict_type=OrderedDict, allow_no_value=True, ): """ @@ -269,7 +263,7 @@ class GitConfigParser(RawConfigParser): fp_.write(convert("[%s]\n" % self.DEFAULTSECT)) for (key, value) in self._defaults.items(): value = salt.utils.stringutils.to_unicode(value).replace("\n", "\n\t") - fp_.write(convert("{} = {}\n".format(key, value))) + fp_.write(convert(f"{key} = {value}\n")) for section in self._sections: fp_.write(convert("[%s]\n" % section)) for (key, value) in self._sections[section].items(): diff --git a/salt/utils/data.py b/salt/utils/data.py index 0235551462f..40c79e3418a 100644 --- a/salt/utils/data.py +++ b/salt/utils/data.py @@ -1049,9 +1049,14 @@ def repack_dictlist(data, strict=False, recurse=False, key_cb=None, val_cb=None) return {} if key_cb is None: - key_cb = lambda x: x + + def key_cb(x): + return x + if val_cb is None: - val_cb = lambda x, y: y + + def val_cb(x, y): + return y valid_non_dict = ((str,), (int,), float) if isinstance(data, list): diff --git a/salt/utils/dns.py b/salt/utils/dns.py index dc0d680c773..271fd79553e 100644 --- a/salt/utils/dns.py +++ b/salt/utils/dns.py @@ -123,7 +123,7 @@ def _to_port(port): assert 1 <= port <= 65535 return port except (ValueError, AssertionError): - raise ValueError("Invalid port {}".format(port)) + raise ValueError(f"Invalid port {port}") def _tree(domain, tld=False): @@ -276,24 +276,24 @@ def _lookup_dig(name, rdtype, timeout=None, servers=None, secure=None): :param servers: [] of servers to use :return: [] of records or False if error """ - cmd = "dig {} -t {} ".format(DIG_OPTIONS, rdtype) + cmd = f"dig {DIG_OPTIONS} -t {rdtype} " if servers: - cmd += "".join(["@{} ".format(srv) for srv in servers]) + cmd += "".join([f"@{srv} " for srv in servers]) if timeout is not None: if servers: timeout = int(float(timeout) / len(servers)) else: timeout = int(timeout) - cmd += "+time={} ".format(timeout) + cmd += f"+time={timeout} " if secure: cmd += "+dnssec +adflag " cmd = __salt__["cmd.run_all"]( - "{} {}".format(cmd, name), python_shell=False, output_loglevel="quiet" + f"{cmd} {name}", python_shell=False, output_loglevel="quiet" ) if "ignoring invalid type" in cmd["stderr"]: - raise ValueError("Invalid DNS type {}".format(rdtype)) + raise ValueError(f"Invalid DNS type {rdtype}") elif cmd["retcode"] != 0: log.warning( "dig returned (%s): %s", @@ -333,9 +333,9 @@ def _lookup_drill(name, rdtype, timeout=None, servers=None, secure=None): cmd = "drill " if secure: cmd += "-D -o ad " - cmd += "{} {} ".format(rdtype, name) + cmd += f"{rdtype} {name} " if servers: - cmd += "".join(["@{} ".format(srv) for srv in servers]) + cmd += "".join([f"@{srv} " for srv in servers]) cmd = __salt__["cmd.run_all"]( cmd, timeout=timeout, python_shell=False, output_loglevel="quiet" ) @@ -364,7 +364,7 @@ def _lookup_drill(name, rdtype, timeout=None, servers=None, secure=None): validated = True continue elif l_type != rdtype: - raise ValueError("Invalid DNS type {}".format(rdtype)) + raise ValueError(f"Invalid DNS type {rdtype}") res.append(_data_clean(l_rec)) @@ -385,10 +385,12 @@ def _lookup_gai(name, rdtype, timeout=None): :param timeout: ignored :return: [] of addresses or False if error """ - try: - sock_t = {"A": socket.AF_INET, "AAAA": socket.AF_INET6}[rdtype] - except KeyError: - raise ValueError("Invalid DNS type {} for gai lookup".format(rdtype)) + if rdtype == "A": + sock_t = socket.AF_INET + elif rdtype == "AAAA": + sock_t = socket.AF_INET6 + else: + raise ValueError(f"Invalid DNS type {rdtype} for gai lookup") if timeout: log.info("Ignoring timeout on gai resolver; fix resolv.conf to do that") @@ -412,18 +414,18 @@ def _lookup_host(name, rdtype, timeout=None, server=None): :param timeout: server response wait :return: [] of records or False if error """ - cmd = "host -t {} ".format(rdtype) + cmd = f"host -t {rdtype} " if timeout: - cmd += "-W {} ".format(int(timeout)) + cmd += f"-W {int(timeout)} " cmd += name if server is not None: - cmd += " {}".format(server) + cmd += f" {server}" cmd = __salt__["cmd.run_all"](cmd, python_shell=False, output_loglevel="quiet") if "invalid type" in cmd["stderr"]: - raise ValueError("Invalid DNS type {}".format(rdtype)) + raise ValueError(f"Invalid DNS type {rdtype}") elif cmd["retcode"] != 0: log.warning("host returned (%s): %s", cmd["retcode"], cmd["stderr"]) return False @@ -470,7 +472,7 @@ def _lookup_dnspython(name, rdtype, timeout=None, servers=None, secure=None): ] return res except dns.rdatatype.UnknownRdatatype: - raise ValueError("Invalid DNS type {}".format(rdtype)) + raise ValueError(f"Invalid DNS type {rdtype}") except ( dns.resolver.NXDOMAIN, dns.resolver.YXDOMAIN, @@ -489,12 +491,12 @@ def _lookup_nslookup(name, rdtype, timeout=None, server=None): :param server: server to query :return: [] of records or False if error """ - cmd = "nslookup -query={} {}".format(rdtype, name) + cmd = f"nslookup -query={rdtype} {name}" if timeout is not None: - cmd += " -timeout={}".format(int(timeout)) + cmd += f" -timeout={int(timeout)}" if server is not None: - cmd += " {}".format(server) + cmd += f" {server}" cmd = __salt__["cmd.run_all"](cmd, python_shell=False, output_loglevel="quiet") @@ -511,7 +513,7 @@ def _lookup_nslookup(name, rdtype, timeout=None, server=None): try: line = next(lookup_res) if "unknown query type" in line: - raise ValueError("Invalid DNS type {}".format(rdtype)) + raise ValueError(f"Invalid DNS type {rdtype}") while True: if name in line: @@ -581,7 +583,6 @@ def lookup( rdtype = rdtype.upper() - # pylint: disable=bad-whitespace,multiple-spaces-before-keyword query_methods = ( ("gai", _lookup_gai, not any((rdtype not in ("A", "AAAA"), servers, secure))), ("dnspython", _lookup_dnspython, HAS_DNSPYTHON), @@ -590,7 +591,6 @@ def lookup( ("host", _lookup_host, HAS_HOST and not secure), ("nslookup", _lookup_nslookup, HAS_NSLOOKUP and not secure), ) - # pylint: enable=bad-whitespace,multiple-spaces-before-keyword try: if method == "auto": @@ -895,7 +895,7 @@ def spf_rec(rdata): # It's a modifier mod, val = mech_spec.split("=", 1) if mod in mods: - raise KeyError("Modifier {} can only appear once".format(mod)) + raise KeyError(f"Modifier {mod} can only appear once") mods.add(mod) continue @@ -959,7 +959,7 @@ def srv_name(svc, proto="tcp", domain=None): if domain: domain = "." + domain - return "_{}._{}{}".format(svc, proto, domain) + return f"_{svc}._{proto}{domain}" def srv_rec(rdatas): @@ -1133,7 +1133,7 @@ def services(services_file="/etc/services"): if not curr_desc: pp_res["desc"] = comment elif comment != curr_desc: - pp_res["desc"] = "{}, {}".format(curr_desc, comment) + pp_res["desc"] = f"{curr_desc}, {comment}" res[name] = svc_res for svc, data in res.items(): @@ -1210,7 +1210,7 @@ def parse_resolv(src="/etc/resolv.conf"): ip_addr ) ip_net = ipaddress.ip_network( - "{}{}".format(ip_addr, mask), strict=False + f"{ip_addr}{mask}", strict=False ) if ip_net.version == 6: # TODO diff --git a/salt/utils/dockermod/__init__.py b/salt/utils/dockermod/__init__.py index f703ee7b1e6..00b012b8992 100644 --- a/salt/utils/dockermod/__init__.py +++ b/salt/utils/dockermod/__init__.py @@ -25,11 +25,11 @@ except ImportError: # functions so that we can get argspecs for the container config, host config, # and networking config (see the get_client_args() function). try: - import docker.types + import docker.types # pylint: disable=no-name-in-module except ImportError: pass try: - import docker.utils + import docker.utils # pylint: disable=no-name-in-module except ImportError: pass @@ -241,7 +241,7 @@ def translate_input( pass except Exception as exc: # pylint: disable=broad-except - error_message = exc.__str__() + error_message = str(exc) log.error("Error translating input: '%s'", error_message, exc_info=True) else: error_message = None diff --git a/salt/utils/dockermod/translate/container.py b/salt/utils/dockermod/translate/container.py index b155308bf74..3bc37101f76 100644 --- a/salt/utils/dockermod/translate/container.py +++ b/salt/utils/dockermod/translate/container.py @@ -378,9 +378,7 @@ def port_bindings(val, **kwargs): try: start, end = helpers.get_port_range(container_port) except ValueError as exc: - # Using __str__() to avoid deprecation warning for using - # the message attribute of the ValueError. - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) bind_vals = [ (_format_port(port_num, proto), None) for port_num in range(start, end + 1) @@ -403,9 +401,7 @@ def port_bindings(val, **kwargs): cport_start, cport_end = helpers.get_port_range(container_port) hport_start, hport_end = helpers.get_port_range(bind_parts[0]) except ValueError as exc: - # Using __str__() to avoid deprecation warning for - # using the message attribute of the ValueError. - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) if (hport_end - hport_start) != (cport_end - cport_start): # Port range is mismatched raise SaltInvocationError( @@ -427,9 +423,7 @@ def port_bindings(val, **kwargs): try: cport_start, cport_end = helpers.get_port_range(container_port) except ValueError as exc: - # Using __str__() to avoid deprecation warning for - # using the message attribute of the ValueError. - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) cport_list = list(range(cport_start, cport_end + 1)) if host_port == "": hport_list = [None] * len(cport_list) @@ -437,9 +431,7 @@ def port_bindings(val, **kwargs): try: hport_start, hport_end = helpers.get_port_range(host_port) except ValueError as exc: - # Using __str__() to avoid deprecation warning for - # using the message attribute of the ValueError. - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) hport_list = list(range(hport_start, hport_end + 1)) if (hport_end - hport_start) != (cport_end - cport_start): @@ -526,9 +518,7 @@ def ports(val, **kwargs): # pylint: disable=unused-argument try: range_start, range_end = helpers.get_port_range(item) except ValueError as exc: - # Using __str__() to avoid deprecation warning for using - # the "message" attribute of the ValueError. - raise SaltInvocationError(exc.__str__()) + raise SaltInvocationError(str(exc)) new_ports.update( [helpers.get_port_def(x, proto) for x in range(range_start, range_end + 1)] ) diff --git a/salt/utils/dockermod/translate/helpers.py b/salt/utils/dockermod/translate/helpers.py index f172d080cdc..5d81f89c99e 100644 --- a/salt/utils/dockermod/translate/helpers.py +++ b/salt/utils/dockermod/translate/helpers.py @@ -72,7 +72,7 @@ def get_port_range(port_def): if range_start > range_end: raise ValueError("start > end") except (TypeError, ValueError) as exc: - if exc.__str__() == "start > end": + if str(exc) == "start > end": msg = ( "Start of port range ({}) cannot be greater than end of " "port range ({})".format(range_start, range_end) diff --git a/salt/utils/files.py b/salt/utils/files.py index 3c57cce7132..8071a55d3a4 100644 --- a/salt/utils/files.py +++ b/salt/utils/files.py @@ -322,8 +322,8 @@ def set_umask(mask): # Don't attempt on Windows, or if no mask was passed yield else: + orig_mask = os.umask(mask) # pylint: disable=blacklisted-function try: - orig_mask = os.umask(mask) # pylint: disable=blacklisted-function yield finally: os.umask(orig_mask) # pylint: disable=blacklisted-function @@ -390,7 +390,9 @@ def fopen(*args, **kwargs): ) kwargs["buffering"] = io.DEFAULT_BUFFER_SIZE - f_handle = open(*args, **kwargs) # pylint: disable=resource-leakage + f_handle = open( # pylint: disable=resource-leakage,unspecified-encoding + *args, **kwargs + ) if is_fcntl_available(): # modify the file descriptor on systems with fcntl @@ -649,7 +651,10 @@ def is_text(fp_, blocksize=512): If more than 30% of the chars in the block are non-text, or there are NUL ('\x00') bytes in the block, assume this is a binary file. """ - int2byte = lambda x: bytes((x,)) + + def int2byte(x): + return bytes((x,)) + text_characters = b"".join(int2byte(i) for i in range(32, 127)) + b"\n\r\t\f\b" try: block = fp_.read(blocksize) diff --git a/salt/utils/fsutils.py b/salt/utils/fsutils.py index 7b0eb084f64..96d0cd16bb8 100644 --- a/salt/utils/fsutils.py +++ b/salt/utils/fsutils.py @@ -57,7 +57,10 @@ def _blkid_output(out, fs_type=None): """ Parse blkid output. """ - flt = lambda data: [el for el in data if el.strip()] + + def flt(data): + return [el for el in data if el.strip()] + data = {} for dev_meta in flt(out.split("\n\n")): dev = {} @@ -84,7 +87,10 @@ def _blkid(fs_type=None): :param fs_type: Filter only devices that are formatted by that file system. """ - flt = lambda data: [el for el in data if el.strip()] + + def flt(data): + return [el for el in data if el.strip()] + data = dict() for dev_meta in flt( os.popen("blkid -o full").read().split(os.linesep) diff --git a/salt/utils/functools.py b/salt/utils/functools.py index f1360527723..f4d4cbdb3de 100644 --- a/salt/utils/functools.py +++ b/salt/utils/functools.py @@ -119,9 +119,7 @@ def call_function(salt_function, *args, **kwargs): # function_kwargs is initialized to a dictionary of keyword arguments the function to be run accepts function_kwargs = dict( zip( - argspec.args[ - -len(argspec.defaults or []) : - ], # pylint: disable=incompatible-py3-code + argspec.args[-len(argspec.defaults or []) :], argspec.defaults or [], ) ) diff --git a/salt/utils/gitfs.py b/salt/utils/gitfs.py index a197921f6ef..934794bfab7 100644 --- a/salt/utils/gitfs.py +++ b/salt/utils/gitfs.py @@ -118,7 +118,7 @@ try: if PYGIT2_VERSION <= Version("0.26.3"): try: import pygit2.ffi - import pygit2.remote + import pygit2.remote # pylint: disable=no-name-in-module except ImportError: # If we couldn't import these, then we're using an old enough # version where ffi isn't in use and this workaround would be @@ -244,12 +244,16 @@ class GitProvider: ): self.opts = opts self.role = role + + def _val_cb(x, y): + return str(y) + self.global_saltenv = salt.utils.data.repack_dictlist( self.opts.get("{}_saltenv".format(self.role), []), strict=True, recurse=True, key_cb=str, - val_cb=lambda x, y: str(y), + val_cb=_val_cb, ) self.conf = copy.deepcopy(per_remote_defaults) # Remove the 'salt://' from the beginning of any globally-defined @@ -473,7 +477,9 @@ class GitProvider: try: self._cache_basename = self.get_checkout_target() except AttributeError: - log.critical(f"__env__ cant generate basename: {self.role} {self.id}") + log.critical( + "__env__ cant generate basename: %s %s", self.role, self.id + ) failhard(self.role) self._cache_full_basename = salt.utils.path.join( self._cache_basehash, self._cache_basename @@ -574,9 +580,9 @@ class GitProvider: """ def _getconf(self, tgt_env="base"): - strip_sep = ( - lambda x: x.rstrip(os.sep) if name in ("root", "mountpoint") else x - ) + def strip_sep(x): + return x.rstrip(os.sep) if name in ("root", "mountpoint") else x + if self.role != "gitfs": return strip_sep(getattr(self, "_" + name)) # Get saltenv-specific configuration @@ -1203,12 +1209,14 @@ class GitProvider: def fetch_request_check(self): fetch_request = salt.utils.path.join(self._salt_working_dir, "fetch_request") if os.path.isfile(fetch_request): - log.debug(f"Fetch request: {self._salt_working_dir}") + log.debug("Fetch request: %s", self._salt_working_dir) try: os.remove(fetch_request) except OSError as exc: log.error( - f"Failed to remove Fetch request: {self._salt_working_dir} {exc}", + "Failed to remove Fetch request: %s %s", + self._salt_working_dir, + exc, exc_info=True, ) self.fetch() @@ -1426,12 +1434,20 @@ class GitPython(GitProvider): tree = tree / self.root(tgt_env) except KeyError: return ret - relpath = lambda path: os.path.relpath(path, self.root(tgt_env)) + + def relpath(path): + return os.path.relpath(path, self.root(tgt_env)) + else: - relpath = lambda path: path - add_mountpoint = lambda path: salt.utils.path.join( - self.mountpoint(tgt_env), path, use_posixpath=True - ) + + def relpath(path): + return path + + def add_mountpoint(path): + return salt.utils.path.join( + self.mountpoint(tgt_env), path, use_posixpath=True + ) + for blob in tree.traverse(): if isinstance(blob, git.Tree): ret.add(add_mountpoint(relpath(blob.path))) @@ -1498,12 +1514,20 @@ class GitPython(GitProvider): tree = tree / self.root(tgt_env) except KeyError: return files, symlinks - relpath = lambda path: os.path.relpath(path, self.root(tgt_env)) + + def relpath(path): + return os.path.relpath(path, self.root(tgt_env)) + else: - relpath = lambda path: path - add_mountpoint = lambda path: salt.utils.path.join( - self.mountpoint(tgt_env), path, use_posixpath=True - ) + + def relpath(path): + return path + + def add_mountpoint(path): + return salt.utils.path.join( + self.mountpoint(tgt_env), path, use_posixpath=True + ) + for file_blob in tree.traverse(): if not isinstance(file_blob, git.Blob): continue @@ -1945,15 +1969,24 @@ class Pygit2(GitProvider): return ret if not isinstance(tree, pygit2.Tree): return ret - relpath = lambda path: os.path.relpath(path, self.root(tgt_env)) + + def relpath(path): + return os.path.relpath(path, self.root(tgt_env)) + else: - relpath = lambda path: path + + def relpath(path): + return path + blobs = [] if tree: _traverse(tree, blobs, self.root(tgt_env)) - add_mountpoint = lambda path: salt.utils.path.join( - self.mountpoint(tgt_env), path, use_posixpath=True - ) + + def add_mountpoint(path): + return salt.utils.path.join( + self.mountpoint(tgt_env), path, use_posixpath=True + ) + for blob in blobs: ret.add(add_mountpoint(relpath(blob))) if self.mountpoint(tgt_env): @@ -2086,15 +2119,24 @@ class Pygit2(GitProvider): return files, symlinks if not isinstance(tree, pygit2.Tree): return files, symlinks - relpath = lambda path: os.path.relpath(path, self.root(tgt_env)) + + def relpath(path): + return os.path.relpath(path, self.root(tgt_env)) + else: - relpath = lambda path: path + + def relpath(path): + return path + blobs = {} if tree: _traverse(tree, blobs, self.root(tgt_env)) - add_mountpoint = lambda path: salt.utils.path.join( - self.mountpoint(tgt_env), path, use_posixpath=True - ) + + def add_mountpoint(path): + return salt.utils.path.join( + self.mountpoint(tgt_env), path, use_posixpath=True + ) + for repo_path in blobs.get("files", []): files.add(add_mountpoint(relpath(repo_path))) for repo_path, link_tgt in blobs.get("symlinks", {}).items(): @@ -2181,9 +2223,12 @@ class Pygit2(GitProvider): if PYGIT2_VERSION >= Version("0.23.2"): self.remotecallbacks = pygit2.RemoteCallbacks(credentials=self.credentials) if not self.ssl_verify: - # Override the certificate_check function with a lambda that + # Override the certificate_check function with another that # just returns True, thus skipping the cert check. - self.remotecallbacks.certificate_check = lambda *args, **kwargs: True + def _certificate_check(*args, **kwargs): + return True + + self.remotecallbacks.certificate_check = _certificate_check else: self.remotecallbacks = None if not self.ssl_verify: @@ -2663,11 +2708,13 @@ class GitBase: pass except OSError as exc: # pylint: disable=broad-except log.error( - f"Failed to make fetch request: {fetch_path} {exc}", + "Failed to make fetch request: %s %s", + fetch_path, + exc, exc_info=True, ) else: - log.error(f"Failed to make fetch request: {fetch_path}") + log.error("Failed to make fetch request: %s", fetch_path) if repo.fetch(): # We can't just use the return value from repo.fetch() # because the data could still have changed if old @@ -3437,7 +3484,7 @@ class GitPillar(GitBase): "Failed to remove existing git_pillar " "mountpoint link %s: %s", lcachelink, - exc.__str__(), + exc, ) wipe_linkdir = False create_link = True @@ -3457,7 +3504,7 @@ class GitPillar(GitBase): log.error( "Failed to os.makedirs() linkdir parent %s: %s", ldirname, - exc.__str__(), + exc, ) return False @@ -3475,7 +3522,7 @@ class GitPillar(GitBase): "Failed to create symlink to %s at path %s: %s", lcachedest, lcachelink, - exc.__str__(), + exc, ) return False except GitLockError: diff --git a/salt/utils/iam.py b/salt/utils/iam.py index dea1e950145..45017df57ef 100644 --- a/salt/utils/iam.py +++ b/salt/utils/iam.py @@ -24,6 +24,7 @@ def _retry_get_url(url, num_retries=10, timeout=5): Based heavily on boto.utils.retry_url """ for i in range(0, num_retries): + exc = None try: result = requests.get(url, timeout=timeout, proxies={"http": ""}) if hasattr(result, "text"): diff --git a/salt/utils/jinja.py b/salt/utils/jinja.py index 898c8d3fc0d..f802156ddb8 100644 --- a/salt/utils/jinja.py +++ b/salt/utils/jinja.py @@ -239,9 +239,7 @@ class PrintableDict(OrderedDict): for key, value in self.items(): if isinstance(value, str): # keeps quotes around strings - # pylint: disable=repr-flag-used-in-string output.append(f"{key!r}: {value!r}") - # pylint: enable=repr-flag-used-in-string else: # let default output output.append(f"{key!r}: {value!s}") @@ -252,9 +250,7 @@ class PrintableDict(OrderedDict): for key, value in self.items(): # Raw string formatter required here because this is a repr # function. - # pylint: disable=repr-flag-used-in-string output.append(f"{key!r}: {value!r}") - # pylint: enable=repr-flag-used-in-string return "{" + ", ".join(output) + "}" diff --git a/salt/utils/msazure.py b/salt/utils/msazure.py index 28f8f33cc2f..de4419caacd 100644 --- a/salt/utils/msazure.py +++ b/salt/utils/msazure.py @@ -108,16 +108,14 @@ def put_blob(storage_conn=None, **kwargs): "x_ms_lease_id": kwargs.get("lease_id", None), } if "blob_path" in kwargs: - data = storage_conn.put_block_blob_from_path( + return storage_conn.put_block_blob_from_path( file_path=kwargs["blob_path"], **blob_kwargs ) elif "blob_content" in kwargs: - data = storage_conn.put_block_blob_from_bytes( + return storage_conn.put_block_blob_from_bytes( blob=kwargs["blob_content"], **blob_kwargs ) - return data - def get_blob(storage_conn=None, **kwargs): """ @@ -157,15 +155,13 @@ def get_blob(storage_conn=None, **kwargs): } if "local_path" in kwargs: - data = storage_conn.get_blob_to_path( + return storage_conn.get_blob_to_path( file_path=kwargs["local_path"], open_mode=kwargs.get("open_mode", "wb"), **blob_kwargs ) elif "return_content" in kwargs: - data = storage_conn.get_blob_to_bytes(**blob_kwargs) - - return data + return storage_conn.get_blob_to_bytes(**blob_kwargs) def object_to_dict(obj): diff --git a/salt/utils/nacl.py b/salt/utils/nacl.py index b04904c2e14..918eb942ca6 100644 --- a/salt/utils/nacl.py +++ b/salt/utils/nacl.py @@ -15,9 +15,9 @@ import salt.utils.win_functions REQ_ERROR = None try: - import nacl.public - import nacl.secret -except (ImportError, OSError) as e: + import nacl.public # pylint: disable=no-name-in-module + import nacl.secret # pylint: disable=no-name-in-module +except ImportError: REQ_ERROR = ( "PyNaCl import error, perhaps missing python PyNaCl package or should update." ) diff --git a/salt/utils/napalm.py b/salt/utils/napalm.py index 082be2167c9..d78422a7111 100644 --- a/salt/utils/napalm.py +++ b/salt/utils/napalm.py @@ -44,8 +44,11 @@ try: # try importing ConnectionClosedException # from napalm-base # this exception has been introduced only in version 0.24.0 + # pylint: disable=unused-import,no-name-in-module from napalm.base.exceptions import ConnectionClosedException + # pylint: enable=unused-import,no-name-in-module + HAS_CONN_CLOSED_EXC_CLASS = True except ImportError: HAS_CONN_CLOSED_EXC_CLASS = False @@ -93,10 +96,8 @@ def virtual(opts, virtualname, filename): else: return ( False, - '"{vname}"" {filename} cannot be loaded: ' - "NAPALM is not installed: ``pip install napalm``".format( - vname=virtualname, filename="({filename})".format(filename=filename) - ), + f'"{virtualname}" ({filename}) cannot be loaded: ' + "NAPALM is not installed: ``pip install napalm``", ) diff --git a/salt/utils/nb_popen.py b/salt/utils/nb_popen.py index 12cdc39e1b0..7624d609713 100644 --- a/salt/utils/nb_popen.py +++ b/salt/utils/nb_popen.py @@ -24,14 +24,12 @@ import time mswindows = sys.platform == "win32" -try: +if mswindows: import msvcrt import pywintypes from win32file import ReadFile, WriteFile from win32pipe import PeekNamedPipe -except ImportError: - import fcntl log = logging.getLogger(__name__) @@ -180,6 +178,8 @@ class NonBlockingPopen(subprocess.Popen): if conn is None: return None + import fcntl + flags = fcntl.fcntl(conn, fcntl.F_GETFL) if not conn.closed: fcntl.fcntl(conn, fcntl.F_SETFL, flags | os.O_NONBLOCK) diff --git a/salt/utils/network.py b/salt/utils/network.py index 9566f433444..13eaa4835ca 100644 --- a/salt/utils/network.py +++ b/salt/utils/network.py @@ -1722,9 +1722,7 @@ def _netlink_tool_remote_on(port, which_end): valid = False tcp_end = "dst" if which_end == "remote_port" else "src" try: - data = subprocess.check_output( - ["ss", "-ant", tcp_end, ":{}".format(port)] - ) # pylint: disable=minimum-python-version + data = subprocess.check_output(["ss", "-ant", tcp_end, f":{port}"]) except subprocess.CalledProcessError: log.error("Failed ss") raise @@ -1770,9 +1768,7 @@ def _sunos_remotes_on(port, which_end): # pragma: no cover """ remotes = set() try: - data = subprocess.check_output( - ["netstat", "-f", "inet", "-n"] - ) # pylint: disable=minimum-python-version + data = subprocess.check_output(["netstat", "-f", "inet", "-n"]) except subprocess.CalledProcessError: log.error("Failed netstat") raise @@ -1817,8 +1813,8 @@ def _freebsd_remotes_on(port, which_end): # pragma: no cover remotes = set() try: - cmd = salt.utils.args.shlex_split("sockstat -4 -c -p {}".format(port)) - data = subprocess.check_output(cmd) # pylint: disable=minimum-python-version + cmd = salt.utils.args.shlex_split(f"sockstat -4 -c -p {port}") + data = subprocess.check_output(cmd) except subprocess.CalledProcessError as ex: log.error('Failed "sockstat" with returncode = %s', ex.returncode) raise @@ -1879,8 +1875,8 @@ def _netbsd_remotes_on(port, which_end): # pragma: no cover remotes = set() try: - cmd = salt.utils.args.shlex_split("sockstat -4 -c -n -p {}".format(port)) - data = subprocess.check_output(cmd) # pylint: disable=minimum-python-version + cmd = salt.utils.args.shlex_split(f"sockstat -4 -c -n -p {port}") + data = subprocess.check_output(cmd) except subprocess.CalledProcessError as ex: log.error('Failed "sockstat" with returncode = %s', ex.returncode) raise @@ -1932,9 +1928,7 @@ def _openbsd_remotes_on(port, which_end): # pragma: no cover """ remotes = set() try: - data = subprocess.check_output( - ["netstat", "-nf", "inet"] - ) # pylint: disable=minimum-python-version + data = subprocess.check_output(["netstat", "-nf", "inet"]) except subprocess.CalledProcessError as exc: log.error('Failed "netstat" with returncode = %s', exc.returncode) raise @@ -1973,9 +1967,7 @@ def _windows_remotes_on(port, which_end): """ remotes = set() try: - data = subprocess.check_output( - ["netstat", "-n"] - ) # pylint: disable=minimum-python-version + data = subprocess.check_output(["netstat", "-n"]) except subprocess.CalledProcessError: log.error("Failed netstat") raise @@ -2024,7 +2016,7 @@ def _linux_remotes_on(port, which_end): "-iTCP:{:d}".format(port), "-n", "-P", - ] # pylint: disable=minimum-python-version + ] ) except subprocess.CalledProcessError as ex: if ex.returncode == 1: @@ -2089,9 +2081,7 @@ def _aix_remotes_on(port, which_end): # pragma: no cover """ remotes = set() try: - data = subprocess.check_output( - ["netstat", "-f", "inet", "-n"] - ) # pylint: disable=minimum-python-version + data = subprocess.check_output(["netstat", "-f", "inet", "-n"]) except subprocess.CalledProcessError: log.error("Failed netstat") raise @@ -2332,9 +2322,8 @@ def filter_by_networks(values, networks): {{ grains['ipv4'] | filter_by_networks(networks) }} """ - _filter = lambda ips, networks: [ - ip for ip in ips for net in networks if ipaddress.ip_address(ip) in net - ] + def _filter(ips, networks): + return [ip for ip in ips for net in networks if ipaddress.ip_address(ip) in net] if networks is not None: networks = [ipaddress.ip_network(network) for network in networks] diff --git a/salt/utils/odict.py b/salt/utils/odict.py index 76f313fe5be..bf9dd06e448 100644 --- a/salt/utils/odict.py +++ b/salt/utils/odict.py @@ -5,311 +5,16 @@ salt.utils.odict ~~~~~~~~~~~~~~~~ - This is a compatibility/"importability" layer for an ordered dictionary. - Tries to import from the standard library if python >= 2.7, then from the - ``ordereddict`` package available from PyPi, and, as a last resort, - provides an ``OrderedDict`` implementation based on:: - - http://code.activestate.com/recipes/576669/ - - It also implements a DefaultOrderedDict Class that serves as a + Implements a DefaultOrderedDict Class that serves as a combination of ``OrderedDict`` and ``defaultdict`` It's source was submitted here:: http://stackoverflow.com/questions/6190331/ """ - -# pragma: no cover # essentially using Python's OrderDict - - +import copy +from collections import OrderedDict from collections.abc import Callable -try: - # pylint: disable=E0611,minimum-python-version - import collections - - class OrderedDict(collections.OrderedDict): - __hash__ = None - -except (ImportError, AttributeError): - try: - import ordereddict - - class OrderedDict(ordereddict.OrderedDict): # pylint: disable=W0232 - __hash_ = None - - except ImportError: - # {{{ http://code.activestate.com/recipes/576693/ (r9) - # Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. - # Passes Python2.7's test suite and incorporates all the latest updates. - - try: - from _thread import get_ident as _get_ident - except ImportError: - from _dummy_thread import get_ident as _get_ident - - # try: - # from _abcoll import KeysView, ValuesView, ItemsView - # except ImportError: - # pass - - class OrderedDict(dict): - "Dictionary that remembers insertion order" - # An inherited dict maps keys to values. - # The inherited dict provides __getitem__, __len__, __contains__, and get. - # The remaining methods are order-aware. - # Big-O running times for all methods are the same as for regular dictionaries. - - # The internal self.__map dictionary maps keys to links in a doubly linked list. - # The circular doubly linked list starts and ends with a sentinel element. - # The sentinel element never gets deleted (this simplifies the algorithm). - # Each link is stored as a list of length three: [PREV, NEXT, KEY]. - __hash_ = None - - def __init__(self, *args, **kwds): # pylint: disable=E1003 - """Initialize an ordered dictionary. Signature is the same as for - regular dictionaries, but keyword arguments are not recommended - because their insertion order is arbitrary. - - """ - super().__init__() - if len(args) > 1: - raise TypeError( - "expected at most 1 arguments, got {}".format(len(args)) - ) - try: - self.__root - except AttributeError: - self.__root = root = [] # sentinel node - root[:] = [root, root, None] - self.__map = {} - self.__update(*args, **kwds) - - def __setitem__(self, key, value, dict_setitem=dict.__setitem__): - "od.__setitem__(i, y) <==> od[i]=y" - # Setting a new item creates a new link which goes at the end of the linked - # list, and the inherited dictionary is updated with the new key/value pair. - if key not in self: - root = self.__root - last = root[0] - last[1] = root[0] = self.__map[key] = [last, root, key] - dict_setitem(self, key, value) - - def __delitem__(self, key, dict_delitem=dict.__delitem__): - "od.__delitem__(y) <==> del od[y]" - # Deleting an existing item uses self.__map to find the link which is - # then removed by updating the links in the predecessor and successor nodes. - dict_delitem(self, key) - link_prev, link_next, key = self.__map.pop(key) - link_prev[1] = link_next - link_next[0] = link_prev - - def __iter__(self): - "od.__iter__() <==> iter(od)" - root = self.__root - curr = root[1] - while curr is not root: - yield curr[2] - curr = curr[1] - - def __reversed__(self): - "od.__reversed__() <==> reversed(od)" - root = self.__root - curr = root[0] - while curr is not root: - yield curr[2] - curr = curr[0] - - def clear(self): - "od.clear() -> None. Remove all items from od." - try: - for node in self.__map.values(): - del node[:] - root = self.__root - root[:] = [root, root, None] - self.__map.clear() - except AttributeError: - pass - dict.clear(self) - - def popitem(self, last=True): - """od.popitem() -> (k, v), return and remove a (key, value) pair. - Pairs are returned in LIFO order if last is true or FIFO order if false. - - """ - if not self: - raise KeyError("dictionary is empty") - root = self.__root - if last: - link = root[0] - link_prev = link[0] - link_prev[1] = root - root[0] = link_prev - else: - link = root[1] - link_next = link[1] - root[1] = link_next - link_next[0] = root - key = link[2] - del self.__map[key] - value = dict.pop(self, key) - return key, value - - # -- the following methods do not depend on the internal structure -- - - def keys(self): - "od.keys() -> list of keys in od" - return list(self) - - def values(self): - "od.values() -> list of values in od" - return [self[key] for key in self] - - def items(self): - "od.items() -> list of (key, value) pairs in od" - return [(key, self[key]) for key in self] - - def iterkeys(self): - "od.iterkeys() -> an iterator over the keys in od" - return iter(self) - - def itervalues(self): - "od.itervalues -> an iterator over the values in od" - for k in self: - yield self[k] - - def iteritems(self): - "od.iteritems -> an iterator over the (key, value) items in od" - for k in self: - yield (k, self[k]) - - def update(*args, **kwds): # pylint: disable=E0211 - """od.update(E, **F) -> None. Update od from dict/iterable E and F. - - If E is a dict instance, does: for k in E: od[k] = E[k] - If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] - Or if E is an iterable of items, does: for k, v in E: od[k] = v - In either case, this is followed by: for k, v in F.items(): od[k] = v - - """ - if len(args) > 2: - raise TypeError( - "update() takes at most 2 positional " - "arguments ({} given)".format(len(args)) - ) - elif not args: - raise TypeError("update() takes at least 1 argument (0 given)") - self = args[0] - # Make progressively weaker assumptions about "other" - other = () - if len(args) == 2: - other = args[1] - if isinstance(other, dict): - for key in other: - self[key] = other[key] - elif hasattr(other, "keys"): - for key in other: - self[key] = other[key] - else: - for key, value in other: - self[key] = value - for key, value in kwds.items(): - self[key] = value - - __update = ( - update # let subclasses override update without breaking __init__ - ) - - __marker = object() - - def pop(self, key, default=__marker): - """od.pop(k[,d]) -> v, remove specified key and return the corresponding value. - If key is not found, d is returned if given, otherwise KeyError is raised. - - """ - if key in self: - result = self[key] - del self[key] - return result - if default is self.__marker: - raise KeyError(key) - return default - - def setdefault(self, key, default=None): - "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od" - if key in self: - return self[key] - self[key] = default - return default - - def __repr__(self, _repr_running={}): # pylint: disable=W0102 - "od.__repr__() <==> repr(od)" - call_key = id(self), _get_ident() - if call_key in _repr_running: - return "..." - _repr_running[call_key] = 1 - try: - if not self: - return "{}()".format(self.__class__.__name__) - return "{}('{}')".format( - self.__class__.__name__, list(self.items()) - ) - finally: - del _repr_running[call_key] - - def __reduce__(self): - "Return state information for pickling" - items = [[k, self[k]] for k in self] - inst_dict = vars(self).copy() - for k in vars(OrderedDict()): - inst_dict.pop(k, None) - if inst_dict: - return (self.__class__, (items,), inst_dict) - return self.__class__, (items,) - - def copy(self): - "od.copy() -> a shallow copy of od" - return self.__class__(self) - - @classmethod - def fromkeys(cls, iterable, value=None): - """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S - and values equal to v (which defaults to None). - - """ - d = cls() - for key in iterable: - d[key] = value - return d - - def __eq__(self, other): - """od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive - while comparison to a regular mapping is order-insensitive. - - """ - if isinstance(other, OrderedDict): - return len(self) == len(other) and self.items() == other.items() - return dict.__eq__(self, other) - - def __ne__(self, other): - return not self == other - - -# # -- the following methods are only used in Python 2.7 -- -# -# def viewkeys(self): -# "od.viewkeys() -> a set-like object providing a view on od's keys" -# return KeysView(self) -# -# def viewvalues(self): -# "od.viewvalues() -> an object providing a view on od's values" -# return ValuesView(self) -# -# def viewitems(self): -# "od.viewitems() -> a set-like object providing a view on od's items" -# return ItemsView(self) -# ## end of http://code.activestate.com/recipes/576693/ }}} - class DefaultOrderedDict(OrderedDict): """ @@ -342,7 +47,7 @@ class DefaultOrderedDict(OrderedDict): return type(self), args, None, None, self.items() def copy(self): - return self.__copy__() + return copy.copy(self) def __copy__(self): return type(self)(self.default_factory, self) diff --git a/salt/utils/openstack/nova.py b/salt/utils/openstack/nova.py index 4c3855edb31..386b585c861 100644 --- a/salt/utils/openstack/nova.py +++ b/salt/utils/openstack/nova.py @@ -197,7 +197,7 @@ class NovaServer: self.extra["password"] = password def __str__(self): - return self.__dict__ + return str(self.__dict__) def get_entry(dict_, key, value, raise_error=True): diff --git a/salt/utils/oset.py b/salt/utils/oset.py index d0bd6536e82..85cc0931328 100644 --- a/salt/utils/oset.py +++ b/salt/utils/oset.py @@ -113,7 +113,7 @@ class OrderedSet(MutableSet): def __contains__(self, key): return key in self.map - def add(self, key): # pylint: disable=arguments-differ + def add(self, key): # pylint: disable=arguments-differ,arguments-renamed """ Add `key` as an item to this OrderedSet, then return its index. @@ -168,7 +168,7 @@ class OrderedSet(MutableSet): del self.map[elem] return elem - def discard(self, key): # pylint: disable=arguments-differ + def discard(self, key): # pylint: disable=arguments-differ,arguments-renamed """ Remove an element. Do not raise an exception if absent. diff --git a/salt/utils/parsers.py b/salt/utils/parsers.py index 036530820d8..385e69f6a15 100644 --- a/salt/utils/parsers.py +++ b/salt/utils/parsers.py @@ -13,7 +13,7 @@ import copy import getpass import logging -import optparse +import optparse # pylint: disable=deprecated-module import os import signal import sys diff --git a/salt/utils/path.py b/salt/utils/path.py index ed4b4a0f35a..f6aa7d5dad7 100644 --- a/salt/utils/path.py +++ b/salt/utils/path.py @@ -182,9 +182,11 @@ def which(exe=None): # The specified extension isn't valid, so we just assume it's part of the # filename and proceed to walk the pathext list else: - is_executable = lambda path, membership=res: is_executable_common( - path - ) and has_executable_ext(path, membership) + + def is_executable(path, membership=res): + return is_executable_common(path) and has_executable_ext( + path, membership + ) else: # in posix, there's no such thing as file extensions..only zuul diff --git a/salt/utils/pkg/__init__.py b/salt/utils/pkg/__init__.py index 9a11e492a04..3dfa9884bb4 100644 --- a/salt/utils/pkg/__init__.py +++ b/salt/utils/pkg/__init__.py @@ -33,7 +33,7 @@ def clear_rtag(opts): if exc.errno != errno.ENOENT: # Using __str__() here to get the fully-formatted error message # (error number, error message, path) - log.warning("Encountered error removing rtag: %s", exc.__str__()) + log.warning("Encountered error removing rtag: %s", exc) def write_rtag(opts): @@ -46,7 +46,7 @@ def write_rtag(opts): with salt.utils.files.fopen(rtag_file, "w+"): pass except OSError as exc: - log.warning("Encountered error writing rtag: %s", exc.__str__()) + log.warning("Encountered error writing rtag: %s", exc) def check_refresh(opts, refresh=None): diff --git a/salt/utils/pkg/win.py b/salt/utils/pkg/win.py index c34fa2c26b3..f988f7a99af 100644 --- a/salt/utils/pkg/win.py +++ b/salt/utils/pkg/win.py @@ -825,7 +825,7 @@ class WinSoftware: Returns: str: Package Id """ - return self.__next__() + return next(self) def get(self, pkg_id, default_value=None): """ @@ -848,7 +848,7 @@ class WinSoftware: return 1 if Version(ver1) > Version(ver2) else -1 @staticmethod - def __latest_to_oldest_version(ver1, ver2): + def __latest_to_oldest_version(ver1, ver2): # pylint: disable=unused-private-member """ Used for sorting version numbers, latest to oldest """ diff --git a/salt/utils/preseed.py b/salt/utils/preseed.py index 749b24dace4..3b1f6105950 100644 --- a/salt/utils/preseed.py +++ b/salt/utils/preseed.py @@ -25,7 +25,7 @@ def mksls(src, dst=None): continue comps = shlex.split(line) - if comps[0] not in ps_opts.keys(): + if comps[0] not in ps_opts: ps_opts[comps[0]] = {} cmds = comps[1].split("/") diff --git a/salt/utils/process.py b/salt/utils/process.py index 6c393706acd..765a2fac8d9 100644 --- a/salt/utils/process.py +++ b/salt/utils/process.py @@ -590,7 +590,7 @@ class ProcessManager: # with the tree option will not be able to find them. return - for pid in self._process_map.copy().keys(): + for pid in self._process_map.copy(): try: os.kill(pid, signal_) except OSError as exc: @@ -942,7 +942,7 @@ class Process(multiprocessing.Process): "logging_config": self.__logging_config__, } - def __decorate_run(self, run_func): + def __decorate_run(self, run_func): # pylint: disable=unused-private-member @functools.wraps(run_func) def wrapped_run_func(): # Static after fork method, always needs to happen first diff --git a/salt/utils/psutil_compat.py b/salt/utils/psutil_compat.py index e6684e5ca46..ef5d9768c10 100644 --- a/salt/utils/psutil_compat.py +++ b/salt/utils/psutil_compat.py @@ -9,104 +9,4 @@ Should be removed once support for psutil <2.0 is dropped. (eg RHEL 6) Built off of http://grodola.blogspot.com/2014/01/psutil-20-porting.html """ - -# No exception handling, as we want ImportError if psutil doesn't exist -import psutil # pylint: disable=3rd-party-module-not-gated - -if psutil.version_info >= (2, 0): - from psutil import * # pylint: disable=wildcard-import,unused-wildcard-import,3rd-party-module-not-gated -else: - # Import hack to work around bugs in old psutil's - # Psuedo "from psutil import *" - _globals = globals() - for attr in psutil.__all__: - _temp = __import__("psutil", globals(), locals(), [attr], 0) - try: - _globals[attr] = getattr(_temp, attr) - except AttributeError: - pass - - # Import functions not in __all__ - # pylint: disable=unused-import,3rd-party-module-not-gated - from psutil import disk_partitions, disk_usage - - # pylint: enable=unused-import,3rd-party-module-not-gated - # Alias new module functions - def boot_time(): - return psutil.BOOT_TIME - - def cpu_count(): - return psutil.NUM_CPUS - - # Alias renamed module functions - pids = psutil.get_pid_list - try: - users = psutil.get_users - except AttributeError: - users = lambda: (_ for _ in ()).throw( - NotImplementedError("Your psutil version is too old") - ) - - # Deprecated in 1.0.1, but not mentioned in blog post - if psutil.version_info < (1, 0, 1): - net_io_counters = psutil.network_io_counters() - - class Process(psutil.Process): # pylint: disable=no-init - # Reimplement overloaded getters/setters - # pylint: disable=arguments-differ - def cpu_affinity(self, *args, **kwargs): - if args or kwargs: - return self.set_cpu_affinity(*args, **kwargs) - else: - return self.get_cpu_affinity() - - def ionice(self, *args, **kwargs): - if args or kwargs: - return self.set_ionice(*args, **kwargs) - else: - return self.get_ionice() - - def nice(self, *args, **kwargs): - if args or kwargs: - return self.set_nice(*args, **kwargs) - else: - return self.get_nice() - - def rlimit(self, *args, **kwargs): - """ - set_rlimit and get_limit were not introduced until psutil v1.1.0 - """ - if psutil.version_info >= (1, 1, 0): - if args or kwargs: - return self.set_rlimit(*args, **kwargs) - else: - return self.get_rlimit() - else: - pass - - # pylint: enable=arguments-differ - - # Alias renamed Process functions - _PROCESS_FUNCTION_MAP = { - "children": "get_children", - "connections": "get_connections", - "cpu_percent": "get_cpu_percent", - "cpu_times": "get_cpu_times", - "io_counters": "get_io_counters", - "memory_info": "get_memory_info", - "memory_info_ex": "get_ext_memory_info", - "memory_maps": "get_memory_maps", - "memory_percent": "get_memory_percent", - "num_ctx_switches": "get_num_ctx_switches", - "num_fds": "get_num_fds", - "num_threads": "get_num_threads", - "open_files": "get_open_files", - "threads": "get_threads", - "cwd": "getcwd", - } - - for new, old in _PROCESS_FUNCTION_MAP.items(): - try: - setattr(Process, new, psutil.Process.__dict__[old]) - except KeyError: - pass +from psutil import * # pylint: disable=wildcard-import,unused-wildcard-import,3rd-party-module-not-gated diff --git a/salt/utils/reactor.py b/salt/utils/reactor.py index 19420a51cf0..3ddb363117c 100644 --- a/salt/utils/reactor.py +++ b/salt/utils/reactor.py @@ -312,6 +312,7 @@ class ReactWrap: Populate the client cache with an instance of the specified type """ reaction_type = low["state"] + # pylint: disable=unsupported-membership-test,unsupported-assignment-operation if reaction_type not in self.client_cache: log.debug("Reactor is populating %s client cache", reaction_type) if reaction_type in ("runner", "wheel"): @@ -333,6 +334,7 @@ class ReactWrap: self.client_cache[reaction_type] = self.reaction_class[reaction_type]( self.opts["conf_file"] ) + # pylint: enable=unsupported-membership-test,unsupported-assignment-operation def run(self, low): """ diff --git a/salt/utils/ssdp.py b/salt/utils/ssdp.py index 497accb522e..4c7e588284d 100644 --- a/salt/utils/ssdp.py +++ b/salt/utils/ssdp.py @@ -157,7 +157,10 @@ class SSDPFactory(SSDPBase): :return: """ tries = 0 - slp_time = lambda: 0.5 / random.randint(10, 30) + + def slp_time(): + return 0.5 / random.randint(10, 30) + slp = slp_time() while tries < attempts: try: diff --git a/salt/utils/templates.py b/salt/utils/templates.py index 554c76d51e1..872d92686af 100644 --- a/salt/utils/templates.py +++ b/salt/utils/templates.py @@ -2,6 +2,8 @@ Template render systems """ import codecs +import importlib.machinery +import importlib.util import logging import os import sys @@ -32,17 +34,6 @@ from salt.utils.decorators.jinja import JinjaFilter, JinjaGlobal, JinjaTest from salt.utils.odict import OrderedDict from salt.utils.versions import Version -if sys.version_info[:2] >= (3, 5): - import importlib.machinery # pylint: disable=no-name-in-module,import-error - import importlib.util # pylint: disable=no-name-in-module,import-error - - USE_IMPORTLIB = True -else: - import imp - - USE_IMPORTLIB = False - - log = logging.getLogger(__name__) @@ -676,18 +667,13 @@ def py(sfn, string=False, **kwargs): # pylint: disable=C0103 base_fname = os.path.basename(sfn) name = base_fname.split(".")[0] - if USE_IMPORTLIB: - # pylint: disable=no-member - loader = importlib.machinery.SourceFileLoader(name, sfn) - spec = importlib.util.spec_from_file_location(name, sfn, loader=loader) - if spec is None: - raise ImportError() - mod = importlib.util.module_from_spec(spec) - spec.loader.exec_module(mod) - # pylint: enable=no-member - sys.modules[name] = mod - else: - mod = imp.load_source(name, sfn) + loader = importlib.machinery.SourceFileLoader(name, sfn) + spec = importlib.util.spec_from_file_location(name, sfn, loader=loader) + if spec is None: + raise ImportError() + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + sys.modules[name] = mod # File templates need these set as __var__ if "__env__" not in kwargs and "saltenv" in kwargs: diff --git a/salt/utils/vault.py b/salt/utils/vault.py index 07fcf3929b1..9e31adf5066 100644 --- a/salt/utils/vault.py +++ b/salt/utils/vault.py @@ -136,10 +136,16 @@ def get_vault_connection(): if namespace is not None: headers = {"X-Vault-Namespace": namespace} response = requests.post( - url, headers=headers, json=payload, verify=verify + url, + headers=headers, + json=payload, + verify=verify, + timeout=120, ) else: - response = requests.post(url, json=payload, verify=verify) + response = requests.post( + url, json=payload, verify=verify, timeout=120 + ) if response.status_code != 200: errmsg = "An error occurred while getting a token from approle" raise salt.exceptions.CommandExecutionError(errmsg) @@ -153,7 +159,9 @@ def get_vault_connection(): headers = {"X-Vault-Token": __opts__["vault"]["auth"]["token"]} if namespace is not None: headers["X-Vault-Namespace"] = namespace - response = requests.post(url, headers=headers, verify=verify) + response = requests.post( + url, headers=headers, verify=verify, timeout=120 + ) if response.status_code != 200: errmsg = "An error occured while unwrapping vault token" raise salt.exceptions.CommandExecutionError(errmsg) @@ -334,19 +342,21 @@ def make_request( token = connection["token"] if not token else token vault_url = connection["url"] if not vault_url else vault_url namespace = namespace or connection.get("namespace") - if "verify" in args: - args["verify"] = args["verify"] - else: + if "verify" not in args: try: args["verify"] = __opts__.get("vault").get("verify", None) except (TypeError, AttributeError): # Don't worry about setting verify if it doesn't exist pass + if "timeout" not in args: + args["timeout"] = 120 url = "{}/{}".format(vault_url, resource) headers = {"X-Vault-Token": str(token), "Content-Type": "application/json"} if namespace is not None: headers["X-Vault-Namespace"] = namespace - response = requests.request(method, url, headers=headers, **args) + response = requests.request( # pylint: disable=missing-timeout + method, url, headers=headers, **args + ) if not response.ok and response.json().get("errors", None) == ["permission denied"]: log.info("Permission denied from vault") del_cache() @@ -407,7 +417,7 @@ def _selftoken_expired(): headers = {"X-Vault-Token": __opts__["vault"]["auth"]["token"]} if namespace is not None: headers["X-Vault-Namespace"] = namespace - response = requests.get(url, headers=headers, verify=verify) + response = requests.get(url, headers=headers, verify=verify, timeout=120) if response.status_code != 200: return True return False @@ -431,7 +441,7 @@ def _wrapped_token_valid(): headers = {"X-Vault-Token": __opts__["vault"]["auth"]["token"]} if namespace is not None: headers["X-Vault-Namespace"] = namespace - response = requests.post(url, headers=headers, verify=verify) + response = requests.post(url, headers=headers, verify=verify, timeout=120) if response.status_code != 200: return False return True diff --git a/salt/utils/verify.py b/salt/utils/verify.py index ab468dd04c1..00f81f5c413 100644 --- a/salt/utils/verify.py +++ b/salt/utils/verify.py @@ -327,7 +327,7 @@ def check_user(user): try: if hasattr(os, "initgroups"): - os.initgroups(user, pwuser.pw_gid) # pylint: disable=minimum-python-version + os.initgroups(user, pwuser.pw_gid) else: os.setgroups(salt.utils.user.get_gid_list(user, include_default=False)) os.setgid(pwuser.pw_gid) @@ -418,7 +418,10 @@ def check_max_open_files(opts): # and the python binding http://timgolden.me.uk/pywin32-docs/win32file.html mof_s = mof_h = win32file._getmaxstdio() else: - mof_s, mof_h = resource.getrlimit(resource.RLIMIT_NOFILE) + + mof_s, mof_h = resource.getrlimit( # pylint: disable=used-before-assignment + resource.RLIMIT_NOFILE + ) accepted_keys_dir = os.path.join(opts.get("pki_dir"), "minions") accepted_count = len(os.listdir(accepted_keys_dir)) diff --git a/salt/utils/versions.py b/salt/utils/versions.py index 9a97fee1bd7..5c03a15b090 100644 --- a/salt/utils/versions.py +++ b/salt/utils/versions.py @@ -352,7 +352,10 @@ def version_cmp(pkg1, pkg2, ignore_epoch=False): version2, and 1 if version1 > version2. Return None if there was a problem making the comparison. """ - normalize = lambda x: str(x).split(":", 1)[-1] if ignore_epoch else str(x) + + def normalize(x): + return str(x).split(":", 1)[-1] if ignore_epoch else str(x) + pkg1 = normalize(pkg1) pkg2 = normalize(pkg2) diff --git a/salt/utils/vt.py b/salt/utils/vt.py index 42635b3be29..55b8172905b 100644 --- a/salt/utils/vt.py +++ b/salt/utils/vt.py @@ -73,6 +73,7 @@ def setwinsize(child, rows=80, cols=80): Thank you for the shortcut PEXPECT """ + # pylint: disable=used-before-assignment TIOCSWINSZ = getattr(termios, "TIOCSWINSZ", -2146929561) if TIOCSWINSZ == 2148037735: # Same bits, but with sign. @@ -396,7 +397,7 @@ class Terminal: def _spawn(self): if not isinstance(self.args, str) and self.shell is True: self.args = " ".join(self.args) - parent, child = pty.openpty() + parent, child = pty.openpty() # pylint: disable=used-before-assignment err_parent, err_child = os.pipe() child_name = os.ttyname(child) proc = subprocess.Popen( # pylint: disable=subprocess-popen-preexec-fn diff --git a/salt/utils/win_network.py b/salt/utils/win_network.py index eeae8fc091b..1e8ac4db3b8 100644 --- a/salt/utils/win_network.py +++ b/salt/utils/win_network.py @@ -330,6 +330,7 @@ def _get_ip_wins_info(i_face): def _get_network_interfaces(): + # pylint: disable=used-before-assignment return NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() diff --git a/salt/utils/win_runas.py b/salt/utils/win_runas.py index 0b695aaad26..b50bc01ddb9 100644 --- a/salt/utils/win_runas.py +++ b/salt/utils/win_runas.py @@ -81,7 +81,8 @@ def create_env(user_token, inherit, timeout=1): break if env is not None: return env - raise exc + if exc is not None: + raise exc def runas(cmdLine, username, password=None, cwd=None): diff --git a/salt/version.py b/salt/version.py index ab852acca0b..8cc50f6ef05 100644 --- a/salt/version.py +++ b/salt/version.py @@ -58,7 +58,7 @@ class SaltVersionsInfo(type): _previous_release = None _next_release = None - # pylint: disable=bad-whitespace,multiple-spaces-before-operator + # pylint: disable=bad-whitespace # ----- Please refrain from fixing whitespace ----------------------------------> # The idea is to keep this readable. # ------------------------------------------------------------------------------- @@ -184,7 +184,7 @@ class SaltVersionsInfo(type): # <---- Please refrain from fixing whitespace ----------------------------------- # The idea is to keep this readable. # ------------------------------------------------------------------------------- - # pylint: enable=bad-whitespace,multiple-spaces-before-operator + # pylint: enable=bad-whitespace # fmt: on @classmethod @@ -862,7 +862,7 @@ def versions_information(include_salt_cloud=False, include_extensions=True): Report the versions of dependent software. """ py_info = [ - ("Python", sys.version.rsplit("\n")[0].strip()), + ("Python", sys.version.rsplit("\n", maxsplit=1)[0].strip()), ] salt_info = list(salt_information()) lib_info = list(dependency_information(include_salt_cloud)) diff --git a/setup.py b/setup.py index c2992548c93..f4d171f9293 100755 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ The setup script for salt """ -# pylint: disable=file-perms,resource-leakage +# pylint: disable=file-perms,resource-leakage,deprecated-module import setuptools # isort:skip import distutils.dist import glob @@ -181,7 +181,7 @@ else: def _parse_requirements_file(requirements_file): parsed_requirements = [] - with open(requirements_file) as rfh: + with open(requirements_file, encoding="utf-8") as rfh: for line in rfh.readlines(): line = line.strip() if not line or line.startswith(("#", "-r", "--")): @@ -260,7 +260,9 @@ class GenerateSaltSyspaths(Command): exit(1) # Write the system paths file - open(self.distribution.salt_syspaths_hardcoded_path, "w").write( + open( + self.distribution.salt_syspaths_hardcoded_path, "w", encoding="utf-8" + ).write( INSTALL_SYSPATHS_TEMPLATE.format( date=DATE, root_dir=self.distribution.salt_root_dir, @@ -308,9 +310,9 @@ class WriteSaltSshPackagingFile(Command): exit(1) # pylint: disable=E0602 - open(self.distribution.salt_ssh_packaging_file, "w").write( - "Packaged for Salt-SSH\n" - ) + open( + self.distribution.salt_ssh_packaging_file, "w", encoding="utf-8" + ).write("Packaged for Salt-SSH\n") # pylint: enable=E0602 @@ -463,7 +465,7 @@ class CloudSdist(Sdist): # pylint: disable=too-many-ancestors try: import requests - req = requests.get(url) + req = requests.get(url, timeout=120) if req.status_code == 200: script_contents = req.text.encode(req.encoding) else: @@ -482,7 +484,7 @@ class CloudSdist(Sdist): # pylint: disable=too-many-ancestors "Error code: {}".format(req.getcode()) ) try: - with open(deploy_path, "w") as fp_: + with open(deploy_path, "w", encoding="utf-8") as fp_: fp_.write(script_contents) except OSError as err: log.error("Failed to write the updated script: {}".format(err)) diff --git a/tests/buildpackage.py b/tests/buildpackage.py index 108cd729a0b..26a2faa5e91 100644 --- a/tests/buildpackage.py +++ b/tests/buildpackage.py @@ -18,7 +18,7 @@ import re import shutil import subprocess import sys -from optparse import OptionGroup, OptionParser +from optparse import OptionGroup, OptionParser # pylint: disable=deprecated-module logging.QUIET = 0 logging.GARBAGE = 1 @@ -236,7 +236,7 @@ def build_centos(opts): log.info("Building CentOS RPM") log.info("Detecting major release") try: - with open("/etc/redhat-release") as fp_: + with open("/etc/redhat-release", encoding="utf-8") as fp_: redhat_release = fp_.read().strip() major_release = int(redhat_release.split()[2].split(".")[0]) except (ValueError, IndexError): @@ -322,9 +322,9 @@ def build_centos(opts): # Prepare SPEC file spec_path = os.path.join(opts.build_dir, "SPECS", "salt.spec") - with open(opts.spec_file) as spec: + with open(opts.spec_file, encoding="utf-8") as spec: spec_lines = spec.read().splitlines() - with open(spec_path, "w") as fp_: + with open(spec_path, "w", encoding="utf-8") as fp_: for line in spec_lines: if line.startswith("%global srcver "): line = "%global srcver {}".format(salt_srcver) diff --git a/tests/committer_parser.py b/tests/committer_parser.py index 8056b7fd406..25572bb3268 100644 --- a/tests/committer_parser.py +++ b/tests/committer_parser.py @@ -53,7 +53,7 @@ def parse_gitlog(filename=None): if not filename or filename == "-": fh = sys.stdin else: - fh = open(filename, "r+") + fh = open(filename, "r+", encoding="utf-8") try: commitcount = 0 diff --git a/tests/conftest.py b/tests/conftest.py index b6adab5401d..38cfa97c7f7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -34,7 +34,7 @@ from tests.support.helpers import ( PRE_PYTEST_SKIP_REASON, get_virtualenv_binary_path, ) -from tests.support.pytest.helpers import * # pylint: disable=unused-wildcard-import +from tests.support.pytest.helpers import * # pylint: disable=unused-wildcard-import,wildcard-import from tests.support.runtests import RUNTIME_VARS from tests.support.sminion import check_required_sminion_attributes, create_sminion @@ -1559,7 +1559,7 @@ def from_filenames_collection_modifyitems(config, items): ): # In this case, this path is considered to be a file containing a line separated list # of files to consider - contents = properly_slashed_path.read_text() + contents = properly_slashed_path.read_text(encoding="utf-8") for sep in ("\r\n", "\\r\\n", "\\n"): contents = contents.replace(sep, "\n") for line in contents.split("\n"): diff --git a/tests/eventlisten.py b/tests/eventlisten.py index 8ff5ada8232..4b56378a448 100644 --- a/tests/eventlisten.py +++ b/tests/eventlisten.py @@ -4,9 +4,7 @@ what the sock_dir is. This script is a generic tool to test event output """ - - -import optparse +import optparse # pylint: disable=deprecated-module import os import pprint import time diff --git a/tests/integration/cloud/clouds/test_oneandone.py b/tests/integration/cloud/clouds/test_oneandone.py index 632f2b871d3..64a2d16694d 100644 --- a/tests/integration/cloud/clouds/test_oneandone.py +++ b/tests/integration/cloud/clouds/test_oneandone.py @@ -5,15 +5,9 @@ import pytest from tests.integration.cloud.helpers.cloud_test_base import TIMEOUT, CloudTest -try: - from oneandone.client import OneAndOneService # pylint: disable=unused-import - - HAS_ONEANDONE = True -except ImportError: - HAS_ONEANDONE = False +pytest.importorskip("oneandone.client", reason="salt-cloud requires >= 1and1 1.2.0") -@pytest.mark.skipif(HAS_ONEANDONE is False, reason="salt-cloud requires >= 1and1 1.2.0") class OneAndOneTest(CloudTest): """ Integration tests for the 1and1 cloud provider @@ -26,7 +20,7 @@ class OneAndOneTest(CloudTest): """ Tests the return of running the --list-images command for 1and1 """ - image_list = self.run_cloud("--list-images {}".format(self.PROVIDER_NAME)) + image_list = self.run_cloud(f"--list-images {self.PROVIDER_NAME}") self.assertIn("coreOSimage", [i.strip() for i in image_list]) def test_instance(self): @@ -35,7 +29,7 @@ class OneAndOneTest(CloudTest): """ # check if instance with salt installed returned ret_str = self.run_cloud( - "-p oneandone-test {}".format(self.instance_name), timeout=TIMEOUT + f"-p oneandone-test {self.instance_name}", timeout=TIMEOUT ) self.assertInstanceExists(ret_str) diff --git a/tests/integration/cloud/clouds/test_vmware.py b/tests/integration/cloud/clouds/test_vmware.py index 1e82566fc21..a0845cb8a6b 100644 --- a/tests/integration/cloud/clouds/test_vmware.py +++ b/tests/integration/cloud/clouds/test_vmware.py @@ -102,7 +102,7 @@ class VMWareTest(CloudTest): """ # salt-cloud -p my-instant-clone IC3 profile_name = "vmware-test-instant-clone" - self.run_cloud(f"-a remove_all_snapshots cloud-tests-template-base") + self.run_cloud("-a remove_all_snapshots cloud-tests-template-base") # create the instance log_format = "%(message)s" diff --git a/tests/integration/modules/test_cp.py b/tests/integration/modules/test_cp.py index af873bb6784..7c92978b31c 100644 --- a/tests/integration/modules/test_cp.py +++ b/tests/integration/modules/test_cp.py @@ -597,7 +597,9 @@ class CPModuleTest(ModuleCase): @pytest.mark.slow_test def test_push(self): log_to_xfer = os.path.join(RUNTIME_VARS.TMP, uuid.uuid4().hex) - open(log_to_xfer, "w").close() # pylint: disable=resource-leakage + open( # pylint: disable=resource-leakage + log_to_xfer, "w", encoding="utf-8" + ).close() try: self.run_function("cp.push", [log_to_xfer]) tgt_cache_file = os.path.join( diff --git a/tests/integration/modules/test_ssh.py b/tests/integration/modules/test_ssh.py index 55586211622..a22551649e7 100644 --- a/tests/integration/modules/test_ssh.py +++ b/tests/integration/modules/test_ssh.py @@ -21,7 +21,7 @@ def check_status(): Check the status of Github for remote operations """ try: - return requests.get("https://github.com").status_code == 200 + return requests.get("https://github.com", timeout=60).status_code == 200 except Exception: # pylint: disable=broad-except return False diff --git a/tests/integration/netapi/rest_tornado/test_app.py b/tests/integration/netapi/rest_tornado/test_app.py index 65bb4ad6463..e8a8656106a 100644 --- a/tests/integration/netapi/rest_tornado/test_app.py +++ b/tests/integration/netapi/rest_tornado/test_app.py @@ -67,7 +67,7 @@ class SaltnadoIntegrationTestsBase( def setUp(self): super().setUp() self.patched_environ = patched_environ(ASYNC_TEST_TIMEOUT="30") - self.patched_environ.__enter__() + self.patched_environ.__enter__() # pylint: disable=unnecessary-dunder-call self.addCleanup(self.patched_environ.__exit__) def tearDown(self): diff --git a/tests/minionswarm.py b/tests/minionswarm.py index cb3cb0aa38d..d34a5ea2e61 100644 --- a/tests/minionswarm.py +++ b/tests/minionswarm.py @@ -7,7 +7,7 @@ on a single system to test scale capabilities # pylint: disable=resource-leakage import hashlib -import optparse +import optparse # pylint: disable=deprecated-module import os import random import shutil diff --git a/tests/modparser.py b/tests/modparser.py index 978b3ad7836..f0de1011437 100644 --- a/tests/modparser.py +++ b/tests/modparser.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python2 - +#!/usr/bin/env python +import argparse import modulefinder import os import pprint @@ -9,13 +9,6 @@ import sys import salt.utils.json import salt.utils.yaml -try: - import argparse # pylint: disable=minimum-python-version - - HAS_ARGPARSE = True -except ImportError: - HAS_ARGPARSE = False - def parse(): """ @@ -46,7 +39,7 @@ def mod_data(opts, full): try: finder.load_file(full) except ImportError as exc: - print("ImportError - {} (Reason: {})".format(full, exc), file=sys.stderr) + print(f"ImportError - {full} (Reason: {exc})", file=sys.stderr) return ret for name, mod in finder.modules.items(): basemod = name.split(".")[0] @@ -86,8 +79,6 @@ def scan(opts): if __name__ == "__main__": - if not HAS_ARGPARSE: - print("The argparse python module is required") opts = parse() try: scand = scan(opts) diff --git a/tests/pytests/functional/cache/test_etcd.py b/tests/pytests/functional/cache/test_etcd.py index 01ec44b4f4f..e69dcba8431 100644 --- a/tests/pytests/functional/cache/test_etcd.py +++ b/tests/pytests/functional/cache/test_etcd.py @@ -21,8 +21,8 @@ pytestmark = [ scope="module", params=(EtcdVersion.v2, EtcdVersion.v3_v2_mode), ids=etcd_version_ids, -) # pylint: disable=function-redefined -def etcd_version(request): +) +def etcd_version(request): # pylint: disable=function-redefined # The only parameter is True because the salt cache does not use # salt/utils/etcd_util.py and if coded for etcd v2 if request.param and not HAS_ETCD_V2: diff --git a/tests/pytests/functional/modules/test_data.py b/tests/pytests/functional/modules/test_data.py index 87f31c230ee..96520cbacbd 100644 --- a/tests/pytests/functional/modules/test_data.py +++ b/tests/pytests/functional/modules/test_data.py @@ -139,9 +139,9 @@ def test_has_key(data_module): ret = data_module.update("foo", "bar") assert ret - ret = data_module.has_key("foo") # pylint: disable=.has_key-is-deprecated-use-in + ret = data_module.has_key("foo") assert ret - ret = data_module.has_key("bar") # pylint: disable=.has_key-is-deprecated-use-in + ret = data_module.has_key("bar") assert not ret diff --git a/tests/pytests/functional/modules/test_system.py b/tests/pytests/functional/modules/test_system.py index 2dabaaebfad..92fb1363864 100644 --- a/tests/pytests/functional/modules/test_system.py +++ b/tests/pytests/functional/modules/test_system.py @@ -128,8 +128,8 @@ def _test_hwclock_sync(system, hwclock_has_compare): raise CompareTimeout for _ in range(2): + orig_handler = signal.signal(signal.SIGALRM, _alrm_handler) try: - orig_handler = signal.signal(signal.SIGALRM, _alrm_handler) signal.alarm(3) rpipeFd, wpipeFd = os.pipe() log.debug("Comparing hwclock to sys clock") diff --git a/tests/pytests/functional/states/file/test_append.py b/tests/pytests/functional/states/file/test_append.py index 874d5d20714..fabb33d305c 100644 --- a/tests/pytests/functional/states/file/test_append.py +++ b/tests/pytests/functional/states/file/test_append.py @@ -145,13 +145,13 @@ def test_file_append_check_cmd(modules, state_tree, tmp_path): Test that check_cmd works for file.append and those states do not run. """ - sls_contents = f""" -append_in_file: - file.append: - - name: /tmp/test - - text: "appended text" - - check_cmd: - - "djasjahj" + sls_contents = """ + append_in_file: + file.append: + - name: /tmp/test + - text: "appended text" + - check_cmd: + - "djasjahj" """ with pytest.helpers.temp_file( "file-append-check-cmd.sls", sls_contents, state_tree diff --git a/tests/pytests/functional/states/file/test_replace.py b/tests/pytests/functional/states/file/test_replace.py index 22dab816804..473ea0cef54 100644 --- a/tests/pytests/functional/states/file/test_replace.py +++ b/tests/pytests/functional/states/file/test_replace.py @@ -378,20 +378,20 @@ def test_file_replace_prerequired_issues_55775(modules, state_tree, tmp_path): assert managed_file.exists() -def test_file_replace_check_cmd(modules, state_tree, tmp_path): +def test_file_replace_check_cmd(modules, state_tree): """ Test that check_cmd works for file.replace and those states do not run. """ - sls_contents = f""" -replace_in_file: - file.replace: - - name: /tmp/test - - pattern: hi - - repl: "replacement text" - - append_if_not_found: True - - check_cmd: - - "djasjahj" + sls_contents = """ + replace_in_file: + file.replace: + - name: /tmp/test + - pattern: hi + - repl: "replacement text" + - append_if_not_found: True + - check_cmd: + - "djasjahj" """ with pytest.helpers.temp_file( "file-replace-check-cmd.sls", sls_contents, state_tree diff --git a/tests/pytests/functional/states/pkgrepo/test_debian.py b/tests/pytests/functional/states/pkgrepo/test_debian.py index 5452ecac1c4..822b4773f5e 100644 --- a/tests/pytests/functional/states/pkgrepo/test_debian.py +++ b/tests/pytests/functional/states/pkgrepo/test_debian.py @@ -614,7 +614,7 @@ def test_repo_absent_existing_repo_trailing_slash_uri( with subtests.test("Remove repo with trailing slash in URI"): # Write contents to file with trailing slash in URI - repo_file.write_text(f"{repo_content}\n") + repo_file.write_text(f"{repo_content}\n", encoding="utf-8") # Perform and validate removal ret = pkgrepo.absent(name=repo_content) assert ret.result @@ -630,7 +630,7 @@ def test_repo_absent_existing_repo_trailing_slash_uri( # Create a repo file that matches the URI but contains no architecture. # This should not be identified as a match for repo_content, and thus # the result of a state should be a no-op. - repo_file.write_text(f"deb {repo_uri} stable main\n") + repo_file.write_text(f"deb {repo_uri} stable main\n", encoding="utf-8") # Since this was a no-op, the state should have succeeded, made no # changes, and left the repo file in place. ret = pkgrepo.absent(name=repo_content) diff --git a/tests/pytests/functional/states/test_docker_container.py b/tests/pytests/functional/states/test_docker_container.py index 2267399891e..1e8c1567217 100644 --- a/tests/pytests/functional/states/test_docker_container.py +++ b/tests/pytests/functional/states/test_docker_container.py @@ -55,7 +55,7 @@ class Network: return ipaddress.ip_network(self.subnet) @_rand_indexes.default - def __rand_indexes(self): + def __rand_indexes(self): # pylint: disable=unused-private-member return random.sample( range(2, self.net.num_addresses - 1), self.net.num_addresses - 3 ) @@ -70,12 +70,14 @@ class Network: @staticmethod def arg_map(arg_name): - return { - "ipv4_address": "IPv4Address", - "ipv6_address": "IPv6Address", - "links": "Links", - "aliases": "Aliases", - }[arg_name] + if arg_name == "ipv4_address": + return "IPv4Address" + if arg_name == "ipv6_address": + return "IPv6Address" + if arg_name == "links": + return "Links" + if arg_name == "aliases": + return "Aliases" @property def compressed_subnet(self): diff --git a/tests/pytests/functional/states/test_docker_network.py b/tests/pytests/functional/states/test_docker_network.py index 16a78b13a4a..e5e9a7ec448 100644 --- a/tests/pytests/functional/states/test_docker_network.py +++ b/tests/pytests/functional/states/test_docker_network.py @@ -46,13 +46,16 @@ class Network: "Indexing not supported for networks without a custom subnet" ) - def arg_map(self, arg_name): - return { - "ipv4_address": "IPv4Address", - "ipv6_address": "IPv6Address", - "links": "Links", - "aliases": "Aliases", - }[arg_name] + @staticmethod + def arg_map(arg_name): + if arg_name == "ipv4_address": + return "IPv4Address" + if arg_name == "ipv6_address": + return "IPv6Address" + if arg_name == "links": + return "Links" + if arg_name == "aliases": + return "Aliases" @property def subnet(self): diff --git a/tests/pytests/functional/states/test_pkg.py b/tests/pytests/functional/states/test_pkg.py index 9ea9aa98aa1..a67aa8bceca 100644 --- a/tests/pytests/functional/states/test_pkg.py +++ b/tests/pytests/functional/states/test_pkg.py @@ -513,7 +513,7 @@ def test_pkg_012_installed_with_wildcard_version(PKG_TARGETS, states, modules): ) expected_comment = ( - "All specified packages are already installed and are at the " "desired version" + "All specified packages are already installed and are at the desired version" ) assert ret.result is True assert ret.raw[next(iter(ret.raw))]["comment"] == expected_comment diff --git a/tests/pytests/functional/states/test_ssh_auth.py b/tests/pytests/functional/states/test_ssh_auth.py index 7ed7c7047fe..fea9a29df6c 100644 --- a/tests/pytests/functional/states/test_ssh_auth.py +++ b/tests/pytests/functional/states/test_ssh_auth.py @@ -45,7 +45,7 @@ def test_ssh_auth_config(tmp_path, system_user, state_tree): ssh_auth_state.manage( name="test", user=system_user.username, - source=f"salt://authorized", + source="salt://authorized", config=str(new_auth_file), ssh_keys=[""], ) diff --git a/tests/pytests/functional/test_crypt.py b/tests/pytests/functional/test_crypt.py index 0c8e90e82d6..b0cf862d641 100644 --- a/tests/pytests/functional/test_crypt.py +++ b/tests/pytests/functional/test_crypt.py @@ -7,6 +7,7 @@ import salt.crypt @pytest.mark.windows_whitelisted def test_generated_keys(tmp_path): - priv = salt.crypt.gen_keys(tmp_path, "aaa", 2048) - assert "\r" not in pathlib.Path(priv).read_text() - assert "\r" not in pathlib.Path(priv.replace(".pem", ".pub")).read_text() + priv = pathlib.Path(salt.crypt.gen_keys(tmp_path, "aaa", 2048)) + pub = priv.with_suffix(".pub") + assert "\r" not in priv.read_text(encoding="utf-8") + assert "\r" not in pub.read_text(encoding="utf-8") diff --git a/tests/pytests/integration/_logging/test_jid_logging.py b/tests/pytests/integration/_logging/test_jid_logging.py index 016bf89e104..96ba7697053 100644 --- a/tests/pytests/integration/_logging/test_jid_logging.py +++ b/tests/pytests/integration/_logging/test_jid_logging.py @@ -12,7 +12,7 @@ def test_jid_in_logs(caplog, salt_call_cli): """ Test JID in log_format """ - jid_formatted_str = DFLT_LOG_FMT_JID.split("%")[0] + jid_formatted_str = DFLT_LOG_FMT_JID.split("%", maxsplit=1)[0] formatter = logging.Formatter(fmt="%(jid)s %(message)s") with caplog.at_level(logging.DEBUG): previous_formatter = caplog.handler.formatter diff --git a/tests/pytests/integration/cli/test_batch.py b/tests/pytests/integration/cli/test_batch.py index 70d66d99598..45c506a2bfd 100644 --- a/tests/pytests/integration/cli/test_batch.py +++ b/tests/pytests/integration/cli/test_batch.py @@ -141,7 +141,9 @@ def test_batch_state_stopping_after_error( # Executing salt with batch: 1 and with failhard. It should stop after the first error. cmd = salt_cli.run( - "state.single" "test.fail_without_changes" "name=test_me", + "state.single", + "test.fail_without_changes", + "name=test_me", "-b 1", "--out=yaml", "--failhard", diff --git a/tests/pytests/integration/cli/test_salt.py b/tests/pytests/integration/cli/test_salt.py index 7f026845843..30752102025 100644 --- a/tests/pytests/integration/cli/test_salt.py +++ b/tests/pytests/integration/cli/test_salt.py @@ -254,7 +254,7 @@ def test_minion_65400(salt_cli, salt_minion, salt_minion_2, salt_master): Ensure correct exit status when salt CLI starts correctly. """ - state = f""" + state = """ custom_test_state: test.configurable_test_state: - name: example diff --git a/tests/pytests/integration/cli/test_syndic_eauth.py b/tests/pytests/integration/cli/test_syndic_eauth.py index a37127c3949..e1d159cdf91 100644 --- a/tests/pytests/integration/cli/test_syndic_eauth.py +++ b/tests/pytests/integration/cli/test_syndic_eauth.py @@ -523,7 +523,7 @@ def all_the_docker( except docker.errors.APIError as exc: # if the container isn't running, there's not thing we can do # at this point. - log.info(f"Docker failed removing /etc/salt: %s", exc) + log.info("Docker failed removing /etc/salt: %s", exc) @pytest.fixture( diff --git a/tests/pytests/integration/modules/state/test_state_test.py b/tests/pytests/integration/modules/state/test_state_test.py index 40049e9a6b6..9dbcadd04e6 100644 --- a/tests/pytests/integration/modules/state/test_state_test.py +++ b/tests/pytests/integration/modules/state/test_state_test.py @@ -136,7 +136,7 @@ def test_state_sls_id_test_state_test_post_run(salt_call_cli, testfile_path): true post the state already being run previously """ source = pathlib.Path(RUNTIME_VARS.BASE_FILES, "testfile") - testfile_path.write_text(source.read_text()) + testfile_path.write_text(source.read_text(encoding="utf-8"), encoding="utf-8") testfile_path.chmod(0o644) ret = salt_call_cli.run("state.sls", "sls-id-test") assert ret.returncode == 0 diff --git a/tests/pytests/integration/sdb/test_etcd_db.py b/tests/pytests/integration/sdb/test_etcd_db.py index d981b222da7..3085dafb8ce 100644 --- a/tests/pytests/integration/sdb/test_etcd_db.py +++ b/tests/pytests/integration/sdb/test_etcd_db.py @@ -28,8 +28,8 @@ def etcd_static_port(sdb_etcd_port): # pylint: disable=function-redefined scope="module", params=(EtcdVersion.v2, EtcdVersion.v3_v2_mode), ids=etcd_version_ids, -) # pylint: disable=function-redefined -def etcd_version(request): +) +def etcd_version(request): # pylint: disable=function-redefined # The only parameter is True because the salt integration # configuration for the salt-master and salt-minion defaults # to v2. diff --git a/tests/pytests/integration/ssh/test_pre_flight.py b/tests/pytests/integration/ssh/test_pre_flight.py index c2fc14094e8..7dc56f37535 100644 --- a/tests/pytests/integration/ssh/test_pre_flight.py +++ b/tests/pytests/integration/ssh/test_pre_flight.py @@ -207,7 +207,7 @@ def test_ssh_pre_flight_script(salt_ssh_cli, caplog, _create_roster, tmp_path, a try: script = pathlib.Path.home() / "hacked" tmp_preflight = pathlib.Path("/tmp", "ssh_pre_flight.sh") - tmp_preflight.write_text(f"touch {script}") + tmp_preflight.write_text(f"touch {script}", encoding="utf-8") os.chown(tmp_preflight, account.info.uid, account.info.gid) ret = salt_ssh_cli.run("test.ping") assert not script.is_file() @@ -239,7 +239,7 @@ def test_ssh_pre_flight_perms(salt_ssh_cli, caplog, _create_roster, account): try: script = pathlib.Path("/tmp", "itworked") preflight = pathlib.Path("/ssh_pre_flight.sh") - preflight.write_text(f"touch {str(script)}") + preflight.write_text(f"touch {str(script)}", encoding="utf-8") tmp_preflight = pathlib.Path("/tmp", preflight.name) _custom_roster(salt_ssh_cli.roster_file, {"ssh_pre_flight": str(preflight)}) @@ -255,7 +255,8 @@ def test_ssh_pre_flight_perms(salt_ssh_cli, caplog, _create_roster, account): fi x=$(( $x + 1 )) done - """ + """, + encoding="utf-8", ) run_script.chmod(0o0777) # pylint: disable=W1509 diff --git a/tests/pytests/pkg/download/test_pkg_download.py b/tests/pytests/pkg/download/test_pkg_download.py index a71d4b038e9..57b1e4c834e 100644 --- a/tests/pytests/pkg/download/test_pkg_download.py +++ b/tests/pytests/pkg/download/test_pkg_download.py @@ -7,7 +7,7 @@ import os import pathlib import shutil -import packaging +import packaging.version import pytest from pytestskipmarkers.utils import platform @@ -97,7 +97,7 @@ def get_salt_release(): salt_release = "3006.0rc2" if pkg_test_type == "download-pkgs": if packaging.version.parse(salt_release) < packaging.version.parse("3006.0rc1"): - log.warning(f"The salt release being tested, {salt_release!r} looks off.") + log.warning("The salt release being tested, %r looks off.", salt_release) return salt_release @@ -109,7 +109,9 @@ def get_repo_subpath_params(): latest_release = packaging.version.parse(latest_env_var) if current_release >= latest_release: log.debug( - f"Running the tests for the latest release since {str(current_release)} >= {str(latest_release)}" + "Running the tests for the latest release since %s >= %s", + current_release, + latest_release, ) params.append("latest") return params diff --git a/tests/pytests/pkg/integration/test_pip_upgrade.py b/tests/pytests/pkg/integration/test_pip_upgrade.py index 19ed1d6d336..cabc74cefef 100644 --- a/tests/pytests/pkg/integration/test_pip_upgrade.py +++ b/tests/pytests/pkg/integration/test_pip_upgrade.py @@ -49,7 +49,7 @@ def test_pip_install(install_salt, salt_call_cli): pytest.fail(f"Failed to find {dep} in the versions report output") if dep_version == installed_version: - log.warning(f"The {dep} dependency is already latest") + log.warning("The %s dependency is already latest", dep) else: found_new = True break @@ -88,7 +88,7 @@ def test_pip_install(install_salt, salt_call_cli): else: pytest.fail(f"Failed to find {dep} in the versions report output") finally: - log.info(f"Uninstalling {dep_version}") + log.info("Uninstalling %s", dep_version) assert salt_call_cli.run( "--local", "pip.uninstall", f"{dep}=={dep_version}" ) diff --git a/tests/pytests/pkg/integration/test_salt_user.py b/tests/pytests/pkg/integration/test_salt_user.py index 4538ce79adb..a7516e2b4d8 100644 --- a/tests/pytests/pkg/integration/test_salt_user.py +++ b/tests/pytests/pkg/integration/test_salt_user.py @@ -296,7 +296,7 @@ def test_paths_log_rotation( for _path in log_files_list: log_path = pathlib.Path(_path) assert log_path.exists() - with log_path.open("a") as f: + with log_path.open("a", encoding="utf-8") as f: f.write("This is a log rotation test\n") # force log rotation diff --git a/tests/pytests/scenarios/blackout/conftest.py b/tests/pytests/scenarios/blackout/conftest.py index 09cee10db66..1cef38bcc84 100644 --- a/tests/pytests/scenarios/blackout/conftest.py +++ b/tests/pytests/scenarios/blackout/conftest.py @@ -46,7 +46,7 @@ class BlackoutPillar: self.minion_1_pillar.write_text(pillar_contents) self.refresh_pillar(exiting_blackout=False) self.in_blackout = True - return self.__enter__() + return self.__enter__() # pylint: disable=unnecessary-dunder-call def exit_blackout(self): if self.in_blackout: diff --git a/tests/pytests/unit/beacons/test_salt_monitor.py b/tests/pytests/unit/beacons/test_salt_monitor.py index 1edf8be539d..e718c780e50 100644 --- a/tests/pytests/unit/beacons/test_salt_monitor.py +++ b/tests/pytests/unit/beacons/test_salt_monitor.py @@ -1,5 +1,3 @@ -# pylint: disable=E8231 -# Salt libs import pytest import salt.beacons.salt_monitor as salt_monitor diff --git a/tests/pytests/unit/cli/test_daemons.py b/tests/pytests/unit/cli/test_daemons.py index 6f339b61234..5d68c56c77b 100644 --- a/tests/pytests/unit/cli/test_daemons.py +++ b/tests/pytests/unit/cli/test_daemons.py @@ -61,9 +61,7 @@ class LoggerMock: :return: """ for data in self.messages: - log_str = ( - data["message"] % data["args"] - ) # pylint: disable=incompatible-py3-code + log_str = data["message"] % data["args"] if (data["type"] == log_type or not log_type) and log_str.find(msg) > -1: return True diff --git a/tests/pytests/unit/client/ssh/test_ssh.py b/tests/pytests/unit/client/ssh/test_ssh.py index e3baf3f5d35..7582cbbee0d 100644 --- a/tests/pytests/unit/client/ssh/test_ssh.py +++ b/tests/pytests/unit/client/ssh/test_ssh.py @@ -229,7 +229,7 @@ def test_update_targets_ip_address(opts): assert opts["tgt"] == user + host client._update_targets() assert opts["tgt"] == host - assert client.targets[host]["user"] == user.split("@")[0] + assert client.targets[host]["user"] == user.split("@", maxsplit=1)[0] def test_update_targets_dns(opts): @@ -245,7 +245,7 @@ def test_update_targets_dns(opts): assert opts["tgt"] == user + host client._update_targets() assert opts["tgt"] == host - assert client.targets[host]["user"] == user.split("@")[0] + assert client.targets[host]["user"] == user.split("@", maxsplit=1)[0] def test_update_targets_no_user(opts): @@ -282,7 +282,7 @@ def test_update_expand_target_dns(opts, roster): client._expand_target() client._update_targets() assert opts["tgt"] == host - assert client.targets[host]["user"] == user.split("@")[0] + assert client.targets[host]["user"] == user.split("@", maxsplit=1)[0] def test_parse_tgt(opts): @@ -298,7 +298,7 @@ def test_parse_tgt(opts): assert not opts.get("ssh_cli_tgt") client = ssh.SSH(opts) assert client.parse_tgt["hostname"] == host - assert client.parse_tgt["user"] == user.split("@")[0] + assert client.parse_tgt["user"] == user.split("@", maxsplit=1)[0] assert opts.get("ssh_cli_tgt") == user + host diff --git a/tests/pytests/unit/cloud/clouds/test_proxmox.py b/tests/pytests/unit/cloud/clouds/test_proxmox.py index 1d1823a8035..405db87caec 100644 --- a/tests/pytests/unit/cloud/clouds/test_proxmox.py +++ b/tests/pytests/unit/cloud/clouds/test_proxmox.py @@ -384,6 +384,7 @@ def test__authenticate_with_custom_port(): "https://proxmox.connection.url:9999/api2/json/access/ticket", verify=True, data={"username": ("fakeuser",), "password": "secretpassword"}, + timeout=120, ) diff --git a/tests/pytests/unit/daemons/masterapi/test_remote_funcs.py b/tests/pytests/unit/daemons/masterapi/test_remote_funcs.py index 8151dcaf006..99821a8f54a 100644 --- a/tests/pytests/unit/daemons/masterapi/test_remote_funcs.py +++ b/tests/pytests/unit/daemons/masterapi/test_remote_funcs.py @@ -42,7 +42,7 @@ def test_mine_get(funcs, tgt_type_key="tgt_type"): funcs.cache.store("minions/webserver", "mine", dict(ip_addr="2001:db8::1:3")) with patch( "salt.utils.minions.CkMinions._check_compound_minions", - MagicMock(return_value=(dict(minions=["webserver"], missing=[]))), + MagicMock(return_value=dict(minions=["webserver"], missing=[])), ): ret = funcs._mine_get( { @@ -81,7 +81,7 @@ def test_mine_get_dict_str(funcs, tgt_type_key="tgt_type"): ) with patch( "salt.utils.minions.CkMinions._check_compound_minions", - MagicMock(return_value=(dict(minions=["webserver"], missing=[]))), + MagicMock(return_value=dict(minions=["webserver"], missing=[])), ): ret = funcs._mine_get( { @@ -114,7 +114,7 @@ def test_mine_get_dict_list(funcs, tgt_type_key="tgt_type"): ) with patch( "salt.utils.minions.CkMinions._check_compound_minions", - MagicMock(return_value=(dict(minions=["webserver"], missing=[]))), + MagicMock(return_value=dict(minions=["webserver"], missing=[])), ): ret = funcs._mine_get( { diff --git a/tests/pytests/unit/fileserver/test_roots.py b/tests/pytests/unit/fileserver/test_roots.py index c1660280bc5..c6a58136a3c 100644 --- a/tests/pytests/unit/fileserver/test_roots.py +++ b/tests/pytests/unit/fileserver/test_roots.py @@ -290,7 +290,7 @@ def test_find_file_not_in_root(tmp_state_tree): """ badfile = pathlib.Path(tmp_state_tree).parent / "bar" badfile.write_text("Bad file") - badpath = f"../bar" + badpath = "../bar" ret = roots.find_file(badpath) assert ret == {"path": "", "rel": ""} badpath = f"{tmp_state_tree / '..' / 'bar'}" @@ -304,7 +304,7 @@ def test_serve_file_not_in_root(tmp_state_tree): """ badfile = pathlib.Path(tmp_state_tree).parent / "bar" badfile.write_text("Bad file") - badpath = f"../bar" + badpath = "../bar" load = {"path": "salt://|..\\bar", "saltenv": "base", "loc": 0} fnd = { "path": f"{tmp_state_tree / '..' / 'bar'}", diff --git a/tests/pytests/unit/modules/dockermod/test_module.py b/tests/pytests/unit/modules/dockermod/test_module.py index abfd101540d..4c820bd9190 100644 --- a/tests/pytests/unit/modules/dockermod/test_module.py +++ b/tests/pytests/unit/modules/dockermod/test_module.py @@ -307,10 +307,10 @@ def test_check_mine_cache_is_refreshed_on_container_change_event(command_name, a try: mine_send.assert_called_with("docker.ps", verbose=True, all=True, host=True) except AssertionError as exc: - raise Exception( + raise AssertionError( "command '{}' did not call docker.ps with expected " "arguments: {}".format(command_name, exc) - ) + ) from exc def test_update_mine(): @@ -319,24 +319,14 @@ def test_update_mine(): """ def config_get_disabled(val, default): - return { - "base_url": docker_mod.NOTSET, - "version": docker_mod.NOTSET, - "docker.url": docker_mod.NOTSET, - "docker.version": docker_mod.NOTSET, - "docker.machine": docker_mod.NOTSET, - "docker.update_mine": False, - }[val] + if val == "docker.update_mine": + return False + return docker_mod.NOTSET def config_get_enabled(val, default): - return { - "base_url": docker_mod.NOTSET, - "version": docker_mod.NOTSET, - "docker.url": docker_mod.NOTSET, - "docker.version": docker_mod.NOTSET, - "docker.machine": docker_mod.NOTSET, - "docker.update_mine": True, - }[val] + if val == "docker.update_mine": + return True + return docker_mod.NOTSET mine_mock = Mock() dunder_salt = { @@ -937,19 +927,19 @@ def test_compare_container_image_id_resolution(): """ def _inspect_container_effect(id_): - return { - "container1": { + if id_ == "container1": + return { "Config": {"Image": "realimage:latest"}, "HostConfig": {}, - }, - "container2": {"Config": {"Image": "image_id"}, "HostConfig": {}}, - }[id_] + } + if id_ == "container2": + return {"Config": {"Image": "image_id"}, "HostConfig": {}} def _inspect_image_effect(id_): - return { - "realimage:latest": {"Id": "image_id"}, - "image_id": {"Id": "image_id"}, - }[id_] + if id_ == "realimage:latest": + return {"Id": "image_id"} + if id_ == "image_id": + return {"Id": "image_id"} inspect_container_mock = MagicMock(side_effect=_inspect_container_effect) inspect_image_mock = MagicMock(side_effect=_inspect_image_effect) @@ -967,8 +957,8 @@ def test_compare_container_ulimits_order(): """ def _inspect_container_effect(id_): - return { - "container1": { + if id_ == "container1": + return { "Config": {}, "HostConfig": { "Ulimits": [ @@ -976,8 +966,9 @@ def test_compare_container_ulimits_order(): {"Hard": 65536, "Soft": 65536, "Name": "nofile"}, ] }, - }, - "container2": { + } + if id_ == "container2": + return { "Config": {}, "HostConfig": { "Ulimits": [ @@ -985,8 +976,7 @@ def test_compare_container_ulimits_order(): {"Hard": -1, "Soft": -1, "Name": "core"}, ] }, - }, - }[id_] + } inspect_container_mock = MagicMock(side_effect=_inspect_container_effect) @@ -1004,16 +994,16 @@ def test_compare_container_env_order(): """ def _inspect_container_effect(id_): - return { - "container1": { + if id_ == "container1": + return { "Config": {}, "HostConfig": {"Env": ["FOO=bar", "HELLO=world"]}, - }, - "container2": { + } + if id_ == "container2": + return { "Config": {}, "HostConfig": {"Env": ["HELLO=world", "FOO=bar"]}, - }, - }[id_] + } inspect_container_mock = MagicMock(side_effect=_inspect_container_effect) diff --git a/tests/pytests/unit/modules/file/test_file_line.py b/tests/pytests/unit/modules/file/test_file_line.py index 80030e1417d..5c2e444617e 100644 --- a/tests/pytests/unit/modules/file/test_file_line.py +++ b/tests/pytests/unit/modules/file/test_file_line.py @@ -1633,7 +1633,7 @@ def test_line_insert_ensure_beforeafter_twolines_exists(tempfile_name): ) # pylint: enable=W1401 after, before = ( - file_content.split(os.linesep)[0], + file_content.split(os.linesep, maxsplit=1)[0], file_content.split(os.linesep)[2], ) diff --git a/tests/pytests/unit/modules/file/test_file_lsattr.py b/tests/pytests/unit/modules/file/test_file_lsattr.py index 232f2a22d4b..5e211b06428 100644 --- a/tests/pytests/unit/modules/file/test_file_lsattr.py +++ b/tests/pytests/unit/modules/file/test_file_lsattr.py @@ -79,9 +79,7 @@ def test_if_chattr_version_is_less_than_required_flags_should_ignore_extended(): ) with patch_has_ext, patch_run: actual = set(filemod.lsattr(fname)[fname]) - msg = "Actual: {!r} Expected: {!r}".format( - actual, expected - ) # pylint: disable=E1322 + msg = f"Actual: {actual!r} Expected: {expected!r}" assert actual == expected, msg @@ -107,9 +105,7 @@ def test_if_chattr_version_is_high_enough_then_extended_flags_should_be_returned ) with patch_has_ext, patch_run: actual = set(filemod.lsattr(fname)[fname]) - msg = "Actual: {!r} Expected: {!r}".format( - actual, expected - ) # pylint: disable=E1322 + msg = f"Actual: {actual!r} Expected: {expected!r}" assert actual == expected, msg @@ -135,7 +131,5 @@ def test_if_supports_extended_but_there_are_no_flags_then_none_should_be_returne ) with patch_has_ext, patch_run: actual = set(filemod.lsattr(fname)[fname]) - msg = "Actual: {!r} Expected: {!r}".format( - actual, expected - ) # pylint: disable=E1322 + msg = f"Actual: {actual!r} Expected: {expected!r}" assert actual == expected, msg diff --git a/tests/pytests/unit/modules/file/test_file_module.py b/tests/pytests/unit/modules/file/test_file_module.py index 34fe4fa210d..ea6acc79fdc 100644 --- a/tests/pytests/unit/modules/file/test_file_module.py +++ b/tests/pytests/unit/modules/file/test_file_module.py @@ -506,12 +506,14 @@ def test_get_diff(): mockself.path = path def readlines(mockself): # pylint: disable=unused-argument - return { - "text1": text1.encode("utf8"), - "text2": text2.encode("utf8"), - "binary1": binary1, - "binary2": binary2, - }[mockself.path].splitlines(True) + if mockself.path == "text1": + return text1.encode("utf8").splitlines(True) + if mockself.path == "text2": + return text2.encode("utf8").splitlines(True) + if mockself.path == "binary1": + return binary1.splitlines(True) + if mockself.path == "binary2": + return binary2.splitlines(True) def __enter__(mockself): return mockself diff --git a/tests/pytests/unit/modules/state/test_state.py b/tests/pytests/unit/modules/state/test_state.py index 7c42646bcf7..e08b2be6ad7 100644 --- a/tests/pytests/unit/modules/state/test_state.py +++ b/tests/pytests/unit/modules/state/test_state.py @@ -759,9 +759,7 @@ def test_top(): with patch.object(os.path, "join", mock): mock = MagicMock(return_value=True) with patch.object(state, "_set_retcode", mock): - assert state.top( - "reverse_top.sls " "exclude=exclude.sls" - ) + assert state.top("reverse_top.sls exclude=exclude.sls") def test_highstate(): @@ -800,7 +798,7 @@ def test_highstate(): mock = MagicMock(return_value=True) with patch.object(salt.payload, "Serial", mock): with patch.object(os.path, "join", mock): - with patch.object(state, "_set" "_retcode", mock): + with patch.object(state, "_set_retcode", mock): assert state.highstate(arg) @@ -906,11 +904,11 @@ def test_sls(): assert state.sls(arg, None, None, True, cache=True) MockState.HighState.flag = True - assert state.sls("core,edit" ".vim dev", None, None, True) + assert state.sls("core,edit.vim dev", None, None, True) MockState.HighState.flag = False with patch.object( - state, "_filter_" "running", return_value=True + state, "_filter_running", return_value=True ), patch.object(os.path, "join", return_value=True), patch.object( os, "umask", return_value=True ), patch.object( @@ -922,7 +920,7 @@ def test_sls(): ), patch( "salt.utils.files.fopen", mock_open() ): - assert state.sls("core,edit" ".vim dev", None, None, True) + assert state.sls("core,edit.vim dev", None, None, True) def test_get_test_value(): diff --git a/tests/pytests/unit/modules/test_cp.py b/tests/pytests/unit/modules/test_cp.py index 6caa9ef5938..6700832e345 100644 --- a/tests/pytests/unit/modules/test_cp.py +++ b/tests/pytests/unit/modules/test_cp.py @@ -43,7 +43,10 @@ def test__render_filenames_render_failed(): saltenv = "base" template = "jinja" file_data = "Remember to keep your files well salted." - mock_jinja = lambda *args, **kwargs: {"result": False, "data": file_data} + + def mock_jinja(*args, **kwargs): + return {"result": False, "data": file_data} + with patch.dict(templates.TEMPLATE_REGISTRY, {"jinja": mock_jinja}): with patch("salt.utils.files.fopen", mock_open(read_data=file_data)): pytest.raises( @@ -65,7 +68,10 @@ def test__render_filenames_success(): saltenv = "base" template = "jinja" file_data = "/srv/salt/biscuits" - mock_jinja = lambda *args, **kwargs: {"result": True, "data": file_data} + + def mock_jinja(*args, **kwargs): + return {"result": True, "data": file_data} + ret = (file_data, file_data) # salt.utils.files.fopen can only be mocked once with patch.dict(templates.TEMPLATE_REGISTRY, {"jinja": mock_jinja}): with patch("salt.utils.files.fopen", mock_open(read_data=file_data)): @@ -149,7 +155,8 @@ def test_push(): assert num_opens == 1, num_opens fh_ = m_open.filehandles[filename][0] assert fh_.read.call_count == 2, fh_.read.call_count - req_channel_factory_mock().__enter__().send.assert_called_once_with( + + req_channel_factory_mock().__enter__().send.assert_called_once_with( # pylint: disable=unnecessary-dunder-call dict( loc=fh_.tell(), # pylint: disable=resource-leakage cmd="_file_recv", diff --git a/tests/pytests/unit/modules/test_devinfo.py b/tests/pytests/unit/modules/test_devinfo.py index d3895e53246..8e0db9bfdec 100644 --- a/tests/pytests/unit/modules/test_devinfo.py +++ b/tests/pytests/unit/modules/test_devinfo.py @@ -42,9 +42,17 @@ def test_devices(): "E": {"ID_BUS": "ata"}, } + def _udev_info(key): + if key == "sda": + return hd + if key == "sdb": + return usb + if key == "sr0": + return cdrom + with patch.dict( devinfo.__salt__, - {"udev.info": lambda d: {"sda": hd, "sdb": usb, "sr0": cdrom}[d]}, + {"udev.info": _udev_info}, ), patch.dict(devinfo.__grains__, {"disks": ["sda", "sdb", "sr0"]}): assert devinfo.filter_({"e.id_bus": "ata"}, {}) == ["sda", "sr0"] assert devinfo.filter_({"e.id_bus": "usb"}, {}) == ["sdb"] diff --git a/tests/pytests/unit/modules/test_glassfish.py b/tests/pytests/unit/modules/test_glassfish.py index 159d00cbb16..e6e22b3a696 100644 --- a/tests/pytests/unit/modules/test_glassfish.py +++ b/tests/pytests/unit/modules/test_glassfish.py @@ -33,6 +33,7 @@ def test__api_get(): url="http://localhost:4848/management/domain/ThePath", verify=True, auth=None, + timeout=120, ) @@ -51,6 +52,7 @@ def test__api_post(): verify=True, auth=None, data='{"1": 1}', + timeout=120, ) @@ -69,4 +71,5 @@ def test__api_delete(): verify=True, auth=None, params={1: 1}, + timeout=120, ) diff --git a/tests/pytests/unit/modules/test_gpg.py b/tests/pytests/unit/modules/test_gpg.py index 697f53c6541..67e6f2e0f84 100644 --- a/tests/pytests/unit/modules/test_gpg.py +++ b/tests/pytests/unit/modules/test_gpg.py @@ -621,7 +621,9 @@ def test_export_public_key_to_file(gpghome): keyids="xxxxxxxxxxxxxxxx", output=exported_keyfile, bare=True ) assert ret == GPG_TEST_PUB_KEY - keyfile_contents = pathlib.Path(exported_keyfile).read_text() + keyfile_contents = pathlib.Path(exported_keyfile).read_text( + encoding="utf-8" + ) assert keyfile_contents == GPG_TEST_PUB_KEY @@ -746,7 +748,9 @@ def test_export_secret_key_to_file_with_gpg_passphrase_in_pillar(gpghome): True, passphrase=GPG_TEST_KEY_PASSPHRASE, ) - keyfile_contents = pathlib.Path(exported_keyfile).read_text() + keyfile_contents = pathlib.Path(exported_keyfile).read_text( + encoding="utf-8" + ) assert keyfile_contents == GPG_TEST_PRIV_KEY diff --git a/tests/pytests/unit/modules/test_hg.py b/tests/pytests/unit/modules/test_hg.py index 314b48b2c8e..5d31217b76d 100644 --- a/tests/pytests/unit/modules/test_hg.py +++ b/tests/pytests/unit/modules/test_hg.py @@ -97,18 +97,15 @@ def test_status_multiple(): """ Test for Status to a given repository (cwd is list) """ + + def func(*args, **kwargs): + if kwargs["cwd"] == "dir 0": + return "A file 0\n" + return "M file 1" + with patch.dict( hg.__salt__, - { - "cmd.run_stdout": MagicMock( - side_effect=( - lambda *args, **kwargs: { - "dir 0": "A file 0\n", - "dir 1": "M file 1", - }[kwargs["cwd"]] - ) - ) - }, + {"cmd.run_stdout": MagicMock(side_effect=func)}, ): assert hg.status(["dir 0", "dir 1"]) == { "dir 0": {"added": ["file 0"]}, diff --git a/tests/pytests/unit/modules/test_mount.py b/tests/pytests/unit/modules/test_mount.py index 3a4e1d544e3..ea5feb8a5e0 100644 --- a/tests/pytests/unit/modules/test_mount.py +++ b/tests/pytests/unit/modules/test_mount.py @@ -416,8 +416,6 @@ def test_set_filesystems_with_data(tmp_sub_dir, config_file): Tests to verify set_filesystems reads and adjusts file /etc/filesystems correctly """ # Note AIX uses tabs in filesystems files, hence disable warings and errors for tabs and spaces - # pylint: disable=W8191 - # pylint: disable=E8101 config_filepath = str(tmp_sub_dir / "filesystems") with patch.dict(mount.__grains__, {"os": "AIX", "kernel": "AIX"}): mount.set_filesystems( diff --git a/tests/pytests/unit/modules/test_salt_version.py b/tests/pytests/unit/modules/test_salt_version.py index 4b7a7cd0731..6e3a09cbe78 100644 --- a/tests/pytests/unit/modules/test_salt_version.py +++ b/tests/pytests/unit/modules/test_salt_version.py @@ -29,8 +29,7 @@ def test_mocked_objects(): else: assert len(v) == 2 - sv = sv.__str__() - assert isinstance(sv, str) + assert isinstance(str(sv), str) with patch("salt.version.SaltStackVersion.LNAMES", {"neon": (2019, 8)}): sv = salt.version.SaltStackVersion.from_name("Neon") diff --git a/tests/pytests/unit/modules/test_solaris_shadow.py b/tests/pytests/unit/modules/test_solaris_shadow.py index 4cc99c6e983..85d7aa41fcd 100644 --- a/tests/pytests/unit/modules/test_solaris_shadow.py +++ b/tests/pytests/unit/modules/test_solaris_shadow.py @@ -29,7 +29,7 @@ skip_on_missing_pwd = pytest.mark.skipif( missing_pwd, reason="Has no pwd module for accessing /etc/password passwords" ) -# pylint: disable=singleton-comparison,comparison-to-True-should-be-if-cond-is-True-or-if-cond +# pylint: disable=singleton-comparison # TODO: A lot of the shadow functionality is common across solaris and Linux. # It would be possible to combine some of this into salt/utils -W. Werner, 2021-01-26 diff --git a/tests/pytests/unit/modules/test_win_powercfg.py b/tests/pytests/unit/modules/test_win_powercfg.py index e1cd9426a4c..ab6f0ee6258 100644 --- a/tests/pytests/unit/modules/test_win_powercfg.py +++ b/tests/pytests/unit/modules/test_win_powercfg.py @@ -168,7 +168,7 @@ def test_get_disk_timeout(query_output): calls = [ call("powercfg /getactivescheme", python_shell=False), call( - "powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK" " DISKIDLE", + "powercfg /q 381b4222-f694-41f0-9685-ff5bb260df2e SUB_DISK DISKIDLE", python_shell=False, ), ] diff --git a/tests/pytests/unit/modules/test_zabbix.py b/tests/pytests/unit/modules/test_zabbix.py index 5c2f8fc7ee5..fd9fae8c1a6 100644 --- a/tests/pytests/unit/modules/test_zabbix.py +++ b/tests/pytests/unit/modules/test_zabbix.py @@ -407,7 +407,6 @@ def test_user_exists(conn_args, set_zabbix_version, query_return, mock_login): """ module_return = True - # pylint: disable=E8128 query_return( { "jsonrpc": "2.0", @@ -464,7 +463,6 @@ def test_user_get(conn_args, set_zabbix_version, query_return, mock_login): "type": "3", } ] - # pylint: disable=E8128 query_return( { "jsonrpc": "2.0", @@ -547,7 +545,6 @@ def test_user_getmedia(conn_args, set_zabbix_version, query_return, mock_login): "active": "0", } ] - # pylint: disable=E8128 query_return( { "jsonrpc": "2.0", @@ -707,7 +704,6 @@ def test_user_list(conn_args, query_return, mock_login): "type": "1", }, ] - # pylint: disable=E8128 query_return( { "jsonrpc": "2.0", @@ -924,7 +920,6 @@ def test_usergroup_list(conn_args, query_return, mock_login): "users_status": "0", }, ] - # pylint: disable=E8128 query_return( { "jsonrpc": "2.0", diff --git a/tests/pytests/unit/modules/virt/conftest.py b/tests/pytests/unit/modules/virt/conftest.py index 03225530056..fb0d8746c57 100644 --- a/tests/pytests/unit/modules/virt/conftest.py +++ b/tests/pytests/unit/modules/virt/conftest.py @@ -39,7 +39,7 @@ class MappedResultMock(MagicMock): def __init__(self): def mapped_results(*args, **kwargs): - if args[0] not in self._instances.keys(): + if args[0] not in self._instances: raise virt.libvirt.libvirtError("Not found: {}".format(args[0])) return self._instances[args[0]] diff --git a/tests/pytests/unit/modules/win_lgpo/test_admx_policies.py b/tests/pytests/unit/modules/win_lgpo/test_admx_policies.py index f808dbf4467..56eecd4bbc2 100644 --- a/tests/pytests/unit/modules/win_lgpo/test_admx_policies.py +++ b/tests/pytests/unit/modules/win_lgpo/test_admx_policies.py @@ -83,7 +83,7 @@ def lgpo_bin(): # download lgpo.zip log.debug("Downloading LGPO.exe from Microsoft") url = "https://download.microsoft.com/download/8/5/C/85C25433-A1B0-4FFA-9429-7E023E7DA8D8/LGPO.zip" - r = requests.get(url) + r = requests.get(url, timeout=60) with salt.utils.files.fopen(zip_file, "wb") as f: f.write(r.content) # extract zip diff --git a/tests/pytests/unit/pillar/test_consul_pillar.py b/tests/pytests/unit/pillar/test_consul_pillar.py index 430f7aa5e43..b37d5f7876e 100644 --- a/tests/pytests/unit/pillar/test_consul_pillar.py +++ b/tests/pytests/unit/pillar/test_consul_pillar.py @@ -54,9 +54,7 @@ def configure_loader_modules(): def test_connection(base_pillar_data): - with patch.dict( - consul_pillar.__salt__, {"grains.get": MagicMock(return_value=({}))} - ): + with patch.dict(consul_pillar.__salt__, {"grains.get": MagicMock(return_value={})}): with patch.object( consul_pillar, "consul_fetch", @@ -71,9 +69,7 @@ def test_connection(base_pillar_data): def test_pillar_data(base_pillar_data): - with patch.dict( - consul_pillar.__salt__, {"grains.get": MagicMock(return_value=({}))} - ): + with patch.dict(consul_pillar.__salt__, {"grains.get": MagicMock(return_value={})}): with patch.object( consul_pillar, "consul_fetch", @@ -90,9 +86,7 @@ def test_pillar_data(base_pillar_data): def test_blank_root(base_pillar_data): - with patch.dict( - consul_pillar.__salt__, {"grains.get": MagicMock(return_value=({}))} - ): + with patch.dict(consul_pillar.__salt__, {"grains.get": MagicMock(return_value={})}): with patch.object( consul_pillar, "consul_fetch", @@ -104,9 +98,7 @@ def test_blank_root(base_pillar_data): def test_pillar_nest(base_pillar_data): - with patch.dict( - consul_pillar.__salt__, {"grains.get": MagicMock(return_value=({}))} - ): + with patch.dict(consul_pillar.__salt__, {"grains.get": MagicMock(return_value={})}): with patch.object( consul_pillar, "consul_fetch", @@ -122,9 +114,7 @@ def test_pillar_nest(base_pillar_data): def test_value_parsing(base_pillar_data): - with patch.dict( - consul_pillar.__salt__, {"grains.get": MagicMock(return_value=({}))} - ): + with patch.dict(consul_pillar.__salt__, {"grains.get": MagicMock(return_value={})}): with patch.object( consul_pillar, "consul_fetch", @@ -137,9 +127,7 @@ def test_value_parsing(base_pillar_data): def test_non_expansion(base_pillar_data): - with patch.dict( - consul_pillar.__salt__, {"grains.get": MagicMock(return_value=({}))} - ): + with patch.dict(consul_pillar.__salt__, {"grains.get": MagicMock(return_value={})}): with patch.object( consul_pillar, "consul_fetch", diff --git a/tests/pytests/unit/proxy/test_napalm.py b/tests/pytests/unit/proxy/test_napalm.py index f93279af900..2a537b8d61e 100644 --- a/tests/pytests/unit/proxy/test_napalm.py +++ b/tests/pytests/unit/proxy/test_napalm.py @@ -276,7 +276,7 @@ def test_grains_refresh(test_opts): def test_fns(): ret = napalm_proxy.fns() - assert "details" in ret.keys() + assert "details" in ret def test_shutdown(test_opts): diff --git a/tests/pytests/unit/runners/test_asam.py b/tests/pytests/unit/runners/test_asam.py index 285138781b7..2f2f7d7e786 100644 --- a/tests/pytests/unit/runners/test_asam.py +++ b/tests/pytests/unit/runners/test_asam.py @@ -44,6 +44,7 @@ def test_add_platform(): auth=("TheUsername", "ThePassword"), data={"manual": "false"}, verify=True, + timeout=120, ) @@ -69,6 +70,7 @@ def test_remove_platform(): "Submit": "Yes", }, verify=True, + timeout=120, ) @@ -88,6 +90,7 @@ def test_list_platforms(): auth=("TheUsername", "ThePassword"), data={"manual": "false"}, verify=True, + timeout=120, ) @@ -107,4 +110,5 @@ def test_list_platform_sets(): auth=("TheUsername", "ThePassword"), data={"manual": "false"}, verify=True, + timeout=120, ) diff --git a/tests/pytests/unit/runners/vault/test_app_role_auth.py b/tests/pytests/unit/runners/vault/test_app_role_auth.py index 241da179a37..14d5dc77ef7 100644 --- a/tests/pytests/unit/runners/vault/test_app_role_auth.py +++ b/tests/pytests/unit/runners/vault/test_app_role_auth.py @@ -73,7 +73,14 @@ def test_generate_token(): headers=ANY, json=ANY, verify=ANY, + timeout=120, + ), + call( + "http://fake_url", + headers=ANY, + json=ANY, + verify=ANY, + timeout=120, ), - call("http://fake_url", headers=ANY, json=ANY, verify=ANY), ] mock.assert_has_calls(calls) diff --git a/tests/pytests/unit/runners/vault/test_token_auth.py b/tests/pytests/unit/runners/vault/test_token_auth.py index 60307dc0955..fcd0ef8058b 100644 --- a/tests/pytests/unit/runners/vault/test_token_auth.py +++ b/tests/pytests/unit/runners/vault/test_token_auth.py @@ -68,7 +68,9 @@ def test_generate_token(): assert "error" not in result assert "token" in result assert result["token"] == "test" - mock.assert_called_with("http://fake_url", headers=ANY, json=ANY, verify=ANY) + mock.assert_called_with( + "http://fake_url", headers=ANY, json=ANY, verify=ANY, timeout=120 + ) # Test uses num_uses = 6 @@ -85,7 +87,11 @@ def test_generate_token(): }, } mock.assert_called_with( - "http://fake_url", headers=ANY, json=json_request, verify=ANY + "http://fake_url", + headers=ANY, + json=json_request, + verify=ANY, + timeout=120, ) # Test ttl @@ -103,7 +109,7 @@ def test_generate_token(): }, } mock.assert_called_with( - "http://fake_url", headers=ANY, json=json_request, verify=ANY + "http://fake_url", headers=ANY, json=json_request, verify=ANY, timeout=120 ) mock = _mock_json_response({}, status_code=403, reason="no reason") @@ -152,4 +158,5 @@ def test_generate_token_with_namespace(): }, json=ANY, verify=ANY, + timeout=120, ) diff --git a/tests/pytests/unit/serializers/test_serializers.py b/tests/pytests/unit/serializers/test_serializers.py index 0f3125c89e3..2d46f320b82 100644 --- a/tests/pytests/unit/serializers/test_serializers.py +++ b/tests/pytests/unit/serializers/test_serializers.py @@ -284,12 +284,12 @@ def test_sls_repr(): sls_obj = convert(OrderedDict([("foo", "bar"), ("baz", "qux")])) # ensure that repr and str are yaml friendly - assert sls_obj.__str__() == "{foo: bar, baz: qux}" - assert sls_obj.__repr__() == "{foo: bar, baz: qux}" + assert str(sls_obj) == "{foo: bar, baz: qux}" + assert repr(sls_obj) == "{foo: bar, baz: qux}" # ensure that repr and str are already quoted - assert sls_obj["foo"].__str__() == '"bar"' - assert sls_obj["foo"].__repr__() == '"bar"' + assert str(sls_obj["foo"]) == '"bar"' + assert repr(sls_obj["foo"]) == '"bar"' @pytest.mark.skipif(yamlex.available is False, reason=SKIP_MESSAGE.format("sls")) diff --git a/tests/pytests/unit/state/test_state_compiler.py b/tests/pytests/unit/state/test_state_compiler.py index db91a0109d7..4bf8f4f751a 100644 --- a/tests/pytests/unit/state/test_state_compiler.py +++ b/tests/pytests/unit/state/test_state_compiler.py @@ -11,7 +11,6 @@ import salt.state import salt.utils.files import salt.utils.platform from salt.exceptions import CommandExecutionError -from salt.utils.odict import OrderedDict from tests.support.mock import MagicMock, patch log = logging.getLogger(__name__) @@ -56,21 +55,21 @@ def test_render_error_on_invalid_requisite(minion_opts): """ with patch("salt.state.State._gather_pillar"): high_data = { - "git": OrderedDict( + "git": salt.state.HashableOrderedDict( [ ( "pkg", [ - OrderedDict( + salt.state.HashableOrderedDict( [ ( "require", [ - OrderedDict( + salt.state.HashableOrderedDict( [ ( "file", - OrderedDict( + salt.state.HashableOrderedDict( [("test1", "test")] ), ) @@ -89,7 +88,9 @@ def test_render_error_on_invalid_requisite(minion_opts): ] ) } - minion_opts["pillar"] = {"git": OrderedDict([("test1", "test")])} + minion_opts["pillar"] = { + "git": salt.state.HashableOrderedDict([("test1", "test")]) + } state_obj = salt.state.State(minion_opts) with pytest.raises(salt.exceptions.SaltRenderError): state_obj.call_high(high_data) @@ -720,13 +721,22 @@ def test_render_requisite_require_disabled(minion_opts): """ with patch("salt.state.State._gather_pillar"): high_data = { - "step_one": OrderedDict( + "step_one": salt.state.HashableOrderedDict( [ ( "test", [ - OrderedDict( - [("require", [OrderedDict([("test", "step_two")])])] + salt.state.HashableOrderedDict( + [ + ( + "require", + [ + salt.state.HashableOrderedDict( + [("test", "step_two")] + ) + ], + ) + ] ), "succeed_with_changes", {"order": 10000}, @@ -764,16 +774,20 @@ def test_render_requisite_require_in_disabled(minion_opts): "__env__": "base", "__sls__": "test.disable_require_in", }, - "step_two": OrderedDict( + "step_two": salt.state.HashableOrderedDict( [ ( "test", [ - OrderedDict( + salt.state.HashableOrderedDict( [ ( "require_in", - [OrderedDict([("test", "step_one")])], + [ + salt.state.HashableOrderedDict( + [("test", "step_one")] + ) + ], ) ] ), @@ -974,7 +988,7 @@ def test_mod_aggregate(minion_opts): "__sls__": "test.62439", "__env__": "base", "__id__": "sl", - "require_in": [OrderedDict([("file", "/tmp/foo")])], + "require_in": [salt.state.HashableOrderedDict([("file", "/tmp/foo")])], "order": 10002, "aggregate": True, "fun": "installed", @@ -1000,7 +1014,7 @@ def test_mod_aggregate(minion_opts): "__env__": "base", "__id__": "figlet", "__agg__": True, - "require": [OrderedDict([("file", "/tmp/foo")])], + "require": [salt.state.HashableOrderedDict([("file", "/tmp/foo")])], "order": 10001, "aggregate": True, "fun": "installed", @@ -1011,7 +1025,7 @@ def test_mod_aggregate(minion_opts): "__sls__": "test.62439", "__env__": "base", "__id__": "sl", - "require_in": [OrderedDict([("file", "/tmp/foo")])], + "require_in": [salt.state.HashableOrderedDict([("file", "/tmp/foo")])], "order": 10002, "aggregate": True, "fun": "installed", @@ -1026,7 +1040,7 @@ def test_mod_aggregate(minion_opts): "__sls__": "test.62439", "__env__": "base", "__id__": "sl", - "require_in": [OrderedDict([("file", "/tmp/foo")])], + "require_in": [salt.state.HashableOrderedDict([("file", "/tmp/foo")])], "order": 10002, "fun": "installed", "__agg__": True, @@ -1045,7 +1059,9 @@ def test_mod_aggregate(minion_opts): assert "require_in" in low_ret # Ensure all the requires from pkg states are in low - assert low_ret["require_in"] == [OrderedDict([("file", "/tmp/foo")])] + assert low_ret["require_in"] == [ + salt.state.HashableOrderedDict([("file", "/tmp/foo")]) + ] # Ensure that the require requisite from the # figlet state doesn't find its way into this state @@ -1190,7 +1206,7 @@ def test_load_modules_list(minion_opts): "__sls__": "test", "__env__": "base", "__id__": "nginx", - "provider": [OrderedDict([("cmd", "cmdmod")])], + "provider": [salt.state.HashableOrderedDict([("cmd", "cmdmod")])], "order": 10000, "fun": "installed", } @@ -1215,7 +1231,7 @@ def test_load_modules_dict(minion_opts): "__sls__": "test", "__env__": "base", "__id__": "nginx", - "provider": OrderedDict([("cmd", "test")]), + "provider": salt.state.HashableOrderedDict([("cmd", "test")]), "order": 10000, "fun": "installed", } diff --git a/tests/pytests/unit/states/test_host.py b/tests/pytests/unit/states/test_host.py index 3a3ab022a02..92e7c5f0a67 100644 --- a/tests/pytests/unit/states/test_host.py +++ b/tests/pytests/unit/states/test_host.py @@ -259,11 +259,7 @@ def test_present(): ): ret = host.present(hostname, ip_str) assert ret["result"] is True - assert ( - ret["comment"] - == "Host {} ({}) already present".format(hostname, ip_str) - in ret["comment"] - ) + assert "Host {} ({}) already present".format(hostname, ip_str) in ret["comment"] assert ret["changes"] == {}, ret["changes"] assert add_host.mock_calls == [], add_host.mock_calls assert rm_host.mock_calls == [], rm_host.mock_calls diff --git a/tests/pytests/unit/transport/test_zeromq.py b/tests/pytests/unit/transport/test_zeromq.py index 97d65a204ad..ec93a72439e 100644 --- a/tests/pytests/unit/transport/test_zeromq.py +++ b/tests/pytests/unit/transport/test_zeromq.py @@ -616,7 +616,7 @@ def test_req_server_chan_encrypt_v2(pki_dir): if HAS_M2: aes = key.private_decrypt(ret["key"], RSA.pkcs1_oaep_padding) else: - cipher = PKCS1_OAEP.new(key) + cipher = PKCS1_OAEP.new(key) # pylint: disable=used-before-assignment aes = cipher.decrypt(ret["key"]) pcrypt = salt.crypt.Crypticle(opts, aes) signed_msg = pcrypt.loads(ret[dictkey]) @@ -1541,7 +1541,7 @@ async def test_unclosed_request_client(minion_opts, io_loop): try: assert client._closing is False with pytest.warns(salt.transport.base.TransportWarning): - client.__del__() + client.__del__() # pylint: disable=unnecessary-dunder-call finally: client.close() @@ -1557,6 +1557,6 @@ async def test_unclosed_publish_client(minion_opts, io_loop): try: assert client._closing is False with pytest.warns(salt.transport.base.TransportWarning): - client.__del__() + client.__del__() # pylint: disable=unnecessary-dunder-call finally: client.close() diff --git a/tests/pytests/unit/utils/test_cloud.py b/tests/pytests/unit/utils/test_cloud.py index 0bfe6d28ce6..7edce2000af 100644 --- a/tests/pytests/unit/utils/test_cloud.py +++ b/tests/pytests/unit/utils/test_cloud.py @@ -59,18 +59,18 @@ def create_class(tmp_path): def set_password( self, servicename, username, password - ): # pylint: disable=arguments-differ + ): # pylint: disable=arguments-differ,arguments-renamed self.__storage.setdefault(servicename, {}).update({username: password}) return 0 def get_password( self, servicename, username - ): # pylint: disable=arguments-differ + ): # pylint: disable=arguments-differ,arguments-renamed return self.__storage.setdefault(servicename, {}).get(username) def delete_password( self, servicename, username - ): # pylint: disable=arguments-differ + ): # pylint: disable=arguments-differ,arguments-renamed self.__storage.setdefault(servicename, {}).pop(username, None) return 0 @@ -249,6 +249,7 @@ def test_run_psexec_command_cleanup_lingering_paexec(caplog): "MermaidMan", "BarnicleBoy", ) + # pylint: disable=no-value-for-parameter mock_client.return_value.cleanup = MagicMock(side_effect=CannotDelete()) cloud.run_psexec_command( @@ -475,7 +476,7 @@ def test_winrm_pinnned_version(): ): try: - import winrm + import winrm # pylint: disable=unused-import except ImportError: raise pytest.skip('The "winrm" python module is not installed in this env.') else: diff --git a/tests/pytests/unit/utils/test_data.py b/tests/pytests/unit/utils/test_data.py index 5614a770316..e6a6cdd6185 100644 --- a/tests/pytests/unit/utils/test_data.py +++ b/tests/pytests/unit/utils/test_data.py @@ -14,8 +14,13 @@ from tests.support.unit import LOREM_IPSUM log = logging.getLogger(__name__) -_b = lambda x: x.encode("utf-8") -_s = lambda x: salt.utils.stringutils.to_str(x, normalize=True) + +def _b(x): + return x.encode("utf-8") + + +def _s(x): + return salt.utils.stringutils.to_str(x, normalize=True) @pytest.fixture @@ -566,7 +571,9 @@ def test_encode(get_test_data, get_BYTES, get_EGGS): None, [True, _b(get_EGGS), get_BYTES], ] - expected[11][_b("subdict")][_b("tuple")] = [ + expected[11][_b("subdict")][ # pylint: disable=unsupported-assignment-operation + _b("tuple") + ] = [ 123, _b("hello"), _b("world"), diff --git a/tests/pytests/unit/utils/test_vault.py b/tests/pytests/unit/utils/test_vault.py index 9e3dfe59f16..af755cadd4b 100644 --- a/tests/pytests/unit/utils/test_vault.py +++ b/tests/pytests/unit/utils/test_vault.py @@ -301,6 +301,7 @@ def test_make_request_single_use_token_run_ok(json_success, cache_single): "http://127.0.0.1:8200/key", headers=expected_headers, verify=ANY, + timeout=ANY, ) assert vault_return.json() == json_success @@ -324,6 +325,7 @@ def test_make_request_single_use_token_run_auth_error(json_denied, cache_single) "http://127.0.0.1:8200/key", headers=expected_headers, verify=ANY, + timeout=ANY, ) assert vault_return.json() == json_denied mock_del_cache.assert_called() @@ -358,6 +360,7 @@ def test_multi_use_token_successful_run(json_success, cache_uses): "http://127.0.0.1:8200/key", headers=expected_headers, verify=ANY, + timeout=ANY, ) mock_write_cache.assert_called_with(expected_cache_write) assert vault_return.json() == json_success @@ -381,6 +384,7 @@ def test_multi_use_token_last_use(json_success, cache_uses_last): "http://127.0.0.1:8200/key", headers=expected_headers, verify=ANY, + timeout=ANY, ) mock_del_cache.assert_called() assert vault_return.json() == json_success @@ -404,6 +408,7 @@ def test_unlimited_use_token_no_decrement(json_success, cache_unlimited): "http://127.0.0.1:8200/key", headers=expected_headers, verify=ANY, + timeout=ANY, ) assert ( not mock_del_cache.called @@ -508,6 +513,7 @@ def test_request_with_namespace(json_success, cache_single_namespace): "http://127.0.0.1:8200/key", headers=expected_headers, verify=ANY, + timeout=ANY, ) assert vault_return.json() == json_success diff --git a/tests/pytests/unit/utils/test_vt.py b/tests/pytests/unit/utils/test_vt.py index c31b25e623c..692bbf76f61 100644 --- a/tests/pytests/unit/utils/test_vt.py +++ b/tests/pytests/unit/utils/test_vt.py @@ -51,6 +51,6 @@ def test_log_sanitize(test_cmd, caplog): stream_stderr=False, ) with caplog.at_level(logging.DEBUG): - ret = term.recv() + term.recv() assert password not in caplog.text assert "******" in caplog.text diff --git a/tests/pytests/unit/wheel/test_file_roots.py b/tests/pytests/unit/wheel/test_file_roots.py index 5c8c54f23a5..4da2f359f2c 100644 --- a/tests/pytests/unit/wheel/test_file_roots.py +++ b/tests/pytests/unit/wheel/test_file_roots.py @@ -17,7 +17,7 @@ def _make_temp_root_file(root, *subpaths, binary=False, dir_only=False): full_path.write_bytes(content) else: content = str(full_path) - full_path.write_text(content) + full_path.write_text(content, encoding="utf-8") @pytest.fixture diff --git a/tests/salt-tcpdump.py b/tests/salt-tcpdump.py index 4a92966132b..c16e98a20e6 100644 --- a/tests/salt-tcpdump.py +++ b/tests/salt-tcpdump.py @@ -34,7 +34,7 @@ tcpdump "tcp[tcpflags] & tcp-syn != 0" and port 4506 and "tcp[tcpflags] & tcp-ac """ # pylint: disable=resource-leakage -import argparse # pylint: disable=minimum-python-version +import argparse import socket import sys import time @@ -124,7 +124,7 @@ class PCAPParser: packet_data = {"ip": {}, "tcp": {}} - (header, packet) = cap.next() # pylint: disable=incompatible-py3-code + (header, packet) = cap.next() eth_length, eth_protocol = self.parse_ether(packet) @@ -232,7 +232,7 @@ class SaltNetstat: """ Read the table of tcp connections & remove header """ - with open("/proc/net/tcp") as tcp_f: + with open("/proc/net/tcp", encoding="utf-8") as tcp_f: content = tcp_f.readlines() content.pop(0) return content diff --git a/tests/saltsh.py b/tests/saltsh.py index 64ace99cc3b..de87f55d9e7 100644 --- a/tests/saltsh.py +++ b/tests/saltsh.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -'''\ +''' Welcome to the Salt repl which exposes the execution environment of a minion in a pre-configured Python shell @@ -91,9 +91,11 @@ def get_salt_vars(): __pillar__ = {} # pylint: disable=invalid-name,unused-variable,possibly-unused-variable - JINJA = lambda x, **y: jinja2.Template(x).render( - grains=__grains__, salt=__salt__, opts=__opts__, pillar=__pillar__, **y - ) + def JINJA(x, **y): + return jinja2.Template(x).render( + grains=__grains__, salt=__salt__, opts=__opts__, pillar=__pillar__, **y + ) + # pylint: enable=invalid-name,unused-variable,possibly-unused-variable return locals() diff --git a/tests/support/copyartifacts.py b/tests/support/copyartifacts.py index a3054d80931..b0e5382a07f 100644 --- a/tests/support/copyartifacts.py +++ b/tests/support/copyartifacts.py @@ -2,7 +2,7 @@ Script for copying back xml junit files from tests """ -import argparse # pylint: disable=minimum-python-version +import argparse import os import subprocess @@ -19,13 +19,12 @@ class DownloadArtifacts: self.sftpclient = paramiko.SFTPClient.from_transport(self.transport) def setup_transport(self): - # pylint: disable=minimum-python-version + config = salt.utils.yaml.safe_load( subprocess.check_output( ["bundle", "exec", "kitchen", "diagnose", self.instance] ) ) - # pylint: enable=minimum-python-version state = config["instances"][self.instance]["state_file"] tport = config["instances"][self.instance]["transport"] transport = paramiko.Transport( @@ -44,9 +43,7 @@ class DownloadArtifacts: Make sure all xml files are readable by the world so that anyone can grab them """ for remote, _ in self.artifacts: - self.transport.open_session().exec_command( - "sudo chmod -R +r {}".format(remote) - ) + self.transport.open_session().exec_command(f"sudo chmod -R +r {remote}") def download(self): self._set_permissions() @@ -61,11 +58,11 @@ class DownloadArtifacts: self._do_download(remote, os.path.join(local, os.path.basename(remote))) def _do_download(self, remote, local): - print("Copying from {} to {}".format(remote, local)) + print(f"Copying from {remote} to {local}") try: self.sftpclient.get(remote, local) except OSError: - print("Failed to copy: {}".format(remote)) + print(f"Failed to copy: {remote}") if __name__ == "__main__": diff --git a/tests/support/generate-names-file-from-failed-test-reports.py b/tests/support/generate-names-file-from-failed-test-reports.py index ac4b13b2fe8..e565f335cf4 100644 --- a/tests/support/generate-names-file-from-failed-test-reports.py +++ b/tests/support/generate-names-file-from-failed-test-reports.py @@ -43,7 +43,7 @@ def main(): failures = set() for fname in sorted(glob.glob(os.path.join(options.reports_dir, "*.xml"))): total_xml_reports += 1 - with open(fname) as rfh: + with open(fname, encoding="utf-8") as rfh: test_suite, test_result = xunitparser.parse(rfh) if not test_result.errors and not test_result.failures: continue @@ -54,7 +54,7 @@ def main(): if not total_xml_reports: parser.exit(status=1, message="No JUnit XML files were parsed") - with open(options.output_file, "w") as wfh: + with open(options.output_file, "w", encoding="utf-8") as wfh: wfh.write(os.linesep.join(sorted(failures))) parser.exit(status=0) diff --git a/tests/support/pkg.py b/tests/support/pkg.py index 3d0e086e077..57feac63855 100644 --- a/tests/support/pkg.py +++ b/tests/support/pkg.py @@ -256,7 +256,7 @@ class SaltPkgInstall: self.install_dir / "salt-minion.exe" ).exists() and not self.relenv: log.debug( - f"Removing {(self.install_dir / 'salt-minion.exe')}" + "Removing %s", self.install_dir / "salt-minion.exe" ) (self.install_dir / "salt-minion.exe").unlink() @@ -640,7 +640,8 @@ class SaltPkgInstall: Pin: origin "repo.saltproject.io" Pin-Priority: 1001 """ - ) + ), + encoding="utf-8", ) cmd.append("--allow-downgrades") env = os.environ.copy() @@ -1487,7 +1488,7 @@ class ApiRequest: @pytest.helpers.register def download_file(url, dest, auth=None): # NOTE the stream=True parameter below - with requests.get(url, stream=True, auth=auth) as r: + with requests.get(url, stream=True, auth=auth, timeout=60) as r: r.raise_for_status() with salt.utils.files.fopen(dest, "wb") as f: for chunk in r.iter_content(chunk_size=8192): diff --git a/tests/support/pytest/etcd.py b/tests/support/pytest/etcd.py index 6606e9436b8..7bcc44fda03 100644 --- a/tests/support/pytest/etcd.py +++ b/tests/support/pytest/etcd.py @@ -59,7 +59,9 @@ def confirm_container_started(timeout_at, container): sleeptime = 1 while time.time() <= timeout_at: try: - response = requests.get("http://localhost:{}/version".format(etcd_port)) + response = requests.get( + "http://localhost:{}/version".format(etcd_port), timeout=60 + ) try: version = response.json() if "etcdserver" in version: diff --git a/tests/support/pytest/helpers.py b/tests/support/pytest/helpers.py index fa12784c04e..e6752ee7070 100644 --- a/tests/support/pytest/helpers.py +++ b/tests/support/pytest/helpers.py @@ -706,13 +706,17 @@ class EntropyGenerator: log.info("The '%s' file is not avilable", kernel_entropy_file) return - self.current_entropy = int(kernel_entropy_file.read_text().strip()) + self.current_entropy = int( + kernel_entropy_file.read_text(encoding="utf-8").strip() + ) log.info("Available Entropy: %s", self.current_entropy) if not kernel_poolsize_file.exists(): log.info("The '%s' file is not avilable", kernel_poolsize_file) else: - self.current_poolsize = int(kernel_poolsize_file.read_text().strip()) + self.current_poolsize = int( + kernel_poolsize_file.read_text(encoding="utf-8").strip() + ) log.info("Entropy Poolsize: %s", self.current_poolsize) # Account for smaller poolsizes using BLAKE2s if self.current_poolsize == 256: @@ -738,7 +742,9 @@ class EntropyGenerator: raise pytest.skip.Exception(message, _use_item_location=True) raise pytest.fail(message) subprocess.run([rngd, "-r", "/dev/urandom"], shell=False, check=True) - self.current_entropy = int(kernel_entropy_file.read_text().strip()) + self.current_entropy = int( + kernel_entropy_file.read_text(encoding="utf-8").strip() + ) log.info("Available Entropy: %s", self.current_entropy) if self.current_entropy >= self.minimum_entropy: break @@ -773,7 +779,9 @@ class EntropyGenerator: check=True, ) os.unlink(target_file.name) - self.current_entropy = int(kernel_entropy_file.read_text().strip()) + self.current_entropy = int( + kernel_entropy_file.read_text(encoding="utf-8").strip() + ) log.info("Available Entropy: %s", self.current_entropy) if self.current_entropy >= self.minimum_entropy: break diff --git a/tests/support/unit.py b/tests/support/unit.py index dc1051ea773..419e287b92f 100644 --- a/tests/support/unit.py +++ b/tests/support/unit.py @@ -158,7 +158,6 @@ class TestLoader(_TestLoader): class TestCase(_TestCase): - # pylint: disable=expected-an-indented-block-comment,too-many-leading-hastag-for-block-comment ## Commented out because it may be causing tests to hang ## at the end of the run # @@ -178,7 +177,6 @@ class TestCase(_TestCase): # print('\nWARNING: A misbehaving test has modified the working directory!\nThe test suite has reset the working directory ' # 'on tearDown() to {0}\n'.format(cls._cwd)) # cls._chdir_counter += 1 - # pylint: enable=expected-an-indented-block-comment,too-many-leading-hastag-for-block-comment def run(self, result=None): self._prerun_instance_attributes = dir(self) @@ -225,7 +223,7 @@ class TestCase(_TestCase): found_zombies += 1 except Exception: # pylint: disable=broad-except pass - proc_info += "|Z:{}".format(found_zombies) + proc_info += f"|Z:{found_zombies}" proc_info += "] {short_desc}".format(short_desc=desc if desc else "") return proc_info else: diff --git a/tests/support/win_installer.py b/tests/support/win_installer.py index 6a2f387dc84..65d39a40d1a 100644 --- a/tests/support/win_installer.py +++ b/tests/support/win_installer.py @@ -29,12 +29,15 @@ def download_and_verify(fp, name, repo=REPO): Download an installer and verify its contents. """ md5 = "{}.md5".format(name) - url = lambda x: "{}/{}".format(repo, x) - resp = requests.get(url(md5)) + + def url(x): + return "{}/{}".format(repo, x) + + resp = requests.get(url(md5), timeout=60) if resp.status_code != 200: raise Exception("Unable to fetch installer md5") installer_md5 = resp.text.strip().split()[0].lower() - resp = requests.get(url(name), stream=True) + resp = requests.get(url(name), stream=True, timeout=60) if resp.status_code != 200: raise Exception("Unable to fetch installer") md5hsh = hashlib.md5() diff --git a/tests/unit/ext/test_ipaddress.py b/tests/unit/ext/test_ipaddress.py index e4b2f98c357..474d05192fc 100644 --- a/tests/unit/ext/test_ipaddress.py +++ b/tests/unit/ext/test_ipaddress.py @@ -13,7 +13,7 @@ """Unittest for ipaddress module.""" -# pylint: disable=string-substitution-usage-error,pointless-statement,abstract-method,cell-var-from-loop +# pylint: disable=pointless-statement,abstract-method,cell-var-from-loop,unnecessary-dunder-call import contextlib import functools @@ -312,7 +312,7 @@ class AddressTestCase_v4(BaseTestCase, CommonTestMixin_v4): def test_invalid_characters(self): def assertBadOctet(addr, octet): - msg = "Only decimal digits permitted in {!r} in {!r}".format(octet, addr) + msg = f"Only decimal digits permitted in {octet!r} in {addr!r}" with self.assertAddressError(re.escape(msg)): ipaddress.IPv4Address(addr) @@ -657,7 +657,7 @@ class NetmaskTestMixin_v4(CommonTestMixin_v4): def assertBadNetmask(addr, netmask): msg = "%r is not a valid netmask" % netmask with self.assertNetmaskError(re.escape(msg)): - self.factory("{}/{}".format(addr, netmask)) + self.factory(f"{addr}/{netmask}") assertBadNetmask("1.2.3.4", "") assertBadNetmask("1.2.3.4", "-1") @@ -827,7 +827,7 @@ class NetmaskTestMixin_v6(CommonTestMixin_v6): def assertBadNetmask(addr, netmask): msg = "%r is not a valid netmask" % netmask with self.assertNetmaskError(re.escape(msg)): - self.factory("{}/{}".format(addr, netmask)) + self.factory(f"{addr}/{netmask}") assertBadNetmask("::1", "") assertBadNetmask("::1", "::1") diff --git a/tests/unit/modules/test_elasticsearch.py b/tests/unit/modules/test_elasticsearch.py index fc073f54d4d..4ab515e7d46 100644 --- a/tests/unit/modules/test_elasticsearch.py +++ b/tests/unit/modules/test_elasticsearch.py @@ -9,18 +9,14 @@ from salt.modules import elasticsearch from tests.support.mock import MagicMock, patch from tests.support.unit import TestCase -# Import elasticsearch exceptions -NO_ELASTIC = False -try: - from elasticsearch import NotFoundError, TransportError -except Exception: # pylint: disable=broad-except - NO_ELASTIC = True - - -@pytest.mark.skipif( - NO_ELASTIC, +_es_module = pytest.importorskip( + "elasticsearch", reason="Install elasticsearch-py before running Elasticsearch unit tests.", ) +NotFoundError = _es_module.NotFoundError +TransportError = _es_module.TransportError + + class ElasticsearchTestCase(TestCase): """ Test cases for salt.modules.elasticsearch diff --git a/tests/unit/modules/test_sysmod.py b/tests/unit/modules/test_sysmod.py index 00185a90099..125f17d8606 100644 --- a/tests/unit/modules/test_sysmod.py +++ b/tests/unit/modules/test_sysmod.py @@ -113,15 +113,17 @@ class SysmodTestCase(TestCase, LoaderModuleMockMixin): cls.salt_dunder[func] = MockDocstringable(docstring) cls._docstrings[func] = docstring - module = func.split(".")[0] + module = func.split(".", maxsplit=1)[0] cls._statedocstrings[func] = docstring cls._statedocstrings[module] = "docstring for {}".format(module) - cls._modules.add(func.split(".")[0]) + cls._modules.add(func.split(".", maxsplit=1)[0]) docstring = "docstring for {}".format(func) mock = MockDocstringable(docstring) - mock.set_module_docstring("docstring for {}".format(func.split(".")[0])) + mock.set_module_docstring( + "docstring for {}".format(func.split(".", maxsplit=1)[0]) + ) Mockstate.State.states[func] = mock cls._modules = sorted(list(cls._modules)) diff --git a/tests/unit/modules/test_zcbuildout.py b/tests/unit/modules/test_zcbuildout.py index db7a862f727..b26fac3a928 100644 --- a/tests/unit/modules/test_zcbuildout.py +++ b/tests/unit/modules/test_zcbuildout.py @@ -116,7 +116,7 @@ class Base(TestCase, LoaderModuleMockMixin): def setUp(self): if salt.utils.platform.is_darwin(): self.patched_environ = patched_environ(__cleanup__=["__PYVENV_LAUNCHER__"]) - self.patched_environ.__enter__() + self.patched_environ.__enter__() # pylint: disable=unnecessary-dunder-call self.addCleanup(self.patched_environ.__exit__) super().setUp() @@ -490,8 +490,8 @@ class BuildoutOnlineTestCase(Base): out = ret["out"] comment = ret["comment"] self.assertTrue(ret["status"]) - self.assertTrue("Creating directory" in out) - self.assertTrue("Installing a." in out) + self.assertIn("Creating directory", out) + self.assertIn("Installing a.", out) self.assertTrue("{} bootstrap.py".format(self.py_st) in comment) self.assertTrue("buildout -c buildout.cfg" in comment) ret = buildout.buildout( @@ -500,17 +500,17 @@ class BuildoutOnlineTestCase(Base): outlog = ret["outlog"] out = ret["out"] comment = ret["comment"] - self.assertTrue("Installing single part: a" in outlog) - self.assertTrue("buildout -c buildout.cfg -N install a" in comment) - self.assertTrue("Installing b." in out) - self.assertTrue("Installing c." in out) + self.assertIn("Installing single part: a", outlog) + self.assertIn("buildout -c buildout.cfg -N install a", comment) + self.assertIn("Installing b.", out) + self.assertIn("Installing c.", out) ret = buildout.buildout( b_dir, parts=["a", "b", "c"], buildout_ver=2, newest=True, python=self.py_st ) outlog = ret["outlog"] out = ret["out"] comment = ret["comment"] - self.assertTrue("buildout -c buildout.cfg -n install a" in comment) + self.assertIn("buildout -c buildout.cfg -n install a", comment) # TODO: Is this test even still needed? @@ -537,8 +537,8 @@ class BuildoutAPITestCase(TestCase): out = ret["out"].decode("utf-8") for out in ["àé", "ççàé"]: - self.assertTrue(out in uretm["logs_by_level"]["info"]) - self.assertTrue(out in uretm["outlog_by_level"]) + self.assertIn(out, uretm["logs_by_level"]["info"]) + self.assertIn(out, uretm["outlog_by_level"]) def test_setup(self): buildout.LOG.clear() diff --git a/tests/unit/states/test_loop.py b/tests/unit/states/test_loop.py index ba100dfe663..ea3b0989d97 100644 --- a/tests/unit/states/test_loop.py +++ b/tests/unit/states/test_loop.py @@ -294,9 +294,7 @@ class LoopTestCaseNoEval(TestCase, LoaderModuleMockMixin): """ with patch.dict( salt.states.loop.__salt__, # pylint: disable=no-member - { - "foo.bar": MagicMock(side_effect=range(1, 7)) - }, # pylint: disable=incompatible-py3-code + {"foo.bar": MagicMock(side_effect=range(1, 7))}, ): self.assertDictEqual( salt.states.loop.until( @@ -312,9 +310,7 @@ class LoopTestCaseNoEval(TestCase, LoaderModuleMockMixin): with patch.dict( salt.states.loop.__salt__, # pylint: disable=no-member - { - "foo.bar": MagicMock(side_effect=range(1, 7)) - }, # pylint: disable=incompatible-py3-code + {"foo.bar": MagicMock(side_effect=range(1, 7))}, ): self.assertDictEqual( salt.states.loop.until_no_eval( @@ -334,9 +330,7 @@ class LoopTestCaseNoEval(TestCase, LoaderModuleMockMixin): """ with patch.dict( salt.states.loop.__salt__, # pylint: disable=no-member - { - "foo.bar": MagicMock(side_effect=range(1, 7)) - }, # pylint: disable=incompatible-py3-code + {"foo.bar": MagicMock(side_effect=range(1, 7))}, ): self.assertDictEqual( salt.states.loop.until( @@ -354,9 +348,7 @@ class LoopTestCaseNoEval(TestCase, LoaderModuleMockMixin): # returning a lower number of attempts (because it's slower). with patch.dict( salt.states.loop.__salt__, # pylint: disable=no-member - { - "foo.bar": MagicMock(side_effect=range(1, 7)) - }, # pylint: disable=incompatible-py3-code + {"foo.bar": MagicMock(side_effect=range(1, 7))}, ): self.assertDictEqual( salt.states.loop.until_no_eval( diff --git a/tests/unit/test_pillar.py b/tests/unit/test_pillar.py index b71c0e9a371..323d5660cfe 100644 --- a/tests/unit/test_pillar.py +++ b/tests/unit/test_pillar.py @@ -36,13 +36,13 @@ class MockFileclient: self.list_states = lambda *x, **y: list_states # pylint: disable=unused-argument,no-method-argument,method-hidden - def cache_file(*args, **kwargs): + def cache_file(self, *args, **kwargs): raise NotImplementedError() - def get_state(*args, **kwargs): + def get_state(self, *args, **kwargs): raise NotImplementedError() - def list_states(*args, **kwargs): + def list_states(self, *args, **kwargs): raise NotImplementedError() # pylint: enable=unused-argument,no-method-argument,method-hidden diff --git a/tests/unit/test_zypp_plugins.py b/tests/unit/test_zypp_plugins.py index 7bd248ffbd9..64bc86b49d3 100644 --- a/tests/unit/test_zypp_plugins.py +++ b/tests/unit/test_zypp_plugins.py @@ -1,7 +1,7 @@ """ :codeauthor: Bo Maryniuk """ -import imp +import imp # pylint: disable=deprecated-module import os import pytest diff --git a/tests/unit/utils/test_configparser.py b/tests/unit/utils/test_configparser.py index ab32ec992d9..d4d3a79ed3c 100644 --- a/tests/unit/utils/test_configparser.py +++ b/tests/unit/utils/test_configparser.py @@ -179,9 +179,7 @@ class TestGitConfigParser(TestCase): self.conf.write(fp_) # Confirm that the new file was written correctly expected = self.fix_indent(ORIG_CONFIG) - # pylint: disable=string-substitution-usage-error - expected.insert(6, "\tfetch = %s" % new_refspec) - # pylint: enable=string-substitution-usage-error + expected.insert(6, f"\tfetch = {new_refspec}") self.assertEqual(self.get_lines(self.new_config), expected) def test_remove_option(self): diff --git a/tests/unit/utils/test_context.py b/tests/unit/utils/test_context.py index abea69fbf62..8cdbb8d53c5 100644 --- a/tests/unit/utils/test_context.py +++ b/tests/unit/utils/test_context.py @@ -102,7 +102,7 @@ class ContextDictTests(AsyncTestCase): wait_iterator = salt.ext.tornado.gen.WaitIterator(*futures) while not wait_iterator.done(): - r = yield wait_iterator.next() # pylint: disable=incompatible-py3-code + r = yield wait_iterator.next() self.assertEqual(r[0], r[1]) # verify that the global value remails self.assertEqual(r[2], r[3]) # verify that the override sticks locally self.assertEqual( diff --git a/tests/unit/utils/test_dns.py b/tests/unit/utils/test_dns.py index 75ceeef1359..225f9811937 100644 --- a/tests/unit/utils/test_dns.py +++ b/tests/unit/utils/test_dns.py @@ -259,8 +259,8 @@ class DNSlookupsCase(TestCase): :param secure: delta cmd.run_all output for secured RESULTS """ # wrong - for wrong in wrong: - with self._mock_cmd_ret(wrong): + for _wrong in wrong: + with self._mock_cmd_ret(_wrong): self.assertEqual(lookup_cb("mockq", "A"), False) # empty response diff --git a/tests/unit/utils/test_systemd.py b/tests/unit/utils/test_systemd.py index 698a2337e5e..082076feba8 100644 --- a/tests/unit/utils/test_systemd.py +++ b/tests/unit/utils/test_systemd.py @@ -351,8 +351,6 @@ class SystemdTestCase(TestCase): Raised by DBUS, e.g. when a PID does not belong to a service """ - ... - dbus_mock = Mock() dbus_mock.DBusException = DBusException() dbus_mock.GetUnitByPID = Mock(site_effect=dbus_mock.DBusException) diff --git a/tests/unit/utils/test_thin.py b/tests/unit/utils/test_thin.py index 7fd1e7b5dc3..28f26824118 100644 --- a/tests/unit/utils/test_thin.py +++ b/tests/unit/utils/test_thin.py @@ -113,7 +113,8 @@ class SSHThinTestCase(TestCase): return popen - def _version_info(self, major=None, minor=None): + @staticmethod + def _version_info(major=None, minor=None): """ Fake version info. @@ -801,7 +802,7 @@ class SSHThinTestCase(TestCase): "salt.utils.thin.tempfile.mkstemp", MagicMock(return_value=(3, ".temporary")) ) @patch("salt.utils.thin.shutil", MagicMock()) - @patch("salt.utils.thin.sys.version_info", _version_info(None, 3, 6)) + @patch("salt.utils.thin.sys.version_info", _version_info(3, 6)) @patch("salt.utils.path.which", MagicMock(return_value="/usr/bin/python")) def test_gen_thin_compression_fallback_py3(self): """ @@ -852,7 +853,7 @@ class SSHThinTestCase(TestCase): "salt.utils.thin.tempfile.mkstemp", MagicMock(return_value=(3, ".temporary")) ) @patch("salt.utils.thin.shutil", MagicMock()) - @patch("salt.utils.thin.sys.version_info", _version_info(None, 3, 6)) + @patch("salt.utils.thin.sys.version_info", _version_info(3, 6)) @patch("salt.utils.path.which", MagicMock(return_value="/usr/bin/python")) def test_gen_thin_control_files_written_py3(self): """ @@ -905,7 +906,7 @@ class SSHThinTestCase(TestCase): "salt.utils.thin.tempfile.mkstemp", MagicMock(return_value=(3, ".temporary")) ) @patch("salt.utils.thin.shutil", MagicMock()) - @patch("salt.utils.thin.sys.version_info", _version_info(None, 3, 6)) + @patch("salt.utils.thin.sys.version_info", _version_info(3, 6)) @patch("salt.utils.hashutils.DigestCollector", MagicMock()) @patch("salt.utils.path.which", MagicMock(return_value="/usr/bin/python")) def test_gen_thin_main_content_files_written_py3(self): @@ -974,7 +975,7 @@ class SSHThinTestCase(TestCase): "salt.utils.thin.tempfile.mkstemp", MagicMock(return_value=(3, ".temporary")) ) @patch("salt.utils.thin.shutil", MagicMock()) - @patch("salt.utils.thin.sys.version_info", _version_info(None, 3, 6)) + @patch("salt.utils.thin.sys.version_info", _version_info(3, 6)) @patch("salt.utils.hashutils.DigestCollector", MagicMock()) @patch("salt.utils.path.which", MagicMock(return_value="/usr/bin/python")) def test_gen_thin_ext_alternative_content_files_written_py3(self): @@ -1087,7 +1088,7 @@ class SSHThinTestCase(TestCase): "salt.utils.thin.tempfile.mkstemp", MagicMock(return_value=(3, ".temporary")) ) @patch("salt.utils.thin.shutil", MagicMock()) - @patch("salt.utils.thin.sys.version_info", _version_info(None, 3, 6)) + @patch("salt.utils.thin.sys.version_info", _version_info(3, 6)) def test_gen_thin_control_files_written_access_denied_cwd(self): """ Test thin.gen_thin function if control files are written (version, salt-call etc) diff --git a/tests/wheeltest.py b/tests/wheeltest.py index 93880b0b9f3..1f661941a81 100644 --- a/tests/wheeltest.py +++ b/tests/wheeltest.py @@ -3,9 +3,7 @@ Test interacting with the wheel system. This script is useful when testing wheel modules """ - - -import optparse +import optparse # pylint: disable=deprecated-module import pprint import salt.auth diff --git a/tools/changelog.py b/tools/changelog.py index 8e9e3ff3e73..99c81c40082 100644 --- a/tools/changelog.py +++ b/tools/changelog.py @@ -110,18 +110,18 @@ def update_rpm(ctx: Context, salt_version: Version, draft: bool = False): header = f"* {date} Salt Project Packaging - {str_salt_version}\n" parts = orig.split("%changelog") tmpspec = "pkg/rpm/salt.spec.1" - with open(tmpspec, "w") as wfp: + with open(tmpspec, "w", encoding="utf-8") as wfp: wfp.write(parts[0]) wfp.write("%changelog\n") wfp.write(header) wfp.write(changes) wfp.write(parts[1]) try: - with open(tmpspec) as rfp: + with open(tmpspec, encoding="utf-8") as rfp: if draft: ctx.info(rfp.read()) else: - with open("pkg/rpm/salt.spec", "w") as wfp: + with open("pkg/rpm/salt.spec", "w", encoding="utf-8") as wfp: wfp.write(rfp.read()) finally: os.remove(tmpspec) @@ -153,20 +153,20 @@ def update_deb(ctx: Context, salt_version: Version, draft: bool = False): tmpchanges = "pkg/rpm/salt.spec.1" debian_changelog_path = "pkg/debian/changelog" tmp_debian_changelog_path = f"{debian_changelog_path}.1" - with open(tmp_debian_changelog_path, "w") as wfp: + with open(tmp_debian_changelog_path, "w", encoding="utf-8") as wfp: wfp.write(f"salt ({salt_version}) stable; urgency=medium\n\n") wfp.write(formated) wfp.write( f"\n -- Salt Project Packaging {date}\n\n" ) - with open(debian_changelog_path) as rfp: + with open(debian_changelog_path, encoding="utf-8") as rfp: wfp.write(rfp.read()) try: - with open(tmp_debian_changelog_path) as rfp: + with open(tmp_debian_changelog_path, encoding="utf-8") as rfp: if draft: ctx.info(rfp.read()) else: - with open(debian_changelog_path, "w") as wfp: + with open(debian_changelog_path, "w", encoding="utf-8") as wfp: wfp.write(rfp.read()) finally: os.remove(tmp_debian_changelog_path) @@ -254,7 +254,7 @@ def update_release_notes( return unreleased = " - UNRELEASED" - warning = f""" + warning = """