Issue31202
Created on 2017-08-14 13:57 by brice.gros, last changed 2020-10-17 00:11 by steve.dower. This issue is now closed.
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 3087 | closed | brice.gros, 2017-08-14 13:57 | |
| PR 16860 | merged | serhiy.storchaka, 2019-10-20 09:06 | |
| PR 16874 | merged | miss-islington, 2019-10-21 17:37 | |
| PR 16875 | merged | miss-islington, 2019-10-21 17:57 | |
| Messages (8) | |||
|---|---|---|---|
| msg300245 - (view) | Author: Brice Gros (brice.gros) * | Date: 2017-08-14 13:57 | |
Windows pathlib.Path.glob(pattern) fixed part of the pattern to lowercase whereas it should be unchanged. Note that this issue is different from http://bugs.python.org/issue26655 : "pathlib glob case sensitivity issue on Windows" where it was asked to get the actual case of the folder from the file system. Assuming a directory contains a folder named 'Folder'. On Windows, calling pathlib.Path().glob('Folder') gives 'folder', but 'Folde?' will return 'Folder' This is an issue for instance if trying to glob files to put them in an archive to be sent to a case sensitive platform. glob.glob() does behave properly though, Windows pathlib.Path is the only platform which has such a behavior. I would expect Path.glob to output the same as glob.glob() for each platform. From comments on http://bugs.python.org/issue19718 : "Path.glob() on case-insensitive Posix filesystems" it sounds that it should even match the native shell behavior. And it looks like it is the case for linux and macOS, I tested that with the following script, whose results on win32, darwin and linux platforms follow: ``` #!/usr/bin/env python3.6 # Let's say this path exists : ./Folder/file from pathlib import Path import glob import os import sys import subprocess def ls(pattern): if sys.platform in ('win32', 'win64'): process = subprocess.run(['powershell', '-Command', f'dir {pattern}'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=os.getcwd(), encoding='utf-8') if process.returncode: return [] # expected output: # # # Directory: C:\path_to\Folder # # # Mode LastWriteTime Length Name # ---- ------------- ------ ---- # -a---- 2017-08-14 10:16 0 file lines = process.stdout.splitlines() folder = os.path.basename(lines[2].split()[-1]) file = lines[7].split()[-1] result = f"{folder}{os.path.sep}{file}" return [result] else: cmd = ['ls', f'{pattern}'] process = subprocess.run(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=os.getcwd(), encoding='utf-8', shell=True) if process.returncode: return [] return [process.stdout.strip()] def main(): print(sys.platform) p = Path('.') tests = ['Folder/*', 'FOlder/*', 'F?lder/*', 'FOlde?/*', 'folder/*', 'f?lder/*'] for t in tests: print(f'{t}:') print(f' Path.glob(): {[str(f) for f in p.glob(t)]}') print(f' glob.glob(): {[f for f in glob.glob(str(p/t))]}') print(f' shell: {ls(str(p/t))}') if __name__ == '__main__': main() ``` ``` Output: win32 darwin linux 1: Folder/*: Folder/*: Folder/*: 1a: Path.glob(): ['folder\\file'] Path.glob(): ['Folder/file'] Path.glob(): ['Folder/file'] 1b: glob.glob(): ['Folder\\file'] glob.glob(): ['Folder/file'] glob.glob(): ['Folder/file'] 1c: shell: ['Folder\\file'] shell: ['Folder/file'] shell: ['Folder/file'] 2: FOlder/*: FOlder/*: FOlder/*: 2a: Path.glob(): ['folder\\file'] Path.glob(): ['FOlder/file'] Path.glob(): [] 2b: glob.glob(): ['FOlder\\file'] glob.glob(): ['FOlder/file'] glob.glob(): [] 2c: shell: ['FOlder\\file'] shell: ['FOlder/file'] shell: [] 3: F?lder/*: F?lder/*: F?lder/*: 3a: Path.glob(): ['Folder\\file'] Path.glob(): ['Folder/file'] Path.glob(): ['Folder/file'] 3b: glob.glob(): ['Folder\\file'] glob.glob(): ['Folder/file'] glob.glob(): ['Folder/file'] 3c: shell: ['Folder\\file'] shell: ['Folder/file'] shell: ['Folder/file'] 4: FOlde?/*: FOlde?/*: FOlde?/*: 4a: Path.glob(): ['Folder\\file'] Path.glob(): [] Path.glob(): [] 4b: glob.glob(): ['Folder\\file'] glob.glob(): [] glob.glob(): [] 4c: shell: ['Folder\\file'] shell: [] shell: [] 5: folder/*: folder/*: folder/*: 5a: Path.glob(): ['folder\\file'] Path.glob(): ['folder/file'] Path.glob(): [] 5b: glob.glob(): ['folder\\file'] glob.glob(): ['folder/file'] glob.glob(): [] 5c: shell: ['folder\\file'] shell: ['folder/file'] shell: [] 6: f?lder/*: f?lder/*: f?lder/*: 6a: Path.glob(): ['Folder\\file'] Path.glob(): [] Path.glob(): [] 6b: glob.glob(): ['Folder\\file'] glob.glob(): [] glob.glob(): [] 6c: shell: ['Folder\\file'] shell: [] shell: [] ``` |
|||
| msg354976 - (view) | Author: Steve Dower (steve.dower) * | Date: 2019-10-19 21:33 | |
Bumping this - it's bitten me a couple of times as one of the build/release scripts relies on Path.glob(). |
|||
| msg355087 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * | Date: 2019-10-21 17:37 | |
New changeset 10ecbadb799ddf3393d1fc80119a3db14724d381 by Serhiy Storchaka in branch 'master': bpo-31202: Preserve case of literal parts in Path.glob() on Windows. (GH-16860) https://github.com/python/cpython/commit/10ecbadb799ddf3393d1fc80119a3db14724d381 |
|||
| msg355093 - (view) | Author: miss-islington (miss-islington) | Date: 2019-10-21 18:12 | |
New changeset 175abccbbfccb2f6489dc5c73f4630c1b25ce504 by Miss Skeleton (bot) in branch '3.7': bpo-31202: Preserve case of literal parts in Path.glob() on Windows. (GH-16860) https://github.com/python/cpython/commit/175abccbbfccb2f6489dc5c73f4630c1b25ce504 |
|||
| msg355095 - (view) | Author: miss-islington (miss-islington) | Date: 2019-10-21 18:18 | |
New changeset 2f8d4f08e2fa62cd5c3f6f824be3e7513ff87e07 by Miss Skeleton (bot) in branch '3.8': bpo-31202: Preserve case of literal parts in Path.glob() on Windows. (GH-16860) https://github.com/python/cpython/commit/2f8d4f08e2fa62cd5c3f6f824be3e7513ff87e07 |
|||
| msg378786 - (view) | Author: Irit Katriel (iritkatriel) * | Date: 2020-10-16 23:11 | |
Can this be closed? |
|||
| msg378792 - (view) | Author: Brice Gros (brice.gros) * | Date: 2020-10-16 23:49 | |
I think so, the original PR has been ported to 3.9, 3.8, 3.7, and all the PRs were merged. |
|||
| msg378794 - (view) | Author: Steve Dower (steve.dower) * | Date: 2020-10-17 00:11 | |
Yeah, looks done. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2020-10-17 00:11:35 | steve.dower | set | status: open -> closed resolution: fixed messages: + msg378794 stage: patch review -> resolved |
| 2020-10-16 23:49:17 | brice.gros | set | messages: + msg378792 |
| 2020-10-16 23:11:52 | iritkatriel | set | nosy:
+ iritkatriel messages: + msg378786 |
| 2019-10-21 18:18:05 | miss-islington | set | messages: + msg355095 |
| 2019-10-21 18:12:20 | miss-islington | set | nosy:
+ miss-islington messages: + msg355093 |
| 2019-10-21 17:57:39 | miss-islington | set | pull_requests: + pull_request16420 |
| 2019-10-21 17:37:39 | miss-islington | set | pull_requests: + pull_request16419 |
| 2019-10-21 17:37:22 | serhiy.storchaka | set | messages: + msg355087 |
| 2019-10-20 09:06:11 | serhiy.storchaka | set | keywords:
+ patch stage: patch review pull_requests: + pull_request16406 |
| 2019-10-20 06:49:47 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka |
| 2019-10-19 21:33:44 | steve.dower | set | messages:
+ msg354976 versions: + Python 3.9, - Python 3.6 |
| 2018-06-07 03:50:26 | ned.deily | set | versions: + Python 3.8, - Python 3.4, Python 3.5 |
| 2017-08-14 13:57:32 | brice.gros | create | |