diff --git a/src/rez/config.py b/src/rez/config.py index 56b4ca3f2..f96c278bc 100644 --- a/src/rez/config.py +++ b/src/rez/config.py @@ -435,6 +435,7 @@ def _parse_env_var(self, value): "alias_back": OptionalStr, "package_preprocess_function": OptionalStrOrFunction, "package_preprocess_mode": PreprocessMode_, + "windows_unc_path": Bool, "error_on_missing_variant_requires": Bool, "context_tracking_host": OptionalStr, "variant_shortlinks_dirname": OptionalStr, diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index 0661978cb..8611dcfa4 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -15,7 +15,7 @@ from rez.utils.formatting import columnise, PackageRequest, ENV_VAR_REGEX, \ header_comment, minor_header_comment from rez.utils.data_utils import deep_del -from rez.utils.filesystem import TempDirs, is_subdirectory, canonical_path +from rez.utils.filesystem import TempDirs, is_subdirectory, canonical_path, real_path from rez.utils.memcached import pool_memcached_connections from rez.utils.logging_ import print_error, print_warning from rez.utils.which import which @@ -1816,8 +1816,8 @@ def _adjust_variant_for_bundling(cls, handle, out): if is_subdirectory(repo_path, bundle_path): vars_["location"] = os.path.relpath( - os.path.realpath(repo_path), - os.path.realpath(bundle_path) + real_path(repo_path), + real_path(bundle_path) ) # serializing in, make repo absolute diff --git a/src/rez/rezconfig.py b/src/rez/rezconfig.py index 1abd59f71..9d013305d 100644 --- a/src/rez/rezconfig.py +++ b/src/rez/rezconfig.py @@ -690,6 +690,11 @@ # - "override": Package's preprocess function completely overrides the global preprocess. package_preprocess_mode = "override" +# Define if we want to windows drive letters to be resolved to UNC paths in the context +# resolution. Before Python 3.8 drive letters were not resolved to drive +# letters. To keep the pre Python 3.8 behavior this should be set to False. +windows_unc_path = False + ############################################################################### # Context Tracking ############################################################################### diff --git a/src/rez/system.py b/src/rez/system.py index 8486a71af..008d63b24 100644 --- a/src/rez/system.py +++ b/src/rez/system.py @@ -8,6 +8,7 @@ import platform from rez import __version__ +from rez.utils.filesystem import real_path from rez.utils.platform_ import platform_ from rez.exceptions import RezSystemError from rez.utils.data_utils import cached_property @@ -237,7 +238,7 @@ def rez_bin_path(self): validation_file = os.path.join(binpath, ".rez_production_install") if os.path.exists(validation_file): - return os.path.realpath(binpath) + return real_path(binpath) return None diff --git a/src/rez/utils/filesystem.py b/src/rez/utils/filesystem.py index fcf0db4f9..c041d9806 100644 --- a/src/rez/utils/filesystem.py +++ b/src/rez/utils/filesystem.py @@ -340,8 +340,8 @@ def make_tmp_name(name): def is_subdirectory(path_a, path_b): """Returns True if `path_a` is a subdirectory of `path_b`.""" - path_a = os.path.realpath(path_a) - path_b = os.path.realpath(path_b) + path_a = real_path(path_a) + path_b = real_path(path_b) try: relative = os.path.relpath(path_a, path_b) except ValueError: @@ -519,7 +519,7 @@ def canonical_path(path, platform=None): if platform is None: platform = platform_ - path = os.path.normpath(os.path.realpath(path)) + path = os.path.normpath(real_path(path)) if not platform.has_case_sensitive_filesystem: return path.lower() @@ -744,3 +744,15 @@ def rename(src, dst): raise OSError("Rename {} to {} failed.".format(src, dst)) else: raise err + + +def real_path(path): + """Determine the real path resolving symbolic links and relative paths. + + Backwards compatibility with python-3.7 behavior of os.path.realpath on windows.""" + + from rez.config import config # Avoid circular imports + + if is_windows and not config.windows_unc_path: + return os.path.abspath(path) + return os.path.realpath(path)