diff --git a/.azure-pipelines/steps/create-virtualenv-linux.yml b/.azure-pipelines/steps/create-virtualenv-linux.yml index e5389376..519c5c5e 100644 --- a/.azure-pipelines/steps/create-virtualenv-linux.yml +++ b/.azure-pipelines/steps/create-virtualenv-linux.yml @@ -9,6 +9,8 @@ steps: echo "Path $PATH" echo "Installing Pipenv…" pipenv install --deploy --dev - pipenv run pip install -e "$(pwd)[test]" --upgrade + pipenv run pip install -e "$(pwd)[tests]" --upgrade echo pipenv --venv && echo pipenv --py && echo pipenv run python --version displayName: Make Virtualenv + env: + PYTHONWARNINGS: 'ignore:DEPRECATION' diff --git a/.azure-pipelines/steps/create-virtualenv-windows.yml b/.azure-pipelines/steps/create-virtualenv-windows.yml index 4dbdb685..35338205 100644 --- a/.azure-pipelines/steps/create-virtualenv-windows.yml +++ b/.azure-pipelines/steps/create-virtualenv-windows.yml @@ -1,31 +1,62 @@ steps: +- script: | + echo "##vso[task.setvariable variable=LANG]C.UTF-8" + echo "##vso[task.setvariable variable=PIP_PROCESS_DEPENDENCY_LINKS]1" + displayName: Set Environment Variables + - powershell: | - $env:PY_EXE=$(python -c "import sys; print(sys.executable)") - if (!$env:PY_EXE) { - $env:PY_EXE="python" - } - Write-Host "##vso[task.setvariable variable=PY_EXE]$env:PY_EXE" - Write-Host "Found Python: $env:PY_EXE" - Invoke-Expression "& '$env:PY_EXE' -m virtualenv D:\.venv" - Write-Host "##vso[task.setvariable variable=VIRTUAL_ENV]D:\.venv" - Invoke-Expression "& 'D:\.venv\Scripts\activate.ps1'" - $env:VIRTUAL_ENV="D:\.venv" - Write-Host "Installing local package..." - Invoke-Expression "& '$env:PY_EXE' -m pip install -e .[test] --upgrade" - Write-Host "upgrading local package in virtual env" - $venv_scripts = Join-Path -path D:\.venv -childpath Scripts - $venv_py = Join-Path -path $venv_scripts -childpath python.exe - Write-Host "##vso[task.setvariable variable=VIRTUAL_ENV_PY]$venv_py" - Invoke-Expression "& '$venv_py' -m pip install -e .[test] --upgrade" - Write-Host "Installing pipenv development packages" - Invoke-Expression "& '$venv_py' -m pipenv install --dev" - Write-Host "Installing local package in pipenv environment" - Invoke-Expression "& '$venv_py' -m pipenv run pip install -e .[test]" - Write-Host "Printing metadata" - Write-Host $(Invoke-Expression "& '$venv_py' -m pipenv --venv") - Write-Host $(Invoke-Expression "& '$venv_py' -m pipenv --py") - Write-Host $(Invoke-Expression "& '$venv_py' -m pipenv run python --version") - displayName: Make Virtualenv + pip install certifi + $env:PYTHON_PATH=$(python -c "import sys; print(sys.executable)") + $env:CERTIFI_CONTENT=$(python -m certifi) + echo "##vso[task.setvariable variable=GIT_SSL_CAINFO]$env:CERTIFI_CONTENT" + echo "##vso[task.setvariable variable=PY_EXE]$env:PYTHON_PATH" + displayName: Set Python Path env: - PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION) + PYTHONWARNINGS: 'ignore:DEPRECATION' + +- script: | + echo "Python path: $(PY_EXE)" + echo "GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)" + $(PY_EXE) -m pipenv install --deploy --dev + env: + PIPENV_DEFAULT_PYTHON_VERSION: '$(PIPENV_DEFAULT_PYTHON_VERSION)' + PYTHONWARNINGS: 'ignore:DEPRECATION' + PIPENV_NOSPIN: '1' + displayName: Make Virtualenv + +# steps: + +# - powershell: | +# $env:PY_EXE=$(python -c "import sys; print(sys.executable)") +# if (!$env:PY_EXE) { +# $env:PY_EXE="python" +# } +# Write-Host "##vso[task.setvariable variable=PY_EXE]$env:PY_EXE" +# Write-Host "Found Python: $env:PY_EXE" +# Invoke-Expression "& '$env:PY_EXE' -m virtualenv D:\.venv" +# Write-Host "##vso[task.setvariable variable=VIRTUAL_ENV]D:\.venv" +# Invoke-Expression "& 'D:\.venv\Scripts\activate.ps1'" +# $env:VIRTUAL_ENV="D:\.venv" +# Write-Host "Installing local package..." +# Invoke-Expression "& '$env:PY_EXE' -m pip install -e .[tests] requests --upgrade" +# Write-Host "upgrading local package in virtual env" +# $venv_scripts = Join-Path -path D:\.venv -childpath Scripts +# $venv_py = Join-Path -path $venv_scripts -childpath python.exe +# Write-Host "##vso[task.setvariable variable=VIRTUAL_ENV_PY]$venv_py" +# Invoke-Expression "& '$venv_py' -m pip install -e .[tests] requests --upgrade" 2>&1 +# Write-Host "Installing pipenv development packages" +# Invoke-Expression "& '$venv_py' -m pipenv install --dev" 2>&1 +# # Write-Host "Installing local package in pipenv environment" +# # Invoke-Expression "& '$venv_py' -m pipenv run pip install -e .[tests] requests" 2>&1 +# # Write-Host "Printing metadata" +# # Write-Host $(Invoke-Expression "& '$venv_py' -m pipenv --venv" 2>&1) +# # Write-Host $(Invoke-Expression "& '$venv_py' -m pipenv --py" 2>&1) +# # Write-Host $(Invoke-Expression "& '$venv_py' -m pipenv run python --version" 2>&1) +# displayName: Make Virtualenv +# failOnStderr: false +# env: +# PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION) +# PYTHONWARNINGS: 'ignore:DEPRECATION' +# PIPENV_VERBOSITY: '-1' +# PIPENV_NOSPIN: '1' diff --git a/.azure-pipelines/steps/create-virtualenv.yml b/.azure-pipelines/steps/create-virtualenv.yml new file mode 100644 index 00000000..48bb2233 --- /dev/null +++ b/.azure-pipelines/steps/create-virtualenv.yml @@ -0,0 +1,37 @@ +steps: + +- script: | + echo "##vso[task.setvariable variable=LANG]C.UTF-8" + echo "##vso[task.setvariable variable=PIP_PROCESS_DEPENDENCY_LINKS]1" + displayName: Set Environment Variables + +- ${{ if eq(parameters.vmImage, 'windows-2019') }}: + - powershell: | + pip install certifi + $env:PYTHON_PATH=$(python -c "import sys; print(sys.executable)") + $env:CERTIFI_CONTENT=$(python -m certifi) + echo "##vso[task.setvariable variable=GIT_SSL_CAINFO]$env:CERTIFI_CONTENT" + echo "##vso[task.setvariable variable=PY_EXE]$env:PYTHON_PATH" + displayName: Set Python Path + env: + PYTHONWARNINGS: 'ignore:DEPRECATION' +- ${{ if ne(parameters.vmImage, 'windows-2019') }}: + - bash: | + pip install certifi + PYTHON_PATH=$(python -c 'import sys; print(sys.executable)') + CERTIFI_CONTENT=$(python -m certifi) + echo "##vso[task.setvariable variable=GIT_SSL_CAINFO]$CERTIFI_CONTENT" + echo "##vso[task.setvariable variable=PY_EXE]$PYTHON_PATH" + displayName: Set Python Path + env: + PYTHONWARNINGS: 'ignore:DEPRECATION' + +- script: | + echo "Python path: $(PY_EXE)" + echo "GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)" + $(PY_EXE) -m pipenv install --deploy --dev + env: + PIPENV_DEFAULT_PYTHON_VERSION: '$(PIPENV_DEFAULT_PYTHON_VERSION)' + PYTHONWARNINGS: 'ignore:DEPRECATION' + PIPENV_NOSPIN: '1' + displayName: Make Virtualenv diff --git a/.azure-pipelines/steps/install-dependencies.yml b/.azure-pipelines/steps/install-dependencies.yml index 1537640a..16d2bd28 100644 --- a/.azure-pipelines/steps/install-dependencies.yml +++ b/.azure-pipelines/steps/install-dependencies.yml @@ -1,3 +1,5 @@ steps: - script: 'python -m pip install --upgrade pip setuptools wheel && python -m pip install -e .[tests] --upgrade' displayName: Upgrade Pip & Install Pipenv + env: + PYTHONWARNINGS: 'ignore:DEPRECATION' diff --git a/.azure-pipelines/steps/run-tests-linux.yml b/.azure-pipelines/steps/run-tests-linux.yml index c49be8b1..02ea8cf8 100644 --- a/.azure-pipelines/steps/run-tests-linux.yml +++ b/.azure-pipelines/steps/run-tests-linux.yml @@ -1,8 +1,14 @@ - script: | # Fix Git SSL errors - export GIT_SSL_CAINFO="$(python -m certifi)" - export LANG="C.UTF-8" - export PIP_PROCESS_DEPENDENCY_LINKS="1" git submodule sync && git submodule update --init --recursive pipenv run pytest --junitxml=test-results.xml displayName: Run integration tests + env: + PYTHONWARNINGS: 'ignore:DEPRECATION' + PY_EXE: $(PY_EXE) + GIT_SSL_CAINFO: $(GIT_SSL_CAINFO) + LANG: $(LANG) + PIP_PROCESS_DEPENDENCY_LINKS: $(PIP_PROCESS_DEPENDENCY_LINKS) + PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION) + PYTHONWARNINGS: ignore:DEPRECATION + PIPENV_NOSPIN: '1' diff --git a/.azure-pipelines/steps/run-tests-windows.yml b/.azure-pipelines/steps/run-tests-windows.yml index cc3aac27..7778f7c5 100644 --- a/.azure-pipelines/steps/run-tests-windows.yml +++ b/.azure-pipelines/steps/run-tests-windows.yml @@ -1,21 +1,39 @@ steps: - powershell: | - # Fix Git SSL errors - Invoke-Expression "& '$env:VIRTUAL_ENV_PY' -m pip install certifi" - Invoke-Expression "& '$env:VIRTUAL_ENV_PY' -m certifi > cacert.txt" - Write-Host "##vso[task.setvariable variable=GIT_SSL_CAINFO]$(Get-Content cacert.txt)" - $env:GIT_SSL_CAINFO="$(Get-Content cacert.txt)" - # Shorten paths to get under MAX_PATH or else integration tests will fail - # https://bugs.python.org/issue18199 subst T: "$env:TEMP" Write-Host "##vso[task.setvariable variable=TEMP]T:\" - $env:TEMP='T:\' Write-Host "##vso[task.setvariable variable=TMP]T:\" - $env:TMP='T:\' - git submodule sync - git submodule update --init --recursive - Invoke-Expression "& '$env:VIRTUAL_ENV_PY' -m pipenv run pytest -ra --ignore=pipenv\patched --ignore=pipenv\vendor --junitxml=test-results.xml tests" + displayName: Fix Temp Variable + +- script: | + git submodule sync && git submodule update --init --recursive + pipenv run pytest -ra --ignore=pipenv\patched --ignore=pipenv\vendor --junitxml=test-results.xml tests displayName: Run integration tests env: - VIRTUAL_ENV: $(VIRTUAL_ENV) - VIRTUAL_ENV_PY: $(VIRTUAL_ENV_PY) + PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION) + PYTHONWARNINGS: 'ignore:DEPRECATION' + PIPENV_NOSPIN: '1' + +# - powershell: | +# # Fix Git SSL errors +# Invoke-Expression "& '$env:VIRTUAL_ENV_PY' -m pip install certifi" +# Invoke-Expression "& '$env:VIRTUAL_ENV_PY' -m certifi > cacert.txt" +# Write-Host "##vso[task.setvariable variable=GIT_SSL_CAINFO]$(Get-Content cacert.txt)" +# $env:GIT_SSL_CAINFO="$(Get-Content cacert.txt)" +# # Shorten paths to get under MAX_PATH or else integration tests will fail +# # https://bugs.python.org/issue18199 +# subst T: "$env:TEMP" +# Write-Host "##vso[task.setvariable variable=TEMP]T:\" +# $env:TEMP='T:\' +# Write-Host "##vso[task.setvariable variable=TMP]T:\" +# $env:TMP='T:\' +# Invoke-Expression "git submodule sync -q" 2>&1 +# Invoke-Expression "git submodule update --init --recursive -q" 2>&1 +# Invoke-Expression "& '$env:VIRTUAL_ENV_PY' -m pipenv run pytest -ra --ignore=pipenv\patched --ignore=pipenv\vendor --junitxml=test-results.xml tests" +# displayName: Run integration tests +# failOnStderr: false +# env: +# VIRTUAL_ENV: $(VIRTUAL_ENV) +# VIRTUAL_ENV_PY: $(VIRTUAL_ENV_PY) +# PYTHONWARNINGS: 'ignore:DEPRECATION' +# PIPENV_VERBOSITY: '-1' diff --git a/.azure-pipelines/steps/run-tests.yml b/.azure-pipelines/steps/run-tests.yml index cee9b846..f559b8ca 100644 --- a/.azure-pipelines/steps/run-tests.yml +++ b/.azure-pipelines/steps/run-tests.yml @@ -1,22 +1,23 @@ steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: $(python.version) - architecture: '$(python.architecture)' - addToPath: true - displayName: Use Python $(python.version) +- task: UsePythonVersion@0 + inputs: + versionSpec: $(python.version) + architecture: '$(python.architecture)' + addToPath: true + displayName: Use Python $(python.version) + +- template: install-dependencies.yml - - template: install-dependencies.yml -steps: - script: | echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]$(PYTHON_VERSION)' env: PYTHON_VERSION: $(python.version) + +- template: create-virtualenv.yml + - ${{ if eq(parameters.vmImage, 'windows-2019') }}: - - template: create-virtualenv-windows.yml - template: run-tests-windows.yml - ${{ if ne(parameters.vmImage, 'windows-2019') }}: - - template: create-virtualenv-linux.yml - template: run-tests-linux.yml - task: PublishTestResults@2 diff --git a/Pipfile b/Pipfile index a5c1fee0..826df207 100644 --- a/Pipfile +++ b/Pipfile @@ -16,4 +16,3 @@ tests = "bash ./run-tests.sh" [pipenv] allow_prereleases = true - diff --git a/pipenv/__init__.py b/pipenv/__init__.py index a83f94e8..695a4939 100644 --- a/pipenv/__init__.py +++ b/pipenv/__init__.py @@ -36,11 +36,19 @@ try: except Exception: pass -from .vendor.vistir.misc import replace_with_text_stream -from .vendor import colorama -replace_with_text_stream("stdout") -replace_with_text_stream("stderr") -# colorama.init(wrap=False) +from pipenv.vendor.vistir.misc import get_text_stream +stdout = get_text_stream("stdout") +stderr = get_text_stream("stderr") + +if os.name == "nt": + from pipenv.vendor.vistir.misc import _can_use_color, _wrap_for_color + if _can_use_color(stdout): + stdout = _wrap_for_color(stdout) + if _can_use_color(stderr): + stderr = _wrap_for_color(stderr) + +sys.stdout = stdout +sys.stderr = stderr from .cli import cli from . import resolver diff --git a/pipenv/core.py b/pipenv/core.py index dd73c711..65541857 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -917,12 +917,12 @@ def do_create_virtualenv(python=None, site_packages=False, pypi_mirror=None): pip_config = {} # Actually create the virtualenv. - with create_spinner("Creating virtual environment...") as sp: + with create_spinner(u"Creating virtual environment...") as sp: c = vistir.misc.run( cmd, verbose=False, return_object=True, write_to_stdout=False, combine_stderr=False, block=True, nospin=True, env=pip_config, ) - click.echo(crayons.blue("{0}".format(c.out)), err=True) + click.echo(crayons.blue(u"{0}".format(c.out)), err=True) if c.returncode != 0: sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(u"Failed creating virtual environment")) error = c.err if environments.is_verbose() else exceptions.prettify_exc(c.err) diff --git a/pipenv/environments.py b/pipenv/environments.py index 1408c99c..34aef2bc 100644 --- a/pipenv/environments.py +++ b/pipenv/environments.py @@ -3,10 +3,12 @@ import os import sys +from io import UnsupportedOperation + from appdirs import user_cache_dir from ._compat import fix_utf8 -from .vendor.vistir.misc import fs_str +from .vendor.vistir.misc import _isatty, fs_str # HACK: avoid resolver.py uses the wrong byte code files. @@ -263,7 +265,10 @@ PIPENV_SHELL = ( ) # Internal, to tell whether the command line session is interactive. -SESSION_IS_INTERACTIVE = bool(os.isatty(sys.stdout.fileno())) +try: + SESSION_IS_INTERACTIVE = _isatty(sys.stdout.fileno()) +except UnsupportedOperation: + SESSION_IS_INTERACTIVE = _isatty(sys.stdout) # Internal, consolidated verbosity representation as an integer. The default diff --git a/pipenv/vendor/requests/__init__.py b/pipenv/vendor/requests/__init__.py index bc168ee5..9a899df6 100644 --- a/pipenv/vendor/requests/__init__.py +++ b/pipenv/vendor/requests/__init__.py @@ -57,10 +57,10 @@ def check_compatibility(urllib3_version, chardet_version): # Check urllib3 for compatibility. major, minor, patch = urllib3_version # noqa: F811 major, minor, patch = int(major), int(minor), int(patch) - # urllib3 >= 1.21.1, <= 1.24 + # urllib3 >= 1.21.1, <= 1.25 assert major == 1 assert minor >= 21 - assert minor <= 24 + assert minor <= 25 # Check chardet for compatibility. major, minor, patch = chardet_version.split('.')[:3] diff --git a/pipenv/vendor/requests/__version__.py b/pipenv/vendor/requests/__version__.py index f5b5d036..9844f740 100644 --- a/pipenv/vendor/requests/__version__.py +++ b/pipenv/vendor/requests/__version__.py @@ -5,10 +5,10 @@ __title__ = 'requests' __description__ = 'Python HTTP for Humans.' __url__ = 'http://python-requests.org' -__version__ = '2.21.0' -__build__ = 0x022100 +__version__ = '2.22.0' +__build__ = 0x022200 __author__ = 'Kenneth Reitz' __author_email__ = 'me@kennethreitz.org' __license__ = 'Apache 2.0' -__copyright__ = 'Copyright 2018 Kenneth Reitz' +__copyright__ = 'Copyright 2019 Kenneth Reitz' __cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/pipenv/vendor/requests/api.py b/pipenv/vendor/requests/api.py index abada96d..ef71d075 100644 --- a/pipenv/vendor/requests/api.py +++ b/pipenv/vendor/requests/api.py @@ -19,7 +19,7 @@ def request(method, url, **kwargs): :param method: method for the new :class:`Request` object. :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary, list of tuples or bytes to send - in the body of the :class:`Request`. + in the query string for the :class:`Request`. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. @@ -65,7 +65,7 @@ def get(url, params=None, **kwargs): :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary, list of tuples or bytes to send - in the body of the :class:`Request`. + in the query string for the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :return: :class:`Response ` object :rtype: requests.Response diff --git a/pipenv/vendor/requirementslib/__init__.py b/pipenv/vendor/requirementslib/__init__.py index a728058a..7f039c07 100644 --- a/pipenv/vendor/requirementslib/__init__.py +++ b/pipenv/vendor/requirementslib/__init__.py @@ -10,7 +10,7 @@ from .models.lockfile import Lockfile from .models.pipfile import Pipfile from .models.requirements import Requirement -__version__ = "1.5.0" +__version__ = "1.5.1" logger = logging.getLogger(__name__) diff --git a/pipenv/vendor/vendor.txt b/pipenv/vendor/vendor.txt index c5ce4c3f..c1342aa9 100644 --- a/pipenv/vendor/vendor.txt +++ b/pipenv/vendor/vendor.txt @@ -22,7 +22,7 @@ pipreqs==0.4.9 docopt==0.6.2 yarg==0.1.9 pythonfinder==1.2.1 -requests==2.21.0 +requests==2.22.0 chardet==3.0.4 idna==2.8 urllib3==1.25.2 diff --git a/pipenv/vendor/vistir/__init__.py b/pipenv/vendor/vistir/__init__.py index 6ad35904..821ea29b 100644 --- a/pipenv/vendor/vistir/__init__.py +++ b/pipenv/vendor/vistir/__init__.py @@ -36,7 +36,7 @@ from .misc import ( from .path import create_tracked_tempdir, create_tracked_tempfile, mkdir_p, rmtree from .spin import create_spinner -__version__ = "0.4.1" +__version__ = "0.4.2" __all__ = [ diff --git a/pipenv/vendor/vistir/_winconsole.py b/pipenv/vendor/vistir/_winconsole.py index 22eea2cd..a29c22d8 100644 --- a/pipenv/vendor/vistir/_winconsole.py +++ b/pipenv/vendor/vistir/_winconsole.py @@ -39,31 +39,35 @@ # the entire interpreter but just work in our little world of # echo and prmopt. +import ctypes import io import os import sys -import zlib import time -import ctypes -import msvcrt +import zlib from ctypes import ( - byref, POINTER, - c_int, + WINFUNCTYPE, + Structure, + byref, c_char, c_char_p, - c_void_p, + c_int, c_ssize_t, c_ulong, + c_void_p, + create_unicode_buffer, py_object, - Structure, windll, - WINFUNCTYPE, ) -from ctypes.wintypes import LPWSTR, LPCWSTR +from ctypes.wintypes import LPCWSTR, LPWSTR from itertools import count + +import msvcrt from six import PY2, text_type -from .misc import StreamWrapper, run + +from .compat import IS_TYPE_CHECKING +from .misc import StreamWrapper, run, to_text try: from ctypes import pythonapi @@ -74,6 +78,10 @@ except ImportError: pythonapi = None +if IS_TYPE_CHECKING: + from typing import Text + + c_ssize_p = POINTER(c_ssize_t) kernel32 = windll.kernel32 @@ -155,6 +163,15 @@ else: PyBuffer_Release(byref(buf)) +def get_long_path(short_path): + # type: (Text, str) -> Text + BUFFER_SIZE = 500 + buffer = create_unicode_buffer(BUFFER_SIZE) + get_long_path_name = windll.kernel32.GetLongPathNameW + get_long_path_name(to_text(short_path), buffer, BUFFER_SIZE) + return buffer.value + + class _WindowsConsoleRawIOBase(io.RawIOBase): def __init__(self, handle): self.handle = handle @@ -232,6 +249,10 @@ class ConsoleStream(object): def name(self): return self.buffer.name + @property + def fileno(self): + return self.buffer.fileno + def write(self, x): if isinstance(x, text_type): return self._text_stream.write(x) diff --git a/pipenv/vendor/vistir/misc.py b/pipenv/vendor/vistir/misc.py index b2df8f97..8d58aad6 100644 --- a/pipenv/vendor/vistir/misc.py +++ b/pipenv/vendor/vistir/misc.py @@ -741,14 +741,16 @@ class StreamWrapper(io.TextIOWrapper): def write(self, x): # try to use backslash and surrogate escape strategies before failing - old_errors = getattr(self, "_errors", self.errors) self._errors = ( "backslashescape" if self.encoding != "mbcs" else "surrogateescape" ) try: return io.TextIOWrapper.write(self, to_text(x, errors=self._errors)) except UnicodeDecodeError: - self._errors = old_errors + if self._errors != "surrogateescape": + self._errors = "surrogateescape" + else: + self._errors = "replace" return io.TextIOWrapper.write(self, to_text(x, errors=self._errors)) def writelines(self, lines): @@ -841,6 +843,9 @@ if os.name == "nt" or sys.platform.startswith("win"): if colorama is not None: + def _is_wrapped_for_color(stream): + return isinstance(stream, (colorama.AnsiToWin32, colorama.ansitowin32.StreamWrapper)) + def _wrap_for_color(stream, color=None): try: cached = _color_stream_cache.get(stream) @@ -911,6 +916,8 @@ def get_text_stream(stream="stdout", encoding=None): sys_stream = stream_map[stream] windows_console = _get_windows_console_stream(sys_stream, encoding, None) if windows_console is not None: + if _can_use_color(windows_console): + return _wrap_for_color(windows_console) return windows_console return get_wrapped_stream(sys_stream, encoding) @@ -927,6 +934,11 @@ def get_text_stdin(): return get_text_stream("stdin") +_text_stdin = _cached_stream_lookup(lambda: sys.stdin, get_text_stdin) +_text_stdout = _cached_stream_lookup(lambda: sys.stdout, get_text_stdout) +_text_stderr = _cached_stream_lookup(lambda: sys.stderr, get_text_stderr) + + TEXT_STREAMS = { "stdin": get_text_stdin, "stdout": get_text_stdout, @@ -934,11 +946,6 @@ TEXT_STREAMS = { } -_text_stdin = _cached_stream_lookup(lambda: sys.stdin, get_text_stdin) -_text_stdout = _cached_stream_lookup(lambda: sys.stdout, get_text_stdout) -_text_stderr = _cached_stream_lookup(lambda: sys.stderr, get_text_stderr) - - def replace_with_text_stream(stream_name): """Given a stream name, replace the target stream with a text-converted equivalent @@ -1009,7 +1016,7 @@ def echo(text, fg=None, bg=None, style=None, file=None, err=False, color=None): text = colorize(text, fg=fg, bg=bg, attrs=style) if not can_use_color or (os.name == "nt" and not _wrap_for_color): text = ANSI_REMOVAL_RE.sub("", text) - elif os.name == "nt" and _wrap_for_color: + elif os.name == "nt" and _wrap_for_color and not _is_wrapped_for_color(file): file = _wrap_for_color(file, color=color) if text: file.write(text) diff --git a/pipenv/vendor/vistir/path.py b/pipenv/vendor/vistir/path.py index 76bdf786..d5b02f64 100644 --- a/pipenv/vendor/vistir/path.py +++ b/pipenv/vendor/vistir/path.py @@ -103,11 +103,13 @@ def normalize_path(path): :rtype: str """ - return os.path.normpath( - os.path.normcase( - os.path.abspath(os.path.expandvars(os.path.expanduser(str(path)))) - ) - ) + path = os.path.abspath(os.path.expandvars(os.path.expanduser(str(path)))) + if os.name == "nt" and os.path.exists(path): + from ._winconsole import get_long_path + + path = get_long_path(path) + + return os.path.normpath(os.path.normcase(path)) def is_in_path(path, parent): @@ -345,18 +347,18 @@ def set_write_bit(fn): from .misc import run if user_sid: - _, err = run( + c = run( [ icacls_exe, + "''{0}''".format(fn), "/grant", "{0}:WD".format(user_sid), - "''{0}''".format(fn), "/T", "/C", "/Q", - ] + ], nospin=True, return_object=True ) - if not err: + if not c.err and c.returncode == 0: return if not os.path.isdir(fn): diff --git a/tasks/vendoring/__init__.py b/tasks/vendoring/__init__.py index aa0a15df..edb64bc8 100644 --- a/tasks/vendoring/__init__.py +++ b/tasks/vendoring/__init__.py @@ -635,7 +635,7 @@ def license_destination(vendor_dir, libname, filename): return ( vendor_dir / override.parent ) / '{0}.{1}'.format(override.name, filename) - license_path = LIBRARY_DIRNAMES[libname] / filename + license_path = Path(LIBRARY_DIRNAMES[libname]) / filename if license_path.as_posix() in LICENSE_RENAMES: return vendor_dir / LICENSE_RENAMES[license_path.as_posix()] return vendor_dir / LIBRARY_DIRNAMES[libname] / filename diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 8848c052..8681f76d 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -12,6 +12,7 @@ from shutil import rmtree as _rmtree import pytest from vistir.compat import ResourceWarning, fs_str, fs_encode, FileNotFoundError, PermissionError, TemporaryDirectory +from vistir.misc import run from vistir.contextmanagers import temp_environ from vistir.path import mkdir_p, create_tracked_tempdir, handle_remove_readonly @@ -246,6 +247,7 @@ class _PipenvInstance(object): venv_root=None, ignore_virtualenvs=True, venv_in_project=True, name=None ): self.pypi = pypi + os.environ["PYTHONWARNINGS"] = "ignore:DEPRECATION" if ignore_virtualenvs: os.environ["PIPENV_IGNORE_VIRTUALENVS"] = fs_str("1") if venv_root: @@ -419,10 +421,17 @@ class VirtualEnv(object): os.environ = self._old_environ def create(self): - python = Path(sys.executable).as_posix() - cmd = "{0} -m virtualenv {1}".format(python, self.path.as_posix()) - c = delegator.run(cmd, block=True) - assert c.return_code == 0 + python = Path(sys.executable).absolute().as_posix() + cmd = [ + python, "-m", "virtualenv", self.path.absolute().as_posix() + ] + c = run( + cmd, verbose=False, return_object=True, write_to_stdout=False, + combine_stderr=False, block=True, nospin=True, + ) + # cmd = "{0} -m virtualenv {1}".format(python, self.path.as_posix()) + # c = delegator.run(cmd, block=True) + assert c.returncode == 0 def activate(self): script_path = "Scripts" if os.name == "nt" else "bin" @@ -432,7 +441,10 @@ class VirtualEnv(object): code = compile(f.read(), str(activate_this), "exec") exec(code, dict(__file__=str(activate_this))) os.environ["VIRTUAL_ENV"] = str(self.path) - return self.path + try: + return self.path.absolute().resolve() + except OSError: + return self.path.absolute() else: raise VirtualenvActivationException("Can't find the activate_this.py script.") diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py index f9c02ee9..4adf46ab 100644 --- a/tests/integration/test_project.py +++ b/tests/integration/test_project.py @@ -9,6 +9,7 @@ import pytest from pipenv.patched import pipfile from pipenv.project import Project from pipenv.utils import temp_environ +from pipenv.vendor.vistir.path import is_in_path import pipenv.environments @@ -184,7 +185,7 @@ def test_run_in_virtualenv_with_global_context(PipenvInstance, pypi, virtualenv) assert c.return_code == 0 c = p.pipenv('run python -c "import click;print(click.__file__)"') assert c.return_code == 0 - assert c.out.strip().startswith(str(virtualenv)) + assert is_in_path(c.out.strip(), str(virtualenv)) c = p.pipenv("clean --dry-run") assert c.return_code == 0 assert "click" in c.out