From 111cd087b8c4933140a31ddf74644fa35f108d20 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 2 Nov 2024 14:22:52 -0600
Subject: [PATCH 01/23] test ko

---
 .github/workflows/continuous-integration.yml | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index fa1fe9554..a3d6eada2 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -32,10 +32,12 @@ jobs:
           - ubuntu-latest
           - windows-latest
           - macos-latest
-        exclude:
-          # https://github.com/stac-utils/pystac/issues/1470
-          - os: windows-latest
-            python-version: "3.13"
+
+        #Working on this issue now! testing CI kickoff
+        # exclude:
+        #   # https://github.com/stac-utils/pystac/issues/1470
+        #   - os: windows-latest
+        #     python-version: "3.13"
     steps:
       - uses: actions/checkout@v4
       - uses: actions/setup-python@v5

From e161345382e07a35fa939207f6bd46cd1ce309f5 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 12:57:27 -0700
Subject: [PATCH 02/23] isolate assertion (very simple check here..)

---
 pystac/utils.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pystac/utils.py b/pystac/utils.py
index 6c0690c78..cdb57c149 100644
--- a/pystac/utils.py
+++ b/pystac/utils.py
@@ -364,7 +364,7 @@ def is_absolute_href(href: str) -> bool:
         bool: ``True`` if the given HREF is absolute, ``False`` if it is relative.
     """
     parsed = safe_urlparse(href)
-    return parsed.scheme != "" or os.path.isabs(parsed.path)
+    return parsed.scheme != "" # or os.path.isabs(parsed.path)
 
 
 def datetime_to_str(dt: datetime, timespec: str = "auto") -> str:

From 5083f3e1934dbdc202aafc69bfe59a7e4b746b9b Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 14:02:52 -0700
Subject: [PATCH 03/23] test windows correctly

---
 .gitignore          | 1 +
 pystac/utils.py     | 3 ++-
 tests/test_utils.py | 6 +++++-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index fb913e75d..b36a5965e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ stdout*
 /integration*
 .idea
 .vscode
+.actrc
 
 
 # Sphinx documentation
diff --git a/pystac/utils.py b/pystac/utils.py
index cdb57c149..ecc89c61d 100644
--- a/pystac/utils.py
+++ b/pystac/utils.py
@@ -364,7 +364,8 @@ def is_absolute_href(href: str) -> bool:
         bool: ``True`` if the given HREF is absolute, ``False`` if it is relative.
     """
     parsed = safe_urlparse(href)
-    return parsed.scheme != "" # or os.path.isabs(parsed.path)
+
+    return parsed.scheme != "" or os.path.isabs(parsed.path)
 
 
 def datetime_to_str(dt: datetime, timespec: str = "auto") -> str:
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 44dd6998a..9d7e217e6 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -218,7 +218,11 @@ def test_is_absolute_href(self) -> None:
             ("item.json", False),
             ("./item.json", False),
             ("../item.json", False),
-            ("/item.json", True),
+            
+            # https://docs.python.org/3/library/os.path.html#os.path.isabs
+            # Windows requires a drive name.
+            ("/item.json", os.name != "nt"),
+            ("d:/item.json", os.name == "nt"),
             ("http://stacspec.org/item.json", True),
         ]
 

From 322308e5fbf5ca371d95c81da32586fa761fd93c Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 14:04:37 -0700
Subject: [PATCH 04/23] cleanup comment

---
 .github/workflows/continuous-integration.yml | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index a3d6eada2..1e4692f6c 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -32,12 +32,6 @@ jobs:
           - ubuntu-latest
           - windows-latest
           - macos-latest
-
-        #Working on this issue now! testing CI kickoff
-        # exclude:
-        #   # https://github.com/stac-utils/pystac/issues/1470
-        #   - os: windows-latest
-        #     python-version: "3.13"
     steps:
       - uses: actions/checkout@v4
       - uses: actions/setup-python@v5

