Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
pip._internal.pyproject Namespace Reference

Functions

bool _is_list_of_str (Any obj)
 
str make_pyproject_path (str unpacked_source_directory)
 
Optional[BuildSystemDetailsload_pyproject_toml (Optional[bool] use_pep517, str pyproject_toml, str setup_py, str req_name)
 

Variables

 BuildSystemDetails
 

Function Documentation

◆ _is_list_of_str()

bool _is_list_of_str ( Any  obj)
protected

Definition at line 16 of file pyproject.py.

16def _is_list_of_str(obj: Any) -> bool:
17 return isinstance(obj, list) and all(isinstance(item, str) for item in obj)
18
19
for i

References i.

Referenced by pip._internal.pyproject.load_pyproject_toml().

Here is the caller graph for this function:

◆ load_pyproject_toml()

Optional[BuildSystemDetails] load_pyproject_toml ( Optional[bool]  use_pep517,
str  pyproject_toml,
str  setup_py,
str   req_name 
)
Load the pyproject.toml file.

Parameters:
    use_pep517 - Has the user requested PEP 517 processing? None
                 means the user hasn't explicitly specified.
    pyproject_toml - Location of the project's pyproject.toml file
    setup_py - Location of the project's setup.py file
    req_name - The name of the requirement we're processing (for
               error reporting)

Returns:
    None if we should use the legacy code path, otherwise a tuple
    (
        requirements from pyproject.toml,
        name of PEP 517 backend,
        requirements we should check are installed after setting
            up the build environment
        directory paths to import the backend from (backend-path),
            relative to the project root.
    )

Definition at line 29 of file pyproject.py.

