Repository: django/django
File: tests/user_commands/tests.py (Python)

Code before:
                parser.parse_args(["--verbositty", "2"])
        self.assertEqual(cm.exception.code, 2)

        error_output = err.getvalue().lower()
        # Ensure it failed for the right reason
        self.assertIn("unrecognized arguments", error_output)

        # On Python 3.14+, suggestions *may* appear depending on environment
        if "did you mean" in error_output:
            self.assertIn("--verbosity", error_output)

    def test_suggest_on_error_works_with_management_commands(self):
        """
        Management commands have suggest_on_error on Python 3.14+.
        """
        from .management.commands.dance import Command as DanceCommand

        dance_cmd = DanceCommand()
        dance_cmd._called_from_command_line = True  # ADD THIS LINE
        parser = dance_cmd.create_parser("django-admin", "dance")

        if PY314:
            self.assertTrue(
                getattr(parser, "suggest_on_error", False),
                "Management command parsers should have suggest_on_error=True",
            )


class CommandRunTests(AdminScriptTestCase):
    """
    Tests that need to run by simulating the command line, not by call_command.
    """

    def test_script_prefix_set_in_commands(self):
        self.write_settings(
            "settings.py",
            apps=["user_commands"],
            sdict={
                "ROOT_URLCONF": '"user_commands.urls"',
                "FORCE_SCRIPT_NAME": '"/PREFIX/"',
            },
        )
        out, err = self.run_manage(["reverse_url"])
        self.assertNoOutput(err)
        self.assertEqual(out.strip(), "/PREFIX/some/url/")

    def test_disallowed_abbreviated_options(self):
        """
        To avoid conflicts with custom options, commands don't allow
        abbreviated forms of the --setting and --pythonpath options.
        """

Review comment (suggestion):
Some fixes for your tests:

1. Use `unittest.skipUnless` on all tests.
2. Use `not PY315` per the above comments about the default chanigng on Python 3.15.
3. Drop the `# ADD THIS LINE` comments, which look like they came from someone's review?
4. Drop the behaviour tests - they are not valuable, as they only test argparse's behaviour, which we can depend on.

```suggestion
    @unittest.skipUnless(PY314 and not PY315, "Requires Python 3.14")
    def test_suggest_on_error_defaults_true(self):
        """
        CommandParser sets suggest_on_error=True on Python 3.14+.
        """
        command = BaseCommand()
        command._called_from_command_line = True
        parser = command.create_parser("prog_name", "subcommand")

        self.assertTrue(parser.suggest_on_error)

    @unittest.skipUnless(PY314 and not PY315, "Requires Python 3.14+")
    def test_suggest_on_error_custom(self):
        """
        Explicit suggest_on_error=False is respected.
        """
        command = BaseCommand()
        command._called_from_command_line = True
        parser = command.create_parser(
            "prog_name", "subcommand", suggest_on_error=False
        )
        self.assertFalse(parser.suggest_on_error)
```

Code after:
            sdict={
                # (staticfiles.E001) The STATICFILES_DIRS setting is not a
                # tuple or list.
                "STATICFILES_DIRS": '"foo"',
            },
        )
        out, err = self.run_manage(["set_option", "--skip-checks", "--set", "foo"])
        self.assertNoOutput(err)
        self.assertEqual(out.strip(), "Set foo")

    def test_subparser_error_formatting(self):
        self.write_settings("settings.py", apps=["user_commands"])
        out, err = self.run_manage(["subparser", "foo", "twelve"])
        self.maxDiff = None
        self.assertNoOutput(out)
        err_lines = err.splitlines()
        self.assertEqual(len(err_lines), 2)
        self.assertEqual(
            err_lines[1],
            "manage.py subparser foo: error: argument bar: invalid int value: 'twelve'",
        )

    def test_subparser_non_django_error_formatting(self):
        self.write_settings("settings.py", apps=["user_commands"])
        out, err = self.run_manage(["subparser_vanilla", "foo", "seven"])
        self.assertNoOutput(out)
        err_lines = err.splitlines()
        self.assertEqual(len(err_lines), 2)
        self.assertEqual(
            err_lines[1],
            "manage.py subparser_vanilla foo: error: argument bar: invalid int value: "
            "'seven'",
        )


class UtilsTests(SimpleTestCase):
    def test_no_existent_external_program(self):
        msg = "Error executing a_42_command_that_doesnt_exist_42"
        with self.assertRaisesMessage(CommandError, msg):
            popen_wrapper(["a_42_command_that_doesnt_exist_42"])

    def test_get_random_secret_key(self):
        key = get_random_secret_key()
        self.assertEqual(len(key), 50)
        for char in key:
            self.assertIn(char, "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)")

    def test_is_ignored_path_true(self):
        patterns = (
            ["foo/bar/baz"],
            ["baz"],