1import os
2import sys
3
4from pipenv.patched.notpip._internal.utils.typing import MYPY_CHECK_RUNNING
5
6if MYPY_CHECK_RUNNING:
7    from typing import List, Optional, Sequence
8
9# Shim to wrap setup.py invocation with setuptools
10#
11# We set sys.argv[0] to the path to the underlying setup.py file so
12# setuptools / distutils don't take the path to the setup.py to be "-c" when
13# invoking via the shim.  This avoids e.g. the following manifest_maker
14# warning: "warning: manifest_maker: standard file '-c' not found".
15_SETUPTOOLS_SHIM = (
16    "import sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};"
17    "f=getattr(tokenize, 'open', open)(__file__);"
18    "code=f.read().replace('\\r\\n', '\\n');"
19    "f.close();"
20    "exec(compile(code, __file__, 'exec'))"
21)
22
23
24def make_setuptools_shim_args(
25    setup_py_path,  # type: str
26    global_options=None,  # type: Sequence[str]
27    no_user_config=False,  # type: bool
28    unbuffered_output=False  # type: bool
29):
30    # type: (...) -> List[str]
31    """
32    Get setuptools command arguments with shim wrapped setup file invocation.
33
34    :param setup_py_path: The path to setup.py to be wrapped.
35    :param global_options: Additional global options.
36    :param no_user_config: If True, disables personal user configuration.
37    :param unbuffered_output: If True, adds the unbuffered switch to the
38     argument list.
39    """
40    sys_executable = os.environ.get('PIP_PYTHON_PATH', sys.executable)
41    args = [sys_executable]
42    if unbuffered_output:
43        args += ["-u"]
44    args += ["-c", _SETUPTOOLS_SHIM.format(setup_py_path)]
45    if global_options:
46        args += global_options
47    if no_user_config:
48        args += ["--no-user-cfg"]
49    return args
50
51
52def make_setuptools_bdist_wheel_args(
53    setup_py_path,  # type: str
54    global_options,  # type: Sequence[str]
55    build_options,  # type: Sequence[str]
56    destination_dir,  # type: str
57):
58    # type: (...) -> List[str]
59    # NOTE: Eventually, we'd want to also -S to the flags here, when we're
60    # isolating. Currently, it breaks Python in virtualenvs, because it
61    # relies on site.py to find parts of the standard library outside the
62    # virtualenv.
63    args = make_setuptools_shim_args(
64        setup_py_path,
65        global_options=global_options,
66        unbuffered_output=True
67    )
68    args += ["bdist_wheel", "-d", destination_dir]
69    args += build_options
70    return args
71
72
73def make_setuptools_clean_args(
74    setup_py_path,  # type: str
75    global_options,  # type: Sequence[str]
76):
77    # type: (...) -> List[str]
78    args = make_setuptools_shim_args(
79        setup_py_path,
80        global_options=global_options,
81        unbuffered_output=True
82    )
83    args += ["clean", "--all"]
84    return args
85
86
87def make_setuptools_develop_args(
88    setup_py_path,  # type: str
89    global_options,  # type: Sequence[str]
90    install_options,  # type: Sequence[str]
91    no_user_config,  # type: bool
92    prefix,  # type: Optional[str]
93    home,  # type: Optional[str]
94    use_user_site,  # type: bool
95):
96    # type: (...) -> List[str]
97    assert not (use_user_site and prefix)
98
99    args = make_setuptools_shim_args(
100        setup_py_path,
101        global_options=global_options,
102        no_user_config=no_user_config,
103    )
104
105    args += ["develop", "--no-deps"]
106
107    args += install_options
108
109    if prefix:
110        args += ["--prefix", prefix]
111    if home is not None:
112        args += ["--home", home]
113
114    if use_user_site:
115        args += ["--user", "--prefix="]
116
117    return args
118
119
120def make_setuptools_egg_info_args(
121    setup_py_path,  # type: str
122    egg_info_dir,  # type: Optional[str]
123    no_user_config,  # type: bool
124):
125    # type: (...) -> List[str]
126    args = make_setuptools_shim_args(setup_py_path)
127    if no_user_config:
128        args += ["--no-user-cfg"]
129
130    args += ["egg_info"]
131
132    if egg_info_dir:
133        args += ["--egg-base", egg_info_dir]
134
135    return args
136
137
138def make_setuptools_install_args(
139    setup_py_path,  # type: str
140    global_options,  # type: Sequence[str]
141    install_options,  # type: Sequence[str]
142    record_filename,  # type: str
143    root,  # type: Optional[str]
144    prefix,  # type: Optional[str]
145    header_dir,  # type: Optional[str]
146    home,  # type: Optional[str]
147    use_user_site,  # type: bool
148    no_user_config,  # type: bool
149    pycompile  # type: bool
150):
151    # type: (...) -> List[str]
152    assert not (use_user_site and prefix)
153    assert not (use_user_site and root)
154
155    args = make_setuptools_shim_args(
156        setup_py_path,
157        global_options=global_options,
158        no_user_config=no_user_config,
159        unbuffered_output=True
160    )
161    args += ["install", "--record", record_filename]
162    args += ["--single-version-externally-managed"]
163
164    if root is not None:
165        args += ["--root", root]
166    if prefix is not None:
167        args += ["--prefix", prefix]
168    if home is not None:
169        args += ["--home", home]
170    if use_user_site:
171        args += ["--user", "--prefix="]
172
173    if pycompile:
174        args += ["--compile"]
175    else:
176        args += ["--no-compile"]
177
178    if header_dir:
179        args += ["--install-headers", header_dir]
180
181    args += install_options
182
183    return args
184