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

os.path.isabs change in behavior in Python 3.13 on MS-Windows #125283

Closed
ikappaki opened this issue Oct 10, 2024 · 9 comments
Closed

os.path.isabs change in behavior in Python 3.13 on MS-Windows #125283

ikappaki opened this issue Oct 10, 2024 · 9 comments
Labels
3.13 bugs and security fixes OS-windows stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@ikappaki
Copy link

ikappaki commented Oct 10, 2024

Bug report

Bug description:

I'm not sure if this is a fix or a regression issue?

os.path.isabs use to return True when a windows path started with /.

In python 3.13

Python 3.13.0 (tags/v3.13.0:60403a5, Oct  7 2024, 09:38:07) [MSC v.1941 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os.path
>>> os.path.isabs("/c:")
False

In python 3.12

Python 3.12.7 (tags/v3.12.7:0b05ead, Oct  1 2024, 03:06:41) [MSC v.1941 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os.path
>>> os.path.isabs("/c:")
True

CPython versions tested on:

3.13

Operating systems tested on:

Windows

@ikappaki ikappaki added the type-bug An unexpected behavior, bug, or error label Oct 10, 2024
@ZeroIntensity ZeroIntensity added OS-windows stdlib Python modules in the Lib dir 3.13 bugs and security fixes labels Oct 11, 2024
@nineteendo
Copy link
Contributor

Works as intended: #113829, maybe a new function could be considered to check if a path is rooted?

@ikappaki
Copy link
Author

Works as intended: #113829, maybe a new function could be considered to check if a path is rooted?

This behavior changes how os.path.isabs interacts with urllib.parse.urlparse when dealing with absolute paths in Windows URIs. In Python 3.12, paths parsed from local file URIs (drive and network paths) were recognized as absolute, but in Python 3.13, they no longer are

import os.path
import pathlib
import urllib.parse

>>> urllib.parse.urlparse(pathlib.Path('c:\\xyz').as_uri())
ParseResult(scheme='file', netloc='', path='/c:/xyz', params='', query='', fragment='')
>>> urllib.parse.urlparse(pathlib.Path('\\\\machine\\xyz').as_uri())
ParseResult(scheme='file', netloc='machine', path='/xyz/', params='', query='', fragment='')

In Python 3.12, os.path.isabs would correctly identify these paths as absolute, including network paths:

>>> os.path.isabs(urllib.parse.urlparse(pathlib.Path('c:\\xyz').as_uri()).path)
True
>>> os.path.isabs(urllib.parse.urlparse(pathlib.Path('\\\\machine\\xyz').as_uri()).path)
True

but not any more in 3.13

>>> os.path.isabs(urllib.parse.urlparse(pathlib.Path('c:\\xyz').as_uri()).path)
False
>>> os.path.isabs(urllib.parse.urlparse(pathlib.Path('\\\\machine\\xyz').as_uri()).path)
False

It seems as if os.path.isabs was never intended to be used with ParseResult paths. I suppose a more appropriate solution would be to directly check if the path starts with '/', which would indicate that it's absolute.

@nineteendo
Copy link
Contributor

You can use pathlib.Path.from_uri() starting from 3.13:

>>> import pathlib
>>> pathlib.Path.from_uri(pathlib.Path('c:/xyz').as_uri())
WindowsPath('c:/xyz')
>>> pathlib.Path.from_uri(pathlib.Path('//server/drive/xyz').as_uri())
WindowsPath('//server/drive/xyz')

This doesn't roundtrip:

>>> import pathlib
>>> import urllib.parse
>>> pathlib.Path(urllib.parse.urlparse(pathlib.Path('c:/xyz').as_uri()).path)
WindowsPath('/c:/xyz')
>>> pathlib.Path(urllib.parse.urlparse(pathlib.Path('//server/drive/xyz').as_uri()).path)
WindowsPath('/drive/xyz')

Also, aren't uri's always absolute?

@marc-hb
Copy link

marc-hb commented Oct 11, 2024

Also, aren't uri's always absolute?

Relative URLs work perfectly fine.

EDIT: I meant in general in life, not related to Python.

@nineteendo
Copy link
Contributor

Well, at least pathlib doesn't allow creating them.

@barneygale
Copy link
Contributor

It seems as if os.path.isabs was never intended to be used with ParseResult paths. I suppose a more appropriate solution would be to directly check if the path starts with '/', which would indicate that it's absolute.

Checking whether it starts with a / makes most sense to me. Another option is posixpath.isabs().

@nineteendo
Copy link
Contributor

nineteendo commented Oct 11, 2024

Use p.scheme and p.netloc and p.path.startswith("/") to check if an uri is absolute, an absolute path doesn't change when joined with another path:

>>> import urllib.parse
>>> urllib.parse.urljoin("file://netloc/foo/", "bar")
'file://netloc/foo/bar'
>>> urllib.parse.urljoin("file://netloc/foo/", "/bar")
'file://netloc/bar'
>>> urllib.parse.urljoin("file://netloc/foo/", "//netloc2/bar")
'file://netloc2/bar'
>>> urllib.parse.urljoin("file://netloc/foo/", "file://netloc2/bar")
'file://netloc2/bar'

That's also why we changed the behaviour of os.path.isabs():

>>> import os.path
>>> os.path.join(r"c:\foo", "bar")
'c:\\foo\\bar'
>>> os.path.join(r"c:\foo", r"\bar")
'c:\\bar'
>>> os.path.join(r"c:\foo", r"d:\bar")
'd:\\bar'

@nineteendo
Copy link
Contributor

I think this can be closed.

@barneygale
Copy link
Contributor

Thanks @nineteendo! Closing.

@barneygale barneygale closed this as not planned Won't fix, can't repro, duplicate, stale Oct 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.13 bugs and security fixes OS-windows stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

5 participants