Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-path for openSUSE:Factory 
checked in at 2024-04-16 20:03:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-path (Old)
 and      /work/SRC/openSUSE:Factory/.python-path.new.26366 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-path"

Tue Apr 16 20:03:11 2024 rev:10 rq:1167772 version:16.14.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-path/python-path.changes  2024-04-07 
22:04:51.340074772 +0200
+++ /work/SRC/openSUSE:Factory/.python-path.new.26366/python-path.changes       
2024-04-16 20:03:42.812161867 +0200
@@ -1,0 +2,9 @@
+Mon Apr 15 08:25:30 UTC 2024 - Dirk Müller <dmuel...@suse.com>
+
+- update to 16.14.0:
+  * Add .symlink_to and .hardlink_to.
+  * Add .cwd method and deprecated .getcwd.
+  * Create 'absolute' method and deprecate 'abspath'.
+  * In readlink, prefer the display path to the substitute path.
+
+-------------------------------------------------------------------

Old:
----
  path-16.12.1.tar.gz

New:
----
  path-16.14.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-path.spec ++++++
--- /var/tmp/diff_new_pack.A4Xjl5/_old  2024-04-16 20:03:44.196212744 +0200
+++ /var/tmp/diff_new_pack.A4Xjl5/_new  2024-04-16 20:03:44.196212744 +0200
@@ -27,7 +27,7 @@
 %define modname path
 %{?sle15_python_module_pythons}
 Name:           python-path%{psuffix}
-Version:        16.12.1
+Version:        16.14.0
 Release:        0
 Summary:        A module wrapper for os.path
 License:        MIT

++++++ path-16.12.1.tar.gz -> path-16.14.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/NEWS.rst new/path-16.14.0/NEWS.rst
--- old/path-16.12.1/NEWS.rst   2024-04-04 12:34:15.000000000 +0200
+++ new/path-16.14.0/NEWS.rst   2024-04-09 02:45:40.000000000 +0200
@@ -1,3 +1,23 @@
+v16.14.0
+========
+
+Features
+--------
+
+- Add .symlink_to and .hardlink_to. (#214)
+- Add .cwd method and deprecated .getcwd. (#214)
+
+
+v16.13.0
+========
+
+Features
+--------
+
+- Create 'absolute' method and deprecate 'abspath'. (#214)
+- In readlink, prefer the display path to the substitute path. (#222)
+
+
 v16.12.1
 ========
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/PKG-INFO new/path-16.14.0/PKG-INFO
--- old/path-16.12.1/PKG-INFO   2024-04-04 12:34:32.697444700 +0200
+++ new/path-16.14.0/PKG-INFO   2024-04-09 02:45:59.090091700 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: path
-Version: 16.12.1
+Version: 16.14.0
 Summary: A module wrapper for os.path
 Home-page: https://github.com/jaraco/path
 Author: Jason Orendorff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/path/__init__.py 
new/path-16.14.0/path/__init__.py
--- old/path-16.12.1/path/__init__.py   2024-04-04 12:34:15.000000000 +0200
+++ new/path-16.14.0/path/__init__.py   2024-04-09 02:45:40.000000000 +0200
@@ -25,23 +25,22 @@
 from __future__ import annotations
 
 import builtins
-import sys
-import warnings
-import os
+import contextlib
+import datetime
+import errno
 import fnmatch
+import functools
 import glob
-import shutil
 import hashlib
-import errno
-import tempfile
-import functools
-import re
-import contextlib
 import importlib
 import itertools
-import datetime
+import os
+import re
+import shutil
+import sys
+import tempfile
+import warnings
 from numbers import Number
-from typing import Union
 
 with contextlib.suppress(ImportError):
     import win32security
@@ -60,32 +59,27 @@
     TextIOWrapper,
 )
 from typing import (
+    IO,
+    TYPE_CHECKING,
     Any,
     BinaryIO,
     Callable,
-    IO,
     Iterator,
-    Optional,
     overload,
 )
 
-from typing import TYPE_CHECKING
-
 if TYPE_CHECKING:
     from _typeshed import (
         OpenBinaryMode,
-        OpenBinaryModeUpdating,
         OpenBinaryModeReading,
+        OpenBinaryModeUpdating,
         OpenBinaryModeWriting,
         OpenTextMode,
     )
     from typing_extensions import Literal
 
-from . import matchers
-from . import masks
-from . import classes
-from .compat.py38 import removesuffix
-
+from . import classes, masks, matchers
+from .compat.py38 import removeprefix, removesuffix
 
 __all__ = ['Path', 'TempDir']
 
@@ -100,7 +94,7 @@
 _default_linesep = object()
 
 
-def _make_timestamp_ns(value: Union[Number, datetime.datetime]) -> Number:
+def _make_timestamp_ns(value: Number | datetime.datetime) -> Number:
     timestamp_s = value if isinstance(value, Number) else value.timestamp()
     return int(timestamp_s * 10**9)
 
@@ -203,7 +197,7 @@
     # --- Special Python methods.
 
     def __repr__(self):
-        return '{}({})'.format(type(self).__name__, super().__repr__())
+        return f'{type(self).__name__}({super().__repr__()})'
 
     # Adding a Path and a string yields a Path.
     def __add__(self, more):
@@ -241,7 +235,7 @@
     __rtruediv__ = __rdiv__
 
     def __enter__(self):
-        self._old_dir = self.getcwd()
+        self._old_dir = self.cwd()
         os.chdir(self)
         return self
 
@@ -249,20 +243,37 @@
         os.chdir(self._old_dir)
 
     @classmethod
-    def getcwd(cls):
+    def cwd(cls):
         """Return the current working directory as a path object.
 
         .. seealso:: :func:`os.getcwd`
         """
         return cls(os.getcwd())
 
+    @classmethod
+    def getcwd(cls):
+        warnings.warn(
+            ".getcwd is deprecated; use cwd",
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        return cls.cwd()
+
     #
     # --- Operations on Path strings.
 
-    def abspath(self):
+    def absolute(self):
         """.. seealso:: :func:`os.path.abspath`"""
         return self._next_class(self.module.abspath(self))
 
+    def abspath(self):
+        warnings.warn(
+            ".abspath is deprecated; use absolute",
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        return self.absolute()
+
     def normcase(self):
         """.. seealso:: :func:`os.path.normcase`"""
         return self._next_class(self.module.normcase(self))
@@ -325,7 +336,7 @@
         return suffix
 
     @property
-    def ext(self):
+    def ext(self):  # pragma: no cover
         warnings.warn(
             ".ext is deprecated; use suffix",
             DeprecationWarning,
@@ -498,10 +509,10 @@
 
         If there is no relative path from `self` to `dest`, for example if
         they reside on different drives in Windows, then this returns
-        ``dest.abspath()``.
+        ``dest.absolute()``.
         """
-        origin = self.abspath()
-        dest = self._next_class(dest).abspath()
+        origin = self.absolute()
+        dest = self._next_class(dest).absolute()
 
         orig_list = origin.normcase().splitall()
         # Don't normcase dest!  We want to preserve the case.
@@ -689,11 +700,11 @@
         self,
         mode: OpenTextMode = ...,
         buffering: int = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
-        opener: Optional[Callable[[str, int], int]] = ...,
+        opener: Callable[[str, int], int] | None = ...,
     ) -> TextIOWrapper: ...
 
     @overload
@@ -701,9 +712,9 @@
         self,
         mode: OpenBinaryMode,
         buffering: Literal[0],
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
         opener: Callable[[str, int], int] = ...,
     ) -> FileIO: ...
@@ -713,9 +724,9 @@
         self,
         mode: OpenBinaryModeUpdating,
         buffering: Literal[-1, 1] = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
         opener: Callable[[str, int], int] = ...,
     ) -> BufferedRandom: ...
@@ -725,9 +736,9 @@
         self,
         mode: OpenBinaryModeReading,
         buffering: Literal[-1, 1] = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
         opener: Callable[[str, int], int] = ...,
     ) -> BufferedReader: ...
@@ -737,9 +748,9 @@
         self,
         mode: OpenBinaryModeWriting,
         buffering: Literal[-1, 1] = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
         opener: Callable[[str, int], int] = ...,
     ) -> BufferedWriter: ...
@@ -749,9 +760,9 @@
         self,
         mode: OpenBinaryMode,
         buffering: int,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
         opener: Callable[[str, int], int] = ...,
     ) -> BinaryIO: ...
@@ -761,9 +772,9 @@
         self,
         mode: str,
         buffering: int = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
         opener: Callable[[str, int], int] = ...,
     ) -> IO[Any]: ...
@@ -787,11 +798,11 @@
         size: int,
         mode: OpenTextMode = ...,
         buffering: int = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
-        opener: Optional[Callable[[str, int], int]] = ...,
+        opener: Callable[[str, int], int] | None = ...,
     ) -> Iterator[str]: ...
 
     @overload
@@ -800,11 +811,11 @@
         size: int,
         mode: OpenBinaryMode,
         buffering: int = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
-        opener: Optional[Callable[[str, int], int]] = ...,
+        opener: Callable[[str, int], int] | None = ...,
     ) -> Iterator[builtins.bytes]: ...
 
     @overload
@@ -813,12 +824,12 @@
         size: int,
         mode: str,
         buffering: int = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
         closefd: bool = ...,
-        opener: Optional[Callable[[str, int], int]] = ...,
-    ) -> Iterator[Union[str, builtins.bytes]]: ...
+        opener: Callable[[str, int], int] | None = ...,
+    ) -> Iterator[str | builtins.bytes]: ...
 
     def chunks(self, size, *args, **kwargs):
         """Returns a generator yielding chunks of the file, so it can
@@ -877,9 +888,9 @@
     def write_text(
         self,
         text: str,
-        encoding: Optional[str] = ...,
+        encoding: str | None = ...,
         errors: str = ...,
-        linesep: Optional[str] = ...,
+        linesep: str | None = ...,
         append: bool = ...,
     ) -> None: ...
 
@@ -889,7 +900,7 @@
         text: builtins.bytes,
         encoding: None = ...,
         errors: str = ...,
-        linesep: Optional[str] = ...,
+        linesep: str | None = ...,
         append: bool = ...,
     ) -> None: ...
 
@@ -1096,7 +1107,7 @@
         """.. seealso:: :func:`os.path.exists`"""
         return self.module.exists(self)
 
-    def isdir(self):
+    def isdir(self):  # pragma: no cover
         warnings.warn(
             "isdir is deprecated; use is_dir",
             DeprecationWarning,
@@ -1108,7 +1119,7 @@
         """.. seealso:: :func:`os.path.isdir`"""
         return self.module.isdir(self)
 
-    def isfile(self):
+    def isfile(self):  # pragma: no cover
         warnings.warn(
             "isfile is deprecated; use is_file",
             DeprecationWarning,
@@ -1248,7 +1259,7 @@
         """
         return os.access(self, *args, **kwargs)
 
-    def stat(self):
+    def stat(self, *, follow_symlinks=True):
         """
         Perform a ``stat()`` system call on this path.
 
@@ -1257,7 +1268,7 @@
 
         .. seealso:: :meth:`lstat`, :func:`os.stat`
         """
-        return os.stat(self)
+        return os.stat(self, follow_symlinks=follow_symlinks)
 
     def lstat(self):
         """
@@ -1316,6 +1327,15 @@
         .. seealso:: :meth:`get_owner`""",
     )
 
+    if 'grp' in globals():  # pragma: no cover
+
+        def group(self, *, follow_symlinks=True):
+            """
+            Return the group name of the file gid.
+            """
+            gid = self.stat(follow_symlinks=follow_symlinks).st_gid
+            return grp.getgrgid(gid).gr_name
+
     if hasattr(os, 'statvfs'):
 
         def statvfs(self):
@@ -1470,6 +1490,14 @@
 
     # --- Links
 
+    def hardlink_to(self, target: str) -> None:
+        """
+        Create a hard link at self, pointing to target.
+
+        .. seealso:: :func:`os.link`
+        """
+        os.link(target, self)
+
     def link(self, newpath):
         """Create a hard link at `newpath`, pointing to this file.
 
@@ -1478,6 +1506,14 @@
         os.link(self, newpath)
         return self._next_class(newpath)
 
+    def symlink_to(self, target: str, target_is_directory: bool = False) -> 
None:
+        """
+        Create a symbolic link at self, pointing to target.
+
+        .. seealso:: :func:`os.symlink`
+        """
+        os.symlink(target, self, target_is_directory)
+
     def symlink(self, newlink=None):
         """Create a symbolic link at `newlink`, pointing here.
 
@@ -1498,7 +1534,7 @@
 
         .. seealso:: :meth:`readlinkabs`, :func:`os.readlink`
         """
-        return self._next_class(os.readlink(self))
+        return self._next_class(removeprefix(os.readlink(self), '\\\\?\\'))
 
     def readlinkabs(self):
         """Return the path to which this symbolic link points.
@@ -1508,7 +1544,7 @@
         .. seealso:: :meth:`readlink`, :func:`os.readlink`
         """
         p = self.readlink()
-        return p if p.isabs() else (self.parent / p).abspath()
+        return p if p.isabs() else (self.parent / p).absolute()
 
     # High-level functions from shutil
     # These functions will be bound to the instance such that
@@ -1873,7 +1909,7 @@
         raise
 
     def warn(msg):
-        warnings.warn(msg, TreeWalkWarning)
+        warnings.warn(msg, TreeWalkWarning, stacklevel=2)
 
     def ignore(msg):
         pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/path/__init__.pyi 
new/path-16.14.0/path/__init__.pyi
--- old/path-16.12.1/path/__init__.pyi  2024-04-04 12:34:15.000000000 +0200
+++ new/path-16.14.0/path/__init__.pyi  2024-04-09 02:45:40.000000000 +0200
@@ -6,19 +6,13 @@
 import sys
 from types import ModuleType, TracebackType
 from typing import (
+    IO,
     Any,
     AnyStr,
     Callable,
     Generator,
     Iterable,
     Iterator,
-    IO,
-    List,
-    Optional,
-    Set,
-    Tuple,
-    Type,
-    Union,
 )
 
 from _typeshed import (
@@ -28,7 +22,7 @@
 from . import classes
 
 # Type for the match argument for several methods
-_Match = Optional[Union[str, Callable[[str], bool], Callable[[Path], bool]]]
+_Match = str | Callable[[str], bool] | Callable[[Path], bool] | None
 
 class TreeWalkWarning(Warning):
     pass
@@ -39,7 +33,7 @@
     def __init__(self, follow: Callable[[Path], bool]): ...
     def __call__(
         self,
-        walker: Generator[Path, Optional[Callable[[], bool]], None],
+        walker: Generator[Path, Callable[[], bool] | None, None],
     ) -> Iterator[Path]: ...
 
 class Path(str):
@@ -47,10 +41,10 @@
 
     def __init__(self, other: Any = ...) -> None: ...
     @classmethod
-    def using_module(cls, module: ModuleType) -> Type[Path]: ...
+    def using_module(cls, module: ModuleType) -> type[Path]: ...
     @classes.ClassProperty
     @classmethod
-    def _next_class(cls: Type[Self]) -> Type[Self]: ...
+    def _next_class(cls: type[Self]) -> type[Self]: ...
     def __repr__(self) -> str: ...
     def __add__(self: Self, more: str) -> Self: ...
     def __radd__(self: Self, other: str) -> Self: ...
@@ -61,12 +55,12 @@
     def __enter__(self: Self) -> Self: ...
     def __exit__(
         self,
-        exc_type: Optional[type[BaseException]],
-        exc_val: Optional[BaseException],
-        exc_tb: Optional[TracebackType],
+        exc_type: type[BaseException] | None,
+        exc_val: BaseException | None,
+        exc_tb: TracebackType | None,
     ) -> None: ...
     @classmethod
-    def getcwd(cls: Type[Self]) -> Self: ...
+    def getcwd(cls: type[Self]) -> Self: ...
     def abspath(self: Self) -> Self: ...
     def normcase(self: Self) -> Self: ...
     def normpath(self: Self) -> Self: ...
@@ -87,29 +81,29 @@
     def parent(self: Self) -> Self: ...
     @property
     def name(self: Self) -> Self: ...
-    def splitpath(self: Self) -> Tuple[Self, str]: ...
-    def splitdrive(self: Self) -> Tuple[Self, Self]: ...
-    def splitext(self: Self) -> Tuple[Self, str]: ...
+    def splitpath(self: Self) -> tuple[Self, str]: ...
+    def splitdrive(self: Self) -> tuple[Self, Self]: ...
+    def splitext(self: Self) -> tuple[Self, str]: ...
     def stripext(self: Self) -> Self: ...
     @classes.multimethod
     def joinpath(cls: Self, first: str, *others: str) -> Self: ...
-    def splitall(self: Self) -> List[Union[Self, str]]: ...
-    def parts(self: Self) -> Tuple[Union[Self, str], ...]: ...
-    def _parts(self: Self) -> Iterator[Union[Self, str]]: ...
-    def _parts_iter(self: Self) -> Iterator[Union[Self, str]]: ...
+    def splitall(self: Self) -> list[Self | str]: ...
+    def parts(self: Self) -> tuple[Self | str, ...]: ...
+    def _parts(self: Self) -> Iterator[Self | str]: ...
+    def _parts_iter(self: Self) -> Iterator[Self | str]: ...
     def relpath(self: Self, start: str = ...) -> Self: ...
     def relpathto(self: Self, dest: str) -> Self: ...
 
     # --- Listing, searching, walking, and matching
     def iterdir(self: Self, match: _Match = ...) -> Iterator[Self]: ...
-    def listdir(self: Self, match: _Match = ...) -> List[Self]: ...
-    def dirs(self: Self, match: _Match = ...) -> List[Self]: ...
-    def files(self: Self, match: _Match = ...) -> List[Self]: ...
+    def listdir(self: Self, match: _Match = ...) -> list[Self]: ...
+    def dirs(self: Self, match: _Match = ...) -> list[Self]: ...
+    def files(self: Self, match: _Match = ...) -> list[Self]: ...
     def walk(
         self: Self,
         match: _Match = ...,
         errors: str = ...,
-    ) -> Generator[Self, Optional[Callable[[], bool]], None]: ...
+    ) -> Generator[Self, Callable[[], bool] | None, None]: ...
     def walkdirs(
         self: Self,
         match: _Match = ...,
@@ -122,30 +116,30 @@
     ) -> Iterator[Self]: ...
     def fnmatch(
         self,
-        pattern: Union[Path, str],
-        normcase: Optional[Callable[[str], str]] = ...,
+        pattern: Path | str,
+        normcase: Callable[[str], str] | None = ...,
     ) -> bool: ...
-    def glob(self: Self, pattern: str) -> List[Self]: ...
+    def glob(self: Self, pattern: str) -> list[Self]: ...
     def iglob(self: Self, pattern: str) -> Iterator[Self]: ...
     def bytes(self) -> builtins.bytes: ...
     def write_bytes(self, bytes: builtins.bytes, append: bool = ...) -> None: 
...
     def read_text(
-        self, encoding: Optional[str] = ..., errors: Optional[str] = ...
+        self, encoding: str | None = ..., errors: str | None = ...
     ) -> str: ...
     def read_bytes(self) -> builtins.bytes: ...
-    def text(self, encoding: Optional[str] = ..., errors: str = ...) -> str: 
...
+    def text(self, encoding: str | None = ..., errors: str = ...) -> str: ...
     def lines(
         self,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
+        encoding: str | None = ...,
+        errors: str | None = ...,
         retain: bool = ...,
-    ) -> List[str]: ...
+    ) -> list[str]: ...
     def write_lines(
         self,
-        lines: List[str],
-        encoding: Optional[str] = ...,
+        lines: list[str],
+        encoding: str | None = ...,
         errors: str = ...,
-        linesep: Optional[str] = ...,
+        linesep: str | None = ...,
         append: bool = ...,
     ) -> None: ...
     def read_md5(self) -> builtins.bytes: ...
@@ -176,7 +170,7 @@
         self,
         mode: int,
         *,
-        dir_fd: Optional[int] = ...,
+        dir_fd: int | None = ...,
         effective_ids: bool = ...,
         follow_symlinks: bool = ...,
     ) -> bool: ...
@@ -188,22 +182,20 @@
 
     if sys.platform != 'win32':
         def statvfs(self) -> os.statvfs_result: ...
-        def pathconf(self, name: Union[str, int]) -> int: ...
+        def pathconf(self, name: str | int) -> int: ...
 
     def utime(
         self,
-        times: Union[Tuple[int, int], Tuple[float, float], None] = ...,
+        times: tuple[int, int] | tuple[float, float] | None = ...,
         *,
-        ns: Tuple[int, int] = ...,
-        dir_fd: Optional[int] = ...,
+        ns: tuple[int, int] = ...,
+        dir_fd: int | None = ...,
         follow_symlinks: bool = ...,
     ) -> Path: ...
-    def chmod(self: Self, mode: Union[str, int]) -> Self: ...
+    def chmod(self: Self, mode: str | int) -> Self: ...
 
     if sys.platform != 'win32':
-        def chown(
-            self: Self, uid: Union[int, str] = ..., gid: Union[int, str] = ...
-        ) -> Self: ...
+        def chown(self: Self, uid: int | str = ..., gid: int | str = ...) -> 
Self: ...
 
     def rename(self: Self, new: str) -> Self: ...
     def renames(self: Self, new: str) -> Self: ...
@@ -221,7 +213,7 @@
     def unlink(self: Self) -> Self: ...
     def unlink_p(self: Self) -> Self: ...
     def link(self: Self, newpath: str) -> Self: ...
-    def symlink(self: Self, newlink: Optional[str] = ...) -> Self: ...
+    def symlink(self: Self, newlink: str | None = ...) -> Self: ...
     def readlink(self: Self) -> Self: ...
     def readlinkabs(self: Self) -> Self: ...
     def copyfile(self, dst: str, *, follow_symlinks: bool = ...) -> str: ...
@@ -233,7 +225,7 @@
         self,
         dst: str,
         symlinks: bool = ...,
-        ignore: Optional[Callable[[str, list[str]], Iterable[str]]] = ...,
+        ignore: Callable[[str, list[str]], Iterable[str]] | None = ...,
         copy_function: Callable[[str, str], None] = ...,
         ignore_dangling_symlinks: bool = ...,
         dirs_exist_ok: bool = ...,
@@ -244,7 +236,7 @@
     def rmtree(
         self,
         ignore_errors: bool = ...,
-        onerror: Optional[Callable[[Any, Any, Any], Any]] = ...,
+        onerror: Callable[[Any, Any, Any], Any] | None = ...,
     ) -> None: ...
     def rmtree_p(self: Self) -> Self: ...
     def chdir(self) -> None: ...
@@ -255,28 +247,28 @@
         symlinks: bool = ...,
         *,
         copy_function: Callable[[str, str], None] = ...,
-        ignore: Callable[[Any, List[str]], Union[List[str], Set[str]]] = ...,
+        ignore: Callable[[Any, list[str]], list[str] | set[str]] = ...,
     ) -> None: ...
 
     if sys.platform != 'win32':
         def chroot(self) -> None: ...
 
     if sys.platform == 'win32':
-        def startfile(self: Self, operation: Optional[str] = ...) -> Self: ...
+        def startfile(self: Self, operation: str | None = ...) -> Self: ...
 
     @contextlib.contextmanager
     def in_place(
         self,
         mode: str = ...,
         buffering: int = ...,
-        encoding: Optional[str] = ...,
-        errors: Optional[str] = ...,
-        newline: Optional[str] = ...,
-        backup_extension: Optional[str] = ...,
-    ) -> Iterator[Tuple[IO[Any], IO[Any]]]: ...
+        encoding: str | None = ...,
+        errors: str | None = ...,
+        newline: str | None = ...,
+        backup_extension: str | None = ...,
+    ) -> Iterator[tuple[IO[Any], IO[Any]]]: ...
     @classes.ClassProperty
     @classmethod
-    def special(cls) -> Callable[[Optional[str]], SpecialResolver]: ...
+    def special(cls) -> Callable[[str | None], SpecialResolver]: ...
 
 class DirectoryNotEmpty(OSError):
     @staticmethod
@@ -298,9 +290,9 @@
     def __init__(
         self,
         path_class: type,
-        appname: Optional[str] = ...,
-        appauthor: Optional[str] = ...,
-        version: Optional[str] = ...,
+        appname: str | None = ...,
+        appauthor: str | None = ...,
+        version: str | None = ...,
         roaming: bool = ...,
         multipath: bool = ...,
     ): ...
@@ -309,13 +301,13 @@
 
 class Multi:
     @classmethod
-    def for_class(cls, path_cls: type) -> Type[MultiPathType]: ...
+    def for_class(cls, path_cls: type) -> type[MultiPathType]: ...
     @classmethod
     def detect(cls, input: str) -> MultiPathType: ...
     def __iter__(self) -> Iterator[Path]: ...
     @classes.ClassProperty
     @classmethod
-    def _next_class(cls) -> Type[Path]: ...
+    def _next_class(cls) -> type[Path]: ...
 
 class MultiPathType(Multi, Path):
     pass
@@ -323,24 +315,22 @@
 class TempDir(Path):
     @classes.ClassProperty
     @classmethod
-    def _next_class(cls) -> Type[Path]: ...
+    def _next_class(cls) -> type[Path]: ...
     def __new__(
-        cls: Type[Self],
-        suffix: Optional[AnyStr] = ...,
-        prefix: Optional[AnyStr] = ...,
-        dir: Optional[Union[AnyStr, os.PathLike[AnyStr]]] = ...,
+        cls: type[Self],
+        suffix: AnyStr | None = ...,
+        prefix: AnyStr | None = ...,
+        dir: AnyStr | os.PathLike[AnyStr] | None = ...,
     ) -> Self: ...
     def __init__(self) -> None: ...
     def __enter__(self) -> Path: ...  # type: ignore
     def __exit__(
         self,
-        exc_type: Optional[type[BaseException]],
-        exc_val: Optional[BaseException],
-        exc_tb: Optional[TracebackType],
+        exc_type: type[BaseException] | None,
+        exc_val: BaseException | None,
+        exc_tb: TracebackType | None,
     ) -> None: ...
 
 class Handlers:
     @classmethod
-    def _resolve(
-        cls, param: Union[str, Callable[[str], None]]
-    ) -> Callable[[str], None]: ...
+    def _resolve(cls, param: str | Callable[[str], None]) -> Callable[[str], 
None]: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/path/classes.pyi 
new/path-16.14.0/path/classes.pyi
--- old/path-16.12.1/path/classes.pyi   2024-04-04 12:34:15.000000000 +0200
+++ new/path-16.14.0/path/classes.pyi   2024-04-09 02:45:40.000000000 +0200
@@ -1,8 +1,8 @@
 from typing import Any, Callable, Optional
 
 class ClassProperty(property):
-    def __get__(self, cls: Any, owner: Optional[type] = ...) -> Any: ...
+    def __get__(self, cls: Any, owner: type | None = ...) -> Any: ...
 
 class multimethod:
     def __init__(self, func: Callable[..., Any]): ...
-    def __get__(self, instance: Any, owner: Optional[type]) -> Any: ...
+    def __get__(self, instance: Any, owner: type | None) -> Any: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/path/compat/py38.py 
new/path-16.14.0/path/compat/py38.py
--- old/path-16.12.1/path/compat/py38.py        2024-04-04 12:34:15.000000000 
+0200
+++ new/path-16.14.0/path/compat/py38.py        2024-04-09 02:45:40.000000000 
+0200
@@ -1,6 +1,5 @@
 import sys
 
-
 if sys.version_info < (3, 9):
 
     def removesuffix(self, suffix):
@@ -9,7 +8,16 @@
             return self[: -len(suffix)]
         else:
             return self[:]
+
+    def removeprefix(self, prefix):
+        if self.startswith(prefix):
+            return self[len(prefix) :]
+        else:
+            return self[:]
 else:
 
     def removesuffix(self, suffix):
         return self.removesuffix(suffix)
+
+    def removeprefix(self, prefix):
+        return self.removeprefix(prefix)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/path/masks.py 
new/path-16.14.0/path/masks.py
--- old/path-16.12.1/path/masks.py      2024-04-04 12:34:15.000000000 +0200
+++ new/path-16.14.0/path/masks.py      2024-04-09 02:45:40.000000000 +0200
@@ -1,8 +1,7 @@
-import re
 import functools
-import operator
 import itertools
-
+import operator
+import re
 
 # from jaraco.functools
 from typing import Any, Callable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/path/matchers.py 
new/path-16.14.0/path/matchers.py
--- old/path-16.12.1/path/matchers.py   2024-04-04 12:34:15.000000000 +0200
+++ new/path-16.14.0/path/matchers.py   2024-04-09 02:45:40.000000000 +0200
@@ -1,9 +1,7 @@
 from __future__ import annotations
 
-import ntpath
 import fnmatch
-
-
+import ntpath
 from typing import Any, overload
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/path.egg-info/PKG-INFO 
new/path-16.14.0/path.egg-info/PKG-INFO
--- old/path-16.12.1/path.egg-info/PKG-INFO     2024-04-04 12:34:32.000000000 
+0200
+++ new/path-16.14.0/path.egg-info/PKG-INFO     2024-04-09 02:45:59.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: path
-Version: 16.12.1
+Version: 16.14.0
 Summary: A module wrapper for os.path
 Home-page: https://github.com/jaraco/path
 Author: Jason Orendorff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/path-16.12.1/test_path.py 
new/path-16.14.0/test_path.py
--- old/path-16.12.1/test_path.py       2024-04-04 12:34:15.000000000 +0200
+++ new/path-16.14.0/test_path.py       2024-04-09 02:45:40.000000000 +0200
@@ -13,31 +13,27 @@
 time on files.
 """
 
-import os
-import sys
-import shutil
-import time
-import types
+import contextlib
+import datetime
+import importlib
 import ntpath
-import posixpath
-import textwrap
+import os
 import platform
-import importlib
-import datetime
-import subprocess
+import posixpath
 import re
-import contextlib
+import shutil
 import stat
+import subprocess
+import sys
+import textwrap
+import time
+import types
 
 import pytest
 from more_itertools import ilen
 
 import path
-from path import Path
-from path import TempDir
-from path import matchers
-from path import SpecialResolver
-from path import Multi
+from path import Multi, Path, SpecialResolver, TempDir, matchers
 
 
 def os_choose(**choices):
@@ -138,12 +134,11 @@
         # .drive
         assert f.drive == os_choose(nt='C:', posix='')
 
-    def test_methods(self):
-        # .abspath()
-        assert Path(os.curdir).abspath() == os.getcwd()
+    def test_absolute(self):
+        assert Path(os.curdir).absolute() == os.getcwd()
 
-        # .getcwd()
-        cwd = Path.getcwd()
+    def test_cwd(self):
+        cwd = Path.cwd()
         assert isinstance(cwd, Path)
         assert cwd == os.getcwd()
 
@@ -305,6 +300,11 @@
         # TODO: shouldn't sub get removed?
         # assert not (dir / 'sub').is_dir()
 
+    @pytest.mark.skipif("not hasattr(Path, 'group')")
+    def test_group(self, tmpdir):
+        file = Path(tmpdir).joinpath('file').touch()
+        assert isinstance(file.group(), str)
+
 
 class TestReadWriteText:
     def test_read_write(self, tmpdir):
@@ -349,12 +349,26 @@
 
 
 class TestLinks:
+    def test_hardlink_to(self, tmpdir):
+        target = Path(tmpdir) / 'target'
+        target.write_text('hello', encoding='utf-8')
+        link = Path(tmpdir).joinpath('link')
+        link.hardlink_to(target)
+        assert link.read_text(encoding='utf-8') == 'hello'
+
     def test_link(self, tmpdir):
         target = Path(tmpdir) / 'target'
         target.write_text('hello', encoding='utf-8')
         link = target.link(Path(tmpdir) / 'link')
         assert link.read_text(encoding='utf-8') == 'hello'
 
+    def test_symlink_to(self, tmpdir):
+        target = Path(tmpdir) / 'target'
+        target.write_text('hello', encoding='utf-8')
+        link = Path(tmpdir).joinpath('link')
+        link.symlink_to(target)
+        assert link.read_text(encoding='utf-8') == 'hello'
+
     def test_symlink_none(self, tmpdir):
         root = Path(tmpdir)
         with root:
@@ -364,13 +378,13 @@
 
     def test_readlinkabs_passthrough(self, tmpdir):
         link = Path(tmpdir) / 'link'
-        Path('foo').abspath().symlink(link)
-        link.readlinkabs() == Path('foo').abspath()
+        Path('foo').absolute().symlink(link)
+        assert link.readlinkabs() == Path('foo').absolute()
 
     def test_readlinkabs_rendered(self, tmpdir):
         link = Path(tmpdir) / 'link'
         Path('foo').symlink(link)
-        link.readlinkabs() == Path(tmpdir) / 'foo'
+        assert link.readlinkabs() == Path(tmpdir) / 'foo'
 
 
 class TestSymbolicLinksWalk:
@@ -563,7 +577,7 @@
             with open(os.path.join(base, name), 'wb'):
                 pass
         except Exception as exc:
-            raise pytest.skip(f"Invalid encodings disallowed {exc}")
+            raise pytest.skip(f"Invalid encodings disallowed {exc}") from exc
         return name
 
     def test_iterdir_other_encoding(self, tmpdir, bytes_filename):  # pragma: 
nocover
@@ -995,7 +1009,7 @@
     def test_chdir_or_cd(self, tmpdir):
         """tests the chdir or cd method"""
         d = Path(str(tmpdir))
-        cwd = d.getcwd()
+        cwd = d.cwd()
 
         # ensure the cwd isn't our tempdir
         assert str(d) != str(cwd)
@@ -1003,18 +1017,18 @@
         d.chdir()
 
         # we now ensure that our cwd is the tempdir
-        assert str(d.getcwd()) == str(tmpdir)
+        assert str(d.cwd()) == str(tmpdir)
         # we're resetting our path
         d = Path(cwd)
 
         # we ensure that our cwd is still set to tempdir
-        assert str(d.getcwd()) == str(tmpdir)
+        assert str(d.cwd()) == str(tmpdir)
 
         # we're calling the alias cd method
         d.cd()
         # now, we ensure cwd isn'r tempdir
-        assert str(d.getcwd()) == str(cwd)
-        assert str(d.getcwd()) != str(tmpdir)
+        assert str(d.cwd()) == str(cwd)
+        assert str(d.cwd()) != str(tmpdir)
 
 
 class TestSubclass:
@@ -1092,7 +1106,7 @@
         Path(tmpdir).joinpath('☃').mkdir()
 
     def test_walkdirs_with_unicode_name(self, tmpdir):
-        for res in Path(tmpdir).walkdirs():
+        for _res in Path(tmpdir).walkdirs():
             pass
 
 

Reply via email to