Skip to content

hatch env-include causing issues on Windows #2223

@onyx-and-iris

Description

@onyx-and-iris

Hello hatch team.

If I include an env-include pattern in one of my environments hatch is unable to create the default env (or any other I think) on Windows. On Linux it creates the environment fine.


Steps to reproduce:

  • hatch new test-env
  • Add env-include to an environment:
[tool.hatch.envs.default]
env-include = ["TEST_ENV_*"]
  • hatch env create
  error: subprocess-exited-with-error

  installing build dependencies did not run successfully.
  exit code: 1

  [7 lines of output]
  WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x000001BD55BF1940>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed')': /simple/hatchling/
  WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x000001BD55B6FB10>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed')': /simple/hatchling/
  WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x000001BD55B6FD90>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed')': /simple/hatchling/
  WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x000001BD55C10050>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed')': /simple/hatchling/
  WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at 0x000001BD55C102D0>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed')': /simple/hatchling/
  ERROR: Could not find a version that satisfies the requirement hatchling (from versions: none)      
  ERROR: No matching distribution found for hatchling
  [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed to build 'file:///S:/scripts/test-env' when installing build dependencies

If I comment out the env-include:

#[tool.hatch.envs.default]
#env-include = ["TEST_ENV_*"]

Then hatch env create succeeds.

However, if I then try to use hatch run to say run an entry point with hatch run test-env, I get:

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\cli\__init__.py:239 in main              │
│                                                                                                  │
│   236                                                                                            │
│   237 def main():  # no cov                                                                      │
│   238 │   try:                                                                                   │
│ ❱ 239 │   │   hatch(prog_name="hatch", windows_expand_args=False)                                │
│   240 │   except Exception:  # noqa: BLE001                                                      │
│   241 │   │   import sys                                                                         │
│   242                                                                                            │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\core.py:1485 in __call__                 │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\core.py:1406 in main                     │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\core.py:1873 in invoke                   │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\core.py:1269 in invoke                   │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\core.py:824 in invoke                    │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\decorators.py:34 in new_func             │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\cli\run\__init__.py:156 in run           │
│                                                                                                  │
│   153 │   elif not env_name:                                                                     │
│   154 │   │   env_name = "system"                                                                │
│   155 │                                                                                          │
│ ❱ 156 │   ctx.invoke(                                                                            │
│   157 │   │   run_command,                                                                       │
│   158 │   │   args=[command, *final_args],                                                       │
│   159 │   │   env_names=[env_name],                                                              │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\core.py:824 in invoke                    │
│                                                                                                  │
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\click\decorators.py:46 in new_func             │
│                                                                                                  │  
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\cli\env\run.py:137 in run                │  
│                                                                                                  │  
│   134 │   elif not matrix_selected and (included_variables or excluded_variables):               │  
│   135 │   │   app.abort(f"Variable selection is unsupported for non-matrix environments: {', '   │  
│   136 │                                                                                          │  
│ ❱ 137 │   for context in app.runner_context(                                                     │  
│   138 │   │   environments,                                                                      │  
│   139 │   │   ignore_compat=ignore_compat or matrix_selected,                                    │  
│   140 │   │   display_header=matrix_selected,                                                    │  
│                                                                                                  │  
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\cli\application.py:122 in runner_context │  
│                                                                                                  │  
│   119 │   │   │   │   yield context                                                              │  
│   120 │   │   │   │                                                                              │  
│   121 │   │   │   │   self.prepare_environment(environment, keep_env=keep_env)                   │  
│ ❱ 122 │   │   │   │   self.execute_context(context)                                              │  
│   123 │   │                                                                                      │  
│   124 │   │   if incompatible:                                                                   │  
│   125 │   │   │   num_incompatible = len(incompatible)                                           │  
│                                                                                                  │  
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\cli\application.py:137 in                │  
│ execute_context                                                                                  │  
│                                                                                                  │  
│   134 │   │   from hatch.utils.structures import EnvVars                                         │
│   135 │   │                                                                                      │  
│   136 │   │   with EnvVars(context.env_vars):                                                    │  
│ ❱ 137 │   │   │   self.run_shell_commands(context)                                               │  
│   138 │                                                                                          │  
│   139 │   def ensure_environment_plugin_dependencies(self) -> None:                              │  
│   140 │   │   self.ensure_plugin_dependencies(                                                   │  
│                                                                                                  │  
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\cli\application.py:72 in                 │  
│ run_shell_commands                                                                               │  
│                                                                                                  │  
│    69 │   │   │   │   │   continue_on_error = True                                               │  
│    70 │   │   │   │   │   command = command[2:]                                                  │  
│    71 │   │   │   │                                                                              │  
│ ❱  72 │   │   │   │   process = context.env.run_shell_command(command)                           │  
│    73 │   │   │   │   sys.stdout.flush()                                                         │  
│    74 │   │   │   │   sys.stderr.flush()                                                         │  
│    75 │   │   │   │   if process.returncode:                                                     │  
│                                                                                                  │  
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\env\plugin\interface.py:884 in           │  
│ run_shell_command                                                                                │  
│                                                                                                  │  
│    881 │   │   is active, with the expectation of providing the same guarantee.                  │  
│    882 │   │   """                                                                               │  
│    883 │   │   kwargs.setdefault("shell", True)                                                  │  
│ ❱  884 │   │   return self.platform.run_command(command, **kwargs)                               │  
│    885 │                                                                                         │  
│    886 │   @contextmanager                                                                       │  
│    887 │   def command_context(self):                                                            │  
│                                                                                                  │  
│ C:\Users\<user>\pipx\venvs\hatch\Lib\site-packages\hatch\utils\platform.py:101 in run_command     │  
│                                                                                                  │  
│    98 │   │   │   return self._run_command_integrated(command, shell=shell, **kwargs)            │  
│    99 │   │                                                                                      │  
│   100 │   │   self.populate_default_popen_kwargs(kwargs, shell=shell)                            │  
│ ❱ 101 │   │   return self.modules.subprocess.run(self.format_for_subprocess(command, shell=she   │  
│   102 │                                                                                          │  
│   103 │   def check_command(self, command: str | list[str], *, shell: bool = False, **kwargs:    │  
│   104 │   │   """                                                                                │  
│                                                                                                  │  
│ C:\Users\<user>\.pyenv\pyenv-win\versions\3.13.11\Lib\subprocess.py:554 in run                    │  
│                                                                                                  │  
│    551 │   │   kwargs['stdout'] = PIPE                                                           │  
│    552 │   │   kwargs['stderr'] = PIPE                                                           │  
│    553 │                                                                                         │  
│ ❱  554 │   with Popen(*popenargs, **kwargs) as process:                                          │  
│    555 │   │   try:                                                                              │  
│    556 │   │   │   stdout, stderr = process.communicate(input, timeout=timeout)                  │  
│    557 │   │   except TimeoutExpired as exc:                                                     │  
│                                                                                                  │  
│ C:\Users\<user>\.pyenv\pyenv-win\versions\3.13.11\Lib\subprocess.py:1039 in __init__              │  
│                                                                                                  │  
│   1036 │   │   │   │   │   self.stderr = io.TextIOWrapper(self.stderr,                           │  
│   1037 │   │   │   │   │   │   │   encoding=encoding, errors=errors)                             │  
│   1038 │   │   │                                                                                 │  
│ ❱ 1039 │   │   │   self._execute_child(args, executable, preexec_fn, close_fds,                  │  
│   1040 │   │   │   │   │   │   │   │   pass_fds, cwd, env,                                       │  
│   1041 │   │   │   │   │   │   │   │   startupinfo, creationflags, shell,                        │  
│   1042 │   │   │   │   │   │   │   │   p2cread, p2cwrite,                                        │  
│                                                                                                  │  
│ C:\Users\<user>\.pyenv\pyenv-win\versions\3.13.11\Lib\subprocess.py:1539 in _execute_child        │  
│                                                                                                  │  
│   1536 │   │   │   │   │   │   system_root = os.environ.get('SystemRoot', '')                    │  
│   1537 │   │   │   │   │   │   comspec = os.path.join(system_root, 'System32', 'cmd.exe')        │  
│   1538 │   │   │   │   │   │   if not os.path.isabs(comspec):                                    │  
│ ❱ 1539 │   │   │   │   │   │   │   raise FileNotFoundError('shell not found: neither %ComSpec%   │  
│   1540 │   │   │   │   │   if os.path.isabs(comspec):                                            │  
│   1541 │   │   │   │   │   │   executable = comspec                                              │  
│   1542 │   │   │   │   else:                                                                     │  
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯  
FileNotFoundError: shell not found: neither %ComSpec% nor %SystemRoot% is set

Although, I checked and both ComSpec and SystemRoot system variables are set.

Again, I can do this on Linux without issues.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions