11
11
from typing import Any
12
12
from typing import cast
13
13
14
+ import tomli
15
+ import tomli_w
16
+
14
17
from poetry .core .packages .dependency import Dependency
15
18
from poetry .core .packages .package import Package
16
19
from poetry .core .semver .helpers import parse_constraint
17
20
from poetry .core .semver .version import Version
18
- from poetry .core .toml .file import TOMLFile
19
21
from poetry .core .version .markers import parse_marker
20
22
from poetry .core .version .requirements import InvalidRequirement
21
- from tomlkit import array
22
- from tomlkit import comment
23
- from tomlkit import document
24
- from tomlkit import inline_table
25
- from tomlkit import item
26
- from tomlkit import table
27
- from tomlkit .exceptions import TOMLKitError
28
- from tomlkit .items import Array
29
23
30
24
31
25
if TYPE_CHECKING :
32
26
from poetry .core .packages .directory_dependency import DirectoryDependency
33
27
from poetry .core .packages .file_dependency import FileDependency
34
28
from poetry .core .packages .url_dependency import URLDependency
35
29
from poetry .core .packages .vcs_dependency import VCSDependency
36
- from tomlkit .items import Table
37
- from tomlkit .toml_document import TOMLDocument
38
30
39
31
from poetry .repositories import Repository
40
32
@@ -53,17 +45,17 @@ class Locker:
53
45
_relevant_keys = [* _legacy_keys , "group" ]
54
46
55
47
def __init__ (self , lock : str | Path , local_config : dict [str , Any ]) -> None :
56
- self ._lock = TOMLFile (lock )
48
+ self ._lock = lock if isinstance ( lock , Path ) else Path (lock )
57
49
self ._local_config = local_config
58
- self ._lock_data : TOMLDocument | None = None
50
+ self ._lock_data : dict [ str , Any ] | None = None
59
51
self ._content_hash = self ._get_content_hash ()
60
52
61
53
@property
62
- def lock (self ) -> TOMLFile :
54
+ def lock (self ) -> Path :
63
55
return self ._lock
64
56
65
57
@property
66
- def lock_data (self ) -> TOMLDocument :
58
+ def lock_data (self ) -> dict [ str , Any ] :
67
59
if self ._lock_data is None :
68
60
self ._lock_data = self ._get_lock_data ()
69
61
@@ -73,7 +65,7 @@ def is_locked(self) -> bool:
73
65
"""
74
66
Checks whether the locker has been locked (lockfile found).
75
67
"""
76
- if not self ._lock .exists ():
68
+ if not self .lock .exists ():
77
69
return False
78
70
79
71
return "package" in self .lock_data
@@ -82,7 +74,8 @@ def is_fresh(self) -> bool:
82
74
"""
83
75
Checks whether the lock file is still up to date with the current hash.
84
76
"""
85
- lock = self ._lock .read ()
77
+ with self .lock .open ("rb" ) as f :
78
+ lock = tomli .load (f )
86
79
metadata = lock .get ("metadata" , {})
87
80
88
81
if "content-hash" in metadata :
@@ -113,7 +106,7 @@ def locked_repository(self) -> Repository:
113
106
source_type = source .get ("type" )
114
107
url = source .get ("url" )
115
108
if source_type in ["directory" , "file" ]:
116
- url = self ._lock . path .parent .joinpath (url ).resolve ().as_posix ()
109
+ url = self .lock .parent .joinpath (url ).resolve ().as_posix ()
117
110
118
111
package = Package (
119
112
info ["name" ],
@@ -186,7 +179,7 @@ def locked_repository(self) -> Repository:
186
179
package .marker = parse_marker (split_dep [1 ].strip ())
187
180
188
181
for dep_name , constraint in info .get ("dependencies" , {}).items ():
189
- root_dir = self ._lock . path .parent
182
+ root_dir = self .lock .parent
190
183
if package .source_type == "directory" :
191
184
# root dir should be the source of the package relative to the lock
192
185
# path
@@ -213,29 +206,23 @@ def locked_repository(self) -> Repository:
213
206
return packages
214
207
215
208
def set_lock_data (self , root : Package , packages : list [Package ]) -> bool :
216
- files : dict [str , Any ] = table ()
209
+ files : dict [str , Any ] = {}
217
210
package_specs = self ._lock_packages (packages )
218
211
# Retrieving hashes
219
212
for package in package_specs :
220
213
if package ["name" ] not in files :
221
214
files [package ["name" ]] = []
222
215
223
216
for f in package ["files" ]:
224
- file_metadata = inline_table ()
217
+ file_metadata = {}
225
218
for k , v in sorted (f .items ()):
226
219
file_metadata [k ] = v
227
220
228
221
files [package ["name" ]].append (file_metadata )
229
222
230
- if files [package ["name" ]]:
231
- package_files = item (files [package ["name" ]])
232
- assert isinstance (package_files , Array )
233
- files [package ["name" ]] = package_files .multiline (True )
234
-
235
223
del package ["files" ]
236
224
237
- lock = document ()
238
- lock .add (comment (GENERATED_COMMENT ))
225
+ lock : dict [str , Any ] = {}
239
226
lock ["package" ] = package_specs
240
227
241
228
if root .extras :
@@ -258,12 +245,10 @@ def set_lock_data(self, root: Package, packages: list[Package]) -> bool:
258
245
259
246
return False
260
247
261
- def _write_lock_data (self , data : TOMLDocument ) -> None :
262
- self .lock .write (data )
263
-
264
- # Checking lock file data consistency
265
- if data != self .lock .read ():
266
- raise RuntimeError ("Inconsistent lock file data." )
248
+ def _write_lock_data (self , data : dict [str , Any ]) -> None :
249
+ with self .lock .open ("wb" ) as f :
250
+ f .write (f"# { GENERATED_COMMENT } \n \n " .encode ("utf-8" ))
251
+ tomli_w .dump (data , f )
267
252
268
253
self ._lock_data = None
269
254
@@ -284,16 +269,17 @@ def _get_content_hash(self) -> str:
284
269
285
270
return sha256 (json .dumps (relevant_content , sort_keys = True ).encode ()).hexdigest ()
286
271
287
- def _get_lock_data (self ) -> TOMLDocument :
288
- if not self ._lock .exists ():
272
+ def _get_lock_data (self ) -> dict [ str , Any ] :
273
+ if not self .lock .exists ():
289
274
raise RuntimeError ("No lockfile found. Unable to read locked packages" )
290
275
291
- try :
292
- lock_data : TOMLDocument = self ._lock .read ()
293
- except TOMLKitError as e :
294
- raise RuntimeError (f"Unable to read the lock file ({ e } )." )
276
+ with self .lock .open ("rb" ) as f :
277
+ try :
278
+ lock_data = tomli .load (f )
279
+ except tomli .TOMLDecodeError as e :
280
+ raise RuntimeError (f"Unable to read the lock file ({ e } )." )
295
281
296
- metadata = cast ( "Table" , lock_data ["metadata" ])
282
+ metadata = lock_data ["metadata" ]
297
283
lock_version = Version .parse (metadata .get ("lock-version" , "1.0" ))
298
284
current_version = Version .parse (self ._VERSION )
299
285
# We expect the locker to be able to read lock files
@@ -348,7 +334,7 @@ def _dump_package(self, package: Package) -> dict[str, Any]:
348
334
if dependency .pretty_name not in dependencies :
349
335
dependencies [dependency .pretty_name ] = []
350
336
351
- constraint = inline_table ()
337
+ constraint : dict [ str , Any ] = {}
352
338
353
339
if dependency .is_directory ():
354
340
dependency = cast ("DirectoryDependency" , dependency )
@@ -414,12 +400,12 @@ def _dump_package(self, package: Package) -> dict[str, Any]:
414
400
}
415
401
416
402
if dependencies :
417
- data ["dependencies" ] = table ()
403
+ data ["dependencies" ] = {}
418
404
for k , constraints in dependencies .items ():
419
405
if len (constraints ) == 1 :
420
406
data ["dependencies" ][k ] = constraints [0 ]
421
407
else :
422
- data ["dependencies" ][k ] = array (). multiline ( True )
408
+ data ["dependencies" ][k ] = []
423
409
for constraint in constraints :
424
410
data ["dependencies" ][k ].append (constraint )
425
411
@@ -437,7 +423,7 @@ def _dump_package(self, package: Package) -> dict[str, Any]:
437
423
url = Path (
438
424
os .path .relpath (
439
425
Path (url ).resolve (),
440
- Path (self ._lock . path .parent ).resolve (),
426
+ Path (self .lock .parent ).resolve (),
441
427
)
442
428
).as_posix ()
443
429
0 commit comments