30
30
from importlib .metadata import Distribution , PathDistribution
31
31
else : # pragma: no cover (<py38)
32
32
from importlib_metadata import Distribution , PathDistribution
33
+
34
+ if sys .version_info >= (3 , 11 ): # pragma: no cover (py311+)
35
+ import tomllib
36
+ else : # pragma: no cover (py311+)
37
+ import tomli as tomllib
38
+
33
39
ConfigSettings = Optional [Dict [str , Any ]]
34
40
35
41
@@ -143,23 +149,14 @@ def _teardown(self) -> None:
143
149
144
150
def perform_packaging (self , for_env : EnvConfigSet ) -> list [Package ]:
145
151
"""build the package to install"""
152
+ deps = self ._load_deps (for_env )
146
153
of_type : str = for_env ["package" ]
147
-
148
- reqs : list [Requirement ] | None = None
149
- if of_type == "wheel" :
150
- w_env = self ._wheel_build_envs .get (for_env ["wheel_build_env" ])
151
- if w_env is not None and w_env is not self :
152
- with w_env .display_context (self ._has_display_suspended ):
153
- reqs = w_env .get_package_dependencies () if isinstance (w_env , Pep517VirtualEnvPackager ) else []
154
- if reqs is None :
155
- reqs = self .get_package_dependencies ()
156
-
157
- extras : set [str ] = for_env ["extras" ]
158
- deps = dependencies_with_extras (reqs , extras )
159
154
if of_type == "dev-legacy" :
155
+ self .setup ()
160
156
deps = [* self .requires (), * self ._frontend .get_requires_for_build_sdist ().requires ] + deps
161
157
package : Package = DevLegacyPackage (self .core ["tox_root" ], deps ) # the folder itself is the package
162
158
elif of_type == "sdist" :
159
+ self .setup ()
163
160
with self ._pkg_lock :
164
161
package = SdistPackage (self ._frontend .build_sdist (sdist_directory = self .pkg_dir ).sdist , deps )
165
162
elif of_type == "wheel" :
@@ -168,6 +165,7 @@ def perform_packaging(self, for_env: EnvConfigSet) -> list[Package]:
168
165
with w_env .display_context (self ._has_display_suspended ):
169
166
return w_env .perform_packaging (for_env )
170
167
else :
168
+ self .setup ()
171
169
with self ._pkg_lock :
172
170
path = self ._frontend .build_wheel (
173
171
wheel_directory = self .pkg_dir ,
@@ -179,6 +177,49 @@ def perform_packaging(self, for_env: EnvConfigSet) -> list[Package]:
179
177
raise TypeError (f"cannot handle package type { of_type } " ) # pragma: no cover
180
178
return [package ]
181
179
180
+ def _load_deps (self , for_env : EnvConfigSet ) -> list [Requirement ]:
181
+ # first check if this is statically available via PEP-621
182
+ deps = self ._load_deps_from_static (for_env )
183
+ if deps is None :
184
+ deps = self ._load_deps_from_built_metadata (for_env )
185
+ return deps
186
+
187
+ def _load_deps_from_static (self , for_env : EnvConfigSet ) -> list [Requirement ] | None :
188
+ pyproject_file = self .core ["package_root" ] / "pyproject.toml"
189
+ if not pyproject_file .exists (): # check if it's static PEP-621 metadata
190
+ return None
191
+ with pyproject_file .open ("rb" ) as file_handler :
192
+ pyproject = tomllib .load (file_handler )
193
+ if "project" not in pyproject :
194
+ return None # is not a PEP-621 pyproject
195
+ project = pyproject ["project" ]
196
+ extras : set [str ] = for_env ["extras" ]
197
+ for dynamic in project .get ("dynamic" , []):
198
+ if dynamic == "dependencies" or (extras and dynamic == "optional-dependencies" ):
199
+ return None # if any dependencies are dynamic we can just calculate all dynamically
200
+
201
+ deps : list [Requirement ] = [Requirement (i ) for i in project .get ("dependencies" , [])]
202
+ optional_deps = project .get ("optional-dependencies" , {})
203
+ for extra in extras :
204
+ deps .extend (Requirement (i ) for i in optional_deps .get (extra , []))
205
+ return deps
206
+
207
+ def _load_deps_from_built_metadata (self , for_env : EnvConfigSet ) -> list [Requirement ]:
208
+ # dependencies might depend on the python environment we're running in => if we build a wheel use that env
209
+ # to calculate the package metadata, otherwise ourselves
210
+ of_type : str = for_env ["package" ]
211
+ reqs : list [Requirement ] | None = None
212
+ if of_type == "wheel" : # wheel packages
213
+ w_env = self ._wheel_build_envs .get (for_env ["wheel_build_env" ])
214
+ if w_env is not None and w_env is not self :
215
+ with w_env .display_context (self ._has_display_suspended ):
216
+ reqs = w_env .get_package_dependencies () if isinstance (w_env , Pep517VirtualEnvPackager ) else []
217
+ if reqs is None :
218
+ reqs = self .get_package_dependencies ()
219
+ extras : set [str ] = for_env ["extras" ]
220
+ deps = dependencies_with_extras (reqs , extras )
221
+ return deps
222
+
182
223
def get_package_dependencies (self ) -> list [Requirement ]:
183
224
with self ._pkg_lock :
184
225
if self ._package_dependencies is None : # pragma: no branch
0 commit comments