Gentoo Archives: gentoo-commits

From: Matt Turner <mattst88@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: lib/portage/
Date: Fri, 01 Apr 2022 20:30:53
Message-Id: 1648844940.1b1c4323d73d095f5ee2816201b5780f6a7ea14b.mattst88@gentoo
1 commit: 1b1c4323d73d095f5ee2816201b5780f6a7ea14b
2 Author: Wolfgang E. Sanyer <WolfgangESanyer <AT> gmail <DOT> com>
3 AuthorDate: Thu Feb 24 02:30:24 2022 +0000
4 Commit: Matt Turner <mattst88 <AT> gentoo <DOT> org>
5 CommitDate: Fri Apr 1 20:29:00 2022 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=1b1c4323
7
8 portage.eapi: use functools @lru_cache decorator
9
10 Also, refactor logic in order to improve readability.
11
12 Closes: https://github.com/gentoo/portage/pull/754
13 Signed-off-by: Wolfgang E. Sanyer <WolfgangESanyer <AT> gmail.com>
14 Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org>
15
16 lib/portage/eapi.py | 458 +++++++++++++++++++---------------------------------
17 1 file changed, 169 insertions(+), 289 deletions(-)
18
19 diff --git a/lib/portage/eapi.py b/lib/portage/eapi.py
20 index 18069b04b..f8e8573ed 100644
21 --- a/lib/portage/eapi.py
22 +++ b/lib/portage/eapi.py
23 @@ -2,288 +2,167 @@
24 # Distributed under the terms of the GNU General Public License v2
25
26 import collections
27 -import operator
28 -import types
29 +import logging
30 +from functools import lru_cache
31 +from typing import Optional
32
33 from portage import eapi_is_supported
34
35
36 -def eapi_has_iuse_defaults(eapi):
37 - return eapi != "0"
38 +def eapi_has_iuse_defaults(eapi: str) -> bool:
39 + return _get_eapi_attrs(eapi).iuse_defaults
40
41
42 -def eapi_has_iuse_effective(eapi):
43 - return eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi")
44 +def eapi_has_iuse_effective(eapi: str) -> bool:
45 + return _get_eapi_attrs(eapi).iuse_effective
46
47
48 -def eapi_has_slot_deps(eapi):
49 - return eapi != "0"
50 +def eapi_has_slot_deps(eapi: str) -> bool:
51 + return _get_eapi_attrs(eapi).slot_deps
52
53
54 -def eapi_has_slot_operator(eapi):
55 - return eapi not in ("0", "1", "2", "3", "4", "4-python")
56 +def eapi_has_slot_operator(eapi: str) -> bool:
57 + return _get_eapi_attrs(eapi).slot_operator
58
59
60 -def eapi_has_src_uri_arrows(eapi):
61 - return eapi not in ("0", "1")
62 +def eapi_has_src_uri_arrows(eapi: str) -> bool:
63 + return _get_eapi_attrs(eapi).src_uri_arrows
64
65
66 -def eapi_has_selective_src_uri_restriction(eapi):
67 - return eapi not in (
68 - "0",
69 - "1",
70 - "2",
71 - "3",
72 - "4",
73 - "4-python",
74 - "4-slot-abi",
75 - "5",
76 - "5-progress",
77 - "6",
78 - "7",
79 - )
80 +def eapi_has_selective_src_uri_restriction(eapi: str) -> bool:
81 + return _get_eapi_attrs(eapi).selective_src_uri_restriction
82
83
84 -def eapi_has_use_deps(eapi):
85 - return eapi not in ("0", "1")
86 +def eapi_has_use_deps(eapi: str) -> bool:
87 + return _get_eapi_attrs(eapi).use_deps
88
89
90 -def eapi_has_strong_blocks(eapi):
91 - return eapi not in ("0", "1")
92 +def eapi_has_strong_blocks(eapi: str) -> bool:
93 + return _get_eapi_attrs(eapi).strong_blocks
94
95
96 -def eapi_has_src_prepare_and_src_configure(eapi):
97 +def eapi_has_src_prepare_and_src_configure(eapi: str) -> bool:
98 return eapi not in ("0", "1")
99
100
101 -def eapi_supports_prefix(eapi):
102 - return eapi not in ("0", "1", "2")
103 +def eapi_supports_prefix(eapi: str) -> bool:
104 + return _get_eapi_attrs(eapi).prefix
105
106
107 -def eapi_exports_AA(eapi):
108 - return eapi in ("0", "1", "2", "3")
109 +def eapi_exports_AA(eapi: str) -> bool:
110 + return _get_eapi_attrs(eapi).exports_AA
111
112
113 -def eapi_exports_KV(eapi):
114 - return eapi in ("0", "1", "2", "3")
115 +def eapi_exports_KV(eapi: str) -> bool:
116 + return _get_eapi_attrs(eapi).exports_KV
117
118
119 -def eapi_exports_merge_type(eapi):
120 - return eapi not in ("0", "1", "2", "3")
121 +def eapi_exports_merge_type(eapi: str) -> bool:
122 + return _get_eapi_attrs(eapi).exports_merge_type
123
124
125 -def eapi_exports_replace_vars(eapi):
126 - return eapi not in ("0", "1", "2", "3")
127 +def eapi_exports_replace_vars(eapi: str) -> bool:
128 + return _get_eapi_attrs(eapi).exports_replace_vars
129
130
131 -def eapi_exports_EBUILD_PHASE_FUNC(eapi):
132 - return eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi")
133 +def eapi_exports_EBUILD_PHASE_FUNC(eapi: str) -> bool:
134 + return _get_eapi_attrs(eapi).exports_EBUILD_PHASE_FUNC
135
136
137 -def eapi_exports_PORTDIR(eapi):
138 - return eapi in (
139 - "0",
140 - "1",
141 - "2",
142 - "3",
143 - "4",
144 - "4-python",
145 - "4-slot-abi",
146 - "5",
147 - "5-progress",
148 - "6",
149 - )
150 +def eapi_exports_PORTDIR(eapi: str) -> bool:
151 + return _get_eapi_attrs(eapi).exports_PORTDIR
152
153
154 -def eapi_exports_ECLASSDIR(eapi):
155 - return eapi in (
156 - "0",
157 - "1",
158 - "2",
159 - "3",
160 - "4",
161 - "4-python",
162 - "4-slot-abi",
163 - "5",
164 - "5-progress",
165 - "6",
166 - )
167 +def eapi_exports_ECLASSDIR(eapi: str) -> bool:
168 + return _get_eapi_attrs(eapi).exports_ECLASSDIR
169
170
171 -def eapi_exports_REPOSITORY(eapi):
172 +def eapi_exports_REPOSITORY(eapi: str) -> bool:
173 return eapi in ("4-python", "5-progress")
174
175
176 -def eapi_has_pkg_pretend(eapi):
177 +def eapi_has_pkg_pretend(eapi: str) -> bool:
178 return eapi not in ("0", "1", "2", "3")
179
180
181 -def eapi_has_implicit_rdepend(eapi):
182 +def eapi_has_implicit_rdepend(eapi: str) -> bool:
183 return eapi in ("0", "1", "2", "3")
184
185
186 -def eapi_has_dosed_dohard(eapi):
187 +def eapi_has_dosed_dohard(eapi: str) -> bool:
188 return eapi in ("0", "1", "2", "3")
189
190
191 -def eapi_has_required_use(eapi):
192 - return eapi not in ("0", "1", "2", "3")
193 +def eapi_has_required_use(eapi: str) -> bool:
194 + return _get_eapi_attrs(eapi).required_use
195
196
197 -def eapi_has_required_use_at_most_one_of(eapi):
198 - return eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi")
199 +def eapi_has_required_use_at_most_one_of(eapi: str) -> bool:
200 + return _get_eapi_attrs(eapi).required_use_at_most_one_of
201
202
203 -def eapi_has_use_dep_defaults(eapi):
204 - return eapi not in ("0", "1", "2", "3")
205 +def eapi_has_use_dep_defaults(eapi: str) -> bool:
206 + return _get_eapi_attrs(eapi).use_dep_defaults
207
208
209 -def eapi_requires_posixish_locale(eapi):
210 - return eapi not in (
211 - "0",
212 - "1",
213 - "2",
214 - "3",
215 - "4",
216 - "4-python",
217 - "4-slot-abi",
218 - "5",
219 - "5-progress",
220 - )
221 +def eapi_requires_posixish_locale(eapi: str) -> bool:
222 + return _get_eapi_attrs(eapi).posixish_locale
223
224
225 -def eapi_has_repo_deps(eapi):
226 - return eapi in ("4-python", "5-progress")
227 +def eapi_has_repo_deps(eapi: str) -> bool:
228 + return _get_eapi_attrs(eapi).repo_deps
229
230
231 -def eapi_allows_dots_in_PN(eapi):
232 - return eapi in ("4-python", "5-progress")
233 +def eapi_allows_dots_in_PN(eapi: str) -> bool:
234 + return _get_eapi_attrs(eapi).dots_in_PN
235
236
237 -def eapi_allows_dots_in_use_flags(eapi):
238 - return eapi in ("4-python", "5-progress")
239 +def eapi_allows_dots_in_use_flags(eapi: str) -> bool:
240 + return _get_eapi_attrs(eapi).dots_in_use_flags
241
242
243 -def eapi_supports_stable_use_forcing_and_masking(eapi):
244 +def eapi_supports_stable_use_forcing_and_masking(eapi: str) -> bool:
245 return eapi not in ("0", "1", "2", "3", "4", "4-python", "4-slot-abi")
246
247
248 -def eapi_allows_directories_on_profile_level_and_repository_level(eapi):
249 +def eapi_allows_directories_on_profile_level_and_repository_level(eapi: str) -> bool:
250 return eapi not in ("0", "1", "2", "3", "4", "4-slot-abi", "5", "6")
251
252
253 -def eapi_has_use_aliases(eapi):
254 +def eapi_has_use_aliases(eapi: str) -> bool:
255 return eapi in ("4-python", "5-progress")
256
257
258 -def eapi_has_automatic_unpack_dependencies(eapi):
259 +def eapi_has_automatic_unpack_dependencies(eapi: str) -> bool:
260 return eapi in ("5-progress",)
261
262
263 -def eapi_allows_package_provided(eapi):
264 - return eapi in (
265 - "0",
266 - "1",
267 - "2",
268 - "3",
269 - "4",
270 - "4-python",
271 - "4-slot-abi",
272 - "5",
273 - "5-progress",
274 - "6",
275 - )
276 +def eapi_allows_package_provided(eapi: str) -> bool:
277 + return _get_eapi_attrs(eapi).allows_package_provided
278
279
280 -def eapi_has_bdepend(eapi):
281 - return eapi not in (
282 - "0",
283 - "1",
284 - "2",
285 - "3",
286 - "4",
287 - "4-python",
288 - "4-slot-abi",
289 - "5",
290 - "5-progress",
291 - "6",
292 - )
293 +def eapi_has_bdepend(eapi: str) -> bool:
294 + return _get_eapi_attrs(eapi).bdepend
295
296
297 -def eapi_has_idepend(eapi):
298 - return eapi not in (
299 - "0",
300 - "1",
301 - "2",
302 - "3",
303 - "4",
304 - "4-python",
305 - "4-slot-abi",
306 - "5",
307 - "5-progress",
308 - "6",
309 - "7",
310 - )
311 +def eapi_has_idepend(eapi: str) -> bool:
312 + return _get_eapi_attrs(eapi).idepend
313
314
315 -def eapi_empty_groups_always_true(eapi):
316 - return eapi in (
317 - "0",
318 - "1",
319 - "2",
320 - "3",
321 - "4",
322 - "4-python",
323 - "4-slot-abi",
324 - "5",
325 - "5-progress",
326 - "6",
327 - )
328 +def eapi_empty_groups_always_true(eapi: str) -> bool:
329 + return _get_eapi_attrs(eapi).empty_groups_always_true
330
331
332 -def eapi_path_variables_end_with_trailing_slash(eapi):
333 - return eapi in (
334 - "0",
335 - "1",
336 - "2",
337 - "3",
338 - "4",
339 - "4-python",
340 - "4-slot-abi",
341 - "5",
342 - "5-progress",
343 - "6",
344 - )
345 +def eapi_path_variables_end_with_trailing_slash(eapi: str) -> bool:
346 + return _get_eapi_attrs(eapi).path_variables_end_with_trailing_slash
347
348
349 -def eapi_has_broot(eapi):
350 - return eapi not in (
351 - "0",
352 - "1",
353 - "2",
354 - "3",
355 - "4",
356 - "4-python",
357 - "4-slot-abi",
358 - "5",
359 - "5-progress",
360 - "6",
361 - )
362 +def eapi_has_broot(eapi: str) -> bool:
363 + return _get_eapi_attrs(eapi).broot
364
365
366 -def eapi_has_sysroot(eapi):
367 - return eapi not in (
368 - "0",
369 - "1",
370 - "2",
371 - "3",
372 - "4",
373 - "4-python",
374 - "4-slot-abi",
375 - "5",
376 - "5-progress",
377 - "6",
378 - )
379 +def eapi_has_sysroot(eapi: str) -> bool:
380 + return _get_eapi_attrs(eapi).sysroot
381
382
383 _eapi_attrs = collections.namedtuple(
384 @@ -324,53 +203,39 @@ _eapi_attrs = collections.namedtuple(
385 )
386
387
388 -_eapi_attr_func_prefixes = (
389 - "eapi_allows_",
390 - "eapi_has_",
391 - "eapi_requires_",
392 - "eapi_supports_",
393 - "eapi_",
394 -)
395 -
396 -
397 -def _eapi_func_decorator(func, attr_getter):
398 - def wrapper(eapi):
399 - return attr_getter(_get_eapi_attrs(eapi))
400 -
401 - wrapper.func = func
402 - wrapper.__doc__ = func.__doc__
403 - return wrapper
404 -
405 +class Eapi:
406 + ALL_EAPIS = (
407 + "0",
408 + "1",
409 + "2",
410 + "3",
411 + "4",
412 + "4-python",
413 + "4-slot-abi",
414 + "5",
415 + "5-progress",
416 + "6",
417 + "7",
418 + "8",
419 + )
420
421 -def _decorate_eapi_funcs():
422 - """
423 - Decorate eapi_* functions so that they use _get_eapi_attrs(eapi)
424 - to cache results.
425 - """
426 - decorated = {}
427 - for k, v in globals().items():
428 - if not (
429 - isinstance(v, types.FunctionType) and k.startswith(_eapi_attr_func_prefixes)
430 - ):
431 - continue
432 - for prefix in _eapi_attr_func_prefixes:
433 - if k.startswith(prefix):
434 - attr_name = k[len(prefix) :]
435 - if hasattr(_eapi_attrs, attr_name):
436 - decorated[k] = _eapi_func_decorator(
437 - v, operator.attrgetter(attr_name)
438 - )
439 - break
440 - globals().update(decorated)
441 + _eapi_val: int = -1
442
443 + def __init__(self, eapi_string: str):
444 + if not eapi_string in self.ALL_EAPIS:
445 + raise ValueError(f"'{eapi_string}' not recognized as a valid EAPI")
446
447 -_decorate_eapi_funcs()
448 + self._eapi_val = int(eapi_string.partition("-")[0])
449
450 + def __ge__(self, other: "Eapi") -> bool:
451 + return self._eapi_val >= other._eapi_val
452
453 -_eapi_attrs_cache = {}
454 + def __le__(self, other: "Eapi") -> bool:
455 + return self._eapi_val <= other._eapi_val
456
457
458 -def _get_eapi_attrs(eapi):
459 +@lru_cache(32)
460 +def _get_eapi_attrs(eapi_str: Optional[str]) -> _eapi_attrs:
461 """
462 When eapi is None then validation is not as strict, since we want the
463 same to work for multiple EAPIs that may have slightly different rules.
464 @@ -378,59 +243,74 @@ def _get_eapi_attrs(eapi):
465 be helpful for handling of corrupt EAPI metadata in essential functions
466 such as pkgsplit.
467 """
468 - eapi_attrs = _eapi_attrs_cache.get(eapi)
469 - if eapi_attrs is not None:
470 - return eapi_attrs
471 -
472 - orig_eapi = eapi
473 - if eapi is not None and not eapi_is_supported(eapi):
474 - eapi = None
475 -
476 - eapi_attrs = _eapi_attrs(
477 - allows_package_provided=(
478 - eapi is None or eapi_allows_package_provided.func(eapi)
479 - ),
480 - bdepend=(eapi is not None and eapi_has_bdepend.func(eapi)),
481 - broot=(eapi is None or eapi_has_broot.func(eapi)),
482 - dots_in_PN=(eapi is None or eapi_allows_dots_in_PN.func(eapi)),
483 - dots_in_use_flags=(eapi is None or eapi_allows_dots_in_use_flags.func(eapi)),
484 - empty_groups_always_true=(
485 - eapi is not None and eapi_empty_groups_always_true.func(eapi)
486 - ),
487 - exports_AA=(eapi is not None and eapi_exports_AA.func(eapi)),
488 - exports_EBUILD_PHASE_FUNC=(
489 - eapi is None or eapi_exports_EBUILD_PHASE_FUNC.func(eapi)
490 - ),
491 - exports_ECLASSDIR=(eapi is not None and eapi_exports_ECLASSDIR.func(eapi)),
492 - exports_KV=(eapi is not None and eapi_exports_KV.func(eapi)),
493 - exports_merge_type=(eapi is None or eapi_exports_merge_type.func(eapi)),
494 - exports_PORTDIR=(eapi is None or eapi_exports_PORTDIR.func(eapi)),
495 - exports_replace_vars=(eapi is None or eapi_exports_replace_vars.func(eapi)),
496 - feature_flag_test=False,
497 - idepend=(eapi is not None and eapi_has_idepend.func(eapi)),
498 - iuse_defaults=(eapi is None or eapi_has_iuse_defaults.func(eapi)),
499 - iuse_effective=(eapi is not None and eapi_has_iuse_effective.func(eapi)),
500 - path_variables_end_with_trailing_slash=(
501 - eapi is not None and eapi_path_variables_end_with_trailing_slash.func(eapi)
502 - ),
503 - posixish_locale=(eapi is not None and eapi_requires_posixish_locale.func(eapi)),
504 - prefix=(eapi is None or eapi_supports_prefix.func(eapi)),
505 - repo_deps=(eapi is None or eapi_has_repo_deps.func(eapi)),
506 - required_use=(eapi is None or eapi_has_required_use.func(eapi)),
507 - required_use_at_most_one_of=(
508 - eapi is None or eapi_has_required_use_at_most_one_of.func(eapi)
509 - ),
510 - selective_src_uri_restriction=(
511 - eapi is None or eapi_has_selective_src_uri_restriction.func(eapi)
512 - ),
513 - slot_deps=(eapi is None or eapi_has_slot_deps.func(eapi)),
514 - slot_operator=(eapi is None or eapi_has_slot_operator.func(eapi)),
515 - src_uri_arrows=(eapi is None or eapi_has_src_uri_arrows.func(eapi)),
516 - strong_blocks=(eapi is None or eapi_has_strong_blocks.func(eapi)),
517 - sysroot=(eapi is None or eapi_has_sysroot.func(eapi)),
518 - use_deps=(eapi is None or eapi_has_use_deps.func(eapi)),
519 - use_dep_defaults=(eapi is None or eapi_has_use_dep_defaults.func(eapi)),
520 - )
521 -
522 - _eapi_attrs_cache[orig_eapi] = eapi_attrs
523 - return eapi_attrs
524 + logging.info("cache info: {}".format(_get_eapi_attrs.cache_info()))
525 + if eapi_str is None or not eapi_is_supported(eapi_str):
526 + return _eapi_attrs(
527 + allows_package_provided=True,
528 + bdepend=False,
529 + broot=True,
530 + dots_in_PN=True,
531 + dots_in_use_flags=True,
532 + empty_groups_always_true=False,
533 + exports_AA=False,
534 + exports_EBUILD_PHASE_FUNC=True,
535 + exports_ECLASSDIR=False,
536 + exports_KV=False,
537 + exports_merge_type=True,
538 + exports_PORTDIR=True,
539 + exports_replace_vars=True,
540 + feature_flag_test=False,
541 + idepend=False,
542 + iuse_defaults=True,
543 + iuse_effective=False,
544 + path_variables_end_with_trailing_slash=False,
545 + posixish_locale=False,
546 + prefix=True,
547 + repo_deps=True,
548 + required_use=True,
549 + required_use_at_most_one_of=True,
550 + selective_src_uri_restriction=True,
551 + slot_deps=True,
552 + slot_operator=True,
553 + src_uri_arrows=True,
554 + strong_blocks=True,
555 + sysroot=True,
556 + use_deps=True,
557 + use_dep_defaults=True,
558 + )
559 + else:
560 + eapi_special = ("4-python", "5-progress")
561 + eapi = Eapi(eapi_str)
562 + return _eapi_attrs(
563 + allows_package_provided=eapi <= Eapi("6"),
564 + bdepend=eapi >= Eapi("7"),
565 + broot=eapi >= Eapi("7"),
566 + dots_in_PN=eapi_str in eapi_special,
567 + dots_in_use_flags=eapi_str in eapi_special,
568 + empty_groups_always_true=eapi <= Eapi("6"),
569 + exports_AA=eapi <= Eapi("3"),
570 + exports_EBUILD_PHASE_FUNC=eapi >= Eapi("5"),
571 + exports_ECLASSDIR=eapi <= Eapi("6"),
572 + exports_KV=eapi <= Eapi("3"),
573 + exports_merge_type=eapi >= Eapi("4"),
574 + exports_PORTDIR=eapi <= Eapi("6"),
575 + exports_replace_vars=eapi >= Eapi("4"),
576 + feature_flag_test=False,
577 + idepend=eapi >= Eapi("8"),
578 + iuse_defaults=eapi >= Eapi("1"),
579 + iuse_effective=eapi >= Eapi("5"),
580 + path_variables_end_with_trailing_slash=eapi <= Eapi("6"),
581 + posixish_locale=eapi >= Eapi("6"),
582 + prefix=eapi >= Eapi("3"),
583 + repo_deps=eapi_str in eapi_special,
584 + required_use=eapi >= Eapi("4"),
585 + required_use_at_most_one_of=eapi >= Eapi("5"),
586 + selective_src_uri_restriction=eapi >= Eapi("8"),
587 + slot_deps=eapi >= Eapi("1"),
588 + slot_operator=eapi >= Eapi("5"),
589 + src_uri_arrows=eapi >= Eapi("2"),
590 + strong_blocks=eapi >= Eapi("2"),
591 + sysroot=eapi >= Eapi("7"),
592 + use_deps=eapi >= Eapi("2"),
593 + use_dep_defaults=eapi >= Eapi("4"),
594 + )