Skip to content

Commit

Permalink
move resolver to venv, remove host markers from lockfile
Browse files Browse the repository at this point in the history
Signed-off-by: Kenneth Reitz <me@kennethreitz.org>
  • Loading branch information
kennethreitz committed Mar 2, 2018
1 parent dc75eb5 commit ecf7842
Show file tree
Hide file tree
Showing 85 changed files with 24,361 additions and 28 deletions.
42 changes: 16 additions & 26 deletions pipenv/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from glob import glob
import json as simplejson

import urllib3
import background
import click
import click_completion
Expand All @@ -27,11 +26,16 @@
import semver
from pipreqs import pipreqs
from blindspin import spinner
from urllib3.exceptions import InsecureRequestWarning
try:
import urllib3
from urllib3.exceptions import InsecureRequestWarning
except ImportError:
pass

from .project import Project
from .utils import (
convert_deps_from_pip, convert_deps_to_pip, is_required_version,
proper_case, pep423_name, split_file, merge_deps, resolve_deps, shellquote, is_vcs,
proper_case, pep423_name, split_file, merge_deps, venv_resolve_deps, shellquote, is_vcs,
python_version, find_windows_executable, is_file, prepare_pip_source_args,
temp_environ, is_valid_url, download_file, get_requirement, need_update_check,
touch_update_stamp, is_pinned, is_star
Expand Down Expand Up @@ -116,7 +120,8 @@ def which(command, location=None, allow_global=False):


# Disable warnings for Python 2.6.
urllib3.disable_warnings(InsecureRequestWarning)
if 'urllib3' in globals():
urllib3.disable_warnings(InsecureRequestWarning)

project = Project(which=which)

Expand Down Expand Up @@ -1069,17 +1074,14 @@ def do_lock(verbose=False, system=False, clear=False, pre=False, keep_outdated=F

# Resolve dev-package dependencies, with pip-tools.
deps = convert_deps_to_pip(dev_packages, project, r=False, include_index=True)
results = resolve_deps(

results = venv_resolve_deps(
deps,
sources=project.sources,
verbose=verbose,
python=python_version(which('python', allow_global=system)),
clear=clear,
which=which,
which_pip=which_pip,
verbose=verbose,
project=project,
clear=clear,
pre=pre,
allow_global=system
)

# Add develop dependencies to lockfile.
Expand Down Expand Up @@ -1133,16 +1135,13 @@ def do_lock(verbose=False, system=False, clear=False, pre=False, keep_outdated=F

# Resolve package dependencies, with pip-tools.
deps = convert_deps_to_pip(project.packages, project, r=False, include_index=True)
results = resolve_deps(
results = venv_resolve_deps(
deps,
sources=project.sources,
verbose=verbose,
python=python_version(which('python', allow_global=system)),
which=which,
which_pip=which_pip,
verbose=verbose,
project=project,
clear=clear,
pre=pre,
allow_global=system
)

# Add default dependencies to lockfile.
Expand Down Expand Up @@ -1194,15 +1193,6 @@ def do_lock(verbose=False, system=False, clear=False, pre=False, keep_outdated=F
lockfile['develop'][default_package] = lockfile['default'][default_package]

if write:
# Run the PEP 508 checker in the virtualenv, add it to the lockfile.
cmd = '"{0}" {1}'.format(which('python', allow_global=system), shellquote(pep508checker.__file__.rstrip('cdo')))
c = delegator.run(cmd)
try:
lockfile['_meta']['host-environment-markers'] = simplejson.loads(c.out)

This comment has been minimized.

Copy link
@javabrett

javabrett May 6, 2018

Contributor

This resolves #753.

except ValueError:
click.echo(crayons.red("An unexpected error occurred while accessing your virtualenv's python installation!"))
click.echo('Please run $ {0} to re-create your environment.'.format(crayons.red('pipenv --rm')))
sys.exit(1)

# Write out the lockfile.
with open(project.lockfile_location, 'w') as f:
Expand Down
52 changes: 52 additions & 0 deletions pipenv/resolver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Pipenv Resolveer.
Usage:
resolver.py <packages>... [--verbose] [--pre] [--clear]
resolver.py (-h | --help)
resolver.py --version
Options:
-h --help Show this screen.
--version Show version.
--clear Clear the cache.
--verbose Display debug information to stderr.
--pre Include pre-releases.
"""

import os
import sys
import json

for _dir in ('vendor', 'patched', '..'):
dirpath = os.path.sep.join([os.path.dirname(__file__), _dir])
sys.path.insert(0, dirpath)

import pipenv.project
import pipenv.core
from pipenv.utils import *

from docopt import docopt
args = docopt(__doc__)

is_verbose = args['--verbose']
do_pre = args['--pre']
do_clear = args['--clear']
packages = args['<packages>']

project = pipenv.core.project

os.environ['PIP_PYTHON_PATH'] = sys.executable

def which(*args, **kwargs):
return sys.executable

def resolve(packages, pre=do_pre, sources=project.sources, verbose=is_verbose, clear=do_clear):
return pipenv.utils.resolve_deps(packages, which, project=project, pre=pre, sources=sources, clear=clear, verbose=verbose)

if __name__ == '__main__':
results = resolve(packages)
print('XYZZY')
if results:
print(json.dumps(results))
else:
print(json.dumps([]))
28 changes: 26 additions & 2 deletions pipenv/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
try:
from pathlib import Path
except ImportError:
from pathlib2 import Path
try:
from pathlib2 import Path
except ImportError:
pass


from distutils.spawn import find_executable
from contextlib import contextmanager
Expand Down Expand Up @@ -333,7 +337,27 @@ class PipCommand(pip.basecommand.Command):
return resolved_tree, resolver


def resolve_deps(deps, which, which_pip, project, sources=None, verbose=False, python=False, clear=False, pre=False, allow_global=False):
def venv_resolve_deps(deps, which, project, pre=False, verbose=False, clear=False):
from . import resolver
import json

resolver = shellquote(resolver.__file__.rstrip('co'))
cmd = '{0} {1} {2} {3} {4}'.format(which('python'), resolver, " ".join(deps), '--pre' if pre else '', '--verbose' if verbose else '')

c = delegator.run(cmd, block=True)

try:
assert c.return_code == 0
except AssertionError:
return []

if verbose:
click.echo(c.out.split('XYZZY')[0], err=True)

return json.loads(c.out.split('XYZZY')[1].strip())


def resolve_deps(deps, which, project, sources=None, verbose=False, python=False, clear=False, pre=False, allow_global=False):
"""Given a list of dependencies, return a resolved list of dependencies,
using pip-tools -- and their hashes, using the warehouse API / pip.
"""
Expand Down
88 changes: 88 additions & 0 deletions pipenv/vendor/requests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-

# __
# /__) _ _ _ _ _/ _
# / ( (- (/ (/ (- _) / _)
# /

"""
Requests HTTP library
~~~~~~~~~~~~~~~~~~~~~
Requests is an HTTP library, written in Python, for human beings. Basic GET
usage:
>>> import requests
>>> r = requests.get('https://www.python.org')
>>> r.status_code
200
>>> 'Python is a programming language' in r.content
True
... or POST:
>>> payload = dict(key1='value1', key2='value2')
>>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
The other HTTP methods are supported - see `requests.api`. Full documentation
is at <http://python-requests.org>.
:copyright: (c) 2016 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more details.
"""

__title__ = 'requests'
__version__ = '2.11.1'
__build__ = 0x021101
__author__ = 'Kenneth Reitz'
__license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2016 Kenneth Reitz'

# Attempt to enable urllib3's SNI support, if possible
# Note: Patched by pip to prevent using the PyOpenSSL module. On Windows this
# prevents upgrading cryptography.
# try:
# from .packages.urllib3.contrib import pyopenssl
# pyopenssl.inject_into_urllib3()
# except ImportError:
# pass

import warnings

# urllib3's DependencyWarnings should be silenced.
from .packages.urllib3.exceptions import DependencyWarning
warnings.simplefilter('ignore', DependencyWarning)

from . import utils
from .models import Request, Response, PreparedRequest
from .api import request, get, head, post, patch, put, delete, options
from .sessions import session, Session
from .status_codes import codes
from .exceptions import (
RequestException, Timeout, URLRequired,
TooManyRedirects, HTTPError, ConnectionError,
FileModeWarning, ConnectTimeout, ReadTimeout
)

# Set default logging handler to avoid "No handler found" warnings.
import logging
try: # Python 2.7+
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass

logging.getLogger(__name__).addHandler(NullHandler())

# FileModeWarnings go off per the default.
warnings.simplefilter('default', FileModeWarning, append=True)
Loading

0 comments on commit ecf7842

Please sign in to comment.