summaryrefslogtreecommitdiff
path: root/src/click/types.py
diff options
context:
space:
mode:
authorcAtaman <chimaataman@gmail.com>2021-07-15 04:15:49 +0100
committerDavid Lord <davidism@gmail.com>2021-08-05 08:25:00 -0700
commit986f322e435fac5e1fb8505d3683c8a224c18b06 (patch)
treef8cb477e4090006f00e2b4890577a43b114f6b96 /src/click/types.py
parent76cc18d1f0bd5854f14526e3ccbce631d8344cce (diff)
downloadclick-986f322e435fac5e1fb8505d3683c8a224c18b06.tar.gz
resolve relative symlinks to the containing directory
Diffstat (limited to 'src/click/types.py')
-rw-r--r--src/click/types.py17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/click/types.py b/src/click/types.py
index 21f0e4f..cd39469 100644
--- a/src/click/types.py
+++ b/src/click/types.py
@@ -836,11 +836,20 @@ class Path(ParamType):
if not is_dash:
if self.resolve_path:
- # realpath on Windows Python < 3.8 doesn't resolve symlinks
+ # Get the absolute directory containing the path.
+ dir_ = os.path.dirname(os.path.abspath(rv))
+
+ # Resolve a symlink. realpath on Windows Python < 3.9
+ # doesn't resolve symlinks. This might return a relative
+ # path even if the path to the link is absolute.
if os.path.islink(rv):
rv = os.readlink(rv)
- rv = os.path.realpath(rv)
+ # Join dir_ with the resolved symlink. If the resolved
+ # path is relative, this will make it relative to the
+ # original containing directory. If it is absolute, this
+ # has no effect.
+ rv = os.path.join(dir_, rv)
try:
st = os.stat(rv)
@@ -871,7 +880,7 @@ class Path(ParamType):
param,
ctx,
)
- if self.writable and not os.access(value, os.W_OK):
+ if self.writable and not os.access(rv, os.W_OK):
self.fail(
_("{name} {filename!r} is not writable.").format(
name=self.name.title(), filename=os.fsdecode(value)
@@ -879,7 +888,7 @@ class Path(ParamType):
param,
ctx,
)
- if self.readable and not os.access(value, os.R_OK):
+ if self.readable and not os.access(rv, os.R_OK):
self.fail(
_("{name} {filename!r} is not readable.").format(
name=self.name.title(), filename=os.fsdecode(value)