Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There is a problem with escape characters in the path passed in by pathlib.Path.mkdir() #91072

Closed
vincentfung mannequin opened this issue Mar 3, 2022 · 7 comments
Closed
Labels
3.10 only security fixes OS-windows type-bug An unexpected behavior, bug, or error

Comments

@vincentfung
Copy link
Mannequin

vincentfung mannequin commented Mar 3, 2022

BPO 46916
Nosy @pfmoore, @tjguk, @zware, @eryksun, @zooba

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2022-03-04.10:56:33.339>
created_at = <Date 2022-03-03.22:17:38.626>
labels = ['type-bug', 'invalid', '3.10', 'OS-windows']
title = 'There is a problem with escape characters in the path passed in by pathlib.Path.mkdir()'
updated_at = <Date 2022-03-04.13:21:07.701>
user = 'https://bugs.python.org/vincentfung'

bugs.python.org fields:

activity = <Date 2022-03-04.13:21:07.701>
actor = 'vincent.fung'
assignee = 'none'
closed = True
closed_date = <Date 2022-03-04.10:56:33.339>
closer = 'vincent.fung'
components = ['Windows']
creation = <Date 2022-03-03.22:17:38.626>
creator = 'vincent.fung'
dependencies = []
files = []
hgrepos = []
issue_num = 46916
keywords = []
message_count = 7.0
messages = ['414483', '414487', '414503', '414504', '414514', '414517', '414524']
nosy_count = 6.0
nosy_names = ['paul.moore', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower', 'vincent.fung']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue46916'
versions = ['Python 3.10']

@vincentfung
Copy link
Mannequin Author

vincentfung mannequin commented Mar 3, 2022

This problem occurs when the directory starts with 't', but works with os.makedirs(e) or macOS.

>>> e = Path(r'F:\ceven\test2')
>>> e.mkdir()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python310\lib\pathlib.py", line 1173, in mkdir
    self._accessor.mkdir(self, mode)
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'F:\\ceven\\test2'
>>> os.makedirs(e)

@vincentfung vincentfung mannequin added 3.10 only security fixes OS-windows type-bug An unexpected behavior, bug, or error labels Mar 3, 2022
@vincentfung
Copy link
Mannequin Author

vincentfung mannequin commented Mar 3, 2022

This problem occurs when the directory starts with 't', but works with os.makedirs(e) or macOS.

>>> e = Path(r'F:\ceven\test2')
>>> e.mkdir()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Program Files\Python310\lib\pathlib.py", line 1173, in mkdir
    self._accessor.mkdir(self, mode)
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'F:\\ceven\\test2'
>>> os.makedirs(e)

Another question about \t:

If a directory is passed as a parameter it will not be possible to use the parameter as a raw string. os.makedirs gives the same error whether it's r'%s' or repr().

@eryksun
Copy link
Contributor

eryksun commented Mar 4, 2022

FileNotFoundError: [WinError 3] The system cannot find
the path specified: 'F:\\ceven\\test2'

The Windows error code, ERROR_PATH_NOT_FOUND (3), indicates that the parent path, r"F:\ceven", does not exist. Try e.mkdir(parents=True) [1].

[1] https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir

@eryksun
Copy link
Contributor

eryksun commented Mar 4, 2022

e = Path(r'F:\ceven\test2')

Using forward slashes in the string literal is preferred, e.g. Path('F:/ceven/test2'). This avoids the problem of backslash escapes in string literals. The Path constructor parses the path and stores it internally as component parts. When the path object is needed as a string, os.fspath() returns the path using the platform's preferred path separator. A WindowsPath or PureWindowsPath uses backslash as the path separator. For example:

    >>> os.fspath(pathlib.PureWindowsPath('F:/ceven/test2'))
    'F:\\ceven\\test2'

@vincentfung
Copy link
Mannequin Author

vincentfung mannequin commented Mar 4, 2022

Oh. Got it.

I thought pathlib would solve this problem completely now, without having to replace the slashes. Thank you for your patient answer.

@vincentfung vincentfung mannequin closed this as completed Mar 4, 2022
@vincentfung vincentfung mannequin added the invalid label Mar 4, 2022
@vincentfung vincentfung mannequin closed this as completed Mar 4, 2022
@vincentfung vincentfung mannequin added the invalid label Mar 4, 2022
@eryksun
Copy link
Contributor

eryksun commented Mar 4, 2022

I thought pathlib would solve this problem completely now,
without having to replace the slashes.

pathlib has nothing to do with how the Python language compiles string literals. A string *literal* is Python source code that gets compiled and instantiated as a string object.

There is no technical problem with using r'F:\ceven\test2'. Using a raw string literal disables backslash escapes. But many developers find it inconvenient to have to use raw strings or to have to escape backslashes by doubling them. Plus raw string literals can't represent a path that ends with a backslash, such as C:\.

The Windows API supports forward slash as a path separator in many cases, but not always, and also not always for paths passed on the command line. So it's preferable to always normalize paths. pathlib takes care of this for you. You can initialize conveniently with forward slashes, but get a Windows path string that uses backslashes.

@vincentfung
Copy link
Mannequin Author

vincentfung mannequin commented Mar 4, 2022

Thank you very much for your patient answer, I am still a developer who has just started, and it seems that I need to learn more about it.

I used repr().replace to replace with forward slashes, and also restricted paths ending in a slash to Improve reliability.

Thanks anagin. ;)

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.10 only security fixes OS-windows type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant