-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Preserve original letter-casing for displaying #13205
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
Conversation
bb3f5ba to
c0c9596
Compare
|
Modified according to review feedbacks. Since that (Edited: synchronize the script content to latest version of this PR) from typing import NamedTuple
import os
def display_path(path: str) -> str:
"""Gives the display value for a given path, making it relative to cwd
if possible."""
rel = os.path.relpath(path)
if rel[:2] == "..":
return path
return os.path.join(".", rel)
class Case(NamedTuple):
input: str
expected: str
testCases = [
Case(
input=r"C:\Users\weida\Projects\pip\main.py",
expected=r".\main.py",
),
Case(
input=r"C:\Users\weida\Projects\pip\main.PY",
expected=r".\main.PY",
),
Case(
input=r"C:\Users\weida\Projects\PIP\main.py",
expected=r".\main.py",
),
Case(
input=r"C:\Users\WeiDa\Projects\ABC\main.PY",
expected=r"C:\Users\WeiDa\Projects\ABC\main.PY",
),
]
# modify this path if needed
assert os.getcwd() == r"C:\Users\weida\Projects\pip"
for idx, test in enumerate(testCases):
result = display_path(test.input)
if result == test.expected:
print(f"Test case {idx} passed.")
else:
print(f"Test case {idx} failed: got {result}, expected {test.expected}.") |
|
Is there a reason why we can't use cc @pfmoore given this primarily impacts Windows. |
No such reason. |
|
@uranusjr do you have any opinions on this? (As our other resident Windows expert... or at least more than me) |
|
Sorry, it looks like I missed the ping here. IMO, preserving case is a good thing to do, so I support the PR. |
src/pip/_internal/utils/misc.py
Outdated
| rel = os.path.relpath(path) | ||
| if rel[:2] == "..": | ||
| return path | ||
| return os.path.join(".", rel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the input path is on a different drive than the CWD? Wouldn’t relpath return an absolute path in that case? We should add a unit test covering that case if there isn’t one already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's something I didn't noticed.
A quick look from the official doc says that worse thing can happen, e.g. throws ValueError.
Thanks for the reminder. 👍
I will enhance this PR this weekend, and try to include a test for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about using pathlib:
try:
relpath = Path(path).relative_to(Path.cwd())
except ValueError:
# If the path isn't relative to the CWD, leave it alone
return path
return str(Path(".") / relpath)
Unlike os.path.relpath, the Path.relative_to method doesn't try to go up the directory tree, so there's no need for the ".." check if we use pathlib.
We should still have some good unit tests for this. If only to ensure that we have a clear specification of the expected results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestions.
PR modified according to the suggestions.
Please let me know if there is any concern. :D
|
Change to draft. More modification required. |
1f0ad14 to
c38ec03
Compare
Simplify input path as a relative path to current working directory, while preserving the original letter-casing at best effort.
c38ec03 to
845e981
Compare
pfmoore
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
|
@ichard26 do you have anything further to add before I merge this? |
ichard26
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No further comments from me. Thanks @wdhongtw for your patience!
|
Thanks @wdhongtw for your contribution! |
This change will preserve path in it's original letter-case during displaying.
Fixes #6823
Becauseos.getcwdandos.path.abspathboth honors original letter-case,we should not normalize case again when calculating the relative path.
(Edited) As suggested, we match input path with cwd in normalized-casing,
while returning the relative part in original-casing.
Original path is returned untouched if the match fails.
And this change actually fix the (harmless) bug in Windows that relative path is not shown correctly,
as a side effect.
Before:
After:
All the testcase in unit test still passed. (And it should, because it's just a cosmetic change.)
I tried to locate the first commit that use
os.path.normcase, but it turns out that it's already therewhen this project migrated from svn to git in 2018.
Maybe there are some good reason to normalize case for the path in the past, but it should be ok to remove it now. :D