Skip to content

Commit

Permalink
Fix readlink problem with PyPy
Browse files Browse the repository at this point in the history
  • Loading branch information
Erotemic committed Jun 9, 2024
1 parent 7f70605 commit 071a6e0
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
11 changes: 10 additions & 1 deletion ubelt/_win32_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,13 @@ def _win32_is_junction(path):
"""
Determines if a path is a win32 junction
Note:
on PyPy this is bugged and will currently return True for a symlinked
directory.
Returns:
bool:
Example:
>>> # xdoctest: +REQUIRES(WIN32)
>>> from ubelt._win32_links import _win32_junction, _win32_is_junction
Expand Down Expand Up @@ -396,12 +403,14 @@ def _is_reparse_point(path):
"""
Check if a directory is a reparse point in windows.
Note: a reparse point seems like it could be a junction or symlink.
.. [SO54678399] https://stackoverflow.com/a/54678399/887074
"""
if jwfs is None:
raise ImportError('jaraco.windows.filesystem is required to run _is_reparse_point')
# if jwfs is not None:
return jwfs.is_reparse_point(path)
return jwfs.is_reparse_point(os.fspath(path))
# else:
# # Fallback without jaraco: TODO: test this is 1-to-1
# # Seems to break on pypy?
Expand Down
12 changes: 11 additions & 1 deletion ubelt/util_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ def _readlink(link):

if _win32_links: # nocover
if _win32_links._win32_is_junction(link):
import platform
if platform.python_implementation() == 'PyPy':
# On PyPy this test can have a false positive
# for what should be a regular link.
path = os.readlink(link)
junction_prefix = '\\\\?\\'
if path.startswith(junction_prefix):
path = path[len(junction_prefix):]
return path
return _win32_links._win32_read_junction(link)
try:
path = os.readlink(link)
Expand Down Expand Up @@ -338,7 +347,8 @@ def _dirstats(dpath=None): # nocover
raise AssertionError(str(ELFDJ) + str(path))
line = '{E:d} {L:d} {F:d} {D:d} {J:d} - {path}'.format(**locals())
if os.path.islink(full_path):
line += ' -> ' + os.readlink(full_path)
# line += ' -> ' + os.readlink(full_path)
line += ' -> ' + _readlink(full_path)
elif _win32_links is not None:
if _win32_links._win32_is_junction(full_path):
resolved = _win32_links._win32_read_junction(full_path)
Expand Down
18 changes: 18 additions & 0 deletions ubelt/util_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,24 @@ def chmod(self, mode, follow_symlinks=True):
# """
# return self.chmod(mode, follow_symlinks=False)

# TODO:
# chainable symlink_to that returns the new link
# chainable hardlink_to that returns the new link
# probably can just uncomment when ready for a new feature
# def symlink_to(self, target, target_is_directory=False):
# """
# Make this path a symlink pointing to the target path.
# """
# super().symlink_to(target, target_is_directory=target_is_directory)
# return self

# def hardlink_to(self, target):
# """
# Make this path a hard link pointing to the same file as *target*.
# """
# super().hardlink_to(target)
# return self

def touch(self, mode=0o0666, exist_ok=True):
"""
Create this file with the given access mode, if it doesn't exist.
Expand Down

0 comments on commit 071a6e0

Please sign in to comment.