Repository: jnothman/searchgrid

Issue:
default Pipeline step's grid gets assigned to alternative steps
The final assertion here fails:
```python
    lr = set_grid(LogisticRegression(), C=[1, 2, 3])
    svc = SVC()
    grid = build_param_grid(set_grid(Pipeline([('root', lr)]), root=[lr, svc]))

    assert len(grid) == 2

    assert lr in grid[0]['root']
    assert svc not in grid[0]['root']
    assert 'root__C' in grid[0]

    assert svc in grid[1]['root']
    assert lr not in grid[1]['root']
    assert 'root__C' not in grid[1]
```

Discussion:

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..72316db
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,4 @@
+## v0.2
+
+- Fixed a bug where the grid of the default estimator in a Pipeline step was
+  attributed to alternatives for that step. :issue:`10`.
diff --git a/README.rst b/README.rst
index e57dd0d..19c83ea 100644
--- a/README.rst
+++ b/README.rst
@@ -152,7 +152,7 @@ Searching over multiple grids.
         ...                 reduce=[kbest, pca])
         >>> gs = make_grid_search(pipe)
 
-.. |py-versions| image:: https://img.shields.io/pypi/pyversions/Django.svg
+.. |py-versions| image:: https://img.shields.io/pypi/pyversions/searchgrid.svg
     :alt: Python versions supported
 
 .. |version| image:: https://badge.fury.io/py/searchgrid.svg
diff --git a/doc/conf.py b/doc/conf.py
index c87eea2..16b8340 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -41,6 +41,7 @@ extensions = [
     'numpydoc',
     'sphinx.ext.ifconfig',
     'sphinx.ext.viewcode',
+    'sphinx_issues',
 ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -65,8 +66,8 @@ copyright = u'2017, Joel Nothman'
 #
 # The short X.Y version.
 
-version = '0.1'
-release = '0.1a1'
+version = '0.1.1'
+release = '0.1.1'
 
 # version = searchgrid.__version__
 # The full version, including alpha/beta/rc tags.
diff --git a/doc/index.rst b/doc/index.rst
index 5ea5fde..197487b 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -5,3 +5,8 @@ API Reference
 
 .. automodule:: searchgrid
    :members:
+
+Changelog
+.........
+
+.. include:: ../README.rst
diff --git a/doc/requirements.txt b/doc/requirements.txt
index a58ea28..100a1f5 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -2,3 +2,4 @@ numpy
 scipy
 scikit-learn
 numpydoc
+sphinx-issues
diff --git a/searchgrid.py b/searchgrid.py
index bbe4862..753a2a7 100644
--- a/searchgrid.py
+++ b/searchgrid.py
@@ -48,8 +48,16 @@ def _build_param_grid(estimator):
     # handle estimator parameters having their own grids
     for param_name, value in estimator.get_params().items():
         if '__' not in param_name and hasattr(value, 'get_params'):
-            grid = _update_grid(grid, _build_param_grid(value),
-                                param_name + '__')
+            out = []
+            value_grid = _build_param_grid(value)
+            for sub_grid in grid:
+                if param_name in sub_grid:
+                    sub_grid = [sub_grid]
+                else:
+                    sub_grid = _update_grid([sub_grid], value_grid,
+                                            param_name + '__')
+                out.extend(sub_grid)
+            grid = out
 
     # handle grid values having their own grids
     out = []
diff --git a/setup.py b/setup.py
index 7cdb90a..f2d609c 100644
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@ def setup_package():
     try:
         # See setup.cfg
         setup(name='searchgrid',
-              version='0.1a1',
+              version='0.1.1',
               py_modules=['searchgrid'],
               setup_requires=['pytest-runner'],
               tests_require=['pytest>=2.7', 'pytest-cov~=2.4'],


Test patch:
diff --git a/test_searchgrid.py b/test_searchgrid.py
index 242b268..4f31d04 100644
--- a/test_searchgrid.py
+++ b/test_searchgrid.py
@@ -48,6 +48,22 @@ def test_build_param_grid_set_estimator():
     assert build_param_grid(estimator) == param_grid
 
 
+def test_regression():
+    lr = set_grid(LogisticRegression(), C=[1, 2, 3])
+    svc = SVC()
+    grid = build_param_grid(set_grid(Pipeline([('root', lr)]), root=[lr, svc]))
+
+    assert len(grid) == 2
+
+    assert lr in grid[0]['root']
+    assert svc not in grid[0]['root']
+    assert 'root__C' in grid[0]
+
+    assert svc in grid[1]['root']
+    assert lr not in grid[1]['root']
+    assert 'root__C' not in grid[1]
+
+
 def test_make_grid_search():
     X, y = load_iris(return_X_y=True)
     lr = LogisticRegression()