diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/click/core.py | 13 | ||||
-rw-r--r-- | src/click/decorators.py | 5 | ||||
-rw-r--r-- | src/click/types.py | 17 |
3 files changed, 16 insertions, 19 deletions
diff --git a/src/click/core.py b/src/click/core.py index 8ca050c..6b08cb2 100644 --- a/src/click/core.py +++ b/src/click/core.py @@ -46,17 +46,6 @@ F = t.TypeVar("F", bound=t.Callable[..., t.Any]) V = t.TypeVar("V") -def _fast_exit(code: int) -> "te.NoReturn": - """Low-level exit that skips Python's cleanup but speeds up exit by - about 10ms for things like shell completion. - - :param code: Exit code. - """ - sys.stdout.flush() - sys.stderr.flush() - os._exit(code) - - def _complete_visible_commands( ctx: "Context", incomplete: str ) -> t.Iterator[t.Tuple[str, "Command"]]: @@ -1130,7 +1119,7 @@ class BaseCommand: from .shell_completion import shell_complete rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) - _fast_exit(rv) + sys.exit(rv) def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: """Alias for :meth:`main`.""" diff --git a/src/click/decorators.py b/src/click/decorators.py index 5940e69..fa8c6f7 100644 --- a/src/click/decorators.py +++ b/src/click/decorators.py @@ -340,9 +340,8 @@ def version_option( if version is None and package_name is None: frame = inspect.currentframe() - assert frame is not None - assert frame.f_back is not None - f_globals = frame.f_back.f_globals if frame is not None else None + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None # break reference cycle # https://docs.python.org/3/library/inspect.html#the-interpreter-stack del frame 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) |