1 # Copyright 1999-2013 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
4 from __future__ import print_function
10 portage.proxy.lazyimport.lazyimport(globals(),
12 'portage.util:writemsg_level',
14 '_emerge.actions:load_emerge_config,run_action,' + \
15 'validate_ebuild_environment',
16 '_emerge.help:help@emerge_help',
18 from portage import os
20 if sys.hexversion >= 0x3000000:
25 "--ask-enter-invalid",
28 "--changelog", "--columns",
32 "--fetchonly", "--fetch-all-uri",
33 "--ignore-default-opts",
36 "--nodeps", "--noreplace",
37 "--nospinner", "--oneshot",
38 "--onlydeps", "--pretend",
39 "--quiet-repo-display",
40 "--quiet-unmerge-warn",
45 "--unordered-display",
47 "--verbose-main-repo-display",
57 "f":"--fetchonly", "F":"--fetch-all-uri",
60 "n":"--noreplace", "N":"--newuse",
61 "o":"--onlydeps", "O":"--nodeps",
62 "p":"--pretend", "P":"--prune",
64 "s":"--search", "S":"--searchdesc",
72 Larry loves Gentoo (%s)
74 _______________________
75 < Have you mooed today? >
76 -----------------------
85 def multiple_actions(action1, action2):
86 sys.stderr.write("\n!!! Multiple actions requested... Please choose one only.\n")
87 sys.stderr.write("!!! '%s' or '%s'\n\n" % (action1, action2))
90 def insert_optional_args(args):
92 Parse optional arguments and insert a value if one has
93 not been provided. This is done before feeding the args
94 to the optparse parser since that parser does not support
95 this feature natively.
98 class valid_integers(object):
99 def __contains__(self, s):
102 except (ValueError, OverflowError):
105 valid_integers = valid_integers()
107 class valid_floats(object):
108 def __contains__(self, s):
111 except (ValueError, OverflowError):
114 valid_floats = valid_floats()
122 '--autounmask' : y_or_n,
123 '--autounmask-keep-masks': y_or_n,
124 '--autounmask-unrestricted-atoms' : y_or_n,
125 '--autounmask-write' : y_or_n,
126 '--buildpkg' : y_or_n,
127 '--complete-graph' : y_or_n,
128 '--deep' : valid_integers,
129 '--depclean-lib-check' : y_or_n,
130 '--deselect' : y_or_n,
131 '--binpkg-respect-use' : y_or_n,
132 '--fail-clean' : y_or_n,
133 '--getbinpkg' : y_or_n,
134 '--getbinpkgonly' : y_or_n,
135 '--jobs' : valid_integers,
136 '--keep-going' : y_or_n,
137 '--load-average' : valid_floats,
138 '--package-moves' : y_or_n,
140 '--quiet-build' : y_or_n,
141 '--quiet-fail' : y_or_n,
142 '--rebuild-if-new-slot': y_or_n,
143 '--rebuild-if-new-rev' : y_or_n,
144 '--rebuild-if-new-ver' : y_or_n,
145 '--rebuild-if-unbuilt' : y_or_n,
146 '--rebuilt-binaries' : y_or_n,
147 '--root-deps' : ('rdeps',),
149 '--selective' : y_or_n,
150 "--use-ebuild-visibility": y_or_n,
152 '--usepkgonly' : y_or_n,
153 '--verbose' : y_or_n,
157 'D' : valid_integers,
158 'j' : valid_integers,
161 # Don't make things like "-kn" expand to "-k n"
162 # since existence of -n makes it too ambiguous.
178 arg = arg_stack.pop()
180 default_arg_choices = default_arg_opts.get(arg)
181 if default_arg_choices is not None:
183 if arg_stack and arg_stack[-1] in default_arg_choices:
184 new_args.append(arg_stack.pop())
186 # insert default argument
187 new_args.append('True')
190 if arg[:1] != "-" or arg[:2] == "--":
195 for k, arg_choices in short_arg_opts.items():
201 for k, arg_choices in short_arg_opts_n.items():
212 if arg_stack and arg_stack[-1] in arg_choices:
213 new_args.append(arg_stack.pop())
215 # insert default argument
216 new_args.append('True')
219 # Insert an empty placeholder in order to
220 # satisfy the requirements of optparse.
222 new_args.append("-" + match)
226 if arg[1:2] == match:
227 if match not in short_arg_opts_n and arg[2:] in arg_choices:
233 saved_opts = arg[1:].replace(match, "")
236 if opt_arg is None and arg_stack and \
237 arg_stack[-1] in arg_choices:
238 opt_arg = arg_stack.pop()
241 new_args.append("True")
243 new_args.append(opt_arg)
245 if saved_opts is not None:
246 # Recycle these on arg_stack since they
247 # might contain another match.
248 arg_stack.append("-" + saved_opts)
252 def _find_bad_atoms(atoms, less_strict=False):
254 Declares all atoms as invalid that have an operator,
255 a use dependency, a blocker or a repo spec.
256 It accepts atoms with wildcards.
257 In less_strict mode it accepts operators and repo specs.
260 for x in ' '.join(atoms).split():
263 atom = portage.dep.Atom(x, allow_wildcard=True, allow_repo=less_strict)
264 except portage.exception.InvalidAtom:
266 atom = portage.dep.Atom("*/"+x, allow_wildcard=True, allow_repo=less_strict)
267 except portage.exception.InvalidAtom:
270 if bad_atom or (atom.operator and not less_strict) or atom.blocker or atom.use:
275 def parse_opts(tmpcmdline, silent=False):
280 actions = frozenset([
281 "clean", "check-news", "config", "depclean", "help",
282 "info", "list-sets", "metadata", "moo",
283 "prune", "regen", "search",
284 "sync", "unmerge", "version",
287 longopt_aliases = {"--cols":"--columns", "--skip-first":"--skipfirst"}
289 true_y_or_n = ("True", "y", "n")
290 true_y = ("True", "y")
295 "help" : "prompt before performing any actions",
297 "choices" : true_y_or_n
301 "help" : "automatically unmask packages",
303 "choices" : true_y_or_n
306 "--autounmask-unrestricted-atoms": {
307 "help" : "write autounmask changes with >= atoms if possible",
309 "choices" : true_y_or_n
312 "--autounmask-keep-masks": {
313 "help" : "don't add package.unmask entries",
315 "choices" : true_y_or_n
318 "--autounmask-write": {
319 "help" : "write changes made by --autounmask to disk",
321 "choices" : true_y_or_n
324 "--accept-properties": {
325 "help":"temporarily override ACCEPT_PROPERTIES",
329 "--accept-restrict": {
330 "help":"temporarily override ACCEPT_RESTRICT",
336 "help" : "Specifies how many times to backtrack if dependency " + \
337 "calculation fails ",
344 "help" : "build binary packages",
346 "choices" : true_y_or_n
349 "--buildpkg-exclude": {
350 "help" :"A space separated list of package atoms for which " + \
351 "no binary packages should be built. This option overrides all " + \
352 "possible ways to enable building of binary packages.",
358 "help":"specify the location for portage configuration files",
362 "help":"enable or disable color output",
367 "--complete-graph": {
368 "help" : "completely account for all known dependencies",
370 "choices" : true_y_or_n
373 "--complete-graph-if-new-use": {
374 "help" : "trigger --complete-graph behavior if USE or IUSE will change for an installed package",
379 "--complete-graph-if-new-ver": {
380 "help" : "trigger --complete-graph behavior if an installed package version will change (upgrade or downgrade)",
389 "help" : "Specifies how deep to recurse into dependencies " + \
390 "of packages given as arguments. If no argument is given, " + \
391 "depth is unlimited. Default behavior is to skip " + \
392 "dependencies of installed packages.",
397 "--depclean-lib-check": {
398 "help" : "check for consumers of libraries before removing them",
400 "choices" : true_y_or_n
404 "help" : "remove atoms/sets from the world file",
406 "choices" : true_y_or_n
410 "help": "substitute the dependencies of installed packages with the dependencies of unbuilt ebuilds",
416 "help" :"A space separated list of package names or slot atoms. " + \
417 "Emerge won't install any ebuild or binary package that " + \
418 "matches any of the given package atoms.",
424 "help" : "clean temp files after build failure",
426 "choices" : true_y_or_n
429 "--ignore-built-slot-operator-deps": {
430 "help": "Ignore the slot/sub-slot := operator parts of dependencies that have "
431 "been recorded when packages where built. This option is intended "
432 "only for debugging purposes, and it only affects built packages "
433 "that specify slot/sub-slot := operator dependencies using the "
434 "experimental \"4-slot-abi\" EAPI.",
443 "help" : "Specifies the number of packages to build " + \
450 "help" : "continue as much as possible after an error",
452 "choices" : true_y_or_n
457 "help" :"Specifies that no new builds should be started " + \
458 "if there are other builds running and the load average " + \
459 "is at least LOAD (a floating-point number).",
464 "--misspell-suggestions": {
465 "help" : "enable package name misspell suggestions",
467 "choices" : ("y", "n")
471 "help":"include unnecessary build time dependencies",
476 "help":"specify conditions to trigger package reinstallation",
478 "choices":["changed-use"]
481 "--reinstall-atoms": {
482 "help" :"A space separated list of package names or slot atoms. " + \
483 "Emerge will treat matching packages as if they are not " + \
484 "installed, and reinstall them if necessary. Implies --deep.",
489 "--binpkg-respect-use": {
490 "help" : "discard binary packages if their use flags \
491 don't match the current configuration",
493 "choices" : true_y_or_n
498 "help" : "fetch binary packages",
500 "choices" : true_y_or_n
505 "help" : "fetch binary packages only",
507 "choices" : true_y_or_n
510 "--usepkg-exclude": {
511 "help" :"A space separated list of package names or slot atoms. " + \
512 "Emerge will ignore matching binary packages. ",
517 "--rebuild-exclude": {
518 "help" :"A space separated list of package names or slot atoms. " + \
519 "Emerge will not rebuild these packages due to the " + \
525 "--rebuild-ignore": {
526 "help" :"A space separated list of package names or slot atoms. " + \
527 "Emerge will not rebuild packages that depend on matching " + \
528 "packages due to the --rebuild flag. ",
534 "help" : "perform package moves when necessary",
536 "choices" : true_y_or_n
541 "help" : "reduced or condensed output",
543 "choices" : true_y_or_n
547 "help" : "redirect build output to logs",
549 "choices" : true_y_or_n,
553 "help" : "suppresses display of the build log on stdout",
555 "choices" : true_y_or_n,
558 "--rebuild-if-new-slot": {
559 "help" : ("Automatically rebuild or reinstall packages when slot/sub-slot := "
560 "operator dependencies can be satisfied by a newer slot, so that "
561 "older packages slots will become eligible for removal by the "
562 "--depclean action as soon as possible."),
564 "choices" : true_y_or_n
567 "--rebuild-if-new-rev": {
568 "help" : "Rebuild packages when dependencies that are " + \
569 "used at both build-time and run-time are built, " + \
570 "if the dependency is not already installed with the " + \
571 "same version and revision.",
573 "choices" : true_y_or_n
576 "--rebuild-if-new-ver": {
577 "help" : "Rebuild packages when dependencies that are " + \
578 "used at both build-time and run-time are built, " + \
579 "if the dependency is not already installed with the " + \
580 "same version. Revision numbers are ignored.",
582 "choices" : true_y_or_n
585 "--rebuild-if-unbuilt": {
586 "help" : "Rebuild packages when dependencies that are " + \
587 "used at both build-time and run-time are built.",
589 "choices" : true_y_or_n
592 "--rebuilt-binaries": {
593 "help" : "replace installed packages with binary " + \
594 "packages that have been rebuilt",
596 "choices" : true_y_or_n
599 "--rebuilt-binaries-timestamp": {
600 "help" : "use only binaries that are newer than this " + \
601 "timestamp for --rebuilt-binaries",
606 "help" : "specify the target root filesystem for merging packages",
611 "help" : "modify interpretation of depedencies",
613 "choices" :("True", "rdeps")
618 "help" : "add specified packages to the world set " + \
619 "(inverse of --oneshot)",
621 "choices" : true_y_or_n
625 "help" : "identical to --noreplace",
627 "choices" : true_y_or_n
630 "--use-ebuild-visibility": {
631 "help" : "use unbuilt ebuild metadata for visibility checks on built packages",
633 "choices" : true_y_or_n
636 "--useoldpkg-atoms": {
637 "help" :"A space separated list of package names or slot atoms. " + \
638 "Emerge will prefer matching binary packages over newer unbuilt packages. ",
645 "help" : "use binary packages",
647 "choices" : true_y_or_n
652 "help" : "use only binary packages",
654 "choices" : true_y_or_n
659 "help" : "verbose output",
661 "choices" : true_y_or_n
665 from optparse import OptionParser
666 parser = OptionParser()
667 if parser.has_option("--help"):
668 parser.remove_option("--help")
670 for action_opt in actions:
671 parser.add_option("--" + action_opt, action="store_true",
672 dest=action_opt.replace("-", "_"), default=False)
673 for myopt in options:
674 parser.add_option(myopt, action="store_true",
675 dest=myopt.lstrip("--").replace("-", "_"), default=False)
676 for shortopt, longopt in shortmapping.items():
677 parser.add_option("-" + shortopt, action="store_true",
678 dest=longopt.lstrip("--").replace("-", "_"), default=False)
679 for myalias, myopt in longopt_aliases.items():
680 parser.add_option(myalias, action="store_true",
681 dest=myopt.lstrip("--").replace("-", "_"), default=False)
683 for myopt, kwargs in argument_options.items():
684 shortopt = kwargs.pop("shortopt", None)
686 if shortopt is not None:
687 args.append(shortopt)
688 parser.add_option(dest=myopt.lstrip("--").replace("-", "_"),
691 tmpcmdline = insert_optional_args(tmpcmdline)
693 myoptions, myargs = parser.parse_args(args=tmpcmdline)
695 if myoptions.ask in true_y:
700 if myoptions.autounmask in true_y:
701 myoptions.autounmask = True
703 if myoptions.autounmask_unrestricted_atoms in true_y:
704 myoptions.autounmask_unrestricted_atoms = True
706 if myoptions.autounmask_keep_masks in true_y:
707 myoptions.autounmask_keep_masks = True
709 if myoptions.autounmask_write in true_y:
710 myoptions.autounmask_write = True
712 if myoptions.buildpkg in true_y:
713 myoptions.buildpkg = True
715 if myoptions.buildpkg_exclude:
716 bad_atoms = _find_bad_atoms(myoptions.buildpkg_exclude, less_strict=True)
717 if bad_atoms and not silent:
718 parser.error("Invalid Atom(s) in --buildpkg-exclude parameter: '%s'\n" % \
719 (",".join(bad_atoms),))
721 if myoptions.changed_use is not False:
722 myoptions.reinstall = "changed-use"
723 myoptions.changed_use = False
725 if myoptions.deselect in true_y:
726 myoptions.deselect = True
728 if myoptions.binpkg_respect_use is not None:
729 if myoptions.binpkg_respect_use in true_y:
730 myoptions.binpkg_respect_use = 'y'
732 myoptions.binpkg_respect_use = 'n'
734 if myoptions.complete_graph in true_y:
735 myoptions.complete_graph = True
737 myoptions.complete_graph = None
739 if myoptions.depclean_lib_check in true_y:
740 myoptions.depclean_lib_check = True
742 if myoptions.exclude:
743 bad_atoms = _find_bad_atoms(myoptions.exclude)
744 if bad_atoms and not silent:
745 parser.error("Invalid Atom(s) in --exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
746 (",".join(bad_atoms),))
748 if myoptions.reinstall_atoms:
749 bad_atoms = _find_bad_atoms(myoptions.reinstall_atoms)
750 if bad_atoms and not silent:
751 parser.error("Invalid Atom(s) in --reinstall-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
752 (",".join(bad_atoms),))
754 if myoptions.rebuild_exclude:
755 bad_atoms = _find_bad_atoms(myoptions.rebuild_exclude)
756 if bad_atoms and not silent:
757 parser.error("Invalid Atom(s) in --rebuild-exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
758 (",".join(bad_atoms),))
760 if myoptions.rebuild_ignore:
761 bad_atoms = _find_bad_atoms(myoptions.rebuild_ignore)
762 if bad_atoms and not silent:
763 parser.error("Invalid Atom(s) in --rebuild-ignore parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
764 (",".join(bad_atoms),))
766 if myoptions.usepkg_exclude:
767 bad_atoms = _find_bad_atoms(myoptions.usepkg_exclude)
768 if bad_atoms and not silent:
769 parser.error("Invalid Atom(s) in --usepkg-exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
770 (",".join(bad_atoms),))
772 if myoptions.useoldpkg_atoms:
773 bad_atoms = _find_bad_atoms(myoptions.useoldpkg_atoms)
774 if bad_atoms and not silent:
775 parser.error("Invalid Atom(s) in --useoldpkg-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \
776 (",".join(bad_atoms),))
778 if myoptions.fail_clean in true_y:
779 myoptions.fail_clean = True
781 if myoptions.getbinpkg in true_y:
782 myoptions.getbinpkg = True
784 myoptions.getbinpkg = None
786 if myoptions.getbinpkgonly in true_y:
787 myoptions.getbinpkgonly = True
789 myoptions.getbinpkgonly = None
791 if myoptions.keep_going in true_y:
792 myoptions.keep_going = True
794 myoptions.keep_going = None
796 if myoptions.package_moves in true_y:
797 myoptions.package_moves = True
799 if myoptions.quiet in true_y:
800 myoptions.quiet = True
802 myoptions.quiet = None
804 if myoptions.quiet_build in true_y:
805 myoptions.quiet_build = 'y'
807 if myoptions.quiet_fail in true_y:
808 myoptions.quiet_fail = 'y'
810 if myoptions.rebuild_if_new_slot in true_y:
811 myoptions.rebuild_if_new_slot = 'y'
813 if myoptions.rebuild_if_new_ver in true_y:
814 myoptions.rebuild_if_new_ver = True
816 myoptions.rebuild_if_new_ver = None
818 if myoptions.rebuild_if_new_rev in true_y:
819 myoptions.rebuild_if_new_rev = True
820 myoptions.rebuild_if_new_ver = None
822 myoptions.rebuild_if_new_rev = None
824 if myoptions.rebuild_if_unbuilt in true_y:
825 myoptions.rebuild_if_unbuilt = True
826 myoptions.rebuild_if_new_rev = None
827 myoptions.rebuild_if_new_ver = None
829 myoptions.rebuild_if_unbuilt = None
831 if myoptions.rebuilt_binaries in true_y:
832 myoptions.rebuilt_binaries = True
834 if myoptions.root_deps in true_y:
835 myoptions.root_deps = True
837 if myoptions.select in true_y:
838 myoptions.select = True
839 myoptions.oneshot = False
840 elif myoptions.select == "n":
841 myoptions.oneshot = True
843 if myoptions.selective in true_y:
844 myoptions.selective = True
846 if myoptions.backtrack is not None:
849 backtrack = int(myoptions.backtrack)
850 except (OverflowError, ValueError):
856 parser.error("Invalid --backtrack parameter: '%s'\n" % \
857 (myoptions.backtrack,))
859 myoptions.backtrack = backtrack
861 if myoptions.deep is not None:
863 if myoptions.deep == "True":
867 deep = int(myoptions.deep)
868 except (OverflowError, ValueError):
871 if deep is not True and deep < 0:
874 parser.error("Invalid --deep parameter: '%s'\n" % \
877 myoptions.deep = deep
881 if myoptions.jobs == "True":
885 jobs = int(myoptions.jobs)
889 if jobs is not True and \
893 parser.error("Invalid --jobs parameter: '%s'\n" % \
896 myoptions.jobs = jobs
898 if myoptions.load_average == "True":
899 myoptions.load_average = None
901 if myoptions.load_average:
903 load_average = float(myoptions.load_average)
907 if load_average <= 0.0:
910 parser.error("Invalid --load-average parameter: '%s'\n" % \
911 (myoptions.load_average,))
913 myoptions.load_average = load_average
915 if myoptions.rebuilt_binaries_timestamp:
917 rebuilt_binaries_timestamp = int(myoptions.rebuilt_binaries_timestamp)
919 rebuilt_binaries_timestamp = -1
921 if rebuilt_binaries_timestamp < 0:
922 rebuilt_binaries_timestamp = 0
924 parser.error("Invalid --rebuilt-binaries-timestamp parameter: '%s'\n" % \
925 (myoptions.rebuilt_binaries_timestamp,))
927 myoptions.rebuilt_binaries_timestamp = rebuilt_binaries_timestamp
929 if myoptions.use_ebuild_visibility in true_y:
930 myoptions.use_ebuild_visibility = True
935 if myoptions.usepkg in true_y:
936 myoptions.usepkg = True
938 myoptions.usepkg = None
940 if myoptions.usepkgonly in true_y:
941 myoptions.usepkgonly = True
943 myoptions.usepkgonly = None
945 if myoptions.verbose in true_y:
946 myoptions.verbose = True
948 myoptions.verbose = None
950 for myopt in options:
951 v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"))
955 for myopt in argument_options:
956 v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"), None)
960 if myoptions.searchdesc:
961 myoptions.search = True
963 for action_opt in actions:
964 v = getattr(myoptions, action_opt.replace("-", "_"))
967 multiple_actions(myaction, action_opt)
969 myaction = action_opt
971 if myaction is None and myoptions.deselect is True:
972 myaction = 'deselect'
974 if myargs and isinstance(myargs[0], bytes):
975 for i in range(len(myargs)):
976 myargs[i] = portage._unicode_decode(myargs[i])
980 return myaction, myopts, myfiles
982 def profile_check(trees, myaction):
983 if myaction in ("help", "info", "search", "sync", "version"):
985 for root_trees in trees.values():
986 if root_trees["root_config"].settings.profiles:
988 # generate some profile related warning messages
989 validate_ebuild_environment(trees)
990 msg = ("Your current profile is invalid. If you have just changed "
991 "your profile configuration, you should revert back to the "
992 "previous configuration. Allowed actions are limited to "
993 "--help, --info, --search, --sync, and --version.")
994 writemsg_level("".join("!!! %s\n" % l for l in textwrap.wrap(msg, 70)),
995 level=logging.ERROR, noiselevel=-1)
999 def emerge_main(args=None):
1001 @param args: command arguments (default: sys.argv[1:])
1007 # Disable color until we're sure that it should be enabled (after
1008 # EMERGE_DEFAULT_OPTS has been parsed).
1009 portage.output.havecolor = 0
1011 # This first pass is just for options that need to be known as early as
1012 # possible, such as --config-root. They will be parsed again later,
1013 # together with EMERGE_DEFAULT_OPTS (which may vary depending on the
1014 # the value of --config-root).
1015 myaction, myopts, myfiles = parse_opts(args, silent=True)
1016 if "--debug" in myopts:
1017 os.environ["PORTAGE_DEBUG"] = "1"
1018 if "--config-root" in myopts:
1019 os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"]
1020 if "--root" in myopts:
1021 os.environ["ROOT"] = myopts["--root"]
1022 if "--accept-properties" in myopts:
1023 os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"]
1024 if "--accept-restrict" in myopts:
1025 os.environ["ACCEPT_RESTRICT"] = myopts["--accept-restrict"]
1027 # optimize --help (no need to load config / EMERGE_DEFAULT_OPTS)
1028 if myaction == "help":
1031 elif myaction == "moo":
1032 print(COWSAY_MOO % platform.system())
1035 # Portage needs to ensure a sane umask for the files it creates.
1037 if myaction == "sync":
1038 portage._sync_disabled_warnings = True
1039 settings, trees, mtimedb = load_emerge_config()
1040 rval = profile_check(trees, myaction)
1041 if rval != os.EX_OK:
1045 if "--ignore-default-opts" not in myopts:
1046 tmpcmdline.extend(portage.util.shlex_split(
1047 settings.get("EMERGE_DEFAULT_OPTS", "")))
1048 tmpcmdline.extend(args)
1049 myaction, myopts, myfiles = parse_opts(tmpcmdline)
1051 return run_action(settings, trees, mtimedb, myaction, myopts, myfiles,
1052 gc_locals=locals().clear)