From b6989438be4a8dbc1d6ad3607c4d2e5a5c6025e8 Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Tue, 7 Jan 2025 12:51:13 -0500
Subject: [PATCH] Stop using the deprecated tmpdir fixture from pytest (#1396)

Use the newer tmp_path
---
 tests/conftest.py    |  5 +++--
 tests/test_crypto.py | 40 ++++++++++++++++++++++++----------------
 tests/test_ssl.py    | 23 +++++++++++++----------
 3 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/tests/conftest.py b/tests/conftest.py
index 90bbd659..73ab7a68 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,6 +1,7 @@
 # Copyright (c) The pyOpenSSL developers
 # See LICENSE for details.
 
+import pathlib
 from tempfile import mktemp
 
 import pytest
@@ -18,10 +19,10 @@ def pytest_report_header(config):
 
 
 @pytest.fixture
-def tmpfile(tmpdir):
+def tmpfile(tmp_path: pathlib.Path) -> bytes:
     """
     Return UTF-8-encoded bytes of a path to a tmp file.
 
     The file will be cleaned up after the test run.
     """
-    return mktemp(dir=tmpdir.dirname).encode("utf-8")
+    return mktemp(dir=tmp_path).encode("utf-8")
diff --git a/tests/test_crypto.py b/tests/test_crypto.py
index 54ce3cd0..5dab8663 100644
--- a/tests/test_crypto.py
+++ b/tests/test_crypto.py
@@ -8,6 +8,7 @@
 from __future__ import annotations
 
 import base64
+import pathlib
 import sys
 import typing
 from datetime import datetime, timedelta, timezone
@@ -2477,9 +2478,11 @@ def test_load_locations_fails_when_all_args_are_none(self) -> None:
         with pytest.raises(Error):
             store.load_locations(None, None)
 
-    def test_load_locations_raises_error_on_failure(self, tmpdir) -> None:
-        invalid_ca_file = tmpdir.join("invalid.pem")
-        invalid_ca_file.write("This is not a certificate")
+    def test_load_locations_raises_error_on_failure(
+        self, tmp_path: pathlib.Path
+    ) -> None:
+        invalid_ca_file = tmp_path / "invalid.pem"
+        invalid_ca_file.write_text("This is not a certificate")
 
         store = X509Store()
         with pytest.raises(Error):
@@ -3369,22 +3372,25 @@ def test_get_verified_chain_invalid_chain_no_root(self) -> None:
         assert exc.value.certificate.get_subject().CN == "intermediate"
 
     @pytest.fixture
-    def root_ca_file(self, tmpdir):
-        return self._create_ca_file(tmpdir, "root_ca_hash_dir", self.root_cert)
+    def root_ca_file(self, tmp_path: pathlib.Path) -> pathlib.Path:
+        return self._create_ca_file(
+            tmp_path, "root_ca_hash_dir", self.root_cert
+        )
 
     @pytest.fixture
-    def intermediate_ca_file(self, tmpdir):
+    def intermediate_ca_file(self, tmp_path: pathlib.Path) -> pathlib.Path:
         return self._create_ca_file(
-            tmpdir, "intermediate_ca_hash_dir", self.intermediate_cert
+            tmp_path, "intermediate_ca_hash_dir", self.intermediate_cert
         )
 
     @staticmethod
-    def _create_ca_file(base_path, hash_directory: str, cacert: X509):
+    def _create_ca_file(
+        base_path: pathlib.Path, hash_directory: str, cacert: X509
+    ) -> pathlib.Path:
         ca_hash = f"{cacert.subject_name_hash():08x}.0"
-        cafile = base_path.join(hash_directory, ca_hash)
-        cafile.write_binary(
-            dump_certificate(FILETYPE_PEM, cacert), ensure=True
-        )
+        cafile = base_path / hash_directory / ca_hash
+        cafile.parent.mkdir(parents=True, exist_ok=True)
+        cafile.write_bytes(dump_certificate(FILETYPE_PEM, cacert))
         return cafile
 
     def test_verify_with_ca_file_location(self, root_ca_file) -> None:
@@ -3396,7 +3402,7 @@ def test_verify_with_ca_file_location(self, root_ca_file) -> None:
 
     def test_verify_with_ca_path_location(self, root_ca_file) -> None:
         store = X509Store()
-        store.load_locations(None, str(root_ca_file.dirname))
+        store.load_locations(None, str(root_ca_file.parent))
 
         store_ctx = X509StoreContext(store, self.intermediate_cert)
         store_ctx.verify_certificate()
@@ -3406,7 +3412,7 @@ def test_verify_with_cafile_and_capath(
     ):
         store = X509Store()
         store.load_locations(
-            cafile=str(root_ca_file), capath=str(intermediate_ca_file.dirname)
+            cafile=str(root_ca_file), capath=str(intermediate_ca_file.parent)
         )
 
         store_ctx = X509StoreContext(store, self.intermediate_server_cert)
@@ -3422,9 +3428,11 @@ def test_verify_with_multiple_ca_files(
         store_ctx = X509StoreContext(store, self.intermediate_server_cert)
         store_ctx.verify_certificate()
 
-    def test_verify_failure_with_empty_ca_directory(self, tmpdir) -> None:
+    def test_verify_failure_with_empty_ca_directory(
+        self, tmp_path: pathlib.Path
+    ) -> None:
         store = X509Store()
-        store.load_locations(None, str(tmpdir))
+        store.load_locations(None, str(tmp_path))
 
         store_ctx = X509StoreContext(store, self.intermediate_cert)
         with pytest.raises(X509StoreContextError) as exc:
diff --git a/tests/test_ssl.py b/tests/test_ssl.py
index feb4d804..5ae2084b 100644
--- a/tests/test_ssl.py
+++ b/tests/test_ssl.py
@@ -9,6 +9,7 @@
 
 import datetime
 import gc
+import pathlib
 import select
 import sys
 import time
@@ -466,7 +467,7 @@ def test_SSLeay_version(self) -> None:
 
 
 @pytest.fixture
-def ca_file(tmpdir):
+def ca_file(tmp_path: pathlib.Path) -> bytes:
     """
     Create a valid PEM file with CA certificates and return the path.
     """
@@ -492,8 +493,8 @@ def ca_file(tmpdir):
 
     certificate = builder.sign(private_key=key, algorithm=hashes.SHA256())
 
-    ca_file = tmpdir.join("test.pem")
-    ca_file.write_binary(
+    ca_file = tmp_path / "test.pem"
+    ca_file.write_bytes(
         certificate.public_bytes(
             encoding=serialization.Encoding.PEM,
         )
@@ -568,12 +569,14 @@ def test_load_client_ca(self, context, ca_file) -> None:
         """
         context.load_client_ca(ca_file)
 
-    def test_load_client_ca_invalid(self, context, tmpdir) -> None:
+    def test_load_client_ca_invalid(
+        self, context, tmp_path: pathlib.Path
+    ) -> None:
         """
         `Context.load_client_ca` raises an Error if the ca file is invalid.
         """
-        ca_file = tmpdir.join("test.pem")
-        ca_file.write("")
+        ca_file = tmp_path / "test.pem"
+        ca_file.write_text("")
 
         with pytest.raises(Error) as e:
             context.load_client_ca(str(ca_file).encode("ascii"))
@@ -1511,7 +1514,7 @@ def test_set_verify_default_callback(self, mode) -> None:
         else:
             self._handshake_test(serverContext, clientContext)
 
-    def test_add_extra_chain_cert(self, tmpdir) -> None:
+    def test_add_extra_chain_cert(self, tmp_path: pathlib.Path) -> None:
         """
         `Context.add_extra_chain_cert` accepts an `X509`
         instance to add to the certificate chain.
@@ -1533,11 +1536,11 @@ def test_add_extra_chain_cert(self, tmpdir) -> None:
             (icert, "i.pem"),
             (scert, "s.pem"),
         ]:
-            with tmpdir.join(name).open("w") as f:
+            with (tmp_path / name).open("w") as f:
                 f.write(dump_certificate(FILETYPE_PEM, cert).decode("ascii"))
 
         for key, name in [(cakey, "ca.key"), (ikey, "i.key"), (skey, "s.key")]:
-            with tmpdir.join(name).open("w") as f:
+            with (tmp_path / name).open("w") as f:
                 f.write(dump_privatekey(FILETYPE_PEM, key).decode("ascii"))
 
         # Create the server context
@@ -1552,7 +1555,7 @@ def test_add_extra_chain_cert(self, tmpdir) -> None:
         clientContext.set_verify(
             VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb
         )
-        clientContext.load_verify_locations(str(tmpdir.join("ca.pem")))
+        clientContext.load_verify_locations(str(tmp_path / "ca.pem"))
 
         # Try it out.
         self._handshake_test(serverContext, clientContext)