Repository: pallets/click

Issue:
UnboundLocalError when combining allow_dash and dir_okay
``` python
import click

@click.command()
@click.argument('filename', type=click.Path(dir_okay=False, allow_dash=True))
def foo(filename):
    pass

if __name__ == '__main__':
    foo()
```

When this script is invoked with the argument '-' I see the following error:

```
  File "boo.py", line 10, in <module>
    foo()
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 695, in main
    with self.make_context(prog_name, args, **extra) as ctx:
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 620, in make_context
    self.parse_args(ctx, args)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 874, in parse_args
    value, args = param.handle_parse_result(ctx, opts, args)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 1390, in handle_parse_result
    value = self.full_process_value(ctx, value)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 1359, in full_process_value
    value = self.process_value(ctx, value)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 1349, in process_value
    return self.type_cast_value(ctx, value)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 1338, in type_cast_value
    return _convert(value, (self.nargs != 1) + bool(self.multiple))
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/core.py", line 1336, in _convert
    return self.type(value, self, ctx)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/types.py", line 38, in __call__
    return self.convert(value, param, ctx)
  File "/home/david/projects/structureshrink/foo/lib/python3.5/site-packages/click-6.4-py3.5.egg/click/types.py", line 426, in convert
    if not self.dir_okay and stat.S_ISDIR(st.st_mode):
```

I am running Python 3.5.1 and using click version 6.4.



Discussion:

Resolving patch:
diff --git a/click/types.py b/click/types.py
--- a/click/types.py
+++ b/click/types.py
@@ -418,26 +418,26 @@ def convert(self, value, param, ctx):
                     filename_to_ui(value)
                 ), param, ctx)
 
-        if not self.file_okay and stat.S_ISREG(st.st_mode):
-            self.fail('%s "%s" is a file.' % (
-                self.path_type,
-                filename_to_ui(value)
-            ), param, ctx)
-        if not self.dir_okay and stat.S_ISDIR(st.st_mode):
-            self.fail('%s "%s" is a directory.' % (
-                self.path_type,
-                filename_to_ui(value)
-            ), param, ctx)
-        if self.writable and not os.access(value, os.W_OK):
-            self.fail('%s "%s" is not writable.' % (
-                self.path_type,
-                filename_to_ui(value)
-            ), param, ctx)
-        if self.readable and not os.access(value, os.R_OK):
-            self.fail('%s "%s" is not readable.' % (
-                self.path_type,
-                filename_to_ui(value)
-            ), param, ctx)
+            if not self.file_okay and stat.S_ISREG(st.st_mode):
+                self.fail('%s "%s" is a file.' % (
+                    self.path_type,
+                    filename_to_ui(value)
+                ), param, ctx)
+            if not self.dir_okay and stat.S_ISDIR(st.st_mode):
+                self.fail('%s "%s" is a directory.' % (
+                    self.path_type,
+                    filename_to_ui(value)
+                ), param, ctx)
+            if self.writable and not os.access(value, os.W_OK):
+                self.fail('%s "%s" is not writable.' % (
+                    self.path_type,
+                    filename_to_ui(value)
+                ), param, ctx)
+            if self.readable and not os.access(value, os.R_OK):
+                self.fail('%s "%s" is not readable.' % (
+                    self.path_type,
+                    filename_to_ui(value)
+                ), param, ctx)
 
         return self.coerce_path_result(rv)
 


Test patch:
diff --git a/tests/test_arguments.py b/tests/test_arguments.py
--- a/tests/test_arguments.py
+++ b/tests/test_arguments.py
@@ -106,6 +106,17 @@ def inout(input, output):
         assert result.exit_code == 0
 
 
+def test_path_args(runner):
+    @click.command()
+    @click.argument('input', type=click.Path(dir_okay=False, allow_dash=True))
+    def foo(input):
+        click.echo(input)
+
+    result = runner.invoke(foo, ['-'])
+    assert result.output == '-\n'
+    assert result.exit_code == 0
+
+
 def test_file_atomics(runner):
     @click.command()
     @click.argument('output', type=click.File('wb', atomic=True))