aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py')
-rwxr-xr-xlib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py668
1 files changed, 0 insertions, 668 deletions
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py
deleted file mode 100755
index b7768027..00000000
--- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/python/_shellcomp.py
+++ /dev/null
@@ -1,668 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_shellcomp -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-No public APIs are provided by this module. Internal use only.
-
-This module implements dynamic tab-completion for any command that uses
-twisted.python.usage. Currently, only zsh is supported. Bash support may
-be added in the future.
-
-Maintainer: Eric P. Mangold - twisted AT teratorn DOT org
-
-In order for zsh completion to take place the shell must be able to find an
-appropriate "stub" file ("completion function") that invokes this code and
-displays the results to the user.
-
-The stub used for Twisted commands is in the file C{twisted-completion.zsh},
-which is also included in the official Zsh distribution at
-C{Completion/Unix/Command/_twisted}. Use this file as a basis for completion
-functions for your own commands. You should only need to change the first line
-to something like C{#compdef mycommand}.
-
-The main public documentation exists in the L{twisted.python.usage.Options}
-docstring, the L{twisted.python.usage.Completions} docstring, and the
-Options howto.
-"""
-import itertools, getopt, inspect
-
-from twisted.python import reflect, util, usage
-
-
-
-def shellComplete(config, cmdName, words, shellCompFile):
- """
- Perform shell completion.
-
- A completion function (shell script) is generated for the requested
- shell and written to C{shellCompFile}, typically C{stdout}. The result
- is then eval'd by the shell to produce the desired completions.
-
- @type config: L{twisted.python.usage.Options}
- @param config: The L{twisted.python.usage.Options} instance to generate
- completions for.
-
- @type cmdName: C{str}
- @param cmdName: The name of the command we're generating completions for.
- In the case of zsh, this is used to print an appropriate
- "#compdef $CMD" line at the top of the output. This is
- not necessary for the functionality of the system, but it
- helps in debugging, since the output we produce is properly
- formed and may be saved in a file and used as a stand-alone
- completion function.
-
- @type words: C{list} of C{str}
- @param words: The raw command-line words passed to use by the shell
- stub function. argv[0] has already been stripped off.
-
- @type shellCompFile: C{file}
- @param shellCompFile: The file to write completion data to.
- """
- # shellName is provided for forward-compatibility. It is not used,
- # since we currently only support zsh.
- shellName, position = words[-1].split(":")
- position = int(position)
- # zsh gives the completion position ($CURRENT) as a 1-based index,
- # and argv[0] has already been stripped off, so we subtract 2 to
- # get the real 0-based index.
- position -= 2
- cWord = words[position]
-
- # since the user may hit TAB at any time, we may have been called with an
- # incomplete command-line that would generate getopt errors if parsed
- # verbatim. However, we must do *some* parsing in order to determine if
- # there is a specific subcommand that we need to provide completion for.
- # So, to make the command-line more sane we work backwards from the
- # current completion position and strip off all words until we find one
- # that "looks" like a subcommand. It may in fact be the argument to a
- # normal command-line option, but that won't matter for our purposes.
- while position >= 1:
- if words[position - 1].startswith("-"):
- position -= 1
- else:
- break
- words = words[:position]
-
- subCommands = getattr(config, 'subCommands', None)
- if subCommands:
- # OK, this command supports sub-commands, so lets see if we have been
- # given one.
-
- # If the command-line arguments are not valid then we won't be able to
- # sanely detect the sub-command, so just generate completions as if no
- # sub-command was found.
- args = None
- try:
- opts, args = getopt.getopt(words,
- config.shortOpt, config.longOpt)
- except getopt.error:
- pass
-
- if args:
- # yes, we have a subcommand. Try to find it.
- for (cmd, short, parser, doc) in config.subCommands:
- if args[0] == cmd or args[0] == short:
- subOptions = parser()
- subOptions.parent = config
-
- gen = ZshSubcommandBuilder(subOptions, config, cmdName,
- shellCompFile)
- gen.write()
- return
-
- # sub-command not given, or did not match any knowns sub-command names
- genSubs = True
- if cWord.startswith("-"):
- # optimization: if the current word being completed starts
- # with a hyphen then it can't be a sub-command, so skip
- # the expensive generation of the sub-command list
- genSubs = False
- gen = ZshBuilder(config, cmdName, shellCompFile)
- gen.write(genSubs=genSubs)
- else:
- gen = ZshBuilder(config, cmdName, shellCompFile)
- gen.write()
-
-
-
-class SubcommandAction(usage.Completer):
- def _shellCode(self, optName, shellType):
- if shellType == usage._ZSH:
- return '*::subcmd:->subcmd'
- raise NotImplementedError("Unknown shellType %r" % (shellType,))
-
-
-
-class ZshBuilder(object):
- """
- Constructs zsh code that will complete options for a given usage.Options
- instance, possibly including a list of subcommand names.
-
- Completions for options to subcommands won't be generated because this
- class will never be used if the user is completing options for a specific
- subcommand. (See L{ZshSubcommandBuilder} below)
-
- @type options: L{twisted.python.usage.Options}
- @ivar options: The L{twisted.python.usage.Options} instance defined for this
- command.
-
- @type cmdName: C{str}
- @ivar cmdName: The name of the command we're generating completions for.
-
- @type file: C{file}
- @ivar file: The C{file} to write the completion function to.
- """
- def __init__(self, options, cmdName, file):
- self.options = options
- self.cmdName = cmdName
- self.file = file
-
-
- def write(self, genSubs=True):
- """
- Generate the completion function and write it to the output file
- @return: C{None}
-
- @type genSubs: C{bool}
- @param genSubs: Flag indicating whether or not completions for the list
- of subcommand should be generated. Only has an effect
- if the C{subCommands} attribute has been defined on the
- L{twisted.python.usage.Options} instance.
- """
- if genSubs and getattr(self.options, 'subCommands', None) is not None:
- gen = ZshArgumentsGenerator(self.options, self.cmdName, self.file)
- gen.extraActions.insert(0, SubcommandAction())
- gen.write()
- self.file.write('local _zsh_subcmds_array\n_zsh_subcmds_array=(\n')
- for (cmd, short, parser, desc) in self.options.subCommands:
- self.file.write('"%s:%s"\n' % (cmd, desc))
- self.file.write(")\n\n")
- self.file.write('_describe "sub-command" _zsh_subcmds_array\n')
- else:
- gen = ZshArgumentsGenerator(self.options, self.cmdName, self.file)
- gen.write()
-
-
-
-class ZshSubcommandBuilder(ZshBuilder):
- """
- Constructs zsh code that will complete options for a given usage.Options
- instance, and also for a single sub-command. This will only be used in
- the case where the user is completing options for a specific subcommand.
-
- @type subOptions: L{twisted.python.usage.Options}
- @ivar subOptions: The L{twisted.python.usage.Options} instance defined for
- the sub command.
- """
- def __init__(self, subOptions, *args):
- self.subOptions = subOptions
- ZshBuilder.__init__(self, *args)
-
-
- def write(self):
- """
- Generate the completion function and write it to the output file
- @return: C{None}
- """
- gen = ZshArgumentsGenerator(self.options, self.cmdName, self.file)
- gen.extraActions.insert(0, SubcommandAction())
- gen.write()
-
- gen = ZshArgumentsGenerator(self.subOptions, self.cmdName, self.file)
- gen.write()
-
-
-
-class ZshArgumentsGenerator(object):
- """
- Generate a call to the zsh _arguments completion function
- based on data in a usage.Options instance
-
- @type options: L{twisted.python.usage.Options}
- @ivar options: The L{twisted.python.usage.Options} instance to generate for
-
- @type cmdName: C{str}
- @ivar cmdName: The name of the command we're generating completions for.
-
- @type file: C{file}
- @ivar file: The C{file} to write the completion function to
-
- The following non-constructor variables are populated by this class
- with data gathered from the C{Options} instance passed in, and its
- base classes.
-
- @type descriptions: C{dict}
- @ivar descriptions: A dict mapping long option names to alternate
- descriptions. When this variable is defined, the descriptions
- contained here will override those descriptions provided in the
- optFlags and optParameters variables.
-
- @type multiUse: C{list}
- @ivar multiUse: An iterable containing those long option names which may
- appear on the command line more than once. By default, options will
- only be completed one time.
-
- @type mutuallyExclusive: C{list} of C{tuple}
- @ivar mutuallyExclusive: A sequence of sequences, with each sub-sequence
- containing those long option names that are mutually exclusive. That is,
- those options that cannot appear on the command line together.
-
- @type optActions: C{dict}
- @ivar optActions: A dict mapping long option names to shell "actions".
- These actions define what may be completed as the argument to the
- given option, and should be given as instances of
- L{twisted.python.usage.Completer}.
-
- Callables may instead be given for the values in this dict. The
- callable should accept no arguments, and return a C{Completer}
- instance used as the action.
-
- @type extraActions: C{list} of C{twisted.python.usage.Completer}
- @ivar extraActions: Extra arguments are those arguments typically
- appearing at the end of the command-line, which are not associated
- with any particular named option. That is, the arguments that are
- given to the parseArgs() method of your usage.Options subclass.
- """
- def __init__(self, options, cmdName, file):
- self.options = options
- self.cmdName = cmdName
- self.file = file
-
- self.descriptions = {}
- self.multiUse = set()
- self.mutuallyExclusive = []
- self.optActions = {}
- self.extraActions = []
-
- for cls in reversed(inspect.getmro(options.__class__)):
- data = getattr(cls, 'compData', None)
- if data:
- self.descriptions.update(data.descriptions)
- self.optActions.update(data.optActions)
- self.multiUse.update(data.multiUse)
-
- self.mutuallyExclusive.extend(data.mutuallyExclusive)
-
- # I don't see any sane way to aggregate extraActions, so just
- # take the one at the top of the MRO (nearest the `options'
- # instance).
- if data.extraActions:
- self.extraActions = data.extraActions
-
- aCL = reflect.accumulateClassList
- aCD = reflect.accumulateClassDict
-
- optFlags = []
- optParams = []
-
- aCL(options.__class__, 'optFlags', optFlags)
- aCL(options.__class__, 'optParameters', optParams)
-
- for i, optList in enumerate(optFlags):
- if len(optList) != 3:
- optFlags[i] = util.padTo(3, optList)
-
- for i, optList in enumerate(optParams):
- if len(optList) != 5:
- optParams[i] = util.padTo(5, optList)
-
-
- self.optFlags = optFlags
- self.optParams = optParams
-
- paramNameToDefinition = {}
- for optList in optParams:
- paramNameToDefinition[optList[0]] = optList[1:]
- self.paramNameToDefinition = paramNameToDefinition
-
- flagNameToDefinition = {}
- for optList in optFlags:
- flagNameToDefinition[optList[0]] = optList[1:]
- self.flagNameToDefinition = flagNameToDefinition
-
- allOptionsNameToDefinition = {}
- allOptionsNameToDefinition.update(paramNameToDefinition)
- allOptionsNameToDefinition.update(flagNameToDefinition)
- self.allOptionsNameToDefinition = allOptionsNameToDefinition
-
- self.addAdditionalOptions()
-
- # makes sure none of the Completions metadata references
- # option names that don't exist. (great for catching typos)
- self.verifyZshNames()
-
- self.excludes = self.makeExcludesDict()
-
-
- def write(self):
- """
- Write the zsh completion code to the file given to __init__
- @return: C{None}
- """
- self.writeHeader()
- self.writeExtras()
- self.writeOptions()
- self.writeFooter()
-
-
- def writeHeader(self):
- """
- This is the start of the code that calls _arguments
- @return: C{None}
- """
- self.file.write('#compdef %s\n\n'
- '_arguments -s -A "-*" \\\n' % (self.cmdName,))
-
-
- def writeOptions(self):
- """
- Write out zsh code for each option in this command
- @return: C{None}
- """
- optNames = self.allOptionsNameToDefinition.keys()
- optNames.sort()
- for longname in optNames:
- self.writeOpt(longname)
-
-
- def writeExtras(self):
- """
- Write out completion information for extra arguments appearing on the
- command-line. These are extra positional arguments not associated
- with a named option. That is, the stuff that gets passed to
- Options.parseArgs().
-
- @return: C{None}
-
- @raises: ValueError: if C{Completer} with C{repeat=True} is found and
- is not the last item in the C{extraActions} list.
- """
- for i, action in enumerate(self.extraActions):
- descr = ""
- if action._descr:
- descr = action._descr
- # a repeatable action must be the last action in the list
- if action._repeat and i != len(self.extraActions) - 1:
- raise ValueError("Completer with repeat=True must be "
- "last item in Options.extraActions")
- self.file.write(escape(action._shellCode('', usage._ZSH)))
- self.file.write(' \\\n')
-
-
- def writeFooter(self):
- """
- Write the last bit of code that finishes the call to _arguments
- @return: C{None}
- """
- self.file.write('&& return 0\n')
-
-
- def verifyZshNames(self):
- """
- Ensure that none of the option names given in the metadata are typoed
- @return: C{None}
- @raise ValueError: Raised if unknown option names have been found.
- """
- def err(name):
- raise ValueError("Unknown option name \"%s\" found while\n"
- "examining Completions instances on %s" % (
- name, self.options))
-
- for name in itertools.chain(self.descriptions, self.optActions,
- self.multiUse):
- if name not in self.allOptionsNameToDefinition:
- err(name)
-
- for seq in self.mutuallyExclusive:
- for name in seq:
- if name not in self.allOptionsNameToDefinition:
- err(name)
-
-
- def excludeStr(self, longname, buildShort=False):
- """
- Generate an "exclusion string" for the given option
-
- @type longname: C{str}
- @param longname: The long option name (e.g. "verbose" instead of "v")
-
- @type buildShort: C{bool}
- @param buildShort: May be True to indicate we're building an excludes
- string for the short option that correspondes to the given long opt.
-
- @return: The generated C{str}
- """
- if longname in self.excludes:
- exclusions = self.excludes[longname].copy()
- else:
- exclusions = set()
-
- # if longname isn't a multiUse option (can't appear on the cmd line more
- # than once), then we have to exclude the short option if we're
- # building for the long option, and vice versa.
- if longname not in self.multiUse:
- if buildShort is False:
- short = self.getShortOption(longname)
- if short is not None:
- exclusions.add(short)
- else:
- exclusions.add(longname)
-
- if not exclusions:
- return ''
-
- strings = []
- for optName in exclusions:
- if len(optName) == 1:
- # short option
- strings.append("-" + optName)
- else:
- strings.append("--" + optName)
- strings.sort() # need deterministic order for reliable unit-tests
- return "(%s)" % " ".join(strings)
-
-
- def makeExcludesDict(self):
- """
- @return: A C{dict} that maps each option name appearing in
- self.mutuallyExclusive to a list of those option names that is it
- mutually exclusive with (can't appear on the cmd line with).
- """
-
- #create a mapping of long option name -> single character name
- longToShort = {}
- for optList in itertools.chain(self.optParams, self.optFlags):
- if optList[1] != None:
- longToShort[optList[0]] = optList[1]
-
- excludes = {}
- for lst in self.mutuallyExclusive:
- for i, longname in enumerate(lst):
- tmp = set(lst[:i] + lst[i+1:])
- for name in tmp.copy():
- if name in longToShort:
- tmp.add(longToShort[name])
-
- if longname in excludes:
- excludes[longname] = excludes[longname].union(tmp)
- else:
- excludes[longname] = tmp
- return excludes
-
-
- def writeOpt(self, longname):
- """
- Write out the zsh code for the given argument. This is just part of the
- one big call to _arguments
-
- @type longname: C{str}
- @param longname: The long option name (e.g. "verbose" instead of "v")
-
- @return: C{None}
- """
- if longname in self.flagNameToDefinition:
- # It's a flag option. Not one that takes a parameter.
- longField = "--%s" % longname
- else:
- longField = "--%s=" % longname
-
- short = self.getShortOption(longname)
- if short != None:
- shortField = "-" + short
- else:
- shortField = ''
-
- descr = self.getDescription(longname)
- descriptionField = descr.replace("[", "\[")
- descriptionField = descriptionField.replace("]", "\]")
- descriptionField = '[%s]' % descriptionField
-
- actionField = self.getAction(longname)
- if longname in self.multiUse:
- multiField = '*'
- else:
- multiField = ''
-
- longExclusionsField = self.excludeStr(longname)
-
- if short:
- #we have to write an extra line for the short option if we have one
- shortExclusionsField = self.excludeStr(longname, buildShort=True)
- self.file.write(escape('%s%s%s%s%s' % (shortExclusionsField,
- multiField, shortField, descriptionField, actionField)))
- self.file.write(' \\\n')
-
- self.file.write(escape('%s%s%s%s%s' % (longExclusionsField,
- multiField, longField, descriptionField, actionField)))
- self.file.write(' \\\n')
-
-
- def getAction(self, longname):
- """
- Return a zsh "action" string for the given argument
- @return: C{str}
- """
- if longname in self.optActions:
- if callable(self.optActions[longname]):
- action = self.optActions[longname]()
- else:
- action = self.optActions[longname]
- return action._shellCode(longname, usage._ZSH)
-
- if longname in self.paramNameToDefinition:
- return ':%s:_files' % (longname,)
- return ''
-
-
- def getDescription(self, longname):
- """
- Return the description to be used for this argument
- @return: C{str}
- """
- #check if we have an alternate descr for this arg, and if so use it
- if longname in self.descriptions:
- return self.descriptions[longname]
-
- #otherwise we have to get it from the optFlags or optParams
- try:
- descr = self.flagNameToDefinition[longname][1]
- except KeyError:
- try:
- descr = self.paramNameToDefinition[longname][2]
- except KeyError:
- descr = None
-
- if descr is not None:
- return descr
-
- # let's try to get it from the opt_foo method doc string if there is one
- longMangled = longname.replace('-', '_') # this is what t.p.usage does
- obj = getattr(self.options, 'opt_%s' % longMangled, None)
- if obj is not None:
- descr = descrFromDoc(obj)
- if descr is not None:
- return descr
-
- return longname # we really ought to have a good description to use
-
-
- def getShortOption(self, longname):
- """
- Return the short option letter or None
- @return: C{str} or C{None}
- """
- optList = self.allOptionsNameToDefinition[longname]
- return optList[0] or None
-
-
- def addAdditionalOptions(self):
- """
- Add additional options to the optFlags and optParams lists.
- These will be defined by 'opt_foo' methods of the Options subclass
- @return: C{None}
- """
- methodsDict = {}
- reflect.accumulateMethods(self.options, methodsDict, 'opt_')
- methodToShort = {}
- for name in methodsDict.copy():
- if len(name) == 1:
- methodToShort[methodsDict[name]] = name
- del methodsDict[name]
-
- for methodName, methodObj in methodsDict.items():
- longname = methodName.replace('_', '-') # t.p.usage does this
- # if this option is already defined by the optFlags or
- # optParameters then we don't want to override that data
- if longname in self.allOptionsNameToDefinition:
- continue
-
- descr = self.getDescription(longname)
-
- short = None
- if methodObj in methodToShort:
- short = methodToShort[methodObj]
-
- reqArgs = methodObj.im_func.func_code.co_argcount
- if reqArgs == 2:
- self.optParams.append([longname, short, None, descr])
- self.paramNameToDefinition[longname] = [short, None, descr]
- self.allOptionsNameToDefinition[longname] = [short, None, descr]
- else:
- # reqArgs must equal 1. self.options would have failed
- # to instantiate if it had opt_ methods with bad signatures.
- self.optFlags.append([longname, short, descr])
- self.flagNameToDefinition[longname] = [short, descr]
- self.allOptionsNameToDefinition[longname] = [short, None, descr]
-
-
-
-def descrFromDoc(obj):
- """
- Generate an appropriate description from docstring of the given object
- """
- if obj.__doc__ is None or obj.__doc__.isspace():
- return None
-
- lines = [x.strip() for x in obj.__doc__.split("\n")
- if x and not x.isspace()]
- return " ".join(lines)
-
-
-
-def escape(x):
- """
- Shell escape the given string
-
- Implementation borrowed from now-deprecated commands.mkarg() in the stdlib
- """
- if '\'' not in x:
- return '\'' + x + '\''
- s = '"'
- for c in x:
- if c in '\\$"`':
- s = s + '\\'
- s = s + c
- s = s + '"'
- return s
-