31) -> Optional[BuildSystemDetails]:
32 """Load the pyproject.toml file.
33
34 Parameters:
35 use_pep517 - Has the user requested PEP 517 processing? None
36 means the user hasn't explicitly specified.
37 pyproject_toml - Location of the project's pyproject.toml file
38 setup_py - Location of the project's setup.py file
39 req_name - The name of the requirement we're processing (for
40 error reporting)
41
42 Returns:
43 None if we should use the legacy code path, otherwise a tuple
44 (
45 requirements from pyproject.toml,
46 name of PEP 517 backend,
47 requirements we should check are installed after setting
48 up the build environment
49 directory paths to import the backend from (backend-path),
50 relative to the project root.
51 )
52 """
53 has_pyproject = os.path.isfile(pyproject_toml)
54 has_setup = os.path.isfile(setup_py)
55
56 if not has_pyproject and not has_setup:
57 raise InstallationError(
58 f"{req_name} does not appear to be a Python project: "
59 f"neither 'setup.py' nor 'pyproject.toml' found."
60 )
61
62 if has_pyproject:
63 with open(pyproject_toml, encoding="utf-8") as f:
64 pp_toml = tomli.loads(f.read())
65 build_system = pp_toml.get("build-system")
66 else:
67 build_system = None
68
69 # The following cases must use PEP 517
70 # We check for use_pep517 being non-None and falsey because that means
71 # the user explicitly requested --no-use-pep517. The value 0 as
72 # opposed to False can occur when the value is provided via an
73 # environment variable or config file option (due to the quirk of
74 # strtobool() returning an integer in pip's configuration code).
75 if has_pyproject and not has_setup:
76 if use_pep517 is not None and not use_pep517:
77 raise InstallationError(
78 "Disabling PEP 517 processing is invalid: "
79 "project does not have a setup.py"
80 )
81 use_pep517 = True
82 elif build_system and "build-backend" in build_system:
83 if use_pep517 is not None and not use_pep517:
84 raise InstallationError(
85 "Disabling PEP 517 processing is invalid: "
86 "project specifies a build backend of {} "
87 "in pyproject.toml".format(build_system["build-backend"])
88 )
89 use_pep517 = True
90
91 # If we haven't worked out whether to use PEP 517 yet,
92 # and the user hasn't explicitly stated a preference,
93 # we do so if the project has a pyproject.toml file
94 # or if we cannot import setuptools or wheels.
95
96 # We fallback to PEP 517 when without setuptools or without the wheel package,
97 # so setuptools can be installed as a default build backend.
98 # For more info see:
99 # https://discuss.python.org/t/pip-without-setuptools-could-the-experience-be-improved/11810/9
100 # https://github.com/pypa/pip/issues/8559
101 elif use_pep517 is None:
102 use_pep517 = (
103 has_pyproject
104 or not importlib.util.find_spec("setuptools")
105 or not importlib.util.find_spec("wheel")
106 )
107
108 # At this point, we know whether we're going to use PEP 517.
109 assert use_pep517 is not None
110
111 # If we're using the legacy code path, there is nothing further
112 # for us to do here.
113 if not use_pep517:
114 return None
115
116 if build_system is None:
117 # Either the user has a pyproject.toml with no build-system
118 # section, or the user has no pyproject.toml, but has opted in
119 # explicitly via --use-pep517.
120 # In the absence of any explicit backend specification, we
121 # assume the setuptools backend that most closely emulates the
122 # traditional direct setup.py execution, and require wheel and
123 # a version of setuptools that supports that backend.
124
125 build_system = {
126 "requires": ["setuptools>=40.8.0", "wheel"],
127 "build-backend": "setuptools.build_meta:__legacy__",
128 }
129
130 # If we're using PEP 517, we have build system information (either
131 # from pyproject.toml, or defaulted by the code above).
132 # Note that at this point, we do not know if the user has actually
133 # specified a backend, though.
134 assert build_system is not None
135
136 # Ensure that the build-system section in pyproject.toml conforms
137 # to PEP 518.
138
139 # Specifying the build-system table but not the requires key is invalid
140 if "requires" not in build_system:
141 raise MissingPyProjectBuildRequires(package=req_name)
142
143 # Error out if requires is not a list of strings
144 requires = build_system["requires"]
145 if not _is_list_of_str(requires):
146 raise InvalidPyProjectBuildRequires(
147 package=req_name,
148 reason="It is not a list of strings.",
149 )
150
151 # Each requirement must be valid as per PEP 508
152 for requirement in requires:
153 try:
154 Requirement(requirement)
155 except InvalidRequirement as error:
156 raise InvalidPyProjectBuildRequires(
157 package=req_name,
158 reason=f"It contains an invalid requirement: {requirement!r}",
159 ) from error
160
161 backend = build_system.get("build-backend")
162 backend_path = build_system.get("backend-path", [])
163 check: List[str] = []
164 if backend is None:
165 # If the user didn't specify a backend, we assume they want to use
166 # the setuptools backend. But we can't be sure they have included
167 # a version of setuptools which supplies the backend. So we
168 # make a note to check that this requirement is present once
169 # we have set up the environment.
170 # This is quite a lot of work to check for a very specific case. But
171 # the problem is, that case is potentially quite common - projects that
172 # adopted PEP 518 early for the ability to specify requirements to
173 # execute setup.py, but never considered needing to mention the build
174 # tools themselves. The original PEP 518 code had a similar check (but
175 # implemented in a different way).
176 backend = "setuptools.build_meta:__legacy__"
177 check = ["setuptools>=40.8.0"]
178
179 return BuildSystemDetails(requires, backend, check, backend_path)

References pip._internal.pyproject._is_list_of_str(), pip._internal.pyproject.BuildSystemDetails, and i.

Here is the call graph for this function:

◆ make_pyproject_path()

str make_pyproject_path ( str  unpacked_source_directory)

Definition at line 20 of file pyproject.py.

20def make_pyproject_path(unpacked_source_directory: str) -> str:
21 return os.path.join(unpacked_source_directory, "pyproject.toml")
22
23

References i.

Variable Documentation

◆ BuildSystemDetails

BuildSystemDetails
Initial value:
1= namedtuple(
2 "BuildSystemDetails", ["requires", "backend", "check", "backend_path"]
3)

Definition at line 24 of file pyproject.py.

Referenced by pip._internal.pyproject.load_pyproject_toml().