Repository: conda/conda

Issue:
conda 4.6.x and conda 4.7.x not able to resolve identical package in different subdirectories
Current Behavior
<!-- What actually happens?
     If you want to include console output, please use "Steps to Reproduce" below. -->

The following happens:
```
[root@596ad8f0842a /]# conda create -n conda-env --dry-run -- test-package
Collecting package metadata (current_repodata.json): done
Solving environment: failed with current_repodata.json, will retry with next repodata source.
Collecting package metadata (repodata.json): done
Solving environment: failed

UnsatisfiableError: The following specifications were found to be incompatible with each other:

Package pandas conflicts for:
test-package -> pandas
Package typing conflicts for:
test-package -> typing
Package libffi conflicts for:
test-package -> libffi[version='>=3.2.1,<4.0a0']
Package pyyaml conflicts for:
test-package -> pyyaml
Package six conflicts for:
test-package -> six[version='>=1.12.0']
Package py4j conflicts for:
test-package -> py4j
Package icu conflicts for:
test-package -> icu
Package wrapt conflicts for:
test-package -> wrapt
Package pytz conflicts for:
test-package -> pytz
Package python conflicts for:
test-package -> python[version='>=2.7.14']
Package pyarrow conflicts for:
test-package -> pyarrow
Package matplotlib conflicts for:
test-package -> matplotlib[version='>=2.0.2,<2.3.0']
```
Also observed on conda 4.6.14

### Steps to Reproduce
<!-- If the current behavior is a bug, please provide specific, minimal steps to independently reproduce.
     Include the exact conda commands that reproduce the issue and their output between the ticks below. -->

1. Create a conda repository `test-channel` with the following set up
2. In /linux-64/repodata.json
```
{
  "info": {
    "subdir": "linux-64"
  },
  "packages": {
    "test-package-4.2.1-py_0.tar.bz2": {
      "build": "py_0",
      "build_number": 0,
      "depends": [
        "icu",
        "libffi >=3.2.1,<4.0a0",
        "matplotlib >=2.0.2,<2.3.0",
        "pandas",
        "py4j",
        "pyarrow",
        "python >=2.7.14",
        "pytz",
        "pyyaml",
        "six >=1.12.0",
        "typing",
        "wrapt"
      ],
      "md5": "1512a7e9a56ecb8523475c891bfa6657",
      "name": "test-package",
      "noarch": "python",
      "sha256": "3c02f947500c13ceb8e8aa38db2af43e9017c4948905d0cbd1610185318fe7d9",
      "size": 30098,
      "subdir": "noarch",
      "timestamp": 1565634321434,
      "version": "4.2.1"
    }
  },
  "removed": [],
  "repodata_version": 1
}
```
3. In /noarch/repodata.json
```
{
  "info": {
    "subdir": "noarch"
  },
  "packages": {
    "test-package-4.2.1-py_0.tar.bz2": {
      "build": "py_0",
      "build_number": 0,
      "depends": [
        "icu",
        "libffi >=3.2.1,<4.0a0",
        "matplotlib >=2.0.2,<2.3.0",
        "pandas",
        "py4j",
        "pyarrow",
        "python >=2.7.14",
        "pytz",
        "pyyaml",
        "six >=1.12.0",
        "typing",
        "wrapt"
      ],
      "md5": "1512a7e9a56ecb8523475c891bfa6657",
      "name": "test-package",
      "noarch": "python",
      "sha256": "3c02f947500c13ceb8e8aa38db2af43e9017c4948905d0cbd1610185318fe7d9",
      "size": 30098,
      "subdir": "noarch",
      "timestamp": 1565634321434,
      "version": "4.2.1"
    }
  },
  "removed": [],
  "repodata_version": 1
}
```
3. Set up conda to only point to the test-channel, note I see this error on `--dry-run` so I did not populate the test-channel with the actual packages.
4. Run `conda create -n conda-env --dry-run -- test-package`

## Expected Behavior
<!-- What do you think should happen? -->
Previously, in conda 4.5.x, there was no issue with resolving packages like this.

## Environment Information
<details open><summary><code>`conda info`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda info' -->

```
[root@596ad8f0842a /]# conda info

     active environment : None
       user config file : /root/.condarc
 populated config files : /root/.condarc
                          /condarc
          conda version : 4.7.10
    conda-build version : not installed
         python version : 3.7.3.final.0
       virtual packages : 
       base environment : /miniconda  (writable)
           channel URLs : file://test-channel/asset/conda/linux-64
                          file://test-channel/asset/conda/noarch
          package cache : /miniconda/pkgs
                          /root/.conda/pkgs
       envs directories : /miniconda/envs
                          /root/.conda/envs
               platform : linux-64
             user-agent : conda/4.7.10 requests/2.22.0 CPython/3.7.3 Linux/4.9.184-linuxkit centos/6.10 glibc/2.12
                UID:GID : 0:0
             netrc file : None
           offline mode : False
```
</p></details>


<details open><summary><code>`conda config --show-sources`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda config --show-sources' -->

```
[root@596ad8f0842a /]# conda config --show-sources
==> /root/.condarc <==
channel_priority: disabled
channels:
  - file://test-channel/asset/conda/
repodata_fns:
  - repodata.json
use_only_tar_bz2: False

==> /condarc <==
channels: []
default_channels: []
```
</p></details>
Note I attempted to remove current_repodata.json from being considered, but this is 4.7.10 before the config value is apparently respected.


<details><summary><code>`conda list --show-channel-urls`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda list --show-channel-urls' -->

```
[root@596ad8f0842a /]# conda list --show-channel-urls
# packages in environment at /miniconda:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                        main    https://repo.anaconda.com/pkgs/main
asn1crypto                0.24.0                   py37_0    https://repo.anaconda.com/pkgs/main
bzip2                     1.0.8                h7b6447c_0    https://repo.anaconda.com/pkgs/main
ca-certificates           2019.5.15                     0    https://repo.anaconda.com/pkgs/main
certifi                   2019.6.16                py37_0    https://repo.anaconda.com/pkgs/main
cffi                      1.12.3           py37h2e261b9_0    https://repo.anaconda.com/pkgs/main
chardet                   3.0.4                    py37_1    https://repo.anaconda.com/pkgs/main
conda                     4.7.10                   py37_0    https://repo.anaconda.com/pkgs/main
conda-package-handling    1.3.11                   py37_0    https://repo.anaconda.com/pkgs/main
cryptography              2.7              py37h1ba5d50_0    https://repo.anaconda.com/pkgs/main
idna                      2.8                      py37_0    https://repo.anaconda.com/pkgs/main
libarchive                3.3.3                h5d8350f_5    https://repo.anaconda.com/pkgs/main
libedit                   3.1.20181209         hc058e9b_0    https://repo.anaconda.com/pkgs/main
libffi                    3.2.1                hd88cf55_4    https://repo.anaconda.com/pkgs/main
libgcc-ng                 9.1.0                hdf63c60_0    https://repo.anaconda.com/pkgs/main
libstdcxx-ng              9.1.0                hdf63c60_0    https://repo.anaconda.com/pkgs/main
libxml2                   2.9.9                hea5a465_1    https://repo.anaconda.com/pkgs/main
lz4-c                     1.8.1.2              h14c3975_0    https://repo.anaconda.com/pkgs/main
lzo                       2.10                 h49e0be7_2    https://repo.anaconda.com/pkgs/main
ncurses                   6.1                  he6710b0_1    https://repo.anaconda.com/pkgs/main
openssl                   1.1.1c               h7b6447c_1    https://repo.anaconda.com/pkgs/main
pip                       19.1.1                   py37_0    https://repo.anaconda.com/pkgs/main
pycosat                   0.6.3            py37h14c3975_0    https://repo.anaconda.com/pkgs/main
pycparser                 2.19                     py37_0    https://repo.anaconda.com/pkgs/main
pyopenssl                 19.0.0                   py37_0    https://repo.anaconda.com/pkgs/main
pysocks                   1.7.0                    py37_0    https://repo.anaconda.com/pkgs/main
python                    3.7.3                h0371630_0    https://repo.anaconda.com/pkgs/main
python-libarchive-c       2.8                     py37_11    https://repo.anaconda.com/pkgs/main
readline                  7.0                  h7b6447c_5    https://repo.anaconda.com/pkgs/main
requests                  2.22.0                   py37_0    https://repo.anaconda.com/pkgs/main
ruamel_yaml               0.15.46          py37h14c3975_0    https://repo.anaconda.com/pkgs/main
setuptools                41.0.1                   py37_0    https://repo.anaconda.com/pkgs/main
six                       1.12.0                   py37_0    https://repo.anaconda.com/pkgs/main
sqlite                    3.29.0               h7b6447c_0    https://repo.anaconda.com/pkgs/main
tk                        8.6.8                hbc83047_0    https://repo.anaconda.com/pkgs/main
tqdm                      4.32.1                     py_0    https://repo.anaconda.com/pkgs/main
urllib3                   1.24.2                   py37_0    https://repo.anaconda.com/pkgs/main
wheel                     0.33.4                   py37_0    https://repo.anaconda.com/pkgs/main
xz                        5.2.4                h14c3975_4    https://repo.anaconda.com/pkgs/main
yaml                      0.1.7                had09818_2    https://repo.anaconda.com/pkgs/main
zlib                      1.2.11               h7b6447c_3    https://repo.anaconda.com/pkgs/main
zstd                      1.3.7                h0b5b093_0    https://repo.anaconda.com/pkgs/main
```
</p></details>



Discussion:
Key question: is this expected behavior for packages that have an identical noarch and linux-64 builds?
Additional note: if I remove the repodata entry for either `linux-64` or `noarch` subdir, but not the other, then the command succeeds
This is likely similar to #8302 which was partially fixed in #8938.  Packages from different subdirs with the same name will also have the same channel which causes conda to consider than as the same package.  

For the time being it is best to not have packages with identical names in `noarch` and another subdir.  This is not the intended behavior, the solver should treat these are two separate packages. 
To add a data point, I'm seeing this on another `conda create` but this time it doesn't seem to be an issue with any packages that I can control, but somewhere in public channels. Is there a suggested way to narrow down where this is coming from?
@jjhelmus do you have any initial thoughts on how to fix the issue within conda? Happy to take a stab at contributing and testing a patch for this edge case.

Resolving patch:
diff --git a/conda/models/match_spec.py b/conda/models/match_spec.py
--- a/conda/models/match_spec.py
+++ b/conda/models/match_spec.py
@@ -181,8 +181,16 @@ def from_dist_str(cls, dist_str):
         if dist_str.endswith(CONDA_PACKAGE_EXTENSION_V1):
             dist_str = dist_str[:-len(CONDA_PACKAGE_EXTENSION_V1)]
         if '::' in dist_str:
