GH-139174: Prepare `pathlib.Path.info` for new methods (part 2) (#140… · python/cpython@1bfe86c

GitHub

@@ -611,72 +611,29 @@ class PureWindowsPath(PurePath):

611611__slots__= ()

612612613613614-class_Info:

615-__slots__= ('_path',)

616-617-def__init__(self, path):

618-self._path=path

619-620-def__repr__(self):

621-path_type="WindowsPath"ifos.name=="nt"else"PosixPath"

622-returnf"<{path_type}.info>"

623-624-def_stat(self, *, follow_symlinks=True):

625-"""Return the status as an os.stat_result."""

626-raiseNotImplementedError

627-628-def_posix_permissions(self, *, follow_symlinks=True):

629-"""Return the POSIX file permissions."""

630-returnS_IMODE(self._stat(follow_symlinks=follow_symlinks).st_mode)

631-632-def_file_id(self, *, follow_symlinks=True):

633-"""Returns the identifier of the file."""

634-st=self._stat(follow_symlinks=follow_symlinks)

635-returnst.st_dev, st.st_ino

636-637-def_access_time_ns(self, *, follow_symlinks=True):

638-"""Return the access time in nanoseconds."""

639-returnself._stat(follow_symlinks=follow_symlinks).st_atime_ns

640-641-def_mod_time_ns(self, *, follow_symlinks=True):

642-"""Return the modify time in nanoseconds."""

643-returnself._stat(follow_symlinks=follow_symlinks).st_mtime_ns

644-645-ifhasattr(os.stat_result, 'st_flags'):

646-def_bsd_flags(self, *, follow_symlinks=True):

647-"""Return the flags."""

648-returnself._stat(follow_symlinks=follow_symlinks).st_flags

649-650-ifhasattr(os, 'listxattr'):

651-def_xattrs(self, *, follow_symlinks=True):

652-"""Return the xattrs as a list of (attr, value) pairs, or an empty

653- list if extended attributes aren't supported."""

654-try:

655-return [

656- (attr, os.getxattr(self._path, attr, follow_symlinks=follow_symlinks))

657-forattrinos.listxattr(self._path, follow_symlinks=follow_symlinks)]

658-exceptOSErroraserr:

659-iferr.errnonotin (EPERM, ENOTSUP, ENODATA, EINVAL, EACCES):

660-raise

661-return []

662-663-664614_STAT_RESULT_ERROR= [] # falsy sentinel indicating stat() failed.

665615666616667-class_StatResultInfo(_Info):

617+class_Info:

668618"""Implementation of pathlib.types.PathInfo that provides status

669619 information by querying a wrapped os.stat_result object. Don't try to

670620 construct it yourself."""

671-__slots__= ('_stat_result', '_lstat_result')

621+__slots__= ('_path', '_entry', '_stat_result', '_lstat_result')

672622673-def__init__(self, path):

674-super().__init__(path)

623+def__init__(self, path, entry=None):

624+self._path=path

625+self._entry=entry

675626self._stat_result=None

676627self._lstat_result=None

677628629+def__repr__(self):

630+path_type="WindowsPath"ifos.name=="nt"else"PosixPath"

631+returnf"<{path_type}.info>"

632+678633def_stat(self, *, follow_symlinks=True):

679634"""Return the status as an os.stat_result."""

635+ifself._entry:

636+returnself._entry.stat(follow_symlinks=follow_symlinks)

680637iffollow_symlinks:

681638ifnotself._stat_result:

682639try:

@@ -696,6 +653,9 @@ def _stat(self, *, follow_symlinks=True):

696653697654defexists(self, *, follow_symlinks=True):

698655"""Whether this path exists."""

656+ifself._entry:

657+ifnotfollow_symlinks:

658+returnTrue

699659iffollow_symlinks:

700660ifself._stat_resultis_STAT_RESULT_ERROR:

701661returnFalse

@@ -710,6 +670,11 @@ def exists(self, *, follow_symlinks=True):

710670711671defis_dir(self, *, follow_symlinks=True):

712672"""Whether this path is a directory."""

673+ifself._entry:

674+try:

675+returnself._entry.is_dir(follow_symlinks=follow_symlinks)

676+exceptOSError:

677+returnFalse

713678iffollow_symlinks:

714679ifself._stat_resultis_STAT_RESULT_ERROR:

715680returnFalse

@@ -724,6 +689,11 @@ def is_dir(self, *, follow_symlinks=True):

724689725690defis_file(self, *, follow_symlinks=True):

726691"""Whether this path is a regular file."""

692+ifself._entry:

693+try:

694+returnself._entry.is_file(follow_symlinks=follow_symlinks)

695+exceptOSError:

696+returnFalse

727697iffollow_symlinks:

728698ifself._stat_resultis_STAT_RESULT_ERROR:

729699returnFalse

@@ -738,6 +708,11 @@ def is_file(self, *, follow_symlinks=True):

738708739709defis_symlink(self):

740710"""Whether this path is a symbolic link."""

711+ifself._entry:

712+try:

713+returnself._entry.is_symlink()

714+exceptOSError:

715+returnFalse

741716ifself._lstat_resultis_STAT_RESULT_ERROR:

742717returnFalse

743718try:

@@ -746,51 +721,40 @@ def is_symlink(self):

746721returnFalse

747722returnS_ISLNK(st.st_mode)

748723724+def_posix_permissions(self, *, follow_symlinks=True):

725+"""Return the POSIX file permissions."""

726+returnS_IMODE(self._stat(follow_symlinks=follow_symlinks).st_mode)

749727750-class_DirEntryInfo(_Info):

751-"""Implementation of pathlib.types.PathInfo that provides status

752- information by querying a wrapped os.DirEntry object. Don't try to

753- construct it yourself."""

754-__slots__= ('_entry',)

755-756-def__init__(self, entry):

757-super().__init__(entry.path)

758-self._entry=entry

759-760-def_stat(self, *, follow_symlinks=True):

761-"""Return the status as an os.stat_result."""

762-returnself._entry.stat(follow_symlinks=follow_symlinks)

728+def_file_id(self, *, follow_symlinks=True):

729+"""Returns the identifier of the file."""

730+st=self._stat(follow_symlinks=follow_symlinks)

731+returnst.st_dev, st.st_ino

763732764-defexists(self, *, follow_symlinks=True):

765-"""Whether this path exists."""

766-ifnotfollow_symlinks:

767-returnTrue

768-try:

769-self._stat(follow_symlinks=follow_symlinks)

770-exceptOSError:

771-returnFalse

772-returnTrue

733+def_access_time_ns(self, *, follow_symlinks=True):

734+"""Return the access time in nanoseconds."""

735+returnself._stat(follow_symlinks=follow_symlinks).st_atime_ns

773736774-defis_dir(self, *, follow_symlinks=True):

775-"""Whether this path is a directory."""

776-try:

777-returnself._entry.is_dir(follow_symlinks=follow_symlinks)

778-exceptOSError:

779-returnFalse

737+def_mod_time_ns(self, *, follow_symlinks=True):

738+"""Return the modify time in nanoseconds."""

739+returnself._stat(follow_symlinks=follow_symlinks).st_mtime_ns

780740781-defis_file(self, *, follow_symlinks=True):

782-"""Whether this path is a regular file."""

783-try:

784-returnself._entry.is_file(follow_symlinks=follow_symlinks)

785-exceptOSError:

786-returnFalse

741+ifhasattr(os.stat_result, 'st_flags'):

742+def_bsd_flags(self, *, follow_symlinks=True):

743+"""Return the flags."""

744+returnself._stat(follow_symlinks=follow_symlinks).st_flags

787745788-defis_symlink(self):

789-"""Whether this path is a symbolic link."""

790-try:

791-returnself._entry.is_symlink()

792-exceptOSError:

793-returnFalse

746+ifhasattr(os, 'listxattr'):

747+def_xattrs(self, *, follow_symlinks=True):

748+"""Return the xattrs as a list of (attr, value) pairs, or an empty

749+ list if extended attributes aren't supported."""

750+try:

751+return [

752+ (attr, os.getxattr(self._path, attr, follow_symlinks=follow_symlinks))

753+forattrinos.listxattr(self._path, follow_symlinks=follow_symlinks)]

754+exceptOSErroraserr:

755+iferr.errnonotin (EPERM, ENOTSUP, ENODATA, EINVAL, EACCES):

756+raise

757+return []

794758795759796760def_copy_info(info, target, follow_symlinks=True):

@@ -877,7 +841,7 @@ def info(self):

877841try:

878842returnself._info

879843exceptAttributeError:

880-self._info=_StatResultInfo(str(self))

844+self._info=_Info(str(self))

881845returnself._info

882846883847defstat(self, *, follow_symlinks=True):

@@ -1057,7 +1021,7 @@ def _filter_trailing_slash(self, paths):

10571021def_from_dir_entry(self, dir_entry, path_str):

10581022path=self.with_segments(path_str)

10591023path._str=path_str

1060-path._info=_DirEntryInfo(dir_entry)

1024+path._info=_Info(dir_entry.path, dir_entry)

10611025returnpath

1062102610631027defiterdir(self):