testisolation 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {testisolation-0.3.0 → testisolation-0.4.0}/PKG-INFO +2 -2
  2. {testisolation-0.3.0 → testisolation-0.4.0}/pyproject.toml +2 -2
  3. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/__init__.py +1 -1
  4. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/env_overrides.py +7 -0
  5. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_env_overrides.py +27 -0
  6. {testisolation-0.3.0 → testisolation-0.4.0}/uv.lock +2 -2
  7. {testisolation-0.3.0 → testisolation-0.4.0}/.github/workflows/ci.yml +0 -0
  8. {testisolation-0.3.0 → testisolation-0.4.0}/.github/workflows/publish.yml +0 -0
  9. {testisolation-0.3.0 → testisolation-0.4.0}/.gitignore +0 -0
  10. {testisolation-0.3.0 → testisolation-0.4.0}/.rlsbl/config.json +0 -0
  11. {testisolation-0.3.0 → testisolation-0.4.0}/.rlsbl/lint/python.toml +0 -0
  12. {testisolation-0.3.0 → testisolation-0.4.0}/.rlsbl/managed-files.json +0 -0
  13. {testisolation-0.3.0 → testisolation-0.4.0}/LICENSE +0 -0
  14. {testisolation-0.3.0 → testisolation-0.4.0}/README.md +0 -0
  15. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/config.py +0 -0
  16. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/pgcluster.py +0 -0
  17. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/plugin.py +0 -0
  18. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/pushguard.py +0 -0
  19. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/sandbox.py +0 -0
  20. {testisolation-0.3.0 → testisolation-0.4.0}/src/testisolation/socketguard.py +0 -0
  21. {testisolation-0.3.0 → testisolation-0.4.0}/tests/conftest.py +0 -0
  22. {testisolation-0.3.0 → testisolation-0.4.0}/tests/sample_consumer/README.md +0 -0
  23. {testisolation-0.3.0 → testisolation-0.4.0}/tests/sample_consumer/acme/__init__.py +0 -0
  24. {testisolation-0.3.0 → testisolation-0.4.0}/tests/sample_consumer/pytest.ini +0 -0
  25. {testisolation-0.3.0 → testisolation-0.4.0}/tests/sample_consumer/tests/conftest.py +0 -0
  26. {testisolation-0.3.0 → testisolation-0.4.0}/tests/sample_consumer/tests/test_git_workflow.py +0 -0
  27. {testisolation-0.3.0 → testisolation-0.4.0}/tests/sample_consumer/tests/test_home_isolation.py +0 -0
  28. {testisolation-0.3.0 → testisolation-0.4.0}/tests/sample_consumer/tests/test_network_is_off.py +0 -0
  29. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_chdir_isolation.py +0 -0
  30. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_config_keys.py +0 -0
  31. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_cross_language_parity.py +0 -0
  32. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_harness_selfcheck.py +0 -0
  33. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_pg_cluster.py +0 -0
  34. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_pg_socket_path.py +0 -0
  35. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_push_guard.py +0 -0
  36. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_sample_consumer.py +0 -0
  37. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_socket_guard.py +0 -0
  38. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_threshold.py +0 -0
  39. {testisolation-0.3.0 → testisolation-0.4.0}/tests/test_tmp_refusal.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: testisolation
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Uncompromising test isolation: your tests structurally cannot touch your real files, secrets, or git identity -- First-class support for Go, Python with pytest, and TypeScript with Node
5
5
  Project-URL: Homepage, https://smmh.dev/testisolation/
6
6
  Project-URL: Documentation, https://smmh.dev/testisolation/
@@ -16,7 +16,7 @@ Classifier: Framework :: Pytest
16
16
  Classifier: Intended Audience :: Developers
17
17
  Classifier: Programming Language :: Python :: 3
18
18
  Classifier: Topic :: Software Development :: Testing
19
- Requires-Python: >=3.11
19
+ Requires-Python: >=3.14
20
20
  Requires-Dist: pytest>=7.0
21
21
  Description-Content-Type: text/markdown
22
22
 
@@ -4,10 +4,10 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "testisolation"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "Uncompromising test isolation: your tests structurally cannot touch your real files, secrets, or git identity -- First-class support for Go, Python with pytest, and TypeScript with Node"
9
9
  readme = "README.md"
10
- requires-python = ">=3.11"
10
+ requires-python = ">=3.14"
11
11
  license = "MIT"
