﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
36479	Failing test for black formatter missing install simulation	Roelzkie	Roelzkie	"The test on `test.user_commands.tests.UtilsTests.test_run_formatters_handles_oserror_for_black_path` attempts to assert a [https://github.com/django/django/blob/main/tests/user_commands/tests.py#L569 `FileNotFoundError`] when simulating a missing black formatter installation. 

{{{
./runtests.py user_commands.tests.UtilsTests.test_run_formatters_handles_oserror_for_black_path
}}}


However, it fails on the `darwin` platform, at least on MacOS v14.7.2 (Sonoma) M1 machine. I tested on a Linux platform, and the test passed.

The root issue is due to the `subprocess.run` command, which yields different `OSError` results on different OS's when the test reaches the [https://github.com/django/django/blob/68a45d9a8078db642f0aca7ddab33af6df7ebeb3/django/core/management/utils.py#L175-L177 `subprocess.run([""nonexistent"", ""--fast"", ""--""])`].

For `darwin` (at least on MacOS v14.7.2 - M1), it yields a `NotADirectoryError` / `OSError(20, ""Not a directory"")` which fails the test.
For `linux`, it yields a `FileNotFoundError` / `OSError(2, ""File not found"")` which passes the test.

Ideally, this test should be able to handle it regardless of the machine platform.

See failed test full stacktrace: https://dpaste.org/pY48h (link will expire, see result below instead).

{{{
FAIL: test_run_formatters_handles_oserror_for_black_path (user_commands.tests.UtilsTests.test_run_formatters_handles_oserror_for_black_path) [FileNotFoundError]
----------------------------------------------------------------------
Traceback (most recent call last):
  File ""/Users/user1/.pyenv/versions/3.13.2/lib/python3.13/unittest/case.py"", line 58, in testPartExecutor
    yield
  File ""/Users/user1/.pyenv/versions/3.13.2/lib/python3.13/unittest/case.py"", line 556, in subTest
    yield
  File ""/Users/user1/projects/django/tests/user_commands/tests.py"", line 584, in test_run_formatters_handles_oserror_for_black_path
    self.assertIn(exception.__qualname__, parsed_error)
    ^^^^^^^
  File ""/Users/user1/.pyenv/versions/3.13.2/lib/python3.13/unittest/case.py"", line 1174, in assertIn
    self.fail(self._formatMessage(msg, standardMsg))
    ^^^^^^^^^^^
  File ""/Users/user1/.pyenv/versions/3.13.2/lib/python3.13/unittest/case.py"", line 732, in fail
    raise self.failureException(msg)
    ^^^^^^^^^^^^^^^
AssertionError: 'FileNotFoundError' not found in 'Formatters failed to launch:Traceback (most recent call last):
  File ""/Users/user1/projects/django/django/core/management/utils.py"", line 175, in run_formatters
    subprocess.run(
    ~~~~~~~~~~~~~~^
        [black_path, ""--fast"", ""--"", *written_files],
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        capture_output=True,
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File ""/Users/user1/.pyenv/versions/3.13.2/lib/python3.13/subprocess.py"", line 556, in run
    with Popen(*popenargs, **kwargs) as process:
         ~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/user1/.pyenv/versions/3.13.2/lib/python3.13/subprocess.py"", line 1038, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        pass_fds, cwd, env,
                        ^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
                        gid, gids, uid, umask,
                        ^^^^^^^^^^^^^^^^^^^^^^
                        start_new_session, process_group)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/Users/user1/.pyenv/versions/3.13.2/lib/python3.13/subprocess.py"", line 1974, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
NotADirectoryError: [Errno 20] Not a directory: \'nonexistent\''
​
----------------------------------------------------------------------
}}}


Update: Please see https://github.com/django/django/pull/19591"	Cleanup/optimization	closed	Core (Management commands)	dev	Normal	fixed		Roelzkie Mike Edmunds	Ready for checkin	1	0	0	0	0	0
