Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pytest-testinfra for 
openSUSE:Factory checked in at 2023-05-23 14:53:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-testinfra (Old)
 and      /work/SRC/openSUSE:Factory/.python-pytest-testinfra.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pytest-testinfra"

Tue May 23 14:53:51 2023 rev:4 rq:1088334 version:8.1.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-pytest-testinfra/python-pytest-testinfra.changes
  2023-05-10 16:18:58.419134126 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pytest-testinfra.new.1533/python-pytest-testinfra.changes
        2023-05-23 14:54:09.842348460 +0200
@@ -1,0 +2,20 @@
+Mon May 22 04:16:57 UTC 2023 - Georg Pfuetzenreuter 
<georg.pfuetzenreu...@suse.com>
+
+- Update to 8.1.0:
+  * [NEW] Add Windows support for File and Service modules
+  * [NEW] Add File.is_executable property
+
+- 8.0.0:
+  * [NEW] Add Group.members attribute
+  * [NEW] Add File.inode attribute
+  * [NEW] Add Interface.routes() method
+  * [NEW] Add Docker.is_restarting attribute
+  * [FIX] Fix possible error in Interface.default()
+  * [FIX] Fix busybox detection in Process module
+  * [FIX] Fix possible KeyError in SysInfo module
+  * [BREAKING] drop support for python 3.7
+
+- 7.0.1:
+  * [FIX] Fix command -v compatibility with dash shell
+
+-------------------------------------------------------------------

Old:
----
  pytest-testinfra-7.0.0.tar.gz

New:
----
  pytest-testinfra-8.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pytest-testinfra.spec ++++++
--- /var/tmp/diff_new_pack.4B4s1W/_old  2023-05-23 14:54:10.658353288 +0200
+++ /var/tmp/diff_new_pack.4B4s1W/_new  2023-05-23 14:54:10.662353312 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-pytest-testinfra
-Version:        7.0.0
+Version:        8.1.0
 Release:        0
 Summary:        Python module to test infrastructures
 License:        Apache-2.0

++++++ pytest-testinfra-7.0.0.tar.gz -> pytest-testinfra-8.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/.flake8 
new/pytest-testinfra-8.1.0/.flake8
--- old/pytest-testinfra-7.0.0/.flake8  2022-12-01 21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/.flake8  2023-05-21 17:38:00.000000000 +0200
@@ -1,5 +1,10 @@
 [flake8]
-extend-ignore = E203, E266, E501, H301, H306
+extend-ignore =
+    E203,
+    E266,
+    E501,
+    H301,
+    H306
 # line length is intentionally set to 80 here because black uses Bugbear
 # See 
https://github.com/psf/black/blob/master/docs/the_black_code_style.md#line-length
 for more details
 max-line-length = 80
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/.pre-commit-config.yaml 
new/pytest-testinfra-8.1.0/.pre-commit-config.yaml
--- old/pytest-testinfra-7.0.0/.pre-commit-config.yaml  1970-01-01 
01:00:00.000000000 +0100
+++ new/pytest-testinfra-8.1.0/.pre-commit-config.yaml  2023-05-21 
17:38:00.000000000 +0200
@@ -0,0 +1,61 @@
+---
+ci:
+  # format compatible with commitlint
+  autoupdate_commit_msg: "chore: pre-commit autoupdate"
+  autoupdate_schedule: monthly
+  autofix_commit_msg: |
+    chore: auto fixes from pre-commit.com hooks
+
+    for more information, see https://pre-commit.ci
+# exclude: >
+#   (?x)^(
+#   )$
+repos:
+  - repo: meta
+    hooks:
+      - id: check-useless-excludes
+  - repo: https://github.com/pre-commit/pre-commit-hooks.git
+    rev: v4.4.0
+    hooks:
+      - id: end-of-file-fixer
+      - id: trailing-whitespace
+      - id: mixed-line-ending
+      - id: fix-byte-order-marker
+      - id: check-executables-have-shebangs
+      - id: check-merge-conflict
+      - id: debug-statements
+        language_version: python3
+  - repo: https://github.com/PyCQA/isort
+    rev: 5.12.0
+    hooks:
+      - id: isort
+        args:
+          # 
https://github.com/pre-commit/mirrors-isort/issues/9#issuecomment-624404082
+          - --filter-files
+  - repo: https://github.com/psf/black
+    rev: 22.10.0
+    hooks:
+      - id: black
+        language_version: python3
+  - repo: https://github.com/pycqa/flake8.git
+    rev: 6.0.0
+    hooks:
+      - id: flake8
+        language_version: python3
+        additional_dependencies:
+          - flake8-bugbear
+          - flake8-comprehensions
+          - flake8-debugger
+          - flake8-logging-format
+          - flake8-pep3101
+          - flake8-print
+  - repo: https://github.com/pre-commit/mirrors-mypy
+    rev: v0.991
+    hooks:
+      - id: mypy
+        # empty args needed in order to match mypy cli behavior
+        additional_dependencies:
+          - types-paramiko
+          - types-setuptools
+          - setuptools-scm
+          - alabaster
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/CHANGELOG.rst 
new/pytest-testinfra-8.1.0/CHANGELOG.rst
--- old/pytest-testinfra-7.0.0/CHANGELOG.rst    2022-12-01 21:30:39.000000000 
+0100
+++ new/pytest-testinfra-8.1.0/CHANGELOG.rst    2023-05-21 17:38:00.000000000 
+0200
@@ -2,6 +2,29 @@
 Changelog
 =========
 
+8.1.0
+=====
+
+* [NEW] Add Windows support for File and Service modules
+* [NEW] Add File.is_executable property
+
+8.0.0
+=====
+
+* [NEW] Add Group.members attribute
+* [NEW] Add File.inode attribute
+* [NEW] Add Interface.routes() method
+* [NEW] Add Docker.is_restarting attribute
+* [FIX] Fix possible error in Interface.default()
+* [FIX] Fix busybox detection in Process module
+* [FIX] Fix possible KeyError in SysInfo module
+* [BREAKING] Drop support for python 3.7
+
+7.0.1
+=====
+
+* [FIX] Fix `command -v` compatibility with dash shell
+
 7.0.0
 =====
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/CONTRIBUTING.rst 
new/pytest-testinfra-8.1.0/CONTRIBUTING.rst
--- old/pytest-testinfra-7.0.0/CONTRIBUTING.rst 2022-12-01 21:30:39.000000000 
+0100
+++ new/pytest-testinfra-8.1.0/CONTRIBUTING.rst 2023-05-21 17:38:00.000000000 
+0200
@@ -7,9 +7,6 @@
 Pull requests
 =============
 
-Regardless the review by a developer, a pull request will trigger automatic
-tests on https://travis-ci.org/pytest-dev/pytest-testinfra/
-
 You're encouraged to setup a full test environment, to add tests and check if
 all the tests pass *before* submitting your pull request. To run the complete
 test suite you must install:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/LICENSE 
new/pytest-testinfra-8.1.0/LICENSE
--- old/pytest-testinfra-7.0.0/LICENSE  2022-12-01 21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/LICENSE  2023-05-21 17:38:00.000000000 +0200
@@ -173,4 +173,3 @@
       defend, and hold each Contributor harmless for any liability
       incurred by, or claims asserted against, such Contributor by reason
       of your accepting any such warranty or additional liability.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/MANIFEST.in 
new/pytest-testinfra-8.1.0/MANIFEST.in
--- old/pytest-testinfra-7.0.0/MANIFEST.in      2022-12-01 21:30:39.000000000 
+0100
+++ new/pytest-testinfra-8.1.0/MANIFEST.in      2023-05-21 17:38:00.000000000 
+0200
@@ -8,6 +8,7 @@
 include .flake8
 include mypy.ini
 include Makefile
+include *.yaml
 include README.rst CONTRIBUTING.rst CHANGELOG.rst
 include MANIFEST.in
 include ansible.cfg
@@ -15,7 +16,6 @@
 include test-requirements.txt
 include LICENSE
 exclude .editorconfig
-exclude .travis.yml
 exclude .gitignore
 prune doc/build
 prune .github
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/PKG-INFO 
new/pytest-testinfra-8.1.0/PKG-INFO
--- old/pytest-testinfra-7.0.0/PKG-INFO 2022-12-01 21:30:48.000000000 +0100
+++ new/pytest-testinfra-8.1.0/PKG-INFO 2023-05-21 17:38:13.932854400 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pytest-testinfra
-Version: 7.0.0
+Version: 8.1.0
 Summary: Test infrastructures
 Home-page: https://github.com/pytest-dev/pytest-testinfra
 Author: Philippe Pepiot
@@ -15,14 +15,13 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Topic :: Software Development :: Testing
 Classifier: Topic :: System :: Systems Administration
 Classifier: Framework :: Pytest
-Requires-Python: >=3.7
+Requires-Python: >=3.8
 Description-Content-Type: text/x-rst
 Provides-Extra: ansible
 Provides-Extra: docker
@@ -53,7 +52,7 @@
 License
 =======
 
-`Apache License 2.0 
<https://github.com/pytest-dev/pytest-testinfra/blob/master/LICENSE>`_
+`Apache License 2.0 
<https://github.com/pytest-dev/pytest-testinfra/blob/main/LICENSE>`_
 
 The logo is licensed under the `Creative Commons NoDerivatives 4.0 License 
<https://creativecommons.org/licenses/by-nd/4.0/>`_
 If you have some other use in mind, contact us.
@@ -66,7 +65,7 @@
     $ pip install pytest-testinfra
 
     # or install the devel version
-    $ pip install 
'git+https://github.com/pytest-dev/pytest-testinfra@master#egg=pytest-testinfra'
+    $ pip install 
'git+https://github.com/pytest-dev/pytest-testinfra@main#egg=pytest-testinfra'
 
 
 Write your first tests file to `test_myinfra.py`:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/README.rst 
new/pytest-testinfra-8.1.0/README.rst
--- old/pytest-testinfra-7.0.0/README.rst       2022-12-01 21:30:39.000000000 
+0100
+++ new/pytest-testinfra-8.1.0/README.rst       2023-05-21 17:38:00.000000000 
+0200
@@ -17,7 +17,7 @@
 License
 =======
 
-`Apache License 2.0 
<https://github.com/pytest-dev/pytest-testinfra/blob/master/LICENSE>`_
+`Apache License 2.0 
<https://github.com/pytest-dev/pytest-testinfra/blob/main/LICENSE>`_
 
 The logo is licensed under the `Creative Commons NoDerivatives 4.0 License 
<https://creativecommons.org/licenses/by-nd/4.0/>`_
 If you have some other use in mind, contact us.
@@ -30,7 +30,7 @@
     $ pip install pytest-testinfra
 
     # or install the devel version
-    $ pip install 
'git+https://github.com/pytest-dev/pytest-testinfra@master#egg=pytest-testinfra'
+    $ pip install 
'git+https://github.com/pytest-dev/pytest-testinfra@main#egg=pytest-testinfra'
 
 
 Write your first tests file to `test_myinfra.py`:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/dev-requirements.txt 
new/pytest-testinfra-8.1.0/dev-requirements.txt
--- old/pytest-testinfra-7.0.0/dev-requirements.txt     2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/dev-requirements.txt     2023-05-21 
17:38:00.000000000 +0200
@@ -1,4 +1,3 @@
 sphinx>=1.3
 alabaster>=0.7.2
-hacking>=4.0
 .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/doc/source/conf.py 
new/pytest-testinfra-8.1.0/doc/source/conf.py
--- old/pytest-testinfra-7.0.0/doc/source/conf.py       2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/doc/source/conf.py       2023-05-21 
17:38:00.000000000 +0200
@@ -21,11 +21,11 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import os
-import sys
-
 import datetime
+import os
 import subprocess
+import sys
+from typing import Dict, List
 
 import alabaster
 
@@ -92,7 +92,7 @@
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = []
+exclude_patterns: List[str] = []
 
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
@@ -133,7 +133,6 @@
     "github_user": "pytest-dev",
     "github_repo": "pytest-testinfra",
     "github_button": True,
-    "travis_button": True,
     "extra_nav_links": {
         "View on github": "https://github.com/pytest-dev/pytest-testinfra";,
     },
@@ -222,7 +221,7 @@
 
 # -- Options for LaTeX output ---------------------------------------------
 
-latex_elements = {
+latex_elements: Dict[str, tuple] = {
     # The paper size ('letterpaper' or 'a4paper')
     # 'papersize': 'letterpaper',
     # The font size ('10pt', '11pt' or '12pt').
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/doc/source/examples.rst 
new/pytest-testinfra-8.1.0/doc/source/examples.rst
--- old/pytest-testinfra-7.0.0/doc/source/examples.rst  2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/doc/source/examples.rst  2023-05-21 
17:38:00.000000000 +0200
@@ -137,7 +137,7 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 KitchenCI (aka Test Kitchen) can use testinfra via its :code:`shell` verifier.
-Add the following to your :code:`.kitchen.yml`, this requires installing 
`paramiko` 
+Add the following to your :code:`.kitchen.yml`, this requires installing 
`paramiko`
 additionally (on your host machine, not in the VM handled by kitchen) ::
 
     verifier:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/images/alpine/Dockerfile 
new/pytest-testinfra-8.1.0/images/alpine/Dockerfile
--- old/pytest-testinfra-7.0.0/images/alpine/Dockerfile 2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/images/alpine/Dockerfile 2023-05-21 
17:38:00.000000000 +0200
@@ -12,5 +12,3 @@
 
 EXPOSE 22
 CMD ["/sbin/init"]
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/images/centos_7/Dockerfile 
new/pytest-testinfra-8.1.0/images/centos_7/Dockerfile
--- old/pytest-testinfra-7.0.0/images/centos_7/Dockerfile       2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/images/centos_7/Dockerfile       1970-01-01 
01:00:00.000000000 +0100
@@ -1,22 +0,0 @@
-FROM centos:7
-
-RUN yum -y install openssh-server && yum clean all &&\
-    (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do if ! test $i 
= systemd-tmpfiles-setup.service; then rm -f $i; fi; done) && \
-    rm -f /lib/systemd/system/multi-user.target.wants/* && \
-    rm -f /etc/systemd/system/*.wants/* && \
-    rm -f /lib/systemd/system/local-fs.target.wants/* && \
-    rm -f /lib/systemd/system/sockets.target.wants/*udev* && \
-    rm -f /lib/systemd/system/sockets.target.wants/*initctl* && \
-    rm -f /lib/systemd/system/basic.target.wants/* && \
-    rm -f /lib/systemd/system/anaconda.target.wants/* && \
-    rm -f /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_rsa_key && \
-    ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_ecdsa_key && \
-    ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key && \
-    sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" 
/etc/ssh/sshd_config && \
-    systemctl enable sshd.service && \
-    mkdir -p /root/.ssh && \
-    echo "ssh-rsa 
AAAAB3NzaC1yc2EAAAADAQABAAABAQCgDryK4AjJeifuc2N54St13KMNlnGLAtibQSMmvSyrhH7XJ1atnBo1HrJhGZNNBVKM67+zYNc9J3fg3qI1g63vSQAA+nXMsDYwu4BPwupakpwJELcGZJxsUGzjGVotVpqPIX5nW8NBGvkVuObI4UELOleq5mQMTGerJO64KkSVi20FDwPJn3q8GG2zk3pESiDA5ShEyFhYC8vOLfSSYD0LYmShAVGCLEgiNb+OXQL6ZRvzqfFEzL0QvaI/l3mb6b0VFPAO4QWOL0xj3cWzOZXOqht3V85CZvSk8ISdNgwCjXLZsPeaYL/toHNvBF30VMrDZ7w4SDU0ZZLEsc/ezxjb"
 > /root/.ssh/authorized_keys
-
-VOLUME ["/sys/fs/cgroup"]
-EXPOSE 22
-CMD ["/usr/sbin/init"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/images/rockylinux8/Dockerfile 
new/pytest-testinfra-8.1.0/images/rockylinux8/Dockerfile
--- old/pytest-testinfra-7.0.0/images/rockylinux8/Dockerfile    1970-01-01 
01:00:00.000000000 +0100
+++ new/pytest-testinfra-8.1.0/images/rockylinux8/Dockerfile    2023-05-21 
17:38:00.000000000 +0200
@@ -0,0 +1,21 @@
+FROM rockylinux:8
+
+RUN dnf -y install openssh-server procps python39 && dnf clean all &&\
+    (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do if ! test $i 
= systemd-tmpfiles-setup.service; then rm -f $i; fi; done) && \
+    rm -f /lib/systemd/system/multi-user.target.wants/* && \
+    rm -f /etc/systemd/system/*.wants/* && \
+    rm -f /lib/systemd/system/local-fs.target.wants/* && \
+    rm -f /lib/systemd/system/sockets.target.wants/*udev* && \
+    rm -f /lib/systemd/system/sockets.target.wants/*initctl* && \
+    rm -f /lib/systemd/system/basic.target.wants/* && \
+    rm -f /lib/systemd/system/anaconda.target.wants/* && \
+    rm -f /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_rsa_key && \
+    ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_ecdsa_key && \
+    ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key && \
+    sed -i "s/#UsePrivilegeSeparation.*/UsePrivilegeSeparation no/g" 
/etc/ssh/sshd_config && \
+    systemctl enable sshd.service && \
+    mkdir -p /root/.ssh && \
+    echo "ssh-rsa 
AAAAB3NzaC1yc2EAAAADAQABAAABAQCgDryK4AjJeifuc2N54St13KMNlnGLAtibQSMmvSyrhH7XJ1atnBo1HrJhGZNNBVKM67+zYNc9J3fg3qI1g63vSQAA+nXMsDYwu4BPwupakpwJELcGZJxsUGzjGVotVpqPIX5nW8NBGvkVuObI4UELOleq5mQMTGerJO64KkSVi20FDwPJn3q8GG2zk3pESiDA5ShEyFhYC8vOLfSSYD0LYmShAVGCLEgiNb+OXQL6ZRvzqfFEzL0QvaI/l3mb6b0VFPAO4QWOL0xj3cWzOZXOqht3V85CZvSk8ISdNgwCjXLZsPeaYL/toHNvBF30VMrDZ7w4SDU0ZZLEsc/ezxjb"
 > /root/.ssh/authorized_keys
+
+EXPOSE 22
+CMD ["/usr/sbin/init"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest-testinfra-7.0.0/images/ubuntu_xenial/Dockerfile 
new/pytest-testinfra-8.1.0/images/ubuntu_xenial/Dockerfile
--- old/pytest-testinfra-7.0.0/images/ubuntu_xenial/Dockerfile  2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/images/ubuntu_xenial/Dockerfile  2023-05-21 
17:38:00.000000000 +0200
@@ -20,4 +20,3 @@
 
 EXPOSE 22
 CMD ["/sbin/init"]
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/mypy.ini 
new/pytest-testinfra-8.1.0/mypy.ini
--- old/pytest-testinfra-7.0.0/mypy.ini 2022-12-01 21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/mypy.ini 2023-05-21 17:38:00.000000000 +0200
@@ -1,14 +1,18 @@
 [mypy]
+files = .
 # XXX: goal is to turn it on
 strict = False
 check_untyped_defs = True
 show_error_codes = True
 
-[mypy-pytest.*]
-ignore_missing_imports = True
-
 [mypy-salt.*]
 ignore_missing_imports = True
 
 [mypy-winrm.*]
 ignore_missing_imports = True
+
+[mypy-alabaster.*]
+ignore_missing_imports = True
+
+[mypy-setuptools_scm.*]
+ignore_missing_imports = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/pyproject.toml 
new/pytest-testinfra-8.1.0/pyproject.toml
--- old/pytest-testinfra-7.0.0/pyproject.toml   2022-12-01 21:30:39.000000000 
+0100
+++ new/pytest-testinfra-8.1.0/pyproject.toml   2023-05-21 17:38:00.000000000 
+0200
@@ -1,5 +1,5 @@
 [tool.black]
-target-version = ['py37']
+target-version = ['py38']
 include = '\.pyi?$'
 exclude = '''
 (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest-testinfra-7.0.0/pytest_testinfra.egg-info/PKG-INFO 
new/pytest-testinfra-8.1.0/pytest_testinfra.egg-info/PKG-INFO
--- old/pytest-testinfra-7.0.0/pytest_testinfra.egg-info/PKG-INFO       
2022-12-01 21:30:48.000000000 +0100
+++ new/pytest-testinfra-8.1.0/pytest_testinfra.egg-info/PKG-INFO       
2023-05-21 17:38:13.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pytest-testinfra
-Version: 7.0.0
+Version: 8.1.0
 Summary: Test infrastructures
 Home-page: https://github.com/pytest-dev/pytest-testinfra
 Author: Philippe Pepiot
@@ -15,14 +15,13 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Topic :: Software Development :: Testing
 Classifier: Topic :: System :: Systems Administration
 Classifier: Framework :: Pytest
-Requires-Python: >=3.7
+Requires-Python: >=3.8
 Description-Content-Type: text/x-rst
 Provides-Extra: ansible
 Provides-Extra: docker
@@ -53,7 +52,7 @@
 License
 =======
 
-`Apache License 2.0 
<https://github.com/pytest-dev/pytest-testinfra/blob/master/LICENSE>`_
+`Apache License 2.0 
<https://github.com/pytest-dev/pytest-testinfra/blob/main/LICENSE>`_
 
 The logo is licensed under the `Creative Commons NoDerivatives 4.0 License 
<https://creativecommons.org/licenses/by-nd/4.0/>`_
 If you have some other use in mind, contact us.
@@ -66,7 +65,7 @@
     $ pip install pytest-testinfra
 
     # or install the devel version
-    $ pip install 
'git+https://github.com/pytest-dev/pytest-testinfra@master#egg=pytest-testinfra'
+    $ pip install 
'git+https://github.com/pytest-dev/pytest-testinfra@main#egg=pytest-testinfra'
 
 
 Write your first tests file to `test_myinfra.py`:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest-testinfra-7.0.0/pytest_testinfra.egg-info/SOURCES.txt 
new/pytest-testinfra-8.1.0/pytest_testinfra.egg-info/SOURCES.txt
--- old/pytest-testinfra-7.0.0/pytest_testinfra.egg-info/SOURCES.txt    
2022-12-01 21:30:48.000000000 +0100
+++ new/pytest-testinfra-8.1.0/pytest_testinfra.egg-info/SOURCES.txt    
2023-05-21 17:38:13.000000000 +0200
@@ -1,4 +1,5 @@
 .flake8
+.pre-commit-config.yaml
 CHANGELOG.rst
 CONTRIBUTING.rst
 LICENSE
@@ -27,8 +28,8 @@
 doc/source/_templates/piwik.html
 images/alpine/Dockerfile
 images/archlinux/Dockerfile
-images/centos_7/Dockerfile
 images/debian_bullseye/Dockerfile
+images/rockylinux8/Dockerfile
 images/ubuntu_xenial/Dockerfile
 pytest_testinfra.egg-info/PKG-INFO
 pytest_testinfra.egg-info/SOURCES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/setup.cfg 
new/pytest-testinfra-8.1.0/setup.cfg
--- old/pytest-testinfra-7.0.0/setup.cfg        2022-12-01 21:30:48.000000000 
+0100
+++ new/pytest-testinfra-8.1.0/setup.cfg        2023-05-21 17:38:13.932854400 
+0200
@@ -18,7 +18,6 @@
        Programming Language :: Python
        Programming Language :: Python :: 3
        Programming Language :: Python :: 3 :: Only
-       Programming Language :: Python :: 3.7
        Programming Language :: Python :: 3.8
        Programming Language :: Python :: 3.9
        Programming Language :: Python :: 3.10
@@ -28,7 +27,7 @@
 
 [options]
 use_scm_version = True
-python_requires = >=3.7
+python_requires = >=3.8
 packages = find:
 setup_requires = 
        setuptools_scm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/test/conftest.py 
new/pytest-testinfra-8.1.0/test/conftest.py
--- old/pytest-testinfra-7.0.0/test/conftest.py 2022-12-01 21:30:39.000000000 
+0100
+++ new/pytest-testinfra-8.1.0/test/conftest.py 2023-05-21 17:38:00.000000000 
+0200
@@ -56,7 +56,7 @@
 DOCKER_IMAGES = [
     "alpine",
     "archlinux",
-    "centos_7",
+    "rockylinux8",
     "debian_bullseye",
     "ubuntu_xenial",
 ]
@@ -113,7 +113,13 @@
         request.addfinalizer(teardown)
 
         port = check_output("docker port %s 22", docker_id)
-        port = int(port.rsplit(":", 1)[-1])
+        # IPv4 addresses seem to be reported consistently
+        # in the first line of the output.
+        # To workaround https://github.com/moby/moby/issues/42442
+        # use only the values of the first line of the command
+        # output
+        port = int(port.splitlines()[0].rsplit(":", 1)[-1])
+
         return docker_id, docker_host, port
 
     fname = "_docker_container_{}_{}".format(image, scope)
@@ -181,7 +187,7 @@
         # Wait ssh to be up
         service = testinfra.get_host(docker_id, connection="docker").service
 
-        images_with_sshd = ("centos_7", "alpine", "archlinux")
+        images_with_sshd = ("rockylinux8", "alpine", "archlinux")
 
         if image in images_with_sshd:
             service_name = "sshd"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/test/test_backends.py 
new/pytest-testinfra-8.1.0/test/test_backends.py
--- old/pytest-testinfra-7.0.0/test/test_backends.py    2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/test/test_backends.py    2023-05-21 
17:38:00.000000000 +0200
@@ -129,7 +129,7 @@
                 b"[g1]\n"
                 b"debian\n"
                 b"[g2]\n"
-                b"centos\n"
+                b"rockylinux\n"
                 b"[g3:children]\n"
                 b"g1\n"
                 b"g2\n"
@@ -142,13 +142,13 @@
         def get_hosts(spec):
             return AnsibleRunner(f.name).get_hosts(spec)
 
-        assert get_hosts("all") == ["centos", "debian", "ungrp"]
-        assert get_hosts("*") == ["centos", "debian", "ungrp"]
+        assert get_hosts("all") == ["debian", "rockylinux", "ungrp"]
+        assert get_hosts("*") == ["debian", "rockylinux", "ungrp"]
         assert get_hosts("g1") == ["debian"]
-        assert get_hosts("*2") == ["centos"]
+        assert get_hosts("*2") == ["rockylinux"]
         assert get_hosts("*ia*") == ["debian"]
-        assert get_hosts("*3") == ["centos", "debian"]
-        assert get_hosts("*4") == ["centos", "debian"]
+        assert get_hosts("*3") == ["debian", "rockylinux"]
+        assert get_hosts("*4") == ["debian", "rockylinux"]
         assert get_hosts("ungrouped") == ["ungrp"]
         assert get_hosts("un*") == ["ungrp"]
         assert get_hosts("nope") == []
@@ -159,7 +159,7 @@
         f.write(
             (
                 b"debian a=b c=d\n"
-                b"centos e=f\n"
+                b"rockylinux e=f\n"
                 b"[all:vars]\n"
                 b"a=a\n"
                 b"[g]\n"
@@ -174,9 +174,9 @@
             return AnsibleRunner(f.name).get_variables(host)
 
         groups = {
-            "all": ["centos", "debian"],
+            "all": ["debian", "rockylinux"],
             "g": ["debian"],
-            "ungrouped": ["centos"],
+            "ungrouped": ["rockylinux"],
         }
         assert get_vars("debian") == {
             "a": "b",
@@ -186,10 +186,10 @@
             "group_names": ["g"],
             "groups": groups,
         }
-        assert get_vars("centos") == {
+        assert get_vars("rockylinux") == {
             "a": "a",
             "e": "f",
-            "inventory_hostname": "centos",
+            "inventory_hostname": "rockylinux",
             "group_names": ["ungrouped"],
             "groups": groups,
         }
@@ -485,12 +485,12 @@
         assert obj.get_connection_type() == connection_type
 
 
-@pytest.mark.testinfra_hosts("docker://centos_7", "ssh://centos_7")
+@pytest.mark.testinfra_hosts("docker://rockylinux8", "ssh://rockylinux8")
 def test_docker_encoding(host):
     encoding = host.check_output(
-        "python -c 'import locale;print(locale.getpreferredencoding())'"
+        "python3 -c 'import locale;print(locale.getpreferredencoding())'"
     )
-    assert encoding == "ANSI_X3.4-1968"
+    assert encoding == "UTF-8"
     string = "ťēꞩƫìṇḟřặ ṧꝕèȃǩ ửƫᵮ8"
     assert host.check_output("echo %s | tee /tmp/s.txt", string) == string
     assert host.file("/tmp/s.txt").content_string.strip() == string
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/test/test_modules.py 
new/pytest-testinfra-8.1.0/test/test_modules.py
--- old/pytest-testinfra-7.0.0/test/test_modules.py     2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/test/test_modules.py     2023-05-21 
17:38:00.000000000 +0200
@@ -27,7 +27,7 @@
         for image in (
             "alpine",
             "archlinux",
-            "centos_7",
+            "rockylinux8",
             "debian_bullseye",
             "ubuntu_xenial",
         )
@@ -47,7 +47,7 @@
     version = {
         "alpine": "8.",
         "archlinux": "9.",
-        "centos_7": "7.",
+        "rockylinux8": "8.",
         "debian_bullseye": "1:8.4",
         "ubuntu_xenial": "1:7.2",
     }[docker_image]
@@ -56,7 +56,7 @@
     release = {
         "alpine": "r3",
         "archlinux": None,
-        "centos_7": ".el7",
+        "rockylinux8": ".el8",
         "debian_bullseye": None,
         "ubuntu_xenial": None,
     }[docker_image]
@@ -73,7 +73,7 @@
     assert python.version.startswith("3.9.")
 
 
-@pytest.mark.testinfra_hosts("docker://centos_7")
+@pytest.mark.testinfra_hosts("docker://rockylinux8")
 def test_non_default_package_tool(host):
     # Make non default pkg tool binary present
     host.run("install -m a+rx /bin/true /usr/bin/dpkg-query")
@@ -103,7 +103,7 @@
     release, distribution, codename, arch = {
         "alpine": (r"^3\.14\.", "alpine", None, "x86_64"),
         "archlinux": ("rolling", "arch", None, "x86_64"),
-        "centos_7": (r"^7$", "centos", None, "x86_64"),
+        "rockylinux8": (r"^8.\d+$", "rocky", None, "x86_64"),
         "debian_bullseye": (r"^11", "debian", "bullseye", "x86_64"),
         "ubuntu_xenial": (r"^16\.04$", "ubuntu", "xenial", "x86_64"),
     }[docker_image]
@@ -115,7 +115,7 @@
 
 @all_images
 def test_ssh_service(host, docker_image):
-    if docker_image in ("centos_7", "alpine", "archlinux"):
+    if docker_image in ("rockylinux8", "alpine", "archlinux"):
         name = "sshd"
     else:
         name = "ssh"
@@ -188,6 +188,7 @@
     assert host.facter("virtual") in (
         {"virtual": "docker"},
         {"virtual": "hyperv"},  # github action uses hyperv
+        {"virtual": "physical"},  # I've this on my machine...
     )
 
 
@@ -249,7 +250,7 @@
     args, comm = {
         "alpine": ("/sbin/init", "init"),
         "archlinux": ("/usr/sbin/init", "systemd"),
-        "centos_7": ("/usr/sbin/init", "systemd"),
+        "rockylinux8": ("/usr/sbin/init", "systemd"),
         "debian_bullseye": ("/sbin/init", "systemd"),
         "ubuntu_xenial": ("/sbin/init", "systemd"),
     }[docker_image]
@@ -349,9 +350,23 @@
     assert f == host.file("/d/f")
     assert not d == f
 
+    host.check_output("ln /d/f /d/h")
+    hardlink = host.file("/d/h")
+    assert hardlink.is_file
+    assert not hardlink.is_symlink
+    assert isinstance(hardlink.inode, int)
+    assert isinstance(f.inode, int)
+    assert hardlink.inode == f.inode
+    assert f == host.file("/d/f")
+    assert not d == f
+
     host.check_output("rm -f /d/p && mkfifo /d/p")
     assert host.file("/d/p").is_pipe
 
+    host.check_output("chmod 700 /d/f")
+    assert f.is_executable
+    assert f.mode == 0o700
+
 
 def test_ansible_unavailable(host):
     expected = "Ansible module is only available with " "ansible connection 
backend"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/test-requirements.txt 
new/pytest-testinfra-8.1.0/test-requirements.txt
--- old/pytest-testinfra-7.0.0/test-requirements.txt    2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/test-requirements.txt    2023-05-21 
17:38:00.000000000 +0200
@@ -1,10 +1,7 @@
-mock
 pytest-cov
 pytest-xdist
 paramiko
 types-paramiko
-tornado<5
 salt
 pywinrm
-ansible>=4.9.0,<5
-mypy
+ansible
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/host.py 
new/pytest-testinfra-8.1.0/testinfra/host.py
--- old/pytest-testinfra-7.0.0/testinfra/host.py        2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/host.py        2023-05-21 
17:38:00.000000000 +0200
@@ -14,6 +14,7 @@
 
 import testinfra.backend
 import testinfra.modules
+from testinfra.utils import cached_property
 
 
 class Host:
@@ -27,26 +28,30 @@
     def __repr__(self):
         return "<testinfra.host.Host {}>".format(self.backend.get_pytest_id())
 
+    @cached_property
+    def has_command_v(self):
+        """Return True if `command -v` is available"""
+        return self.run("command -v command").rc == 0
+
     def exists(self, command):
         """Return True if given command exist in $PATH"""
-        rc = self.run_expect([0, 1, 127], "command -v %s", command).rc
-        if rc == 127:
-            return self.run_expect([0, 1], "which %s", command).rc == 0
+        if self.has_command_v:
+            out = self.run("command -v %s", command)
         else:
-            return rc == 0
+            out = self.run_expect([0, 1], "which %s", command)
+        return out.rc == 0
 
     def find_command(self, command, extrapaths=("/sbin", "/usr/sbin")):
         """Return path of given command
 
         raise ValueError if command cannot be found
         """
-        out = self.run_expect([0, 1, 127], "command -v %s", command)
+        if self.has_command_v:
+            out = self.run("command -v %s", command)
+        else:
+            out = self.run_expect([0, 1], "which %s", command)
         if out.rc == 0:
             return out.stdout.rstrip("\r\n")
-        if out.rc == 127:
-            out = self.run_expect([0, 1], "which %s", command)
-            if out.rc == 0:
-                return out.stdout.rstrip("\r\n")
         for basedir in extrapaths:
             path = os.path.join(basedir, command)
             if self.exists(path):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/main.py 
new/pytest-testinfra-8.1.0/testinfra/main.py
--- old/pytest-testinfra-7.0.0/testinfra/main.py        2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/main.py        2023-05-21 
17:38:00.000000000 +0200
@@ -16,5 +16,5 @@
 
 
 def main():
-    warnings.warn("calling testinfra is deprecated, call py.test instead")
+    warnings.warn("calling testinfra is deprecated, call py.test instead", 
stacklevel=1)
     return pytest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/modules/docker.py 
new/pytest-testinfra-8.1.0/testinfra/modules/docker.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/docker.py      2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/docker.py      2023-05-21 
17:38:00.000000000 +0200
@@ -42,6 +42,10 @@
         return self.inspect()["State"]["Running"]
 
     @property
+    def is_restarting(self):
+        return self.inspect()["State"]["Restarting"]
+
+    @property
     def id(self):
         return self.inspect()["Id"]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/modules/file.py 
new/pytest-testinfra-8.1.0/testinfra/modules/file.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/file.py        2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/file.py        2023-05-21 
17:38:00.000000000 +0200
@@ -36,22 +36,32 @@
 
     @property
     def is_file(self):
+        """Test if the path is a regular file"""
         return self.run_test("test -f %s", self.path).rc == 0
 
     @property
     def is_directory(self):
+        """Test if the path exists and a directory"""
         return self.run_test("test -d %s", self.path).rc == 0
 
     @property
+    def is_executable(self):
+        """Test if the path exists and permission to execute is granted"""
+        return self.run_test("test -x %s", self.path).rc == 0
+
+    @property
     def is_pipe(self):
+        """Test if the path exists and is a pipe"""
         return self.run_test("test -p %s", self.path).rc == 0
 
     @property
     def is_socket(self):
+        """Test if the path exists and is a socket"""
         return self.run_test("test -S %s", self.path).rc == 0
 
     @property
     def is_symlink(self):
+        """Test if the path exists and is a symbolic link"""
         return self.run_test("test -L %s", self.path).rc == 0
 
     @property
@@ -86,10 +96,12 @@
 
     @property
     def group(self):
+        """Return file group name as string"""
         raise NotImplementedError
 
     @property
     def gid(self):
+        """Return file group id as integer"""
         raise NotImplementedError
 
     @property
@@ -116,14 +128,20 @@
         raise NotImplementedError
 
     def contains(self, pattern):
+        """Checks content of file for pattern
+
+        This uses grep and thus follows the grep regex syntax.
+        """
         return self.run_test("grep -qs -- %s %s", pattern, self.path).rc == 0
 
     @property
     def md5sum(self):
+        """Compute the MD5 message digest of the file content"""
         raise NotImplementedError
 
     @property
     def sha256sum(self):
+        """Compute the SHA256 message digest of the file content"""
         raise NotImplementedError
 
     def _get_content(self, decode):
@@ -197,6 +215,8 @@
             return BSDFile
         if host.system_info.type == "darwin":
             return DarwinFile
+        if host.system_info.type == "windows":
+            return WindowsFile
         raise NotImplementedError
 
 
@@ -233,6 +253,10 @@
         return int(self.check_output("stat -c %%s %s", self.path))
 
     @property
+    def inode(self):
+        return int(self.check_output("stat -c %%i %s", self.path))
+
+    @property
     def md5sum(self):
         return self.check_output("md5sum %s | cut -d' ' -f1", self.path)
 
@@ -308,3 +332,173 @@
     @property
     def sha256sum(self):
         return self.check_output("cksum -a sha256 < %s", self.path)
+
+
+class WindowsFile(File):
+    @property
+    def exists(self):
+        """Test if file exists
+
+        >>> host.file(r"C:/Users").exists
+        True
+        >>> host.file(r"C:/nonexistent").exists
+        False
+        """
+
+        return (
+            self.check_output(r"powershell -command \"Test-Path '%s'\"", 
self.path)
+            == "True"
+        )
+
+    @property
+    def is_file(self):
+        return (
+            self.check_output(
+                r"powershell -command \"(Get-Item '%s') -is 
[System.IO.FileInfo]\"",
+                self.path,
+            )
+            == "True"
+        )
+
+    @property
+    def is_directory(self):
+        return (
+            self.check_output(
+                r"powershell -command \"(Get-Item '%s') -is 
[System.IO.DirectoryInfo]\"",
+                self.path,
+            )
+            == "True"
+        )
+
+    @property
+    def is_pipe(self):
+        raise NotImplementedError
+
+    @property
+    def is_socket(self):
+        raise NotImplementedError
+
+    @property
+    def is_symlink(self):
+        return (
+            self.check_output(
+                r"powershell -command \"(Get-Item -Path '%s').Attributes -band 
[System.IO.FileAttributes]::ReparsePoint\"",
+                self.path,
+            )
+            == "True"
+        )
+
+    @property
+    def linked_to(self):
+        """Resolve symlink
+
+        >>> host.file("C:/Users/lock").linked_to
+        'C:/Program Files/lock'
+        """
+        return self.check_output(
+            r"powershell -command \"(Get-Item -Path '%s' 
-ReadOnly).FullName\"",
+            self.path,
+        )
+
+    @property
+    def user(self):
+        raise NotImplementedError
+
+    @property
+    def uid(self):
+        raise NotImplementedError
+
+    @property
+    def group(self):
+        raise NotImplementedError
+
+    @property
+    def gid(self):
+        raise NotImplementedError
+
+    @property
+    def mode(self):
+        raise NotImplementedError
+
+    def contains(self, pattern):
+        """Checks content of file for pattern
+
+        This follows the regex syntax.
+        """
+        return (
+            self.run_test(
+                r"powershell -command \"Select-String -Path '%s' -Pattern 
'%s'\"",
+                self.path,
+                pattern,
+            ).stdout
+            != ""
+        )
+
+    @property
+    def md5sum(self):
+        raise NotImplementedError
+
+    @property
+    def sha256sum(self):
+        raise NotImplementedError
+
+    def _get_content(self, decode):
+        out = self.run_expect([0], r"powershell -command \"cat -- '%s'\"", 
self.path)
+        if decode:
+            return out.stdout
+        return out.stdout_bytes
+
+    @property
+    def content(self):
+        """Return file content as bytes
+
+        >>> host.file("C:/Windows/Temp/foo").content
+        b'caf\\xc3\\xa9'
+        """
+        return self._get_content(False)
+
+    @property
+    def content_string(self):
+        """Return file content as string
+
+        >>> host.file("C:/Windows/Temp/foo").content_string
+        'café'
+        """
+        return self._get_content(True)
+
+    @property
+    def mtime(self):
+        """Return time of last modification as datetime.datetime object
+
+        >>> host.file("C:/Windows/passwd").mtime
+        datetime.datetime(2015, 3, 15, 20, 25, 40)
+        """
+        date_time_str = self.check_output(
+            r"powershell -command \"Get-ChildItem -Path '%s' | Select-Object 
-ExpandProperty LastWriteTime\"",
+            self.path,
+        )
+        return datetime.datetime.strptime(
+            date_time_str.strip(), "%A, %B %d, %Y %I:%M:%S %p"
+        )
+
+    @property
+    def size(self):
+        """Return size of file in bytes"""
+        return int(
+            self.check_output(
+                r"powershell -command \"Get-Item -Path '%s' | Select-Object 
-ExpandProperty Length\"",
+                self.path,
+            )
+        )
+
+    def listdir(self):
+        """Return list of items under the directory
+
+        >>> host.file("C:/Windows/Temp").listdir()
+        ['foo_file', 'bar_dir']
+        """
+        out = self.check_output(
+            r"powershell -command \"Get-ChildItem -Path '%s' | Select-Object 
-ExpandProperty Name\"",
+            self.path,
+        )
+        return [item.strip() for item in out.strip().split("\n")]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/modules/group.py 
new/pytest-testinfra-8.1.0/testinfra/modules/group.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/group.py       2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/group.py       2023-05-21 
17:38:00.000000000 +0200
@@ -37,5 +37,13 @@
     def gid(self):
         return int(self.check_output("getent group %s | cut -d':' -f3", 
self.name))
 
+    @property
+    def members(self):
+        """Return all users that are members of this group."""
+        users = self.check_output("getent group %s | cut -d':' -f4", self.name)
+        if users:
+            return users.split(",")
+        return []
+
     def __repr__(self):
         return "<group {}>".format(self.name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest-testinfra-7.0.0/testinfra/modules/interface.py 
new/pytest-testinfra-8.1.0/testinfra/modules/interface.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/interface.py   2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/interface.py   2023-05-21 
17:38:00.000000000 +0200
@@ -10,6 +10,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json
+import re
+
 from testinfra.modules.base import Module
 from testinfra.utils import cached_property
 
@@ -48,6 +51,26 @@
         """
         raise NotImplementedError
 
+    def routes(self, scope=None):
+        """Return the routes associated with the interface, optionally 
filtered by scope
+        ("host", "link" or "global").
+
+        >>> host.interface("eth0").routes()
+        [{'dst': 'default',
+        'flags': [],
+        'gateway': '192.0.2.1',
+        'metric': 3003,
+        'prefsrc': '192.0.2.5',
+        'protocol': 'dhcp'},
+        {'dst': '192.0.2.0/24',
+        'flags': [],
+        'metric': 3003,
+        'prefsrc': '192.0.2.5',
+        'protocol': 'dhcp',
+        'scope': 'link'}]
+        """
+        raise NotImplementedError
+
     def __repr__(self):
         return "<interface {}>".format(self.name)
 
@@ -109,13 +132,25 @@
                 addrs.append(splitted[1].split("/", 1)[0])
         return addrs
 
+    def routes(self, scope=None):
+        cmd = f"{self._ip} --json route list dev %s"
+
+        if scope is None:
+            out = self.check_output(cmd, self.name)
+        else:
+            out = self.check_output(cmd + " scope %s", self.name, scope)
+
+        return json.loads(out)
+
     @classmethod
     def default(cls, family=None):
         _default = cls(None, family=family)
         out = cls.check_output("{} route ls".format(_default._ip))
         for line in out.splitlines():
             if "default" in line:
-                _default.name = line.strip().rsplit(" ", 1)[-1]
+                match = re.search(r"dev\s(\S+)", line)
+                if match:
+                    _default.name = match.group(1)
         return _default
 
     @classmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/modules/package.py 
new/pytest-testinfra-8.1.0/testinfra/modules/package.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/package.py     2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/package.py     2023-05-21 
17:38:00.000000000 +0200
@@ -35,7 +35,7 @@
         - pkg (FreeBSD)
         - pkg_info (NetBSD)
         - pkg_info (OpenBSD)
-        - rpm (RHEL, Centos, Fedora, ...)
+        - rpm (RHEL, RockyLinux, Fedora, ...)
         """
         raise NotImplementedError
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/modules/pip.py 
new/pytest-testinfra-8.1.0/testinfra/modules/pip.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/pip.py 2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/pip.py 2023-05-21 
17:38:00.000000000 +0200
@@ -147,7 +147,8 @@
         """Raise a `DeprecationWarning`"""
         warnings.warn(
             "Calling host.pip_package is deprecated, call host.pip instead",
-            DeprecationWarning,
+            category=DeprecationWarning,
+            stacklevel=2,
         )
 
     @classmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/modules/process.py 
new/pytest-testinfra-8.1.0/testinfra/modules/process.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/process.py     2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/process.py     2023-05-21 
17:38:00.000000000 +0200
@@ -109,6 +109,9 @@
     def get_module_class(cls, host):
         if host.file("/bin/ps").linked_to == "/bin/busybox":
             return BusyboxProcess
+        if host.file("/bin/busybox").exists:
+            if host.file("/bin/ps").inode == host.file("/bin/busybox").inode:
+                return BusyboxProcess
         if host.system_info.type == "linux" or 
host.system_info.type.endswith("bsd"):
             return PosixProcess
         raise NotImplementedError
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/modules/service.py 
new/pytest-testinfra-8.1.0/testinfra/modules/service.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/service.py     2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/service.py     2023-05-21 
17:38:00.000000000 +0200
@@ -103,6 +103,8 @@
             return OpenBSDService
         if host.system_info.type == "netbsd":
             return NetBSDService
+        if host.system_info.type == "windows":
+            return WindowsService
         raise NotImplementedError
 
     def __repr__(self):
@@ -275,3 +277,25 @@
     @property
     def is_enabled(self):
         raise NotImplementedError
+
+
+class WindowsService(Service):
+    @property
+    def is_running(self):
+        return (
+            self.check_output(
+                "Get-Service '%s' | Select -ExpandProperty Status",
+                self.name,
+            )
+            == "Running"
+        )
+
+    @property
+    def is_enabled(self):
+        return (
+            self.check_output(
+                "Get-Service '%s' | Select -ExpandProperty StartType",
+                self.name,
+            )
+            == "Automatic"
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest-testinfra-7.0.0/testinfra/modules/systeminfo.py 
new/pytest-testinfra-8.1.0/testinfra/modules/systeminfo.py
--- old/pytest-testinfra-7.0.0/testinfra/modules/systeminfo.py  2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/modules/systeminfo.py  2023-05-21 
17:38:00.000000000 +0200
@@ -79,7 +79,7 @@
                             line[len(key) :].replace('"', "").replace("'", 
"").strip()
                         )
             # Arch doesn't have releases
-            if sysinfo["distribution"] == "arch":
+            if "distribution" in sysinfo and sysinfo["distribution"] == "arch":
                 sysinfo["release"] = "rolling"
             return sysinfo
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/testinfra/plugin.py 
new/pytest-testinfra-8.1.0/testinfra/plugin.py
--- old/pytest-testinfra-7.0.0/testinfra/plugin.py      2022-12-01 
21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/testinfra/plugin.py      2023-05-21 
17:38:00.000000000 +0200
@@ -189,7 +189,7 @@
         return super().write(s)
 
 
-@pytest.mark.trylast
+@pytest.hookimpl(trylast=True)
 def pytest_configure(config):
     if config.getoption("--verbose", 0) > 1:
         root = logging.getLogger()
@@ -207,7 +207,7 @@
             config.pluginmanager.register(NagiosReporter(out), 
"nagiosreporter")
 
 
-@pytest.mark.trylast
+@pytest.hookimpl(trylast=True)
 def pytest_sessionfinish(session, exitstatus):
     reporter = session.config.pluginmanager.getplugin("nagiosreporter")
     if reporter:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-testinfra-7.0.0/tox.ini 
new/pytest-testinfra-8.1.0/tox.ini
--- old/pytest-testinfra-7.0.0/tox.ini  2022-12-01 21:30:39.000000000 +0100
+++ new/pytest-testinfra-8.1.0/tox.ini  2023-05-21 17:38:00.000000000 +0200
@@ -1,8 +1,9 @@
 [tox]
+minversion = 4.0.16
 envlist=
   lint
-  py{36,37,38,39,310}
-  doc
+  py
+  docs
   packaging
 
 [testenv]
@@ -10,28 +11,22 @@
 deps=
     -rtest-requirements.txt
 commands=
-    {envpython} -m mypy testinfra test
     {envpython} -m pytest {posargs:-v -n 4 --cov testinfra --cov-report xml 
--cov-report term test}
 usedevelop=True
-passenv=HOME TRAVIS DOCKER_CERT_PATH DOCKER_HOST DOCKER_TLS_VERIFY 
WSL_DISTRO_NAME
+passenv=
+    HOME
+    TRAVIS
+    DOCKER_CERT_PATH
+    DOCKER_HOST
+    DOCKER_TLS_VERIFY
+    WSL_DISTRO_NAME
 
 [testenv:lint]
 description = Performs linting tasks
-deps=
-  flake8
-  hacking>=4.0
-  flake8-bugbear
-  flake8-comprehensions
-  flake8-debugger
-  flake8-logging-format
-  flake8-pep3101
-  flake8-print
-  black
-  isort
+deps =
+    pre-commit>=2.6.0
 commands=
-  black --check --diff {toxinidir}
-  isort --check --diff testinfra test setup.py
-  flake8 {posargs}
+  pre-commit run -a
 
 [testenv:docs]
 deps=-rdev-requirements.txt

++++++ testinfra-parametrize-backends-test.patch ++++++
--- /var/tmp/diff_new_pack.4B4s1W/_old  2023-05-23 14:54:11.154356223 +0200
+++ /var/tmp/diff_new_pack.4B4s1W/_new  2023-05-23 14:54:11.158356246 +0200
@@ -1,8 +1,6 @@
-Index: pytest-testinfra-6.3.0/test/test_backends.py
-===================================================================
---- pytest-testinfra-6.3.0.orig/test/test_backends.py
-+++ pytest-testinfra-6.3.0/test/test_backends.py
-@@ -467,13 +467,13 @@ def test_ansible_unknown_option():
+--- a/test/test_backends.py    2023-05-21 17:38:00.000000000 +0200
++++ b/test/test_backends.py    2023-05-22 06:22:56.491195059 +0200
+@@ -476,13 +476,13 @@
      with pytest.raises(KeyError, match="^'unknown'$"):
          runner.options_to_cli({"unknown": True})
  
@@ -20,5 +18,5 @@
 +    assert obj.get_connection_type() == connection_type
  
  
- @pytest.mark.testinfra_hosts("docker://centos_7", "ssh://centos_7")
+ @pytest.mark.testinfra_hosts("docker://rockylinux8", "ssh://rockylinux8")
 

Reply via email to