Repository: django/django
File: django/contrib/auth/management/__init__.py (Python)

Code before:

                planned.append((perm, old_codename, new_codename, new_name_str))

    existing = {
        p.codename
        for p in Permission.objects.using(db).filter(
            content_type__app_label=app_label,
            codename__in=[new for _, _, new, _ in planned],
        )
    }

    # Look for conflicts
    for perm, old, new, _ in planned:
        if new in existing and perm.codename != new:
            conflicts.append((perm.pk, old, new))

    # Raise error if conflicts found
    if conflicts:
        style = color_style()
        for pk, old, new in conflicts:
            print(
                style.WARNING(
                    f"Failed to rename permission {pk} "
                    f"from '{old}' to '{new}'. "
                    f"Please resolve the conflict manually."
                )
            )
        raise IntegrityError(
            f"{len(conflicts)} permission rename conflict(s) detected."
        )

    with transaction.atomic(using=db):
        for perm, _, new_codename, new_name_str in planned:
            perm.codename = new_codename
            perm.name = new_name_str
            perm.save(update_fields={"codename", "name"}, using=db)

    for _, from_codename, to_codename, _ in planned:
        if verbosity >= 2:
            print(
                f"Renamed permission(s): "
                f"{app_label}.{from_codename} → {to_codename}"
            )


def get_system_username():
    """
    Return the current system user's username, or an empty string if the
    username could not be determined.
    """
    try:

Review comment (bug):
We need to capture this output in the test with `captured_stdout` and assert over it, see test run:

```py
.........Failed to rename permission 463 from 'change_oldmodel' to 'change_newmodel'. Please resolve the conflict manually.
....
----------------------------------------------------------------------
Ran 117 tests in 2.015s
```

Code after:
        )
    }

    # Look for conflicts
    for perm, old, new, _ in planned:
        if new in existing and perm.codename != new:
            conflicts.append((perm.pk, old, new))

    # Raise error if conflicts found
    if conflicts:
        if verbosity:
            style = color_style()
            for pk, old, new in conflicts:
                msg = (
                    f"Failed to rename permission {pk} from '{old}' to '{new}'. "
                    f"Please resolve the conflict manually.\n"
                )
                stdout.write(style.WARNING(msg))
        error_message = f"{len(conflicts)} permission rename conflict(s) detected."
        raise RuntimeError(error_message)

    with transaction.atomic(using=db):
        for perm, _, new_codename, new_name_str in planned:
            perm.codename = new_codename
            perm.name = new_name_str
            perm.save(update_fields={"codename", "name"}, using=db)

    for _, from_codename, to_codename, _ in planned:
        if verbosity >= 2:
            stdout.write(
                f"Renamed permission(s): "
                f"{app_label}.{from_codename} → {to_codename}\n"
            )


def get_system_username():
    """
    Return the current system user's username, or an empty string if the
    username could not be determined.
    """
    try:
        result = getpass.getuser()
    except (ImportError, KeyError, OSError):
        # TODO: Drop ImportError and KeyError when dropping support for PY312.
        # KeyError (Python <3.13) or OSError (Python 3.13+) will be raised by
        # os.getpwuid() (called by getuser()) if there is no corresponding
        # entry in the /etc/passwd file (for example, in a very restricted
        # chroot environment).
        return ""
    return result