Repository: amoffat/sh (python)

Issue:
Accept pathlib.Path objects for _out and _err
Currently, if I pass `pathlib.Path` object to any command as its `_out` argument, it is effectively ignored without any error:
```
import sh
from pathlib import Path

out = Path('/tmp/out')
sh.echo('hello', _out=out)
print(out.exists())  # False
```

Current workaround is to convert path to `string` before passing it to sh:
```
sh.echo('hello', _out=str(out))
print(out.exists())  # True
```

It would be nice to also accept Paths "as is", or at least raise an error if something unsupported is passed for `_out` or `_err`.

Pull request description:
Accept pathlib.Path objects for stdout/stderr
Fix #597.
I decided to not add an additional import for `pathlib.Path` and instead check if the object passed is "path-like" according to [PEP-519](https://www.python.org/dev/peps/pep-0519/).

Patch:
diff --git a/sh.py b/sh.py
index 5fc9c2c..f14f63a 100644
--- a/sh.py
+++ b/sh.py
@@ -990,7 +990,7 @@ class RunningCommand(object):
 
 
 def output_redirect_is_filename(out):
-    return isinstance(out, basestring)
+    return isinstance(out, basestring) or hasattr(out, '__fspath__')
 
 
 def get_prepend_stack():


Test patch:
diff --git a/test.py b/test.py
index 0e4b206..6d17a25 100644
--- a/test.py
+++ b/test.py
@@ -136,6 +136,7 @@ requires_utf8 = skipUnless(sh.DEFAULT_ENCODING == "UTF-8", "System encoding must
 not_macos = skipUnless(not IS_MACOS, "Doesn't work on MacOS")
 requires_py3 = skipUnless(IS_PY3, "Test only works on Python 3")
 requires_py35 = skipUnless(IS_PY3 and MINOR_VER >= 5, "Test only works on Python 3.5 or higher")
+requires_py36 = skipUnless(IS_PY3 and MINOR_VER >= 6, "Test only works on Python 3.6 or higher")
 
 
 def requires_poller(poller):
@@ -1772,6 +1773,15 @@ exit(code)
         outfile.seek(0)
         self.assertEqual(b"output\n", outfile.read())
 
+    @requires_py36
+    def test_out_pathlike(self):
+        from pathlib import Path
+        outfile = tempfile.NamedTemporaryFile()
+        py = create_tmp_test("print('output')")
+        python(py.name, _out=Path(outfile.name))
+        outfile.seek(0)
+        self.assertEqual(b"output\n", outfile.read())
+
     def test_bg_exit_code(self):
         py = create_tmp_test("""
 import time