Skip to content

Commit 824f6fc

Browse files
bonzinidcbaker
authored andcommitted
cargo: move TypedDicts for Cargo.toml to "raw" module
Fix a few issues: * Cargo.lock's version is an int * Different BuildTargets have different types for the argument of from_raw Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 939cfa6 commit 824f6fc

File tree

3 files changed

+208
-194
lines changed

3 files changed

+208
-194
lines changed

mesonbuild/cargo/interpreter.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
if T.TYPE_CHECKING:
2727
from typing_extensions import Protocol, Self
2828

29-
from . import manifest
29+
from . import manifest, raw
3030
from .. import mparser
3131
from ..environment import Environment
3232
from ..interpreterbase import SubProject
@@ -40,6 +40,8 @@ class DataclassInstance(Protocol):
4040
manifest.FixedDependency, manifest.FixedLibTarget,
4141
manifest.FixedBuildTarget)
4242

43+
_R = T.TypeVar('_R', bound='raw._BaseBuildTarget')
44+
4345

4446
_EXTRA_KEYS_WARNING = (
4547
"This may (unlikely) be an error in the cargo manifest, or may be a missing "
@@ -61,15 +63,15 @@ def fixup_meson_varname(name: str) -> str:
6163

6264
# Pylance can figure out that these do not, in fact, overlap, but mypy can't
6365
@T.overload
64-
def _fixup_raw_mappings(d: manifest.BuildTarget) -> manifest.FixedBuildTarget: ... # type: ignore
66+
def _fixup_raw_mappings(d: raw.BuildTarget) -> manifest.FixedBuildTarget: ... # type: ignore
6567

6668
@T.overload
67-
def _fixup_raw_mappings(d: manifest.LibTarget) -> manifest.FixedLibTarget: ... # type: ignore
69+
def _fixup_raw_mappings(d: raw.LibTarget) -> manifest.FixedLibTarget: ... # type: ignore
6870

6971
@T.overload
70-
def _fixup_raw_mappings(d: manifest.Dependency) -> manifest.FixedDependency: ...
72+
def _fixup_raw_mappings(d: raw.Dependency) -> manifest.FixedDependency: ...
7173

72-
def _fixup_raw_mappings(d: T.Union[manifest.BuildTarget, manifest.LibTarget, manifest.Dependency]
74+
def _fixup_raw_mappings(d: T.Union[raw.BuildTarget, raw.LibTarget, raw.Dependency]
7375
) -> T.Union[manifest.FixedBuildTarget, manifest.FixedLibTarget,
7476
manifest.FixedDependency]:
7577
"""Fixup raw cargo mappings to ones more suitable for python to consume.
@@ -153,7 +155,7 @@ def __post_init__(self) -> None:
153155
self.api = _version_to_api(self.version)
154156

155157
@classmethod
156-
def from_raw(cls, raw: manifest.Package) -> Self:
158+
def from_raw(cls, raw: raw.Package) -> Self:
157159
pkg = T.cast('manifest.FixedPackage',
158160
{fixup_meson_varname(k): v for k, v in raw.items()})
159161
pkg = _handle_unknown_keys(pkg, cls, f'Package entry {pkg["name"]}')
@@ -233,7 +235,7 @@ def __post_init__(self, name: str) -> None:
233235
raise MesonException(f'Cannot determine minimum API version from {self.version}.')
234236

235237
@classmethod
236-
def from_raw(cls, name: str, raw: manifest.DependencyV) -> Dependency:
238+
def from_raw(cls, name: str, raw: raw.DependencyV) -> Dependency:
237239
"""Create a dependency from a raw cargo dictionary"""
238240
if isinstance(raw, str):
239241
return cls(name, version.convert(raw))
@@ -242,7 +244,7 @@ def from_raw(cls, name: str, raw: manifest.DependencyV) -> Dependency:
242244

243245

244246
@dataclasses.dataclass
245-
class BuildTarget:
247+
class BuildTarget(T.Generic[_R]):
246248

247249
name: str
248250
crate_type: T.List[manifest.CRATE_TYPE] = dataclasses.field(default_factory=lambda: ['lib'])
@@ -270,13 +272,13 @@ class BuildTarget:
270272
plugin: bool = False
271273

272274
@classmethod
273-
def from_raw(cls, raw: manifest.BuildTarget) -> Self:
275+
def from_raw(cls, raw: raw.BuildTarget) -> Self:
274276
name = raw.get('name', '<anonymous>')
275277
build = _handle_unknown_keys(_fixup_raw_mappings(raw), cls, f'Binary entry {name}')
276278
return cls(**build)
277279

278280
@dataclasses.dataclass
279-
class Library(BuildTarget):
281+
class Library(BuildTarget['raw.LibTarget']):
280282

281283
"""Representation of a Cargo Library Entry."""
282284

@@ -288,44 +290,44 @@ class Library(BuildTarget):
288290
doc_scrape_examples: bool = True
289291

290292
@classmethod
291-
def from_raw(cls, raw: manifest.LibTarget, fallback_name: str) -> Self: # type: ignore[override]
293+
def from_raw(cls, raw: raw.LibTarget, fallback_name: str) -> Self: # type: ignore[override]
294+
if 'name' not in raw:
295+
raw['name'] = fallback_name
292296
fixed = _fixup_raw_mappings(raw)
293297

294298
# We need to set the name field if it's not set manually, including if
295299
# other fields are set in the lib section
296-
if 'name' not in fixed:
297-
fixed['name'] = fallback_name
298300
fixed = _handle_unknown_keys(fixed, cls, f'Library entry {fixed["name"]}')
299301

300302
return cls(**fixed)
301303

302304

303305
@dataclasses.dataclass
304-
class Binary(BuildTarget):
306+
class Binary(BuildTarget['raw.BuildTarget']):
305307

306308
"""Representation of a Cargo Bin Entry."""
307309

308310
doc: bool = True
309311

310312

311313
@dataclasses.dataclass
312-
class Test(BuildTarget):
314+
class Test(BuildTarget['raw.BuildTarget']):
313315

314316
"""Representation of a Cargo Test Entry."""
315317

316318
bench: bool = True
317319

318320

319321
@dataclasses.dataclass
320-
class Benchmark(BuildTarget):
322+
class Benchmark(BuildTarget['raw.BuildTarget']):
321323

322324
"""Representation of a Cargo Benchmark Entry."""
323325

324326
test: bool = True
325327

326328

327329
@dataclasses.dataclass
328-
class Example(BuildTarget):
330+
class Example(BuildTarget['raw.BuildTarget']):
329331

330332
"""Representation of a Cargo Example Entry."""
331333

@@ -365,7 +367,7 @@ def __post_init__(self) -> None:
365367
self.system_dependencies = {k: SystemDependency.from_raw(k, v) for k, v in self.package.metadata.get('system-deps', {}).items()}
366368

367369

368-
def _convert_manifest(raw_manifest: manifest.Manifest, subdir: str, path: str = '') -> Manifest:
370+
def _convert_manifest(raw_manifest: raw.Manifest, subdir: str, path: str = '') -> Manifest:
369371
return Manifest(
370372
Package.from_raw(raw_manifest['package']),
371373
{k: Dependency.from_raw(k, v) for k, v in raw_manifest.get('dependencies', {}).items()},
@@ -503,9 +505,9 @@ def _load_manifest(self, subdir: str) -> Manifest:
503505
manifest_ = self.manifests.get(subdir)
504506
if not manifest_:
505507
filename = os.path.join(self.environment.source_dir, subdir, 'Cargo.toml')
506-
raw = load_toml(filename)
507-
if 'package' in raw:
508-
raw_manifest = T.cast('manifest.Manifest', raw)
508+
toml = load_toml(filename)
509+
if 'package' in toml:
510+
raw_manifest = T.cast('raw.Manifest', toml)
509511
manifest_ = _convert_manifest(raw_manifest, subdir)
510512
self.manifests[subdir] = manifest_
511513
else:
@@ -821,7 +823,7 @@ def load_wraps(source_dir: str, subproject_dir: str) -> T.List[PackageDefinition
821823
filename = os.path.join(source_dir, 'Cargo.lock')
822824
if os.path.exists(filename):
823825
try:
824-
cargolock = T.cast('manifest.CargoLock', load_toml(filename))
826+
cargolock = T.cast('raw.CargoLock', load_toml(filename))
825827
except TomlImplementationMissing as e:
826828
mlog.warning('Failed to load Cargo.lock:', str(e), fatal=False)
827829
return wraps

mesonbuild/cargo/manifest.py

Lines changed: 5 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,9 @@
66
from __future__ import annotations
77
import typing as T
88

9-
from typing_extensions import Literal, TypedDict, Required
10-
11-
EDITION = Literal['2015', '2018', '2021']
12-
CRATE_TYPE = Literal['bin', 'lib', 'dylib', 'staticlib', 'cdylib', 'rlib', 'proc-macro']
13-
14-
Package = TypedDict(
15-
'Package',
16-
{
17-
'name': Required[str],
18-
'version': Required[str],
19-
'authors': T.List[str],
20-
'edition': EDITION,
21-
'rust-version': str,
22-
'description': str,
23-
'readme': str,
24-
'license': str,
25-
'license-file': str,
26-
'keywords': T.List[str],
27-
'categories': T.List[str],
28-
'workspace': str,
29-
'build': str,
30-
'links': str,
31-
'include': T.List[str],
32-
'exclude': T.List[str],
33-
'publish': bool,
34-
'metadata': T.Dict[str, T.Dict[str, str]],
35-
'default-run': str,
36-
'autolib': bool,
37-
'autobins': bool,
38-
'autoexamples': bool,
39-
'autotests': bool,
40-
'autobenches': bool,
41-
},
42-
total=False,
43-
)
44-
"""A description of the Package Dictionary."""
9+
from typing_extensions import TypedDict, Required
10+
11+
from .raw import EDITION, CRATE_TYPE
4512

4613
class FixedPackage(TypedDict, total=False):
4714

@@ -73,32 +40,6 @@ class FixedPackage(TypedDict, total=False):
7340
autobenches: bool
7441

7542

76-
class Badge(TypedDict):
77-
78-
"""An entry in the badge section."""
79-
80-
status: Literal['actively-developed', 'passively-developed', 'as-is', 'experimental', 'deprecated', 'none']
81-
82-
83-
Dependency = TypedDict(
84-
'Dependency',
85-
{
86-
'version': str,
87-
'registry': str,
88-
'git': str,
89-
'branch': str,
90-
'rev': str,
91-
'path': str,
92-
'optional': bool,
93-
'package': str,
94-
'default-features': bool,
95-
'features': T.List[str],
96-
},
97-
total=False,
98-
)
99-
"""An entry in the *dependencies sections."""
100-
101-
10243
class FixedDependency(TypedDict, total=False):
10344

10445
"""An entry in the *dependencies sections, fixed up."""
@@ -115,38 +56,6 @@ class FixedDependency(TypedDict, total=False):
11556
features: T.List[str]
11657

11758

118-
DependencyV = T.Union[Dependency, str]
119-
"""A Dependency entry, either a string or a Dependency Dict."""
120-
121-
122-
_BaseBuildTarget = TypedDict(
123-
'_BaseBuildTarget',
124-
{
125-
'path': str,
126-
'test': bool,
127-
'doctest': bool,
128-
'bench': bool,
129-
'doc': bool,
130-
'plugin': bool,
131-
'proc-macro': bool,
132-
'harness': bool,
133-
'edition': EDITION,
134-
'crate-type': T.List[CRATE_TYPE],
135-
'required-features': T.List[str],
136-
},
137-
total=False,
138-
)
139-
140-
141-
class BuildTarget(_BaseBuildTarget, total=False):
142-
143-
name: Required[str]
144-
145-
class LibTarget(_BaseBuildTarget, total=False):
146-
147-
name: str
148-
149-
15059
class _BaseFixedBuildTarget(TypedDict, total=False):
15160
path: str
15261
test: bool
@@ -162,86 +71,10 @@ class _BaseFixedBuildTarget(TypedDict, total=False):
16271

16372
class FixedBuildTarget(_BaseFixedBuildTarget, total=False):
16473

165-
name: str
166-
167-
class FixedLibTarget(_BaseFixedBuildTarget, total=False):
168-
16974
name: Required[str]
170-
proc_macro: bool
171-
17275

173-
class Target(TypedDict):
17476

175-
"""Target entry in the Manifest File."""
176-
177-
dependencies: T.Dict[str, DependencyV]
178-
179-
180-
class Workspace(TypedDict):
181-
182-
"""The representation of a workspace.
183-
184-
In a vritual manifest the :attribute:`members` is always present, but in a
185-
project manifest, an empty workspace may be provided, in which case the
186-
workspace is implicitly filled in by values from the path based dependencies.
187-
188-
the :attribute:`exclude` is always optional
189-
"""
190-
191-
members: T.List[str]
192-
exclude: T.List[str]
193-
194-
195-
Manifest = TypedDict(
196-
'Manifest',
197-
{
198-
'package': Required[Package],
199-
'badges': T.Dict[str, Badge],
200-
'dependencies': T.Dict[str, DependencyV],
201-
'dev-dependencies': T.Dict[str, DependencyV],
202-
'build-dependencies': T.Dict[str, DependencyV],
203-
'lib': LibTarget,
204-
'bin': T.List[BuildTarget],
205-
'test': T.List[BuildTarget],
206-
'bench': T.List[BuildTarget],
207-
'example': T.List[BuildTarget],
208-
'features': T.Dict[str, T.List[str]],
209-
'target': T.Dict[str, Target],
210-
'workspace': Workspace,
211-
212-
# TODO: patch?
213-
# TODO: replace?
214-
},
215-
total=False,
216-
)
217-
"""The Cargo Manifest format."""
218-
219-
220-
class VirtualManifest(TypedDict):
221-
222-
"""The Representation of a virtual manifest.
223-
224-
Cargo allows a root manifest that contains only a workspace, this is called
225-
a virtual manifest. This doesn't really map 1:1 with any meson concept,
226-
except perhaps the proposed "meta project".
227-
"""
228-
229-
workspace: Workspace
230-
231-
class CargoLockPackage(TypedDict, total=False):
232-
233-
"""A description of a package in the Cargo.lock file format."""
77+
class FixedLibTarget(_BaseFixedBuildTarget, total=False):
23478

23579
name: str
236-
version: str
237-
source: str
238-
checksum: str
239-
240-
241-
class CargoLock(TypedDict, total=False):
242-
243-
"""A description of the Cargo.lock file format."""
244-
245-
version: str
246-
package: T.List[CargoLockPackage]
247-
metadata: T.Dict[str, str]
80+
proc_macro: bool

0 commit comments

Comments
 (0)