Gentoo Archives: gentoo-commits

From: Matt Turner <mattst88@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/gentoolkit:master commit in: pym/gentoolkit/, pym/gentoolkit/test/eclean/, pym/gentoolkit/ekeyword/, ...
Date: Mon, 20 Sep 2021 22:58:04
Message-Id: 1632178312.bbcd72b5fe85fe9bbca1913f8aa22077d94e75d0.mattst88@gentoo
1 commit: bbcd72b5fe85fe9bbca1913f8aa22077d94e75d0
2 Author: Wolfgang E. Sanyer <WolfgangESanyer <AT> gmail <DOT> com>
3 AuthorDate: Mon Sep 20 12:49:15 2021 +0000
4 Commit: Matt Turner <mattst88 <AT> gentoo <DOT> org>
5 CommitDate: Mon Sep 20 22:51:52 2021 +0000
6 URL: https://gitweb.gentoo.org/proj/gentoolkit.git/commit/?id=bbcd72b5
7
8 Change tabs to spaces (using autopep8). Also, format repo using black.
9
10 The following command was used to change the tabs to spaces:
11
12 autopep8 --in-place --select=E101,E11,E121,E122,E123,E124,E125,E126,E127,E128,E129,E131,E133,E20,E211,E22,E224,E224,E226,E227,E228,E231,E241,E242,E251,E252,E26,E265,E266,E27,E301,E302,E303,E304,E305,E306,W291,W293,W391 -r .
13
14 And then black was run as `black .` on the entire tree
15
16 Signed-off-by: Wolfgang E. Sanyer <WolfgangESanyer <AT> gmail.com>
17 Signed-off-by: Matt Turner <mattst88 <AT> gentoo.org>
18
19 bin/eclean | 33 +-
20 bin/eclean-dist | 33 +-
21 bin/eclean-pkg | 33 +-
22 bin/ekeyword | 28 +-
23 bin/enalyze | 40 +-
24 bin/epkginfo | 54 +-
25 bin/equery | 44 +-
26 bin/eshowkw | 2 +-
27 bin/imlate | 28 +-
28 bin/merge-driver-ekeyword | 9 +-
29 bin/revdep-rebuild | 42 +-
30 pym/gentoolkit/__init__.py | 10 +-
31 pym/gentoolkit/atom.py | 626 +++++++-------
32 pym/gentoolkit/base.py | 207 ++---
33 pym/gentoolkit/cpv.py | 400 ++++-----
34 pym/gentoolkit/dbapi.py | 8 +-
35 pym/gentoolkit/dependencies.py | 608 +++++++-------
36 pym/gentoolkit/eclean/clean.py | 274 +++----
37 pym/gentoolkit/eclean/cli.py | 1099 ++++++++++++++-----------
38 pym/gentoolkit/eclean/exclude.py | 483 +++++------
39 pym/gentoolkit/eclean/output.py | 354 ++++----
40 pym/gentoolkit/eclean/pkgindex.py | 148 ++--
41 pym/gentoolkit/eclean/search.py | 1122 ++++++++++++-------------
42 pym/gentoolkit/ekeyword/ekeyword.py | 825 ++++++++++---------
43 pym/gentoolkit/ekeyword/test_ekeyword.py | 638 +++++++--------
44 pym/gentoolkit/enalyze/__init__.py | 163 ++--
45 pym/gentoolkit/enalyze/analyze.py | 928 +++++++++++----------
46 pym/gentoolkit/enalyze/lib.py | 685 ++++++++--------
47 pym/gentoolkit/enalyze/output.py | 537 ++++++------
48 pym/gentoolkit/enalyze/rebuild.py | 708 ++++++++--------
49 pym/gentoolkit/eprefix.py | 6 +-
50 pym/gentoolkit/equery/__init__.py | 556 ++++++-------
51 pym/gentoolkit/equery/belongs.py | 218 ++---
52 pym/gentoolkit/equery/check.py | 453 ++++++-----
53 pym/gentoolkit/equery/depends.py | 325 ++++----
54 pym/gentoolkit/equery/depgraph.py | 395 ++++-----
55 pym/gentoolkit/equery/files.py | 496 +++++------
56 pym/gentoolkit/equery/has.py | 326 ++++----
57 pym/gentoolkit/equery/hasuse.py | 272 ++++---
58 pym/gentoolkit/equery/keywords.py | 5 +-
59 pym/gentoolkit/equery/list_.py | 424 +++++-----
60 pym/gentoolkit/equery/meta.py | 955 +++++++++++-----------
61 pym/gentoolkit/equery/size.py | 257 +++---
62 pym/gentoolkit/equery/uses.py | 522 ++++++------
63 pym/gentoolkit/equery/which.py | 156 ++--
64 pym/gentoolkit/errors.py | 205 ++---
65 pym/gentoolkit/eshowkw/__init__.py | 318 +++++---
66 pym/gentoolkit/eshowkw/display_pretty.py | 208 ++---
67 pym/gentoolkit/eshowkw/keywords_content.py | 756 +++++++++--------
68 pym/gentoolkit/eshowkw/keywords_header.py | 273 ++++---
69 pym/gentoolkit/flag.py | 276 +++----
70 pym/gentoolkit/formatters.py | 223 +++--
71 pym/gentoolkit/helpers.py | 492 +++++------
72 pym/gentoolkit/imlate/imlate.py | 915 ++++++++++++---------
73 pym/gentoolkit/keyword.py | 180 ++--
74 pym/gentoolkit/metadata.py | 454 ++++++-----
75 pym/gentoolkit/module_base.py | 268 +++---
76 pym/gentoolkit/package.py | 1118 ++++++++++++-------------
77 pym/gentoolkit/pprinter.py | 253 +++---
78 pym/gentoolkit/profile.py | 192 ++---
79 pym/gentoolkit/query.py | 720 ++++++++--------
80 pym/gentoolkit/revdep_rebuild/analyse.py | 781 +++++++++---------
81 pym/gentoolkit/revdep_rebuild/assign.py | 312 +++----
82 pym/gentoolkit/revdep_rebuild/cache.py | 281 ++++---
83 pym/gentoolkit/revdep_rebuild/collect.py | 437 +++++-----
84 pym/gentoolkit/revdep_rebuild/rebuild.py | 266 +++---
85 pym/gentoolkit/revdep_rebuild/runner.py | 93 +--
86 pym/gentoolkit/revdep_rebuild/settings.py | 299 +++----
87 pym/gentoolkit/revdep_rebuild/stuff.py | 164 ++--
88 pym/gentoolkit/sets.py | 73 +-
89 pym/gentoolkit/test/eclean/creator.py | 388 +++++----
90 pym/gentoolkit/test/eclean/distsupport.py | 885 ++++++++++----------
91 pym/gentoolkit/test/eclean/test_clean.py | 6 +-
92 pym/gentoolkit/test/eclean/test_search.py | 1221 +++++++++++++++-------------
93 pym/gentoolkit/test/equery/test_init.py | 74 +-
94 pym/gentoolkit/test/test_atom.py | 250 +++---
95 pym/gentoolkit/test/test_cpv.py | 219 ++---
96 pym/gentoolkit/test/test_helpers.py | 123 +--
97 pym/gentoolkit/test/test_keyword.py | 91 ++-
98 pym/gentoolkit/test/test_profile.py | 92 +--
99 pym/gentoolkit/test/test_query.py | 177 ++--
100 pym/gentoolkit/test/test_syntax.py | 38 +-
101 pym/gentoolkit/textwrap_.py | 180 ++--
102 pym/gentoolkit/versionmatch.py | 209 +++--
103 setup.py | 239 +++---
104 85 files changed, 15252 insertions(+), 14032 deletions(-)
105
106 diff --git a/bin/eclean b/bin/eclean
107 index 90f9e55..c315c88 100755
108 --- a/bin/eclean
109 +++ b/bin/eclean
110 @@ -6,9 +6,9 @@ Distributed under the terms of the GNU General Public License v2
111
112 # Meta:
113 __author__ = "Thomas de Grenier de Latour (tgl), " + \
114 - "modular re-write by: Brian Dolbec (dol-sen)"
115 + "modular re-write by: Brian Dolbec (dol-sen)"
116 __email__ = "degrenier@×××××××××××.fr, " + \
117 - "brian.dolbec@×××××.com"
118 + "brian.dolbec@×××××.com"
119 __version__ = "git"
120 __productname__ = "eclean"
121 __description__ = "A cleaning tool for Gentoo distfiles and binaries."
122 @@ -18,29 +18,28 @@ import sys
123
124 # This block ensures that ^C interrupts are handled quietly.
125 try:
126 - import signal
127 + import signal
128
129 - def exithandler(signum,frame):
130 - signal.signal(signal.SIGINT, signal.SIG_IGN)
131 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
132 - print()
133 - sys.exit(1)
134 + def exithandler(signum, frame):
135 + signal.signal(signal.SIGINT, signal.SIG_IGN)
136 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
137 + print()
138 + sys.exit(1)
139
140 - signal.signal(signal.SIGINT, exithandler)
141 - signal.signal(signal.SIGTERM, exithandler)
142 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
143 + signal.signal(signal.SIGINT, exithandler)
144 + signal.signal(signal.SIGTERM, exithandler)
145 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
146
147 except KeyboardInterrupt:
148 - print()
149 - sys.exit(1)
150 + print()
151 + sys.exit(1)
152
153
154 from gentoolkit.eclean.cli import main
155
156 try:
157 - main()
158 + main()
159 except KeyboardInterrupt:
160 - print("Aborted.")
161 - sys.exit(130)
162 + print("Aborted.")
163 + sys.exit(130)
164 sys.exit(0)
165 -
166
167 diff --git a/bin/eclean-dist b/bin/eclean-dist
168 index 90f9e55..c315c88 100755
169 --- a/bin/eclean-dist
170 +++ b/bin/eclean-dist
171 @@ -6,9 +6,9 @@ Distributed under the terms of the GNU General Public License v2
172
173 # Meta:
174 __author__ = "Thomas de Grenier de Latour (tgl), " + \
175 - "modular re-write by: Brian Dolbec (dol-sen)"
176 + "modular re-write by: Brian Dolbec (dol-sen)"
177 __email__ = "degrenier@×××××××××××.fr, " + \
178 - "brian.dolbec@×××××.com"
179 + "brian.dolbec@×××××.com"
180 __version__ = "git"
181 __productname__ = "eclean"
182 __description__ = "A cleaning tool for Gentoo distfiles and binaries."
183 @@ -18,29 +18,28 @@ import sys
184
185 # This block ensures that ^C interrupts are handled quietly.
186 try:
187 - import signal
188 + import signal
189
190 - def exithandler(signum,frame):
191 - signal.signal(signal.SIGINT, signal.SIG_IGN)
192 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
193 - print()
194 - sys.exit(1)
195 + def exithandler(signum, frame):
196 + signal.signal(signal.SIGINT, signal.SIG_IGN)
197 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
198 + print()
199 + sys.exit(1)
200
201 - signal.signal(signal.SIGINT, exithandler)
202 - signal.signal(signal.SIGTERM, exithandler)
203 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
204 + signal.signal(signal.SIGINT, exithandler)
205 + signal.signal(signal.SIGTERM, exithandler)
206 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
207
208 except KeyboardInterrupt:
209 - print()
210 - sys.exit(1)
211 + print()
212 + sys.exit(1)
213
214
215 from gentoolkit.eclean.cli import main
216
217 try:
218 - main()
219 + main()
220 except KeyboardInterrupt:
221 - print("Aborted.")
222 - sys.exit(130)
223 + print("Aborted.")
224 + sys.exit(130)
225 sys.exit(0)
226 -
227
228 diff --git a/bin/eclean-pkg b/bin/eclean-pkg
229 index 90f9e55..c315c88 100755
230 --- a/bin/eclean-pkg
231 +++ b/bin/eclean-pkg
232 @@ -6,9 +6,9 @@ Distributed under the terms of the GNU General Public License v2
233
234 # Meta:
235 __author__ = "Thomas de Grenier de Latour (tgl), " + \
236 - "modular re-write by: Brian Dolbec (dol-sen)"
237 + "modular re-write by: Brian Dolbec (dol-sen)"
238 __email__ = "degrenier@×××××××××××.fr, " + \
239 - "brian.dolbec@×××××.com"
240 + "brian.dolbec@×××××.com"
241 __version__ = "git"
242 __productname__ = "eclean"
243 __description__ = "A cleaning tool for Gentoo distfiles and binaries."
244 @@ -18,29 +18,28 @@ import sys
245
246 # This block ensures that ^C interrupts are handled quietly.
247 try:
248 - import signal
249 + import signal
250
251 - def exithandler(signum,frame):
252 - signal.signal(signal.SIGINT, signal.SIG_IGN)
253 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
254 - print()
255 - sys.exit(1)
256 + def exithandler(signum, frame):
257 + signal.signal(signal.SIGINT, signal.SIG_IGN)
258 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
259 + print()
260 + sys.exit(1)
261
262 - signal.signal(signal.SIGINT, exithandler)
263 - signal.signal(signal.SIGTERM, exithandler)
264 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
265 + signal.signal(signal.SIGINT, exithandler)
266 + signal.signal(signal.SIGTERM, exithandler)
267 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
268
269 except KeyboardInterrupt:
270 - print()
271 - sys.exit(1)
272 + print()
273 + sys.exit(1)
274
275
276 from gentoolkit.eclean.cli import main
277
278 try:
279 - main()
280 + main()
281 except KeyboardInterrupt:
282 - print("Aborted.")
283 - sys.exit(130)
284 + print("Aborted.")
285 + sys.exit(130)
286 sys.exit(0)
287 -
288
289 diff --git a/bin/ekeyword b/bin/ekeyword
290 index 8767fe3..c45ff5c 100755
291 --- a/bin/ekeyword
292 +++ b/bin/ekeyword
293 @@ -15,27 +15,27 @@ import os
294 import sys
295 # This block ensures that ^C interrupts are handled quietly.
296 try:
297 - import signal
298 + import signal
299
300 - def exithandler(signum,frame):
301 - signal.signal(signal.SIGINT, signal.SIG_IGN)
302 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
303 - print()
304 - sys.exit(1)
305 + def exithandler(signum, frame):
306 + signal.signal(signal.SIGINT, signal.SIG_IGN)
307 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
308 + print()
309 + sys.exit(1)
310
311 - signal.signal(signal.SIGINT, exithandler)
312 - signal.signal(signal.SIGTERM, exithandler)
313 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
314 + signal.signal(signal.SIGINT, exithandler)
315 + signal.signal(signal.SIGTERM, exithandler)
316 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
317
318 except KeyboardInterrupt:
319 - print()
320 - sys.exit(1)
321 + print()
322 + sys.exit(1)
323
324 from gentoolkit.ekeyword import ekeyword
325
326 try:
327 - ekeyword.main(sys.argv[1:])
328 + ekeyword.main(sys.argv[1:])
329 except KeyboardInterrupt:
330 - print("Aborted.")
331 - sys.exit(130)
332 + print("Aborted.")
333 + sys.exit(130)
334 sys.exit(0)
335
336 diff --git a/bin/enalyze b/bin/enalyze
337 index 9e27bed..caa3362 100755
338 --- a/bin/enalyze
339 +++ b/bin/enalyze
340 @@ -13,32 +13,32 @@ files in the event of corruption, and possibly more.
341 import sys
342 # This block ensures that ^C interrupts are handled quietly.
343 try:
344 - import signal
345 + import signal
346
347 - def exithandler(signum,frame):
348 - signal.signal(signal.SIGINT, signal.SIG_IGN)
349 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
350 - print()
351 - sys.exit(1)
352 + def exithandler(signum, frame):
353 + signal.signal(signal.SIGINT, signal.SIG_IGN)
354 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
355 + print()
356 + sys.exit(1)
357
358 - signal.signal(signal.SIGINT, exithandler)
359 - signal.signal(signal.SIGTERM, exithandler)
360 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
361 + signal.signal(signal.SIGINT, exithandler)
362 + signal.signal(signal.SIGTERM, exithandler)
363 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
364
365 except KeyboardInterrupt:
366 - print()
367 - sys.exit(1)
368 + print()
369 + sys.exit(1)
370
371 from gentoolkit import enalyze, errors
372
373 try:
374 - enalyze.main()
375 + enalyze.main()
376 except errors.GentoolkitException as err:
377 - if '--debug' in sys.argv:
378 - raise
379 - else:
380 - from gentoolkit import pprinter as pp
381 - sys.stderr.write(pp.error(str(err)))
382 - print()
383 - print("Add '--debug' to global options for traceback.")
384 - sys.exit(1)
385 + if '--debug' in sys.argv:
386 + raise
387 + else:
388 + from gentoolkit import pprinter as pp
389 + sys.stderr.write(pp.error(str(err)))
390 + print()
391 + print("Add '--debug' to global options for traceback.")
392 + sys.exit(1)
393
394 diff --git a/bin/epkginfo b/bin/epkginfo
395 index 5d3aab2..4cb483e 100755
396 --- a/bin/epkginfo
397 +++ b/bin/epkginfo
398 @@ -6,11 +6,11 @@
399 """Shortcut to equery meta"""
400
401 __authors__ = (
402 - 'Douglas Anderson <douglasjanderson@×××××.com>: equery meta',
403 - 'Ned Ludd <solar@g.o>: first full implimentation'
404 - 'Eldad Zack <eldad@g.o>: earch',
405 - 'Eric Olinger <EvvL AT RustedHalo DOT net>: metadata'
406 - )
407 + 'Douglas Anderson <douglasjanderson@×××××.com>: equery meta',
408 + 'Ned Ludd <solar@g.o>: first full implimentation'
409 + 'Eldad Zack <eldad@g.o>: earch',
410 + 'Eric Olinger <EvvL AT RustedHalo DOT net>: metadata'
411 +)
412
413 import sys
414
415 @@ -19,32 +19,34 @@ from gentoolkit.equery import mod_usage
416 from gentoolkit.equery.meta import main, print_help
417 from portage.exception import AmbiguousPackageName
418
419 +
420 def print_epkginfo_help():
421 - print(mod_usage(mod_name="epkginfo"))
422 - print()
423 - print_help(with_usage=False)
424 + print(mod_usage(mod_name="epkginfo"))
425 + print()
426 + print_help(with_usage=False)
427 +
428
429 equery.initialize_configuration()
430 args = sys.argv[1:]
431 if not args or set(('-h', '--help')).intersection(args):
432 - print_epkginfo_help()
433 + print_epkginfo_help()
434 else:
435 - try:
436 - main(args)
437 - except AmbiguousPackageName as e:
438 - pkgs = e.args[0]
439 - for candidate in pkgs:
440 - print(candidate)
441 -
442 - from gentoolkit import pprinter as pp
443 - from os.path import basename # To get the short name
444 -
445 - print(file=sys.stderr)
446 - print(pp.error("The short ebuild name '%s' is ambiguous. Please specify" % basename(pkgs[0])),
447 - file=sys.stderr, end="")
448 - pp.die(1, "one of the above fully-qualified ebuild names instead.")
449 - except errors.GentoolkitException as err:
450 - from gentoolkit import pprinter as pp
451 - pp.die(1, str(err))
452 + try:
453 + main(args)
454 + except AmbiguousPackageName as e:
455 + pkgs = e.args[0]
456 + for candidate in pkgs:
457 + print(candidate)
458 +
459 + from gentoolkit import pprinter as pp
460 + from os.path import basename # To get the short name
461 +
462 + print(file=sys.stderr)
463 + print(pp.error("The short ebuild name '%s' is ambiguous. Please specify" % basename(pkgs[0])),
464 + file=sys.stderr, end="")
465 + pp.die(1, "one of the above fully-qualified ebuild names instead.")
466 + except errors.GentoolkitException as err:
467 + from gentoolkit import pprinter as pp
468 + pp.die(1, str(err))
469
470 # vim: set ts=4 sw=4 tw=79:
471
472 diff --git a/bin/equery b/bin/equery
473 index 386194d..0e52294 100755
474 --- a/bin/equery
475 +++ b/bin/equery
476 @@ -12,35 +12,35 @@ import os
477 import sys
478 # This block ensures that ^C interrupts are handled quietly.
479 try:
480 - import signal
481 + import signal
482
483 - def exithandler(signum,frame):
484 - signal.signal(signal.SIGINT, signal.SIG_IGN)
485 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
486 - print()
487 - sys.exit(1)
488 + def exithandler(signum, frame):
489 + signal.signal(signal.SIGINT, signal.SIG_IGN)
490 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
491 + print()
492 + sys.exit(1)
493
494 - signal.signal(signal.SIGINT, exithandler)
495 - signal.signal(signal.SIGTERM, exithandler)
496 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
497 + signal.signal(signal.SIGINT, exithandler)
498 + signal.signal(signal.SIGTERM, exithandler)
499 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
500
501 except KeyboardInterrupt:
502 - print()
503 - sys.exit(1)
504 + print()
505 + sys.exit(1)
506
507 from gentoolkit import equery, errors
508
509 try:
510 - equery.main(sys.argv)
511 + equery.main(sys.argv)
512 except errors.GentoolkitNonZeroExit as err:
513 - sys.exit(err.return_code)
514 + sys.exit(err.return_code)
515 except errors.GentoolkitException as err:
516 - if '--debug' in sys.argv or bool(os.getenv('DEBUG', False)):
517 - raise
518 - else:
519 - from gentoolkit import pprinter as pp
520 - sys.stderr.write(pp.error(str(err)))
521 - if err.is_serious:
522 - print()
523 - print("Add '--debug' to global options for traceback.")
524 - sys.exit(1)
525 + if '--debug' in sys.argv or bool(os.getenv('DEBUG', False)):
526 + raise
527 + else:
528 + from gentoolkit import pprinter as pp
529 + sys.stderr.write(pp.error(str(err)))
530 + if err.is_serious:
531 + print()
532 + print("Add '--debug' to global options for traceback.")
533 + sys.exit(1)
534
535 diff --git a/bin/eshowkw b/bin/eshowkw
536 index e987cce..0ef4dda 100755
537 --- a/bin/eshowkw
538 +++ b/bin/eshowkw
539 @@ -6,4 +6,4 @@
540 import sys
541 from gentoolkit.eshowkw import main as emain
542
543 -sys.exit(emain(sys.argv[1:]))
544 \ No newline at end of file
545 +sys.exit(emain(sys.argv[1:]))
546
547 diff --git a/bin/imlate b/bin/imlate
548 index cd4f7ab..318d612 100755
549 --- a/bin/imlate
550 +++ b/bin/imlate
551 @@ -15,27 +15,27 @@ import os
552 import sys
553 # This block ensures that ^C interrupts are handled quietly.
554 try:
555 - import signal
556 + import signal
557
558 - def exithandler(signum,frame):
559 - signal.signal(signal.SIGINT, signal.SIG_IGN)
560 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
561 - print()
562 - sys.exit(1)
563 + def exithandler(signum, frame):
564 + signal.signal(signal.SIGINT, signal.SIG_IGN)
565 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
566 + print()
567 + sys.exit(1)
568
569 - signal.signal(signal.SIGINT, exithandler)
570 - signal.signal(signal.SIGTERM, exithandler)
571 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
572 + signal.signal(signal.SIGINT, exithandler)
573 + signal.signal(signal.SIGTERM, exithandler)
574 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
575
576 except KeyboardInterrupt:
577 - print()
578 - sys.exit(1)
579 + print()
580 + sys.exit(1)
581
582 from gentoolkit.imlate import imlate
583
584 try:
585 - imlate.main()
586 + imlate.main()
587 except KeyboardInterrupt:
588 - print("Aborted.")
589 - sys.exit(130)
590 + print("Aborted.")
591 + sys.exit(130)
592 sys.exit(0)
593
594 diff --git a/bin/merge-driver-ekeyword b/bin/merge-driver-ekeyword
595 index 7f4a10b..73e0430 100755
596 --- a/bin/merge-driver-ekeyword
597 +++ b/bin/merge-driver-ekeyword
598 @@ -21,6 +21,7 @@ from gentoolkit.ekeyword import ekeyword
599
600 KeywordChanges = List[Tuple[Optional[List[str]], Optional[List[str]]]]
601
602 +
603 def keyword_array(keyword_line: str) -> List[str]:
604 # Find indices of string inside the double-quotes
605 i1: int = keyword_line.find('"') + 1
606 @@ -112,10 +113,10 @@ def main(argv: Sequence[str]) -> int:
607 if len(argv) != 5:
608 sys.exit(-1)
609
610 - O = argv[1] # %O - filename of original
611 - A = argv[2] # %A - filename of our current version
612 - B = argv[3] # %B - filename of the other branch's version
613 - P = argv[4] # %P - original path of the file
614 + O = argv[1] # %O - filename of original
615 + A = argv[2] # %A - filename of our current version
616 + B = argv[3] # %B - filename of the other branch's version
617 + P = argv[4] # %P - original path of the file
618
619 # Get changes from %O to %B
620 changes = keyword_changes(O, B)
621
622 diff --git a/bin/revdep-rebuild b/bin/revdep-rebuild
623 index 51783c5..332dfcf 100755
624 --- a/bin/revdep-rebuild
625 +++ b/bin/revdep-rebuild
626 @@ -12,35 +12,35 @@ dependent upon the upgraded package.
627 import sys
628 # This block ensures that ^C interrupts are handled quietly.
629 try:
630 - import signal
631 + import signal
632
633 - def exithandler(signum,frame):
634 - signal.signal(signal.SIGINT, signal.SIG_IGN)
635 - signal.signal(signal.SIGTERM, signal.SIG_IGN)
636 - print()
637 - sys.exit(1)
638 + def exithandler(signum, frame):
639 + signal.signal(signal.SIGINT, signal.SIG_IGN)
640 + signal.signal(signal.SIGTERM, signal.SIG_IGN)
641 + print()
642 + sys.exit(1)
643
644 - signal.signal(signal.SIGINT, exithandler)
645 - signal.signal(signal.SIGTERM, exithandler)
646 - signal.signal(signal.SIGPIPE, signal.SIG_DFL)
647 + signal.signal(signal.SIGINT, exithandler)
648 + signal.signal(signal.SIGTERM, exithandler)
649 + signal.signal(signal.SIGPIPE, signal.SIG_DFL)
650
651
652 except KeyboardInterrupt:
653 - print()
654 - sys.exit(1)
655 + print()
656 + sys.exit(1)
657
658 from gentoolkit import errors
659 from gentoolkit.revdep_rebuild import rebuild
660
661 try:
662 - success = rebuild.main(rebuild.parse_options())
663 - sys.exit(success)
664 + success = rebuild.main(rebuild.parse_options())
665 + sys.exit(success)
666 except errors.GentoolkitException as err:
667 - if '--debug' in sys.argv:
668 - raise
669 - else:
670 - from gentoolkit import pprinter as pp
671 - sys.stderr.write(pp.error(str(err)))
672 - print()
673 - print("Add '--debug' to global options for traceback.")
674 - sys.exit(1)
675 + if '--debug' in sys.argv:
676 + raise
677 + else:
678 + from gentoolkit import pprinter as pp
679 + sys.stderr.write(pp.error(str(err)))
680 + print()
681 + print("Add '--debug' to global options for traceback.")
682 + sys.exit(1)
683
684 diff --git a/pym/gentoolkit/__init__.py b/pym/gentoolkit/__init__.py
685 index 9af78fc..ab9ce9d 100644
686 --- a/pym/gentoolkit/__init__.py
687 +++ b/pym/gentoolkit/__init__.py
688 @@ -10,14 +10,14 @@ import sys
689
690 CONFIG = {
691 # Color handling: -1: Use Portage settings, 0: Force off, 1: Force on
692 - 'color': -1,
693 + "color": -1,
694 # Guess piping output:
695 - 'piping': False if sys.stdout.isatty() else True,
696 + "piping": False if sys.stdout.isatty() else True,
697 # Set some defaults:
698 - 'quiet': False,
699 + "quiet": False,
700 # verbose is True if not quiet and not piping
701 - 'verbose': True,
702 - 'debug': False
703 + "verbose": True,
704 + "debug": False,
705 }
706
707 # vim: set ts=8 sw=4 tw=79:
708
709 diff --git a/pym/gentoolkit/atom.py b/pym/gentoolkit/atom.py
710 index 364fe4e..dd843d7 100644
711 --- a/pym/gentoolkit/atom.py
712 +++ b/pym/gentoolkit/atom.py
713 @@ -6,7 +6,7 @@
714
715 """Subclasses portage.dep.Atom to provide methods on a Gentoo atom string."""
716
717 -__all__ = ('Atom',)
718 +__all__ = ("Atom",)
719
720 # =======
721 # Imports
722 @@ -24,319 +24,319 @@ from gentoolkit import errors
723 # Classes
724 # =======
725
726 +
727 class Atom(portage.dep.Atom, CPV):
728 - """Portage's Atom class with improvements from pkgcore.
729 + """Portage's Atom class with improvements from pkgcore.
730 +
731 + portage.dep.Atom provides the following instance variables:
732 +
733 + @type operator: str
734 + @ivar operator: one of ('=', '=*', '<', '>', '<=', '>=', '~', None)
735 + @type cp: str
736 + @ivar cp: cat/pkg
737 + @type cpv: str
738 + @ivar cpv: cat/pkg-ver (if ver)
739 + @type slot: str or None (modified to tuple if not None)
740 + @ivar slot: slot passed in as cpv:#
741 + """
742 +
743 + # Necessary for Portage versions < 2.1.7
744 + _atoms = weakref.WeakValueDictionary()
745 +
746 + def __init__(self, atom):
747 + self.atom = atom
748 + self.operator = self.blocker = self.use = self.slot = None
749 +
750 + try:
751 + portage.dep.Atom.__init__(self, atom)
752 + except portage.exception.InvalidAtom:
753 + raise errors.GentoolkitInvalidAtom(atom)
754 +
755 + # Make operator compatible with intersects
756 + if self.operator is None:
757 + self.operator = ""
758 +
759 + CPV.__init__(self, self.cpv)
760 +
761 + # use_conditional is USE flag condition for this Atom to be required:
762 + # For: !build? ( >=sys-apps/sed-4.0.5 ), use_conditional = '!build'
763 + self.use_conditional = None
764 +
765 + def __eq__(self, other):
766 + if not isinstance(other, self.__class__):
767 + err = "other isn't of %s type, is %s"
768 + raise TypeError(err % (self.__class__, other.__class__))
769 +
770 + if self.operator != other.operator:
771 + return False
772 +
773 + if not CPV.__eq__(self, other):
774 + return False
775 +
776 + if bool(self.blocker) != bool(other.blocker):
777 + return False
778 +
779 + if self.blocker and other.blocker:
780 + if self.blocker.overlap.forbid != other.blocker.overlap.forbid:
781 + return False
782 +
783 + if self.use_conditional != other.use_conditional:
784 + return False
785 +
786 + # Don't believe Portage has something like this
787 + # c = cmp(self.negate_vers, other.negate_vers)
788 + # if c:
789 + # return c
790 +
791 + if self.slot != other.slot:
792 + return False
793 +
794 + this_use = None
795 + if self.use is not None:
796 + this_use = sorted(self.use.tokens)
797 + that_use = None
798 + if other.use is not None:
799 + that_use = sorted(other.use.tokens)
800 + if this_use != that_use:
801 + return False
802 +
803 + # Not supported by Portage Atom yet
804 + # return cmp(self.repo_name, other.repo_name)
805 + return True
806 +
807 + def __hash__(self):
808 + return hash(self.atom)
809 +
810 + def __ne__(self, other):
811 + return not self == other
812 +
813 + def __lt__(self, other):
814 + if not isinstance(other, self.__class__):
815 + err = "other isn't of %s type, is %s"
816 + raise TypeError(err % (self.__class__, other.__class__))
817 +
818 + if self.operator != other.operator:
819 + return self.operator < other.operator
820 +
821 + if not CPV.__eq__(self, other):
822 + return CPV.__lt__(self, other)
823 +
824 + if bool(self.blocker) != bool(other.blocker):
825 + # We want non blockers, then blockers, so only return True
826 + # if self.blocker is True and other.blocker is False.
827 + return bool(self.blocker) > bool(other.blocker)
828 +
829 + if self.blocker and other.blocker:
830 + if self.blocker.overlap.forbid != other.blocker.overlap.forbid:
831 + # we want !! prior to !
832 + return self.blocker.overlap.forbid < other.blocker.overlap.forbid
833 +
834 + # Don't believe Portage has something like this
835 + # c = cmp(self.negate_vers, other.negate_vers)
836 + # if c:
837 + # return c
838 +
839 + if self.slot != other.slot:
840 + if self.slot is None:
841 + return False
842 + elif other.slot is None:
843 + return True
844 + return self.slot < other.slot
845 +
846 + this_use = []
847 + if self.use is not None:
848 + this_use = sorted(self.use.tokens)
849 + that_use = []
850 + if other.use is not None:
851 + that_use = sorted(other.use.tokens)
852 + if this_use != that_use:
853 + return this_use < that_use
854 +
855 + # Not supported by Portage Atom yet
856 + # return cmp(self.repo_name, other.repo_name)
857 +
858 + return False
859 +
860 + def __gt__(self, other):
861 + if not isinstance(other, self.__class__):
862 + err = "other isn't of %s type, is %s"
863 + raise TypeError(err % (self.__class__, other.__class__))
864 +
865 + return not self <= other
866 +
867 + def __le__(self, other):
868 + if not isinstance(other, self.__class__):
869 + raise TypeError(
870 + "other isn't of %s type, is %s" % (self.__class__, other.__class__)
871 + )
872 + return self < other or self == other
873 +
874 + def __ge__(self, other):
875 + if not isinstance(other, self.__class__):
876 + raise TypeError(
877 + "other isn't of %s type, is %s" % (self.__class__, other.__class__)
878 + )
879 + return self > other or self == other
880 +
881 + def __repr__(self):
882 + uc = self.use_conditional
883 + uc = "%s? " % uc if uc is not None else ""
884 + return "<%s %r>" % (self.__class__.__name__, "%s%s" % (uc, self.atom))
885 +
886 + def __setattr__(self, name, value):
887 + object.__setattr__(self, name, value)
888 +
889 + def intersects(self, other):
890 + """Check if a passed in package atom "intersects" this atom.
891 +
892 + Lifted from pkgcore.
893 +
894 + Two atoms "intersect" if a package can be constructed that
895 + matches both:
896 + - if you query for just "dev-lang/python" it "intersects" both
897 + "dev-lang/python" and ">=dev-lang/python-2.4"
898 + - if you query for "=dev-lang/python-2.4" it "intersects"
899 + ">=dev-lang/python-2.4" and "dev-lang/python" but not
900 + "<dev-lang/python-2.3"
901 +
902 + @type other: L{gentoolkit.atom.Atom} or
903 + L{gentoolkit.versionmatch.VersionMatch}
904 + @param other: other package to compare
905 + @see: L{pkgcore.ebuild.atom}
906 + """
907 + # Our "cp" (cat/pkg) must match exactly:
908 + if self.cp != other.cp:
909 + # Check to see if one is name only:
910 + # We don't bother checking if self.category is None: it can't be
911 + # because we're an Atom subclass and that would be invalid.
912 + return not other.category and self.name == other.name
913 +
914 + # Slot dep only matters if we both have one. If we do they
915 + # must be identical:
916 + this_slot = getattr(self, "slot", None)
917 + that_slot = getattr(other, "slot", None)
918 + if this_slot is not None and that_slot is not None and this_slot != that_slot:
919 + return False
920 +
921 + if self.repo is not None and other.repo is not None and self.repo != other.repo:
922 + return False
923 +
924 + # Use deps are similar: if one of us forces a flag on and the
925 + # other forces it off we do not intersect. If only one of us
926 + # cares about a flag it is irrelevant.
927 +
928 + # Skip the (very common) case of one of us not having use deps:
929 + this_use = getattr(self, "use", None)
930 + that_use = getattr(other, "use", None)
931 + if this_use and that_use:
932 + # Set of flags we do not have in common:
933 + flags = set(this_use.tokens) ^ set(that_use.tokens)
934 + for flag in flags:
935 + # If this is unset and we also have the set version we fail:
936 + if flag[0] == "-" and flag[1:] in flags:
937 + return False
938 +
939 + # Remaining thing to check is version restrictions. Get the
940 + # ones we can check without actual version comparisons out of
941 + # the way first.
942 +
943 + # If one of us is unversioned we intersect:
944 + if not self.operator or not other.operator:
945 + return True
946 +
947 + # If we are both "unbounded" in the same direction we intersect:
948 + if ("<" in self.operator and "<" in other.operator) or (
949 + ">" in self.operator and ">" in other.operator
950 + ):
951 + return True
952 +
953 + # If one of us is an exact match we intersect if the other matches it:
954 + if self.operator == "=":
955 + if other.operator == "=*":
956 + return self.fullversion.startswith(other.fullversion)
957 + return VersionMatch(other, op=other.operator).match(self)
958 + if other.operator == "=":
959 + if self.operator == "=*":
960 + return other.fullversion.startswith(self.fullversion)
961 + return VersionMatch(self, op=self.operator).match(other)
962 +
963 + # If we are both ~ matches we match if we are identical:
964 + if self.operator == other.operator == "~":
965 + return self.version == other.version and self.revision == other.revision
966 +
967 + # If we are both glob matches we match if one of us matches the other.
968 + if self.operator == other.operator == "=*":
969 + return self.fullversion.startswith(
970 + other.fullversion
971 + ) or other.fullversion.startswith(self.fullversion)
972 +
973 + # If one of us is a glob match and the other a ~ we match if the glob
974 + # matches the ~ (ignoring a revision on the glob):
975 + if self.operator == "=*" and other.operator == "~":
976 + return other.fullversion.startswith(self.version)
977 + if other.operator == "=*" and self.operator == "~":
978 + return self.fullversion.startswith(other.version)
979 +
980 + # If we get here at least one of us is a <, <=, > or >=:
981 + if self.operator in ("<", "<=", ">", ">="):
982 + ranged, ranged.operator = self, self.operator
983 + else:
984 + ranged, ranged.operator = other, other.operator
985 + other, other.operator = self, self.operator
986 +
987 + if "<" in other.operator or ">" in other.operator:
988 + # We are both ranged, and in the opposite "direction" (or
989 + # we would have matched above). We intersect if we both
990 + # match the other's endpoint (just checking one endpoint
991 + # is not enough, it would give a false positive on <=2 vs >2)
992 + return VersionMatch(other, op=other.operator).match(
993 + ranged
994 + ) and VersionMatch(ranged, op=ranged.operator).match(other)
995 +
996 + if other.operator == "~":
997 + # Other definitely matches its own version. If ranged also
998 + # does we're done:
999 + if VersionMatch(ranged, op=ranged.operator).match(other):
1000 + return True
1001 + # The only other case where we intersect is if ranged is a
1002 + # > or >= on other's version and a nonzero revision. In
1003 + # that case other will match ranged. Be careful not to
1004 + # give a false positive for ~2 vs <2 here:
1005 + return ranged.operator in (">", ">=") and VersionMatch(
1006 + other, op=other.operator
1007 + ).match(ranged)
1008 +
1009 + if other.operator == "=*":
1010 + # a glob match definitely matches its own version, so if
1011 + # ranged does too we're done:
1012 + if VersionMatch(ranged, op=ranged.operator).match(other):
1013 + return True
1014 + if "<" in ranged.operator:
1015 + # If other.revision is not defined then other does not
1016 + # match anything smaller than its own fullversion:
1017 + if other.revision:
1018 + return False
1019 +
1020 + # If other.revision is defined then we can always
1021 + # construct a package smaller than other.fullversion by
1022 + # tagging e.g. an _alpha1 on.
1023 + return ranged.fullversion.startswith(other.version)
1024 + else:
1025 + # Remaining cases where this intersects: there is a
1026 + # package greater than ranged.fullversion and
1027 + # other.fullversion that they both match.
1028 + return ranged.fullversion.startswith(other.version)
1029 +
1030 + # Handled all possible ops.
1031 + raise NotImplementedError(
1032 + "Someone added an operator without adding it to intersects"
1033 + )
1034 +
1035 + def get_depstr(self):
1036 + """Returns a string representation of the original dep"""
1037 + uc = self.use_conditional
1038 + uc = "%s? " % uc if uc is not None else ""
1039 + return "%s%s" % (uc, self.atom)
1040
1041 - portage.dep.Atom provides the following instance variables:
1042 -
1043 - @type operator: str
1044 - @ivar operator: one of ('=', '=*', '<', '>', '<=', '>=', '~', None)
1045 - @type cp: str
1046 - @ivar cp: cat/pkg
1047 - @type cpv: str
1048 - @ivar cpv: cat/pkg-ver (if ver)
1049 - @type slot: str or None (modified to tuple if not None)
1050 - @ivar slot: slot passed in as cpv:#
1051 - """
1052 -
1053 - # Necessary for Portage versions < 2.1.7
1054 - _atoms = weakref.WeakValueDictionary()
1055 -
1056 - def __init__(self, atom):
1057 - self.atom = atom
1058 - self.operator = self.blocker = self.use = self.slot = None
1059 -
1060 - try:
1061 - portage.dep.Atom.__init__(self, atom)
1062 - except portage.exception.InvalidAtom:
1063 - raise errors.GentoolkitInvalidAtom(atom)
1064 -
1065 - # Make operator compatible with intersects
1066 - if self.operator is None:
1067 - self.operator = ''
1068 -
1069 - CPV.__init__(self, self.cpv)
1070 -
1071 - # use_conditional is USE flag condition for this Atom to be required:
1072 - # For: !build? ( >=sys-apps/sed-4.0.5 ), use_conditional = '!build'
1073 - self.use_conditional = None
1074 -
1075 - def __eq__(self, other):
1076 - if not isinstance(other, self.__class__):
1077 - err = "other isn't of %s type, is %s"
1078 - raise TypeError(err % (self.__class__, other.__class__))
1079 -
1080 - if self.operator != other.operator:
1081 - return False
1082 -
1083 - if not CPV.__eq__(self, other):
1084 - return False
1085 -
1086 - if bool(self.blocker) != bool(other.blocker):
1087 - return False
1088 -
1089 - if self.blocker and other.blocker:
1090 - if self.blocker.overlap.forbid != other.blocker.overlap.forbid:
1091 - return False
1092 -
1093 - if self.use_conditional != other.use_conditional:
1094 - return False
1095 -
1096 - # Don't believe Portage has something like this
1097 - #c = cmp(self.negate_vers, other.negate_vers)
1098 - #if c:
1099 - # return c
1100 -
1101 - if self.slot != other.slot:
1102 - return False
1103 -
1104 - this_use = None
1105 - if self.use is not None:
1106 - this_use = sorted(self.use.tokens)
1107 - that_use = None
1108 - if other.use is not None:
1109 - that_use = sorted(other.use.tokens)
1110 - if this_use != that_use:
1111 - return False
1112 -
1113 - # Not supported by Portage Atom yet
1114 - #return cmp(self.repo_name, other.repo_name)
1115 - return True
1116 -
1117 - def __hash__(self):
1118 - return hash(self.atom)
1119 -
1120 - def __ne__(self, other):
1121 - return not self == other
1122 -
1123 - def __lt__(self, other):
1124 - if not isinstance(other, self.__class__):
1125 - err = "other isn't of %s type, is %s"
1126 - raise TypeError(err % (self.__class__, other.__class__))
1127 -
1128 - if self.operator != other.operator:
1129 - return self.operator < other.operator
1130 -
1131 - if not CPV.__eq__(self, other):
1132 - return CPV.__lt__(self, other)
1133 -
1134 - if bool(self.blocker) != bool(other.blocker):
1135 - # We want non blockers, then blockers, so only return True
1136 - # if self.blocker is True and other.blocker is False.
1137 - return bool(self.blocker) > bool(other.blocker)
1138 -
1139 - if self.blocker and other.blocker:
1140 - if self.blocker.overlap.forbid != other.blocker.overlap.forbid:
1141 - # we want !! prior to !
1142 - return (self.blocker.overlap.forbid <
1143 - other.blocker.overlap.forbid)
1144 -
1145 - # Don't believe Portage has something like this
1146 - #c = cmp(self.negate_vers, other.negate_vers)
1147 - #if c:
1148 - # return c
1149 -
1150 - if self.slot != other.slot:
1151 - if self.slot is None:
1152 - return False
1153 - elif other.slot is None:
1154 - return True
1155 - return self.slot < other.slot
1156 -
1157 - this_use = []
1158 - if self.use is not None:
1159 - this_use = sorted(self.use.tokens)
1160 - that_use = []
1161 - if other.use is not None:
1162 - that_use = sorted(other.use.tokens)
1163 - if this_use != that_use:
1164 - return this_use < that_use
1165 -
1166 - # Not supported by Portage Atom yet
1167 - #return cmp(self.repo_name, other.repo_name)
1168 -
1169 - return False
1170 -
1171 - def __gt__(self, other):
1172 - if not isinstance(other, self.__class__):
1173 - err = "other isn't of %s type, is %s"
1174 - raise TypeError(err % (self.__class__, other.__class__))
1175 -
1176 - return not self <= other
1177 -
1178 - def __le__(self, other):
1179 - if not isinstance(other, self.__class__):
1180 - raise TypeError("other isn't of %s type, is %s" % (
1181 - self.__class__, other.__class__)
1182 - )
1183 - return self < other or self == other
1184 -
1185 - def __ge__(self, other):
1186 - if not isinstance(other, self.__class__):
1187 - raise TypeError("other isn't of %s type, is %s" % (
1188 - self.__class__, other.__class__)
1189 - )
1190 - return self > other or self == other
1191 -
1192 - def __repr__(self):
1193 - uc = self.use_conditional
1194 - uc = "%s? " % uc if uc is not None else ''
1195 - return "<%s %r>" % (self.__class__.__name__, "%s%s" % (uc, self.atom))
1196 -
1197 - def __setattr__(self, name, value):
1198 - object.__setattr__(self, name, value)
1199 -
1200 - def intersects(self, other):
1201 - """Check if a passed in package atom "intersects" this atom.
1202 -
1203 - Lifted from pkgcore.
1204 -
1205 - Two atoms "intersect" if a package can be constructed that
1206 - matches both:
1207 - - if you query for just "dev-lang/python" it "intersects" both
1208 - "dev-lang/python" and ">=dev-lang/python-2.4"
1209 - - if you query for "=dev-lang/python-2.4" it "intersects"
1210 - ">=dev-lang/python-2.4" and "dev-lang/python" but not
1211 - "<dev-lang/python-2.3"
1212 -
1213 - @type other: L{gentoolkit.atom.Atom} or
1214 - L{gentoolkit.versionmatch.VersionMatch}
1215 - @param other: other package to compare
1216 - @see: L{pkgcore.ebuild.atom}
1217 - """
1218 - # Our "cp" (cat/pkg) must match exactly:
1219 - if self.cp != other.cp:
1220 - # Check to see if one is name only:
1221 - # We don't bother checking if self.category is None: it can't be
1222 - # because we're an Atom subclass and that would be invalid.
1223 - return (not other.category and self.name == other.name)
1224 -
1225 - # Slot dep only matters if we both have one. If we do they
1226 - # must be identical:
1227 - this_slot = getattr(self, 'slot', None)
1228 - that_slot = getattr(other, 'slot', None)
1229 - if (this_slot is not None and that_slot is not None and
1230 - this_slot != that_slot):
1231 - return False
1232 -
1233 - if (self.repo is not None and other.repo is not None and
1234 - self.repo != other.repo):
1235 - return False
1236 -
1237 - # Use deps are similar: if one of us forces a flag on and the
1238 - # other forces it off we do not intersect. If only one of us
1239 - # cares about a flag it is irrelevant.
1240 -
1241 - # Skip the (very common) case of one of us not having use deps:
1242 - this_use = getattr(self, 'use', None)
1243 - that_use = getattr(other, 'use', None)
1244 - if this_use and that_use:
1245 - # Set of flags we do not have in common:
1246 - flags = set(this_use.tokens) ^ set(that_use.tokens)
1247 - for flag in flags:
1248 - # If this is unset and we also have the set version we fail:
1249 - if flag[0] == '-' and flag[1:] in flags:
1250 - return False
1251 -
1252 - # Remaining thing to check is version restrictions. Get the
1253 - # ones we can check without actual version comparisons out of
1254 - # the way first.
1255 -
1256 - # If one of us is unversioned we intersect:
1257 - if not self.operator or not other.operator:
1258 - return True
1259 -
1260 - # If we are both "unbounded" in the same direction we intersect:
1261 - if (('<' in self.operator and '<' in other.operator) or
1262 - ('>' in self.operator and '>' in other.operator)):
1263 - return True
1264 -
1265 - # If one of us is an exact match we intersect if the other matches it:
1266 - if self.operator == '=':
1267 - if other.operator == '=*':
1268 - return self.fullversion.startswith(other.fullversion)
1269 - return VersionMatch(other, op=other.operator).match(self)
1270 - if other.operator == '=':
1271 - if self.operator == '=*':
1272 - return other.fullversion.startswith(self.fullversion)
1273 - return VersionMatch(self, op=self.operator).match(other)
1274 -
1275 - # If we are both ~ matches we match if we are identical:
1276 - if self.operator == other.operator == '~':
1277 - return (self.version == other.version and
1278 - self.revision == other.revision)
1279 -
1280 - # If we are both glob matches we match if one of us matches the other.
1281 - if self.operator == other.operator == '=*':
1282 - return (self.fullversion.startswith(other.fullversion) or
1283 - other.fullversion.startswith(self.fullversion))
1284 -
1285 - # If one of us is a glob match and the other a ~ we match if the glob
1286 - # matches the ~ (ignoring a revision on the glob):
1287 - if self.operator == '=*' and other.operator == '~':
1288 - return other.fullversion.startswith(self.version)
1289 - if other.operator == '=*' and self.operator == '~':
1290 - return self.fullversion.startswith(other.version)
1291 -
1292 - # If we get here at least one of us is a <, <=, > or >=:
1293 - if self.operator in ('<', '<=', '>', '>='):
1294 - ranged, ranged.operator = self, self.operator
1295 - else:
1296 - ranged, ranged.operator = other, other.operator
1297 - other, other.operator = self, self.operator
1298 -
1299 - if '<' in other.operator or '>' in other.operator:
1300 - # We are both ranged, and in the opposite "direction" (or
1301 - # we would have matched above). We intersect if we both
1302 - # match the other's endpoint (just checking one endpoint
1303 - # is not enough, it would give a false positive on <=2 vs >2)
1304 - return (
1305 - VersionMatch(other, op=other.operator).match(ranged) and
1306 - VersionMatch(ranged, op=ranged.operator).match(other)
1307 - )
1308 -
1309 - if other.operator == '~':
1310 - # Other definitely matches its own version. If ranged also
1311 - # does we're done:
1312 - if VersionMatch(ranged, op=ranged.operator).match(other):
1313 - return True
1314 - # The only other case where we intersect is if ranged is a
1315 - # > or >= on other's version and a nonzero revision. In
1316 - # that case other will match ranged. Be careful not to
1317 - # give a false positive for ~2 vs <2 here:
1318 - return (ranged.operator in ('>', '>=') and
1319 - VersionMatch(other, op=other.operator).match(ranged))
1320 -
1321 - if other.operator == '=*':
1322 - # a glob match definitely matches its own version, so if
1323 - # ranged does too we're done:
1324 - if VersionMatch(ranged, op=ranged.operator).match(other):
1325 - return True
1326 - if '<' in ranged.operator:
1327 - # If other.revision is not defined then other does not
1328 - # match anything smaller than its own fullversion:
1329 - if other.revision:
1330 - return False
1331 -
1332 - # If other.revision is defined then we can always
1333 - # construct a package smaller than other.fullversion by
1334 - # tagging e.g. an _alpha1 on.
1335 - return ranged.fullversion.startswith(other.version)
1336 - else:
1337 - # Remaining cases where this intersects: there is a
1338 - # package greater than ranged.fullversion and
1339 - # other.fullversion that they both match.
1340 - return ranged.fullversion.startswith(other.version)
1341 -
1342 - # Handled all possible ops.
1343 - raise NotImplementedError(
1344 - 'Someone added an operator without adding it to intersects')
1345 -
1346 - def get_depstr(self):
1347 - """Returns a string representation of the original dep
1348 - """
1349 - uc = self.use_conditional
1350 - uc = "%s? " % uc if uc is not None else ''
1351 - return "%s%s" % (uc, self.atom)
1352
1353 # vim: set ts=4 sw=4 tw=79:
1354
1355 diff --git a/pym/gentoolkit/base.py b/pym/gentoolkit/base.py
1356 index 372ed74..8dfa2db 100644
1357 --- a/pym/gentoolkit/base.py
1358 +++ b/pym/gentoolkit/base.py
1359 @@ -6,7 +6,7 @@
1360 """Gentoolkit Base Module class to hold common module operation functions
1361 """
1362
1363 -__docformat__ = 'epytext'
1364 +__docformat__ = "epytext"
1365
1366
1367 import os
1368 @@ -18,127 +18,132 @@ from gentoolkit.formatters import format_options
1369
1370
1371 GLOBAL_OPTIONS = (
1372 - (" -h, --help", "display this help message"),
1373 - (" -q, --quiet", "minimal output"),
1374 - (" -C, --no-color", "turn off colors"),
1375 - (" -N, --no-pipe", "turn off pipe detection"),
1376 - (" -V, --version", "display version info")
1377 + (" -h, --help", "display this help message"),
1378 + (" -q, --quiet", "minimal output"),
1379 + (" -C, --no-color", "turn off colors"),
1380 + (" -N, --no-pipe", "turn off pipe detection"),
1381 + (" -V, --version", "display version info"),
1382 )
1383
1384
1385 def initialize_configuration():
1386 - """Setup the standard equery config"""
1387 -
1388 - # Get terminal size
1389 - term_width = pp.output.get_term_size()[1]
1390 - if term_width < 1:
1391 - # get_term_size() failed. Set a sane default width:
1392 - term_width = 80
1393 - # Terminal size, minus a 1-char margin for text wrapping
1394 - gentoolkit.CONFIG['termWidth'] = term_width - 1
1395 - # Guess color output
1396 - if (gentoolkit.CONFIG['color'] == -1 and (not sys.stdout.isatty() or
1397 - os.getenv("NOCOLOR") in ("yes", "true")) or gentoolkit.CONFIG['color'] == 0):
1398 - pp.output.nocolor()
1399 - gentoolkit.CONFIG['verbose'] = not gentoolkit.CONFIG['piping']
1400 + """Setup the standard equery config"""
1401 +
1402 + # Get terminal size
1403 + term_width = pp.output.get_term_size()[1]
1404 + if term_width < 1:
1405 + # get_term_size() failed. Set a sane default width:
1406 + term_width = 80
1407 + # Terminal size, minus a 1-char margin for text wrapping
1408 + gentoolkit.CONFIG["termWidth"] = term_width - 1
1409 + # Guess color output
1410 + if (
1411 + gentoolkit.CONFIG["color"] == -1
1412 + and (not sys.stdout.isatty() or os.getenv("NOCOLOR") in ("yes", "true"))
1413 + or gentoolkit.CONFIG["color"] == 0
1414 + ):
1415 + pp.output.nocolor()
1416 + gentoolkit.CONFIG["verbose"] = not gentoolkit.CONFIG["piping"]
1417
1418
1419 def split_arguments(args):
1420 - """Separate module name from module arguments"""
1421 + """Separate module name from module arguments"""
1422
1423 - return args.pop(0), args
1424 + return args.pop(0), args
1425
1426
1427 def main_usage(module_info):
1428 - """Return the main usage message for analyse"""
1429 - return "%(usage)s %(product)s [%(g_opts)s] %(mod_name)s [%(mod_opts)s]" % {
1430 - 'usage': pp.emph("Usage:"),
1431 - 'product': pp.productname(module_info["__productname__"]),
1432 - 'g_opts': pp.globaloption("global-options"),
1433 - 'mod_name': pp.command("module-name"),
1434 - 'mod_opts': pp.localoption("module-options")
1435 - }
1436 + """Return the main usage message for analyse"""
1437 + return "%(usage)s %(product)s [%(g_opts)s] %(mod_name)s [%(mod_opts)s]" % {
1438 + "usage": pp.emph("Usage:"),
1439 + "product": pp.productname(module_info["__productname__"]),
1440 + "g_opts": pp.globaloption("global-options"),
1441 + "mod_name": pp.command("module-name"),
1442 + "mod_opts": pp.localoption("module-options"),
1443 + }
1444
1445
1446 def print_version(module_info):
1447 - """Print the version of this tool to the console."""
1448 + """Print the version of this tool to the console."""
1449
1450 - print("%(product)s (%(version)s) - %(docstring)s" % {
1451 - "product": pp.productname(module_info["__productname__"]),
1452 - "version": module_info["__version__"],
1453 - "docstring": module_info["__doc__"]
1454 - })
1455 + print(
1456 + "%(product)s (%(version)s) - %(docstring)s"
1457 + % {
1458 + "product": pp.productname(module_info["__productname__"]),
1459 + "version": module_info["__version__"],
1460 + "docstring": module_info["__doc__"],
1461 + }
1462 + )
1463
1464
1465 def print_help(module_info, formatted_options=None, with_description=True):
1466 - """Print description, usage and a detailed help message.
1467 -
1468 - @param with_description (bool): Option to print module's __doc__ or not
1469 - """
1470 -
1471 - if with_description:
1472 - print()
1473 - print(module_info["__doc__"])
1474 - print()
1475 - print(main_usage(module_info))
1476 - print()
1477 - print(pp.globaloption("global options"))
1478 - print(format_options(GLOBAL_OPTIONS))
1479 - print()
1480 - if formatted_options:
1481 - print(pp.command("modules") + " (" + pp.command("short name") + ")")
1482 - print(format_options(formatted_options))
1483 - else:
1484 - print("Error: calling function did not supply formatted options")
1485 - print()
1486 + """Print description, usage and a detailed help message.
1487 +
1488 + @param with_description (bool): Option to print module's __doc__ or not
1489 + """
1490 +
1491 + if with_description:
1492 + print()
1493 + print(module_info["__doc__"])
1494 + print()
1495 + print(main_usage(module_info))
1496 + print()
1497 + print(pp.globaloption("global options"))
1498 + print(format_options(GLOBAL_OPTIONS))
1499 + print()
1500 + if formatted_options:
1501 + print(pp.command("modules") + " (" + pp.command("short name") + ")")
1502 + print(format_options(formatted_options))
1503 + else:
1504 + print("Error: calling function did not supply formatted options")
1505 + print()
1506
1507
1508 def parse_global_options(global_opts, args, module_info, formatted_options):
1509 - """Parse global input args and return True if we should display help for
1510 - the called module, else False (or display help and exit from here).
1511 - """
1512 -
1513 - need_help = False
1514 - do_help = False
1515 - opts = (opt[0] for opt in global_opts)
1516 - for opt in opts:
1517 - if opt in ('-h', '--help'):
1518 - do_help = True
1519 - if args:
1520 - need_help = True
1521 - else:
1522 - do_help = True
1523 - elif opt in ('-q','--quiet'):
1524 - gentoolkit.CONFIG['quiet'] = True
1525 - elif opt in ('-C', '--no-color', '--nocolor'):
1526 - gentoolkit.CONFIG['color'] = 0
1527 - pp.output.nocolor()
1528 - elif opt in ('-N', '--no-pipe'):
1529 - gentoolkit.CONFIG['piping'] = False
1530 - elif opt in ('-V', '--version'):
1531 - print_version(module_info)
1532 - sys.exit(0)
1533 - elif opt in ('--debug'):
1534 - gentoolkit.CONFIG['debug'] = True
1535 - if do_help:
1536 - print_help( module_info, formatted_options)
1537 - sys.exit(0)
1538 - return need_help
1539 + """Parse global input args and return True if we should display help for
1540 + the called module, else False (or display help and exit from here).
1541 + """
1542 +
1543 + need_help = False
1544 + do_help = False
1545 + opts = (opt[0] for opt in global_opts)
1546 + for opt in opts:
1547 + if opt in ("-h", "--help"):
1548 + do_help = True
1549 + if args:
1550 + need_help = True
1551 + else:
1552 + do_help = True
1553 + elif opt in ("-q", "--quiet"):
1554 + gentoolkit.CONFIG["quiet"] = True
1555 + elif opt in ("-C", "--no-color", "--nocolor"):
1556 + gentoolkit.CONFIG["color"] = 0
1557 + pp.output.nocolor()
1558 + elif opt in ("-N", "--no-pipe"):
1559 + gentoolkit.CONFIG["piping"] = False
1560 + elif opt in ("-V", "--version"):
1561 + print_version(module_info)
1562 + sys.exit(0)
1563 + elif opt in ("--debug"):
1564 + gentoolkit.CONFIG["debug"] = True
1565 + if do_help:
1566 + print_help(module_info, formatted_options)
1567 + sys.exit(0)
1568 + return need_help
1569
1570
1571 def mod_usage(mod_name="module", arg="pkgspec", optional=False):
1572 - """Provide a consistant usage message to the calling module.
1573 -
1574 - @type arg: string
1575 - @param arg: what kind of argument the module takes (pkgspec, filename, etc)
1576 - @type optional: bool
1577 - @param optional: is the argument optional?
1578 - """
1579 -
1580 - return "%(usage)s: %(mod_name)s [%(opts)s] %(arg)s" % {
1581 - 'usage': pp.emph("Usage"),
1582 - 'mod_name': pp.command(mod_name),
1583 - 'opts': pp.localoption("options"),
1584 - 'arg': ("[%s]" % pp.emph(arg)) if optional else pp.emph(arg)
1585 - }
1586 -
1587 + """Provide a consistant usage message to the calling module.
1588 +
1589 + @type arg: string
1590 + @param arg: what kind of argument the module takes (pkgspec, filename, etc)
1591 + @type optional: bool
1592 + @param optional: is the argument optional?
1593 + """
1594 +
1595 + return "%(usage)s: %(mod_name)s [%(opts)s] %(arg)s" % {
1596 + "usage": pp.emph("Usage"),
1597 + "mod_name": pp.command(mod_name),
1598 + "opts": pp.localoption("options"),
1599 + "arg": ("[%s]" % pp.emph(arg)) if optional else pp.emph(arg),
1600 + }
1601
1602 diff --git a/pym/gentoolkit/cpv.py b/pym/gentoolkit/cpv.py
1603 index 5238e24..6b2a533 100644
1604 --- a/pym/gentoolkit/cpv.py
1605 +++ b/pym/gentoolkit/cpv.py
1606 @@ -6,11 +6,7 @@
1607
1608 """Provides attributes and methods for a category/package-version string."""
1609
1610 -__all__ = (
1611 - 'CPV',
1612 - 'compare_strs',
1613 - 'split_cpv'
1614 -)
1615 +__all__ = ("CPV", "compare_strs", "split_cpv")
1616
1617 # =======
1618 # Imports
1619 @@ -26,228 +22,232 @@ from gentoolkit import errors
1620 # Globals
1621 # =======
1622
1623 -isvalid_version_re = re.compile(r"^(?:cvs\.)?(?:\d+)(?:\.\d+)*[a-z]?"
1624 - r"(?:_(p(?:re)?|beta|alpha|rc)\d*)*$")
1625 +isvalid_version_re = re.compile(
1626 + r"^(?:cvs\.)?(?:\d+)(?:\.\d+)*[a-z]?" r"(?:_(p(?:re)?|beta|alpha|rc)\d*)*$"
1627 +)
1628 isvalid_cat_re = re.compile(r"^(?:[a-zA-Z0-9][-a-zA-Z0-9+._]*(?:/(?!$))?)+$")
1629 _pkg_re = re.compile(r"^[a-zA-Z0-9+._]+$")
1630 # Prefix specific revision is of the form -r0<digit>+.<digit>+
1631 -isvalid_rev_re = re.compile(r'(\d+|0\d+\.\d+)')
1632 +isvalid_rev_re = re.compile(r"(\d+|0\d+\.\d+)")
1633
1634 # =======
1635 # Classes
1636 # =======
1637
1638 +
1639 class CPV:
1640 - """Provides methods on a category/package-version string.
1641 -
1642 - Will also correctly split just a package or package-version string.
1643 -
1644 - Example usage:
1645 - >>> from gentoolkit.cpv import CPV
1646 - >>> cpv = CPV('sys-apps/portage-2.2-r1')
1647 - >>> cpv.category, cpv.name, cpv.fullversion
1648 - ('sys-apps', 'portage', '2.2-r1')
1649 - >>> str(cpv)
1650 - 'sys-apps/portage-2.2-r1'
1651 - >>> # An 'rc' (release candidate) version is less than non 'rc' version:
1652 - ... CPV('sys-apps/portage-2') > CPV('sys-apps/portage-2_rc10')
1653 - True
1654 - """
1655 -
1656 - def __init__(self, cpv, validate=False):
1657 - self.cpv = cpv
1658 - self._category = None
1659 - self._name = None
1660 - self._version = None
1661 - self._revision = None
1662 - self._cp = None
1663 - self._fullversion = None
1664 -
1665 - self.validate = validate
1666 - if validate and not self.name:
1667 - raise errors.GentoolkitInvalidCPV(cpv)
1668 -
1669 - @property
1670 - def category(self):
1671 - if self._category is None:
1672 - self._set_cpv_chunks()
1673 - return self._category
1674 -
1675 - @property
1676 - def name(self):
1677 - if self._name is None:
1678 - self._set_cpv_chunks()
1679 - return self._name
1680 -
1681 - @property
1682 - def version(self):
1683 - if self._version is None:
1684 - self._set_cpv_chunks()
1685 - return self._version
1686 -
1687 - @property
1688 - def revision(self):
1689 - if self._revision is None:
1690 - self._set_cpv_chunks()
1691 - return self._revision
1692 -
1693 - @property
1694 - def cp(self):
1695 - if self._cp is None:
1696 - sep = '/' if self.category else ''
1697 - self._cp = sep.join((self.category, self.name))
1698 - return self._cp
1699 -
1700 - @property
1701 - def fullversion(self):
1702 - if self._fullversion is None:
1703 - sep = '-' if self.revision else ''
1704 - self._fullversion = sep.join((self.version, self.revision))
1705 - return self._fullversion
1706 -
1707 - def _set_cpv_chunks(self):
1708 - chunks = split_cpv(self.cpv, validate=self.validate)
1709 - self._category = chunks[0]
1710 - self._name = chunks[1]
1711 - self._version = chunks[2]
1712 - self._revision = chunks[3]
1713 -
1714 - def __eq__(self, other):
1715 - if not isinstance(other, self.__class__):
1716 - return False
1717 - return self.cpv == other.cpv
1718 -
1719 - def __hash__(self):
1720 - return hash(self.cpv)
1721 -
1722 - def __ne__(self, other):
1723 - return not self == other
1724 -
1725 - def __lt__(self, other):
1726 - if not isinstance(other, self.__class__):
1727 - raise TypeError("other isn't of %s type, is %s" % (
1728 - self.__class__, other.__class__)
1729 - )
1730 -
1731 - if self.category != other.category:
1732 - return self.category < other.category
1733 - elif self.name != other.name:
1734 - return self.name < other.name
1735 - else:
1736 - # FIXME: this cmp() hack is for vercmp not using -1,0,1
1737 - # See bug 266493; this was fixed in portage-2.2_rc31
1738 - #return vercmp(self.fullversion, other.fullversion)
1739 - return vercmp(self.fullversion, other.fullversion) < 0
1740 -
1741 - def __gt__(self, other):
1742 - if not isinstance(other, self.__class__):
1743 - raise TypeError("other isn't of %s type, is %s" % (
1744 - self.__class__, other.__class__)
1745 - )
1746 - return not self <= other
1747 -
1748 - def __le__(self, other):
1749 - if not isinstance(other, self.__class__):
1750 - raise TypeError("other isn't of %s type, is %s" % (
1751 - self.__class__, other.__class__)
1752 - )
1753 - return self < other or self == other
1754 -
1755 - def __ge__(self, other):
1756 - if not isinstance(other, self.__class__):
1757 - raise TypeError("other isn't of %s type, is %s" % (
1758 - self.__class__, other.__class__)
1759 - )
1760 - return self > other or self == other
1761 -
1762 - def __repr__(self):
1763 - return "<%s %r>" % (self.__class__.__name__, str(self))
1764 -
1765 - def __str__(self):
1766 - return self.cpv
1767 + """Provides methods on a category/package-version string.
1768 +
1769 + Will also correctly split just a package or package-version string.
1770 +
1771 + Example usage:
1772 + >>> from gentoolkit.cpv import CPV
1773 + >>> cpv = CPV('sys-apps/portage-2.2-r1')
1774 + >>> cpv.category, cpv.name, cpv.fullversion
1775 + ('sys-apps', 'portage', '2.2-r1')
1776 + >>> str(cpv)
1777 + 'sys-apps/portage-2.2-r1'
1778 + >>> # An 'rc' (release candidate) version is less than non 'rc' version:
1779 + ... CPV('sys-apps/portage-2') > CPV('sys-apps/portage-2_rc10')
1780 + True
1781 + """
1782 +
1783 + def __init__(self, cpv, validate=False):
1784 + self.cpv = cpv
1785 + self._category = None
1786 + self._name = None
1787 + self._version = None
1788 + self._revision = None
1789 + self._cp = None
1790 + self._fullversion = None
1791 +
1792 + self.validate = validate
1793 + if validate and not self.name:
1794 + raise errors.GentoolkitInvalidCPV(cpv)
1795 +
1796 + @property
1797 + def category(self):
1798 + if self._category is None:
1799 + self._set_cpv_chunks()
1800 + return self._category
1801 +
1802 + @property
1803 + def name(self):
1804 + if self._name is None:
1805 + self._set_cpv_chunks()
1806 + return self._name
1807 +
1808 + @property
1809 + def version(self):
1810 + if self._version is None:
1811 + self._set_cpv_chunks()
1812 + return self._version
1813 +
1814 + @property
1815 + def revision(self):
1816 + if self._revision is None:
1817 + self._set_cpv_chunks()
1818 + return self._revision
1819 +
1820 + @property
1821 + def cp(self):
1822 + if self._cp is None:
1823 + sep = "/" if self.category else ""
1824 + self._cp = sep.join((self.category, self.name))
1825 + return self._cp
1826 +
1827 + @property
1828 + def fullversion(self):
1829 + if self._fullversion is None:
1830 + sep = "-" if self.revision else ""
1831 + self._fullversion = sep.join((self.version, self.revision))
1832 + return self._fullversion
1833 +
1834 + def _set_cpv_chunks(self):
1835 + chunks = split_cpv(self.cpv, validate=self.validate)
1836 + self._category = chunks[0]
1837 + self._name = chunks[1]
1838 + self._version = chunks[2]
1839 + self._revision = chunks[3]
1840 +
1841 + def __eq__(self, other):
1842 + if not isinstance(other, self.__class__):
1843 + return False
1844 + return self.cpv == other.cpv
1845 +
1846 + def __hash__(self):
1847 + return hash(self.cpv)
1848 +
1849 + def __ne__(self, other):
1850 + return not self == other
1851 +
1852 + def __lt__(self, other):
1853 + if not isinstance(other, self.__class__):
1854 + raise TypeError(
1855 + "other isn't of %s type, is %s" % (self.__class__, other.__class__)
1856 + )
1857 +
1858 + if self.category != other.category:
1859 + return self.category < other.category
1860 + elif self.name != other.name:
1861 + return self.name < other.name
1862 + else:
1863 + # FIXME: this cmp() hack is for vercmp not using -1,0,1
1864 + # See bug 266493; this was fixed in portage-2.2_rc31
1865 + # return vercmp(self.fullversion, other.fullversion)
1866 + return vercmp(self.fullversion, other.fullversion) < 0
1867 +
1868 + def __gt__(self, other):
1869 + if not isinstance(other, self.__class__):
1870 + raise TypeError(
1871 + "other isn't of %s type, is %s" % (self.__class__, other.__class__)
1872 + )
1873 + return not self <= other
1874 +
1875 + def __le__(self, other):
1876 + if not isinstance(other, self.__class__):
1877 + raise TypeError(
1878 + "other isn't of %s type, is %s" % (self.__class__, other.__class__)
1879 + )
1880 + return self < other or self == other
1881 +
1882 + def __ge__(self, other):
1883 + if not isinstance(other, self.__class__):
1884 + raise TypeError(
1885 + "other isn't of %s type, is %s" % (self.__class__, other.__class__)
1886 + )
1887 + return self > other or self == other
1888 +
1889 + def __repr__(self):
1890 + return "<%s %r>" % (self.__class__.__name__, str(self))
1891 +
1892 + def __str__(self):
1893 + return self.cpv
1894
1895
1896 # =========
1897 # Functions
1898 # =========
1899
1900 +
1901 def compare_strs(pkg1, pkg2):
1902 - """Similar to the builtin cmp, but for package strings. Usually called
1903 - as: package_list.sort(cpv.compare_strs)
1904 + """Similar to the builtin cmp, but for package strings. Usually called
1905 + as: package_list.sort(cpv.compare_strs)
1906
1907 - An alternative is to use the CPV descriptor from gentoolkit.cpv:
1908 - >>> package_list = ['sys-apps/portage-9999', 'media-video/ffmpeg-9999']
1909 - >>> cpvs = sorted(CPV(x) for x in package_list)
1910 + An alternative is to use the CPV descriptor from gentoolkit.cpv:
1911 + >>> package_list = ['sys-apps/portage-9999', 'media-video/ffmpeg-9999']
1912 + >>> cpvs = sorted(CPV(x) for x in package_list)
1913
1914 - @see: >>> help(cmp)
1915 - """
1916 + @see: >>> help(cmp)
1917 + """
1918
1919 - pkg1 = catpkgsplit(pkg1)
1920 - pkg2 = catpkgsplit(pkg2)
1921 - if pkg1[0] != pkg2[0]:
1922 - return -1 if pkg1[0] < pkg2[0] else 1
1923 - elif pkg1[1] != pkg2[1]:
1924 - return -1 if pkg1[1] < pkg2[1] else 1
1925 - else:
1926 - return pkgcmp(pkg1[1:], pkg2[1:])
1927 + pkg1 = catpkgsplit(pkg1)
1928 + pkg2 = catpkgsplit(pkg2)
1929 + if pkg1[0] != pkg2[0]:
1930 + return -1 if pkg1[0] < pkg2[0] else 1
1931 + elif pkg1[1] != pkg2[1]:
1932 + return -1 if pkg1[1] < pkg2[1] else 1
1933 + else:
1934 + return pkgcmp(pkg1[1:], pkg2[1:])
1935
1936
1937 def split_cpv(cpv, validate=True):
1938 - """Split a cpv into category, name, version and revision.
1939 -
1940 - Modified from pkgcore.ebuild.cpv
1941 -
1942 - @type cpv: str
1943 - @param cpv: pkg, cat/pkg, pkg-ver, cat/pkg-ver
1944 - @rtype: tuple
1945 - @return: (category, pkg_name, version, revision)
1946 - Each tuple element is a string or empty string ("").
1947 - """
1948 -
1949 - category = name = version = revision = ''
1950 -
1951 - try:
1952 - category, pkgver = cpv.rsplit("/", 1)
1953 - except ValueError:
1954 - pkgver = cpv
1955 - if validate and category and not isvalid_cat_re.match(category):
1956 - raise errors.GentoolkitInvalidCPV(cpv)
1957 - pkg_chunks = pkgver.split("-")
1958 - lpkg_chunks = len(pkg_chunks)
1959 - if lpkg_chunks == 1:
1960 - return (category, pkg_chunks[0], version, revision)
1961 - if isvalid_rev(pkg_chunks[-1]):
1962 - if lpkg_chunks < 3:
1963 - # needs at least ('pkg', 'ver', 'rev')
1964 - raise errors.GentoolkitInvalidCPV(cpv)
1965 - rev = pkg_chunks.pop(-1)
1966 - if rev:
1967 - revision = rev
1968 -
1969 - if isvalid_version_re.match(pkg_chunks[-1]):
1970 - version = pkg_chunks.pop(-1)
1971 -
1972 - if not isvalid_pkg_name(pkg_chunks):
1973 - raise errors.GentoolkitInvalidCPV(cpv)
1974 - name = '-'.join(pkg_chunks)
1975 -
1976 - return (category, name, version, revision)
1977 + """Split a cpv into category, name, version and revision.
1978 +
1979 + Modified from pkgcore.ebuild.cpv
1980 +
1981 + @type cpv: str
1982 + @param cpv: pkg, cat/pkg, pkg-ver, cat/pkg-ver
1983 + @rtype: tuple
1984 + @return: (category, pkg_name, version, revision)
1985 + Each tuple element is a string or empty string ("").
1986 + """
1987 +
1988 + category = name = version = revision = ""
1989 +
1990 + try:
1991 + category, pkgver = cpv.rsplit("/", 1)
1992 + except ValueError:
1993 + pkgver = cpv
1994 + if validate and category and not isvalid_cat_re.match(category):
1995 + raise errors.GentoolkitInvalidCPV(cpv)
1996 + pkg_chunks = pkgver.split("-")
1997 + lpkg_chunks = len(pkg_chunks)
1998 + if lpkg_chunks == 1:
1999 + return (category, pkg_chunks[0], version, revision)
2000 + if isvalid_rev(pkg_chunks[-1]):
2001 + if lpkg_chunks < 3:
2002 + # needs at least ('pkg', 'ver', 'rev')
2003 + raise errors.GentoolkitInvalidCPV(cpv)
2004 + rev = pkg_chunks.pop(-1)
2005 + if rev:
2006 + revision = rev
2007 +
2008 + if isvalid_version_re.match(pkg_chunks[-1]):
2009 + version = pkg_chunks.pop(-1)
2010 +
2011 + if not isvalid_pkg_name(pkg_chunks):
2012 + raise errors.GentoolkitInvalidCPV(cpv)
2013 + name = "-".join(pkg_chunks)
2014 +
2015 + return (category, name, version, revision)
2016
2017
2018 def isvalid_pkg_name(chunks):
2019 - if not chunks[0]:
2020 - # this means a leading -
2021 - return False
2022 - mf = _pkg_re.match
2023 - if not all(not s or mf(s) for s in chunks):
2024 - return False
2025 - if len(chunks) > 1 and chunks[-1].isdigit():
2026 - # not allowed.
2027 - return False
2028 - return True
2029 + if not chunks[0]:
2030 + # this means a leading -
2031 + return False
2032 + mf = _pkg_re.match
2033 + if not all(not s or mf(s) for s in chunks):
2034 + return False
2035 + if len(chunks) > 1 and chunks[-1].isdigit():
2036 + # not allowed.
2037 + return False
2038 + return True
2039
2040
2041 def isvalid_rev(s):
2042 - return s and s[0] == 'r' and isvalid_rev_re.match(s[1:])
2043 + return s and s[0] == "r" and isvalid_rev_re.match(s[1:])
2044 +
2045
2046 # vim: set ts=4 sw=4 tw=79:
2047
2048 diff --git a/pym/gentoolkit/dbapi.py b/pym/gentoolkit/dbapi.py
2049 index be37f32..9e480f8 100644
2050 --- a/pym/gentoolkit/dbapi.py
2051 +++ b/pym/gentoolkit/dbapi.py
2052 @@ -9,14 +9,16 @@
2053 take advantage of them being lazy-loaded.
2054 """
2055
2056 -print("gentoolkit.dbapi is deprecated.\n",
2057 - "Please migrate to using the assigned calls directly")
2058 +print(
2059 + "gentoolkit.dbapi is deprecated.\n",
2060 + "Please migrate to using the assigned calls directly",
2061 +)
2062
2063 import portage
2064
2065 BINDB = portage.db[portage.root]["bintree"].dbapi
2066 PORTDB = portage.db[portage.root]["porttree"].dbapi
2067 VARDB = portage.db[portage.root]["vartree"].dbapi
2068 -#virtuals = portage.db[portage.root]["virtuals"]
2069 +# virtuals = portage.db[portage.root]["virtuals"]
2070
2071 # vim: set ts=8 sw=4 tw=79:
2072
2073 diff --git a/pym/gentoolkit/dependencies.py b/pym/gentoolkit/dependencies.py
2074 index 38676a2..f94b82e 100644
2075 --- a/pym/gentoolkit/dependencies.py
2076 +++ b/pym/gentoolkit/dependencies.py
2077 @@ -4,8 +4,8 @@
2078
2079 """Provides a class for easy calculating dependencies for a given CPV."""
2080
2081 -__docformat__ = 'epytext'
2082 -__all__ = ('Dependencies',)
2083 +__docformat__ = "epytext"
2084 +__all__ = ("Dependencies",)
2085
2086 # =======
2087 # Imports
2088 @@ -23,302 +23,314 @@ from gentoolkit.query import Query
2089 # Classes
2090 # =======
2091
2092 +
2093 class Dependencies(Query):
2094 - """Access a package's dependencies and reverse dependencies.
2095 -
2096 - Example usage:
2097 - >>> from gentoolkit.dependencies import Dependencies
2098 - >>> portage = Dependencies('sys-apps/portage-9999')
2099 - >>> portage
2100 - <Dependencies 'sys-apps/portage-9999'>
2101 - >>> # All methods return gentoolkit.atom.Atom instances
2102 - ... portage.get_depend()
2103 - ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
2104 - [<Atom 'python3? =dev-lang/python-3*'>,
2105 - <Atom '!python3? >=dev-lang/python-2.7'>, ...]
2106 -
2107 - """
2108 - def __init__(self, query, parser=None):
2109 - Query.__init__(self, query)
2110 - self.use = []
2111 - self.depatom = str()
2112 -
2113 - # Allow a custom parser function:
2114 - self.parser = parser if parser else self._parser
2115 -
2116 - def __eq__(self, other):
2117 - if self.atom != other.atom:
2118 - return False
2119 - else:
2120 - return True
2121 -
2122 - def __ne__(self, other):
2123 - return not self == other
2124 -
2125 - def __hash__(self):
2126 - return hash((self.atom, self.depatom, tuple(self.use)))
2127 -
2128 - def __repr__(self):
2129 - return "<%s %r>" % (self.__class__.__name__, self.atom)
2130 -
2131 - def environment(self, envvars):
2132 - """Returns predefined env vars DEPEND, SRC_URI, etc."""
2133 -
2134 - # Try to use the Portage tree first, since emerge only uses the tree
2135 - # when calculating dependencies
2136 - try:
2137 - result = portage.db[portage.root]["porttree"].dbapi.aux_get(self.cpv, envvars)
2138 - except KeyError:
2139 - try:
2140 - result = portage.db[portage.root]["vartree"].dbapi.aux_get(self.cpv, envvars)
2141 - except KeyError:
2142 - return []
2143 - return result
2144 -
2145 - def _get_depend(self, env_vars, raw=False):
2146 - raw_depend = ' '.join(self.environment(env_vars))
2147 - if raw:
2148 - return raw_depend
2149 - try:
2150 - return self.parser(raw_depend)
2151 - except portage.exception.InvalidPackageName as err:
2152 - raise errors.GentoolkitInvalidCPV(err)
2153 -
2154 - def get_depend(self, **kwargs):
2155 - """Get the contents of DEPEND and parse it with self.parser."""
2156 - return self._get_depend(('DEPEND', ), **kwargs)
2157 -
2158 - def get_pdepend(self, **kwargs):
2159 - """Get the contents of PDEPEND and parse it with self.parser."""
2160 - return self._get_depend(('PDEPEND', ), **kwargs)
2161 -
2162 - def get_rdepend(self, **kwargs):
2163 - """Get the contents of RDEPEND and parse it with self.parser."""
2164 - return self._get_depend(('RDEPEND', ), **kwargs)
2165 -
2166 - def get_all_depends(self, **kwargs):
2167 - """Get the contents of ?DEPEND and parse it with self.parser."""
2168 - env_vars = ('DEPEND', 'PDEPEND', 'RDEPEND', 'BDEPEND')
2169 - return self._get_depend(env_vars, **kwargs)
2170 -
2171 - def graph_depends(
2172 - self,
2173 - max_depth=1,
2174 - printer_fn=None,
2175 - # The rest of these are only used internally:
2176 - depth=1,
2177 - seen=None,
2178 - depcache=None,
2179 - result=None
2180 - ):
2181 - """Graph direct dependencies for self.
2182 -
2183 - Optionally gather indirect dependencies.
2184 -
2185 - @type max_depth: int
2186 - @keyword max_depth: Maximum depth to recurse if.
2187 - <1 means no maximum depth
2188 - >0 means recurse only this depth;
2189 - @type printer_fn: callable
2190 - @keyword printer_fn: If None, no effect. If set, it will be applied to
2191 - each result.
2192 - @rtype: list
2193 - @return: [(depth, pkg), ...]
2194 - """
2195 - if seen is None:
2196 - seen = set()
2197 - if depcache is None:
2198 - depcache = dict()
2199 - if result is None:
2200 - result = list()
2201 -
2202 - pkgdep = None
2203 - deps = self.get_all_depends()
2204 - for dep in deps:
2205 - if dep.atom in depcache:
2206 - continue
2207 - try:
2208 - pkgdep = depcache[dep.atom]
2209 - except KeyError:
2210 - pkgdep = Query(dep.atom).find_best()
2211 - depcache[dep.atom] = pkgdep
2212 - if not pkgdep:
2213 - continue
2214 - elif pkgdep.cpv in seen:
2215 - continue
2216 - if depth <= max_depth or max_depth == 0:
2217 - if printer_fn is not None:
2218 - printer_fn(depth, pkgdep, dep)
2219 - result.append((depth,pkgdep))
2220 -
2221 - seen.add(pkgdep.cpv)
2222 - if depth < max_depth or max_depth == 0:
2223 - # result is passed in and added to directly
2224 - # so rdeps is disposable
2225 - rdeps = pkgdep.deps.graph_depends( # noqa
2226 - max_depth=max_depth,
2227 - printer_fn=printer_fn,
2228 - # The rest of these are only used internally:
2229 - depth=depth+1,
2230 - seen=seen,
2231 - depcache=depcache,
2232 - result=result
2233 - )
2234 - return result
2235 -
2236 - def graph_reverse_depends(
2237 - self,
2238 - pkgset=None,
2239 - max_depth=-1,
2240 - only_direct=True,
2241 - printer_fn=None,
2242 - # The rest of these are only used internally:
2243 - depth=0,
2244 - depcache=None,
2245 - seen=None,
2246 - result=None
2247 - ):
2248 - """Graph direct reverse dependencies for self.
2249 -
2250 - Example usage:
2251 - >>> from gentoolkit.dependencies import Dependencies
2252 - >>> ffmpeg = Dependencies('media-video/ffmpeg-9999')
2253 - >>> # I only care about installed packages that depend on me:
2254 - ... from gentoolkit.helpers import get_installed_cpvs
2255 - >>> # I want to pass in a sorted list. We can pass strings or
2256 - ... # Package or Atom types, so I'll use Package to sort:
2257 - ... from gentoolkit.package import Package
2258 - >>> installed = sorted(get_installed_cpvs())
2259 - >>> deptree = ffmpeg.graph_reverse_depends(
2260 - ... only_direct=False, # Include indirect revdeps
2261 - ... pkgset=installed) # from installed pkgset
2262 - >>> len(deptree)
2263 - 24
2264 -
2265 - @type pkgset: iterable
2266 - @keyword pkgset: sorted pkg cpv strings or anything sublassing
2267 - L{gentoolkit.cpv.CPV} to use for calculate our revdep graph.
2268 - @type max_depth: int
2269 - @keyword max_depth: Maximum depth to recurse if only_direct=False.
2270 - -1 means no maximum depth;
2271 - 0 is the same as only_direct=True;
2272 - >0 means recurse only this many times;
2273 - @type only_direct: bool
2274 - @keyword only_direct: to recurse or not to recurse
2275 - @type printer_fn: callable
2276 - @keyword printer_fn: If None, no effect. If set, it will be applied to
2277 - each L{gentoolkit.atom.Atom} object as it is added to the results.
2278 - @rtype: list
2279 - @return: L{gentoolkit.dependencies.Dependencies} objects
2280 - """
2281 - if not pkgset:
2282 - err = ("%s kwarg 'pkgset' must be set. "
2283 - "Can be list of cpv strings or any 'intersectable' object.")
2284 - raise errors.GentoolkitFatalError(err % (self.__class__.__name__,))
2285 -
2286 - if depcache is None:
2287 - depcache = dict()
2288 - if seen is None:
2289 - seen = set()
2290 - if result is None:
2291 - result = list()
2292 -
2293 - if depth == 0:
2294 - pkgset = tuple(Dependencies(x) for x in pkgset)
2295 -
2296 - pkgdep = None
2297 - for pkgdep in pkgset:
2298 - raw_depends = pkgdep.get_all_depends(raw=True)
2299 - if self.cp not in raw_depends:
2300 - # fast path for obviously non-matching packages. This saves
2301 - # us the work of instantiating a whole Atom() for *every*
2302 - # dependency of *every* package in pkgset.
2303 - continue
2304 - try:
2305 - all_depends = depcache[pkgdep]
2306 - except KeyError:
2307 - all_depends = uniqify(pkgdep.get_all_depends())
2308 - depcache[pkgdep] = all_depends
2309 -
2310 - dep_is_displayed = False
2311 - for dep in all_depends:
2312 - # TODO: Add ability to determine if dep is enabled by USE flag.
2313 - # Check portage.dep.use_reduce
2314 - if dep.intersects(self):
2315 - pkgdep.depth = depth
2316 - pkgdep.matching_dep = dep
2317 - if printer_fn is not None:
2318 - printer_fn(pkgdep, dep_is_displayed=dep_is_displayed)
2319 - result.append(pkgdep)
2320 - dep_is_displayed = True
2321 -
2322 - # if --indirect specified, call ourselves again with the dep
2323 - # Do not call if we have already called ourselves.
2324 - if (
2325 - dep_is_displayed and not only_direct and
2326 - pkgdep.cpv not in seen and
2327 - (depth < max_depth or max_depth == -1)
2328 - ):
2329 -
2330 - seen.add(pkgdep.cpv)
2331 - result.append(
2332 - pkgdep.graph_reverse_depends(
2333 - pkgset=pkgset,
2334 - max_depth=max_depth,
2335 - only_direct=only_direct,
2336 - printer_fn=printer_fn,
2337 - depth=depth+1,
2338 - depcache=depcache,
2339 - seen=seen,
2340 - result=result
2341 - )
2342 - )
2343 -
2344 - if depth == 0:
2345 - return result
2346 - return pkgdep
2347 -
2348 - def _parser(self, deps, use_conditional=None, depth=0):
2349 - """?DEPEND file parser.
2350 -
2351 - @rtype: list
2352 - @return: L{gentoolkit.atom.Atom} objects
2353 - """
2354 - result = []
2355 -
2356 - if depth == 0:
2357 - deps = paren_reduce(deps)
2358 - for tok in deps:
2359 - if tok == '||':
2360 - continue
2361 - if tok[-1] == '?':
2362 - use_conditional = tok[:-1]
2363 - continue
2364 - if isinstance(tok, list):
2365 - sub_r = self._parser(tok, use_conditional, depth=depth+1)
2366 - result.extend(sub_r)
2367 - use_conditional = None
2368 - continue
2369 - # FIXME: This is a quick fix for bug #299260.
2370 - # A better fix is to not discard blockers in the parser,
2371 - # but to check for atom.blocker in whatever equery/depends
2372 - # (in this case) and ignore them there.
2373 - # TODO: Test to see how much a performance impact ignoring
2374 - # blockers here rather than checking for atom.blocker has.
2375 - if tok[0] == '!':
2376 - # We're not interested in blockers
2377 - continue
2378 - # skip it if it's empty
2379 - if tok and tok != '':
2380 - atom = Atom(tok)
2381 - if use_conditional is not None:
2382 - atom.use_conditional = use_conditional
2383 - result.append(atom)
2384 - else:
2385 - message = "dependencies.py: _parser() found an empty " +\
2386 - "dep string token for: %s, deps= %s"
2387 - raise errors.GentoolkitInvalidAtom(message %(self.cpv, deps))
2388 -
2389 - return result
2390 + """Access a package's dependencies and reverse dependencies.
2391 +
2392 + Example usage:
2393 + >>> from gentoolkit.dependencies import Dependencies
2394 + >>> portage = Dependencies('sys-apps/portage-9999')
2395 + >>> portage
2396 + <Dependencies 'sys-apps/portage-9999'>
2397 + >>> # All methods return gentoolkit.atom.Atom instances
2398 + ... portage.get_depend()
2399 + ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
2400 + [<Atom 'python3? =dev-lang/python-3*'>,
2401 + <Atom '!python3? >=dev-lang/python-2.7'>, ...]
2402 +
2403 + """
2404 +
2405 + def __init__(self, query, parser=None):
2406 + Query.__init__(self, query)
2407 + self.use = []
2408 + self.depatom = str()
2409 +
2410 + # Allow a custom parser function:
2411 + self.parser = parser if parser else self._parser
2412 +
2413 + def __eq__(self, other):
2414 + if self.atom != other.atom:
2415 + return False
2416 + else:
2417 + return True
2418 +
2419 + def __ne__(self, other):
2420 + return not self == other
2421 +
2422 + def __hash__(self):
2423 + return hash((self.atom, self.depatom, tuple(self.use)))
2424 +
2425 + def __repr__(self):
2426 + return "<%s %r>" % (self.__class__.__name__, self.atom)
2427 +
2428 + def environment(self, envvars):
2429 + """Returns predefined env vars DEPEND, SRC_URI, etc."""
2430 +
2431 + # Try to use the Portage tree first, since emerge only uses the tree
2432 + # when calculating dependencies
2433 + try:
2434 + result = portage.db[portage.root]["porttree"].dbapi.aux_get(
2435 + self.cpv, envvars
2436 + )
2437 + except KeyError:
2438 + try:
2439 + result = portage.db[portage.root]["vartree"].dbapi.aux_get(
2440 + self.cpv, envvars
2441 + )
2442 + except KeyError:
2443 + return []
2444 + return result
2445 +
2446 + def _get_depend(self, env_vars, raw=False):
2447 + raw_depend = " ".join(self.environment(env_vars))
2448 + if raw:
2449 + return raw_depend
2450 + try:
2451 + return self.parser(raw_depend)
2452 + except portage.exception.InvalidPackageName as err:
2453 + raise errors.GentoolkitInvalidCPV(err)
2454 +
2455 + def get_depend(self, **kwargs):
2456 + """Get the contents of DEPEND and parse it with self.parser."""
2457 + return self._get_depend(("DEPEND",), **kwargs)
2458 +
2459 + def get_pdepend(self, **kwargs):
2460 + """Get the contents of PDEPEND and parse it with self.parser."""
2461 + return self._get_depend(("PDEPEND",), **kwargs)
2462 +
2463 + def get_rdepend(self, **kwargs):
2464 + """Get the contents of RDEPEND and parse it with self.parser."""
2465 + return self._get_depend(("RDEPEND",), **kwargs)
2466 +
2467 + def get_all_depends(self, **kwargs):
2468 + """Get the contents of ?DEPEND and parse it with self.parser."""
2469 + env_vars = ("DEPEND", "PDEPEND", "RDEPEND", "BDEPEND")
2470 + return self._get_depend(env_vars, **kwargs)
2471 +
2472 + def graph_depends(
2473 + self,
2474 + max_depth=1,
2475 + printer_fn=None,
2476 + # The rest of these are only used internally:
2477 + depth=1,
2478 + seen=None,
2479 + depcache=None,
2480 + result=None,
2481 + ):
2482 + """Graph direct dependencies for self.
2483 +
2484 + Optionally gather indirect dependencies.
2485 +
2486 + @type max_depth: int
2487 + @keyword max_depth: Maximum depth to recurse if.
2488 + <1 means no maximum depth
2489 + >0 means recurse only this depth;
2490 + @type printer_fn: callable
2491 + @keyword printer_fn: If None, no effect. If set, it will be applied to
2492 + each result.
2493 + @rtype: list
2494 + @return: [(depth, pkg), ...]
2495 + """
2496 + if seen is None:
2497 + seen = set()
2498 + if depcache is None:
2499 + depcache = dict()
2500 + if result is None:
2501 + result = list()
2502 +
2503 + pkgdep = None
2504 + deps = self.get_all_depends()
2505 + for dep in deps:
2506 + if dep.atom in depcache:
2507 + continue
2508 + try:
2509 + pkgdep = depcache[dep.atom]
2510 + except KeyError:
2511 + pkgdep = Query(dep.atom).find_best()
2512 + depcache[dep.atom] = pkgdep
2513 + if not pkgdep:
2514 + continue
2515 + elif pkgdep.cpv in seen:
2516 + continue
2517 + if depth <= max_depth or max_depth == 0:
2518 + if printer_fn is not None:
2519 + printer_fn(depth, pkgdep, dep)
2520 + result.append((depth, pkgdep))
2521 +
2522 + seen.add(pkgdep.cpv)
2523 + if depth < max_depth or max_depth == 0:
2524 + # result is passed in and added to directly
2525 + # so rdeps is disposable
2526 + rdeps = pkgdep.deps.graph_depends( # noqa
2527 + max_depth=max_depth,
2528 + printer_fn=printer_fn,
2529 + # The rest of these are only used internally:
2530 + depth=depth + 1,
2531 + seen=seen,
2532 + depcache=depcache,
2533 + result=result,
2534 + )
2535 + return result
2536 +
2537 + def graph_reverse_depends(
2538 + self,
2539 + pkgset=None,
2540 + max_depth=-1,
2541 + only_direct=True,
2542 + printer_fn=None,
2543 + # The rest of these are only used internally:
2544 + depth=0,
2545 + depcache=None,
2546 + seen=None,
2547 + result=None,
2548 + ):
2549 + """Graph direct reverse dependencies for self.
2550 +
2551 + Example usage:
2552 + >>> from gentoolkit.dependencies import Dependencies
2553 + >>> ffmpeg = Dependencies('media-video/ffmpeg-9999')
2554 + >>> # I only care about installed packages that depend on me: