Repository: tox-dev/tox

Issue:
tox4 python version change arrow should be inverted
```
type: recreate env because python changed version_info=[3, 9, 7, 'final', 0]->[3, 10, 0, 'candidate', 2] |
```

Comments:

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d6dd3e68..8ce71718 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -12,7 +12,7 @@ repos:
       - id: end-of-file-fixer
       - id: trailing-whitespace
   - repo: https://github.com/asottile/pyupgrade
-    rev: v2.25.0
+    rev: v2.25.1
     hooks:
       - id: pyupgrade
         args: ["--py36-plus"]
diff --git a/docs/changelog/2211.bugfix.rst b/docs/changelog/2211.bugfix.rst
new file mode 100644
index 00000000..7584fd21
--- /dev/null
+++ b/docs/changelog/2211.bugfix.rst
@@ -0,0 +1,1 @@
+Fix old-new value on recreate cache miss-match are swapped -- by :user:`gaborbernat`.
diff --git a/src/tox/tox_env/python/api.py b/src/tox/tox_env/python/api.py
index 2bec85d2..222e14ec 100644
--- a/src/tox/tox_env/python/api.py
+++ b/src/tox/tox_env/python/api.py
@@ -173,7 +173,7 @@ class Python(ToxEnv, ABC):
         removed = [f"{k}={v!r}" for k, v in old.items() if k not in conf]
         if removed:
             result.append(f"removed {' | '.join(removed)}")
-        changed = [f"{k}={v!r}->{old[k]!r}" for k, v in conf.items() if k in old and v != old[k]]
+        changed = [f"{k}={old[k]!r}->{v!r}" for k, v in conf.items() if k in old and v != old[k]]
         if changed:
             result.append(f"changed {' | '.join(changed)}")
         return f'python {", ".join(result)}'


Test patch:
diff --git a/src/tox/pytest.py b/src/tox/pytest.py
index 265292be..b7d7be7d 100644
--- a/src/tox/pytest.py
+++ b/src/tox/pytest.py
@@ -398,8 +398,11 @@ def empty_project(tox_project: ToxProjectCreator, monkeypatch: MonkeyPatch) -> T
     return project
 
 
+_RUN_INTEGRATION_TEST_FLAG = "--run-integration"
+
+
 def pytest_addoption(parser: Parser) -> None:
-    parser.addoption("--run-integration", action="store_true", help="run the integration tests")
+    parser.addoption(_RUN_INTEGRATION_TEST_FLAG, action="store_true", help="run the integration tests")
 
 
 def pytest_configure(config: PyTestConfig) -> None:
@@ -413,12 +416,12 @@ def pytest_collection_modifyitems(config: PyTestConfig, items: List[Function]) -
     if len(items) == 1:  # pragma: no cover # hard to test
         return
 
-    skip_int = pytest.mark.skip(reason="integration tests not run (no --run-int flag)")
+    skip_int = pytest.mark.skip(reason=f"integration tests not run (no {_RUN_INTEGRATION_TEST_FLAG} flag)")
 
     def is_integration(test_item: Function) -> bool:
         return test_item.get_closest_marker("integration") is not None
 
-    integration_enabled = config.getoption("--run-integration")
+    integration_enabled = config.getoption(_RUN_INTEGRATION_TEST_FLAG)
     if not integration_enabled:  # pragma: no cover # hard to test
         for item in items:
             if is_integration(item):
diff --git a/tests/tox_env/python/test_python_api.py b/tests/tox_env/python/test_python_api.py
index aa588d44..2204a22a 100644
--- a/tests/tox_env/python/test_python_api.py
+++ b/tests/tox_env/python/test_python_api.py
@@ -60,7 +60,7 @@ def test_build_wheel_in_non_base_pkg_env(
 def test_diff_msg_added_removed_changed() -> None:
     before = {"A": "1", "F": "8", "C": "3", "D": "4", "E": "6"}
     after = {"G": "9", "B": "2", "C": "3", "D": "5", "E": "7"}
-    expected = "python added A='1' | F='8', removed G='9' | B='2', changed D='4'->'5' | E='6'->'7'"
+    expected = "python added A='1' | F='8', removed G='9' | B='2', changed D='5'->'4' | E='7'->'6'"
     assert Python._diff_msg(before, after) == expected
 
 
diff --git a/tests/tox_env/python/virtual_env/test_virtualenv_api.py b/tests/tox_env/python/virtual_env/test_virtualenv_api.py
index 5398e7f2..490aa295 100644
--- a/tests/tox_env/python/virtual_env/test_virtualenv_api.py
+++ b/tests/tox_env/python/virtual_env/test_virtualenv_api.py
@@ -119,7 +119,7 @@ def test_recreate_when_virtualenv_changes(tox_project: ToxProjectCreator, mocker
 
     mocker.patch.object(api, "virtualenv_version", "1.0")
     result = proj.run("r")
-    assert f"recreate env because python changed virtualenv version='1.0'->'{virtualenv_version}'" in result.out
+    assert f"recreate env because python changed virtualenv version='{virtualenv_version}'->'1.0'" in result.out
     assert "remove tox env folder" in result.out