Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-74453: Deprecate os.path.commonprefix#144436

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
sethmlarson wants to merge6 commits intopython:main
base:main
Choose a base branch
Loading
fromsethmlarson:deprecate-os-path-commonprefix
Open
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletionsDoc/deprecations/pending-removal-in-future.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,6 +78,9 @@ although there is currently no date scheduled for their removal.

* :mod:`os`: Calling :func:`os.register_at_fork` in a multi-threaded process.

* :mod:`os.path`: :func:`os.path.commonprefix` is deprecated, use
:func:`os.path.commonpath` for path prefixes.
Copy link
Member

Choose a reason for hiding this comment

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

It may be interesting to explain how commonprefix() is misleading and can lead to security issues.

Same remark for commonprefix() deprecation documentation below.


* :class:`!pydoc.ErrorDuringImport`: A tuple value for *exc_info* parameter is
deprecated, use an exception instance.

Expand Down
3 changes: 3 additions & 0 deletionsDoc/library/os.path.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -120,6 +120,9 @@ the :mod:`glob` module.)
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.

.. deprecated:: next
Deprecated in favor of :func:`os.path.commonpath` for path prefixes.


.. function:: dirname(path, /)

Expand Down
9 changes: 9 additions & 0 deletionsLib/genericpath.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,15 @@ def getctime(filename, /):
# Return the longest prefix of all list elements.
def commonprefix(m, /):
"Given a list of pathnames, returns the longest common leading component"
import warnings
warnings.warn('os.path.commonprefix() is deprecated. Use '
'os.path.commonpath() for longest path prefix.',
category=DeprecationWarning,
stacklevel=2)
return _commonprefix(m)

def _commonprefix(m, /):
"Internal implementation of commonprefix()"
if not m: return ''
# Some people pass in a list of pathname parts to operate in an OS-agnostic
# fashion; don't try to translate in that case as that's an abuse of the
Expand Down
2 changes: 1 addition & 1 deletionLib/posixpath.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -542,7 +542,7 @@ def relpath(path, start=None):
start_list = start_tail.split(sep) if start_tail else []
path_list = path_tail.split(sep) if path_tail else []
# Work out how much of the filepath is shared by start and path.
i = len(commonprefix([start_list, path_list]))
i = len(genericpath._commonprefix([start_list, path_list]))

rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
if not rel_list:
Expand Down
136 changes: 69 additions & 67 deletionsLib/test/test_genericpath.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,71 +34,72 @@ def test_no_argument(self):
.format(self.pathmodule.__name__, attr))

def test_commonprefix(self):
commonprefix = self.pathmodule.commonprefix
self.assertEqual(
commonprefix([]),
""
)
self.assertEqual(
commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
"/home/swen"
)
self.assertEqual(
commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
"/home/swen/"
)
self.assertEqual(
commonprefix(["/home/swen/spam", "/home/swen/spam"]),
"/home/swen/spam"
)
self.assertEqual(
commonprefix(["home:swenson:spam", "home:swen:spam"]),
"home:swen"
)
self.assertEqual(
commonprefix([":home:swen:spam", ":home:swen:eggs"]),
":home:swen:"
)
self.assertEqual(
commonprefix([":home:swen:spam", ":home:swen:spam"]),
":home:swen:spam"
)

self.assertEqual(
commonprefix([b"/home/swenson/spam", b"/home/swen/spam"]),
b"/home/swen"
)
self.assertEqual(
commonprefix([b"/home/swen/spam", b"/home/swen/eggs"]),
b"/home/swen/"
)
self.assertEqual(
commonprefix([b"/home/swen/spam", b"/home/swen/spam"]),
b"/home/swen/spam"
)
self.assertEqual(
commonprefix([b"home:swenson:spam", b"home:swen:spam"]),
b"home:swen"
)
self.assertEqual(
commonprefix([b":home:swen:spam", b":home:swen:eggs"]),
b":home:swen:"
)
self.assertEqual(
commonprefix([b":home:swen:spam", b":home:swen:spam"]),
b":home:swen:spam"
)

testlist = ['', 'abc', 'Xbcd', 'Xb', 'XY', 'abcd',
'aXc', 'abd', 'ab', 'aX', 'abcX']
for s1 in testlist:
for s2 in testlist:
p = commonprefix([s1, s2])
self.assertStartsWith(s1, p)
self.assertStartsWith(s2, p)
if s1 != s2:
n = len(p)
self.assertNotEqual(s1[n:n+1], s2[n:n+1])
with warnings_helper.check_warnings((".*commonpath().*", DeprecationWarning)):
commonprefix = self.pathmodule.commonprefix
Comment on lines 36 to +38
Copy link
Member

Choose a reason for hiding this comment

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

May I suggest that you have:

deftest_commonprefix(self):withwarnings_helper...:self.do_test_commonprefix()defdo_test_commonprefix(self):# the original test

That way, the diff will be smaller

self.assertEqual(
commonprefix([]),
""
)
self.assertEqual(
commonprefix(["/home/swenson/spam", "/home/swen/spam"]),
"/home/swen"
)
self.assertEqual(
commonprefix(["/home/swen/spam", "/home/swen/eggs"]),
"/home/swen/"
)
self.assertEqual(
commonprefix(["/home/swen/spam", "/home/swen/spam"]),
"/home/swen/spam"
)
self.assertEqual(
commonprefix(["home:swenson:spam", "home:swen:spam"]),
"home:swen"
)
self.assertEqual(
commonprefix([":home:swen:spam", ":home:swen:eggs"]),
":home:swen:"
)
self.assertEqual(
commonprefix([":home:swen:spam", ":home:swen:spam"]),
":home:swen:spam"
)

self.assertEqual(
commonprefix([b"/home/swenson/spam", b"/home/swen/spam"]),
b"/home/swen"
)
self.assertEqual(
commonprefix([b"/home/swen/spam", b"/home/swen/eggs"]),
b"/home/swen/"
)
self.assertEqual(
commonprefix([b"/home/swen/spam", b"/home/swen/spam"]),
b"/home/swen/spam"
)
self.assertEqual(
commonprefix([b"home:swenson:spam", b"home:swen:spam"]),
b"home:swen"
)
self.assertEqual(
commonprefix([b":home:swen:spam", b":home:swen:eggs"]),
b":home:swen:"
)
self.assertEqual(
commonprefix([b":home:swen:spam", b":home:swen:spam"]),
b":home:swen:spam"
)

testlist = ['', 'abc', 'Xbcd', 'Xb', 'XY', 'abcd',
'aXc', 'abd', 'ab', 'aX', 'abcX']
for s1 in testlist:
for s2 in testlist:
p = commonprefix([s1, s2])
self.assertStartsWith(s1, p)
self.assertStartsWith(s2, p)
if s1 != s2:
n = len(p)
self.assertNotEqual(s1[n:n+1], s2[n:n+1])

def test_getsize(self):
filename = os_helper.TESTFN
Expand DownExpand Up@@ -606,8 +607,9 @@ def test_path_isdir(self):
self.assertPathEqual(os.path.isdir)

def test_path_commonprefix(self):
self.assertEqual(os.path.commonprefix([self.file_path, self.file_name]),
self.file_name)
with warnings_helper.check_warnings((".*commonpath().*", DeprecationWarning)):
self.assertEqual(os.path.commonprefix([self.file_path, self.file_name]),
self.file_name)

def test_path_getsize(self):
self.assertPathEqual(os.path.getsize)
Expand Down
14 changes: 8 additions & 6 deletionsLib/test/test_ntpath.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,6 +10,7 @@
from ntpath import ALL_BUT_LAST, ALLOW_MISSING
from test import support
from test.support import os_helper
from test.support import warnings_helper
from test.support.os_helper import FakePath
from test import test_genericpath
from tempfile import TemporaryFile
Expand DownExpand Up@@ -298,12 +299,13 @@ def test_isabs(self):
tester('ntpath.isabs("\\\\.\\C:")', 1)

def test_commonprefix(self):
Copy link
Member

Choose a reason for hiding this comment

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

Ditto

tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
"/home/swen")
tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
"\\home\\swen\\")
tester('ntpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
"/home/swen/spam")
with warnings_helper.check_warnings((".*commonpath().*", DeprecationWarning)):
tester('ntpath.commonprefix(["/home/swenson/spam", "/home/swen/spam"])',
"/home/swen")
tester('ntpath.commonprefix(["\\home\\swen\\spam", "\\home\\swen\\eggs"])',
"\\home\\swen\\")
tester('ntpath.commonprefix(["/home/swen/spam", "/home/swen/spam"])',
"/home/swen/spam")

def test_join(self):
tester('ntpath.join("")', '')
Expand Down
15 changes: 13 additions & 2 deletionsLib/unittest/util.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
"""Various utility functions."""

fromcollectionsimportnamedtuple,Counter
fromos.pathimportcommonprefix

__unittest=True

Expand All@@ -21,13 +20,25 @@ def _shorten(s, prefixlen, suffixlen):
s='%s[%d chars]%s'% (s[:prefixlen],skip,s[len(s)-suffixlen:])
returns

def_commonprefix(m,/):
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
def_commonprefix(m,/):
def_commonprefix(m):

as it's private, no need to enforce the /

ifnotm:
return""
m=sorted(m)
prefix=m[0]
foriteminm[1:]:
foriinrange(len(prefix)):
ifitem[i]!=prefix[i]:
prefix=prefix[:i]
break
Comment on lines +26 to +32
Copy link
Member

Choose a reason for hiding this comment

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

Can we use the min/max + enumerate approach instead?

returnprefix

def_common_shorten_repr(*args):
args=tuple(map(safe_repr,args))
maxlen=max(map(len,args))
ifmaxlen<=_MAX_LENGTH:
returnargs

prefix=commonprefix(args)
prefix=_commonprefix(args)
prefixlen=len(prefix)

common_len=_MAX_LENGTH- \
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
Deprecate :func:`os.path.commonprefix` in favor of
:func:`os.path.commonpath` for path segment prefixes.
Loading

[8]ページ先頭

©2009-2026 Movatter.jp