From 6aba9a7e5447a7190ac22fffbd63638f38b4ce63 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 14:06:05 -0700
Subject: [PATCH 05/23] ruff fix

---
 tests/test_utils.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 9d7e217e6..642515c1e 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -218,7 +218,6 @@ def test_is_absolute_href(self) -> None:
             ("item.json", False),
             ("./item.json", False),
             ("../item.json", False),
-            
             # https://docs.python.org/3/library/os.path.html#os.path.isabs
             # Windows requires a drive name.
             ("/item.json", os.name != "nt"),

From ba13777e97c5557242005e9bfe82e74759647e99 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 14:14:38 -0700
Subject: [PATCH 06/23] update changelog

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index afa2697e4..6fdb0993c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
 
 - Write STAC v1.1.0 ([#1427](https://github.com/stac-utils/pystac/pull/1427))
 - Use [uv](https://github.com/astral-sh/uv) for development dependencies and docs ([#1439](https://github.com/stac-utils/pystac/pull/1439))
+- Correctly detect absolute file path ref on windows ([#1475]https://github.com/stac-utils/pystac/pull/1475)
 
 ## [v1.11.0] - 2024-09-26
 

From b33c4e2e624de6971d0dfd966552dd22d87a70e5 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 14:15:16 -0700
Subject: [PATCH 07/23] update changelog

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6fdb0993c..8a1047816 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@
 
 - Write STAC v1.1.0 ([#1427](https://github.com/stac-utils/pystac/pull/1427))
 - Use [uv](https://github.com/astral-sh/uv) for development dependencies and docs ([#1439](https://github.com/stac-utils/pystac/pull/1439))
-- Correctly detect absolute file path ref on windows ([#1475]https://github.com/stac-utils/pystac/pull/1475)
+- Correctly detect absolute file path ref on windows, reflecting change in python 3.13 ([#1475]https://github.com/stac-utils/pystac/pull/1475) (only effects python 3.13)
 
 ## [v1.11.0] - 2024-09-26
 

From 53240dcbb10223a7e282b3960a74f92c70e63e77 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 15:29:15 -0700
Subject: [PATCH 08/23] fix for 3.12

---
 tests/test_utils.py | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 4744caab2..b268da0aa 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,5 +1,6 @@
 import json
 import os
+import sys
 import time
 import unittest
 from datetime import datetime, timedelta, timezone
@@ -215,14 +216,19 @@ def test_make_absolute_href_windows(self) -> None:
 
     def test_is_absolute_href(self) -> None:
         # Test cases of (href, expected)
+
+        is_py_3_13_on_windows: bool = (
+            sys.version_info.major == 3
+            and sys.version_info.minor >= 13
+            and os.name == "nt"
+        )
+
         test_cases = [
             ("item.json", False),
             ("./item.json", False),
             ("../item.json", False),
-            # https://docs.python.org/3/library/os.path.html#os.path.isabs
-            # Windows requires a drive name.
-            ("/item.json", os.name != "nt"),
-            ("d:/item.json", os.name == "nt"),
+            ("/item.json", not is_py_3_13_on_windows),
+            ("d:/item.json", is_py_3_13_on_windows),
             ("http://stacspec.org/item.json", True),
         ]
 

From c861fe96c0036ae66e1a0091041502205c6fd2c9 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 15:43:42 -0700
Subject: [PATCH 09/23] really cover in new test

---
 tests/test_utils.py | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index b268da0aa..578f6c49e 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -216,19 +216,10 @@ def test_make_absolute_href_windows(self) -> None:
 
     def test_is_absolute_href(self) -> None:
         # Test cases of (href, expected)
-
-        is_py_3_13_on_windows: bool = (
-            sys.version_info.major == 3
-            and sys.version_info.minor >= 13
-            and os.name == "nt"
-        )
-
         test_cases = [
             ("item.json", False),
             ("./item.json", False),
             ("../item.json", False),
-            ("/item.json", not is_py_3_13_on_windows),
-            ("d:/item.json", is_py_3_13_on_windows),
             ("http://stacspec.org/item.json", True),
         ]
 
@@ -236,9 +227,32 @@ def test_is_absolute_href(self) -> None:
             actual = is_absolute_href(href)
             self.assertEqual(actual, expected)
 
+    def test_is_absolute_href_os_aware(self) -> None:
+        # Test cases of (href, expected)
+
+        # These tests ensure that is_absolute_href can respond correctly to the os
+        # in a forwards and backwards compatible way.
+        # Windows requires a drive name when python > 3.13 (https://docs.python.org/3/library/os.path.html#os.path.isabs)
+        is_py_3_13: bool = sys.version_info.major == 3 and sys.version_info.minor >= 13
+
+        is_windows = os.name != "nt"
+
+        test_cases = [
+            ("/item.json", not (is_windows and is_py_3_13)),
+            ("/home/someuser/Downloads/item.json", not (is_windows and is_py_3_13)),
+            ("d:/item.json", is_windows),
+            ("c:/files/more_files/item.json", is_windows),
+        ]
+
+        for href, expected in test_cases:
+            actual = is_absolute_href(href)
+            self.assertEqual(actual, expected)
+
     @pytest.mark.skipif(os.name != "nt", reason="Windows only test")
     def test_is_absolute_href_windows(self) -> None:
         # Test cases of (href, expected)
+
+        # Further nuanced cases for Windows.
         test_cases = [
             ("item.json", False),
             (".\\item.json", False),

From 03a3a0c725ebe0ee12e0c20fe75f9360fad4ad2c Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 15:48:54 -0700
Subject: [PATCH 10/23] drive supported only on 3.13

---
 tests/test_utils.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 578f6c49e..c12c825cc 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -240,8 +240,8 @@ def test_is_absolute_href_os_aware(self) -> None:
         test_cases = [
             ("/item.json", not (is_windows and is_py_3_13)),
             ("/home/someuser/Downloads/item.json", not (is_windows and is_py_3_13)),
-            ("d:/item.json", is_windows),
-            ("c:/files/more_files/item.json", is_windows),
+            ("d:/item.json", (is_windows and is_py_3_13)),
+            ("c:/files/more_files/item.json", (is_windows and is_py_3_13)),
         ]
 
         for href, expected in test_cases:

From 0e6bbbd0416418ddf179fc009351655509a17ba3 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 15:55:21 -0700
Subject: [PATCH 11/23] check one

---
 tests/test_utils.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index c12c825cc..4c948f5b5 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -241,7 +241,7 @@ def test_is_absolute_href_os_aware(self) -> None:
             ("/item.json", not (is_windows and is_py_3_13)),
             ("/home/someuser/Downloads/item.json", not (is_windows and is_py_3_13)),
             ("d:/item.json", (is_windows and is_py_3_13)),
-            ("c:/files/more_files/item.json", (is_windows and is_py_3_13)),
+            # ("c:/files/more_files/item.json", (is_windows and is_py_3_13)),
         ]
 
         for href, expected in test_cases:

From 5924e0709fc13a89e52a3e28053675cc91c10c74 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 15:56:10 -0700
Subject: [PATCH 12/23] check two

---
 tests/test_utils.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 4c948f5b5..0d26ab73a 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -240,7 +240,7 @@ def test_is_absolute_href_os_aware(self) -> None:
         test_cases = [
             ("/item.json", not (is_windows and is_py_3_13)),
             ("/home/someuser/Downloads/item.json", not (is_windows and is_py_3_13)),
-            ("d:/item.json", (is_windows and is_py_3_13)),
+            # ("d:/item.json", (is_windows and is_py_3_13)),
             # ("c:/files/more_files/item.json", (is_windows and is_py_3_13)),
         ]
 

From 2d987ff58297b9c9203918fb16c0b84949bc36de Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 15:58:39 -0700
Subject: [PATCH 13/23] correct is_windows in tests

---
 tests/test_utils.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 0d26ab73a..41db0c4f7 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -235,13 +235,13 @@ def test_is_absolute_href_os_aware(self) -> None:
         # Windows requires a drive name when python > 3.13 (https://docs.python.org/3/library/os.path.html#os.path.isabs)
         is_py_3_13: bool = sys.version_info.major == 3 and sys.version_info.minor >= 13
 
-        is_windows = os.name != "nt"
+        is_windows = os.name == "nt"
 
         test_cases = [
             ("/item.json", not (is_windows and is_py_3_13)),
             ("/home/someuser/Downloads/item.json", not (is_windows and is_py_3_13)),
-            # ("d:/item.json", (is_windows and is_py_3_13)),
-            # ("c:/files/more_files/item.json", (is_windows and is_py_3_13)),
+            ("d:/item.json", (is_windows and is_py_3_13)),
+            ("c:/files/more_files/item.json", (is_windows and is_py_3_13)),
         ]
 
         for href, expected in test_cases:

From 343462020a5fa0653a8b04db18f7b15f79069f60 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 16 Nov 2024 16:04:24 -0700
Subject: [PATCH 14/23] correct is_windows in tests part 2

---
 tests/test_utils.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 41db0c4f7..728285737 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -240,8 +240,8 @@ def test_is_absolute_href_os_aware(self) -> None:
         test_cases = [
             ("/item.json", not (is_windows and is_py_3_13)),
             ("/home/someuser/Downloads/item.json", not (is_windows and is_py_3_13)),
-            ("d:/item.json", (is_windows and is_py_3_13)),
-            ("c:/files/more_files/item.json", (is_windows and is_py_3_13)),
+            ("d:/item.json", is_windows),
+            ("c:/files/more_files/item.json", is_windows),
         ]
 
         for href, expected in test_cases:

From e44eab760012ff6959269ac81184937ea74f1a92 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 23 Nov 2024 15:12:50 -0700
Subject: [PATCH 15/23] use os path for path count

---
 tests/test_catalog.py | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/tests/test_catalog.py b/tests/test_catalog.py
index cb8bdace1..12100b99d 100644
--- a/tests/test_catalog.py
+++ b/tests/test_catalog.py
@@ -832,12 +832,18 @@ def test_generate_subcatalogs_works_for_subcatalogs_with_same_ids(self) -> None:
         assert len(result) == 6
 
         catalog.normalize_hrefs("/")
+
         for item in catalog.get_items(recursive=True):
             item_parent = item.get_parent()
             assert item_parent is not None
             parent_href = item_parent.self_href
             path_to_parent, _ = os.path.split(parent_href)
-            subcats = [el for el in path_to_parent.split("/") if el]
+            # subcats = [el for el in path_to_parent.split("/") if el]
+            subcats = list(
+                Path(path_to_parent).parts[1:]
+            )  # Skip drive letter if present (Windows)
+
+            ## D: creates failure for py3.13 on windows
             assert len(subcats) == 2, f" for item '{item.id}'"
 
     def test_map_items(self) -> None:

From e79df49b4957bfb216512a7edbcddba4c63c8add Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 23 Nov 2024 15:30:16 -0700
Subject: [PATCH 16/23] use os path for path count in display as well

---
 tests/test_catalog.py |  1 -
 tests/test_layout.py  | 11 +++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/tests/test_catalog.py b/tests/test_catalog.py
index 12100b99d..a1bc3ab46 100644
--- a/tests/test_catalog.py
+++ b/tests/test_catalog.py
@@ -843,7 +843,6 @@ def test_generate_subcatalogs_works_for_subcatalogs_with_same_ids(self) -> None:
                 Path(path_to_parent).parts[1:]
             )  # Skip drive letter if present (Windows)
 
-            ## D: creates failure for py3.13 on windows
             assert len(subcats) == 2, f" for item '{item.id}'"
 
     def test_map_items(self) -> None:
diff --git a/tests/test_layout.py b/tests/test_layout.py
index ff27f76b2..c6a0fa52d 100644
--- a/tests/test_layout.py
+++ b/tests/test_layout.py
@@ -1,4 +1,6 @@
+import os
 import posixpath
+import sys
 import unittest
 from collections.abc import Callable
 from datetime import datetime, timedelta
@@ -413,6 +415,15 @@ class AsIsLayoutStrategyTest(unittest.TestCase):
     def setUp(self) -> None:
         self.strategy = AsIsLayoutStrategy()
 
+        path_includes_drive: bool = (
+            sys.version_info.major == 3
+            and sys.version_info.minor >= 13
+            and os.name == "nt"
+        )
+        self.expected_local_href = (
+            "/an/href" if not path_includes_drive else "D:/an/href"
+        )
+
     def test_catalog(self) -> None:
         cat = pystac.Catalog(id="test", description="test desc")
         with self.assertRaises(ValueError):

From 5cd3665a73484c36adfb3f6e5f160e290276edda Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 23 Nov 2024 15:30:16 -0700
Subject: [PATCH 17/23] use os path for path count in display as well

---
 tests/test_layout.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/test_layout.py b/tests/test_layout.py
index c6a0fa52d..003df47e5 100644
--- a/tests/test_layout.py
+++ b/tests/test_layout.py
@@ -432,7 +432,7 @@ def test_catalog(self) -> None:
         href = self.strategy.get_href(
             cat, parent_dir="https://example.com", is_root=True
         )
-        self.assertEqual(href, "/an/href")
+        self.assertEqual(href, self.expected_local_href)
 
     def test_collection(self) -> None:
         collection = TestCases.case_8()
@@ -445,7 +445,7 @@ def test_collection(self) -> None:
         href = self.strategy.get_href(
             collection, parent_dir="https://example.com", is_root=True
         )
-        self.assertEqual(href, "/an/href")
+        self.assertEqual(href, self.expected_local_href)
 
     def test_item(self) -> None:
         collection = TestCases.case_8()
@@ -455,7 +455,7 @@ def test_item(self) -> None:
             self.strategy.get_href(item, parent_dir="http://example.com")
         item.set_self_href("/an/href")
         href = self.strategy.get_href(item, parent_dir="http://example.com")
-        self.assertEqual(href, "/an/href")
+        self.assertEqual(href, self.expected_local_href)
 
 
 class APILayoutStrategyTest(unittest.TestCase):

From c00fff44823de0fc769a06c2f4ac34ad8e895f19 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 23 Nov 2024 15:45:00 -0700
Subject: [PATCH 18/23] rm whitespace

---
 pystac/utils.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/pystac/utils.py b/pystac/utils.py
index edb90c095..76c3f7100 100644
--- a/pystac/utils.py
+++ b/pystac/utils.py
@@ -364,7 +364,6 @@ def is_absolute_href(href: str) -> bool:
         bool: ``True`` if the given HREF is absolute, ``False`` if it is relative.
     """
     parsed = safe_urlparse(href)
-
     return parsed.scheme != "" or os.path.isabs(parsed.path)
 
 

From c38a786f72c2aabc9d02e858cf2af0b28d458b9e Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 23 Nov 2024 15:46:40 -0700
Subject: [PATCH 19/23] rm unecc comment

---
 tests/test_utils.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 728285737..5e7549c5d 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -252,7 +252,6 @@ def test_is_absolute_href_os_aware(self) -> None:
     def test_is_absolute_href_windows(self) -> None:
         # Test cases of (href, expected)
 
-        # Further nuanced cases for Windows.
         test_cases = [
             ("item.json", False),
             (".\\item.json", False),

From 56f76bec10af633eeede0c863f2c4011912a2f0f Mon Sep 17 00:00:00 2001
From: Pete Gadomski <pete.gadomski@gmail.com>
Date: Mon, 25 Nov 2024 06:50:01 -0700
Subject: [PATCH 20/23] Update tests/test_catalog.py

---
 tests/test_catalog.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/test_catalog.py b/tests/test_catalog.py
index a1bc3ab46..dfb3db2ed 100644
--- a/tests/test_catalog.py
+++ b/tests/test_catalog.py
@@ -838,7 +838,6 @@ def test_generate_subcatalogs_works_for_subcatalogs_with_same_ids(self) -> None:
             assert item_parent is not None
             parent_href = item_parent.self_href
             path_to_parent, _ = os.path.split(parent_href)
-            # subcats = [el for el in path_to_parent.split("/") if el]
             subcats = list(
                 Path(path_to_parent).parts[1:]
             )  # Skip drive letter if present (Windows)

From 19262b5c689951e878462c96a48b8fbee5946523 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 7 Dec 2024 14:00:58 -0700
Subject: [PATCH 21/23] factor out function

---
 tests/test_layout.py    | 19 ++++++++-----------
 tests/test_utils.py     | 13 +++----------
 tests/utils/__init__.py |  2 ++
 tests/utils/os_utils.py |  8 ++++++++
 4 files changed, 21 insertions(+), 21 deletions(-)
 create mode 100644 tests/utils/os_utils.py

diff --git a/tests/test_layout.py b/tests/test_layout.py
index 003df47e5..a71f94635 100644
--- a/tests/test_layout.py
+++ b/tests/test_layout.py
@@ -1,6 +1,4 @@
-import os
 import posixpath
-import sys
 import unittest
 from collections.abc import Callable
 from datetime import datetime, timedelta
@@ -17,7 +15,12 @@
     LayoutTemplate,
     TemplateLayoutStrategy,
 )
-from tests.utils import ARBITRARY_BBOX, ARBITRARY_GEOM, TestCases
+from tests.utils import (
+    ARBITRARY_BBOX,
+    ARBITRARY_GEOM,
+    TestCases,
+    path_includes_drive_letter,
+)
 
 
 class LayoutTemplateTest(unittest.TestCase):
@@ -300,7 +303,7 @@ def test_produces_fallback_layout_for_catalog(self) -> None:
         )
         cat = pystac.Catalog(id="test", description="test desc")
         href = strategy.get_href(cat, parent_dir="http://example.com")
-        expected = fallback.get_href(cat, parent_dir="http://example.com")
+        expected = fallback.get_href(cat, parent_dir="htt4p://example.com")
         self.assertEqual(href, expected)
 
     def test_produces_layout_for_collection(self) -> None:
@@ -414,14 +417,8 @@ def test_produces_layout_for_item(self) -> None:
 class AsIsLayoutStrategyTest(unittest.TestCase):
     def setUp(self) -> None:
         self.strategy = AsIsLayoutStrategy()
-
-        path_includes_drive: bool = (
-            sys.version_info.major == 3
-            and sys.version_info.minor >= 13
-            and os.name == "nt"
-        )
         self.expected_local_href = (
-            "/an/href" if not path_includes_drive else "D:/an/href"
+            "/an/href" if not path_includes_drive_letter() else "D:/an/href"
         )
 
     def test_catalog(self) -> None:
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 5e7549c5d..0c825bdad 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,6 +1,5 @@
 import json
 import os
-import sys
 import time
 import unittest
 from datetime import datetime, timedelta, timezone
@@ -22,7 +21,7 @@
     safe_urlparse,
     str_to_datetime,
 )
-from tests.utils import TestCases
+from tests.utils import TestCases, path_includes_drive_letter
 
 
 class UtilsTest(unittest.TestCase):
@@ -230,16 +229,10 @@ def test_is_absolute_href(self) -> None:
     def test_is_absolute_href_os_aware(self) -> None:
         # Test cases of (href, expected)
 
-        # These tests ensure that is_absolute_href can respond correctly to the os
-        # in a forwards and backwards compatible way.
-        # Windows requires a drive name when python > 3.13 (https://docs.python.org/3/library/os.path.html#os.path.isabs)
-        is_py_3_13: bool = sys.version_info.major == 3 and sys.version_info.minor >= 13
-
         is_windows = os.name == "nt"
-
         test_cases = [
-            ("/item.json", not (is_windows and is_py_3_13)),
-            ("/home/someuser/Downloads/item.json", not (is_windows and is_py_3_13)),
+            ("/item.json", not path_includes_drive_letter()),
+            ("/home/someuser/Downloads/item.json", not path_includes_drive_letter()),
             ("d:/item.json", is_windows),
             ("c:/files/more_files/item.json", is_windows),
         ]
diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py
index 1dc552f57..aa6af7c7e 100644
--- a/tests/utils/__init__.py
+++ b/tests/utils/__init__.py
@@ -4,6 +4,7 @@
     "ARBITRARY_BBOX",
     "ARBITRARY_EXTENT",
     "MockStacIO",
+    "path_includes_drive_letter",
 ]
 from copy import deepcopy
 from datetime import datetime
@@ -12,6 +13,7 @@
 from dateutil.parser import parse
 
 import pystac
+from tests.utils.os_utils import path_includes_drive_letter
 from tests.utils.stac_io_mock import MockStacIO
 from tests.utils.test_cases import (
     ARBITRARY_BBOX,
diff --git a/tests/utils/os_utils.py b/tests/utils/os_utils.py
new file mode 100644
index 000000000..89f99b523
--- /dev/null
+++ b/tests/utils/os_utils.py
@@ -0,0 +1,8 @@
+import os
+import sys
+
+
+def path_includes_drive_letter() -> bool:
+    return (
+        sys.version_info.major >= 3 and sys.version_info.minor >= 13 and os.name == "nt"
+    )

From 9a165c2cc5a1954f7b1efb13fc02526f709719eb Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 7 Dec 2024 14:02:14 -0700
Subject: [PATCH 22/23] typo

---
 tests/test_layout.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_layout.py b/tests/test_layout.py
index a71f94635..ad3996ed2 100644
--- a/tests/test_layout.py
+++ b/tests/test_layout.py
@@ -303,7 +303,7 @@ def test_produces_fallback_layout_for_catalog(self) -> None:
         )
         cat = pystac.Catalog(id="test", description="test desc")
         href = strategy.get_href(cat, parent_dir="http://example.com")
-        expected = fallback.get_href(cat, parent_dir="htt4p://example.com")
+        expected = fallback.get_href(cat, parent_dir="http://example.com")
         self.assertEqual(href, expected)
 
     def test_produces_layout_for_collection(self) -> None:

From 53afd3040e65ad2eed50119dc8eccb24f6a07bb9 Mon Sep 17 00:00:00 2001
From: KeynesYouDigit <vince.buscarello@gmail.com>
Date: Sat, 7 Dec 2024 14:04:27 -0700
Subject: [PATCH 23/23] factor out

---
 tests/test_utils.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/test_utils.py b/tests/test_utils.py
index 0c825bdad..5e9f85cef 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -230,9 +230,10 @@ def test_is_absolute_href_os_aware(self) -> None:
         # Test cases of (href, expected)
 
         is_windows = os.name == "nt"
+        incl_drive_letter = path_includes_drive_letter()
         test_cases = [
-            ("/item.json", not path_includes_drive_letter()),
-            ("/home/someuser/Downloads/item.json", not path_includes_drive_letter()),
+            ("/item.json", not incl_drive_letter),
+            ("/home/someuser/Downloads/item.json", not incl_drive_letter),
             ("d:/item.json", is_windows),
             ("c:/files/more_files/item.json", is_windows),
         ]