Repository: conda/conda

Issue:
Installing a local noarch package fails
I downloaded a bokeh noarch package from https://anaconda.org/bokeh/bokeh/0.12.7dev3/download/noarch/bokeh-0.12.7dev3-py_0.tar.bz2 to install and received an error when trying to install from downloaded package:

    conda install ../conda/bokeh-0.12.7dev3-py_0-noarch.tar.bz2 -p /Users/hsparra/milestone1_py36An unexpected error has occurred.
     Please consider posting the following information to the
     conda GitHub issue tracker at:

    https://github.com/conda/conda/issues


    Current conda install:

               platform : osx-64
          conda version : 4.3.21
       conda is private : False
      conda-env version : 4.3.21
    conda-build version : 2.1.15
         python version : 3.5.2.final.0
       requests version : 2.12.4
       root environment : /Users/hsparra/anaconda  (writable)
    default environment : /Users/hsparra/milestone1_py36
       envs directories : /Users/hsparra/anaconda/envs
                          /Users/hsparra/.conda/envs
          package cache : /Users/hsparra/anaconda/pkgs
                          /Users/hsparra/.conda/pkgs
           channel URLs : https://conda.anaconda.org/bokeh/c/dev/osx-64
                          https://conda.anaconda.org/bokeh/c/dev/noarch
                          https://conda.anaconda.org/anaconda/osx-64
                          https://conda.anaconda.org/anaconda/noarch
                          https://repo.continuum.io/pkgs/free/osx-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/r/osx-64
                          https://repo.continuum.io/pkgs/r/noarch
                          https://repo.continuum.io/pkgs/pro/osx-64
                          https://repo.continuum.io/pkgs/pro/noarch
                          https://conda.anaconda.org/conda-forge/osx-64
                          https://conda.anaconda.org/conda-forge/noarch
                          https://conda.anaconda.org/anaconda-fusion/osx-64
                          https://conda.anaconda.org/anaconda-fusion/noarch
                          https://conda.anaconda.org/anaconda-mosaic/osx-64
                          https://conda.anaconda.org/anaconda-mosaic/noarch
                          https://conda.anaconda.org/quanyuan/osx-64
                          https://conda.anaconda.org/quanyuan/noarch
            config file : /Users/hsparra/.condarc
             netrc file : None
           offline mode : False
             user-agent : conda/4.3.21 requests/2.12.4 CPython/3.5.2 Darwin/16.6.0 OSX/10.12.5
                UID:GID : 503:20

     $ /Users/hsparra/milestone1_py36/bin/conda install ../conda/bokeh-0.12.7dev3-py_0-noarch.tar.bz2 -p /Users/hsparra/milestone1_py36`




    Traceback (most recent call last):
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/exceptions.py", line 632, in conda_exception_handler
        return_value = func(*args, **kwargs)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/cli/main.py", line 137, in _main
        exit_code = args.func(args, p)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/cli/main_install.py", line 80, in execute
        install(args, parser, 'install')
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/cli/install.py", line 199, in install
        explicit(args_packages, prefix, verbose=not context.quiet)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/misc.py", line 110, in explicit
        execute_actions(actions, index, verbose=verbose)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/plan.py", line 830, in execute_actions
        execute_instructions(plan, index, verbose)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/instructions.py", line 247, in execute_instructions
        cmd(state, arg)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/instructions.py", line 108, in UNLINKLINKTRANSACTION_CMD
        txn.execute()
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/link.py", line 263, in execute
        self.verify()
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/link.py", line 242, in verify
        self.prepare()
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/link.py", line 173, in prepare
        concatv(unlink_actions, link_actions))
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/link.py", line 172, in <genexpr>
        self.all_actions = tuple(per_pkg_actions for per_pkg_actions in
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/link.py", line 169, in <genexpr>
        for pkg_info, lt in zip(self.packages_info_to_link, link_types)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/link.py", line 406, in make_link_actions
        file_link_actions = LinkPathAction.create_file_link_actions(*required_quad)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/path_actions.py", line 181, in create_file_link_actions
        return tuple(make_file_link_action(spi) for spi in package_info.paths_data.paths)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/path_actions.py", line 181, in <genexpr>
        return tuple(make_file_link_action(spi) for spi in package_info.paths_data.paths)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/core/path_actions.py", line 161, in make_file_link_action
        target_short_path = get_python_noarch_target_path(source_path_info.path, sp_dir)
      File "/Users/hsparra/anaconda/lib/python3.5/site-packages/conda/common/path.py", line 238, in get_python_noarch_target_path
        return source_short_path.replace('site-packages', sp_dir, 1)
    TypeError: Can't convert 'NoneType' object to str implicitly`


Installing from anaconda.org using the bokeh dev channel,
 `conda install -c bokeh/label/dev bokeh` 
works, but specifying the package directly does not work
 `conda install https://anaconda.org/bokeh/bokeh/0.12.7dev3/download/noarch/bokeh-0.12.7dev3-py_0.tar.bz2`


Discussion:
Any chance this bugs gets resolved?
Not sure if this is a bug, because when a tarball is installed directly like that, conda doesn't invoke the solver and installs the package directly, so in the scenario when the conda environment or prefix in which the package is going to be installed doesn't already have some version of python installed, conda doesn't know which `lib/python??/site-packages` directory to pick.

To get around this problem, install python into that environment/prefix first, and then install the noarch_python tarball.

Resolving patch:
diff --git a/conda/core/path_actions.py b/conda/core/path_actions.py
--- a/conda/core/path_actions.py
+++ b/conda/core/path_actions.py
@@ -13,6 +13,7 @@
 from .envs_manager import USER_ENVIRONMENTS_TXT_FILE, register_env, unregister_env
 from .portability import _PaddingError, update_prefix
 from .prefix_data import PrefixData
+from .. import CondaError
 from .._vendor.auxlib.compat import with_metaclass
 from .._vendor.auxlib.ish import dals
 from ..base.constants import CONDA_TARBALL_EXTENSION
@@ -161,6 +162,10 @@ def make_file_link_action(source_path_data):
             noarch = package_info.repodata_record.noarch
             if noarch == NoarchType.python:
                 sp_dir = transaction_context['target_site_packages_short_path']
+                if sp_dir is None:
+                    raise CondaError("Unable to determine python site-packages "
+                                     "dir in target_prefix!\nPlease make sure "
+                                     "python is installed in %s" % target_prefix)
                 target_short_path = get_python_noarch_target_path(source_path_data.path, sp_dir)
             elif noarch is None or noarch == NoarchType.generic:
                 target_short_path = source_path_data.path


Test patch:
diff --git a/tests/common/pkg_formats/test_python.py b/tests/common/pkg_formats/test_python.py
--- a/tests/common/pkg_formats/test_python.py
+++ b/tests/common/pkg_formats/test_python.py
@@ -398,7 +398,7 @@ def test_metadata():
 
 # Python Distributions
 # -----------------------------------------------------------------------------
-@pytest.mark.xfail(datetime.now() < datetime(2018, 12, 1),
+@pytest.mark.xfail(datetime.now() < datetime(2019, 1, 1),
                    reason="This test needs to be refactored for the case of raising a hard "
                                 "error when the anchor_file doesn't exist.",
                    strict=True)
diff --git a/tests/test_create.py b/tests/test_create.py
--- a/tests/test_create.py
+++ b/tests/test_create.py
@@ -584,8 +584,13 @@ def test_strict_channel_priority(self):
         assert not stderr
         json_obj = json_loads(stdout)
         channel_groups = groupby("channel",json_obj["actions"]["LINK"])
+        channel_groups = sorted(list(channel_groups))
         # conda-forge should be the only channel in the solution on unix
-        assert list(channel_groups) == ["conda-forge"]
+        # fiona->gdal->libgdal->m2w64-xz brings in pkgs/msys2 on win
+        if on_win:
+            assert channel_groups == ["conda-forge", "pkgs/msys2"]
+        else:
+            assert channel_groups == ["conda-forge"]
 
     def test_strict_resolve_get_reduced_index(self):
         channels = (Channel("defaults"),)
@@ -925,8 +930,7 @@ def test_install_freeze_installed_flag(self):
                 run_command(Commands.INSTALL, prefix,
                             "conda-forge::tensorflow>=1.4 --dry-run --freeze-installed")
 
-    @pytest.mark.xfail(on_win and datetime.now() < datetime(2018, 11, 1),
-                       reason="need to talk with @msarahan about blas patches on Windows",
+    @pytest.mark.xfail(on_win, reason="nomkl not present on windows",
                        strict=True)
     def test_install_features(self):
         with make_temp_env("python=2 numpy=1.13 nomkl") as prefix:
diff --git a/tests/test_resolve.py b/tests/test_resolve.py
--- a/tests/test_resolve.py
+++ b/tests/test_resolve.py
@@ -1025,7 +1025,7 @@ def test_no_features():
     ]
 
 
-@pytest.mark.skipif(datetime.now() < datetime(2018, 12, 1), reason="bogus test; talk with @mcg1969")
+@pytest.mark.skipif(datetime.now() < datetime(2019, 1, 1), reason="bogus test; talk with @mcg1969")
 def test_multiple_solution():
     assert False
 #    index2 = index.copy()