Repository: pypa/cibuildwheel

Issue:
Setting PIP options can break environment setup
### Description

Setting a pip option, like `PIP_USE_DEPRECATED=out-of-tree-build` can break the initial setup, because this option gets applied to the original pip version (21.1 on Windows) instead of our pinned version. We should possibly ignore PIP_* variables or all environment variables during this initial setup for the pinned versions of things.

See https://github.com/pybind/cmake_example/pull/66

Example of problematic line: https://github.com/pypa/cibuildwheel/blob/f717468ff60fbd2ee76b6327596d078ad0ec13d5/cibuildwheel/macos.py#L232

### Build log

https://github.com/pybind/cmake_example/runs/4346290813?check_suite_focus=true

### CI config

https://github.com/pybind/cmake_example/blob/c06fc016af76bd0f6a637705afc5d4cbfa554f5a/.github/workflows/wheels.yml#L49


Discussion:
Hmm yes, I can see the argument. We could also defer applying CIBW_ENVIRONMENT until after our internal tools install? Not sure which is preferable though. 
It would be simpler to defer till after the internal tools install, since we set a few pip variables (like the version check).

Resolving patch:
diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py
--- a/cibuildwheel/macos.py
+++ b/cibuildwheel/macos.py
@@ -192,24 +192,10 @@ def setup_python(
     # https://github.com/pypa/virtualenv/issues/620
     # Also see https://github.com/python/cpython/pull/9516
     env.pop("__PYVENV_LAUNCHER__", None)
-    env = environment.as_dictionary(prev_environment=env)
 
     # we version pip ourselves, so we don't care about pip version checking
     env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
 
-    # check what version we're on
-    call(["which", "python"], env=env)
-    call(["python", "--version"], env=env)
-    which_python = subprocess.run(
-        ["which", "python"], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE
-    ).stdout.strip()
-    if which_python != "/tmp/cibw_bin/python":
-        print(
-            "cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
-            file=sys.stderr,
-        )
-        sys.exit(1)
-
     # Install pip
 
     requires_reinstall = not (installation_bin_path / "pip").exists()
@@ -233,6 +219,10 @@ def setup_python(
         cwd="/tmp",
     )
 
+    # Apply our environment after pip is ready
+    env = environment.as_dictionary(prev_environment=env)
+
+    # check what pip version we're on
     assert (installation_bin_path / "pip").exists()
     call(["which", "pip"], env=env)
     call(["pip", "--version"], env=env)
@@ -246,6 +236,19 @@ def setup_python(
         )
         sys.exit(1)
 
+    # check what Python version we're on
+    call(["which", "python"], env=env)
+    call(["python", "--version"], env=env)
+    which_python = subprocess.run(
+        ["which", "python"], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE
+    ).stdout.strip()
+    if which_python != "/tmp/cibw_bin/python":
+        print(
+            "cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
+            file=sys.stderr,
+        )
+        sys.exit(1)
+
     # Set MACOSX_DEPLOYMENT_TARGET to 10.9, if the user didn't set it.
     # PyPy defaults to 10.7, causing inconsistencies if it's left unset.
     env.setdefault("MACOSX_DEPLOYMENT_TARGET", "10.9")
diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py
--- a/cibuildwheel/windows.py
+++ b/cibuildwheel/windows.py
@@ -157,31 +157,6 @@ def setup_python(
     )
     env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
 
-    # update env with results from CIBW_ENVIRONMENT
-    env = environment.as_dictionary(prev_environment=env)
-
-    # for the logs - check we're running the right version of python
-    call(["where", "python"], env=env)
-    call(["python", "--version"], env=env)
-    call(["python", "-c", "\"import struct; print(struct.calcsize('P') * 8)\""], env=env)
-    where_python = (
-        subprocess.run(
-            ["where", "python"],
-            env=env,
-            universal_newlines=True,
-            check=True,
-            stdout=subprocess.PIPE,
-        )
-        .stdout.splitlines()[0]
-        .strip()
-    )
-    if where_python != str(installation_path / "python.exe"):
-        print(
-            "cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
-            file=sys.stderr,
-        )
-        sys.exit(1)
-
     log.step("Installing build tools...")
 
     # Install pip
@@ -230,6 +205,32 @@ def setup_python(
         cwd=CIBW_INSTALL_PATH,
     )
 
+    # update env with results from CIBW_ENVIRONMENT
+    env = environment.as_dictionary(prev_environment=env)
+
+    # check what Python version we're on
+    call(["where", "python"], env=env)
+    call(["python", "--version"], env=env)
+    call(["python", "-c", "\"import struct; print(struct.calcsize('P') * 8)\""], env=env)
+    where_python = (
+        subprocess.run(
+            ["where", "python"],
+            env=env,
+            universal_newlines=True,
+            check=True,
+            stdout=subprocess.PIPE,
+        )
+        .stdout.splitlines()[0]
+        .strip()
+    )
+    if where_python != str(installation_path / "python.exe"):
+        print(
+            "cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
+            file=sys.stderr,
+        )
+        sys.exit(1)
+
+    # check what pip version we're on
     assert (installation_path / "Scripts" / "pip.exe").exists()
     where_pip = (
         subprocess.run(


Test patch: