1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
'''Functions that are used in the generation process.'''
from .errors import CrazyError
from . import completion_validator
from . import cli
from . import config as _config
from . import when
class GenerationContext:
'''Holds global configuration and helpers used during code generation.'''
# pylint: disable=too-few-public-methods
def __init__(self, config, helpers):
self.config = config
self.helpers = helpers
def get_option_context(self, commandline, option):
'''Return OptionGenerationContext based on current context.'''
return OptionGenerationContext(
self.config,
self.helpers,
commandline,
option
)
class OptionGenerationContext(GenerationContext):
'''Extends GenerationContext; holds commandline and option objects.'''
# pylint: disable=too-few-public-methods
def __init__(self, config, helpers, commandline, option):
super().__init__(config, helpers)
self.commandline = commandline
self.option = option
def _apply_config(commandline, config):
'''Applies configuration settings to a command line object.
If a setting in the CommandLine or Option object is set to ExtendedBool.INHERIT,
it will be overridden by the corresponding setting from the config object.
Args:
commandline (CommandLine): The command line object to apply the configuration to.
config (Config): The configuration object containing the settings to apply.
Returns:
None
'''
assert isinstance(commandline, cli.CommandLine), \
"commandline_apply_config: commandline: expected CommandLine, got %r" % commandline
assert isinstance(config, _config.Config), \
"commandline_apply_config: config: expected Config, got %r" % config
if commandline.abbreviate_commands == cli.ExtendedBool.INHERIT:
commandline.abbreviate_commands = config.abbreviate_commands
if commandline.abbreviate_options == cli.ExtendedBool.INHERIT:
commandline.abbreviate_options = config.abbreviate_options
if commandline.inherit_options == cli.ExtendedBool.INHERIT:
commandline.inherit_options = config.inherit_options
for option in commandline.options:
if option.repeatable == cli.ExtendedBool.INHERIT:
option.repeatable = config.repeatable_options
if config.disabled_hidden:
for option in commandline.options:
option.hidden = False
if config.disabled_final:
for option in commandline.options:
option.final = False
if config.disabled_groups:
for option in commandline.options:
option.groups = []
if config.disabled_repeatable:
for option in commandline.options:
option.repeatable = True
if config.disabled_when:
for option in commandline.options:
option.when = None
for positional in commandline.positionals:
positional.when = None
def _add_parsed_when(commandline):
for option in commandline.options:
if option.when:
try:
option.when_parsed = when.parse_when(option.when)
except CrazyError as e:
raise CrazyError('%s: %s: when: %s: %s' % (
commandline.get_command_path(),
option.get_option_strings_key('|'),
option.when,
e)) from e
else:
option.when_parsed = None
for positional in commandline.positionals:
if positional.when:
try:
positional.when_parsed = when.parse_when(positional.when)
except CrazyError as e:
raise CrazyError('%s: %s: %s: when: %s: %s' % (
commandline.get_command_path(),
positional.number,
positional.metavar,
positional.when,
e)) from e
def enhance_commandline(commandline, config):
'''Enhance commandline.
- Make a copy of commandline
- Apply configuration to it
- Add `when_parsed` attribute
'''
commandline = commandline.copy()
commandline.visit_commandlines(lambda c: _apply_config(c, config))
commandline.visit_commandlines(_add_parsed_when)
completion_validator.validate_commandlines(commandline)
return commandline
def visit_commandlines(completion_class, ctxt, commandline):
'''Visit commandlines with a completer class.'''
result = []
def _call_generator(commandline):
result.append(completion_class(ctxt, commandline))
commandline.visit_commandlines(_call_generator)
return result
|