Skip to content

Commit cd245f5

Browse files
committed
path.local: fix == doesn't imply same hash on Windows for paths which differ only by case
1 parent 4da806b commit cd245f5

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

CHANGELOG

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
1.8.2 (TBD)
2+
===========
3+
4+
- On Windows, ``py.path.local``s which differ only in case now have the same
5+
Python hash value. Previously, such paths were considered equal but had
6+
different hashes, which is not allowed and breaks the assumptions made by
7+
dicts, sets and other users of hashes.
8+
19
1.8.1 (2019-12-27)
210
==================
311

py/_path/local.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,10 @@ def __init__(self, path=None, expanduser=False):
163163
self.strpath = abspath(path)
164164

165165
def __hash__(self):
166-
return hash(self.strpath)
166+
s = self.strpath
167+
if iswin32:
168+
s = s.lower()
169+
return hash(s)
167170

168171
def __eq__(self, other):
169172
s1 = fspath(self)

testing/path/test_local.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,17 @@ def test_tilde_expansion(self, monkeypatch, tmpdir):
164164
p = py.path.local("~", expanduser=True)
165165
assert p == os.path.expanduser("~")
166166

167+
@pytest.mark.skipif(
168+
not sys.platform.startswith("win32"), reason="case insensitive only on windows"
169+
)
170+
def test_eq_hash_are_case_insensitive_on_windows(self):
171+
a = py.path.local("/some/path")
172+
b = py.path.local("/some/PATH")
173+
assert a == b
174+
assert hash(a) == hash(b)
175+
assert a in {b}
176+
assert a in {b: 'b'}
177+
167178
def test_eq_with_strings(self, path1):
168179
path1 = path1.join('sampledir')
169180
path2 = str(path1)

0 commit comments

Comments
 (0)