pw_ide, pw_presubmit: Remove Path.is_relative_to()

Remove uses of Path.is_relative_to() which is not supported by
Python 3.8.

Change-Id: I34746f777740639ac537b6d74cfe193d84223ed0
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/111474
Reviewed-by: Chad Norvell <chadnorvell@google.com>
Pigweed-Auto-Submit: Rob Mohr <mohrr@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com>
diff --git a/pw_ide/py/pw_ide/activate.py b/pw_ide/py/pw_ide/activate.py
index 6c83a6b..a11b33a 100644
--- a/pw_ide/py/pw_ide/activate.py
+++ b/pw_ide/py/pw_ide/activate.py
@@ -201,11 +201,19 @@
     user_home = Path.home().resolve()
     resolved_path = Path(path).resolve()
 
-    if resolved_path.is_relative_to(project_root):
+    # TODO(b/248257406) Remove once we drop support for Python 3.8.
+    def is_relative_to(path: Path, other: Path) -> bool:
+        try:
+            path.relative_to(other)
+            return True
+        except ValueError:
+            return False
+
+    if is_relative_to(resolved_path, project_root):
         return (f'{project_root_prefix}/' +
                 str(resolved_path.relative_to(project_root)))
 
-    if resolved_path.is_relative_to(user_home):
+    if is_relative_to(resolved_path, user_home):
         return (f'{user_home_prefix}/' +
                 str(resolved_path.relative_to(user_home)))
 
diff --git a/pw_presubmit/py/pw_presubmit/python_checks.py b/pw_presubmit/py/pw_presubmit/python_checks.py
index 482ae00..92ed5cc 100644
--- a/pw_presubmit/py/pw_presubmit/python_checks.py
+++ b/pw_presubmit/py/pw_presubmit/python_checks.py
@@ -79,10 +79,19 @@
         file_string = line[3:].rstrip()
         source_file_path = Path(file_string)
 
+        # TODO(b/248257406) Remove once we drop support for Python 3.8.
+        def is_relative_to(path: Path, other: Path) -> bool:
+            try:
+                path.relative_to(other)
+                return True
+            except ValueError:
+                return False
+
         # Attempt to map a generated Python package source file to the root
         # source tree.
         # pylint: disable=no-member
-        if not source_file_path.is_relative_to(  # type: ignore[attr-defined]
+        if not is_relative_to(
+                source_file_path,  # type: ignore[attr-defined]
                 repo_root):
             # pylint: enable=no-member
             source_file_path = repo_root / str(source_file_path).replace(
@@ -90,7 +99,8 @@
 
         # If mapping fails don't modify this line.
         # pylint: disable=no-member
-        if not source_file_path.is_relative_to(  # type: ignore[attr-defined]
+        if not is_relative_to(
+                source_file_path,  # type: ignore[attr-defined]
                 repo_root):
             # pylint: enable=no-member
             lcov_output += line + '\n'