Skip to content

Commit

Permalink
Merge pull request #118 from jaraco/feature/is-symlink
Browse files Browse the repository at this point in the history
Implement is_symlink
  • Loading branch information
jaraco authored May 26, 2024
2 parents 051250e + dc5fe8f commit 3a22d72
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
1 change: 1 addition & 0 deletions newsfragments/117.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implement is_symlink.
27 changes: 17 additions & 10 deletions tests/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import contextlib
import pathlib
import pickle
import stat
import sys
import unittest
from .compat.overlay import zipfile
Expand All @@ -15,12 +16,17 @@
from ._test_params import parameterize, Invoked


def _make_link(info: zipfile.ZipInfo): # type: ignore[name-defined]
info.external_attr |= stat.S_IFLNK << 16


def build_alpharep_fixture():
"""
Create a zip file with this structure:
.
├── a.txt
├── n.txt (-> a.txt)
├── b
│ ├── c.txt
│ ├── d
Expand All @@ -41,6 +47,7 @@ def build_alpharep_fixture():
- multiple files in a directory (b/c, b/f)
- a directory containing only a directory (g/h)
- a directory with files of different extensions (j/klm)
- a symlink (n) pointing to (a)
"alpha" because it uses alphabet
"rep" because it's a representative example
Expand All @@ -55,6 +62,9 @@ def build_alpharep_fixture():
zf.writestr("j/k.bin", b"content of k")
zf.writestr("j/l.baz", b"content of l")
zf.writestr("j/m.bar", b"content of m")
zf.writestr("n.txt", b"a.txt")
_make_link(zf.infolist()[-1])

zf.filename = "alpharep.zip"
return zf

Expand Down Expand Up @@ -85,7 +95,7 @@ def zipfile_ondisk(self, alpharep):
def test_iterdir_and_types(self, alpharep):
root = zipfile.Path(alpharep)
assert root.is_dir()
a, b, g, j = root.iterdir()
a, k, b, g, j = root.iterdir()
assert a.is_file()
assert b.is_dir()
assert g.is_dir()
Expand All @@ -105,7 +115,7 @@ def test_is_file_missing(self, alpharep):
@pass_alpharep
def test_iterdir_on_file(self, alpharep):
root = zipfile.Path(alpharep)
a, b, g, j = root.iterdir()
a, k, b, g, j = root.iterdir()
with self.assertRaises(ValueError):
a.iterdir()

Expand All @@ -120,7 +130,7 @@ def test_subdir_is_dir(self, alpharep):
@pass_alpharep
def test_open(self, alpharep):
root = zipfile.Path(alpharep)
a, b, g, j = root.iterdir()
a, k, b, g, j = root.iterdir()
with a.open(encoding="utf-8") as strm:
data = strm.read()
self.assertEqual(data, "content of a")
Expand Down Expand Up @@ -224,7 +234,7 @@ def test_open_missing_directory(self, alpharep):
@pass_alpharep
def test_read(self, alpharep):
root = zipfile.Path(alpharep)
a, b, g, j = root.iterdir()
a, k, b, g, j = root.iterdir()
assert a.read_text(encoding="utf-8") == "content of a"
# Also check positional encoding arg (gh-101144).
assert a.read_text("utf-8") == "content of a"
Expand Down Expand Up @@ -290,7 +300,7 @@ def test_mutability(self, alpharep):
reflect that change.
"""
root = zipfile.Path(alpharep)
a, b, g, j = root.iterdir()
a, k, b, g, j = root.iterdir()
alpharep.writestr('foo.txt', 'foo')
alpharep.writestr('bar/baz.txt', 'baz')
assert any(child.name == 'foo.txt' for child in root.iterdir())
Expand Down Expand Up @@ -507,12 +517,9 @@ def test_eq_hash(self, alpharep):

@pass_alpharep
def test_is_symlink(self, alpharep):
"""
See python/cpython#82102 for symlink support beyond this object.
"""

root = zipfile.Path(alpharep)
assert not root.is_symlink()
assert not root.joinpath('a.txt').is_symlink()
assert root.joinpath('n.txt').is_symlink()

@pass_alpharep
def test_relative_to(self, alpharep):
Expand Down
7 changes: 5 additions & 2 deletions zipp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import contextlib
import pathlib
import re
import stat
import sys

from .compat.py310 import text_encoding
Expand Down Expand Up @@ -391,9 +392,11 @@ def match(self, path_pattern):

def is_symlink(self):
"""
Return whether this path is a symlink. Always false (python/cpython#82102).
Return whether this path is a symlink.
"""
return False
info = self.root.getinfo(self.at)
mode = info.external_attr >> 16
return stat.S_ISLNK(mode)

def glob(self, pattern):
if not pattern:
Expand Down

0 comments on commit 3a22d72

Please sign in to comment.