There are 4 tests in `auth_test/test_management.py` which fail when run by 
tox on windows.

- `test_system_username` - Raises an `ImportError`
- `test_non_ascii_verbose_name` - mock input mapping assumes default 
username, and raise an error
- `test_default_username` - Enters an infinite loop asking for a valid 
username
- `test_createsuperuser_command_suggested_username_with_database_option` - 
Enters an infinite loop asking for a
  valid username

I've traced this to `getpass.getuser`. Under windows `import pwd` cause an 
`ImportError`, unless `USERNAME` is set,
tox doesn't seem to  include this environment variable in the environments 
it creates, even when I tried adding
`USERNAME` to `passenv` in `tox.ini:testenv` (Note this is the first time 
I've used tox, so I could be doing
something wrong).

This causes `test_system_username` to raise an `ImportError` thereby 
failing and `get_system_username` to return an
empty string.

This means that `get_default_username` also returns an empty string. This 
causes `test_non_ascii_verbose_name` to
have an invalid mock input mapping as its map assumes the username request 
has a default option.

Further the empty string from `get_default_username`, results in a input 
validation error causing `get_input_data`
to return `None` resulting in `test_default_username` and
`test_createsuperuser_command_suggested_username_with_database_option` 
causing them to  enter an infinite loop
requesting a valid username, in `handle`.

See Code extracts below:

**def handle, 
django/contrib/auth/management/commands/createsuperuser.py:90**
*(username loop, starting on line 122)*
```python
while username is None:
    message = self._get_input_message(
        self.username_field, default_username
    )
    username = self.get_input_data(
        self.username_field, message, default_username
    )
    if username:
        error_msg = self._validate_username(
            username, verbose_field_name, database
        )
        if error_msg:
            self.stderr.write(error_msg)
            username = None
            continue
```

**def get_input_data, 
django/contrib/auth/management/commands/createsuperuser.py:250**
```python
def get_input_data(self, field, message, default=None):
    """
    Override this method if you want to customize data inputs or
    validation exceptions.
    """
    raw_value = input(message)
    if default and raw_value == "":
        raw_value = default
    try:
        val = field.clean(raw_value, None)
    except exceptions.ValidationError as e:
        self.stderr.write("Error: %s" % "; ".join(e.messages))
        val = None

    return val
```

 **def get_system_username, django/contrib/auth/management/__init__.py:114**
```python
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):
        # KeyError will be raised by os.getpwuid() (called by getuser())
        # if there is no corresponding entry in the /etc/passwd file
        # (a very restricted chroot environment, for example).
        return ""
    return result
```

**def getuser, getpass.py:154**
```python
def getuser():
    """Get the username from the environment or password database.

    First try various environment variables, then the password
    database.  This works on Windows as long as USERNAME is set.

    """

    for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
        user = os.environ.get(name)
        if user:
            return user

    # If this fails, the exception will "explain" why
    import pwd
    return pwd.getpwuid(os.getuid())[0]
```

## TOX Environment
Below I've include a sanitized version of my tox environment, generated by 
the Python Debug console (pycharm python
debugger)

```pycon
for k, v in os.environ.items():
    print(f"{k}: {v}")

PROGRAMFILES: C:\Program Files
TEMP: c:\users\{username}\AppData\Local\Temp
SYSTEMDRIVE: C:
PROGRAMFILES(X86): C:\Program Files (x86)
PATHEXT: 
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW;.RB;.RBW
TMP: c:\users\{username}\AppData\Local\Temp
USERPROFILE: c:\users\{username}
COMSPEC: C:\WINDOWS\system32\cmd.exe
PATH: {repo_path}\.tox\py3\Scripts;{venv_path};{python_path};{windows_path}
SYSTEMROOT: C:\WINDOWS
PROGRAMDATA: C:\ProgramData
APPDATA: c:\users\{username}\AppData\Roaming
PROCESSOR_ARCHITECTURE: AMD64
NUMBER_OF_PROCESSORS: 20
PYTHONDONTWRITEBYTECODE: 1
PYTHONHASHSEED: 261
TOX_ENV_NAME: py3
TOX_ENV_DIR: {repo_path}\.tox\py3
_JB_DO_NOT_CALL_ENTER_MATRIX: 1
VIRTUAL_ENV: {repo_path}\repo\.tox\py3
TMPDIR: c:\users\{username}\AppData\Local\Temp\django_0vhaflop
DJANGO_SETTINGS_MODULE: test_sqlite
RUNNING_DJANGOS_TEST_SUITE: true
```

## Possible Solution

I was able to solve this by adding `os.environ.setdefault("USERNAME", 
"test_user")` to `runtests.py` to ensure that
`USERNAME` is always defined so `getpass.getuser` will just return that 
value. However I'm not sure this is the
correct solution.

## Note
I'm using tox installed in my virtual environment using the command `pip 
install 'tox<4'` as when using
the default tox install (version 4) it failed to install django as an 
editable package in the tox environment (in
the config it was listing `PACKAGE=skip` I'm not sure why this happened)

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/2137ad05-91d1-462a-8309-87971bdffc55n%40googlegroups.com.

Reply via email to