Repository: pytest-dev/pytest-django (python)

Issue:
OSError on long command-line args
In the logic of django_find_project there exist these lines:
```
    def find_django_path(args):
        args = map(str, args)
        args = [arg_to_path(x) for x in args if not x.startswith("-")]
        args = [p for p in args if p.is_dir()]
...
```
Unfortunately, this means that if there are really long command-line args that this can get a `OSError: [Errno 36] File name too long: ...` which prevents me from, for example, using really long args to pytest's `-k` option.
Thanks for looking into this.


Discussion:
Please consider creating a failing test and fix for this yourself.
I assume the `args = [p for p in args if p.is_dir()]` should be turned into a loop that try/catches any OSError and ignores it.
/cc @voidus for the pathlib change that appears to trigger this

Patch:
diff --git a/pytest_django/plugin.py b/pytest_django/plugin.py
--- a/pytest_django/plugin.py
+++ b/pytest_django/plugin.py
@@ -120,7 +120,10 @@ def _handle_import_error(extra_message):
 
 def _add_django_project_to_path(args):
     def is_django_project(path):
-        return path.is_dir() and (path / 'manage.py').exists()
+        try:
+            return path.is_dir() and (path / 'manage.py').exists()
+        except OSError:
+            return False
 
     def arg_to_path(arg):
         # Test classes or functions can be appended to paths separated by ::
@@ -130,7 +133,6 @@ def arg_to_path(arg):
     def find_django_path(args):
         args = map(str, args)
         args = [arg_to_path(x) for x in args if not x.startswith("-")]
-        args = [p for p in args if p.is_dir()]
 
         if not args:
             args = [pathlib.Path.cwd()]


Test patch:
diff --git a/tests/test_manage_py_scan.py b/tests/test_manage_py_scan.py
--- a/tests/test_manage_py_scan.py
+++ b/tests/test_manage_py_scan.py
@@ -83,3 +83,15 @@ def test_django_project_found_invalid_settings_version(django_testdir, monkeypat
     result = django_testdir.runpytest_subprocess('django_project_root', '--help')
     assert result.ret == 0
     result.stdout.fnmatch_lines(['*usage:*'])
+
+
+@pytest.mark.django_project(project_root='django_project_root',
+                            create_manage_py=True)
+def test_runs_without_error_on_long_args(django_testdir):
+    django_testdir.create_test_module("""
+    def test_this_is_a_long_message_which_caused_a_bug_when_scanning_for_manage_py_12346712341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234112341234112451234123412341234123412341234123412341234123412341234123412341234123412341234123412341234():
+        assert 1 + 1 == 2
+    """)
+
+    result = django_testdir.runpytest_subprocess('-k', 'this_is_a_long_message_which_caused_a_bug_when_scanning_for_manage_py_12346712341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234123412341234112341234112451234123412341234123412341234123412341234123412341234123412341234123412341234123412341234', 'django_project_root')
+    assert result.ret == 0