diff -r d1c0bc1d0625 -r 37bad1be7660 Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py Tue Jun 14 12:39:18 2016 +0300 +++ b/Lib/test/test_zipfile.py Tue Jun 14 12:54:51 2016 +0200 @@ -1983,6 +1983,16 @@ if os.path.exists(TESTFN): unlink(TESTFN) +class TestWithSymlink(unittest.TestCase): + def setUp(self): + os.mkdir(TESTFN2) + + def test_extract(self): + with zipfile.ZipFile(findfile("ziplink.zip")) as zipf: + zipf.extractall(TESTFN2) + self.assertTrue(os.path.islink(os.path.join(TESTFN2, "link"))) + self.assertTrue(os.path.isfile(os.path.join(TESTFN2, "file"))) + class ZipInfoTests(unittest.TestCase): def test_from_file(self): diff -r d1c0bc1d0625 -r 37bad1be7660 Lib/test/ziplink.zip Binary file Lib/test/ziplink.zip has changed diff -r d1c0bc1d0625 -r 37bad1be7660 Lib/zipfile.py --- a/Lib/zipfile.py Tue Jun 14 12:39:18 2016 +0300 +++ b/Lib/zipfile.py Tue Jun 14 12:54:51 2016 +0200 @@ -1536,9 +1536,14 @@ os.mkdir(targetpath) return targetpath - with self.open(member, pwd=pwd) as source, \ - open(targetpath, "wb") as target: - shutil.copyfileobj(source, target) + if stat.S_ISLNK(member.external_attr >> 16) and \ + hasattr(os, "symlink"): # Symlink + link = self.open(member, pwd=pwd).read() + os.symlink(link, targetpath) + else: # Normal file + with self.open(member, pwd=pwd) as source, \ + open(targetpath, "wb") as target: + shutil.copyfileobj(source, target) return targetpath