We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Windows: urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
Hello,

Can you, please, help me to debug https://travis-ci.org/github/ets-labs/python-dependency-injector/jobs/739050288?

It occurs only on Windows. Error says: ``urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)>``. I'm unclear whos certificate has expired.

Best,
Roman


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `setup.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 from pathlib import Path
3 
4 try:
5     from setuptools import setup
6 except ImportError:
7     from distutils.core import setup
8 
9 this_directory = Path(__file__).parent
10 long_description = (this_directory / 'README.md').read_text(encoding='utf-8')
11 
12 setup(
13     name='cibuildwheel',
14     version='1.6.3',
15     install_requires=['bashlex!=0.13', 'toml'],
16     description="Build Python wheels on CI with minimal configuration.",
17     long_description=long_description,
18     long_description_content_type='text/markdown',
19     author="Joe Rickerby",
20     author_email='joerick@mac.com',
21     url='https://github.com/joerick/cibuildwheel',
22     project_urls={
23         'Changelog': 'https://github.com/joerick/cibuildwheel#changelog',
24         'Documentation': 'https://cibuildwheel.readthedocs.io/',
25     },
26     packages=['cibuildwheel', ],
27     license="BSD",
28     zip_safe=False,
29     package_data={
30         'cibuildwheel': ['resources/*'],
31     },
32     # Supported python versions
33     python_requires='>=3.6',
34     keywords='ci wheel packaging pypi travis appveyor macos linux windows',
35     classifiers=[
36         'Intended Audience :: Developers',
37         'Natural Language :: English',
38         'Programming Language :: Python :: 3',
39         'Development Status :: 5 - Production/Stable',
40         'License :: OSI Approved :: BSD License',
41         'Programming Language :: Python :: Implementation :: CPython',
42         'Topic :: Software Development :: Build Tools',
43     ],
44     entry_points={
45         'console_scripts': [
46             'cibuildwheel = cibuildwheel.__main__:main',
47         ],
48     },
49 )
50
```

Path: `cibuildwheel/util.py`
Content:
```
1 import os
2 import textwrap
3 import urllib.request
4 from fnmatch import fnmatch
5 from pathlib import Path
6 from time import sleep
7 
8 from typing import Dict, List, NamedTuple, Optional, Union
9 
10 from .environment import ParsedEnvironment
11 
12 
13 def prepare_command(command: str, **kwargs: Union[str, os.PathLike]) -> str:
14     '''
15     Preprocesses a command by expanding variables like {python}.
16 
17     For example, used in the test_command option to specify the path to the
18     project's root.
19     '''
20     return command.format(python='python', pip='pip', **kwargs)
21 
22 
23 def get_build_verbosity_extra_flags(level: int) -> List[str]:
24     if level > 0:
25         return ['-' + level * 'v']
26     elif level < 0:
27         return ['-' + -level * 'q']
28     else:
29         return []
30 
31 
32 class BuildSelector:
33     def __init__(self, build_config: str, skip_config: str):
34         self.build_patterns = build_config.split()
35         self.skip_patterns = skip_config.split()
36 
37     def __call__(self, build_id: str) -> bool:
38         def match_any(patterns: List[str]) -> bool:
39             return any(fnmatch(build_id, pattern) for pattern in patterns)
40         return match_any(self.build_patterns) and not match_any(self.skip_patterns)
41 
42     def __repr__(self) -> str:
43         return f'BuildSelector({" ".join(self.build_patterns)!r} - {" ".join(self.skip_patterns)!r})'
44 
45 
46 # Taken from https://stackoverflow.com/a/107717
47 class Unbuffered:
48     def __init__(self, stream):  # type: ignore
49         self.stream = stream
50 
51     def write(self, data):  # type: ignore
52         self.stream.write(data)
53         self.stream.flush()
54 
55     def writelines(self, datas):  # type: ignore
56         self.stream.writelines(datas)
57         self.stream.flush()
58 
59     def __getattr__(self, attr):  # type: ignore
60         return getattr(self.stream, attr)
61 
62 
63 def download(url: str, dest: Path) -> None:
64     print(f'+ Download {url} to {dest}')
65     dest_dir = dest.parent
66     if not dest_dir.exists():
67         dest_dir.mkdir(parents=True)
68 
69     repeat_num = 3
70     for i in range(repeat_num):
71         try:
72             response = urllib.request.urlopen(url)
73         except Exception:
74             if i == repeat_num - 1:
75                 raise
76             sleep(3)
77             continue
78         break
79 
80     try:
81         dest.write_bytes(response.read())
82     finally:
83         response.close()
84 
85 
86 class DependencyConstraints:
87     def __init__(self, base_file_path: Path):
88         assert base_file_path.exists()
89         self.base_file_path = base_file_path.resolve()
90 
91     @staticmethod
92     def with_defaults() -> 'DependencyConstraints':
93         return DependencyConstraints(
94             base_file_path=resources_dir / 'constraints.txt'
95         )
96 
97     def get_for_python_version(self, version: str) -> Path:
98         version_parts = version.split('.')
99 
100         # try to find a version-specific dependency file e.g. if
101         # ./constraints.txt is the base, look for ./constraints-python27.txt
102         specific_stem = self.base_file_path.stem + f'-python{version_parts[0]}{version_parts[1]}'
103         specific_name = specific_stem + self.base_file_path.suffix
104         specific_file_path = self.base_file_path.with_name(specific_name)
105         if specific_file_path.exists():
106             return specific_file_path
107         else:
108             return self.base_file_path
109 
110     def __str__(self):
111         return f"File '{self.base_file_path}'"
112 
113 
114 class BuildOptions(NamedTuple):
115     package_dir: Path
116     output_dir: Path
117     build_selector: BuildSelector
118     environment: ParsedEnvironment
119     before_all: str
120     before_build: Optional[str]
121     repair_command: str
122     manylinux_images: Optional[Dict[str, str]]
123     dependency_constraints: Optional[DependencyConstraints]
124     test_command: Optional[str]
125     before_test: Optional[str]
126     test_requires: List[str]
127     test_extras: str
128     build_verbosity: int
129 
130 
131 resources_dir = Path(__file__).resolve().parent / 'resources'
132 get_pip_script = resources_dir / 'get-pip.py'
133 install_certifi_script = resources_dir / "install_certifi.py"
134 
135 
136 class NonPlatformWheelError(Exception):
137     def __init__(self) -> None:
138         message = textwrap.dedent('''
139             cibuildwheel: Build failed because a pure Python wheel was generated.
140 
141             If you intend to build a pure-Python wheel, you don't need cibuildwheel - use
142             `pip wheel -w DEST_DIR .` instead.
143 
144             If you expected a platform wheel, check your project configuration, or run
145             cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
146         ''')
147 
148         super().__init__(message)
149
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py
--- a/cibuildwheel/util.py
+++ b/cibuildwheel/util.py
@@ -1,6 +1,8 @@
 import os
 import textwrap
+import certifi
 import urllib.request
+import ssl
 from fnmatch import fnmatch
 from pathlib import Path
 from time import sleep
@@ -66,10 +68,14 @@
     if not dest_dir.exists():
         dest_dir.mkdir(parents=True)
 
+    # we've had issues when relying on the host OS' CA certificates on Windows,
+    # so we use certifi (this sounds odd but requests also does this by default)
+    cafile = os.environ.get('SSL_CERT_FILE', certifi.where())
+    context = ssl.create_default_context(cafile=cafile)
     repeat_num = 3
     for i in range(repeat_num):
         try:
-            response = urllib.request.urlopen(url)
+            response = urllib.request.urlopen(url, context=context)
         except Exception:
             if i == repeat_num - 1:
                 raise
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@
 setup(
     name='cibuildwheel',
     version='1.6.3',
-    install_requires=['bashlex!=0.13', 'toml'],
+    install_requires=['bashlex!=0.13', 'toml', 'certifi'],
     description="Build Python wheels on CI with minimal configuration.",
     long_description=long_description,
     long_description_content_type='text/markdown',

{"golden_diff": "diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py\n--- a/cibuildwheel/util.py\n+++ b/cibuildwheel/util.py\n@@ -1,6 +1,8 @@\n import os\n import textwrap\n+import certifi\n import urllib.request\n+import ssl\n from fnmatch import fnmatch\n from pathlib import Path\n from time import sleep\n@@ -66,10 +68,14 @@\n     if not dest_dir.exists():\n         dest_dir.mkdir(parents=True)\n \n+    # we've had issues when relying on the host OS' CA certificates on Windows,\n+    # so we use certifi (this sounds odd but requests also does this by default)\n+    cafile = os.environ.get('SSL_CERT_FILE', certifi.where())\n+    context = ssl.create_default_context(cafile=cafile)\n     repeat_num = 3\n     for i in range(repeat_num):\n         try:\n-            response = urllib.request.urlopen(url)\n+            response = urllib.request.urlopen(url, context=context)\n         except Exception:\n             if i == repeat_num - 1:\n                 raise\ndiff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -12,7 +12,7 @@\n setup(\n     name='cibuildwheel',\n     version='1.6.3',\n-    install_requires=['bashlex!=0.13', 'toml'],\n+    install_requires=['bashlex!=0.13', 'toml', 'certifi'],\n     description=\"Build Python wheels on CI with minimal configuration.\",\n     long_description=long_description,\n     long_description_content_type='text/markdown',\n", "issue": "Windows: urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed\nHello,\r\n\r\nCan you, please, help me to debug https://travis-ci.org/github/ets-labs/python-dependency-injector/jobs/739050288?\r\n\r\nIt occurs only on Windows. Error says: ``urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)>``. I'm unclear whos certificate has expired.\r\n\r\nBest,\r\nRoman\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom pathlib import Path\n\ntry:\n    from setuptools import setup\nexcept ImportError:\n    from distutils.core import setup\n\nthis_directory = Path(__file__).parent\nlong_description = (this_directory / 'README.md').read_text(encoding='utf-8')\n\nsetup(\n    name='cibuildwheel',\n    version='1.6.3',\n    install_requires=['bashlex!=0.13', 'toml'],\n    description=\"Build Python wheels on CI with minimal configuration.\",\n    long_description=long_description,\n    long_description_content_type='text/markdown',\n    author=\"Joe Rickerby\",\n    author_email='joerick@mac.com',\n    url='https://github.com/joerick/cibuildwheel',\n    project_urls={\n        'Changelog': 'https://github.com/joerick/cibuildwheel#changelog',\n        'Documentation': 'https://cibuildwheel.readthedocs.io/',\n    },\n    packages=['cibuildwheel', ],\n    license=\"BSD\",\n    zip_safe=False,\n    package_data={\n        'cibuildwheel': ['resources/*'],\n    },\n    # Supported python versions\n    python_requires='>=3.6',\n    keywords='ci wheel packaging pypi travis appveyor macos linux windows',\n    classifiers=[\n        'Intended Audience :: Developers',\n        'Natural Language :: English',\n        'Programming Language :: Python :: 3',\n        'Development Status :: 5 - Production/Stable',\n        'License :: OSI Approved :: BSD License',\n        'Programming Language :: Python :: Implementation :: CPython',\n        'Topic :: Software Development :: Build Tools',\n    ],\n    entry_points={\n        'console_scripts': [\n            'cibuildwheel = cibuildwheel.__main__:main',\n        ],\n    },\n)\n", "path": "setup.py"}, {"content": "import os\nimport textwrap\nimport urllib.request\nfrom fnmatch import fnmatch\nfrom pathlib import Path\nfrom time import sleep\n\nfrom typing import Dict, List, NamedTuple, Optional, Union\n\nfrom .environment import ParsedEnvironment\n\n\ndef prepare_command(command: str, **kwargs: Union[str, os.PathLike]) -> str:\n    '''\n    Preprocesses a command by expanding variables like {python}.\n\n    For example, used in the test_command option to specify the path to the\n    project's root.\n    '''\n    return command.format(python='python', pip='pip', **kwargs)\n\n\ndef get_build_verbosity_extra_flags(level: int) -> List[str]:\n    if level > 0:\n        return ['-' + level * 'v']\n    elif level < 0:\n        return ['-' + -level * 'q']\n    else:\n        return []\n\n\nclass BuildSelector:\n    def __init__(self, build_config: str, skip_config: str):\n        self.build_patterns = build_config.split()\n        self.skip_patterns = skip_config.split()\n\n    def __call__(self, build_id: str) -> bool:\n        def match_any(patterns: List[str]) -> bool:\n            return any(fnmatch(build_id, pattern) for pattern in patterns)\n        return match_any(self.build_patterns) and not match_any(self.skip_patterns)\n\n    def __repr__(self) -> str:\n        return f'BuildSelector({\" \".join(self.build_patterns)!r} - {\" \".join(self.skip_patterns)!r})'\n\n\n# Taken from https://stackoverflow.com/a/107717\nclass Unbuffered:\n    def __init__(self, stream):  # type: ignore\n        self.stream = stream\n\n    def write(self, data):  # type: ignore\n        self.stream.write(data)\n        self.stream.flush()\n\n    def writelines(self, datas):  # type: ignore\n        self.stream.writelines(datas)\n        self.stream.flush()\n\n    def __getattr__(self, attr):  # type: ignore\n        return getattr(self.stream, attr)\n\n\ndef download(url: str, dest: Path) -> None:\n    print(f'+ Download {url} to {dest}')\n    dest_dir = dest.parent\n    if not dest_dir.exists():\n        dest_dir.mkdir(parents=True)\n\n    repeat_num = 3\n    for i in range(repeat_num):\n        try:\n            response = urllib.request.urlopen(url)\n        except Exception:\n            if i == repeat_num - 1:\n                raise\n            sleep(3)\n            continue\n        break\n\n    try:\n        dest.write_bytes(response.read())\n    finally:\n        response.close()\n\n\nclass DependencyConstraints:\n    def __init__(self, base_file_path: Path):\n        assert base_file_path.exists()\n        self.base_file_path = base_file_path.resolve()\n\n    @staticmethod\n    def with_defaults() -> 'DependencyConstraints':\n        return DependencyConstraints(\n            base_file_path=resources_dir / 'constraints.txt'\n        )\n\n    def get_for_python_version(self, version: str) -> Path:\n        version_parts = version.split('.')\n\n        # try to find a version-specific dependency file e.g. if\n        # ./constraints.txt is the base, look for ./constraints-python27.txt\n        specific_stem = self.base_file_path.stem + f'-python{version_parts[0]}{version_parts[1]}'\n        specific_name = specific_stem + self.base_file_path.suffix\n        specific_file_path = self.base_file_path.with_name(specific_name)\n        if specific_file_path.exists():\n            return specific_file_path\n        else:\n            return self.base_file_path\n\n    def __str__(self):\n        return f\"File '{self.base_file_path}'\"\n\n\nclass BuildOptions(NamedTuple):\n    package_dir: Path\n    output_dir: Path\n    build_selector: BuildSelector\n    environment: ParsedEnvironment\n    before_all: str\n    before_build: Optional[str]\n    repair_command: str\n    manylinux_images: Optional[Dict[str, str]]\n    dependency_constraints: Optional[DependencyConstraints]\n    test_command: Optional[str]\n    before_test: Optional[str]\n    test_requires: List[str]\n    test_extras: str\n    build_verbosity: int\n\n\nresources_dir = Path(__file__).resolve().parent / 'resources'\nget_pip_script = resources_dir / 'get-pip.py'\ninstall_certifi_script = resources_dir / \"install_certifi.py\"\n\n\nclass NonPlatformWheelError(Exception):\n    def __init__(self) -> None:\n        message = textwrap.dedent('''\n            cibuildwheel: Build failed because a pure Python wheel was generated.\n\n            If you intend to build a pure-Python wheel, you don't need cibuildwheel - use\n            `pip wheel -w DEST_DIR .` instead.\n\n            If you expected a platform wheel, check your project configuration, or run\n            cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.\n        ''')\n\n        super().__init__(message)\n", "path": "cibuildwheel/util.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom pathlib import Path\n\ntry:\n    from setuptools import setup\nexcept ImportError:\n    from distutils.core import setup\n\nthis_directory = Path(__file__).parent\nlong_description = (this_directory / 'README.md').read_text(encoding='utf-8')\n\nsetup(\n    name='cibuildwheel',\n    version='1.6.3',\n    install_requires=['bashlex!=0.13', 'toml', 'certifi'],\n    description=\"Build Python wheels on CI with minimal configuration.\",\n    long_description=long_description,\n    long_description_content_type='text/markdown',\n    author=\"Joe Rickerby\",\n    author_email='joerick@mac.com',\n    url='https://github.com/joerick/cibuildwheel',\n    project_urls={\n        'Changelog': 'https://github.com/joerick/cibuildwheel#changelog',\n        'Documentation': 'https://cibuildwheel.readthedocs.io/',\n    },\n    packages=['cibuildwheel', ],\n    license=\"BSD\",\n    zip_safe=False,\n    package_data={\n        'cibuildwheel': ['resources/*'],\n    },\n    # Supported python versions\n    python_requires='>=3.6',\n    keywords='ci wheel packaging pypi travis appveyor macos linux windows',\n    classifiers=[\n        'Intended Audience :: Developers',\n        'Natural Language :: English',\n        'Programming Language :: Python :: 3',\n        'Development Status :: 5 - Production/Stable',\n        'License :: OSI Approved :: BSD License',\n        'Programming Language :: Python :: Implementation :: CPython',\n        'Topic :: Software Development :: Build Tools',\n    ],\n    entry_points={\n        'console_scripts': [\n            'cibuildwheel = cibuildwheel.__main__:main',\n        ],\n    },\n)\n", "path": "setup.py"}, {"content": "import os\nimport textwrap\nimport certifi\nimport urllib.request\nimport ssl\nfrom fnmatch import fnmatch\nfrom pathlib import Path\nfrom time import sleep\n\nfrom typing import Dict, List, NamedTuple, Optional, Union\n\nfrom .environment import ParsedEnvironment\n\n\ndef prepare_command(command: str, **kwargs: Union[str, os.PathLike]) -> str:\n    '''\n    Preprocesses a command by expanding variables like {python}.\n\n    For example, used in the test_command option to specify the path to the\n    project's root.\n    '''\n    return command.format(python='python', pip='pip', **kwargs)\n\n\ndef get_build_verbosity_extra_flags(level: int) -> List[str]:\n    if level > 0:\n        return ['-' + level * 'v']\n    elif level < 0:\n        return ['-' + -level * 'q']\n    else:\n        return []\n\n\nclass BuildSelector:\n    def __init__(self, build_config: str, skip_config: str):\n        self.build_patterns = build_config.split()\n        self.skip_patterns = skip_config.split()\n\n    def __call__(self, build_id: str) -> bool:\n        def match_any(patterns: List[str]) -> bool:\n            return any(fnmatch(build_id, pattern) for pattern in patterns)\n        return match_any(self.build_patterns) and not match_any(self.skip_patterns)\n\n    def __repr__(self) -> str:\n        return f'BuildSelector({\" \".join(self.build_patterns)!r} - {\" \".join(self.skip_patterns)!r})'\n\n\n# Taken from https://stackoverflow.com/a/107717\nclass Unbuffered:\n    def __init__(self, stream):  # type: ignore\n        self.stream = stream\n\n    def write(self, data):  # type: ignore\n        self.stream.write(data)\n        self.stream.flush()\n\n    def writelines(self, datas):  # type: ignore\n        self.stream.writelines(datas)\n        self.stream.flush()\n\n    def __getattr__(self, attr):  # type: ignore\n        return getattr(self.stream, attr)\n\n\ndef download(url: str, dest: Path) -> None:\n    print(f'+ Download {url} to {dest}')\n    dest_dir = dest.parent\n    if not dest_dir.exists():\n        dest_dir.mkdir(parents=True)\n\n    # we've had issues when relying on the host OS' CA certificates on Windows,\n    # so we use certifi (this sounds odd but requests also does this by default)\n    cafile = os.environ.get('SSL_CERT_FILE', certifi.where())\n    context = ssl.create_default_context(cafile=cafile)\n    repeat_num = 3\n    for i in range(repeat_num):\n        try:\n            response = urllib.request.urlopen(url, context=context)\n        except Exception:\n            if i == repeat_num - 1:\n                raise\n            sleep(3)\n            continue\n        break\n\n    try:\n        dest.write_bytes(response.read())\n    finally:\n        response.close()\n\n\nclass DependencyConstraints:\n    def __init__(self, base_file_path: Path):\n        assert base_file_path.exists()\n        self.base_file_path = base_file_path.resolve()\n\n    @staticmethod\n    def with_defaults() -> 'DependencyConstraints':\n        return DependencyConstraints(\n            base_file_path=resources_dir / 'constraints.txt'\n        )\n\n    def get_for_python_version(self, version: str) -> Path:\n        version_parts = version.split('.')\n\n        # try to find a version-specific dependency file e.g. if\n        # ./constraints.txt is the base, look for ./constraints-python27.txt\n        specific_stem = self.base_file_path.stem + f'-python{version_parts[0]}{version_parts[1]}'\n        specific_name = specific_stem + self.base_file_path.suffix\n        specific_file_path = self.base_file_path.with_name(specific_name)\n        if specific_file_path.exists():\n            return specific_file_path\n        else:\n            return self.base_file_path\n\n    def __str__(self):\n        return f\"File '{self.base_file_path}'\"\n\n\nclass BuildOptions(NamedTuple):\n    package_dir: Path\n    output_dir: Path\n    build_selector: BuildSelector\n    environment: ParsedEnvironment\n    before_all: str\n    before_build: Optional[str]\n    repair_command: str\n    manylinux_images: Optional[Dict[str, str]]\n    dependency_constraints: Optional[DependencyConstraints]\n    test_command: Optional[str]\n    before_test: Optional[str]\n    test_requires: List[str]\n    test_extras: str\n    build_verbosity: int\n\n\nresources_dir = Path(__file__).resolve().parent / 'resources'\nget_pip_script = resources_dir / 'get-pip.py'\ninstall_certifi_script = resources_dir / \"install_certifi.py\"\n\n\nclass NonPlatformWheelError(Exception):\n    def __init__(self) -> None:\n        message = textwrap.dedent('''\n            cibuildwheel: Build failed because a pure Python wheel was generated.\n\n            If you intend to build a pure-Python wheel, you don't need cibuildwheel - use\n            `pip wheel -w DEST_DIR .` instead.\n\n            If you expected a platform wheel, check your project configuration, or run\n            cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.\n        ''')\n\n        super().__init__(message)\n", "path": "cibuildwheel/util.py"}]}