diff --git a/contrib/cirrus/build_podman.sh b/contrib/cirrus/build_podman.sh index 9a217b0b..87218d71 100755 --- a/contrib/cirrus/build_podman.sh +++ b/contrib/cirrus/build_podman.sh @@ -7,4 +7,3 @@ systemctl stop podman.socket || : dnf erase podman -y dnf copr enable rhcontainerbot/podman-next -y dnf install podman -y - diff --git a/docs/source/_templates/apidoc/toc.rst_t b/docs/source/_templates/apidoc/toc.rst_t index f0877eeb..878540ce 100644 --- a/docs/source/_templates/apidoc/toc.rst_t +++ b/docs/source/_templates/apidoc/toc.rst_t @@ -5,4 +5,3 @@ {% for docname in docnames %} {{ docname }} {%- endfor %} - diff --git a/docs/source/conf.py b/docs/source/conf.py index caf916d3..819ec13b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -15,17 +15,17 @@ from sphinx.domains.python import PythonDomain -sys.path.insert(0, os.path.abspath('../..')) +sys.path.insert(0, os.path.abspath("../..")) # -- Project information ----------------------------------------------------- -project = u'Podman Python SDK' -copyright = u'2021, Red Hat Inc' -author = u'Red Hat Inc' +project = "Podman Python SDK" +copyright = "2021, Red Hat Inc" +author = "Red Hat Inc" # The full version, including alpha/beta/rc tags -version = '3.2.1.0' +version = "3.2.1.0" release = version add_module_names = False @@ -39,22 +39,22 @@ # sphinx.ext.napoleon: Support for NumPy and Google style docstrings # sphinx.ext.viewcode: Add links to highlighted source code # isort: unique-list -extensions = ['sphinx.ext.napoleon', 'sphinx.ext.autodoc', 'sphinx.ext.viewcode'] +extensions = ["sphinx.ext.napoleon", "sphinx.ext.autodoc", "sphinx.ext.viewcode"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. # isort: unique-list exclude_patterns = [ - 'podman.api.*rst', - 'podman.rst', - 'podman.version.rst', - 'podman.tlsconfig.rst', - 'podman.errors.rst', - 'podman.domain.rst', + "podman.api.*rst", + "podman.rst", + "podman.version.rst", + "podman.tlsconfig.rst", + "podman.errors.rst", + "podman.domain.rst", ] @@ -63,44 +63,44 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' -html_favicon = '_static/podman-logo.ico' +html_theme = "alabaster" +html_favicon = "_static/podman-logo.ico" html_theme_options = { - 'description': 'Develop scripted Podman operations', - 'fixed_sidebar': False, - 'github_banner': True, - 'github_repo': 'podman-py', - 'github_user': 'containers', - 'logo': "podman-logo.png", - 'logo_name': True, - 'show_powered_by': False, - 'extra_nav_links': { - 'Report PodmanPy Issue': 'https://github.com/containers/podman-py/issues', - 'Podman Reference': 'https://docs.podman.io', - 'Podman on github': 'https://github.com/containers/podman', + "description": "Develop scripted Podman operations", + "fixed_sidebar": False, + "github_banner": True, + "github_repo": "podman-py", + "github_user": "containers", + "logo": "podman-logo.png", + "logo_name": True, + "show_powered_by": False, + "extra_nav_links": { + "Report PodmanPy Issue": "https://github.com/containers/podman-py/issues", + "Podman Reference": "https://docs.podman.io", + "Podman on github": "https://github.com/containers/podman", }, } html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', - 'searchbox.html', + "**": [ + "about.html", + "navigation.html", + "relations.html", + "searchbox.html", ] } # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # -- autoclass settings ------------------------------------------------------ s autodoc_member_order = "groupwise" autodoc_default_options = { - 'members': True, - 'inherited-members': True, - 'show-inheritance': True, + "members": True, + "inherited-members": True, + "show-inheritance": True, } autoclass_content = "both" @@ -123,8 +123,8 @@ class PatchedPythonDomain(PythonDomain): def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): - if 'refspecific' in node: - del node['refspecific'] + if "refspecific" in node: + del node["refspecific"] return super(PatchedPythonDomain, self).resolve_xref( env, fromdocname, builder, typ, target, node, contnode ) @@ -132,7 +132,7 @@ def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): def skip(app, what, name, obj, would_skip, options): # isort: unique-list - cls = ['ApiConnection', 'DockerClient', 'DockerException'] + cls = ["ApiConnection", "DockerClient", "DockerException"] if name in cls: return True diff --git a/docs/source/index.rst b/docs/source/index.rst index d254b58d..fd729289 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -74,4 +74,4 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` -* :ref:`search` \ No newline at end of file +* :ref:`search` diff --git a/podman/__init__.py b/podman/__init__.py index 3f259ea2..3c4ad4f9 100644 --- a/podman/__init__.py +++ b/podman/__init__.py @@ -8,4 +8,4 @@ from podman.version import __version__ # isort: unique-list -__all__ = ['PodmanClient', '__version__', 'from_env'] +__all__ = ["PodmanClient", "__version__", "from_env"] diff --git a/podman/api/__init__.py b/podman/api/__init__.py index 8ad99451..2b493ed5 100644 --- a/podman/api/__init__.py +++ b/podman/api/__init__.py @@ -13,7 +13,11 @@ stream_frames, stream_helper, ) -from podman.api.tar_utils import create_tar, prepare_containerfile, prepare_containerignore +from podman.api.tar_utils import ( + create_tar, + prepare_containerfile, + prepare_containerignore, +) DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024 @@ -27,22 +31,22 @@ # isort: unique-list __all__ = [ - 'APIClient', - 'COMPATIBLE_VERSION', - 'DEFAULT_CHUNK_SIZE', - 'Literal', - 'VERSION', - 'cached_property', - 'create_tar', - 'decode_header', - 'frames', - 'parse_repository', - 'prepare_body', - 'prepare_cidr', - 'prepare_containerfile', - 'prepare_containerignore', - 'prepare_filters', - 'prepare_timestamp', - 'stream_frames', - 'stream_helper', + "APIClient", + "COMPATIBLE_VERSION", + "DEFAULT_CHUNK_SIZE", + "Literal", + "VERSION", + "cached_property", + "create_tar", + "decode_header", + "frames", + "parse_repository", + "prepare_body", + "prepare_cidr", + "prepare_containerfile", + "prepare_containerignore", + "prepare_filters", + "prepare_timestamp", + "stream_frames", + "stream_helper", ] diff --git a/podman/api/client.py b/podman/api/client.py index 062c3cad..f303b904 100644 --- a/podman/api/client.py +++ b/podman/api/client.py @@ -3,7 +3,18 @@ import json import warnings import urllib.parse -from typing import Any, ClassVar, IO, Iterable, List, Mapping, Optional, Tuple, Type, Union +from typing import ( + Any, + ClassVar, + IO, + Iterable, + List, + Mapping, + Optional, + Tuple, + Type, + Union, +) import requests from requests.adapters import HTTPAdapter @@ -36,7 +47,7 @@ class ParameterDeprecationWarning(DeprecationWarning): # Make the ParameterDeprecationWarning visible for user. -warnings.simplefilter('always', ParameterDeprecationWarning) +warnings.simplefilter("always", ParameterDeprecationWarning) class APIResponse: diff --git a/podman/api/http_utils.py b/podman/api/http_utils.py index 0f327c91..04f53200 100644 --- a/podman/api/http_utils.py +++ b/podman/api/http_utils.py @@ -100,4 +100,4 @@ def _filter_values(mapping: Mapping[str, Any], recursion=False) -> Dict[str, Any def encode_auth_header(auth_config: Dict[str, str]) -> str: - return base64.urlsafe_b64encode(json.dumps(auth_config).encode('utf-8')) + return base64.urlsafe_b64encode(json.dumps(auth_config).encode("utf-8")) diff --git a/podman/api/parse_utils.py b/podman/api/parse_utils.py index c07762ea..8d531740 100644 --- a/podman/api/parse_utils.py +++ b/podman/api/parse_utils.py @@ -56,7 +56,9 @@ def prepare_timestamp(value: Union[datetime, int, None]) -> Optional[int]: raise ValueError(f"Type '{type(value)}' is not supported by prepare_timestamp()") -def prepare_cidr(value: Union[ipaddress.IPv4Network, ipaddress.IPv6Network]) -> (str, str): +def prepare_cidr( + value: Union[ipaddress.IPv4Network, ipaddress.IPv6Network], +) -> (str, str): """Returns network address and Base64 encoded netmask from CIDR. The return values are dictated by the Go JSON decoder. diff --git a/podman/api/path_utils.py b/podman/api/path_utils.py index 84f9769e..9027ee7e 100644 --- a/podman/api/path_utils.py +++ b/podman/api/path_utils.py @@ -9,10 +9,10 @@ def get_runtime_dir() -> str: """Returns the runtime directory for the current user""" try: - return os.environ['XDG_RUNTIME_DIR'] + return os.environ["XDG_RUNTIME_DIR"] except KeyError: user = getpass.getuser() - fallback = f'/tmp/podmanpy-runtime-dir-fallback-{user}' + fallback = f"/tmp/podmanpy-runtime-dir-fallback-{user}" try: # This must be a real directory, not a symlink, so attackers can't diff --git a/podman/api/tar_utils.py b/podman/api/tar_utils.py index 950cc44f..82c53135 100644 --- a/podman/api/tar_utils.py +++ b/podman/api/tar_utils.py @@ -21,7 +21,7 @@ def prepare_containerignore(anchor: str) -> List[str]: if not ignore.exists(): continue - with ignore.open(encoding='utf-8') as file: + with ignore.open(encoding="utf-8") as file: return list( filter( lambda l: l and not l.startswith("#"), diff --git a/podman/api/typing_extensions.py b/podman/api/typing_extensions.py index ff698f4c..84edc769 100644 --- a/podman/api/typing_extensions.py +++ b/podman/api/typing_extensions.py @@ -65,8 +65,8 @@ class _TypingEmpty: def _no_slots_copy(dct): dict_copy = dict(dct) - if '__slots__' in dict_copy: - for slot in dict_copy['__slots__']: + if "__slots__" in dict_copy: + for slot in dict_copy["__slots__"]: dict_copy.pop(slot, None) return dict_copy @@ -83,7 +83,7 @@ def _check_generic(cls, parameters): ) -if hasattr(typing, '_generic_new'): +if hasattr(typing, "_generic_new"): _generic_new = typing._generic_new else: # Note: The '_generic_new(...)' function is used as a part of the @@ -104,7 +104,7 @@ def _generic_new(base_cls, cls, *args, **kwargs): # See https://github.com/python/typing/pull/439 -if hasattr(typing, '_geqv'): +if hasattr(typing, "_geqv"): from typing import _geqv _geqv_defined = True @@ -134,11 +134,11 @@ def _check_methods_in_mro(C, *methods): # Please keep __all__ alphabetized within each category. __all__ = [ # Super-special typing primitives. - 'ClassVar', - 'Concatenate', - 'Final', - 'ParamSpec', - 'Type', + "ClassVar", + "Concatenate", + "Final", + "ParamSpec", + "Type", # ABCs (from collections.abc). # The following are added depending on presence # of their non-generic counterparts in stdlib: @@ -150,24 +150,24 @@ def _check_methods_in_mro(C, *methods): # 'AsyncContextManager', # 'ChainMap', # Concrete collection types. - 'ContextManager', - 'Counter', - 'Deque', - 'DefaultDict', - 'OrderedDict', - 'TypedDict', + "ContextManager", + "Counter", + "Deque", + "DefaultDict", + "OrderedDict", + "TypedDict", # Structural checks, a.k.a. protocols. - 'SupportsIndex', + "SupportsIndex", # One-off things. - 'final', - 'IntVar', - 'Literal', - 'NewType', - 'overload', - 'Text', - 'TypeAlias', - 'TypeGuard', - 'TYPE_CHECKING', + "final", + "IntVar", + "Literal", + "NewType", + "overload", + "Text", + "TypeAlias", + "TypeGuard", + "TYPE_CHECKING", ] # Annotated relies on substitution trees of pep 560. It will not work for @@ -184,12 +184,12 @@ def _check_methods_in_mro(C, *methods): HAVE_PROTOCOLS = sys.version_info[:3] != (3, 5, 0) if HAVE_PROTOCOLS: - __all__.extend(['Protocol', 'runtime', 'runtime_checkable']) + __all__.extend(["Protocol", "runtime", "runtime_checkable"]) # TODO -if hasattr(typing, 'NoReturn'): +if hasattr(typing, "NoReturn"): NoReturn = typing.NoReturn -elif hasattr(typing, '_FinalTypingBase'): +elif hasattr(typing, "_FinalTypingBase"): class _NoReturn(typing._FinalTypingBase, _root=True): """Special type indicating functions that never return. @@ -245,17 +245,17 @@ def stop() -> NoReturn: # Some unconstrained type variables. These are used by the container types. # (These are not for export.) -T = typing.TypeVar('T') # Any type. -KT = typing.TypeVar('KT') # Key type. -VT = typing.TypeVar('VT') # Value type. -T_co = typing.TypeVar('T_co', covariant=True) # Any type covariant containers. -V_co = typing.TypeVar('V_co', covariant=True) # Any type covariant containers. -VT_co = typing.TypeVar('VT_co', covariant=True) # Value type covariant containers. -T_contra = typing.TypeVar('T_contra', contravariant=True) # Ditto contravariant. - -if hasattr(typing, 'ClassVar'): +T = typing.TypeVar("T") # Any type. +KT = typing.TypeVar("KT") # Key type. +VT = typing.TypeVar("VT") # Value type. +T_co = typing.TypeVar("T_co", covariant=True) # Any type covariant containers. +V_co = typing.TypeVar("V_co", covariant=True) # Any type covariant containers. +VT_co = typing.TypeVar("VT_co", covariant=True) # Value type covariant containers. +T_contra = typing.TypeVar("T_contra", contravariant=True) # Ditto contravariant. + +if hasattr(typing, "ClassVar"): ClassVar = typing.ClassVar -elif hasattr(typing, '_FinalTypingBase'): +elif hasattr(typing, "_FinalTypingBase"): class _ClassVar(typing._FinalTypingBase, _root=True): """Special type construct to mark class variables. @@ -274,7 +274,7 @@ class Starship: be used with isinstance() or issubclass(). """ - __slots__ = ('__type__',) + __slots__ = ("__type__",) def __init__(self, tp=None, **kwds): self.__type__ = tp @@ -284,11 +284,11 @@ def __getitem__(self, item): if self.__type__ is None: return cls( typing._type_check( - item, '{} accepts only single type.'.format(cls.__name__[1:]) + item, "{} accepts only single type.".format(cls.__name__[1:]) ), _root=True, ) - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) def _eval_type(self, globalns, localns): new_tp = typing._eval_type(self.__type__, globalns, localns) @@ -299,7 +299,7 @@ def _eval_type(self, globalns, localns): def __repr__(self): r = super().__repr__() if self.__type__ is not None: - r += '[{}]'.format(typing._type_repr(self.__type__)) + r += "[{}]".format(typing._type_repr(self.__type__)) return r def __hash__(self): @@ -333,10 +333,10 @@ def __subclasscheck__(self, cls): def __getitem__(self, item): cls = type(self) if self.__type__ is not None: - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) param = typing._type_check( - item, '{} accepts only single type.'.format(cls.__name__[1:]) + item, "{} accepts only single type.".format(cls.__name__[1:]) ) return cls(self.__name__, self.__bases__, dict(self.__dict__), tp=param, _root=True) @@ -345,13 +345,17 @@ def _eval_type(self, globalns, localns): if new_tp == self.__type__: return self return type(self)( - self.__name__, self.__bases__, dict(self.__dict__), tp=self.__type__, _root=True + self.__name__, + self.__bases__, + dict(self.__dict__), + tp=self.__type__, + _root=True, ) def __repr__(self): r = super().__repr__() if self.__type__ is not None: - r += '[{}]'.format(typing._type_repr(self.__type__)) + r += "[{}]".format(typing._type_repr(self.__type__)) return r def __hash__(self): @@ -385,20 +389,20 @@ class Starship: # On older versions of typing there is an internal class named "Final". -if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7): +if hasattr(typing, "Final") and sys.version_info[:2] >= (3, 7): Final = typing.Final elif sys.version_info[:2] >= (3, 7): class _FinalForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return "typing_extensions." + self._name def __getitem__(self, parameters): - item = typing._type_check(parameters, '{} accepts only single type'.format(self._name)) + item = typing._type_check(parameters, "{} accepts only single type".format(self._name)) return _GenericAlias(self, (item,)) Final = _FinalForm( - 'Final', + "Final", doc="""A special typing construct to indicate that a name cannot be re-assigned or overridden in a subclass. For example: @@ -413,7 +417,7 @@ class FastConnector(Connection): There is no runtime checking of these properties.""", ) -elif hasattr(typing, '_FinalTypingBase'): +elif hasattr(typing, "_FinalTypingBase"): class _Final(typing._FinalTypingBase, _root=True): """A special typing construct to indicate that a name @@ -431,7 +435,7 @@ class FastConnector(Connection): There is no runtime checking of these properties. """ - __slots__ = ('__type__',) + __slots__ = ("__type__",) def __init__(self, tp=None, **kwds): self.__type__ = tp @@ -441,11 +445,11 @@ def __getitem__(self, item): if self.__type__ is None: return cls( typing._type_check( - item, '{} accepts only single type.'.format(cls.__name__[1:]) + item, "{} accepts only single type.".format(cls.__name__[1:]) ), _root=True, ) - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) def _eval_type(self, globalns, localns): new_tp = typing._eval_type(self.__type__, globalns, localns) @@ -456,7 +460,7 @@ def _eval_type(self, globalns, localns): def __repr__(self): r = super().__repr__() if self.__type__ is not None: - r += '[{}]'.format(typing._type_repr(self.__type__)) + r += "[{}]".format(typing._type_repr(self.__type__)) return r def __hash__(self): @@ -490,10 +494,10 @@ def __subclasscheck__(self, cls): def __getitem__(self, item): cls = type(self) if self.__type__ is not None: - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) param = typing._type_check( - item, '{} accepts only single type.'.format(cls.__name__[1:]) + item, "{} accepts only single type.".format(cls.__name__[1:]) ) return cls(self.__name__, self.__bases__, dict(self.__dict__), tp=param, _root=True) @@ -502,13 +506,17 @@ def _eval_type(self, globalns, localns): if new_tp == self.__type__: return self return type(self)( - self.__name__, self.__bases__, dict(self.__dict__), tp=self.__type__, _root=True + self.__name__, + self.__bases__, + dict(self.__dict__), + tp=self.__type__, + _root=True, ) def __repr__(self): r = super().__repr__() if self.__type__ is not None: - r += '[{}]'.format(typing._type_repr(self.__type__)) + r += "[{}]".format(typing._type_repr(self.__type__)) return r def __hash__(self): @@ -540,7 +548,7 @@ class FastConnector(Connection): __type__ = None -if hasattr(typing, 'final'): +if hasattr(typing, "final"): final = typing.final else: @@ -571,19 +579,19 @@ def IntVar(name): return TypeVar(name) -if hasattr(typing, 'Literal'): +if hasattr(typing, "Literal"): Literal = typing.Literal elif sys.version_info[:2] >= (3, 7): class _LiteralForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return "typing_extensions." + self._name def __getitem__(self, parameters): return _GenericAlias(self, parameters) Literal = _LiteralForm( - 'Literal', + "Literal", doc="""A type that can be used to indicate to type checkers that the corresponding value has a value literally equivalent to the provided parameter. For example: @@ -597,7 +605,7 @@ def __getitem__(self, parameters): checking verifying that the parameter is actually a value instead of a type.""", ) -elif hasattr(typing, '_FinalTypingBase'): +elif hasattr(typing, "_FinalTypingBase"): class _Literal(typing._FinalTypingBase, _root=True): """A type that can be used to indicate to type checkers that the @@ -613,7 +621,7 @@ class _Literal(typing._FinalTypingBase, _root=True): verifying that the parameter is actually a value instead of a type. """ - __slots__ = ('__values__',) + __slots__ = ("__values__",) def __init__(self, values=None, **kwds): self.__values__ = values @@ -624,7 +632,7 @@ def __getitem__(self, values): if not isinstance(values, tuple): values = (values,) return cls(values, _root=True) - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) def _eval_type(self, globalns, localns): return self @@ -632,7 +640,7 @@ def _eval_type(self, globalns, localns): def __repr__(self): r = super().__repr__() if self.__values__ is not None: - r += '[{}]'.format(', '.join(map(typing._type_repr, self.__values__))) + r += "[{}]".format(", ".join(map(typing._type_repr, self.__values__))) return r def __hash__(self): @@ -666,11 +674,17 @@ def __subclasscheck__(self, cls): def __getitem__(self, item): cls = type(self) if self.__values__ is not None: - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) if not isinstance(item, tuple): item = (item,) - return cls(self.__name__, self.__bases__, dict(self.__dict__), values=item, _root=True) + return cls( + self.__name__, + self.__bases__, + dict(self.__dict__), + values=item, + _root=True, + ) def _eval_type(self, globalns, localns): return self @@ -678,7 +692,7 @@ def _eval_type(self, globalns, localns): def __repr__(self): r = super().__repr__() if self.__values__ is not None: - r += '[{}]'.format(', '.join(map(typing._type_repr, self.__values__))) + r += "[{}]".format(", ".join(map(typing._type_repr, self.__values__))) return r def __hash__(self): @@ -748,11 +762,11 @@ def utf8(value): # This is not a real generic class. Don't use outside annotations. -if hasattr(typing, 'Type'): +if hasattr(typing, "Type"): Type = typing.Type else: # Internal type variable used for Type[]. - CT_co = typing.TypeVar('CT_co', covariant=True, bound=type) + CT_co = typing.TypeVar("CT_co", covariant=True, bound=type) class Type(typing.Generic[CT_co], extra=type): """A special construct usable to annotate class objects. @@ -812,7 +826,7 @@ def __subclasscheck__(self, subclass): """ if sys.version_info[:3] >= (3, 5, 3) or sys.version_info[:3] < (3, 5, 0): if self.__origin__ is not None: - if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']: + if sys._getframe(1).f_globals["__name__"] not in ["abc", "functools"]: raise TypeError( "Parameterized generics cannot be used with class or instance checks" ) @@ -832,15 +846,17 @@ def __subclasscheck__(self, subclass): return False -if _define_guard('Awaitable'): +if _define_guard("Awaitable"): class Awaitable( - typing.Generic[T_co], metaclass=_ExtensionsGenericMeta, extra=collections_abc.Awaitable + typing.Generic[T_co], + metaclass=_ExtensionsGenericMeta, + extra=collections_abc.Awaitable, ): __slots__ = () -if _define_guard('Coroutine'): +if _define_guard("Coroutine"): class Coroutine( Awaitable[V_co], @@ -851,23 +867,27 @@ class Coroutine( __slots__ = () -if _define_guard('AsyncIterable'): +if _define_guard("AsyncIterable"): class AsyncIterable( - typing.Generic[T_co], metaclass=_ExtensionsGenericMeta, extra=collections_abc.AsyncIterable + typing.Generic[T_co], + metaclass=_ExtensionsGenericMeta, + extra=collections_abc.AsyncIterable, ): __slots__ = () -if _define_guard('AsyncIterator'): +if _define_guard("AsyncIterator"): class AsyncIterator( - AsyncIterable[T_co], metaclass=_ExtensionsGenericMeta, extra=collections_abc.AsyncIterator + AsyncIterable[T_co], + metaclass=_ExtensionsGenericMeta, + extra=collections_abc.AsyncIterator, ): __slots__ = () -if hasattr(typing, 'Deque'): +if hasattr(typing, "Deque"): Deque = typing.Deque elif _geqv_defined: @@ -900,9 +920,9 @@ def __new__(cls, *args, **kwds): return _generic_new(collections.deque, cls, *args, **kwds) -if hasattr(typing, 'ContextManager'): +if hasattr(typing, "ContextManager"): ContextManager = typing.ContextManager -elif hasattr(contextlib, 'AbstractContextManager'): +elif hasattr(contextlib, "AbstractContextManager"): class ContextManager( typing.Generic[T_co], @@ -938,10 +958,10 @@ def __subclasshook__(cls, C): return NotImplemented -if hasattr(typing, 'AsyncContextManager'): +if hasattr(typing, "AsyncContextManager"): AsyncContextManager = typing.AsyncContextManager - __all__.append('AsyncContextManager') -elif hasattr(contextlib, 'AbstractAsyncContextManager'): + __all__.append("AsyncContextManager") +elif hasattr(contextlib, "AbstractAsyncContextManager"): class AsyncContextManager( typing.Generic[T_co], @@ -950,7 +970,7 @@ class AsyncContextManager( ): __slots__ = () - __all__.append('AsyncContextManager') + __all__.append("AsyncContextManager") elif sys.version_info[:2] >= (3, 5): exec( """ @@ -974,7 +994,7 @@ def __subclasshook__(cls, C): """ ) -if hasattr(typing, 'DefaultDict'): +if hasattr(typing, "DefaultDict"): DefaultDict = typing.DefaultDict elif _geqv_defined: @@ -1007,7 +1027,7 @@ def __new__(cls, *args, **kwds): return _generic_new(collections.defaultdict, cls, *args, **kwds) -if hasattr(typing, 'OrderedDict'): +if hasattr(typing, "OrderedDict"): OrderedDict = typing.OrderedDict elif (3, 7, 0) <= sys.version_info[:3] < (3, 7, 2): OrderedDict = typing._alias(collections.OrderedDict, (KT, VT)) @@ -1042,11 +1062,11 @@ def __new__(cls, *args, **kwds): return _generic_new(collections.OrderedDict, cls, *args, **kwds) -if hasattr(typing, 'Counter'): +if hasattr(typing, "Counter"): Counter = typing.Counter elif (3, 5, 0) <= sys.version_info[:3] <= (3, 5, 1): assert _geqv_defined - _TInt = typing.TypeVar('_TInt') + _TInt = typing.TypeVar("_TInt") class _CounterMeta(typing.GenericMeta): """Metaclass for Counter""" @@ -1055,7 +1075,10 @@ def __getitem__(self, item): return super().__getitem__((item, int)) class Counter( - collections.Counter, typing.Dict[T, int], metaclass=_CounterMeta, extra=collections.Counter + collections.Counter, + typing.Dict[T, int], + metaclass=_CounterMeta, + extra=collections.Counter, ): __slots__ = () @@ -1095,10 +1118,10 @@ def __new__(cls, *args, **kwds): return _generic_new(collections.Counter, cls, *args, **kwds) -if hasattr(typing, 'ChainMap'): +if hasattr(typing, "ChainMap"): ChainMap = typing.ChainMap - __all__.append('ChainMap') -elif hasattr(collections, 'ChainMap'): + __all__.append("ChainMap") +elif hasattr(collections, "ChainMap"): # ChainMap only exists in 3.3+ if _geqv_defined: @@ -1130,9 +1153,9 @@ def __new__(cls, *args, **kwds): return collections.ChainMap(*args, **kwds) return _generic_new(collections.ChainMap, cls, *args, **kwds) - __all__.append('ChainMap') + __all__.append("ChainMap") -if _define_guard('AsyncGenerator'): +if _define_guard("AsyncGenerator"): class AsyncGenerator( AsyncIterator[T_co], @@ -1143,7 +1166,7 @@ class AsyncGenerator( __slots__ = () -if hasattr(typing, 'NewType'): +if hasattr(typing, "NewType"): NewType = typing.NewType else: @@ -1174,12 +1197,12 @@ def new_type(x): return new_type -if hasattr(typing, 'Text'): +if hasattr(typing, "Text"): Text = typing.Text else: Text = str -if hasattr(typing, 'TYPE_CHECKING'): +if hasattr(typing, "TYPE_CHECKING"): TYPE_CHECKING = typing.TYPE_CHECKING else: # Constant that's True when type checking, but False here. @@ -1189,7 +1212,7 @@ def new_type(x): def _gorg(cls): """This function exists for compatibility with old typing versions.""" assert isinstance(cls, GenericMeta) - if hasattr(cls, '_gorg'): + if hasattr(cls, "_gorg"): return cls._gorg while cls.__origin__ is not None: cls = cls.__origin__ @@ -1208,51 +1231,51 @@ def _next_in_mro(cls): # noqa _PROTO_WHITELIST = [ - 'Callable', - 'Awaitable', - 'Iterable', - 'Iterator', - 'AsyncIterable', - 'AsyncIterator', - 'Hashable', - 'Sized', - 'Container', - 'Collection', - 'Reversible', - 'ContextManager', - 'AsyncContextManager', + "Callable", + "Awaitable", + "Iterable", + "Iterator", + "AsyncIterable", + "AsyncIterator", + "Hashable", + "Sized", + "Container", + "Collection", + "Reversible", + "ContextManager", + "AsyncContextManager", ] def _get_protocol_attrs(cls): attrs = set() for base in cls.__mro__[:-1]: # without object - if base.__name__ in ('Protocol', 'Generic'): + if base.__name__ in ("Protocol", "Generic"): continue - annotations = getattr(base, '__annotations__', {}) + annotations = getattr(base, "__annotations__", {}) for attr in list(base.__dict__.keys()) + list(annotations.keys()): - if not attr.startswith('_abc_') and attr not in ( - '__abstractmethods__', - '__annotations__', - '__weakref__', - '_is_protocol', - '_is_runtime_protocol', - '__dict__', - '__args__', - '__slots__', - '__next_in_mro__', - '__parameters__', - '__origin__', - '__orig_bases__', - '__extra__', - '__tree_hash__', - '__doc__', - '__subclasshook__', - '__init__', - '__new__', - '__module__', - '_MutableMapping__marker', - '_gorg', + if not attr.startswith("_abc_") and attr not in ( + "__abstractmethods__", + "__annotations__", + "__weakref__", + "_is_protocol", + "_is_runtime_protocol", + "__dict__", + "__args__", + "__slots__", + "__next_in_mro__", + "__parameters__", + "__origin__", + "__orig_bases__", + "__extra__", + "__tree_hash__", + "__doc__", + "__subclasshook__", + "__init__", + "__new__", + "__module__", + "_MutableMapping__marker", + "_gorg", ): attrs.add(attr) return attrs @@ -1262,13 +1285,13 @@ def _is_callable_members_only(cls): return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls)) -if hasattr(typing, 'Protocol'): +if hasattr(typing, "Protocol"): Protocol = typing.Protocol elif HAVE_PROTOCOLS and not PEP_560: def _no_init(self, *args, **kwargs): if type(self)._is_protocol: - raise TypeError('Protocols cannot be instantiated') + raise TypeError("Protocols cannot be instantiated") class _ProtocolMeta(GenericMeta): """Internal metaclass for Protocol. @@ -1338,9 +1361,9 @@ def __new__( bases = tuple(_gorg(b) if isinstance(b, GenericMeta) else b for b in bases) if any(isinstance(b, GenericMeta) and b is not Generic for b in bases): bases = tuple(b for b in bases if b is not Generic) - namespace.update({'__origin__': origin, '__extra__': extra}) + namespace.update({"__origin__": origin, "__extra__": extra}) self = super(GenericMeta, cls).__new__(cls, name, bases, namespace, _root=True) - super(GenericMeta, self).__setattr__('_gorg', self if not origin else _gorg(origin)) + super(GenericMeta, self).__setattr__("_gorg", self if not origin else _gorg(origin)) self.__parameters__ = tvars self.__args__ = ( tuple( @@ -1356,7 +1379,7 @@ def __new__( elif origin is not None: self._abc_registry = origin._abc_registry self._abc_cache = origin._abc_cache - if hasattr(self, '_subs_tree'): + if hasattr(self, "_subs_tree"): self.__tree_hash__ = ( hash(self._subs_tree()) if origin else super(GenericMeta, self).__hash__() ) @@ -1364,7 +1387,7 @@ def __new__( def __init__(cls, *args, **kwargs): super().__init__(*args, **kwargs) - if not cls.__dict__.get('_is_protocol', None): + if not cls.__dict__.get("_is_protocol", None): cls._is_protocol = any( b is Protocol or isinstance(b, _ProtocolMeta) and b.__origin__ is Protocol for b in cls.__bases__ @@ -1373,7 +1396,7 @@ def __init__(cls, *args, **kwargs): for base in cls.__mro__[1:]: if not ( base in (object, Generic) - or base.__module__ == 'collections.abc' + or base.__module__ == "collections.abc" and base.__name__ in _PROTO_WHITELIST or isinstance(base, TypingMeta) and base._is_protocol @@ -1381,24 +1404,24 @@ def __init__(cls, *args, **kwargs): and base.__origin__ is Generic ): raise TypeError( - 'Protocols can only inherit from other protocols, got %r' % base + "Protocols can only inherit from other protocols, got %r" % base ) cls.__init__ = _no_init def _proto_hook(other): - if not cls.__dict__.get('_is_protocol', None): + if not cls.__dict__.get("_is_protocol", None): return NotImplemented if not isinstance(other, type): # Same error as for issubclass(1, int) - raise TypeError('issubclass() arg 1 must be a class') + raise TypeError("issubclass() arg 1 must be a class") for attr in _get_protocol_attrs(cls): for base in other.__mro__: if attr in base.__dict__: if base.__dict__[attr] is None: return NotImplemented break - annotations = getattr(base, '__annotations__', {}) + annotations = getattr(base, "__annotations__", {}) if ( isinstance(annotations, typing.Mapping) and attr in annotations @@ -1410,14 +1433,14 @@ def _proto_hook(other): return NotImplemented return True - if '__subclasshook__' not in cls.__dict__: + if "__subclasshook__" not in cls.__dict__: cls.__subclasshook__ = _proto_hook def __instancecheck__(self, instance): # We need this method for situations where attributes are # assigned in __init__. if ( - not getattr(self, '_is_protocol', False) or _is_callable_members_only(self) + not getattr(self, "_is_protocol", False) or _is_callable_members_only(self) ) and issubclass(instance.__class__, self): return True if self._is_protocol: @@ -1434,23 +1457,31 @@ def __instancecheck__(self, instance): def __subclasscheck__(self, cls): if self.__origin__ is not None: - if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']: + if sys._getframe(1).f_globals["__name__"] not in ["abc", "functools"]: raise TypeError( "Parameterized generics cannot be used with class or instance checks" ) return False - if self.__dict__.get('_is_protocol', None) and not self.__dict__.get( - '_is_runtime_protocol', None + if self.__dict__.get("_is_protocol", None) and not self.__dict__.get( + "_is_runtime_protocol", None ): - if sys._getframe(1).f_globals['__name__'] in ['abc', 'functools', 'typing']: + if sys._getframe(1).f_globals["__name__"] in [ + "abc", + "functools", + "typing", + ]: return False raise TypeError( "Instance and class checks can only be used with @runtime protocols" ) - if self.__dict__.get('_is_runtime_protocol', None) and not _is_callable_members_only( + if self.__dict__.get("_is_runtime_protocol", None) and not _is_callable_members_only( self ): - if sys._getframe(1).f_globals['__name__'] in ['abc', 'functools', 'typing']: + if sys._getframe(1).f_globals["__name__"] in [ + "abc", + "functools", + "typing", + ]: return super(GenericMeta, self).__subclasscheck__(cls) raise TypeError("Protocols with non-method members don't support issubclass()") return super(GenericMeta, self).__subclasscheck__(cls) @@ -1548,7 +1579,7 @@ def __new__(cls, *args, **kwds): def _no_init(self, *args, **kwargs): if type(self)._is_protocol: - raise TypeError('Protocols cannot be instantiated') + raise TypeError("Protocols cannot be instantiated") class _ProtocolMeta(abc.ABCMeta): # This metaclass is a bit unfortunate and exists only because of the lack @@ -1557,7 +1588,7 @@ def __instancecheck__(cls, instance): # We need this method for situations where attributes are # assigned in __init__. if ( - not getattr(cls, '_is_protocol', False) or _is_callable_members_only(cls) + not getattr(cls, "_is_protocol", False) or _is_callable_members_only(cls) ) and issubclass(instance.__class__, cls): return True if cls._is_protocol: @@ -1604,6 +1635,7 @@ class GenProto(Protocol[T]): def meth(self) -> T: ... """ + __slots__ = () _is_protocol = True @@ -1643,13 +1675,13 @@ def __class_getitem__(cls, params): def __init_subclass__(cls, *args, **kwargs): tvars = [] - if '__orig_bases__' in cls.__dict__: + if "__orig_bases__" in cls.__dict__: error = Generic in cls.__orig_bases__ else: error = Generic in cls.__bases__ if error: raise TypeError("Cannot inherit from plain Generic") - if '__orig_bases__' in cls.__dict__: + if "__orig_bases__" in cls.__dict__: tvars = _collect_type_vars(cls.__orig_bases__) # Look for Generic[T1, ..., Tn] or Protocol[T1, ..., Tn]. # If found, tvars must be a subset of it. @@ -1658,9 +1690,12 @@ def __init_subclass__(cls, *args, **kwargs): # and reject multiple Generic[...] and/or Protocol[...]. gvars = None for base in cls.__orig_bases__: - if isinstance(base, _GenericAlias) and base.__origin__ in (Generic, Protocol): + if isinstance(base, _GenericAlias) and base.__origin__ in ( + Generic, + Protocol, + ): # for error messages - the_base = 'Generic' if base.__origin__ is Generic else 'Protocol' + the_base = "Generic" if base.__origin__ is Generic else "Protocol" if gvars is not None: raise TypeError( "Cannot inherit from Generic[...]" @@ -1673,8 +1708,8 @@ def __init_subclass__(cls, *args, **kwargs): tvarset = set(tvars) gvarset = set(gvars) if not tvarset <= gvarset: - s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) - s_args = ', '.join(str(g) for g in gvars) + s_vars = ", ".join(str(t) for t in tvars if t not in gvarset) + s_args = ", ".join(str(g) for g in gvars) raise TypeError( "Some type variables ({}) are not listed in {}[{}]".format( s_vars, the_base, s_args @@ -1684,33 +1719,33 @@ def __init_subclass__(cls, *args, **kwargs): cls.__parameters__ = tuple(tvars) # Determine if this is a protocol or a concrete subclass. - if not cls.__dict__.get('_is_protocol', None): + if not cls.__dict__.get("_is_protocol", None): cls._is_protocol = any(b is Protocol for b in cls.__bases__) # Set (or override) the protocol subclass hook. def _proto_hook(other): - if not cls.__dict__.get('_is_protocol', None): + if not cls.__dict__.get("_is_protocol", None): return NotImplemented - if not getattr(cls, '_is_runtime_protocol', False): - if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']: + if not getattr(cls, "_is_runtime_protocol", False): + if sys._getframe(2).f_globals["__name__"] in ["abc", "functools"]: return NotImplemented raise TypeError( "Instance and class checks can only be used with @runtime protocols" ) if not _is_callable_members_only(cls): - if sys._getframe(2).f_globals['__name__'] in ['abc', 'functools']: + if sys._getframe(2).f_globals["__name__"] in ["abc", "functools"]: return NotImplemented raise TypeError("Protocols with non-method members don't support issubclass()") if not isinstance(other, type): # Same error as for issubclass(1, int) - raise TypeError('issubclass() arg 1 must be a class') + raise TypeError("issubclass() arg 1 must be a class") for attr in _get_protocol_attrs(cls): for base in other.__mro__: if attr in base.__dict__: if base.__dict__[attr] is None: return NotImplemented break - annotations = getattr(base, '__annotations__', {}) + annotations = getattr(base, "__annotations__", {}) if ( isinstance(annotations, typing.Mapping) and attr in annotations @@ -1722,7 +1757,7 @@ def _proto_hook(other): return NotImplemented return True - if '__subclasshook__' not in cls.__dict__: + if "__subclasshook__" not in cls.__dict__: cls.__subclasshook__ = _proto_hook # We have nothing more to do for non-protocols. @@ -1733,18 +1768,18 @@ def _proto_hook(other): for base in cls.__bases__: if not ( base in (object, Generic) - or base.__module__ == 'collections.abc' + or base.__module__ == "collections.abc" and base.__name__ in _PROTO_WHITELIST or isinstance(base, _ProtocolMeta) and base._is_protocol ): raise TypeError( - 'Protocols can only inherit from other protocols, got %r' % base + "Protocols can only inherit from other protocols, got %r" % base ) cls.__init__ = _no_init -if hasattr(typing, 'runtime_checkable'): +if hasattr(typing, "runtime_checkable"): runtime_checkable = typing.runtime_checkable elif HAVE_PROTOCOLS: @@ -1758,7 +1793,7 @@ def runtime_checkable(cls): """ if not isinstance(cls, _ProtocolMeta) or not cls._is_protocol: raise TypeError( - '@runtime_checkable can be only applied to protocol classes, got %r' % cls + "@runtime_checkable can be only applied to protocol classes, got %r" % cls ) cls._is_runtime_protocol = True return cls @@ -1768,7 +1803,7 @@ def runtime_checkable(cls): # Exists for backwards compatibility. runtime = runtime_checkable -if hasattr(typing, 'SupportsIndex'): +if hasattr(typing, "SupportsIndex"): SupportsIndex = typing.SupportsIndex elif HAVE_PROTOCOLS: @@ -1791,29 +1826,36 @@ def __index__(self) -> int: def _check_fails(cls, other): try: - if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools', 'typing']: + if sys._getframe(1).f_globals["__name__"] not in [ + "abc", + "functools", + "typing", + ]: # Typed dicts are only for static structural subtyping. - raise TypeError('TypedDict does not support instance and class checks') + raise TypeError("TypedDict does not support instance and class checks") except (AttributeError, ValueError): pass return False def _dict_new(*args, **kwargs): if not args: - raise TypeError('TypedDict.__new__(): not enough arguments') + raise TypeError("TypedDict.__new__(): not enough arguments") _, args = args[0], args[1:] # allow the "cls" keyword be passed return dict(*args, **kwargs) - _dict_new.__text_signature__ = '($cls, _typename, _fields=None, /, **kwargs)' + _dict_new.__text_signature__ = "($cls, _typename, _fields=None, /, **kwargs)" def _typeddict_new(*args, total=True, **kwargs): if not args: - raise TypeError('TypedDict.__new__(): not enough arguments') + raise TypeError("TypedDict.__new__(): not enough arguments") _, args = args[0], args[1:] # allow the "cls" keyword be passed if args: - typename, args = args[0], args[1:] # allow the "_typename" keyword be passed - elif '_typename' in kwargs: - typename = kwargs.pop('_typename') + typename, args = ( + args[0], + args[1:], + ) # allow the "_typename" keyword be passed + elif "_typename" in kwargs: + typename = kwargs.pop("_typename") import warnings warnings.warn( @@ -1830,12 +1872,12 @@ def _typeddict_new(*args, total=True, **kwargs): (fields,) = args # allow the "_fields" keyword be passed except ValueError: raise TypeError( - 'TypedDict.__new__() takes from 2 to 3 ' - 'positional arguments but {} ' - 'were given'.format(len(args) + 2) + "TypedDict.__new__() takes from 2 to 3 " + "positional arguments but {} " + "were given".format(len(args) + 2) ) - elif '_fields' in kwargs and len(kwargs) == 1: - fields = kwargs.pop('_fields') + elif "_fields" in kwargs and len(kwargs) == 1: + fields = kwargs.pop("_fields") import warnings warnings.warn( @@ -1851,17 +1893,17 @@ def _typeddict_new(*args, total=True, **kwargs): elif kwargs: raise TypeError("TypedDict takes either a dict or keyword arguments, but not both") - ns = {'__annotations__': dict(fields)} + ns = {"__annotations__": dict(fields)} try: # Setting correct module is necessary to make typed dict classes pickleable. - ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__') + ns["__module__"] = sys._getframe(1).f_globals.get("__name__", "__main__") except (AttributeError, ValueError): pass return _TypedDictMeta(typename, (), ns, total=total) _typeddict_new.__text_signature__ = ( - '($cls, _typename, _fields=None, /, *, total=True, **kwargs)' + "($cls, _typename, _fields=None, /, *, total=True, **kwargs)" ) class _TypedDictMeta(type): @@ -1877,11 +1919,11 @@ def __new__(cls, name, bases, ns, total=True): # TypedDict supports all three syntaxes described in its docstring. # Subclasses and instances of TypedDict return actual dictionaries # via _dict_new. - ns['__new__'] = _typeddict_new if name == 'TypedDict' else _dict_new + ns["__new__"] = _typeddict_new if name == "TypedDict" else _dict_new tp_dict = super(_TypedDictMeta, cls).__new__(cls, name, (dict,), ns) annotations = {} - own_annotations = ns.get('__annotations__', {}) + own_annotations = ns.get("__annotations__", {}) own_annotation_keys = set(own_annotations.keys()) msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" own_annotations = {n: typing._type_check(tp, msg) for n, tp in own_annotations.items()} @@ -1889,9 +1931,9 @@ def __new__(cls, name, bases, ns, total=True): optional_keys = set() for base in bases: - annotations.update(base.__dict__.get('__annotations__', {})) - required_keys.update(base.__dict__.get('__required_keys__', ())) - optional_keys.update(base.__dict__.get('__optional_keys__', ())) + annotations.update(base.__dict__.get("__annotations__", {})) + required_keys.update(base.__dict__.get("__required_keys__", ())) + optional_keys.update(base.__dict__.get("__optional_keys__", ())) annotations.update(own_annotations) if total: @@ -1902,13 +1944,13 @@ def __new__(cls, name, bases, ns, total=True): tp_dict.__annotations__ = annotations tp_dict.__required_keys__ = frozenset(required_keys) tp_dict.__optional_keys__ = frozenset(optional_keys) - if not hasattr(tp_dict, '__total__'): + if not hasattr(tp_dict, "__total__"): tp_dict.__total__ = total return tp_dict __instancecheck__ = __subclasscheck__ = _check_fails - TypedDict = _TypedDictMeta('TypedDict', (dict,), {}) + TypedDict = _TypedDictMeta("TypedDict", (dict,), {}) TypedDict.__module__ = __name__ TypedDict.__doc__ = """A simple typed name space. At runtime it is equivalent to a plain dict. @@ -1940,7 +1982,7 @@ class Point2D(TypedDict): """ # Python 3.9+ has PEP 593 (Annotated and modified get_type_hints) -if hasattr(typing, 'Annotated'): +if hasattr(typing, "Annotated"): Annotated = typing.Annotated get_type_hints = typing.get_type_hints # Not exported and not a public API, but needed for get_origin() and get_args() @@ -1971,7 +2013,8 @@ def copy_with(self, params): def __repr__(self): return "typing_extensions.Annotated[{}, {}]".format( - typing._type_repr(self.__origin__), ", ".join(repr(a) for a in self.__metadata__) + typing._type_repr(self.__origin__), + ", ".join(repr(a) for a in self.__metadata__), ) def __reduce__(self): @@ -2094,7 +2137,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): def _is_dunder(name): """Returns True if name is a __dunder_variable_name__.""" - return len(name) > 4 and name.startswith('__') and name.endswith('__') + return len(name) > 4 and name.startswith("__") and name.endswith("__") # Prior to Python 3.7 types did not have `copy_with`. A lot of the equality # checks, argument expansion etc. are done on the _subs_tree. As a result we @@ -2119,7 +2162,7 @@ def _tree_repr(self, tree): else: tp_repr = origin[0]._tree_repr(origin) metadata_reprs = ", ".join(repr(arg) for arg in metadata) - return '%s[%s, %s]' % (cls, tp_repr, metadata_reprs) + return "%s[%s, %s]" % (cls, tp_repr, metadata_reprs) def _subs_tree(self, tvars=None, args=None): # noqa if self is Annotated: @@ -2188,7 +2231,7 @@ def __getattr__(self, attr): raise AttributeError(attr) def __setattr__(self, attr, value): - if _is_dunder(attr) or attr.startswith('_abc_'): + if _is_dunder(attr) or attr.startswith("_abc_"): super().__setattr__(attr, value) elif self.__origin__ is None: raise AttributeError(attr) @@ -2273,7 +2316,14 @@ def get_origin(tp): if isinstance(tp, _AnnotatedAlias): return Annotated if isinstance( - tp, (_GenericAlias, GenericAlias, _BaseGenericAlias, ParamSpecArgs, ParamSpecKwargs) + tp, + ( + _GenericAlias, + GenericAlias, + _BaseGenericAlias, + ParamSpecArgs, + ParamSpecKwargs, + ), ): return tp.__origin__ if tp is Generic: @@ -2303,13 +2353,13 @@ def get_args(tp): return () -if hasattr(typing, 'TypeAlias'): +if hasattr(typing, "TypeAlias"): TypeAlias = typing.TypeAlias elif sys.version_info[:2] >= (3, 9): class _TypeAliasForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return "typing_extensions." + self._name @_TypeAliasForm def TypeAlias(self, parameters): @@ -2329,10 +2379,10 @@ def TypeAlias(self, parameters): class _TypeAliasForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return "typing_extensions." + self._name TypeAlias = _TypeAliasForm( - 'TypeAlias', + "TypeAlias", doc="""Special marker indicating that an assignment should be recognized as a proper type alias definition by type checkers. @@ -2345,13 +2395,13 @@ def __repr__(self): above.""", ) -elif hasattr(typing, '_FinalTypingBase'): +elif hasattr(typing, "_FinalTypingBase"): class _TypeAliasMeta(typing.TypingMeta): """Metaclass for TypeAlias""" def __repr__(self): - return 'typing_extensions.TypeAlias' + return "typing_extensions.TypeAlias" class _TypeAliasBase(typing._FinalTypingBase, metaclass=_TypeAliasMeta, _root=True): """Special marker indicating that an assignment should @@ -2374,7 +2424,7 @@ def __subclasscheck__(self, cls): raise TypeError("TypeAlias cannot be used with issubclass().") def __repr__(self): - return 'typing_extensions.TypeAlias' + return "typing_extensions.TypeAlias" TypeAlias = _TypeAliasBase(_root=True) else: @@ -2407,7 +2457,7 @@ class TypeAlias(metaclass=_TypeAliasMeta, _root=True): # Python 3.10+ has PEP 612 -if hasattr(typing, 'ParamSpecArgs'): +if hasattr(typing, "ParamSpecArgs"): ParamSpecArgs = typing.ParamSpecArgs ParamSpecKwargs = typing.ParamSpecKwargs else: @@ -2462,7 +2512,7 @@ def __repr__(self): return "{}.kwargs".format(self.__origin__.__name__) -if hasattr(typing, 'ParamSpec'): +if hasattr(typing, "ParamSpec"): ParamSpec = typing.ParamSpec else: # Inherits from list as a workaround for Callable checks in Python < 3.9.2. @@ -2530,25 +2580,25 @@ def __init__(self, name, *, bound=None, covariant=False, contravariant=False): self.__covariant__ = bool(covariant) self.__contravariant__ = bool(contravariant) if bound: - self.__bound__ = typing._type_check(bound, 'Bound must be a type.') + self.__bound__ = typing._type_check(bound, "Bound must be a type.") else: self.__bound__ = None # for pickling: try: - def_mod = sys._getframe(1).f_globals.get('__name__', '__main__') + def_mod = sys._getframe(1).f_globals.get("__name__", "__main__") except (AttributeError, ValueError): def_mod = None - if def_mod != 'typing_extensions': + if def_mod != "typing_extensions": self.__module__ = def_mod def __repr__(self): if self.__covariant__: - prefix = '+' + prefix = "+" elif self.__contravariant__: - prefix = '-' + prefix = "-" else: - prefix = '~' + prefix = "~" return prefix + self.__name__ def __hash__(self): @@ -2596,9 +2646,9 @@ def __init__(self, origin, args): def __repr__(self): _type_repr = typing._type_repr - return '{origin}[{args}]'.format( + return "{origin}[{args}]".format( origin=_type_repr(self.__origin__), - args=', '.join(_type_repr(arg) for arg in self.__args__), + args=", ".join(_type_repr(arg) for arg in self.__args__), ) def __hash__(self): @@ -2632,7 +2682,7 @@ def _concatenate_getitem(self, parameters): return _ConcatenateGenericAlias(self, parameters) -if hasattr(typing, 'Concatenate'): +if hasattr(typing, "Concatenate"): Concatenate = typing.Concatenate _ConcatenateGenericAlias = typing._ConcatenateGenericAlias # noqa elif sys.version_info[:2] >= (3, 9): @@ -2655,13 +2705,13 @@ def Concatenate(self, parameters): class _ConcatenateForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return "typing_extensions." + self._name def __getitem__(self, parameters): return _concatenate_getitem(self, parameters) Concatenate = _ConcatenateForm( - 'Concatenate', + "Concatenate", doc="""Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a higher order function which adds, removes or transforms parameters of a callable. @@ -2674,13 +2724,13 @@ def __getitem__(self, parameters): """, ) -elif hasattr(typing, '_FinalTypingBase'): +elif hasattr(typing, "_FinalTypingBase"): class _ConcatenateAliasMeta(typing.TypingMeta): """Metaclass for Concatenate.""" def __repr__(self): - return 'typing_extensions.Concatenate' + return "typing_extensions.Concatenate" class _ConcatenateAliasBase( typing._FinalTypingBase, metaclass=_ConcatenateAliasMeta, _root=True @@ -2705,7 +2755,7 @@ def __subclasscheck__(self, cls): raise TypeError("Concatenate cannot be used with issubclass().") def __repr__(self): - return 'typing_extensions.Concatenate' + return "typing_extensions.Concatenate" def __getitem__(self, parameters): return _concatenate_getitem(self, parameters) @@ -2744,13 +2794,13 @@ class Concatenate(metaclass=_ConcatenateAliasMeta, _root=True): __slots__ = () -if hasattr(typing, 'TypeGuard'): +if hasattr(typing, "TypeGuard"): TypeGuard = typing.TypeGuard elif sys.version_info[:2] >= (3, 9): class _TypeGuardForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return "typing_extensions." + self._name @_TypeGuardForm def TypeGuard(self, parameters): @@ -2796,23 +2846,23 @@ def is_str(val: Union[str, float]): ``TypeGuard`` also works with type variables. For more information, see PEP 647 (User-Defined Type Guards). """ - item = typing._type_check(parameters, '{} accepts only single type.'.format(self)) + item = typing._type_check(parameters, "{} accepts only single type.".format(self)) return _GenericAlias(self, (item,)) elif sys.version_info[:2] >= (3, 7): class _TypeGuardForm(typing._SpecialForm, _root=True): def __repr__(self): - return 'typing_extensions.' + self._name + return "typing_extensions." + self._name def __getitem__(self, parameters): item = typing._type_check( - parameters, '{} accepts only a single type'.format(self._name) + parameters, "{} accepts only a single type".format(self._name) ) return _GenericAlias(self, (item,)) TypeGuard = _TypeGuardForm( - 'TypeGuard', + "TypeGuard", doc="""Special typing form used to annotate the return type of a user-defined type guard function. ``TypeGuard`` only accepts a single type argument. At runtime, functions marked this way should return a boolean. @@ -2856,7 +2906,7 @@ def is_str(val: Union[str, float]): PEP 647 (User-Defined Type Guards). """, ) -elif hasattr(typing, '_FinalTypingBase'): +elif hasattr(typing, "_FinalTypingBase"): class _TypeGuard(typing._FinalTypingBase, _root=True): """Special typing form used to annotate the return type of a user-defined @@ -2902,7 +2952,7 @@ def is_str(val: Union[str, float]): PEP 647 (User-Defined Type Guards). """ - __slots__ = ('__type__',) + __slots__ = ("__type__",) def __init__(self, tp=None, **kwds): self.__type__ = tp @@ -2912,11 +2962,11 @@ def __getitem__(self, item): if self.__type__ is None: return cls( typing._type_check( - item, '{} accepts only a single type.'.format(cls.__name__[1:]) + item, "{} accepts only a single type.".format(cls.__name__[1:]) ), _root=True, ) - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) def _eval_type(self, globalns, localns): new_tp = typing._eval_type(self.__type__, globalns, localns) @@ -2927,7 +2977,7 @@ def _eval_type(self, globalns, localns): def __repr__(self): r = super().__repr__() if self.__type__ is not None: - r += '[{}]'.format(typing._type_repr(self.__type__)) + r += "[{}]".format(typing._type_repr(self.__type__)) return r def __hash__(self): @@ -2961,10 +3011,10 @@ def __subclasscheck__(self, cls): def __getitem__(self, item): cls = type(self) if self.__type__ is not None: - raise TypeError('{} cannot be further subscripted'.format(cls.__name__[1:])) + raise TypeError("{} cannot be further subscripted".format(cls.__name__[1:])) param = typing._type_check( - item, '{} accepts only single type.'.format(cls.__name__[1:]) + item, "{} accepts only single type.".format(cls.__name__[1:]) ) return cls(self.__name__, self.__bases__, dict(self.__dict__), tp=param, _root=True) @@ -2973,13 +3023,17 @@ def _eval_type(self, globalns, localns): if new_tp == self.__type__: return self return type(self)( - self.__name__, self.__bases__, dict(self.__dict__), tp=self.__type__, _root=True + self.__name__, + self.__bases__, + dict(self.__dict__), + tp=self.__type__, + _root=True, ) def __repr__(self): r = super().__repr__() if self.__type__ is not None: - r += '[{}]'.format(typing._type_repr(self.__type__)) + r += "[{}]".format(typing._type_repr(self.__type__)) return r def __hash__(self): diff --git a/podman/api/uds.py b/podman/api/uds.py index 0f512610..13ae5b18 100644 --- a/podman/api/uds.py +++ b/podman/api/uds.py @@ -10,7 +10,12 @@ import urllib3 import urllib3.connection -from requests.adapters import DEFAULT_POOLBLOCK, DEFAULT_POOLSIZE, DEFAULT_RETRIES, HTTPAdapter +from requests.adapters import ( + DEFAULT_POOLBLOCK, + DEFAULT_POOLSIZE, + DEFAULT_RETRIES, + HTTPAdapter, +) from ..errors import APIError diff --git a/podman/client.py b/podman/client.py index 5785f6b9..7f02ed2c 100644 --- a/podman/client.py +++ b/podman/client.py @@ -123,16 +123,16 @@ def from_env( version = None kwargs = { - 'version': version, - 'timeout': timeout, - 'tls': False, - 'credstore_env': credstore_env, - 'max_pool_size': max_pool_size, + "version": version, + "timeout": timeout, + "tls": False, + "credstore_env": credstore_env, + "max_pool_size": max_pool_size, } host = environment.get("CONTAINER_HOST") or environment.get("DOCKER_HOST") or None if host is not None: - kwargs['base_url'] = host + kwargs["base_url"] = host return PodmanClient(**kwargs) diff --git a/podman/domain/config.py b/podman/domain/config.py index f683d446..20a857e6 100644 --- a/podman/domain/config.py +++ b/podman/domain/config.py @@ -74,7 +74,7 @@ def __init__(self, path: Optional[str] = None): self.is_default = True # this elif is only for testing purposes elif "@@is_test@@" in path: - test_path = path.replace("@@is_test@@", '') + test_path = path.replace("@@is_test@@", "") self.path = Path(test_path) / "podman-connections.json" old_toml_file = Path(test_path) / "containers.conf" self.is_default = True @@ -85,13 +85,13 @@ def __init__(self, path: Optional[str] = None): self.attrs = {} if self.path.exists(): try: - with open(self.path, encoding='utf-8') as file: + with open(self.path, encoding="utf-8") as file: self.attrs = json.load(file) except: # pylint: disable=bare-except # if the user specifies a path, it can either be a JSON file # or a TOML file - so try TOML next try: - with self.path.open(encoding='utf-8') as file: + with self.path.open(encoding="utf-8") as file: buffer = file.read() loaded_toml = toml_loads(buffer) self.attrs.update(loaded_toml) @@ -102,7 +102,7 @@ def __init__(self, path: Optional[str] = None): # Read the old toml file configuration if self.is_default and old_toml_file.exists(): - with old_toml_file.open(encoding='utf-8') as file: + with old_toml_file.open(encoding="utf-8") as file: buffer = file.read() loaded_toml = toml_loads(buffer) self.attrs.update(loaded_toml) diff --git a/podman/domain/containers.py b/podman/domain/containers.py index c99ed926..c1040667 100644 --- a/podman/domain/containers.py +++ b/podman/domain/containers.py @@ -25,7 +25,7 @@ class Container(PodmanResource): def name(self): """str: Returns container's name.""" with suppress(KeyError): - if 'Name' in self.attrs: + if "Name" in self.attrs: return self.attrs["Name"].lstrip("/") return self.attrs["Names"][0].lstrip("/") return None @@ -148,7 +148,8 @@ def exec_run( workdir: str = None, demux: bool = False, ) -> Tuple[ - Optional[int], Union[Iterator[Union[bytes, Tuple[bytes, bytes]]], Any, Tuple[bytes, bytes]] + Optional[int], + Union[Iterator[Union[bytes, Tuple[bytes, bytes]]], Any, Tuple[bytes, bytes]], ]: """Run given command inside container and return results. @@ -206,10 +207,12 @@ def exec_run( # create the exec instance response = self.client.post(f"/containers/{self.name}/exec", data=json.dumps(data)) response.raise_for_status() - exec_id = response.json()['Id'] + exec_id = response.json()["Id"] # start the exec instance, this will store command output start_resp = self.client.post( - f"/exec/{exec_id}/start", data=json.dumps({"Detach": detach, "Tty": tty}), stream=stream + f"/exec/{exec_id}/start", + data=json.dumps({"Detach": detach, "Tty": tty}), + stream=stream, ) start_resp.raise_for_status() @@ -221,8 +224,8 @@ def exec_run( response.raise_for_status() if demux: stdout_data, stderr_data = demux_output(start_resp.content) - return response.json().get('ExitCode'), (stdout_data, stderr_data) - return response.json().get('ExitCode'), start_resp.content + return response.json().get("ExitCode"), (stdout_data, stderr_data) + return response.json().get("ExitCode"), start_resp.content def export(self, chunk_size: int = api.DEFAULT_CHUNK_SIZE) -> Iterator[bytes]: """Download container's filesystem contents as a tar archive. @@ -407,7 +410,8 @@ def start(self, **kwargs) -> None: detach_keys: Override the key sequence for detaching a container (Podman only) """ response = self.client.post( - f"/containers/{self.id}/start", params={"detachKeys": kwargs.get("detach_keys")} + f"/containers/{self.id}/start", + params={"detachKeys": kwargs.get("detach_keys")}, ) response.raise_for_status() diff --git a/podman/domain/containers_create.py b/podman/domain/containers_create.py index b6b1fadd..5fbe3729 100644 --- a/podman/domain/containers_create.py +++ b/podman/domain/containers_create.py @@ -16,14 +16,17 @@ logger = logging.getLogger("podman.containers") -NAMED_VOLUME_PATTERN = re.compile(r'[a-zA-Z0-9][a-zA-Z0-9_.-]*') +NAMED_VOLUME_PATTERN = re.compile(r"[a-zA-Z0-9][a-zA-Z0-9_.-]*") class CreateMixin: # pylint: disable=too-few-public-methods """Class providing create method for ContainersManager.""" def create( - self, image: Union[Image, str], command: Union[str, List[str], None] = None, **kwargs + self, + image: Union[Image, str], + command: Union[str, List[str], None] = None, + **kwargs, ) -> Container: """Create a container. @@ -351,7 +354,9 @@ def create( payload = api.prepare_body(payload) response = self.client.post( - "/containers/create", headers={"content-type": "application/json"}, data=payload + "/containers/create", + headers={"content-type": "application/json"}, + data=payload, ) response.raise_for_status(not_found=ImageNotFound) @@ -435,9 +440,9 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]: try: return int(size) except ValueError as bad_size: - mapping = {'b': 0, 'k': 1, 'm': 2, 'g': 3} - mapping_regex = ''.join(mapping.keys()) - search = re.search(rf'^(\d+)([{mapping_regex}])$', size.lower()) + mapping = {"b": 0, "k": 1, "m": 2, "g": 3} + mapping_regex = "".join(mapping.keys()) + search = re.search(rf"^(\d+)([{mapping_regex}])$", size.lower()) if search: return int(search.group(1)) * (1024 ** mapping[search.group(2)]) raise TypeError( @@ -574,7 +579,7 @@ def to_bytes(size: Union[int, str, None]) -> Union[int, None]: if k in bool_options and v is True: options.append(option_name) elif k in regular_options: - options.append(f'{option_name}={v}') + options.append(f"{option_name}={v}") elif k in simple_options: options.append(v) @@ -674,12 +679,12 @@ def parse_host_port(_container_port, _protocol, _host): for item in args.pop("volumes", {}).items(): key, value = item - extended_mode = value.get('extended_mode', []) + extended_mode = value.get("extended_mode", []) if not isinstance(extended_mode, list): raise ValueError("'extended_mode' value should be a list") options = extended_mode - mode = value.get('mode') + mode = value.get("mode") if mode is not None: if not isinstance(mode, str): raise ValueError("'mode' value should be a str") @@ -694,10 +699,10 @@ def parse_host_port(_container_port, _protocol, _host): params["volumes"].append(volume) else: mount_point = { - "destination": value['bind'], + "destination": value["bind"], "options": options, "source": key, - "type": 'bind', + "type": "bind", } params["mounts"].append(mount_point) diff --git a/podman/domain/containers_manager.py b/podman/domain/containers_manager.py index b204e877..aeb1d732 100644 --- a/podman/domain/containers_manager.py +++ b/podman/domain/containers_manager.py @@ -140,7 +140,11 @@ def remove(self, container_id: Union[Container, str], **kwargs): container_id = container_id.id # v is used for the compat endpoint while volumes is used for the libpod endpoint - params = {"v": kwargs.get("v"), "force": kwargs.get("force"), "volumes": kwargs.get("v")} + params = { + "v": kwargs.get("v"), + "force": kwargs.get("force"), + "volumes": kwargs.get("v"), + } response = self.client.delete(f"/containers/{container_id}", params=params) response.raise_for_status() diff --git a/podman/domain/images_build.py b/podman/domain/images_build.py index 84de5d5b..15f8362b 100644 --- a/podman/domain/images_build.py +++ b/podman/domain/images_build.py @@ -85,7 +85,7 @@ def build(self, **kwargs) -> Tuple[Image, Iterator[bytes]]: path = tempfile.TemporaryDirectory() # pylint: disable=consider-using-with filename = pathlib.Path(path.name) / params["dockerfile"] - with open(filename, "w", encoding='utf-8') as file: + with open(filename, "w", encoding="utf-8") as file: shutil.copyfileobj(kwargs["fileobj"], file) body = api.create_tar(anchor=path.name, gzip=kwargs.get("gzip", False)) elif "path" in kwargs: diff --git a/podman/domain/images_manager.py b/podman/domain/images_manager.py index e19478c3..c1d3d198 100644 --- a/podman/domain/images_manager.py +++ b/podman/domain/images_manager.py @@ -152,7 +152,9 @@ def load( # Make the client request before entering the generator response = self.client.post( - "/images/load", data=post_data, headers={"Content-type": "application/x-tar"} + "/images/load", + data=post_data, + headers={"Content-type": "application/x-tar"}, ) response.raise_for_status() # Catch any errors before proceeding @@ -255,7 +257,7 @@ def push( "format": kwargs.get("format"), } - name = f'{repository}:{tag}' if tag else repository + name = f"{repository}:{tag}" if tag else repository name = urllib.parse.quote_plus(name) response = self.client.post(f"/images/{name}/push", params=params, headers=headers) response.raise_for_status(not_found=ImageNotFound) @@ -295,7 +297,11 @@ def _push_helper( # pylint: disable=too-many-locals,too-many-branches def pull( - self, repository: str, tag: Optional[str] = None, all_tags: bool = False, **kwargs + self, + repository: str, + tag: Optional[str] = None, + all_tags: bool = False, + **kwargs, ) -> Union[Image, List[Image], Iterator[str]]: """Request Podman service to pull image(s) from repository. @@ -366,7 +372,7 @@ def pull( progress_bar = kwargs.get("progress_bar", False) if progress_bar: if Progress is None: - raise ModuleNotFoundError('progress_bar requires \'rich.progress\' module') + raise ModuleNotFoundError("progress_bar requires 'rich.progress' module") params["compatMode"] = True stream = True @@ -384,7 +390,7 @@ def pull( ) with progress: for line in response.iter_lines(): - decoded_line = json.loads(line.decode('utf-8')) + decoded_line = json.loads(line.decode("utf-8")) self.__show_progress_bar(decoded_line, progress, tasks) return None @@ -405,10 +411,10 @@ def pull( def __show_progress_bar(self, line, progress, tasks): completed = False - if line['status'] == 'Download complete': + if line["status"] == "Download complete": description = f'[green][Download complete {line["id"]}]' completed = True - elif line['status'] == 'Downloading': + elif line["status"] == "Downloading": description = f'[bold][Downloading {line["id"]}]' else: # skip other statuses @@ -423,7 +429,7 @@ def __show_progress_bar(self, line, progress, tasks): tasks[task_id] = progress.add_task(description, total=100, completed=100) else: tasks[task_id] = progress.add_task( - description, total=line['progressDetail']['total'] + description, total=line["progressDetail"]["total"] ) else: if completed: @@ -432,7 +438,7 @@ def __show_progress_bar(self, line, progress, tasks): # update the progress bar to show 100% progress.update(tasks[task_id], description=description, total=100, completed=100) else: - progress.update(tasks[task_id], completed=line['progressDetail']['current']) + progress.update(tasks[task_id], completed=line["progressDetail"]["current"]) def remove( self, diff --git a/podman/domain/manager.py b/podman/domain/manager.py index 9be479d9..e0e03a85 100644 --- a/podman/domain/manager.py +++ b/podman/domain/manager.py @@ -81,7 +81,9 @@ def resource(self): """Type[PodmanResource]: Class which the factory method prepare_model() will use.""" def __init__( - self, client: Optional[APIClient] = None, podman_client: Optional["PodmanClient"] = None + self, + client: Optional[APIClient] = None, + podman_client: Optional["PodmanClient"] = None, ) -> None: """Initialize Manager() object. @@ -126,7 +128,10 @@ def prepare_model(self, attrs: Union[PodmanResource, Mapping[str, Any]]) -> Podm # TODO Determine why pylint is reporting typing.Type not callable # pylint: disable=not-callable return self.resource( - attrs=attrs, client=self.client, podman_client=self.podman_client, collection=self + attrs=attrs, + client=self.client, + podman_client=self.podman_client, + collection=self, ) # pylint: disable=broad-exception-raised diff --git a/podman/domain/networks.py b/podman/domain/networks.py index b509132a..870bae7d 100644 --- a/podman/domain/networks.py +++ b/podman/domain/networks.py @@ -86,8 +86,8 @@ def connect(self, container: Union[str, Container], *_, **kwargs) -> None: # TODO Talk with baude on which IPAddress field is needed... ipam = { - "IPv4Address": kwargs.get('ipv4_address'), - "IPv6Address": kwargs.get('ipv6_address'), + "IPv4Address": kwargs.get("ipv4_address"), + "IPv6Address": kwargs.get("ipv6_address"), "Links": kwargs.get("link_local_ips"), } ipam = {k: v for (k, v) in ipam.items() if not (v is None or len(v) == 0)} diff --git a/podman/domain/secrets.py b/podman/domain/secrets.py index 77093ab0..19b3b87c 100644 --- a/podman/domain/secrets.py +++ b/podman/domain/secrets.py @@ -21,7 +21,7 @@ def id(self): # pylint: disable=invalid-name def name(self): """str: name of the secret.""" with suppress(KeyError): - return self.attrs['Spec']['Name'] + return self.attrs["Spec"]["Name"] return "" def remove( diff --git a/podman/domain/volumes.py b/podman/domain/volumes.py index 842ed7a4..6867d5c8 100644 --- a/podman/domain/volumes.py +++ b/podman/domain/volumes.py @@ -112,7 +112,8 @@ def list(self, *_, **kwargs) -> List[Volume]: return [self.prepare_model(i) for i in response.json()] def prune( - self, filters: Optional[Dict[str, str]] = None # pylint: disable=unused-argument + self, + filters: Optional[Dict[str, str]] = None, # pylint: disable=unused-argument ) -> Dict[Literal["VolumesDeleted", "SpaceReclaimed"], Any]: """Delete unused volumes. diff --git a/podman/errors/__init__.py b/podman/errors/__init__.py index 49a65157..675e74a9 100644 --- a/podman/errors/__init__.py +++ b/podman/errors/__init__.py @@ -12,15 +12,15 @@ # isort: unique-list __all__ = [ - 'APIError', - 'BuildError', - 'ContainerError', - 'DockerException', - 'ImageNotFound', - 'InvalidArgument', - 'NotFound', - 'NotFoundError', - 'PodmanError', + "APIError", + "BuildError", + "ContainerError", + "DockerException", + "ImageNotFound", + "InvalidArgument", + "NotFound", + "NotFoundError", + "PodmanError", ] try: diff --git a/podman/tests/README.md b/podman/tests/README.md index ad5e01c0..ad35f5d8 100644 --- a/podman/tests/README.md +++ b/podman/tests/README.md @@ -7,4 +7,3 @@ ## Coverage Reporting Framework `coverage.py` see https://coverage.readthedocs.io/en/coverage-5.0.3/#quick-start - diff --git a/podman/tests/integration/base.py b/podman/tests/integration/base.py index d79711d9..f51792a8 100644 --- a/podman/tests/integration/base.py +++ b/podman/tests/integration/base.py @@ -13,6 +13,7 @@ # under the License. # """Base integration test code""" + import logging import os import shutil @@ -56,9 +57,11 @@ def setUp(self): self.test_dir = self.useFixture(fixtures.TempDir()).path self.socket_file = os.path.join(self.test_dir, uuid.uuid4().hex) - self.socket_uri = f'unix://{self.socket_file}' + self.socket_uri = f"unix://{self.socket_file}" self.service_launcher = utils.PodmanLauncher( - self.socket_uri, podman_path=IntegrationTest.podman, log_level=self.log_level + self.socket_uri, + podman_path=IntegrationTest.podman, + log_level=self.log_level, ) self.service_launcher.start() self.addCleanup(self.service_launcher.stop) diff --git a/podman/tests/integration/test_adapters.py b/podman/tests/integration/test_adapters.py index 598597cb..07c03fd5 100644 --- a/podman/tests/integration/test_adapters.py +++ b/podman/tests/integration/test_adapters.py @@ -39,14 +39,14 @@ def test_tcp_ping(self): podman.start(check_socket=False) time.sleep(0.5) - with PodmanClient(base_url=f"tcp:localhost:8889") as client: + with PodmanClient(base_url="tcp:localhost:8889") as client: self.assertTrue(client.ping()) - with PodmanClient(base_url=f"http://localhost:8889") as client: + with PodmanClient(base_url="http://localhost:8889") as client: self.assertTrue(client.ping()) finally: podman.stop() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/integration/test_container_create.py b/podman/tests/integration/test_container_create.py index 45f2f202..7fcd5abd 100644 --- a/podman/tests/integration/test_container_create.py +++ b/podman/tests/integration/test_container_create.py @@ -27,42 +27,47 @@ def tearUp(self): def test_container_named_volume_mount(self): with self.subTest("Check volume mount"): volumes = { - 'test_bind_1': {'bind': '/mnt/vol1', 'mode': 'rw'}, - 'test_bind_2': {'bind': '/mnt/vol2', 'extended_mode': ['ro', 'noexec']}, - 'test_bind_3': {'bind': '/mnt/vol3', 'extended_mode': ['noexec'], 'mode': 'rw'}, + "test_bind_1": {"bind": "/mnt/vol1", "mode": "rw"}, + "test_bind_2": {"bind": "/mnt/vol2", "extended_mode": ["ro", "noexec"]}, + "test_bind_3": { + "bind": "/mnt/vol3", + "extended_mode": ["noexec"], + "mode": "rw", + }, } container = self.client.containers.create(self.alpine_image, volumes=volumes) - container_mounts = container.attrs.get('Mounts', {}) + container_mounts = container.attrs.get("Mounts", {}) self.assertEqual(len(container_mounts), len(volumes)) for mount in container_mounts: - name = mount.get('Name') + name = mount.get("Name") self.assertIn(name, volumes) test_mount = volumes.get(name) - test_mode = test_mount.get('mode', '') - test_extended_mode = test_mount.get('extended_mode', []) + test_mode = test_mount.get("mode", "") + test_extended_mode = test_mount.get("extended_mode", []) # check RO/RW - if 'ro' in test_mode or 'ro' in test_extended_mode: - self.assertEqual(mount.get('RW'), False) + if "ro" in test_mode or "ro" in test_extended_mode: + self.assertEqual(mount.get("RW"), False) - if 'rw' in test_mode or 'rw' in test_extended_mode: - self.assertEqual(mount.get('RW'), True) + if "rw" in test_mode or "rw" in test_extended_mode: + self.assertEqual(mount.get("RW"), True) - other_options = [o for o in test_extended_mode if o not in ['ro', 'rw']] + other_options = [o for o in test_extended_mode if o not in ["ro", "rw"]] for o in other_options: - self.assertIn(o, mount.get('Options')) + self.assertIn(o, mount.get("Options")) def test_container_directory_volume_mount(self): """Test that directories can be mounted with the ``volume`` parameter.""" - with self.subTest("Check bind mount"): + with self.subTest("Check bind mount on ro mode"): volumes = { - "/etc/hosts": dict(bind="/test_ro", mode='ro'), - "/etc/hosts": dict(bind="/test_rw", mode='rw'), + "/etc/hosts": dict(bind="/test_ro", mode="ro"), } container = self.client.containers.create( - self.alpine_image, command=["cat", "/test_ro", "/test_rw"], volumes=volumes + self.alpine_image, + command=["cat", "/test_ro", "/test_rw"], + volumes=volumes, ) - container_mounts = container.attrs.get('Mounts', {}) + container_mounts = container.attrs.get("Mounts", {}) self.assertEqual(len(container_mounts), len(volumes)) self.containers.append(container) @@ -70,14 +75,40 @@ def test_container_directory_volume_mount(self): for directory, mount_spec in volumes.items(): self.assertIn( f"{directory}:{mount_spec['bind']}:{mount_spec['mode']},rprivate,rbind", - container.attrs.get('HostConfig', {}).get('Binds', list()), + container.attrs.get("HostConfig", {}).get("Binds", list()), ) # check if container can be started and exits with EC == 0 container.start() container.wait() - self.assertEqual(container.attrs.get('State', dict()).get('ExitCode', 256), 0) + self.assertEqual(container.attrs.get("State", dict()).get("ExitCode", 256), 0) + + with self.subTest("Check bind mount on rw mode"): + volumes = { + "/etc/hosts": dict(bind="/test_rw", mode="rw"), + } + container = self.client.containers.create( + self.alpine_image, + command=["cat", "/test_ro", "/test_rw"], + volumes=volumes, + ) + container_mounts = container.attrs.get("Mounts", {}) + self.assertEqual(len(container_mounts), len(volumes)) + + self.containers.append(container) + + for directory, mount_spec in volumes.items(): + self.assertIn( + f"{directory}:{mount_spec['bind']}:{mount_spec['mode']},rprivate,rbind", + container.attrs.get("HostConfig", {}).get("Binds", list()), + ) + + # check if container can be started and exits with EC == 0 + container.start() + container.wait() + + self.assertEqual(container.attrs.get("State", dict()).get("ExitCode", 256), 0) def test_container_extra_hosts(self): """Test Container Extra hosts""" @@ -85,12 +116,14 @@ def test_container_extra_hosts(self): with self.subTest("Check extra hosts in container object"): proper_container = self.client.containers.create( - self.alpine_image, command=["cat", "/etc/hosts"], extra_hosts=extra_hosts + self.alpine_image, + command=["cat", "/etc/hosts"], + extra_hosts=extra_hosts, ) self.containers.append(proper_container) formatted_hosts = [f"{hosts}:{ip}" for hosts, ip in extra_hosts.items()] self.assertEqual( - proper_container.attrs.get('HostConfig', dict()).get('ExtraHosts', list()), + proper_container.attrs.get("HostConfig", dict()).get("ExtraHosts", list()), formatted_hosts, ) @@ -105,106 +138,117 @@ def test_container_extra_hosts(self): def _test_memory_limit(self, parameter_name, host_config_name, set_mem_limit=False): """Base for tests which checks memory limits""" memory_limit_tests = [ - {'value': 1000, 'expected_value': 1000}, - {'value': '1000', 'expected_value': 1000}, - {'value': '1234b', 'expected_value': 1234}, - {'value': '123k', 'expected_value': 123 * 1024}, - {'value': '44m', 'expected_value': 44 * 1024 * 1024}, - {'value': '2g', 'expected_value': 2 * 1024 * 1024 * 1024}, + {"value": 1000, "expected_value": 1000}, + {"value": "1000", "expected_value": 1000}, + {"value": "1234b", "expected_value": 1234}, + {"value": "123k", "expected_value": 123 * 1024}, + {"value": "44m", "expected_value": 44 * 1024 * 1024}, + {"value": "2g", "expected_value": 2 * 1024 * 1024 * 1024}, ] for test in memory_limit_tests: - parameters = {parameter_name: test['value']} + parameters = {parameter_name: test["value"]} if set_mem_limit: - parameters['mem_limit'] = test['expected_value'] - 100 + parameters["mem_limit"] = test["expected_value"] - 100 container = self.client.containers.create(self.alpine_image, **parameters) self.containers.append(container) self.assertEqual( - container.attrs.get('HostConfig', dict()).get(host_config_name), - test['expected_value'], + container.attrs.get("HostConfig", dict()).get(host_config_name), + test["expected_value"], ) def test_container_ports(self): """Test ports binding""" port_tests = [ { - 'input': {'97/tcp': '43'}, - 'expected_output': {'97/tcp': [{'HostIp': '', 'HostPort': '43'}]}, + "input": {"97/tcp": "43"}, + "expected_output": {"97/tcp": [{"HostIp": "", "HostPort": "43"}]}, }, { - 'input': {'2/udp': ('127.0.0.1', '939')}, - 'expected_output': {'2/udp': [{'HostIp': '127.0.0.1', 'HostPort': '939'}]}, + "input": {"2/udp": ("127.0.0.1", "939")}, + "expected_output": {"2/udp": [{"HostIp": "127.0.0.1", "HostPort": "939"}]}, }, { - 'input': { - '11123/tcp': [('127.0.0.1', '11123'), ('127.0.0.1', '112'), '1123', '159'] + "input": { + "11123/tcp": [ + ("127.0.0.1", "11123"), + ("127.0.0.1", "112"), + "1123", + "159", + ] }, - 'expected_output': { - '11123/tcp': [ - {'HostIp': '127.0.0.1', 'HostPort': '11123'}, - {'HostIp': '', 'HostPort': '112'}, - {'HostIp': '', 'HostPort': '1123'}, - {'HostIp': '', 'HostPort': '159'}, + "expected_output": { + "11123/tcp": [ + {"HostIp": "127.0.0.1", "HostPort": "11123"}, + {"HostIp": "", "HostPort": "112"}, + {"HostIp": "", "HostPort": "1123"}, + {"HostIp": "", "HostPort": "159"}, ] }, }, { - 'input': {'1111/tcp': {"port": ('127.0.0.1', 1111), "range": 3}}, - 'expected_output': { - '1111/tcp': [{'HostIp': '127.0.0.1', 'HostPort': '1111'}], - '1112/tcp': [{'HostIp': '127.0.0.1', 'HostPort': '1112'}], - '1113/tcp': [{'HostIp': '127.0.0.1', 'HostPort': '1113'}], + "input": {"1111/tcp": {"port": ("127.0.0.1", 1111), "range": 3}}, + "expected_output": { + "1111/tcp": [{"HostIp": "127.0.0.1", "HostPort": "1111"}], + "1112/tcp": [{"HostIp": "127.0.0.1", "HostPort": "1112"}], + "1113/tcp": [{"HostIp": "127.0.0.1", "HostPort": "1113"}], }, }, { - 'input': { - '1222/tcp': [{"port": 1234, "range": 2}, {"ip": "127.0.0.1", "port": 4567}] + "input": { + "1222/tcp": [ + {"port": 1234, "range": 2}, + {"ip": "127.0.0.1", "port": 4567}, + ] }, - 'expected_output': { - '1222/tcp': [ - {'HostIp': '', 'HostPort': '1234'}, - {'HostIp': '127.0.0.1', 'HostPort': '4567'}, + "expected_output": { + "1222/tcp": [ + {"HostIp": "", "HostPort": "1234"}, + {"HostIp": "127.0.0.1", "HostPort": "4567"}, ], - '1223/tcp': [{'HostIp': '', 'HostPort': '1235'}], + "1223/tcp": [{"HostIp": "", "HostPort": "1235"}], }, }, { - 'input': { + "input": { 2244: 3344, }, - 'expected_output': { - '2244/tcp': [ - {'HostIp': '', 'HostPort': '3344'}, + "expected_output": { + "2244/tcp": [ + {"HostIp": "", "HostPort": "3344"}, ], }, }, ] for port_test in port_tests: - container = self.client.containers.create(self.alpine_image, ports=port_test['input']) + container = self.client.containers.create(self.alpine_image, ports=port_test["input"]) self.containers.append(container) self.assertTrue( all( [ - x in port_test['expected_output'] - for x in container.attrs.get('HostConfig', {}).get('PortBindings') + x in port_test["expected_output"] + for x in container.attrs.get("HostConfig", {}).get("PortBindings") ] ) ) def test_container_dns_option(self): - expected_dns_opt = ['edns0'] + expected_dns_opt = ["edns0"] container = self.client.containers.create( - self.alpine_image, command=["cat", "/etc/resolv.conf"], dns_opt=expected_dns_opt + self.alpine_image, + command=["cat", "/etc/resolv.conf"], + dns_opt=expected_dns_opt, ) self.containers.append(container) with self.subTest("Check HostConfig"): self.assertEqual( - container.attrs.get('HostConfig', {}).get('DnsOptions'), expected_dns_opt + container.attrs.get("HostConfig", {}).get("DnsOptions"), + expected_dns_opt, ) with self.subTest("Check content of /etc/resolv.conf"): @@ -217,27 +261,27 @@ def test_container_dns_option(self): def test_container_healthchecks(self): """Test passing various healthcheck options""" parameters = { - 'healthcheck': {'Test': ['CMD-SHELL curl http://localhost || exit']}, - 'health_check_on_failure_action': 1, + "healthcheck": {"Test": ["CMD-SHELL curl http://localhost || exit"]}, + "health_check_on_failure_action": 1, } container = self.client.containers.create(self.alpine_image, **parameters) self.containers.append(container) def test_container_mem_limit(self): """Test passing memory limit""" - self._test_memory_limit('mem_limit', 'Memory') + self._test_memory_limit("mem_limit", "Memory") def test_container_memswap_limit(self): """Test passing memory swap limit""" - self._test_memory_limit('memswap_limit', 'MemorySwap', set_mem_limit=True) + self._test_memory_limit("memswap_limit", "MemorySwap", set_mem_limit=True) def test_container_mem_reservation(self): """Test passing memory reservation""" - self._test_memory_limit('mem_reservation', 'MemoryReservation') + self._test_memory_limit("mem_reservation", "MemoryReservation") def test_container_shm_size(self): """Test passing shared memory size""" - self._test_memory_limit('shm_size', 'ShmSize') + self._test_memory_limit("shm_size", "ShmSize") def test_container_mounts(self): """Test passing mounts""" @@ -255,23 +299,28 @@ def test_container_mounts(self): self.containers.append(container) self.assertIn( f"{mount['source']}:{mount['target']}:ro,Z,rprivate,rbind", - container.attrs.get('HostConfig', {}).get('Binds', list()), + container.attrs.get("HostConfig", {}).get("Binds", list()), ) # check if container can be started and exits with EC == 0 container.start() container.wait() - self.assertEqual(container.attrs.get('State', dict()).get('ExitCode', 256), 0) + self.assertEqual(container.attrs.get("State", dict()).get("ExitCode", 256), 0) with self.subTest("Check tmpfs mount"): - mount = {"type": "tmpfs", "source": "tmpfs", "target": "/test", "size": "456k"} + mount = { + "type": "tmpfs", + "source": "tmpfs", + "target": "/test", + "size": "456k", + } container = self.client.containers.create( self.alpine_image, command=["df", "-h"], mounts=[mount] ) self.containers.append(container) self.assertEqual( - container.attrs.get('HostConfig', {}).get('Tmpfs', {}).get(mount['target']), + container.attrs.get("HostConfig", {}).get("Tmpfs", {}).get(mount["target"]), f"size={mount['size']},rw,rprivate,nosuid,nodev,tmpcopyup", ) @@ -295,15 +344,15 @@ def test_container_devices(self): ) self.containers.append(container) - container_devices = container.attrs.get('HostConfig', {}).get('Devices', []) + container_devices = container.attrs.get("HostConfig", {}).get("Devices", []) with self.subTest("Check devices in container object"): for device in devices: - path_on_host, path_in_container = device.split(':', 1) + path_on_host, path_in_container = device.split(":", 1) self.assertTrue( any( [ - c.get('PathOnHost') == path_on_host - and c.get('PathInContainer') == path_in_container + c.get("PathOnHost") == path_on_host + and c.get("PathInContainer") == path_in_container for c in container_devices ] ) @@ -315,11 +364,11 @@ def test_container_devices(self): logs = b"\n".join(container.logs()).decode() - device_regex = r'(\d+, *?\d+).*?{}\n' + device_regex = r"(\d+, *?\d+).*?{}\n" for device in devices: # check whether device exists - source_device, destination_device = device.split(':', 1) + source_device, destination_device = device.split(":", 1) source_match = re.search( device_regex.format(source_device.rsplit("/", 1)[-1]), logs ) @@ -349,7 +398,7 @@ def test_read_write_tmpfs(self): ] for test in test_cases: - read_write_tmpfs = test.get('read_write_tmpfs') + read_write_tmpfs = test.get("read_write_tmpfs") with self.subTest(f"Check read_write_tmpfs set to {read_write_tmpfs}"): kwargs = ( {"read_write_tmpfs": read_write_tmpfs} if read_write_tmpfs is not None else {} @@ -380,5 +429,5 @@ def test_read_write_tmpfs(self): self.assertIn(expected_output, logs) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/integration/test_container_exec.py b/podman/tests/integration/test_container_exec.py index 43190797..1eec7726 100644 --- a/podman/tests/integration/test_container_exec.py +++ b/podman/tests/integration/test_container_exec.py @@ -1,5 +1,3 @@ -import unittest - import podman.tests.integration.base as base from podman import PodmanClient @@ -29,7 +27,7 @@ def test_container_exec_run(self): error_code, stdout = container.exec_run("echo hello") self.assertEqual(error_code, 0) - self.assertEqual(stdout, b'\x01\x00\x00\x00\x00\x00\x00\x06hello\n') + self.assertEqual(stdout, b"\x01\x00\x00\x00\x00\x00\x00\x06hello\n") def test_container_exec_run_errorcode(self): """Test a failing command with stdout and stderr in a single bytestring""" @@ -39,7 +37,8 @@ def test_container_exec_run_errorcode(self): self.assertEqual(error_code, 1) self.assertEqual( - output, b"\x02\x00\x00\x00\x00\x00\x00+ls: nonexistent: No such file or directory\n" + output, + b"\x02\x00\x00\x00\x00\x00\x00+ls: nonexistent: No such file or directory\n", ) def test_container_exec_run_demux(self): @@ -58,9 +57,9 @@ def test_container_exec_run_stream(self): container.start() command = [ - '/bin/sh', - '-c', - 'echo 0 ; sleep .1 ; echo 1 ; sleep .1 ; echo 2 ; sleep .1 ;', + "/bin/sh", + "-c", + "echo 0 ; sleep .1 ; echo 1 ; sleep .1 ; echo 2 ; sleep .1 ;", ] error_code, output = container.exec_run(command, stream=True) @@ -68,9 +67,9 @@ def test_container_exec_run_stream(self): self.assertEqual( list(output), [ - b'0\n', - b'1\n', - b'2\n', + b"0\n", + b"1\n", + b"2\n", ], ) @@ -80,11 +79,11 @@ def test_container_exec_run_stream_demux(self): container.start() command = [ - '/bin/sh', - '-c', - 'echo 0 ; >&2 echo 1 ; sleep .1 ; ' - + 'echo 2 ; >&2 echo 3 ; sleep .1 ; ' - + 'echo 4 ; >&2 echo 5 ; sleep .1 ;', + "/bin/sh", + "-c", + "echo 0 ; >&2 echo 1 ; sleep .1 ; " + + "echo 2 ; >&2 echo 3 ; sleep .1 ; " + + "echo 4 ; >&2 echo 5 ; sleep .1 ;", ] error_code, output = container.exec_run(command, stream=True, demux=True) @@ -92,12 +91,12 @@ def test_container_exec_run_stream_demux(self): self.assertEqual( list(output), [ - (b'0\n', None), - (None, b'1\n'), - (b'2\n', None), - (None, b'3\n'), - (b'4\n', None), - (None, b'5\n'), + (b"0\n", None), + (None, b"1\n"), + (b"2\n", None), + (None, b"3\n"), + (b"4\n", None), + (None, b"5\n"), ], ) @@ -107,9 +106,9 @@ def test_container_exec_run_stream_detach(self): container.start() command = [ - '/bin/sh', - '-c', - 'echo 0 ; sleep .1 ; echo 1 ; sleep .1 ; echo 2 ; sleep .1 ;', + "/bin/sh", + "-c", + "echo 0 ; sleep .1 ; echo 1 ; sleep .1 ; echo 2 ; sleep .1 ;", ] error_code, output = container.exec_run(command, stream=True, detach=True) @@ -119,5 +118,5 @@ def test_container_exec_run_stream_detach(self): # The endpoint should return immediately, before we are able to actually get any of the output. self.assertEqual( output, - b'\n', + b"\n", ) diff --git a/podman/tests/integration/test_containers.py b/podman/tests/integration/test_containers.py index d92a7d7a..afc4e2b8 100644 --- a/podman/tests/integration/test_containers.py +++ b/podman/tests/integration/test_containers.py @@ -45,7 +45,7 @@ def test_container_crud(self): container = self.client.containers.create( self.alpine_image, command=["echo", random_string], - ports={'2222/tcp': 3333, 2244: 3344}, + ports={"2222/tcp": 3333, 2244: 3344}, ) self.assertIsInstance(container, Container) self.assertGreater(len(container.attrs), 0) @@ -63,11 +63,13 @@ def test_container_crud(self): self.assertIn("2222/tcp", container.attrs["NetworkSettings"]["Ports"]) self.assertEqual( - "3333", container.attrs["NetworkSettings"]["Ports"]["2222/tcp"][0]["HostPort"] + "3333", + container.attrs["NetworkSettings"]["Ports"]["2222/tcp"][0]["HostPort"], ) self.assertIn("2244/tcp", container.attrs["NetworkSettings"]["Ports"]) self.assertEqual( - "3344", container.attrs["NetworkSettings"]["Ports"]["2244/tcp"][0]["HostPort"] + "3344", + container.attrs["NetworkSettings"]["Ports"]["2244/tcp"][0]["HostPort"], ) file_contents = b"This is an integration test for archive." @@ -173,7 +175,7 @@ def test_container_rm_anonymous_volume(self): ENV foo=bar """ tmp_file = tempfile.mktemp() - file = open(tmp_file, 'w') + file = open(tmp_file, "w") file.write(container_file) file.close() self.client.images.build(dockerfile=tmp_file, tag="test-img", path=".") @@ -196,7 +198,7 @@ def test_container_rm_anonymous_volume(self): self.assertEqual(len(volume_list), len(existing_volumes)) def test_container_labels(self): - labels = {'label1': 'value1', 'label2': 'value2'} + labels = {"label1": "value1", "label2": "value2"} labeled_container = self.client.containers.create(self.alpine_image, labels=labels) unlabeled_container = self.client.containers.create( self.alpine_image, @@ -221,5 +223,5 @@ def test_container_labels(self): unlabeled_container.remove(v=True) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/integration/test_images.py b/podman/tests/integration/test_images.py index 298d13ec..0d35aa23 100644 --- a/podman/tests/integration/test_images.py +++ b/podman/tests/integration/test_images.py @@ -13,14 +13,11 @@ # under the License. # """Images integration tests.""" + import io -import queue import tarfile -import threading import types import unittest -from contextlib import suppress -from datetime import datetime, timedelta import podman.tests.integration.base as base from podman import PodmanClient @@ -140,7 +137,7 @@ def test_corrupt_load(self): self.assertIn("payload does not match", e.exception.explanation) def test_build(self): - buffer = io.StringIO(f"""FROM quay.io/libpod/alpine_labels:latest""") + buffer = io.StringIO("""FROM quay.io/libpod/alpine_labels:latest""") image, stream = self.client.images.build(fileobj=buffer) self.assertIsNotNone(image) @@ -154,7 +151,8 @@ def test_scp(self): with self.assertRaises(APIError) as e: next( self.client.images.scp( - source="randuser@fake.ip.addr:22::quay.io/libpod/alpine", quiet=False + source="randuser@fake.ip.addr:22::quay.io/libpod/alpine", + quiet=False, ) ) self.assertRegex( diff --git a/podman/tests/integration/test_manifests.py b/podman/tests/integration/test_manifests.py index 71235f0c..ce7cee98 100644 --- a/podman/tests/integration/test_manifests.py +++ b/podman/tests/integration/test_manifests.py @@ -74,5 +74,5 @@ def test_create_409(self): self.client.manifests.create(self.invalid_manifest_name) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/integration/test_networks.py b/podman/tests/integration/test_networks.py index 0b5d44d1..76e9b854 100644 --- a/podman/tests/integration/test_networks.py +++ b/podman/tests/integration/test_networks.py @@ -13,7 +13,7 @@ # under the License. # """Network integration tests.""" -import os + import random import unittest from contextlib import suppress diff --git a/podman/tests/integration/test_pods.py b/podman/tests/integration/test_pods.py index 396a42e3..20f919b6 100644 --- a/podman/tests/integration/test_pods.py +++ b/podman/tests/integration/test_pods.py @@ -153,5 +153,5 @@ def test_ps(self): pod.stop() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/integration/test_secrets.py b/podman/tests/integration/test_secrets.py index 6347ac6f..389de0f2 100644 --- a/podman/tests/integration/test_secrets.py +++ b/podman/tests/integration/test_secrets.py @@ -48,5 +48,5 @@ def test_secret_crud(self): self.client.secrets.get(secret.id) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/integration/test_system.py b/podman/tests/integration/test_system.py index bcc38711..18cdff48 100644 --- a/podman/tests/integration/test_system.py +++ b/podman/tests/integration/test_system.py @@ -30,21 +30,21 @@ def setUp(self): def test_info(self): """integration: system info call""" output = self.client.info() - self.assertTrue('host' in output) + self.assertTrue("host" in output) def test_version(self): """integration: system version call""" output = self.client.version() - self.assertTrue('Platform' in output) - self.assertTrue('Version' in output) - self.assertTrue('ApiVersion' in output) + self.assertTrue("Platform" in output) + self.assertTrue("Version" in output) + self.assertTrue("ApiVersion" in output) def test_show_disk_usage(self): """integration: system disk usage call""" output = self.client.df() - self.assertTrue('Images' in output) - self.assertTrue('Containers' in output) - self.assertTrue('Volumes' in output) + self.assertTrue("Images" in output) + self.assertTrue("Containers" in output) + self.assertTrue("Volumes" in output) def test_login(self): """integration: system login call""" @@ -53,7 +53,10 @@ def test_login(self): with self.assertRaises(APIError) as e: next( self.client.login( - "fake_user", "fake_password", "fake_email@fake_domain.test", "fake_registry" + "fake_user", + "fake_password", + "fake_email@fake_domain.test", + "fake_registry", ) ) self.assertRegex( diff --git a/podman/tests/integration/test_volumes.py b/podman/tests/integration/test_volumes.py index 34dc19d2..79a1683b 100644 --- a/podman/tests/integration/test_volumes.py +++ b/podman/tests/integration/test_volumes.py @@ -17,7 +17,8 @@ def test_volume_crud(self): """Test Volume CRUD.""" volume_name = f"volume_{random.getrandbits(160):x}" self.assertFalse( - self.client.volumes.exists(volume_name), "Storage is corrupt from previous run" + self.client.volumes.exists(volume_name), + "Storage is corrupt from previous run", ) with self.subTest("Create"): @@ -45,5 +46,5 @@ def test_inspect_404(self): self.client.volumes.get("NoSuchVolume") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/integration/utils.py b/podman/tests/integration/utils.py index 78aea63a..2a5d58ef 100644 --- a/podman/tests/integration/utils.py +++ b/podman/tests/integration/utils.py @@ -13,6 +13,7 @@ # under the License. # """Integration Test Utils""" + import logging import os import shutil @@ -42,11 +43,11 @@ def __init__( """create a launcher and build podman command""" podman_exe: str = podman_path if not podman_exe: - podman_exe = shutil.which('podman') + podman_exe = shutil.which("podman") if podman_exe is None: raise errors.PodmanNotInstalled() - self.socket_file: str = socket_uri.replace('unix://', '') + self.socket_file: str = socket_uri.replace("unix://", "") self.log_level = log_level self.proc = None @@ -54,7 +55,7 @@ def __init__( self.cmd: List[str] = [] if privileged: - self.cmd.append('sudo') + self.cmd.append("sudo") self.cmd.append(podman_exe) @@ -76,7 +77,10 @@ def __init__( ) process = subprocess.run( - [podman_exe, "--version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT + [podman_exe, "--version"], + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, ) self.version = str(process.stdout.decode("utf-8")).strip().split()[2] @@ -85,7 +89,7 @@ def start(self, check_socket=True) -> None: logger.info( "Launching(%s) %s refid=%s", self.version, - ' '.join(self.cmd), + " ".join(self.cmd), self.reference_id, ) @@ -97,9 +101,7 @@ def consume_lines(pipe, consume_fn): def consume(line: str): logger.debug(line.strip("\n") + f" refid={self.reference_id}") - self.proc = subprocess.Popen( - self.cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT - ) # pylint: disable=consider-using-with + self.proc = subprocess.Popen(self.cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # pylint: disable=consider-using-with threading.Thread(target=consume_lines, args=[self.proc.stdout, consume]).start() if not check_socket: diff --git a/podman/tests/unit/test_api_utils.py b/podman/tests/unit/test_api_utils.py index dcafc294..326cf1c2 100644 --- a/podman/tests/unit/test_api_utils.py +++ b/podman/tests/unit/test_api_utils.py @@ -3,7 +3,7 @@ import unittest from typing import Any, Optional from unittest import mock -from unittest.mock import Mock, mock_open, patch +from unittest.mock import mock_open, patch from dataclasses import dataclass @@ -20,9 +20,15 @@ class TestCase: cases = [ TestCase(name="empty str", input="", expected=None), - TestCase(name="str", input="reference=fedora", expected='{"reference": ["fedora"]}'), TestCase( - name="List[str]", input=["reference=fedora"], expected='{"reference": ["fedora"]}' + name="str", + input="reference=fedora", + expected='{"reference": ["fedora"]}', + ), + TestCase( + name="List[str]", + input=["reference=fedora"], + expected='{"reference": ["fedora"]}', ), TestCase( name="Dict[str,str]", @@ -165,5 +171,5 @@ def test_prepare_body_dict_empty_string(self): self.assertDictEqual(payload, actual_dict) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_build.py b/podman/tests/unit/test_build.py index a12187ea..3b9b3a29 100644 --- a/podman/tests/unit/test_build.py +++ b/podman/tests/unit/test_build.py @@ -47,7 +47,7 @@ def test_build(self, mock_prepare_containerfile, mock_create_tar): {"stream": " ---\u003e Running in abdc1e6896c6"}, {"stream": " ---\u003e 713bca62012e"}, {"stream": "Removing intermediate container abdc1e6896c6"}, - {"stream": "Step 2 : CMD [\"/bin/sh\"]"}, + {"stream": 'Step 2 : CMD ["/bin/sh"]'}, {"stream": " ---\u003e Running in dba30f2a1a7e"}, {"stream": " ---\u003e 032b8b2855fc"}, {"stream": "Removing intermediate container dba30f2a1a7e"}, @@ -141,5 +141,5 @@ def test_build_encoding(self, mock): self.client.images.build(path="/root", gzip=True, encoding="utf-8") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_config.py b/podman/tests/unit/test_config.py index e2d61d7e..272e915a 100644 --- a/podman/tests/unit/test_config.py +++ b/podman/tests/unit/test_config.py @@ -56,16 +56,16 @@ def setUp(self): """ # Define the file path - self.path_json = os.path.join(self.temp_dir, 'podman-connections.json') - self.path_toml = os.path.join(self.temp_dir, 'containers.conf') + self.path_json = os.path.join(self.temp_dir, "podman-connections.json") + self.path_toml = os.path.join(self.temp_dir, "containers.conf") # Write data to the JSON file j_data = json.loads(self.data_json) - with open(self.path_json, 'w+') as file_json: + with open(self.path_json, "w+") as file_json: json.dump(j_data, file_json) # Write data to the TOML file - with open(self.path_toml, 'w+') as file_toml: + with open(self.path_toml, "w+") as file_toml: # toml.dump(self.data_toml, file_toml) file_toml.write(self.data_toml) @@ -122,7 +122,7 @@ def test_connections(self): self.assertEqual(config.services["production"].identity, Path("/home/root/.ssh/id_rsa")) PodmanConfigTestCaseTOML.opener.assert_called_with( - Path("/home/developer/containers.conf"), encoding='utf-8' + Path("/home/developer/containers.conf"), encoding="utf-8" ) @@ -150,10 +150,10 @@ def setUp(self) -> None: } """ - self.path = os.path.join(self.temp_dir, 'podman-connections.json') + self.path = os.path.join(self.temp_dir, "podman-connections.json") # Write data to the JSON file data = json.loads(self.data) - with open(self.path, 'w+') as file: + with open(self.path, "w+") as file: json.dump(data, file) def test_connections(self): @@ -166,5 +166,5 @@ def test_connections(self): self.assertEqual(config.services["production"].identity, Path("/home/root/.ssh/id_rsa")) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_container.py b/podman/tests/unit/test_container.py index 5d0023e0..9f55a161 100644 --- a/podman/tests/unit/test_container.py +++ b/podman/tests/unit/test_container.py @@ -251,7 +251,7 @@ def test_diff_404(self, mock): @requests_mock.Mocker() def test_export(self, mock): - tarball = b'Yet another weird tarball...' + tarball = b"Yet another weird tarball..." body = io.BytesIO(tarball) adapter = mock.get( tests.LIBPOD_URL @@ -268,7 +268,7 @@ def test_export(self, mock): @requests_mock.Mocker() def test_get_archive(self, mock): - tarball = b'Yet another weird tarball...' + tarball = b"Yet another weird tarball..." body = io.BytesIO(tarball) header_value = { @@ -341,7 +341,7 @@ def test_put_archive(self, mock): ) container = Container(attrs=FIRST_CONTAINER, client=self.client.api) - tarball = b'Yet another weird tarball...' + tarball = b"Yet another weird tarball..." body = io.BytesIO(tarball) actual = container.put_archive(path="/etc/motd", data=body.getvalue()) self.assertTrue(actual) @@ -362,7 +362,7 @@ def test_put_archive_404(self, mock): ) container = Container(attrs=FIRST_CONTAINER, client=self.client.api) - tarball = b'Yet another weird tarball...' + tarball = b"Yet another weird tarball..." body = io.BytesIO(tarball) actual = container.put_archive(path="deadbeef", data=body.getvalue()) self.assertFalse(actual) @@ -373,17 +373,17 @@ def test_top(self, mock): body = { "Processes": [ [ - 'jhonce', - '2417', - '2274', - '0', - 'Mar01', - '?', - '00:00:01', + "jhonce", + "2417", + "2274", + "0", + "Mar01", + "?", + "00:00:01", '/usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "/usr/bin/gnome-session"', ], - ['jhonce', '5544', '3522', '0', 'Mar01', 'pts/1', '00:00:02', '-bash'], - ['jhonce', '6140', '3522', '0', 'Mar01', 'pts/2', '00:00:00', '-bash'], + ["jhonce", "5544", "3522", "0", "Mar01", "pts/1", "00:00:02", "-bash"], + ["jhonce", "6140", "3522", "0", "Mar01", "pts/2", "00:00:00", "-bash"], ], "Titles": ["UID", "PID", "PPID", "C", "STIME", "TTY", "TIME CMD"], } @@ -403,17 +403,35 @@ def test_top_with_streaming(self, mock): { "Processes": [ [ - 'jhonce', - '2417', - '2274', - '0', - 'Mar01', - '?', - '00:00:01', + "jhonce", + "2417", + "2274", + "0", + "Mar01", + "?", + "00:00:01", '/usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "/usr/bin/gnome-session"', ], - ['jhonce', '5544', '3522', '0', 'Mar01', 'pts/1', '00:00:02', '-bash'], - ['jhonce', '6140', '3522', '0', 'Mar01', 'pts/2', '00:00:00', '-bash'], + [ + "jhonce", + "5544", + "3522", + "0", + "Mar01", + "pts/1", + "00:00:02", + "-bash", + ], + [ + "jhonce", + "6140", + "3522", + "0", + "Mar01", + "pts/2", + "00:00:00", + "-bash", + ], ], "Titles": ["UID", "PID", "PPID", "C", "STIME", "TTY", "TIME CMD"], } @@ -442,5 +460,5 @@ def test_top_with_streaming(self, mock): self.assertTrue(adapter.called_once) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_containersmanager.py b/podman/tests/unit/test_containersmanager.py index cb0ec167..d04b0fb2 100644 --- a/podman/tests/unit/test_containersmanager.py +++ b/podman/tests/unit/test_containersmanager.py @@ -8,7 +8,7 @@ # Python < 3.10 from collections import Iterator -from unittest.mock import ANY, DEFAULT, patch, MagicMock +from unittest.mock import DEFAULT, patch, MagicMock import requests_mock @@ -64,7 +64,8 @@ def test_get(self, mock): "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" ) self.assertEqual( - actual.id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" + actual.id, + "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", ) @requests_mock.Mocker() @@ -104,10 +105,12 @@ def test_list(self, mock): self.assertIsInstance(actual, list) self.assertEqual( - actual[0].id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" + actual[0].id, + "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", ) self.assertEqual( - actual[1].id, "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03" + actual[1].id, + "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03", ) @requests_mock.Mocker() @@ -132,10 +135,12 @@ def test_list_filtered(self, mock): self.assertIsInstance(actual, list) self.assertEqual( - actual[0].id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" + actual[0].id, + "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", ) self.assertEqual( - actual[1].id, "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03" + actual[1].id, + "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03", ) @requests_mock.Mocker() @@ -148,10 +153,12 @@ def test_list_no_filters(self, mock): self.assertIsInstance(actual, list) self.assertEqual( - actual[0].id, "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd" + actual[0].id, + "87e1325c82424e49a00abdd4de08009eb76c7de8d228426a9b8af9318ced5ecd", ) self.assertEqual( - actual[1].id, "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03" + actual[1].id, + "6dc84cc0a46747da94e4c1571efcc01a756b4017261440b4b8985d37203c3c03", ) @requests_mock.Mocker() @@ -228,8 +235,8 @@ def test_create_parse_host_port(self, mock): json=FIRST_CONTAINER, ) - port_str = {'2233': 3333} - port_str_protocol = {'2244/tcp': 3344} + port_str = {"2233": 3333} + port_str_protocol = {"2244/tcp": 3344} port_int = {2255: 3355} ports = {**port_str, **port_str_protocol, **port_int} self.client.containers.create("fedora", "/usr/bin/ls", ports=ports) @@ -237,23 +244,23 @@ def test_create_parse_host_port(self, mock): self.client.containers.client.post.assert_called() expected_ports = [ { - 'container_port': 2233, - 'host_port': 3333, - 'protocol': 'tcp', + "container_port": 2233, + "host_port": 3333, + "protocol": "tcp", }, { - 'container_port': 2244, - 'host_port': 3344, - 'protocol': 'tcp', + "container_port": 2244, + "host_port": 3344, + "protocol": "tcp", }, { - 'container_port': 2255, - 'host_port': 3355, - 'protocol': 'tcp', + "container_port": 2255, + "host_port": 3355, + "protocol": "tcp", }, ] - actual_ports = json.loads(self.client.containers.client.post.call_args[1]['data'])[ - 'portmappings' + actual_ports = json.loads(self.client.containers.client.post.call_args[1]["data"])[ + "portmappings" ] self.assertEqual(expected_ports, actual_ports) @@ -327,7 +334,7 @@ def test_run(self, mock): actual = self.client.containers.run("fedora", "/usr/bin/ls") self.assertIsInstance(actual, bytes) - self.assertEqual(actual, b'This is a unittest - line 1This is a unittest - line 2') + self.assertEqual(actual, b"This is a unittest - line 1This is a unittest - line 2") # iter() cannot be reset so subtests used to create new instance with self.subTest("Stream results"): @@ -340,5 +347,5 @@ def test_run(self, mock): self.assertEqual(next(actual), b"This is a unittest - line 2") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_events.py b/podman/tests/unit/test_events.py index 2ac3a9a7..e34c2069 100644 --- a/podman/tests/unit/test_events.py +++ b/podman/tests/unit/test_events.py @@ -63,5 +63,5 @@ def test_list(self, mock): self.assertEqual(event["Type"], "pod") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_image.py b/podman/tests/unit/test_image.py index b5107abf..56256e9f 100644 --- a/podman/tests/unit/test_image.py +++ b/podman/tests/unit/test_image.py @@ -93,7 +93,7 @@ def test_reload(self, mock): @requests_mock.Mocker() def test_save(self, mock): - tarball = b'Yet another weird tarball...' + tarball = b"Yet another weird tarball..." body = io.BytesIO(tarball) adapter = mock.get( @@ -110,5 +110,5 @@ def test_save(self, mock): self.assertTrue(adapter.called_once) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_imagesmanager.py b/podman/tests/unit/test_imagesmanager.py index 4906daf2..1d16d9bd 100644 --- a/podman/tests/unit/test_imagesmanager.py +++ b/podman/tests/unit/test_imagesmanager.py @@ -1,6 +1,6 @@ import types import unittest -from unittest.mock import mock_open, patch +from unittest.mock import patch try: # Python >= 3.10 @@ -94,7 +94,8 @@ def test_list_1(self, mock): self.assertEqual(str(images[0]), "") self.assertEqual( - images[0].id, "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab" + images[0].id, + "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", ) self.assertIsInstance(images[0].labels, dict) @@ -136,7 +137,8 @@ def test_list_filters(self, mock): images = self.client.images.list(filters={"dangling": True}) self.assertEqual( - images[0].id, "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab" + images[0].id, + "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", ) @requests_mock.Mocker() @@ -149,7 +151,8 @@ def test_list_all(self, mock): images = self.client.images.list(all=True) self.assertEqual( - images[0].id, "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab" + images[0].id, + "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", ) @requests_mock.Mocker() @@ -325,10 +328,10 @@ def test_load(self, mock): self.client.images.load() with self.assertRaises(PodmanError): - self.client.images.load(b'data', b'file_path') + self.client.images.load(b"data", b"file_path") with self.assertRaises(PodmanError): - self.client.images.load(data=b'data', file_path=b'file_path') + self.client.images.load(data=b"data", file_path=b"file_path") # Patch Path.read_bytes to mock the file reading behavior with patch("pathlib.Path.read_bytes", return_value=b"mock tarball data"): @@ -361,13 +364,14 @@ def test_load(self, mock): json=FIRST_IMAGE, ) - gntr = self.client.images.load(b'This is a weird tarball...') + gntr = self.client.images.load(b"This is a weird tarball...") self.assertIsInstance(gntr, types.GeneratorType) report = list(gntr) self.assertEqual(len(report), 1) self.assertEqual( - report[0].id, "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab" + report[0].id, + "sha256:326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", ) @requests_mock.Mocker() @@ -586,7 +590,8 @@ def test_pull_2x(self, mock): self.assertEqual(images[0].id, image_id) self.assertEqual( - images[1].id, "c4b16966ecd94ffa910eab4e630e24f259bf34a87e924cd4b1434f267b0e354e" + images[1].id, + "c4b16966ecd94ffa910eab4e630e24f259bf34a87e924cd4b1434f267b0e354e", ) @requests_mock.Mocker() @@ -627,7 +632,8 @@ def test_list_with_name_overrides_reference_filter(self, mock): # The name parameter should override the reference filter images = self.client.images.list( - name="fedora", filters={"reference": "ubuntu"} # This should be overridden + name="fedora", + filters={"reference": "ubuntu"}, # This should be overridden ) self.assertEqual(len(images), 1) @@ -668,5 +674,5 @@ def test_list_with_none_name(self, mock): self.assertIsInstance(images[0], Image) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_manager.py b/podman/tests/unit/test_manager.py index fe1b599e..de4c72e3 100644 --- a/podman/tests/unit/test_manager.py +++ b/podman/tests/unit/test_manager.py @@ -9,5 +9,5 @@ def test_prepare_model(self): PodsManager().prepare_model(attrs=("Sets", "Not", "supported")) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_manifests.py b/podman/tests/unit/test_manifests.py index f0f8cda6..d3e52425 100644 --- a/podman/tests/unit/test_manifests.py +++ b/podman/tests/unit/test_manifests.py @@ -24,5 +24,5 @@ def test_name(self): self.assertIsNone(manifest.name) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_network.py b/podman/tests/unit/test_network.py index b5dfb06b..35ccb0c0 100644 --- a/podman/tests/unit/test_network.py +++ b/podman/tests/unit/test_network.py @@ -67,7 +67,8 @@ def test_id(self): actual = Network(attrs={"name": "database"}) self.assertEqual( - actual.id, "3549b0028b75d981cdda2e573e9cb49dedc200185876df299f912b79f69dabd8" + actual.id, + "3549b0028b75d981cdda2e573e9cb49dedc200185876df299f912b79f69dabd8", ) def test_name(self): @@ -104,12 +105,12 @@ def test_connect(self, mock): self.assertDictEqual( adapter.last_request.json(), { - 'Container': 'podman_ctnr', + "Container": "podman_ctnr", "EndpointConfig": { - 'Aliases': ['production'], - 'IPAMConfig': {'IPv4Address': '172.16.0.1'}, - 'IPAddress': '172.16.0.1', - 'NetworkID': '2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9', + "Aliases": ["production"], + "IPAMConfig": {"IPv4Address": "172.16.0.1"}, + "IPAddress": "172.16.0.1", + "NetworkID": "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9", }, }, ) @@ -124,11 +125,11 @@ def test_disconnect(self, mock): self.assertDictEqual( adapter.last_request.json(), { - 'Container': 'podman_ctnr', + "Container": "podman_ctnr", "Force": True, }, ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_networksmanager.py b/podman/tests/unit/test_networksmanager.py index 1219bb54..1b634c35 100644 --- a/podman/tests/unit/test_networksmanager.py +++ b/podman/tests/unit/test_networksmanager.py @@ -124,7 +124,8 @@ def test_get(self, mock): actual = self.client.networks.get("podman") self.assertIsInstance(actual, Network) self.assertEqual( - actual.id, "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9" + actual.id, + "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9", ) @requests_mock.Mocker() @@ -139,13 +140,15 @@ def test_list_libpod(self, mock): self.assertIsInstance(actual[0], Network) self.assertEqual( - actual[0].id, "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9" + actual[0].id, + "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9", ) self.assertEqual(actual[0].attrs["name"], "podman") self.assertIsInstance(actual[1], Network) self.assertEqual( - actual[1].id, "3549b0028b75d981cdda2e573e9cb49dedc200185876df299f912b79f69dabd8" + actual[1].id, + "3549b0028b75d981cdda2e573e9cb49dedc200185876df299f912b79f69dabd8", ) self.assertEqual(actual[1].name, "database") @@ -191,5 +194,5 @@ def test_prune_libpod(self, mock): self.assertListEqual(actual["NetworksDeleted"], ["podman", "database"]) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_parse_utils.py b/podman/tests/unit/test_parse_utils.py index a7768deb..e20002a9 100644 --- a/podman/tests/unit/test_parse_utils.py +++ b/podman/tests/unit/test_parse_utils.py @@ -90,5 +90,5 @@ def test_stream_helper_with_decode(self): self.assertDictEqual(json.loads(expected), actual) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_pod.py b/podman/tests/unit/test_pod.py index 7fb5dd13..d166dd5d 100644 --- a/podman/tests/unit/test_pod.py +++ b/podman/tests/unit/test_pod.py @@ -165,17 +165,17 @@ def test_top(self, mock): body = { "Processes": [ [ - 'jhonce', - '2417', - '2274', - '0', - 'Mar01', - '?', - '00:00:01', + "jhonce", + "2417", + "2274", + "0", + "Mar01", + "?", + "00:00:01", '/usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "/usr/bin/gnome-session"', ], - ['jhonce', '5544', '3522', '0', 'Mar01', 'pts/1', '00:00:02', '-bash'], - ['jhonce', '6140', '3522', '0', 'Mar01', 'pts/2', '00:00:00', '-bash'], + ["jhonce", "5544", "3522", "0", "Mar01", "pts/1", "00:00:02", "-bash"], + ["jhonce", "6140", "3522", "0", "Mar01", "pts/2", "00:00:00", "-bash"], ], "Titles": ["UID", "PID", "PPID", "C", "STIME", "TTY", "TIME CMD"], } @@ -206,5 +206,5 @@ def test_unpause(self, mock): self.assertTrue(adapter.called_once) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_podmanclient.py b/podman/tests/unit/test_podmanclient.py index 7456bad3..e6f9e7fb 100644 --- a/podman/tests/unit/test_podmanclient.py +++ b/podman/tests/unit/test_podmanclient.py @@ -45,7 +45,7 @@ def mocked_open(self, *args, **kwargs): self.mocked_open = mocked_open - @mock.patch('requests.Session.close') + @mock.patch("requests.Session.close") def test_close(self, mock_close): self.client.close() @@ -66,7 +66,9 @@ def test_contextmanager(self, mock): self.assertDictEqual(actual, body) self.assertIn("User-Agent", mock.last_request.headers) self.assertIn( - "PodmanPy/", mock.last_request.headers["User-Agent"], mock.last_request.headers + "PodmanPy/", + mock.last_request.headers["User-Agent"], + mock.last_request.headers, ) def test_swarm(self): @@ -109,5 +111,5 @@ def test_connect_default(self): PodmanClientTestCase.opener.assert_called_with(expected, encoding="utf-8") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_podsmanager.py b/podman/tests/unit/test_podsmanager.py index 4512f8e6..5cbc1fb2 100644 --- a/podman/tests/unit/test_podsmanager.py +++ b/podman/tests/unit/test_podsmanager.py @@ -66,7 +66,8 @@ def test_get(self, mock): "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8" ) self.assertEqual( - actual.id, "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8" + actual.id, + "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8", ) @requests_mock.Mocker() @@ -96,10 +97,12 @@ def test_list(self, mock): actual = self.client.pods.list() self.assertEqual( - actual[0].id, "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8" + actual[0].id, + "c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8", ) self.assertEqual( - actual[1].id, "c847d00ed0474835a2e246f00e90346fe98d388f98064f4494953c5fb921b8bc" + actual[1].id, + "c847d00ed0474835a2e246f00e90346fe98d388f98064f4494953c5fb921b8bc", ) @requests_mock.Mocker() @@ -134,17 +137,17 @@ def test_stats(self, mock): body = { "Processes": [ [ - 'jhonce', - '2417', - '2274', - '0', - 'Mar01', - '?', - '00:00:01', + "jhonce", + "2417", + "2274", + "0", + "Mar01", + "?", + "00:00:01", '/usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "/usr/bin/gnome-session"', ], - ['jhonce', '5544', '3522', '0', 'Mar01', 'pts/1', '00:00:02', '-bash'], - ['jhonce', '6140', '3522', '0', 'Mar01', 'pts/2', '00:00:00', '-bash'], + ["jhonce", "5544", "3522", "0", "Mar01", "pts/1", "00:00:02", "-bash"], + ["jhonce", "6140", "3522", "0", "Mar01", "pts/2", "00:00:00", "-bash"], ], "Titles": ["UID", "PID", "PPID", "C", "STIME", "TTY", "TIME CMD"], } @@ -164,17 +167,17 @@ def test_stats_without_decode(self, mock): body = { "Processes": [ [ - 'jhonce', - '2417', - '2274', - '0', - 'Mar01', - '?', - '00:00:01', + "jhonce", + "2417", + "2274", + "0", + "Mar01", + "?", + "00:00:01", '/usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "/usr/bin/gnome-session"', ], - ['jhonce', '5544', '3522', '0', 'Mar01', 'pts/1', '00:00:02', '-bash'], - ['jhonce', '6140', '3522', '0', 'Mar01', 'pts/2', '00:00:00', '-bash'], + ["jhonce", "5544", "3522", "0", "Mar01", "pts/1", "00:00:02", "-bash"], + ["jhonce", "6140", "3522", "0", "Mar01", "pts/2", "00:00:00", "-bash"], ], "Titles": ["UID", "PID", "PPID", "C", "STIME", "TTY", "TIME CMD"], } @@ -185,7 +188,8 @@ def test_stats_without_decode(self, mock): ) actual = self.client.pods.stats( - name="c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8", decode=True + name="c8b9f5b17dc1406194010c752fc6dcb330192032e27648db9b14060447ecf3b8", + decode=True, ) self.assertDictEqual(actual, body) @@ -194,30 +198,30 @@ def test_top_with_streaming(self, mock): stream = [ [ { - 'CPU': '2.53%', - 'MemUsage': '49.15kB / 16.71GB', - 'MemUsageBytes': '48KiB / 15.57GiB', - 'Mem': '0.00%', - 'NetIO': '7.638kB / 430B', - 'BlockIO': '-- / --', - 'PIDS': '1', - 'Pod': '1c948ab42339', - 'CID': 'd999c49a7b6c', - 'Name': '1c948ab42339-infra', + "CPU": "2.53%", + "MemUsage": "49.15kB / 16.71GB", + "MemUsageBytes": "48KiB / 15.57GiB", + "Mem": "0.00%", + "NetIO": "7.638kB / 430B", + "BlockIO": "-- / --", + "PIDS": "1", + "Pod": "1c948ab42339", + "CID": "d999c49a7b6c", + "Name": "1c948ab42339-infra", } ], [ { - 'CPU': '1.46%', - 'MemUsage': '57.23B / 16.71GB', - 'MemUsageBytes': '48KiB / 15.57GiB', - 'Mem': '0.00%', - 'NetIO': '7.638kB / 430B', - 'BlockIO': '-- / --', - 'PIDS': '1', - 'Pod': '1c948ab42339', - 'CID': 'd999c49a7b6c', - 'Name': '1c948ab42339-infra', + "CPU": "1.46%", + "MemUsage": "57.23B / 16.71GB", + "MemUsageBytes": "48KiB / 15.57GiB", + "Mem": "0.00%", + "NetIO": "7.638kB / 430B", + "BlockIO": "-- / --", + "PIDS": "1", + "Pod": "1c948ab42339", + "CID": "d999c49a7b6c", + "Name": "1c948ab42339-infra", } ], ] @@ -246,5 +250,5 @@ def test_stats_400(self): self.client.pods.stats(all=True, name="container") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_registrydata.py b/podman/tests/unit/test_registrydata.py index 90d0d31f..62d7eb6a 100644 --- a/podman/tests/unit/test_registrydata.py +++ b/podman/tests/unit/test_registrydata.py @@ -56,7 +56,8 @@ def test_init(self, mock): collection=ImagesManager(client=self.client.api), ) self.assertEqual( - actual.id, "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab" + actual.id, + "326dd9d7add24646a325e8eaa82125294027db2332e49c5828d96312c5d773ab", ) def test_platform(self): @@ -106,5 +107,5 @@ def test_platform_500(self): rd.has_platform("This/is/not/a/legal/image/name") -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_secrets.py b/podman/tests/unit/test_secrets.py index ab5f521f..c93a949f 100644 --- a/podman/tests/unit/test_secrets.py +++ b/podman/tests/unit/test_secrets.py @@ -20,5 +20,5 @@ def test_podmanclient(self): self.assertIsInstance(manager, SecretsManager) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_system.py b/podman/tests/unit/test_system.py index bb6c1bfa..6a62948a 100644 --- a/podman/tests/unit/test_system.py +++ b/podman/tests/unit/test_system.py @@ -71,5 +71,5 @@ def test_version(self, mock): self.assertDictEqual(self.client.version(), body) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_volume.py b/podman/tests/unit/test_volume.py index f7f65350..c150e04e 100644 --- a/podman/tests/unit/test_volume.py +++ b/podman/tests/unit/test_volume.py @@ -40,5 +40,5 @@ def test_remove(self, mock): self.assertTrue(adapter.called_once) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/podman/tests/unit/test_volumesmanager.py b/podman/tests/unit/test_volumesmanager.py index 6650929b..6111660f 100644 --- a/podman/tests/unit/test_volumesmanager.py +++ b/podman/tests/unit/test_volumesmanager.py @@ -138,5 +138,5 @@ def test_prune(self, mock): ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/pyproject.toml b/pyproject.toml index 9db36747..5361b2fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,4 +30,3 @@ log_cli = true log_cli_level = "DEBUG" log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)" log_cli_date_format = "%Y-%m-%d %H:%M:%S" -