Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/4.3.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
kalefranz committed Jan 12, 2017
2 parents eb1f000 + 105140d commit f804f69
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 23 deletions.
6 changes: 1 addition & 5 deletions .travis.yml
Expand Up @@ -36,16 +36,12 @@ matrix:
- os: osx
env: PYTHON_VERSION=3.5
language: generic
- python: '3.5'
env: CONDA_BUILD=1.21.14
os: linux
language: python
- python: '3.5'
env: CONDA_BUILD=2.0.12
os: linux
language: python
- python: '3.5'
env: CONDA_BUILD=2.1.0
env: CONDA_BUILD=2.1.1
os: linux
language: python

Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,13 @@
* general support for all bourne- and c-based shells #3175


## 4.3.4 (unreleased)

### Non-User-Facing Changes
* make arch in IndexRecord a StringField instead of EnumField
* improve conda-build compatibility (#4266)


## 4.3.3 (2017-01-10)

### Improvements
Expand Down Expand Up @@ -201,6 +208,14 @@
* context-dependent setup.py files (#4057)


## 4.2.16 (unreleased)

### Bug Fixes
* do not replace \ with / in file:// URLs on Windows (#4269)
* include aliases for first command-line argument (#4279)
* fix for multi-line FTP status codes (#4276)


## 4.2.15 (2017-01-10)

### Improvements
Expand Down
6 changes: 3 additions & 3 deletions conda/cli/main.py
Expand Up @@ -130,9 +130,9 @@ def completer(prefix, **kwargs):
if i.startswith(prefix)]

# when using sys.argv, first argument is generally conda or __main__.py. Ignore it.
if (any(sname in args[0] for sname in ('conda', 'conda.exe',
'__main__.py', 'conda-script.py')) and
(args[1] in main_modules + find_commands() or args[1].startswith('-'))):
if (any(sname in args[0] for sname in ('conda', 'conda.exe', '__main__.py', 'conda-script.py'))
and (args[1] in list(sub_parsers.choices.keys()) + find_commands()
or args[1].startswith('-'))):
log.debug("Ignoring first argument (%s), as it is not a subcommand", args[0])
args = args[1:]

Expand Down
4 changes: 4 additions & 0 deletions conda/core/index.py
Expand Up @@ -496,3 +496,7 @@ def create_cache_dir():
except OSError:
pass
return cache_dir


def dist_str_in_index(index, dist_str):
return Dist(dist_str) in index
12 changes: 12 additions & 0 deletions conda/core/package_cache.py
Expand Up @@ -512,3 +512,15 @@ def rm_fetched(dist):
def download(url, dst_path, session=None, md5=None, urlstxt=False, retries=3):
from ..gateways.download import download as gateway_download
gateway_download(url, dst_path, md5)


class package_cache(object):

def __contains__(self, dist):
return dist in PackageCache.first_writable()

def keys(self):
return iter(PackageCache.first_writable())

def __delitem__(self, dist):
del PackageCache.first_writable()[dist]
7 changes: 5 additions & 2 deletions conda/exports.py
Expand Up @@ -7,6 +7,9 @@

log = getLogger(__name__)

from . import CondaError # NOQA
CondaError = CondaError

from . import compat, plan # NOQA
compat, plan = compat, plan

Expand All @@ -32,8 +35,8 @@
TmpDownload = TmpDownload
handle_proxy_407 = lambda x, y: warn("handle_proxy_407 is deprecated. "
"Now handled by CondaSession.")
from .core.index import fetch_index # NOQA
fetch_index = fetch_index
from .core.index import dist_str_in_index, fetch_index # NOQA
dist_str_in_index, fetch_index = dist_str_in_index, fetch_index
from .core.package_cache import download, rm_fetched # NOQA
download, rm_fetched = download, rm_fetched

Expand Down
39 changes: 38 additions & 1 deletion conda/gateways/adapters/ftp.py
Expand Up @@ -243,7 +243,7 @@ def build_response(request, data, code, encoding):
response.raw = data
response.url = request.url
response.request = request
response.status_code = int(code.split()[0])
response.status_code = get_status_code_from_code_response(code)

# Make sure to seek the file-like raw object back to the start.
response.raw.seek(0)
Expand Down Expand Up @@ -275,3 +275,40 @@ def parse_multipart_files(request):
buf.seek(0)

return buf


def get_status_code_from_code_response(code):
"""
The idea is to handle complicated code response (even multi lines).
We get the status code in two ways:
- extracting the code from the last valid line in the response
- getting it from the 3 first digits in the code
After a comparison between the two values,
we can safely set the code or raise a warning.
Examples:
- get_status_code_from_code_response('200 Welcome') == 200
- multi_line_code = '226-File successfully transferred\n226 0.000 seconds'
get_status_code_from_code_response(multi_line_code) == 226
- multi_line_with_code_conflicts = '200-File successfully transferred\n226 0.000 seconds'
get_status_code_from_code_response(multi_line_with_code_conflicts) == 226
For more detail see RFC 959, page 36, on multi-line responses:
https://www.ietf.org/rfc/rfc959.txt
"Thus the format for multi-line replies is that the first line
will begin with the exact required reply code, followed
immediately by a Hyphen, "-" (also known as Minus), followed by
text. The last line will begin with the same code, followed
immediately by Space <SP>, optionally some text, and the Telnet
end-of-line code."
"""
last_valid_line_from_code = [line for line in code.split('\n') if line][-1]
status_code_from_last_line = int(last_valid_line_from_code.split()[0])
status_code_from_first_digits = int(code[:3])
if status_code_from_last_line != status_code_from_first_digits:
log.warning(
'FTP response status code seems to be inconsistent.\n'
'Code received: %s, extracted: %s and %s',
code,
status_code_from_last_line,
status_code_from_first_digits
)
return status_code_from_last_line
5 changes: 3 additions & 2 deletions conda/gateways/download.py
Expand Up @@ -63,9 +63,10 @@ def download(url, target_full_path, md5sum):
resp = session.get(url, stream=True, proxies=session.proxies, timeout=timeout)
resp.raise_for_status()

content_length = int(resp.headers.get('Content-Length'))
content_length = int(resp.headers.get('Content-Length', 0))

getLogger('fetch.start').info((basename(target_full_path)[:14], content_length))
if content_length:
getLogger('fetch.start').info((basename(target_full_path)[:14], content_length))

digest_builder = hashlib.new('md5')
try:
Expand Down
4 changes: 2 additions & 2 deletions conda/install.py
Expand Up @@ -47,8 +47,8 @@

# backwards compatibility for conda-build
def package_cache():
log.warn('package_cache() is a no-op and deprecated')
return {}
from .core.package_cache import package_cache
return package_cache()


if on_win:
Expand Down
4 changes: 2 additions & 2 deletions conda/models/channel.py
Expand Up @@ -212,8 +212,8 @@ def from_value(value):
return Channel(name=UNKNOWN_CHANNEL)
value = ensure_text_type(value)
if has_scheme(value):
if value.startswith('file:'):
value = win_path_backout(value)
if value.startswith('file:') and on_win:
value = value.replace('\\', '/')
return Channel.from_url(value)
elif is_path(value):
return Channel.from_url(path_to_url(value))
Expand Down
6 changes: 6 additions & 0 deletions conda/models/enums.py
Expand Up @@ -68,6 +68,9 @@ def __int__(self):
def __str__(self):
return self.name

def __json__(self):
return self.name


class PathType(Enum):
"""
Expand All @@ -86,3 +89,6 @@ class PathType(Enum):

def __str__(self):
return self.name

def __json__(self):
return self.name
4 changes: 2 additions & 2 deletions conda/models/index_record.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

from .enums import Arch, LinkType, Platform
from .enums import LinkType, Platform
from .._vendor.auxlib.entity import (BooleanField, ComposableField, DictSafeMixin, Entity,
EnumField, ImmutableEntity, IntegerField, ListField,
MapField, StringField)
Expand Down Expand Up @@ -46,7 +46,7 @@ class Link(DictSafeMixin, Entity):
class IndexRecord(DictSafeMixin, ImmutableEntity): # rename to IndexRecord
_lazy_validate = True

arch = EnumField(Arch, required=False, nullable=True)
arch = StringField(required=False, nullable=True)
build = StringField()
build_number = IntegerField()
date = StringField(required=False)
Expand Down
5 changes: 5 additions & 0 deletions conda/resolve.py
Expand Up @@ -558,6 +558,11 @@ def package_quad(self, dist):
def package_name(self, dist):
return self.package_quad(dist)[0]

def get_pkgs(self, ms, emptyok=False):
# legacy method for conda-build
# TODO: remove in conda 4.4
return self.get_dists_for_spec(ms, emptyok)

def get_dists_for_spec(self, ms, emptyok=False):
ms = MatchSpec(ms)
dists = self.find_matches(ms)
Expand Down
7 changes: 4 additions & 3 deletions utils/travis-run-install.sh
Expand Up @@ -82,7 +82,8 @@ miniconda_install() {

conda_build_install() {
# install conda
python utils/setup-testing.py install
rm -rf $(~/miniconda/bin/python -c "import site; print(site.getsitepackages()[0])")/conda
~/miniconda/bin/python utils/setup-testing.py install
hash -r
conda info

Expand All @@ -91,7 +92,7 @@ conda_build_install() {
conda install -y -q -c conda-forge perl pytest-xdist
conda install -y -q anaconda-client numpy

python -m pip install pytest-capturelog pytest-mock
~/miniconda/bin/python -m pip install pytest-capturelog pytest-mock

conda config --set add_pip_as_python_dependency true

Expand All @@ -101,7 +102,7 @@ conda_build_install() {
# install conda-build
git clone -b $CONDA_BUILD --single-branch --depth 1000 https://github.com/conda/conda-build.git
pushd conda-build
python setup.py install
~/miniconda/bin/pip install .
hash -r
conda info
popd
Expand Down
2 changes: 1 addition & 1 deletion utils/travis-run-script.sh
Expand Up @@ -55,7 +55,7 @@ conda_build_unit_test() {
echo
echo ">>>>>>>>>>>> running conda-build unit tests >>>>>>>>>>>>>>>>>>>>>"
echo
python -m pytest -n 2 --basetemp /tmp/cb tests || echo -e "\n>>>>> conda-build tests exited with code" $? "\n\n\n"
~/miniconda/bin/python -m pytest --basetemp /tmp/cb tests || echo -e "\n>>>>> conda-build tests exited with code" $? "\n\n\n"
popd
}

Expand Down

0 comments on commit f804f69

Please sign in to comment.