12
12
  license-files = ["LICENSE"]
13
13
  authors = [{ name = "S. M. Hosseini", email = "m.hosseini@veliu.com" }]
@@ -8,7 +8,7 @@ stance. See :mod:`testisolation.config` for the ini keys.
8
8
  from .config import PRESERVE_VARS, REQUIRED_KEYS, Settings
9
9
  from .socketguard import NetworkBlocked, Policy
10
10
 
11
- __version__ = "0.3.0"
11
+ __version__ = "0.4.0"
12
12
 
13
13
  # No ``__all__`` here on purpose. Every name above is defined -- and documented
14
14
  # -- on its own module's API-reference page; re-listing them here would make the
@@ -103,6 +103,11 @@ def install(settings: Settings) -> None:
103
103
  # and a session commit identity so real-git fixtures that skip per-repo
104
104
  # identity still commit.
105
105
  #
106
+ # maintenance.auto=false: without it a git commit may start
107
+ # `git maintenance run --auto --detach` in the background, which keeps
108
+ # writing into .git after the commit returns and races the removal of the
109
+ # test's temporary directory ("unlinkat .git: directory not empty").
110
+ #
106
111
  # We deliberately do NOT set core.hooksPath here. core.hooksPath overrides
107
112
  # REPO-LOCAL hooks too, which would silently disable a suite's real
108
113
  # pre-push-hook tests. A global config cannot inject hooks on its own, so
@@ -118,6 +123,8 @@ def install(settings: Settings) -> None:
118
123
  "\tallow = never\n"
119
124
  "[init]\n"
120
125
  "\tdefaultBranch = main\n"
126
+ "[maintenance]\n"
127
+ "\tauto = false\n"
121
128
  )
122
129
  os.environ["GIT_CONFIG_GLOBAL"] = str(gitconfig)
123
130
  os.environ["GIT_CONFIG_SYSTEM"] = str(gitconfig)
@@ -107,6 +107,33 @@ def test_git_commits_are_attributed_to_the_throwaway_identity(tmp_path):
107
107
  )
108
108
 
109
109
 
110
+ def test_a_commit_starts_no_background_maintenance(tmp_path):
111
+ # A git commit may start `git maintenance run --auto --detach` in the
112
+ # background, which keeps writing into .git after the commit returns and
113
+ # races the removal of the test's temporary directory ("unlinkat .git:
114
+ # directory not empty"). rerere is enabled so the maintenance run would have
115
+ # work to do. The child is observed through git's own trace2 event stream,
116
+ # which records every child process git starts.
117
+ repo = tmp_path / "repo"
118
+ subprocess.run(["git", "init", "-q", str(repo)], check=True)
119
+ subprocess.run(["git", "-C", str(repo), "config", "rerere.enabled", "true"], check=True)
120
+ (repo / "f.txt").write_text("x\n")
121
+ subprocess.run(["git", "-C", str(repo), "add", "f.txt"], check=True)
122
+
123
+ trace = tmp_path / "trace2.json"
124
+ subprocess.run(
125
+ ["git", "-C", str(repo), "commit", "-qm", "x"],
126
+ env={**os.environ, "GIT_TRACE2_EVENT": str(trace)},
127
+ check=True,
128
+ )
129
+ events = trace.read_text()
130
+ assert '"commit"' in events, (
131
+ "the trace2 stream does not record the commit itself, so it proves nothing:\n" + events
132
+ )
133
+ maintenance = [line for line in events.splitlines() if '"maintenance"' in line]
134
+ assert maintenance == [], "the commit started a git maintenance child process"
135
+
136
+
110
137
  def test_ssh_protocol_is_refused_by_the_throwaway_config(tmp_path):
111
138
  config_path = Path(os.environ["GIT_CONFIG_GLOBAL"]).read_text()
112
139
  assert "allow = never" in config_path
@@ -1,6 +1,6 @@
1
1
  version = 1
2
2
  revision = 3
3
- requires-python = ">=3.11"
3
+ requires-python = ">=3.14"
4
4
 
5
5
  [[package]]
6
6
  name = "colorama"
@@ -87,7 +87,7 @@ wheels = [
87
87
 
88
88
  [[package]]
89
89
  name = "testisolation"
90
- version = "0.3.0"
90
+ version = "0.4.0"
91
91
  source = { editable = "." }
92
92
  dependencies = [
93
93
  { name = "pytest" },
File without changes
File without changes
File without changes