Repository: pypa/virtualenv

Issue:
virtualenv dont work if file "C:\Program" was created
**Issue**

1. install python to %ProgramFiles%
2. create file `C:\Program`
3. type `virtualenv venv` in cmd
4. type `call venv\Scripts\activate`
5. type `python`

Get error: `Unable to create process using 'c:\program files\python39\python.exe'`

screen:
<img width="1109" height="479" alt="Image" src="https://github.com/user-attachments/assets/6ea1539f-4c78-4346-933f-f87688146a5e" />

**Environment**

Provide at least:

- OS: windows
- Shell: cmd
- Python version and path: 3.9 in c:\program files\python

**Output of the virtual environment creation**

```console
C:\Users\Kuznetsov_NA>virtualenv venv
created virtual environment CPython3.9.2.final.0-64 in 318ms
  creator CPython3Windows(dest=C:\Users\Kuznetsov_NA\venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\Kuznetsov_NA\AppData\Local\pypa\virtualenv)
    added seed packages: pip==25.2, setuptools==80.9.0, wheel==0.45.1
  activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

C:\Users\Kuznetsov_NA>call venv\Scripts\activate

(venv) C:\Users\Kuznetsov_NA>python
Unable to create process using 'c:\program files\python39\python.exe'
```

Discussion:

Fix (patch):
diff --git a/docs/changelog/2985.bugfix.rst b/docs/changelog/2985.bugfix.rst
new file mode 100644
index 000000000..ae2fe2aca
--- /dev/null
+++ b/docs/changelog/2985.bugfix.rst
@@ -0,0 +1,1 @@
+Fix Windows activation scripts to properly quote ``python.exe`` path, preventing failures when Python is installed in a path with spaces (e.g., ``C:\Program Files``) and a file named ``C:\Program`` exists on the filesystem - by :user:`rahuldevikar`.
diff --git a/src/virtualenv/activation/batch/pydoc.bat b/src/virtualenv/activation/batch/pydoc.bat
index 3d46a231a..d55f8ac03 100644
--- a/src/virtualenv/activation/batch/pydoc.bat
+++ b/src/virtualenv/activation/batch/pydoc.bat
@@ -1,1 +1,1 @@
-python.exe -m pydoc %*
+"python.exe" -m pydoc %*
diff --git a/src/virtualenv/activation/powershell/activate.ps1 b/src/virtualenv/activation/powershell/activate.ps1
index 9f95e4370..052a8298d 100644
--- a/src/virtualenv/activation/powershell/activate.ps1
+++ b/src/virtualenv/activation/powershell/activate.ps1
@@ -46,7 +46,7 @@ function global:deactivate([switch] $NonDestructive) {
 }
 
 function global:pydoc {
-    python -m pydoc $args
+    & python -m pydoc $args
 }
 
 # unset irrelevant variables


Test changes:
diff --git a/tests/unit/activation/test_batch.py b/tests/unit/activation/test_batch.py
index db2595860..74c5a0f97 100644
--- a/tests/unit/activation/test_batch.py
+++ b/tests/unit/activation/test_batch.py
@@ -7,6 +7,38 @@
 from virtualenv.activation import BatchActivator
 
 
+def test_batch_pydoc_bat_quoting(tmp_path):
+    """Test that pydoc.bat properly quotes python.exe path to handle spaces."""
+
+    # GIVEN: A mock interpreter
+    class MockInterpreter:
+        os = "nt"
+        tcl_lib = None
+        tk_lib = None
+
+    class MockCreator:
+        def __init__(self, dest):
+            self.dest = dest
+            self.bin_dir = dest / "Scripts"
+            self.bin_dir.mkdir(parents=True)
+            self.interpreter = MockInterpreter()
+            self.pyenv_cfg = {}
+            self.env_name = "test-env"
+
+    creator = MockCreator(tmp_path)
+    options = Namespace(prompt=None)
+    activator = BatchActivator(options)
+
+    # WHEN: Generate activation scripts
+    activator.generate(creator)
+
+    # THEN: pydoc.bat should quote python.exe to handle paths with spaces
+    pydoc_content = (creator.bin_dir / "pydoc.bat").read_text(encoding="utf-8")
+
+    # The python.exe should be quoted to handle paths with spaces like "C:\Program Files\Python39\python.exe"
+    assert '"python.exe"' in pydoc_content, f"python.exe should be quoted in pydoc.bat. Content:\n{pydoc_content}"
+
+
 @pytest.mark.parametrize(
     ("tcl_lib", "tk_lib", "present"),
     [
diff --git a/tests/unit/activation/test_powershell.py b/tests/unit/activation/test_powershell.py
index 2a48956cf..cd6057eec 100644
--- a/tests/unit/activation/test_powershell.py
+++ b/tests/unit/activation/test_powershell.py
@@ -8,6 +8,40 @@
 from virtualenv.activation import PowerShellActivator
 
 
+def test_powershell_pydoc_call_operator(tmp_path):
+    """Test that PowerShell pydoc function uses call operator to handle spaces in python path."""
+
+    # GIVEN: A mock interpreter
+    class MockInterpreter:
+        os = "nt"
+        tcl_lib = None
+        tk_lib = None
+
+    class MockCreator:
+        def __init__(self, dest):
+            self.dest = dest
+            self.bin_dir = dest / "Scripts"
+            self.bin_dir.mkdir(parents=True)
+            self.interpreter = MockInterpreter()
+            self.pyenv_cfg = {}
+            self.env_name = "test-env"
+
+    creator = MockCreator(tmp_path)
+    options = Namespace(prompt=None)
+    activator = PowerShellActivator(options)
+
+    # WHEN: Generate activation scripts
+    activator.generate(creator)
+
+    # THEN: pydoc function should use call operator & to handle paths with spaces
+    activate_content = (creator.bin_dir / "activate.ps1").read_text(encoding="utf-8-sig")
+
+    # The pydoc function should use & call operator to handle paths with spaces
+    assert "& python -m pydoc" in activate_content, (
+        f"pydoc function should use & call operator. Content:\n{activate_content}"
+    )
+
+
 @pytest.mark.parametrize(
     ("tcl_lib", "tk_lib", "present"),
     [