-            channel_str, dist_str = dist_str.split("::", 1)
-            parts['channel'] = channel_str
+            channel_subdir_str, dist_str = dist_str.split("::", 1)
+            if '/' in channel_subdir_str:
+                channel_str, subdir = channel_subdir_str.split('/', 2)
+                parts.update({
+                    'channel': channel_str,
+                    'subdir': subdir,
+                })
+            else:
+                parts['channel'] = channel_subdir_str
+
         name, version, build = dist_str.rsplit('-', 2)
         parts.update({
             'name': name,
diff --git a/conda/models/records.py b/conda/models/records.py
--- a/conda/models/records.py
+++ b/conda/models/records.py
@@ -281,7 +281,7 @@ def __eq__(self, other):
         return self._pkey == other._pkey
 
     def dist_str(self):
-        return "%s::%s-%s-%s" % (self.channel.canonical_name, self.name, self.version, self.build)
+        return "%s%s::%s-%s-%s" % (self.channel.canonical_name, ("/" + self.subdir) if self.subdir else "", self.name, self.version, self.build)
 
     def dist_fields_dump(self):
         return {


Test patch:
diff --git a/tests/core/test_solve.py b/tests/core/test_solve.py
--- a/tests/core/test_solve.py
+++ b/tests/core/test_solve.py
@@ -24,7 +24,7 @@
 from conda.models.records import PrefixRecord
 from conda.models.enums import PackageType
 from conda.resolve import MatchSpec
-from ..helpers import get_index_r_1, get_index_r_2, get_index_r_4, \
+from ..helpers import add_subdir_to_iter, get_index_r_1, get_index_r_2, get_index_r_4, \
     get_index_r_5, get_index_cuda, get_index_must_unfreeze
 
 from conda.common.compat import iteritems
@@ -154,7 +154,7 @@ def test_solve_1():
     with get_solver(specs) as solver:
         final_state = solver.solve_final_state()
         # print(convert_to_dist_str(final_state))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -163,7 +163,7 @@ def test_solve_1():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-3.3.2-0',
             'channel-1::numpy-1.7.1-py33_0',
-        )
+        ))
         assert convert_to_dist_str(final_state) == order
 
     specs_to_add = MatchSpec("python=2"),
@@ -171,7 +171,7 @@ def test_solve_1():
                     prefix_records=final_state, history_specs=specs) as solver:
         final_state = solver.solve_final_state()
         # print(convert_to_dist_str(final_state))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -180,7 +180,7 @@ def test_solve_1():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
             'channel-1::numpy-1.7.1-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state) == order
 
 
@@ -190,7 +190,7 @@ def test_solve_2():
     with get_solver_aggregate_1(specs) as solver:
         final_state = solver.solve_final_state()
         # print(convert_to_dist_str(final_state))
-        order = (
+        order = add_subdir_to_iter((
             'channel-2::mkl-2017.0.3-0',
             'channel-2::openssl-1.0.2l-0',
             'channel-2::readline-6.2-2',
@@ -200,7 +200,7 @@ def test_solve_2():
             'channel-2::zlib-1.2.11-0',
             'channel-2::python-3.6.2-0',
             'channel-2::numpy-1.13.1-py36_0'
-        )
+        ))
         assert convert_to_dist_str(final_state) == order
 
     specs_to_add = MatchSpec("channel-4::numpy"),
@@ -242,9 +242,9 @@ def test_cuda_1():
         with get_solver_cuda(specs) as solver:
             final_state = solver.solve_final_state()
             # print(convert_to_dist_str(final_state))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::cudatoolkit-9.0-0',
-            )
+            ))
             assert convert_to_dist_str(final_state) == order
 
 
@@ -255,9 +255,9 @@ def test_cuda_2():
         with get_solver_cuda(specs) as solver:
             final_state = solver.solve_final_state()
             # print(convert_to_dist_str(final_state))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::cudatoolkit-10.0-0',
-            )
+            ))
             assert convert_to_dist_str(final_state) == order
 
 
@@ -298,7 +298,7 @@ def test_prune_1():
     with get_solver(specs) as solver:
         final_state_1 = solver.solve_final_state()
         pprint(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::libnvvm-1.0-p0',
             'channel-1::mkl-rt-11.0-p0',
             'channel-1::openssl-1.0.1c-0',
@@ -321,7 +321,7 @@ def test_prune_1():
             'channel-1::scikit-learn-0.13.1-np16py27_p0',
             'channel-1::mkl-11.0-np16py27_p0',
             'channel-1::accelerate-1.1.0-np16py27_p0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs_to_remove = MatchSpec("numbapro"),
@@ -330,7 +330,7 @@ def test_prune_1():
         unlink_precs, link_precs = solver.solve_for_diff()
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
-        unlink_order = (
+        unlink_order = add_subdir_to_iter((
             'channel-1::accelerate-1.1.0-np16py27_p0',
             'channel-1::mkl-11.0-np16py27_p0',
             'channel-1::scikit-learn-0.13.1-np16py27_p0',
@@ -346,10 +346,10 @@ def test_prune_1():
             'channel-1::llvm-3.2-0',
             'channel-1::mkl-rt-11.0-p0',
             'channel-1::libnvvm-1.0-p0',
-        )
-        link_order = (
+        ))
+        link_order = add_subdir_to_iter((
             'channel-1::numpy-1.6.2-py27_4',
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -360,7 +360,7 @@ def test_force_remove_1():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -369,7 +369,7 @@ def test_force_remove_1():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
             'channel-1::numpy-1.7.1-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     # without force_remove, taking out python takes out everything that depends on it, too,
@@ -382,10 +382,9 @@ def test_force_remove_1():
         print(convert_to_dist_str(final_state_2))
         # openssl remains because it is in the aggressive_update_packages set,
         #    but everything else gets removed
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
-
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
     # with force remove, we remove only the explicit specs that we provide
@@ -396,7 +395,7 @@ def test_force_remove_1():
         final_state_2 = solver.solve_final_state(force_remove=True)
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::numpy-1.7.1-py27_0',
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
@@ -404,7 +403,7 @@ def test_force_remove_1():
             'channel-1::system-5.8-1',
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
     # re-solving restores order
@@ -412,7 +411,7 @@ def test_force_remove_1():
         final_state_3 = solver.solve_final_state()
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_3))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -421,7 +420,7 @@ def test_force_remove_1():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
             'channel-1::numpy-1.7.1-py27_0'
-        )
+        ))
         assert convert_to_dist_str(final_state_3) == order
 
 
@@ -431,7 +430,7 @@ def test_no_deps_1():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -439,7 +438,7 @@ def test_no_deps_1():
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs_to_add = MatchSpec("numba"),
@@ -447,7 +446,7 @@ def test_no_deps_1():
         final_state_2 = solver.solve_final_state()
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -460,7 +459,7 @@ def test_no_deps_1():
             'channel-1::meta-0.4.2.dev-py27_0',
             'channel-1::numpy-1.7.1-py27_0',
             'channel-1::numba-0.8.1-np17py27_0'
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
     specs_to_add = MatchSpec("numba"),
@@ -468,7 +467,7 @@ def test_no_deps_1():
         final_state_2 = solver.solve_final_state(deps_modifier='NO_DEPS')
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -477,7 +476,7 @@ def test_no_deps_1():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
             'channel-1::numba-0.8.1-np17py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
 
@@ -487,7 +486,7 @@ def test_only_deps_1():
         final_state_1 = solver.solve_final_state(deps_modifier=DepsModifier.ONLY_DEPS)
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -499,7 +498,7 @@ def test_only_deps_1():
             'channel-1::llvmpy-0.11.2-py27_0',
             'channel-1::meta-0.4.2.dev-py27_0',
             'channel-1::numpy-1.7.1-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
 
@@ -509,7 +508,7 @@ def test_only_deps_2():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -518,7 +517,7 @@ def test_only_deps_2():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.3-7',
             'channel-1::numpy-1.5.1-py27_4',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs_to_add = MatchSpec("numba=0.5"),
@@ -526,7 +525,7 @@ def test_only_deps_2():
         final_state_2 = solver.solve_final_state(deps_modifier=DepsModifier.ONLY_DEPS)
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -540,7 +539,7 @@ def test_only_deps_2():
             'channel-1::nose-1.3.0-py27_0',
             'channel-1::numpy-1.7.1-py27_0',
             # 'channel-1::numba-0.5.0-np17py27_0',  # not in the order because only_deps
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
     # fails because numpy=1.5 is in our history as an explicit spec
@@ -554,7 +553,7 @@ def test_only_deps_2():
         final_state_2 = solver.solve_final_state(deps_modifier=DepsModifier.ONLY_DEPS)
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -568,7 +567,7 @@ def test_only_deps_2():
             'channel-1::nose-1.3.0-py27_0',
             'channel-1::numpy-1.7.1-py27_0',
             # 'channel-1::numba-0.5.0-np17py27_0',   # not in the order because only_deps
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
 
@@ -578,7 +577,7 @@ def test_update_all_1():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -587,7 +586,7 @@ def test_update_all_1():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.6.8-6',
             'channel-1::numpy-1.5.1-py26_4',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs_to_add = MatchSpec("numba=0.6"), MatchSpec("numpy")
@@ -595,7 +594,7 @@ def test_update_all_1():
         final_state_2 = solver.solve_final_state()
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -608,7 +607,7 @@ def test_update_all_1():
             'channel-1::nose-1.3.0-py26_0',
             'channel-1::numpy-1.7.1-py26_0',
             'channel-1::numba-0.6.0-np17py26_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
     specs_to_add = MatchSpec("numba=0.6"),
@@ -616,7 +615,7 @@ def test_update_all_1():
         final_state_2 = solver.solve_final_state(update_modifier=UpdateModifier.UPDATE_ALL)
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -629,7 +628,7 @@ def test_update_all_1():
             'channel-1::nose-1.3.0-py26_0',
             'channel-1::numpy-1.7.1-py26_0',
             'channel-1::numba-0.6.0-np17py26_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
 
@@ -639,7 +638,7 @@ def test_broken_install():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order_original = (
+        order_original = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -653,7 +652,7 @@ def test_broken_install():
             'channel-1::dateutil-2.1-py27_1',
             'channel-1::scipy-0.12.0-np16py27_0',
             'channel-1::pandas-0.11.0-np16py27_1',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order_original
         assert solver._r.environment_is_consistent(final_state_1)
 
@@ -669,7 +668,7 @@ def test_broken_install():
         final_state_2 = solver.solve_final_state()
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             "channel-1::numpy-1.7.1-py33_p0",
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
@@ -686,7 +685,7 @@ def test_broken_install():
             'channel-1::dateutil-2.1-py27_1',
             'channel-1::flask-0.9-py27_0',
             'channel-1::pandas-0.11.0-np16py27_1'
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
         assert not solver._r.environment_is_consistent(final_state_2)
 
@@ -696,7 +695,7 @@ def test_broken_install():
         final_state_2 = solver.solve_final_state()
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -713,7 +712,7 @@ def test_broken_install():
             'channel-1::flask-0.9-py27_0',
             'channel-1::scipy-0.12.0-np16py27_0',
             'channel-1::pandas-0.11.0-np16py27_1',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
         assert solver._r.environment_is_consistent(final_state_2)
 
@@ -731,7 +730,7 @@ def test_conda_downgrade():
         with get_solver_aggregate_1(specs) as solver:
             final_state_1 = solver.solve_final_state()
             pprint(convert_to_dist_str(final_state_1))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-4::ca-certificates-2018.03.07-0',
                 'channel-2::conda-env-2.6.0-0',
                 'channel-2::libffi-3.2.1-1',
@@ -774,7 +773,7 @@ def test_conda_downgrade():
                 'channel-4::requests-2.19.1-py37_0',
                 'channel-4::conda-4.5.10-py37_0',
                 'channel-4::conda-build-3.12.1-py37_0'
-            )
+            ))
             assert convert_to_dist_str(final_state_1) == order
 
     specs_to_add = MatchSpec("itsdangerous"),  # MatchSpec("conda"),
@@ -789,9 +788,9 @@ def test_conda_downgrade():
             unlink_order = (
                 # no conda downgrade
             )
-            link_order = (
+            link_order = add_subdir_to_iter((
                 'channel-2::itsdangerous-0.24-py_0',
-            )
+            ))
             assert convert_to_dist_str(unlink_precs) == unlink_order
             assert convert_to_dist_str(link_precs) == link_order
 
@@ -810,7 +809,7 @@ def test_conda_downgrade():
             unlink_precs, link_precs = solver.solve_for_diff()
             pprint(convert_to_dist_str(unlink_precs))
             pprint(convert_to_dist_str(link_precs))
-            unlink_order = (
+            unlink_order = add_subdir_to_iter((
                 # now conda gets downgraded
                 'channel-4::conda-build-3.12.1-py37_0',
                 'channel-4::conda-4.5.10-py37_0',
@@ -847,8 +846,8 @@ def test_conda_downgrade():
                 'channel-4::tk-8.6.7-hc745277_3',
                 'channel-4::openssl-1.0.2p-h14c3975_0',
                 'channel-4::ncurses-6.1-hf484d3e_0',
-            )
-            link_order = (
+            ))
+            link_order = add_subdir_to_iter((
                 'channel-2::openssl-1.0.2l-0',
                 'channel-2::readline-6.2-2',
                 'channel-2::sqlite-3.13.0-0',
@@ -882,7 +881,7 @@ def test_conda_downgrade():
                 'channel-2::pyopenssl-17.0.0-py36_0',
                 'channel-2::conda-4.3.30-py36h5d9f9f4_0',
                 'channel-4::conda-build-3.12.1-py36_0'
-            )
+            ))
             assert convert_to_dist_str(unlink_precs) == unlink_order
             assert convert_to_dist_str(link_precs) == link_order
     finally:
@@ -906,23 +905,23 @@ def test_unfreeze_when_required():
     with get_solver_must_unfreeze(specs) as solver:
         final_state_1 = solver.solve_final_state()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-freeze::libbar-2.0-0',
             'channel-freeze::libfoo-1.0-0',
             'channel-freeze::foobar-1.0-0',
             'channel-freeze::qux-1.0-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs = MatchSpec("foobar"),
     with get_solver_must_unfreeze(specs) as solver:
         final_state_1 = solver.solve_final_state()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-freeze::libbar-2.0-0',
             'channel-freeze::libfoo-2.0-0',
             'channel-freeze::foobar-2.0-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     # When frozen there is no solution - but conda tries really hard to not freeze things that conflict
@@ -937,12 +936,12 @@ def test_unfreeze_when_required():
         final_state_2 = solver.solve_final_state(update_modifier=UpdateModifier.UPDATE_SPECS)
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-freeze::libbar-2.0-0',
             'channel-freeze::libfoo-1.0-0',
             'channel-freeze::foobar-1.0-0',
             'channel-freeze::qux-1.0-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
 
@@ -952,7 +951,7 @@ def test_auto_update_conda():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -963,7 +962,7 @@ def test_auto_update_conda():
             'channel-1::python-2.7.5-0',
             'channel-1::pyyaml-3.10-py27_0',
             'channel-1::conda-1.3.5-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     with env_vars({"CONDA_AUTO_UPDATE_CONDA": "yes"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
@@ -972,7 +971,7 @@ def test_auto_update_conda():
             final_state_2 = solver.solve_final_state()
             # PrefixDag(final_state_2, specs).open_url()
             print(convert_to_dist_str(final_state_2))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::openssl-1.0.1c-0',
                 'channel-1::readline-6.2-0',
                 'channel-1::sqlite-3.7.13-0',
@@ -984,7 +983,7 @@ def test_auto_update_conda():
                 'channel-1::pytz-2013b-py27_0',
                 'channel-1::pyyaml-3.10-py27_0',
                 'channel-1::conda-1.3.5-py27_0',
-            )
+            ))
             assert convert_to_dist_str(final_state_2) == order
 
     saved_sys_prefix = sys.prefix
@@ -996,7 +995,7 @@ def test_auto_update_conda():
                 final_state_2 = solver.solve_final_state()
                 # PrefixDag(final_state_2, specs).open_url()
                 print(convert_to_dist_str(final_state_2))
-                order = (
+                order = add_subdir_to_iter((
                     'channel-1::openssl-1.0.1c-0',
                     'channel-1::readline-6.2-0',
                     'channel-1::sqlite-3.7.13-0',
@@ -1008,7 +1007,7 @@ def test_auto_update_conda():
                     'channel-1::pytz-2013b-py27_0',
                     'channel-1::pyyaml-3.10-py27_0',
                     'channel-1::conda-1.5.2-py27_0',
-                )
+                ))
                 assert convert_to_dist_str(final_state_2) == order
 
         with env_vars({"CONDA_AUTO_UPDATE_CONDA": "no"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
@@ -1017,7 +1016,7 @@ def test_auto_update_conda():
                 final_state_2 = solver.solve_final_state()
                 # PrefixDag(final_state_2, specs).open_url()
                 print(convert_to_dist_str(final_state_2))
-                order = (
+                order = add_subdir_to_iter((
                     'channel-1::openssl-1.0.1c-0',
                     'channel-1::readline-6.2-0',
                     'channel-1::sqlite-3.7.13-0',
@@ -1029,7 +1028,7 @@ def test_auto_update_conda():
                     'channel-1::pytz-2013b-py27_0',
                     'channel-1::pyyaml-3.10-py27_0',
                     'channel-1::conda-1.3.5-py27_0',
-                )
+                ))
                 assert convert_to_dist_str(final_state_2) == order
     finally:
         sys.prefix = saved_sys_prefix
@@ -1041,7 +1040,7 @@ def test_explicit_conda_downgrade():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1052,7 +1051,7 @@ def test_explicit_conda_downgrade():
             'channel-1::python-2.7.5-0',
             'channel-1::pyyaml-3.10-py27_0',
             'channel-1::conda-1.5.2-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     with env_vars({"CONDA_AUTO_UPDATE_CONDA": "yes"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
@@ -1061,7 +1060,7 @@ def test_explicit_conda_downgrade():
             final_state_2 = solver.solve_final_state()
             # PrefixDag(final_state_2, specs).open_url()
             print(convert_to_dist_str(final_state_2))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::openssl-1.0.1c-0',
                 'channel-1::readline-6.2-0',
                 'channel-1::sqlite-3.7.13-0',
@@ -1072,7 +1071,7 @@ def test_explicit_conda_downgrade():
                 'channel-1::python-2.7.5-0',
                 'channel-1::pyyaml-3.10-py27_0',
                 'channel-1::conda-1.3.5-py27_0',
-            )
+            ))
             assert convert_to_dist_str(final_state_2) == order
 
     saved_sys_prefix = sys.prefix
@@ -1084,7 +1083,7 @@ def test_explicit_conda_downgrade():
                 final_state_2 = solver.solve_final_state()
                 # PrefixDag(final_state_2, specs).open_url()
                 print(convert_to_dist_str(final_state_2))
-                order = (
+                order = add_subdir_to_iter((
                     'channel-1::openssl-1.0.1c-0',
                     'channel-1::readline-6.2-0',
                     'channel-1::sqlite-3.7.13-0',
@@ -1095,7 +1094,7 @@ def test_explicit_conda_downgrade():
                     'channel-1::python-2.7.5-0',
                     'channel-1::pyyaml-3.10-py27_0',
                     'channel-1::conda-1.3.5-py27_0',
-                )
+                ))
                 assert convert_to_dist_str(final_state_2) == order
 
         with env_vars({"CONDA_AUTO_UPDATE_CONDA": "no"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
@@ -1104,7 +1103,7 @@ def test_explicit_conda_downgrade():
                 final_state_2 = solver.solve_final_state()
                 # PrefixDag(final_state_2, specs).open_url()
                 print(convert_to_dist_str(final_state_2))
-                order = (
+                order = add_subdir_to_iter((
                     'channel-1::openssl-1.0.1c-0',
                     'channel-1::readline-6.2-0',
                     'channel-1::sqlite-3.7.13-0',
@@ -1115,7 +1114,7 @@ def test_explicit_conda_downgrade():
                     'channel-1::python-2.7.5-0',
                     'channel-1::pyyaml-3.10-py27_0',
                     'channel-1::conda-1.3.5-py27_0',
-                )
+                ))
                 assert convert_to_dist_str(final_state_2) == order
     finally:
         sys.prefix = saved_sys_prefix
@@ -1137,9 +1136,9 @@ def solve(prev_state, specs_to_add, order):
     with env_vars({"CONDA_AGGRESSIVE_UPDATE_PACKAGES": ""}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
         base_state = solve(
             empty_state, ["libpng=1.2"],
-            (
+            add_subdir_to_iter((
                 'channel-1::libpng-1.2.50-0',
-            ))
+            )))
 
     # # ~~has "libpng" restricted to "=1.2" by history_specs~~ NOPE!
     # In conda 4.6 making aggressive_update *more* aggressive, making it override history specs.
@@ -1147,48 +1146,48 @@ def solve(prev_state, specs_to_add, order):
     with env_vars({"CONDA_AGGRESSIVE_UPDATE_PACKAGES": "libpng"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
         solve(
             state_1, ["cmake=2.8.9"],
-            (
+            add_subdir_to_iter((
                 'channel-1::cmake-2.8.9-0',
                 'channel-1::libpng-1.5.13-1',
-            ))
+            )))
     with env_vars({"CONDA_AGGRESSIVE_UPDATE_PACKAGES": ""}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
         state_1_2 = solve(
             state_1, ["cmake=2.8.9"],
-            (
+            add_subdir_to_iter((
                 'channel-1::cmake-2.8.9-0',
                 'channel-1::libpng-1.2.50-0',
-            ))
+            )))
     with env_vars({"CONDA_AGGRESSIVE_UPDATE_PACKAGES": "libpng"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
         solve(
             state_1_2, ["cmake>2.8.9"],
-            (
+            add_subdir_to_iter((
                 'channel-1::cmake-2.8.10.2-0',
                 'channel-1::libpng-1.5.13-1',
-            ))
+            )))
 
     # use new history_specs to remove "libpng" version restriction
     state_2 = (base_state[0], (MatchSpec("libpng"),))
     with env_vars({"CONDA_AGGRESSIVE_UPDATE_PACKAGES": "libpng"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
         solve(
             state_2, ["cmake=2.8.9"],
-            (
+            add_subdir_to_iter((
                 'channel-1::cmake-2.8.9-0',
                 'channel-1::libpng-1.5.13-1',
-            ))
+            )))
     with env_vars({"CONDA_AGGRESSIVE_UPDATE_PACKAGES": ""}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
         state_2_2 = solve(
             state_2, ["cmake=2.8.9"],
-            (
+            add_subdir_to_iter((
                 'channel-1::cmake-2.8.9-0',
                 'channel-1::libpng-1.2.50-0',
-            ))
+            )))
     with env_vars({"CONDA_AGGRESSIVE_UPDATE_PACKAGES": "libpng"}, stack_callback=conda_tests_ctxt_mgmt_def_pol):
         solve(
             state_2_2, ["cmake>2.8.9"],
-            (
+            add_subdir_to_iter((
                 'channel-1::cmake-2.8.10.2-0',
                 'channel-1::libpng-1.5.13-1',
-            ))
+            )))
 
 
 def test_python2_update():
@@ -1198,7 +1197,7 @@ def test_python2_update():
     with get_solver_4(specs) as solver:
         final_state_1 = solver.solve_final_state()
         pprint(convert_to_dist_str(final_state_1))
-        order1 = (
+        order1 = add_subdir_to_iter((
             'channel-4::ca-certificates-2018.03.07-0',
             'channel-4::conda-env-2.6.0-1',
             'channel-4::libgcc-ng-8.2.0-hdf63c60_0',
@@ -1232,14 +1231,14 @@ def test_python2_update():
             'channel-4::urllib3-1.23-py27_0',
             'channel-4::requests-2.19.1-py27_0',
             'channel-4::conda-4.5.10-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order1
 
     specs_to_add = MatchSpec("python=3"),
     with get_solver_4(specs_to_add, prefix_records=final_state_1, history_specs=specs) as solver:
         final_state_2 = solver.solve_final_state()
         pprint(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-4::ca-certificates-2018.03.07-0',
             'channel-4::conda-env-2.6.0-1',
             'channel-4::libgcc-ng-8.2.0-hdf63c60_0',
@@ -1271,7 +1270,7 @@ def test_python2_update():
             'channel-4::urllib3-1.23-py37_0',
             'channel-4::requests-2.19.1-py37_0',
             'channel-4::conda-4.5.10-py37_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
 
@@ -1281,7 +1280,7 @@ def test_update_deps_1():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         # print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1289,14 +1288,14 @@ def test_update_deps_1():
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs2 = MatchSpec("numpy=1.7.0"), MatchSpec("python=2.7.3")
     with get_solver(specs2, prefix_records=final_state_1, history_specs=specs) as solver:
         final_state_2 = solver.solve_final_state()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1306,14 +1305,14 @@ def test_update_deps_1():
             'channel-1::python-2.7.3-7',
             'channel-1::nose-1.3.0-py27_0',
             'channel-1::numpy-1.7.0-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
     specs_to_add = MatchSpec("iopro"),
     with get_solver(specs_to_add, prefix_records=final_state_2, history_specs=specs2) as solver:
         final_state_3a = solver.solve_final_state()
         print(convert_to_dist_str(final_state_3a))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1325,14 +1324,14 @@ def test_update_deps_1():
             'channel-1::nose-1.3.0-py27_0',
             'channel-1::numpy-1.7.0-py27_0',
             'channel-1::iopro-1.5.0-np17py27_p0',
-        )
+        ))
         assert convert_to_dist_str(final_state_3a) == order
 
     specs_to_add = MatchSpec("iopro"),
     with get_solver(specs_to_add, prefix_records=final_state_2, history_specs=specs2) as solver:
         final_state_3 = solver.solve_final_state(update_modifier=UpdateModifier.UPDATE_DEPS)
         pprint(convert_to_dist_str(final_state_3))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1344,7 +1343,7 @@ def test_update_deps_1():
             'channel-1::nose-1.3.0-py27_0',
             'channel-1::numpy-1.7.1-py27_0',  # with update_deps, numpy should switch from 1.7.0 to 1.7.1
             'channel-1::iopro-1.5.0-np17py27_p0',
-        )
+        ))
         assert convert_to_dist_str(final_state_3) == order
 
     specs_to_add = MatchSpec("iopro"),
@@ -1352,7 +1351,7 @@ def test_update_deps_1():
         final_state_3 = solver.solve_final_state(update_modifier=UpdateModifier.UPDATE_DEPS,
                                                  deps_modifier=DepsModifier.ONLY_DEPS)
         pprint(convert_to_dist_str(final_state_3))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::unixodbc-2.3.1-0',
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
@@ -1364,7 +1363,7 @@ def test_update_deps_1():
             'channel-1::nose-1.3.0-py27_0',
             'channel-1::numpy-1.7.1-py27_0',  # with update_deps, numpy should switch from 1.7.0 to 1.7.1
             # 'channel-1::iopro-1.5.0-np17py27_p0',
-        )
+        ))
         assert convert_to_dist_str(final_state_3) == order
 
 
@@ -1373,7 +1372,7 @@ def test_update_deps_2():
     with get_solver_aggregate_2(specs) as solver:
         final_state_1 = solver.solve_final_state()
         pprint(convert_to_dist_str(final_state_1))
-        order1 = (
+        order1 = add_subdir_to_iter((
             'channel-4::ca-certificates-2018.03.07-0',
             'channel-4::libgcc-ng-8.2.0-hdf63c60_0',
             'channel-4::libstdcxx-ng-8.2.0-hdf63c60_0',
@@ -1395,7 +1394,7 @@ def test_update_deps_2():
             'channel-4::setuptools-40.0.0-py36_0',
             'channel-2::jinja2-2.8-py36_1',
             'channel-2::flask-0.12-py36_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order1
 
     # The "conda update flask" case is held back by the jinja2==2.8 user-requested spec.
@@ -1404,12 +1403,12 @@ def test_update_deps_2():
         unlink_precs, link_precs = solver.solve_for_diff()
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
-        unlink_order = (
+        unlink_order = add_subdir_to_iter((
             'channel-2::flask-0.12-py36_0',
-        )
-        link_order = (
+        ))
+        link_order = add_subdir_to_iter((
             'channel-4::flask-0.12.2-py36hb24657c_0',
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -1419,14 +1418,14 @@ def test_update_deps_2():
         unlink_precs, link_precs = solver.solve_for_diff(update_modifier=UpdateModifier.UPDATE_DEPS)
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
-        unlink_order = (
+        unlink_order = add_subdir_to_iter((
             'channel-2::flask-0.12-py36_0',
             'channel-2::jinja2-2.8-py36_1',
-        )
-        link_order = (
+        ))
+        link_order = add_subdir_to_iter((
             'channel-4::jinja2-2.10-py36_0',
             'channel-4::flask-1.0.2-py36_1',
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -1436,7 +1435,7 @@ def test_fast_update_with_update_modifier_not_set():
     with get_solver_4(specs) as solver:
         final_state_1 = solver.solve_final_state()
         pprint(convert_to_dist_str(final_state_1))
-        order1 = (
+        order1 = add_subdir_to_iter((
             'channel-4::ca-certificates-2018.03.07-0',
             'channel-4::libgcc-ng-8.2.0-hdf63c60_0',
             'channel-4::libstdcxx-ng-8.2.0-hdf63c60_0',
@@ -1449,7 +1448,7 @@ def test_fast_update_with_update_modifier_not_set():
             'channel-4::readline-7.0-ha6073c6_4',
             'channel-4::sqlite-3.21.0-h1bed415_2',
             'channel-4::python-2.7.14-h89e7a4a_22',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order1
 
     specs_to_add = MatchSpec("python"),
@@ -1457,19 +1456,19 @@ def test_fast_update_with_update_modifier_not_set():
         unlink_precs, link_precs = solver.solve_for_diff()
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
-        unlink_order = (
+        unlink_order = add_subdir_to_iter((
             'channel-4::python-2.7.14-h89e7a4a_22',
             'channel-4::libedit-3.1-heed3624_0',
             'channel-4::openssl-1.0.2l-h077ae2c_5',
             'channel-4::ncurses-6.0-h9df7e31_2'
-        )
-        link_order = (
+        ))
+        link_order = add_subdir_to_iter((
             'channel-4::ncurses-6.1-hf484d3e_0',
             'channel-4::openssl-1.0.2p-h14c3975_0',
             'channel-4::xz-5.2.4-h14c3975_4',
             'channel-4::libedit-3.1.20170329-h6b74fdf_2',
             'channel-4::python-3.6.4-hc3d631a_1',  # python is upgraded
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -1478,20 +1477,20 @@ def test_fast_update_with_update_modifier_not_set():
         unlink_precs, link_precs = solver.solve_for_diff()
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
-        unlink_order = (
+        unlink_order = add_subdir_to_iter((
             'channel-4::python-2.7.14-h89e7a4a_22',
             'channel-4::sqlite-3.21.0-h1bed415_2',
             'channel-4::libedit-3.1-heed3624_0',
             'channel-4::openssl-1.0.2l-h077ae2c_5',
             'channel-4::ncurses-6.0-h9df7e31_2',
-        )
-        link_order = (
+        ))
+        link_order = add_subdir_to_iter((
             'channel-4::ncurses-6.1-hf484d3e_0',
             'channel-4::openssl-1.0.2p-h14c3975_0',
             'channel-4::libedit-3.1.20170329-h6b74fdf_2',
             'channel-4::sqlite-3.24.0-h84994c4_0',  # sqlite is upgraded
             'channel-4::python-2.7.15-h1571d57_0',  # python is not upgraded
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -1509,7 +1508,7 @@ def test_pinned_1():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         pprint(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1518,7 +1517,7 @@ def test_pinned_1():
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-3.3.2-0',
             'channel-1::numpy-1.7.1-py33_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     with env_var("CONDA_PINNED_PACKAGES", "python=2.6&iopro<=1.4.2", stack_callback=conda_tests_ctxt_mgmt_def_pol):
@@ -1527,9 +1526,9 @@ def test_pinned_1():
             final_state_1 = solver.solve_final_state()
             # PrefixDag(final_state_1, specs).open_url()
             pprint(convert_to_dist_str(final_state_1))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::system-5.8-0',
-            )
+            ))
             assert convert_to_dist_str(final_state_1) == order
 
         # ignore_pinned=True
@@ -1539,7 +1538,7 @@ def test_pinned_1():
             final_state_2 = solver.solve_final_state(ignore_pinned=True)
             # PrefixDag(final_state_1, specs).open_url()
             pprint(convert_to_dist_str(final_state_2))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::openssl-1.0.1c-0',
                 'channel-1::readline-6.2-0',
                 'channel-1::sqlite-3.7.13-0',
@@ -1547,7 +1546,7 @@ def test_pinned_1():
                 'channel-1::tk-8.5.13-0',
                 'channel-1::zlib-1.2.7-0',
                 'channel-1::python-3.3.2-0',
-            )
+            ))
             assert convert_to_dist_str(final_state_2) == order
 
         # ignore_pinned=False
@@ -1557,7 +1556,7 @@ def test_pinned_1():
             final_state_2 = solver.solve_final_state(ignore_pinned=False)
             # PrefixDag(final_state_1, specs).open_url()
             pprint(convert_to_dist_str(final_state_2))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::openssl-1.0.1c-0',
                 'channel-1::readline-6.2-0',
                 'channel-1::sqlite-3.7.13-0',
@@ -1565,7 +1564,7 @@ def test_pinned_1():
                 'channel-1::tk-8.5.13-0',
                 'channel-1::zlib-1.2.7-0',
                 'channel-1::python-2.6.8-6',
-            )
+            ))
             assert convert_to_dist_str(final_state_2) == order
 
         # incompatible CLI and configured specs
@@ -1585,7 +1584,7 @@ def test_pinned_1():
             final_state_3 = solver.solve_final_state()
             # PrefixDag(final_state_1, specs).open_url()
             pprint(convert_to_dist_str(final_state_3))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::openssl-1.0.1c-0',
                 'channel-1::readline-6.2-0',
                 'channel-1::sqlite-3.7.13-0',
@@ -1598,7 +1597,7 @@ def test_pinned_1():
                 'channel-1::llvmpy-0.11.2-py26_0',
                 'channel-1::numpy-1.7.1-py26_0',
                 'channel-1::numba-0.8.1-np17py26_0',
-            )
+            ))
             assert convert_to_dist_str(final_state_3) == order
 
         specs_to_add = MatchSpec("python"),
@@ -1608,7 +1607,7 @@ def test_pinned_1():
             final_state_4 = solver.solve_final_state(update_modifier=UpdateModifier.UPDATE_DEPS)
             # PrefixDag(final_state_1, specs).open_url()
             pprint(convert_to_dist_str(final_state_4))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::openssl-1.0.1c-0',
                 'channel-1::readline-6.2-0',
                 'channel-1::sqlite-3.7.13-0',
@@ -1621,7 +1620,7 @@ def test_pinned_1():
                 'channel-1::llvmpy-0.11.2-py26_0',
                 'channel-1::numpy-1.7.1-py26_0',
                 'channel-1::numba-0.8.1-np17py26_0',
-            )
+            ))
             assert convert_to_dist_str(final_state_4) == order
 
         specs_to_add = MatchSpec("python"),
@@ -1631,7 +1630,7 @@ def test_pinned_1():
             final_state_5 = solver.solve_final_state(update_modifier=UpdateModifier.UPDATE_ALL)
             # PrefixDag(final_state_1, specs).open_url()
             pprint(convert_to_dist_str(final_state_5))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-1::openssl-1.0.1c-0',
                 'channel-1::readline-6.2-0',
                 'channel-1::sqlite-3.7.13-0',
@@ -1644,7 +1643,7 @@ def test_pinned_1():
                 'channel-1::llvmpy-0.11.2-py26_0',
                 'channel-1::numpy-1.7.1-py26_0',
                 'channel-1::numba-0.8.1-np17py26_0',
-            )
+            ))
             assert convert_to_dist_str(final_state_5) == order
 
     # now update without pinning
@@ -1655,7 +1654,7 @@ def test_pinned_1():
         final_state_5 = solver.solve_final_state(update_modifier=UpdateModifier.UPDATE_ALL)
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_5))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1667,7 +1666,7 @@ def test_pinned_1():
             'channel-1::llvmpy-0.11.2-py33_0',
             'channel-1::numpy-1.7.1-py33_0',
             'channel-1::numba-0.8.1-np17py33_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_5) == order
 
 
@@ -1680,7 +1679,7 @@ def test_no_update_deps_1():  # i.e. FREEZE_DEPS
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1688,7 +1687,7 @@ def test_no_update_deps_1():  # i.e. FREEZE_DEPS
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs_to_add = MatchSpec("zope.interface"),
@@ -1696,7 +1695,7 @@ def test_no_update_deps_1():  # i.e. FREEZE_DEPS
         final_state_2 = solver.solve_final_state()
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1706,7 +1705,7 @@ def test_no_update_deps_1():  # i.e. FREEZE_DEPS
             'channel-1::python-2.7.5-0',
             'channel-1::nose-1.3.0-py27_0',
             'channel-1::zope.interface-4.0.5-py27_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
     specs_to_add = MatchSpec("zope.interface>4.1"),
@@ -1720,7 +1719,7 @@ def test_no_update_deps_1():  # i.e. FREEZE_DEPS
         final_state_2 = solver.solve_final_state()
         # PrefixDag(final_state_2, specs).open_url()
         print(convert_to_dist_str(final_state_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1730,7 +1729,7 @@ def test_no_update_deps_1():  # i.e. FREEZE_DEPS
             'channel-1::python-3.3.2-0',
             'channel-1::nose-1.3.0-py33_0',
             'channel-1::zope.interface-4.1.1.1-py33_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_2) == order
 
 
@@ -1740,7 +1739,7 @@ def test_force_reinstall_1():
         final_state_1 = solver.solve_final_state()
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1748,7 +1747,7 @@ def test_force_reinstall_1():
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs_to_add = specs
@@ -1773,7 +1772,7 @@ def test_force_reinstall_2():
         assert not unlink_dists
         # PrefixDag(final_state_1, specs).open_url()
         print(convert_to_dist_str(link_dists))
-        order = (
+        order = add_subdir_to_iter((
             'channel-1::openssl-1.0.1c-0',
             'channel-1::readline-6.2-0',
             'channel-1::sqlite-3.7.13-0',
@@ -1781,7 +1780,7 @@ def test_force_reinstall_2():
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
             'channel-1::python-2.7.5-0',
-        )
+        ))
         assert convert_to_dist_str(link_dists) == order
 
 
@@ -1791,7 +1790,7 @@ def test_timestamps_1():
         unlink_dists, link_dists = solver.solve_for_diff(force_reinstall=True)
         assert not unlink_dists
         pprint(convert_to_dist_str(link_dists))
-        order = (
+        order = add_subdir_to_iter((
             'channel-4::ca-certificates-2018.03.07-0',
             'channel-4::libgcc-ng-8.2.0-hdf63c60_0',
             'channel-4::libstdcxx-ng-8.2.0-hdf63c60_0',
@@ -1806,7 +1805,7 @@ def test_timestamps_1():
             'channel-4::sqlite-3.23.1-he433501_0',
             'channel-4::python-3.6.2-hca45abc_19',  # this package has a later timestamp but lower hash value
                                                     # than the alternate 'channel-4::python-3.6.2-hda45abc_19'
-        )
+        ))
         assert convert_to_dist_str(link_dists) == order
 
 def test_channel_priority_churn_minimized():
@@ -1836,7 +1835,7 @@ def test_remove_with_constrained_dependencies():
         assert not unlink_dists_1
         pprint(convert_to_dist_str(link_dists_1))
         assert not unlink_dists_1
-        order = (
+        order = add_subdir_to_iter((
             'channel-4::ca-certificates-2018.03.07-0',
             'channel-4::conda-env-2.6.0-1',
             'channel-4::libgcc-ng-8.2.0-hdf63c60_0',
@@ -1879,7 +1878,7 @@ def test_remove_with_constrained_dependencies():
             'channel-4::requests-2.19.1-py37_0',
             'channel-4::conda-4.5.10-py37_0',
             'channel-4::conda-build-3.12.1-py37_0',
-        )
+        ))
         assert convert_to_dist_str(link_dists_1) == order
 
     specs_to_remove = MatchSpec("pycosat"),
@@ -1887,11 +1886,11 @@ def test_remove_with_constrained_dependencies():
         unlink_dists_2, link_dists_2 = solver.solve_for_diff()
         assert not link_dists_2
         pprint(convert_to_dist_str(unlink_dists_2))
-        order = (
+        order = add_subdir_to_iter((
             'channel-4::conda-build-3.12.1-py37_0',
             'channel-4::conda-4.5.10-py37_0',
             'channel-4::pycosat-0.6.3-py37h14c3975_0',
-        )
+        ))
         for spec in order:
             assert spec in convert_to_dist_str(unlink_dists_2)
 
@@ -1903,7 +1902,7 @@ def test_priority_1():
             with get_solver_aggregate_1(specs) as solver:
                 final_state_1 = solver.solve_final_state()
                 pprint(convert_to_dist_str(final_state_1))
-                order = (
+                order = add_subdir_to_iter((
                     'channel-2::mkl-2017.0.3-0',
                     'channel-2::openssl-1.0.2l-0',
                     'channel-2::readline-6.2-2',
@@ -1916,7 +1915,7 @@ def test_priority_1():
                     'channel-2::six-1.10.0-py27_0',
                     'channel-2::python-dateutil-2.6.1-py27_0',
                     'channel-2::pandas-0.20.3-py27_0',
-                )
+                ))
                 assert convert_to_dist_str(final_state_1) == order
 
         with env_var("CONDA_CHANNEL_PRIORITY", "False", stack_callback=conda_tests_ctxt_mgmt_def_pol):
@@ -1926,10 +1925,10 @@ def test_priority_1():
                 pprint(convert_to_dist_str(final_state_2))
                 # python and pandas will be updated as they are explicit specs.  Other stuff may or may not,
                 #     as required to satisfy python and pandas
-                order = (
+                order = add_subdir_to_iter((
                     'channel-4::python-2.7.15-h1571d57_0',
                     'channel-4::pandas-0.23.4-py27h04863e7_0',
-                )
+                ))
                 for spec in order:
                     assert spec in convert_to_dist_str(final_state_2)
 
@@ -1940,10 +1939,10 @@ def test_priority_1():
                                     history_specs=specs) as solver:
             final_state_3 = solver.solve_final_state()
             pprint(convert_to_dist_str(final_state_3))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-2::python-2.7.13-0',
                 'channel-2::pandas-0.20.3-py27_0',
-            )
+            ))
             for spec in order:
                 assert spec in convert_to_dist_str(final_state_3)
 
@@ -1953,10 +1952,10 @@ def test_priority_1():
                                     prefix_records=final_state_3, history_specs=specs) as solver:
             final_state_4 = solver.solve_final_state()
             pprint(convert_to_dist_str(final_state_4))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-2::python-2.7.13-0',
                 'channel-2::six-1.9.0-py27_0',
-            )
+            ))
             for spec in order:
                 assert spec in convert_to_dist_str(final_state_4)
             assert 'pandas' not in convert_to_dist_str(final_state_4)
@@ -1971,7 +1970,7 @@ def test_features_solve_1():
         with get_solver_aggregate_1(specs) as solver:
             final_state_1 = solver.solve_final_state()
             pprint(convert_to_dist_str(final_state_1))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-2::nomkl-1.0-0',
                 'channel-2::libgfortran-3.0.0-1',
                 'channel-2::openssl-1.0.2l-0',
@@ -1982,14 +1981,14 @@ def test_features_solve_1():
                 'channel-2::openblas-0.2.19-0',
                 'channel-2::python-2.7.13-0',
                 'channel-2::numpy-1.13.1-py27_nomkl_0',
-            )
+            ))
             assert convert_to_dist_str(final_state_1) == order
 
     with env_var("CONDA_CHANNEL_PRIORITY", "False", stack_callback=conda_tests_ctxt_mgmt_def_pol):
         with get_solver_aggregate_1(specs) as solver:
             final_state_1 = solver.solve_final_state()
             pprint(convert_to_dist_str(final_state_1))
-            order = (
+            order = add_subdir_to_iter((
                 'channel-4::blas-1.0-openblas',
                 'channel-4::ca-certificates-2018.03.07-0',
                 'channel-2::libffi-3.2.1-1',
@@ -2008,7 +2007,7 @@ def test_features_solve_1():
                 'channel-4::python-2.7.15-h1571d57_0',
                 'channel-4::numpy-base-1.15.0-py27h7cdd4dd_0',
                 'channel-4::numpy-1.15.0-py27h2aefc1b_0',
-            )
+            ))
             assert convert_to_dist_str(final_state_1) == order
 
 
@@ -2018,7 +2017,7 @@ def test_freeze_deps_1():
     with get_solver_2(specs) as solver:
         final_state_1 = solver.solve_final_state()
         pprint(convert_to_dist_str(final_state_1))
-        order = (
+        order = add_subdir_to_iter((
             'channel-2::openssl-1.0.2l-0',
             'channel-2::readline-6.2-2',
             'channel-2::sqlite-3.13.0-0',
@@ -2027,7 +2026,7 @@ def test_freeze_deps_1():
             'channel-2::zlib-1.2.11-0',
             'channel-2::python-3.4.5-0',
             'channel-2::six-1.7.3-py34_0',
-        )
+        ))
         assert convert_to_dist_str(final_state_1) == order
 
     specs_to_add = MatchSpec("bokeh"),
@@ -2036,7 +2035,7 @@ def test_freeze_deps_1():
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
         unlink_order = ()
-        link_order = (
+        link_order = add_subdir_to_iter((
             'channel-2::mkl-2017.0.3-0',
             'channel-2::yaml-0.1.6-0',
             'channel-2::backports_abc-0.5-py34_0',
@@ -2049,7 +2048,7 @@ def test_freeze_deps_1():
             'channel-2::python-dateutil-2.6.1-py34_0',
             'channel-2::tornado-4.4.2-py34_0',
             'channel-2::bokeh-0.12.4-py34_0',
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -2061,7 +2060,7 @@ def test_freeze_deps_1():
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
         unlink_order = ()
-        link_order = (
+        link_order = add_subdir_to_iter((
             'channel-2::mkl-2017.0.3-0',
             'channel-2::yaml-0.1.6-0',
             'channel-2::backports_abc-0.5-py34_0',
@@ -2074,7 +2073,7 @@ def test_freeze_deps_1():
             'channel-2::python-dateutil-2.6.1-py34_0',
             'channel-2::tornado-4.4.2-py34_0',
             'channel-2::bokeh-0.12.4-py34_0',
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -2095,12 +2094,12 @@ def test_freeze_deps_1():
         unlink_precs, link_precs = solver.solve_for_diff()
         pprint(convert_to_dist_str(unlink_precs))
         pprint(convert_to_dist_str(link_precs))
-        unlink_order = (
+        unlink_order = add_subdir_to_iter((
             'channel-2::six-1.7.3-py34_0',
             'channel-2::python-3.4.5-0',
             'channel-2::xz-5.2.3-0',
-        )
-        link_order = (
+        ))
+        link_order = add_subdir_to_iter((
             'channel-2::mkl-2017.0.3-0',
             'channel-2::yaml-0.1.6-0',
             'channel-2::python-2.7.13-0',
@@ -2120,7 +2119,7 @@ def test_freeze_deps_1():
             'channel-2::jinja2-2.9.6-py27_0',
             'channel-2::tornado-4.5.2-py27_0',
             'channel-2::bokeh-0.12.5-py27_1',
-        )
+        ))
         assert convert_to_dist_str(unlink_precs) == unlink_order
         assert convert_to_dist_str(link_precs) == link_order
 
@@ -2243,7 +2242,7 @@ def test_downgrade_python_prevented_with_sane_message():
         final_state_1 = solver.solve_final_state()
     # PrefixDag(final_state_1, specs).open_url()
     pprint(convert_to_dist_str(final_state_1))
-    order = (
+    order = add_subdir_to_iter((
         'channel-1::openssl-1.0.1c-0',
         'channel-1::readline-6.2-0',
         'channel-1::sqlite-3.7.13-0',
@@ -2251,7 +2250,7 @@ def test_downgrade_python_prevented_with_sane_message():
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
         'channel-1::python-2.6.8-6',
-    )
+    ))
     assert convert_to_dist_str(final_state_1) == order
 
     # incompatible CLI and configured specs
diff --git a/tests/helpers.py b/tests/helpers.py
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -111,6 +111,25 @@ def run_inprocess_conda_command(command, disallow_stderr=True):
     return c.stdout, c.stderr, exit_code
 
 
+def add_subdir(dist_string):
+    channel_str, package_str = dist_string.split('::')
+    channel_str = channel_str + '/' +  context.subdir
+    return '::'.join([channel_str, package_str])
+
+
+def add_subdir_to_iter(iterable):
+    if isinstance(iterable, dict):
+        return {add_subdir(k) : v for k, v in iterable.items()}
+    elif isinstance(iterable, list):
+        return list(map(add_subdir, iterable))
+    elif isinstance(iterable, set):
+        return set(map(add_subdir, iterable))
+    elif isinstance(iterable, tuple):
+        return tuple(map(add_subdir, iterable))
+    else:
+        raise Exception("Unable to add subdir to object of unknown type.")
+
+
 @contextmanager
 def tempdir():
     tempdirdir = gettempdir()
diff --git a/tests/models/test_prefix_graph.py b/tests/models/test_prefix_graph.py
--- a/tests/models/test_prefix_graph.py
+++ b/tests/models/test_prefix_graph.py
@@ -13,6 +13,7 @@
 from conda.models.records import PackageRecord
 import pytest
 from tests.core.test_solve import get_solver_4, get_solver_5
+from tests.helpers import add_subdir_to_iter
 
 try:
     from unittest.mock import Mock, patch
@@ -218,17 +219,17 @@ def test_prefix_graph_1():
     )
     assert nodes == order
 
-    spec_matches = {
+    spec_matches = add_subdir_to_iter({
         'channel-4::intel-openmp-2018.0.3-0': {'intel-openmp'},
-    }
+    })
     assert {node.dist_str(): set(str(ms) for ms in specs) for node, specs in graph.spec_matches.items()} == spec_matches
 
     removed_nodes = graph.prune()
     nodes = tuple(rec.dist_str() for rec in graph.records)
     pprint(nodes)
-    order = (
+    order = add_subdir_to_iter((
         'channel-4::intel-openmp-2018.0.3-0',
-    )
+    ))
     assert nodes == order
 
     removed_nodes = tuple(rec.name for rec in removed_nodes)
diff --git a/tests/test_resolve.py b/tests/test_resolve.py
--- a/tests/test_resolve.py
+++ b/tests/test_resolve.py
@@ -16,7 +16,7 @@
 from conda.models.enums import PackageType
 from conda.models.records import PackageRecord
 from conda.resolve import MatchSpec, Resolve, ResolvePackageNotFound
-from .helpers import TEST_DATA_DIR, get_index_r_1, get_index_r_4, raises
+from .helpers import TEST_DATA_DIR, add_subdir, add_subdir_to_iter, get_index_r_1, get_index_r_4, raises
 
 index, r, = get_index_r_1()
 f_mkl = set(['mkl'])
@@ -66,7 +66,7 @@ def test_empty(self):
     def test_iopro_nomkl(self):
         installed = r.install(['iopro 1.4*', 'python 2.7*', 'numpy 1.7*'], returnall=True)
         installed = [rec.dist_str() for rec in installed]
-        assert installed == [
+        assert installed == add_subdir_to_iter([
             'channel-1::iopro-1.4.3-np17py27_p0',
             'channel-1::numpy-1.7.1-py27_0',
             'channel-1::openssl-1.0.1c-0',
@@ -77,12 +77,12 @@ def test_iopro_nomkl(self):
             'channel-1::tk-8.5.13-0',
             'channel-1::unixodbc-2.3.1-0',
             'channel-1::zlib-1.2.7-0',
-        ]
+        ])
 
     def test_iopro_mkl(self):
         installed = r.install(['iopro 1.4*', 'python 2.7*', 'numpy 1.7*', MatchSpec(track_features='mkl')], returnall=True)
         installed = [prec.dist_str() for prec in installed]
-        assert installed == [
+        assert installed == add_subdir_to_iter([
             'channel-1::iopro-1.4.3-np17py27_p0',
             'channel-1::mkl-rt-11.0-p0',
             'channel-1::numpy-1.7.1-py27_p0',
@@ -94,7 +94,7 @@ def test_iopro_mkl(self):
             'channel-1::tk-8.5.13-0',
             'channel-1::unixodbc-2.3.1-0',
             'channel-1::zlib-1.2.7-0',
-        ]
+        ])
 
     def test_mkl(self):
         a = r.install(['mkl 11*', MatchSpec(track_features='mkl')])
@@ -110,13 +110,13 @@ def test_scipy_mkl(self):
         precs = r.install(['scipy', 'python 2.7*', 'numpy 1.7*', MatchSpec(track_features='mkl')])
         self.assert_have_mkl(precs, ('numpy', 'scipy'))
         dist_strs = [prec.dist_str() for prec in precs]
-        assert 'channel-1::scipy-0.12.0-np17py27_p0' in dist_strs
+        assert add_subdir('channel-1::scipy-0.12.0-np17py27_p0') in dist_strs
 
     def test_anaconda_nomkl(self):
         precs = r.install(['anaconda 1.5.0', 'python 2.7*', 'numpy 1.7*'])
         assert len(precs) == 107
         dist_strs = [prec.dist_str() for prec in precs]
-        assert 'channel-1::scipy-0.12.0-np17py27_0' in dist_strs
+        assert add_subdir('channel-1::scipy-0.12.0-np17py27_0') in dist_strs
 
 
 def test_generate_eq_1():
@@ -140,7 +140,7 @@ def test_generate_eq_1():
     eqb = {key: value for key, value in iteritems(eqb)}
     eqt = {key: value for key, value in iteritems(eqt)}
     assert eqc == {}
-    assert eqv == {
+    assert eqv == add_subdir_to_iter({
         'channel-1::anaconda-1.4.0-np15py27_0': 1,
         'channel-1::anaconda-1.4.0-np16py27_0': 1,
         'channel-1::anaconda-1.4.0-np17py27_0': 1,
@@ -215,8 +215,8 @@ def test_generate_eq_1():
         'channel-1::xlrd-0.9.0-py27_0': 1,
         'channel-1::xlrd-0.9.0-py33_0': 1,
         'channel-1::xlwt-0.7.4-py27_0': 1
-    }
-    assert eqb == {
+    })
+    assert eqb == add_subdir_to_iter({
         'channel-1::cubes-0.10.2-py27_0': 1,
         'channel-1::dateutil-2.1-py27_0': 1,
         'channel-1::dateutil-2.1-py33_0': 1,
@@ -244,7 +244,7 @@ def test_generate_eq_1():
         'channel-1::theano-0.5.0-np16py27_0': 1,
         'channel-1::theano-0.5.0-np17py27_0': 1,
         'channel-1::zeromq-2.2.0-0': 1
-    }
+    })
 
     # No timestamps in the current data set
     assert eqt == {}
@@ -254,7 +254,7 @@ def test_pseudo_boolean():
     # The latest version of iopro, 1.5.0, was not built against numpy 1.5
     installed = r.install(['iopro', 'python 2.7*', 'numpy 1.5*'], returnall=True)
     installed = [rec.dist_str() for rec in installed]
-    assert installed == [
+    assert installed == add_subdir_to_iter([
         'channel-1::iopro-1.4.3-np15py27_p0',
         'channel-1::numpy-1.5.1-py27_4',
         'channel-1::openssl-1.0.1c-0',
@@ -265,11 +265,11 @@ def test_pseudo_boolean():
         'channel-1::tk-8.5.13-0',
         'channel-1::unixodbc-2.3.1-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     installed = r.install(['iopro', 'python 2.7*', 'numpy 1.5*', MatchSpec(track_features='mkl')], returnall=True)
     installed = [rec.dist_str() for rec in installed]
-    assert installed == [
+    assert installed == add_subdir_to_iter([
         'channel-1::iopro-1.4.3-np15py27_p0',
         'channel-1::mkl-rt-11.0-p0',
         'channel-1::numpy-1.5.1-py27_p4',
@@ -281,14 +281,14 @@ def test_pseudo_boolean():
         'channel-1::tk-8.5.13-0',
         'channel-1::unixodbc-2.3.1-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
 
 def test_get_dists():
     reduced_index = r.get_reduced_index((MatchSpec("anaconda 1.4.0"), ))
     dist_strs = [prec.dist_str() for prec in reduced_index]
-    assert 'channel-1::anaconda-1.4.0-np17py27_0' in dist_strs
-    assert 'channel-1::freetype-2.4.10-0' in dist_strs
+    assert add_subdir('channel-1::anaconda-1.4.0-np17py27_0') in dist_strs
+    assert add_subdir('channel-1::freetype-2.4.10-0') in dist_strs
 
 
 def test_get_reduced_index_unmanageable():
@@ -643,11 +643,11 @@ def test_nonexistent_deps():
     index2 = {key: value for key, value in iteritems(index2)}
     r = Resolve(index2)
 
-    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('mypackage'))) == {
+    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('mypackage'))) == add_subdir_to_iter({
         'defaults::mypackage-1.0-py33_0',
         'defaults::mypackage-1.1-py33_0',
-    }
-    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('mypackage'), ))) == {
+    })
+    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('mypackage'), ))) == add_subdir_to_iter({
         'defaults::mypackage-1.1-py33_0',
         'channel-1::nose-1.1.2-py33_0',
         'channel-1::nose-1.2.1-py33_0',
@@ -666,12 +666,12 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    }
+    })
 
     target_result = r.install(['mypackage'])
     assert target_result == r.install(['mypackage 1.1'])
     target_result = [rec.dist_str() for rec in target_result]
-    assert target_result == [
+    assert target_result == add_subdir_to_iter([
         'defaults::mypackage-1.1-py33_0',
         'channel-1::nose-1.3.0-py33_0',
         'channel-1::openssl-1.0.1c-0',
@@ -681,13 +681,13 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
     assert raises(ResolvePackageNotFound, lambda: r.install(['mypackage 1.0']))
     assert raises(ResolvePackageNotFound, lambda: r.install(['mypackage 1.0', 'burgertime 1.0']))
 
     target_result = r.install(['anotherpackage 1.0'])
     target_result = [rec.dist_str() for rec in target_result]
-    assert target_result == [
+    assert target_result == add_subdir_to_iter([
         'defaults::anotherpackage-1.0-py33_0',
         'defaults::mypackage-1.1-py33_0',
         'channel-1::nose-1.3.0-py33_0',
@@ -698,11 +698,11 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     target_result = r.install(['anotherpackage'])
     target_result = [rec.dist_str() for rec in target_result]
-    assert target_result == [
+    assert target_result == add_subdir_to_iter([
         'defaults::anotherpackage-2.0-py33_0',
         'defaults::mypackage-1.1-py33_0',
         'channel-1::nose-1.3.0-py33_0',
@@ -713,7 +713,7 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     # This time, the latest version is messed up
     index3 = index.copy()
@@ -769,11 +769,12 @@ def test_nonexistent_deps():
     index3 = {key: value for key, value in iteritems(index3)}
     r = Resolve(index3)
 
-    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('mypackage'))) == {
+    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('mypackage'))) == add_subdir_to_iter({
         'defaults::mypackage-1.0-py33_0',
         'defaults::mypackage-1.1-py33_0',
-        }
-    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('mypackage'), )).keys()) == {
+        })
+    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('mypackage'), )).keys()) ==\
+           add_subdir_to_iter({
         'defaults::mypackage-1.0-py33_0',
         'channel-1::nose-1.1.2-py33_0',
         'channel-1::nose-1.2.1-py33_0',
@@ -792,11 +793,11 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    }
+    })
 
     target_result = r.install(['mypackage'])
     target_result = [rec.dist_str() for rec in target_result]
-    assert target_result == [
+    assert target_result == add_subdir_to_iter([
         'defaults::mypackage-1.0-py33_0',
         'channel-1::nose-1.3.0-py33_0',
         'channel-1::openssl-1.0.1c-0',
@@ -806,12 +807,12 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
     assert raises(ResolvePackageNotFound, lambda: r.install(['mypackage 1.1']))
 
     target_result = r.install(['anotherpackage 1.0'])
     target_result = [rec.dist_str() for rec in target_result]
-    assert target_result == [
+    assert target_result == add_subdir_to_iter([
         'defaults::anotherpackage-1.0-py33_0',
         'defaults::mypackage-1.0-py33_0',
         'channel-1::nose-1.3.0-py33_0',
@@ -822,13 +823,13 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     # If recursive checking is working correctly, this will give
     # anotherpackage 2.0, not anotherpackage 1.0
     target_result = r.install(['anotherpackage'])
     target_result = [rec.dist_str() for rec in target_result]
-    assert target_result == [
+    assert target_result == add_subdir_to_iter([
         'defaults::anotherpackage-2.0-py33_0',
         'defaults::mypackage-1.0-py33_0',
         'channel-1::nose-1.3.0-py33_0',
@@ -839,7 +840,7 @@ def test_nonexistent_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
 
 def test_install_package_with_feature():
@@ -929,20 +930,20 @@ def test_circular_dependencies():
     index2 = {key: value for key, value in iteritems(index2)}
     r = Resolve(index2)
 
-    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('package1'))) == {
+    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('package1'))) == add_subdir_to_iter({
         'defaults::package1-1.0-0',
-    }
-    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('package1'), )).keys()) == {
+    })
+    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('package1'), )).keys()) == add_subdir_to_iter({
         'defaults::package1-1.0-0',
         'defaults::package2-1.0-0',
-    }
+    })
     result = r.install(['package1', 'package2'])
     assert r.install(['package1']) == r.install(['package2']) == result
     result = [r.dist_str() for r in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'defaults::package1-1.0-0',
         'defaults::package2-1.0-0',
-    ]
+    ])
 
 
 def test_optional_dependencies():
@@ -987,25 +988,25 @@ def test_optional_dependencies():
     index2 = {key: value for key, value in iteritems(index2)}
     r = Resolve(index2)
 
-    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('package1'))) == {
+    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('package1'))) == add_subdir_to_iter({
         'defaults::package1-1.0-0',
-    }
-    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('package1'), )).keys()) == {
+    })
+    assert set(prec.dist_str() for prec in r.get_reduced_index((MatchSpec('package1'), )).keys()) == add_subdir_to_iter({
         'defaults::package1-1.0-0',
         'defaults::package2-2.0-0',
-    }
+    })
     result = r.install(['package1'])
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'defaults::package1-1.0-0',
-    ]
+    ])
     result = r.install(['package1', 'package2'])
     assert result == r.install(['package1', 'package2 >1.0'])
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'defaults::package1-1.0-0',
         'defaults::package2-2.0-0',
-    ]
+    ])
     assert raises(UnsatisfiableError, lambda: r.install(['package1', 'package2 <2.0']))
     assert raises(UnsatisfiableError, lambda: r.install(['package1', 'package2 1.0']))
 
@@ -1013,7 +1014,7 @@ def test_optional_dependencies():
 def test_irrational_version():
     result = r.install(['pytz 2012d', 'python 3*'], returnall=True)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::openssl-1.0.1c-0',
         'channel-1::python-3.3.2-0',
         'channel-1::pytz-2012d-py33_0',
@@ -1022,14 +1023,14 @@ def test_irrational_version():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
 
 def test_no_features():
     # Without this, there would be another solution including 'scipy-0.11.0-np16py26_p3.tar.bz2'.
     result = r.install(['python 2.6*', 'numpy 1.6*', 'scipy 0.11*'], returnall=True)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::numpy-1.6.2-py26_4',
         'channel-1::openssl-1.0.1c-0',
         'channel-1::python-2.6.8-6',
@@ -1039,11 +1040,11 @@ def test_no_features():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     result = r.install(['python 2.6*', 'numpy 1.6*', 'scipy 0.11*', MatchSpec(track_features='mkl')], returnall=True)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::mkl-rt-11.0-p0',           # This,
         'channel-1::numpy-1.6.2-py26_p4',      # this,
         'channel-1::openssl-1.0.1c-0',
@@ -1054,7 +1055,7 @@ def test_no_features():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     index2 = index.copy()
     pandas = PackageRecord(**{
@@ -1110,7 +1111,7 @@ def test_no_features():
     # of the specs directly have mkl versions)
     result = r2.solve(['pandas 0.12.0 np16py27_0', 'python 2.7*'], returnall=True)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::numpy-1.6.2-py27_4',
         'channel-1::openssl-1.0.1c-0',
@@ -1123,11 +1124,11 @@ def test_no_features():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     result = r2.solve(['pandas 0.12.0 np16py27_0', 'python 2.7*', MatchSpec(track_features='mkl')], returnall=True)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::mkl-rt-11.0-p0',           # This
         'channel-1::numpy-1.6.2-py27_p5',      # and this are different.
@@ -1141,13 +1142,13 @@ def test_no_features():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
 
 def test_broken_install():
     installed = r.install(['pandas', 'python 2.7*', 'numpy 1.6*'])
     _installed = [rec.dist_str() for rec in installed]
-    assert _installed == [
+    assert _installed == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::numpy-1.6.2-py27_4',
         'channel-1::openssl-1.0.1c-0',
@@ -1161,7 +1162,7 @@ def test_broken_install():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     # Add an incompatible numpy; installation should be untouched
     installed1 = list(installed)
@@ -1210,7 +1211,7 @@ def test_pip_depends_removed_on_inconsistent_env():
 def test_remove():
     installed = r.install(['pandas', 'python 2.7*'])
     _installed = [rec.dist_str() for rec in installed]
-    assert _installed == [
+    assert _installed == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::numpy-1.7.1-py27_0',
         'channel-1::openssl-1.0.1c-0',
@@ -1224,11 +1225,11 @@ def test_remove():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     result = r.remove(['pandas'], installed=installed)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::numpy-1.7.1-py27_0',
         'channel-1::openssl-1.0.1c-0',
@@ -1241,12 +1242,12 @@ def test_remove():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     # Pandas requires numpy
     result = r.remove(['numpy'], installed=installed)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::openssl-1.0.1c-0',
         'channel-1::python-2.7.5-0',
@@ -1257,7 +1258,7 @@ def test_remove():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
 
 def test_channel_priority_1():
@@ -1327,7 +1328,7 @@ def test_channel_priority_2():
         eqc, eqv, eqb, eqa, eqt = r2.generate_version_metrics(C, list(r2.groups.keys()))
         eqc = {key: value for key, value in iteritems(eqc)}
         pprint(eqc)
-        assert eqc == {
+        assert eqc == add_subdir_to_iter({
             'channel-4::mkl-2017.0.4-h4c4d0af_0': 1,
             'channel-4::mkl-2018.0.0-hb491cac_4': 1,
             'channel-4::mkl-2018.0.1-h19d6760_4': 1,
@@ -1451,10 +1452,10 @@ def test_channel_priority_2():
             'channel-4::tk-8.6.7-hc745277_3': 1,
             'channel-4::zlib-1.2.11-ha838bed_2': 1,
             'channel-4::zlib-1.2.11-hfbfcf68_1': 1,
-        }
+        })
         installed_w_priority = [prec.dist_str() for prec in this_r.install(spec)]
         pprint(installed_w_priority)
-        assert installed_w_priority == [
+        assert installed_w_priority == add_subdir_to_iter([
             'channel-1::dateutil-2.1-py27_1',
             'channel-1::numpy-1.7.1-py27_0',
             'channel-1::openssl-1.0.1c-0',
@@ -1468,7 +1469,7 @@ def test_channel_priority_2():
             'channel-1::system-5.8-1',
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
-        ]
+        ])
 
     # setting strict actually doesn't do anything here; just ensures it's not 'disabled'
     with env_var("CONDA_CHANNEL_PRIORITY", "strict", stack_callback=conda_tests_ctxt_mgmt_def_pol):
@@ -1480,7 +1481,7 @@ def test_channel_priority_2():
         eqc = {key: value for key, value in iteritems(eqc)}
         assert eqc == {}, eqc
         installed_w_strict = [prec.dist_str() for prec in this_r.install(spec)]
-        assert installed_w_strict == [
+        assert installed_w_strict == add_subdir_to_iter([
             'channel-1::dateutil-2.1-py27_1',
             'channel-1::numpy-1.7.1-py27_0',
             'channel-1::openssl-1.0.1c-0',
@@ -1494,7 +1495,7 @@ def test_channel_priority_2():
             'channel-1::system-5.8-1',
             'channel-1::tk-8.5.13-0',
             'channel-1::zlib-1.2.7-0',
-        ], installed_w_strict
+        ]), installed_w_strict
 
     with env_var("CONDA_CHANNEL_PRIORITY", "False", stack_callback=conda_tests_ctxt_mgmt_def_pol):
         dists = this_r.get_reduced_index(spec)
@@ -1503,7 +1504,7 @@ def test_channel_priority_2():
         eqc, eqv, eqb, eqa, eqt = r2.generate_version_metrics(C, list(r2.groups.keys()))
         eqc = {key: value for key, value in iteritems(eqc)}
         pprint(eqc)
-        assert eqc == {
+        assert eqc == add_subdir_to_iter({
             'channel-1::dateutil-1.5-py27_0': 1,
             'channel-1::mkl-10.3-0': 6,
             'channel-1::mkl-10.3-p1': 6,
@@ -1757,10 +1758,10 @@ def test_channel_priority_2():
             'channel-4::sqlite-3.21.0-h1bed415_2': 3,
             'channel-4::sqlite-3.22.0-h1bed415_0': 2,
             'channel-4::sqlite-3.23.1-he433501_0': 1,
-        }
+        })
         installed_wo_priority = set([prec.dist_str() for prec in this_r.install(spec)])
         pprint(installed_wo_priority)
-        assert installed_wo_priority == {
+        assert installed_wo_priority == add_subdir_to_iter({
             'channel-4::blas-1.0-mkl',
             'channel-4::ca-certificates-2018.03.07-0',
             'channel-4::intel-openmp-2018.0.3-0',
@@ -1785,7 +1786,7 @@ def test_channel_priority_2():
             'channel-4::sqlite-3.24.0-h84994c4_0',
             'channel-4::tk-8.6.7-hc745277_3',
             'channel-4::zlib-1.2.11-ha838bed_2',
-        }
+        })
 
 
 def test_dependency_sort():
@@ -1794,7 +1795,7 @@ def test_dependency_sort():
     must_have = {prec.name: prec for prec in installed}
     installed = r.dependency_sort(must_have)
 
-    results_should_be = [
+    results_should_be = add_subdir_to_iter([
         'channel-1::openssl-1.0.1c-0',
         'channel-1::readline-6.2-0',
         'channel-1::sqlite-3.7.13-0',
@@ -1808,7 +1809,7 @@ def test_dependency_sort():
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::scipy-0.12.0-np16py27_0',
         'channel-1::pandas-0.11.0-np16py27_1'
-    ]
+    ])
     assert len(installed) == len(results_should_be)
     assert [prec.dist_str() for prec in installed] == results_should_be
 
@@ -1816,7 +1817,7 @@ def test_dependency_sort():
 def test_update_deps():
     installed = r.install(['python 2.7*', 'numpy 1.6*', 'pandas 0.10.1'])
     result = [rec.dist_str() for rec in installed]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::numpy-1.6.2-py27_4',
         'channel-1::openssl-1.0.1c-0',
@@ -1829,14 +1830,14 @@ def test_update_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     # scipy, and pandas should all be updated here. pytz is a new
     # dependency of pandas. But numpy does not _need_ to be updated
     # to get the latest version of pandas, so it stays put.
     result = r.install(['pandas', 'python 2.7*'], installed=installed, update_deps=True, returnall=True)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::numpy-1.6.2-py27_4',
         'channel-1::openssl-1.0.1c-0',
@@ -1850,13 +1851,13 @@ def test_update_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
     # pandas should be updated here. However, it's going to try to not update
     # scipy, so it won't be updated to the latest version (0.11.0).
     result = r.install(['pandas', 'python 2.7*'], installed=installed, update_deps=False, returnall=True)
     result = [rec.dist_str() for rec in result]
-    assert result == [
+    assert result == add_subdir_to_iter([
         'channel-1::dateutil-2.1-py27_1',
         'channel-1::numpy-1.6.2-py27_4',
         'channel-1::openssl-1.0.1c-0',
@@ -1869,7 +1870,7 @@ def test_update_deps():
         'channel-1::system-5.8-1',
         'channel-1::tk-8.5.13-0',
         'channel-1::zlib-1.2.7-0',
-    ]
+    ])
 
 
 def test_surplus_features_1():
@@ -2048,6 +2049,51 @@ def test_get_reduced_index_broadening_preferred_solution():
             assert d.version == '2.5', "bottom version should be 2.5, but is {}".format(d.version)
 
 
+def test_arch_preferred_when_otherwise_identical_dependencies():
+    index2 = index.copy()
+    package1_noarch = PackageRecord(**{
+        "channel": "defaults",
+        "subdir": "noarch",
+        "md5": "0123456789",
+        "fn": "doesnt-matter-here",
+        'build': '0',
+        'build_number': 0,
+        'depends': [],
+        'name': 'package1',
+        'requires': [],
+        'version': '1.0',
+    })
+    index2[package1_noarch] = package1_noarch
+    package1_linux64 = PackageRecord(**{
+        "channel": "defaults",
+        "subdir": context.subdir,
+        "md5": "0123456789",
+        "fn": "doesnt-matter-here",
+        'build': '0',
+        'build_number': 0,
+        'depends': [],
+        'name': 'package1',
+        'requires': [],
+        'version': '1.0',
+    })
+    index2[package1_linux64] = package1_linux64
+    index2 = {key: value for key, value in iteritems(index2)}
+    r = Resolve(index2)
+
+    matches = r.find_matches(MatchSpec('package1'))
+    assert len(matches) == 2
+    assert set(prec.dist_str() for prec in r.find_matches(MatchSpec('package1'))) == {
+        'defaults/noarch::package1-1.0-0',
+        add_subdir('defaults::package1-1.0-0')
+    }
+
+    result = r.install(['package1'])
+    result = [rec.dist_str() for rec in result]
+    assert result == [
+        add_subdir('defaults::package1-1.0-0'),
+    ]
+
+
 def test_arch_preferred_over_noarch_when_otherwise_equal():
     index = (
         PackageRecord(**{