Skip to content

Conversation

@sethmlarson
Copy link
Contributor

@sethmlarson sethmlarson commented Feb 3, 2026

Follow-up from #144401, this PR moves to deprecate os.path.commonprefix() in favor of the correctly behaving os.path.commonpath() and the behavior-describing string.commonprefix().

I'm not sure if this is all I have to do to deprecate an API, if there is more documentation that needs to happen let me know.


📚 Documentation preview 📚: https://cpython-previews--144436.org.readthedocs.build/

Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need a What's New entry for that.

Comment on lines 61 to 62
import os
m = tuple(map(os.fspath, m))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really fond of this. string.commonprefix() should be specific to strings and should not care about pathlike objects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is only done for backwards compatibility. I would be happy to get rid of it, but I figured that this would be not allowed considering we're doing a "rename", not a new API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no backwards compatibility here. We create a new function in a module that is not related to filepaths at all. I do not consider this as a rename, I really consider this as a new API. Instead, I would keep the implementation of os.path.commonpath as is and add in a follow-up PR string.commonprefix which does not do the fspath computation. We then document that os.path.commonpath should be reimplemented as string.commonprefix(tuple(map(os.fspath, m))) if needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this new string.commonprefix() should be a direct, one-to-one, drop-in replacement for the old os.path.commonprefix().

We're not doing anyone favours by changing the behaviour and making them [have to decide whether they need to] jump through extra hoops.

Chances are they should be using os.path.commonpath() instead, but if not, let them just replace the module name and keep the same old behaviour.

I doubt there's significant performance improvement from changing it either.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me this isn't about performance, it's about semantics. string contains string-related utilities, not path-related ones. I am really opposed to having string.commonprefix being smart here. I know that we are not necessarily doing the user a favor but I don't want to have unrelated utilities in string. It is, for me, the wrong module for that.

Copy link
Member

@hugovk hugovk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also list in Doc/deprecations/pending-removal-in-future.rst.

https://docs.python.org/dev/deprecations/index.html#pending-removal-in-future-versions

Comment on lines 61 to 62
import os
m = tuple(map(os.fspath, m))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this new string.commonprefix() should be a direct, one-to-one, drop-in replacement for the old os.path.commonprefix().

We're not doing anyone favours by changing the behaviour and making them [have to decide whether they need to] jump through extra hoops.

Chances are they should be using os.path.commonpath() instead, but if not, let them just replace the module name and keep the same old behaviour.

I doubt there's significant performance improvement from changing it either.

sethmlarson and others added 2 commits February 3, 2026 12:28
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
@sethmlarson
Copy link
Contributor Author

Alright, most recent two commits should address all review comments. I have preserved backwards compatibility in the drop-in replacement string.commonprefix().

@sethmlarson sethmlarson requested review from hugovk and picnixz and removed request for picnixz February 3, 2026 18:33
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry, but I do not want string.commonprefix to be equivalent to os.path.commonprefix. Semantically it doesn't make sense to have an os-related utility in string.

In addition, we only talk about "strings" in the documentation. Having an implicit os.fspath conversion should be documented otherwise. If we want to mimic os.path.commonpath in the first place, I do not see why we can't just keep it but soft-deprecate it.

Note that commonprefix does not care about the fact that we are strings. It also works for any sequence, as long as the elements can be ordered (e.g., we can use commonprefix for list of lists):

>>> os.path.commonpath([[1], [1,3]])
[1]

Since we expose it in string, anyone using a non-string as the first argument will not be able to make it work (because we raise a TypeError in os.fspath). So I would expect a string-like object to be acceptable but because of os.fspath it wouldn't be. This would be contrary to what the string module stands for.

If we want a commonprefix utility, I would suggest adding one to itertools, and use the latter. I believe it makes more sense to have something related to commonprefix out there. Or for strings only, have it in difflib.

@bedevere-app
Copy link

bedevere-app bot commented Feb 3, 2026

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

And if you don't make the requested changes, you will be put in the comfy chair!

@sethmlarson
Copy link
Contributor Author

Because I want to prioritize warning users about this function, I am okay with not providing a string.commonprefix() function and simply raising a DeprecationWarning in this PR. I want to avoid this warning getting delayed further, as has happened for the past ~30 years since the confusing behavior has been reported.

sethmlarson and others added 2 commits February 3, 2026 21:56
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
@sethmlarson sethmlarson force-pushed the deprecate-os-path-commonprefix branch from d4c0bb4 to 166c39d Compare February 3, 2026 23:06
@sethmlarson
Copy link
Contributor Author

@picnixz @hugovk I have removed string.commonprefix in 166c39d, I will happily revert or change this if there is a suggestion that should be completed in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants