Repository: mahmoud/boltons

Issue:
URL.navigate fails with path in base URL
The following and several permutations fail attempting to concatenate a `tuple` with a `list`:

```
URL('http://localhost').navigate('a').navigate('b')
```
Result:

```
...
            else:  # relative path
>               new_path_parts = list(self.path_parts[:-1]) + dest.path_parts
E               TypeError: can only concatenate list (not "tuple") to list

boltons/urlutils.py:657: TypeError
```

I am a little unclear about exactly what *should* happen when 'a' has a trailing slash or not, but enough cases fail that I know *something* is wrong.
I will follow shortly with a PR with a number of test cases, some of which I know are wrong, so I am hoping I can get some clarification about what the correct behavior *should* be.

This is not strictly an issue with chaining the `navigate` calls, but rather ambiguity of what should happen with the base URL lacks a trailing '/' and failures that result from that.

Env data:
platform darwin
Python 3.6.5 (built w/pyenv)
pytest-3.5.1

Discussion:
mahmoud: Nice work, appreciate the tests! Also check out [hyperlink](https://github.com/python-hyper/hyperlink). It's a bit different, but might fit the bill in some cases.  :) Thanks again!

Patch:
diff --git a/boltons/urlutils.py b/boltons/urlutils.py
index 6016e8a..7462ed4 100644
--- a/boltons/urlutils.py
+++ b/boltons/urlutils.py
@@ -685,7 +685,8 @@ class URL(object):
             if dest.path.startswith(u'/'):   # absolute path
                 new_path_parts = list(dest.path_parts)
             else:  # relative path
-                new_path_parts = self.path_parts[:-1] + dest.path_parts
+                new_path_parts = list(self.path_parts[:-1]) \
+                               + list(dest.path_parts)
         else:
             new_path_parts = list(self.path_parts)
             if not query_params:


Test patch:
diff --git a/tests/test_urlutils.py b/tests/test_urlutils.py
index a8e1539..2351899 100644
--- a/tests/test_urlutils.py
+++ b/tests/test_urlutils.py
@@ -313,6 +313,25 @@ def test_navigate():
     assert navd.to_text() == _dest_text
 
 
+@pytest.mark.parametrize(
+    ('expected', 'base', 'paths'), [
+    ('https://host/b', 'https://host', ('a', '/b', )),
+    ('https://host/b', 'https://host', ('a', 'b', )),
+    ('https://host/a/b', 'https://host', ('a/', 'b', )),
+    ('https://host/b', 'https://host', ('/a', 'b', )),
+    ('https://host/a/b', 'https://host/a/', (None, 'b', )),
+    ('https://host/b', 'https://host/a', (None, 'b', )),
+])
+def test_chained_navigate(expected, base, paths):
+    """Chained :meth:`navigate` calls produces correct results."""
+    url = URL(base)
+
+    for path in paths:
+        url = url.navigate(path)
+
+    assert expected == url.to_text()
+
+
 # TODO: RFC3986 6.2.3 (not just for query add, either)
 # def test_add_query():
 #     url = URL('http://www.example.com')