@task(help=dict(<EOL>verbose="<STR_LIT>",<EOL>pypi="<STR_LIT>",<EOL>))<EOL>def bump(ctx, verbose=False, pypi=False):

cfg = config.load()<EOL>scm = scm_provider(cfg.project_root, commit=False, ctx=ctx)<EOL>if not scm.workdir_is_clean():<EOL><INDENT>notify.warning("<STR_LIT>")<EOL><DEDENT>pep440 = scm.pep440_dev_version(verbose=verbose, non_local=pypi)<EOL>setup_cfg = cfg.rootjoin('<STR_LIT>')<EOL>if not pep440:<EOL><INDENT>notify.info("<STR_LIT>")<EOL><DEDENT>elif os.path.exists(setup_cfg):<EOL><INDENT>with io.open(setup_cfg, encoding='<STR_LIT:utf-8>') as handle:<EOL><INDENT>data = handle.readlines()<EOL><DEDENT>changed = False<EOL>for i, line in enumerate(data):<EOL><INDENT>if re.match(r"<STR_LIT>", line):<EOL><INDENT>verb, _ = data[i].split('<STR_LIT:=>', <NUM_LIT:1>)<EOL>data[i] = '<STR_LIT>'.format(verb, pep440)<EOL>changed = True<EOL><DEDENT><DEDENT>if changed:<EOL><INDENT>notify.info("<STR_LIT>")<EOL>with io.open(setup_cfg, '<STR_LIT:w>', encoding='<STR_LIT:utf-8>') as handle:<EOL><INDENT>handle.write('<STR_LIT>'.join(data))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>notify.warning("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>notify.warning("<STR_LIT>")<EOL><DEDENT>if os.path.exists(setup_cfg):<EOL><INDENT>egg_info = shell.capture("<STR_LIT>", echo=True if verbose else None)<EOL>for line in egg_info.splitlines():<EOL><INDENT>if line.endswith('<STR_LIT>'):<EOL><INDENT>pkg_info_file = line.split(None, <NUM_LIT:1>)[<NUM_LIT:1>]<EOL>with io.open(pkg_info_file, encoding='<STR_LIT:utf-8>') as handle:<EOL><INDENT>notify.info('<STR_LIT:\n>'.join(i for i in handle.readlines() if i.startswith('<STR_LIT>')).strip())<EOL><DEDENT><DEDENT><DEDENT>ctx.run("<STR_LIT>", echo=True if verbose else None)<EOL><DEDENT>


@task(help=dict(<EOL>devpi="<STR_LIT>",<EOL>egg="<STR_LIT>",<EOL>wheel="<STR_LIT>",<EOL>auto="<STR_LIT>",<EOL>))<EOL>def dist(ctx, devpi=False, egg=False, wheel=False, auto=True):

config.load()<EOL>cmd = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]<EOL>if auto:<EOL><INDENT>egg = sys.version_info.major == <NUM_LIT:2><EOL>try:<EOL><INDENT>import wheel as _<EOL>wheel = True<EOL><DEDENT>except ImportError:<EOL><INDENT>wheel = False<EOL><DEDENT><DEDENT>if egg:<EOL><INDENT>cmd.append("<STR_LIT>")<EOL><DEDENT>if wheel:<EOL><INDENT>cmd.append("<STR_LIT>")<EOL><DEDENT>ctx.run("<STR_LIT>")<EOL>ctx.run('<STR_LIT:U+0020>'.join(cmd))<EOL>if devpi:<EOL><INDENT>ctx.run("<STR_LIT>")<EOL><DEDENT>


cfg = config.load()<EOL>ctx.run("<STR_LIT>")<EOL>pkg_info = get_egg_info(cfg)<EOL>version = pkg_info.version if pkg_info else cfg.project.version<EOL>pex_files = []<EOL>for script in cfg.project.entry_points['<STR_LIT>']:<EOL><INDENT>script, entry_point = script.split('<STR_LIT:=>', <NUM_LIT:1>)<EOL>script, entry_point = script.strip(), entry_point.strip()<EOL>pex_file = cfg.rootjoin('<STR_LIT>', '<STR_LIT>'.format(script, version))<EOL>cmd = ['<STR_LIT>', '<STR_LIT>', cfg.rootjoin('<STR_LIT>'), cfg.project_root, '<STR_LIT:-c>', script, '<STR_LIT>', pex_file]<EOL>if opts:<EOL><INDENT>cmd.append(opts)<EOL><DEDENT>ctx.run('<STR_LIT:U+0020>'.join(cmd))<EOL>non_universal = set()<EOL>with closing(zipfile.ZipFile(pex_file, mode="<STR_LIT:r>")) as pex_contents:<EOL><INDENT>for pex_name in pex_contents.namelist():  <EOL><INDENT>if pex_name.endswith('<STR_LIT>') and '<STR_LIT>' not in pex_name:<EOL><INDENT>non_universal.add(pex_name.split('<STR_LIT>')[<NUM_LIT:0>].split('<STR_LIT:/>')[-<NUM_LIT:1>])<EOL><DEDENT><DEDENT><DEDENT>if non_universal:<EOL><INDENT>notify.warning("<STR_LIT>"<EOL>.format(pex_file.replace(os.getcwd(), '<STR_LIT:.>'), '<STR_LIT>'.join(sorted(non_universal))))<EOL>envs = [i.split('<STR_LIT:->')[-<NUM_LIT:3>:] for i in non_universal]<EOL>envs = {i[<NUM_LIT:0>]: i[<NUM_LIT:1>:] for i in envs}<EOL>if len(envs) > <NUM_LIT:1>:<EOL><INDENT>envs = {k: v for k, v in envs.items() if not k.startswith('<STR_LIT>')}<EOL><DEDENT>env_id = []<EOL>for k, v in sorted(envs.items()):<EOL><INDENT>env_id.append(k)<EOL>env_id.extend(v)<EOL><DEDENT>env_id = '<STR_LIT:->'.join(env_id)<EOL><DEDENT>else:<EOL><INDENT>env_id = '<STR_LIT>'<EOL><DEDENT>new_pex_file = pex_file.replace('<STR_LIT>', '<STR_LIT>'.format(env_id))<EOL>notify.info("<STR_LIT>".format(os.path.basename(new_pex_file)))<EOL>os.rename(pex_file, new_pex_file)<EOL>pex_file = new_pex_file<EOL>pex_files.append(pex_file)<EOL><DEDENT>if not pex_files:<EOL><INDENT>notify.warning("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if pyrun:<EOL><INDENT>if any(pyrun.startswith(i) for i in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>')):<EOL><INDENT>pyrun_url = pyrun<EOL><DEDENT>else:<EOL><INDENT>pyrun_cfg = dict(ctx.rituals.pyrun)<EOL>pyrun_cfg.update(parse_qsl(pyrun.replace(os.pathsep, '<STR_LIT:&>')))<EOL>pyrun_url = (pyrun_cfg['<STR_LIT>'] + '<STR_LIT:/>' +<EOL>pyrun_cfg['<STR_LIT>']).format(**pyrun_cfg)<EOL><DEDENT>notify.info("<STR_LIT>".format(pyrun_url))<EOL>with url_as_file(pyrun_url, ext='<STR_LIT>') as pyrun_tarball:<EOL><INDENT>pyrun_tar = tarfile.TarFile.gzopen(pyrun_tarball)<EOL>for pex_file in pex_files[:]:<EOL><INDENT>pyrun_exe = pyrun_tar.extractfile('<STR_LIT>')<EOL>with open(pex_file, '<STR_LIT:rb>') as pex_handle:<EOL><INDENT>pyrun_pex_file = '<STR_LIT>'.format(<EOL>pex_file[:-<NUM_LIT:4>], pyrun_url.rsplit('<STR_LIT>')[-<NUM_LIT:1>][:-<NUM_LIT:4>])<EOL>with open(pyrun_pex_file, '<STR_LIT:wb>') as pyrun_pex:<EOL><INDENT>pyrun_pex.write(INSTALLER_BASH.replace('<STR_LIT>', '<STR_LIT>'.format(len(INSTALLER_BASH) + <NUM_LIT:1>)))<EOL>shutil.copyfileobj(pyrun_exe, pyrun_pex)<EOL>shutil.copyfileobj(pex_handle, pyrun_pex)<EOL><DEDENT>shutil.copystat(pex_file, pyrun_pex_file)<EOL>notify.info("<STR_LIT>".format(pretty_path(pyrun_pex_file)))<EOL>pex_files.append(pyrun_pex_file)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if upload:<EOL><INDENT>base_url = ctx.rituals.release.upload.base_url.rstrip('<STR_LIT:/>')<EOL>if not base_url:<EOL><INDENT>notify.failure("<STR_LIT>")<EOL><DEDENT>for pex_file in pex_files:<EOL><INDENT>url = base_url + '<STR_LIT:/>' + ctx.rituals.release.upload.path.lstrip('<STR_LIT:/>').format(<EOL>name=cfg.project.name, version=cfg.project.version, filename=os.path.basename(pex_file))<EOL>notify.info("<STR_LIT>".format(url))<EOL>with io.open(pex_file, '<STR_LIT:rb>') as handle:<EOL><INDENT>reply = requests.put(url, data=handle.read())<EOL>if reply.status_code in range(<NUM_LIT:200>, <NUM_LIT>):<EOL><INDENT>notify.info("<STR_LIT>".format(**vars(reply)))<EOL><DEDENT>else:<EOL><INDENT>notify.warning("<STR_LIT>".format(**vars(reply)))<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>


@task(default=True, help=dict(<EOL>dput="<STR_LIT>",<EOL>opts="<STR_LIT>",<EOL>))<EOL>def build(ctx, dput='<STR_LIT>', opts='<STR_LIT>'):

<EOL>with io.open('<STR_LIT>', encoding='<STR_LIT:utf-8>') as changes:<EOL><INDENT>metadata = re.match(r'<STR_LIT>', changes.readline().rstrip())<EOL>if not metadata:<EOL><INDENT>notify.failure('<STR_LIT>')<EOL><DEDENT>name, version, _, _ = metadata.groups()<EOL><DEDENT>ctx.run('<STR_LIT>'.format(ctx.rituals.deb.build.opts, opts))<EOL>if not os.path.exists('<STR_LIT>'):<EOL><INDENT>os.makedirs('<STR_LIT>')<EOL><DEDENT>artifact_pattern = '<STR_LIT>'.format(name, re.sub(r'<STR_LIT>', '<STR_LIT:?>', version))<EOL>changes_files = []<EOL>for debfile in glob.glob('<STR_LIT>' + artifact_pattern):<EOL><INDENT>shutil.move(debfile, '<STR_LIT>')<EOL>if debfile.endswith('<STR_LIT>'):<EOL><INDENT>changes_files.append(os.path.join('<STR_LIT>', os.path.basename(debfile)))<EOL><DEDENT><DEDENT>ctx.run('<STR_LIT>'.format(artifact_pattern))<EOL>if dput:<EOL><INDENT>ctx.run('<STR_LIT>'.format(dput, '<STR_LIT:U+0020>'.join(changes_files)))<EOL><DEDENT>


registered = None<EOL>if sys.platform.startswith('<STR_LIT>'):<EOL><INDENT>if os.path.splitext(exe_name)[<NUM_LIT:1>].lower() != '<STR_LIT>':<EOL><INDENT>exe_name += '<STR_LIT>'<EOL><DEDENT>import _winreg <EOL>try:<EOL><INDENT>key = "<STR_LIT>" + exe_name<EOL>value = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, key)<EOL>registered = (value, "<STR_LIT>"+key)<EOL><DEDENT>except _winreg.error:<EOL><INDENT>pass<EOL><DEDENT>if registered and not os.path.exists(registered[<NUM_LIT:0>]):<EOL><INDENT>registered = None<EOL><DEDENT><DEDENT>return registered<EOL>

Windows allow application paths to be registered in the registry.


if sys.platform.startswith('<STR_LIT>'):<EOL><INDENT>return os.path.normpath(os.path.normcase(fname1)) == os.path.normpath(os.path.normcase(fname2))<EOL><DEDENT>else:<EOL><INDENT>return os.path.samefile(fname1, fname2)<EOL><DEDENT>

OS independent `samefile` implementation.


def _cull(potential, matches, verbose=<NUM_LIT:0>):

for match in matches: <EOL><INDENT>if _samefile(potential[<NUM_LIT:0>], match[<NUM_LIT:0>]):<EOL><INDENT>if verbose:<EOL><INDENT>sys.stderr.write("<STR_LIT>" % potential)<EOL><DEDENT>return None<EOL><DEDENT><DEDENT>if not stat.S_ISREG(os.stat(potential[<NUM_LIT:0>]).st_mode):<EOL><INDENT>if verbose:<EOL><INDENT>sys.stderr.write("<STR_LIT>" % potential)<EOL><DEDENT><DEDENT>elif not os.access(potential[<NUM_LIT:0>], os.X_OK):<EOL><INDENT>if verbose:<EOL><INDENT>sys.stderr.write("<STR_LIT>" % potential)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>matches.append(potential)<EOL>return potential<EOL><DEDENT>return None<EOL>

Cull inappropriate matches. Possible reasons:
        - a duplicate of a previous match
        - not a disk file
        - not executable (non-Windows)
    If 'potential' is approved it is returned and added to 'matches'.
    Otherwise, None is returned.


def whichgen(command, path=None, verbose=<NUM_LIT:0>, exts=None):

matches = []<EOL>if path is None:<EOL><INDENT>using_given_path = <NUM_LIT:0><EOL>path = os.environ.get("<STR_LIT>", "<STR_LIT>").split(os.pathsep)<EOL>if sys.platform.startswith("<STR_LIT>"):<EOL><INDENT>path.insert(<NUM_LIT:0>, os.curdir)  <EOL><DEDENT><DEDENT>else:<EOL><INDENT>using_given_path = <NUM_LIT:1><EOL><DEDENT>if sys.platform.startswith("<STR_LIT>"):<EOL><INDENT>if exts is None:<EOL><INDENT>exts = os.environ.get("<STR_LIT>", "<STR_LIT>").split(os.pathsep)<EOL>for ext in exts:<EOL><INDENT>if ext.lower() == "<STR_LIT>":<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>exts = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL><DEDENT><DEDENT>elif not isinstance(exts, list):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if exts is not None:<EOL><INDENT>raise WhichError("<STR_LIT>" % sys.platform)<EOL><DEDENT>exts = []<EOL><DEDENT>if os.sep in command or os.altsep and os.altsep in command:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>for i, dir_name in enumerate(path):<EOL><INDENT>if sys.platform.startswith("<STR_LIT>") and len(dir_name) >= <NUM_LIT:2> and dir_name[<NUM_LIT:0>] == '<STR_LIT:">' and dir_name[-<NUM_LIT:1>] == '<STR_LIT:">':<EOL><INDENT>dir_name = dir_name[<NUM_LIT:1>:-<NUM_LIT:1>]<EOL><DEDENT>for ext in ['<STR_LIT>']+exts:<EOL><INDENT>abs_name = os.path.abspath(os.path.normpath(os.path.join(dir_name, command+ext)))<EOL>if os.path.isfile(abs_name):<EOL><INDENT>if using_given_path:<EOL><INDENT>from_where = "<STR_LIT>" % i<EOL><DEDENT>elif not sys.platform.startswith("<STR_LIT>"):<EOL><INDENT>from_where = "<STR_LIT>" % i<EOL><DEDENT>elif i == <NUM_LIT:0>:<EOL><INDENT>from_where = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>from_where = "<STR_LIT>" % (i-<NUM_LIT:1>)<EOL><DEDENT>match = _cull((abs_name, from_where), matches, verbose)<EOL>if match:<EOL><INDENT>if verbose:<EOL><INDENT>yield match<EOL><DEDENT>else:<EOL><INDENT>yield match[<NUM_LIT:0>]<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>match = _get_registered_executable(command)<EOL>if match is not None:<EOL><INDENT>match = _cull(match, matches, verbose)<EOL>if match:<EOL><INDENT>if verbose:<EOL><INDENT>yield match<EOL><DEDENT>else:<EOL><INDENT>yield match[<NUM_LIT:0>]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

Return a generator of full paths to the given command.

    "command" is a the name of the executable to search for.
    "path" is an optional alternate path list to search. The default it
        to use the PATH environment variable.
    "verbose", if true, will cause a 2-tuple to be returned for each
        match. The second element is a textual description of where the
        match was found.
    "exts" optionally allows one to specify a list of extensions to use
        instead of the standard list for this system. This can
        effectively be used as an optimization to, for example, avoid
        stat's of "foo.vbs" when searching for "foo" and you know it is
        not a VisualBasic script but ".vbs" is on PATHEXT. This option
        is only supported on Windows.

    This method returns a generator which yields either full paths to
    the given command or, if verbose, tuples of the form (<path to
    command>, <where path found>).


def which(command, path=None, verbose=<NUM_LIT:0>, exts=None):

matched = whichgen(command, path, verbose, exts)<EOL>try:<EOL><INDENT>match = next(matched)<EOL><DEDENT>except StopIteration:<EOL><INDENT>raise WhichError("<STR_LIT>" % command)<EOL><DEDENT>else:<EOL><INDENT>return match<EOL><DEDENT>

Return the full path to the first match of the given command on
    the path.

    "command" is a the name of the executable to search for.
    "path" is an optional alternate path list to search. The default it
        to use the PATH environment variable.
    "verbose", if true, will cause a 2-tuple to be returned. The second
        element is a textual description of where the match was found.
    "exts" optionally allows one to specify a list of extensions to use
        instead of the standard list for this system. This can
        effectively be used as an optimization to, for example, avoid
        stat's of "foo.vbs" when searching for "foo" and you know it is
        not a VisualBasic script but ".vbs" is on PATHEXT. This option
        is only supported on Windows.

    If no match is found for the command, a WhichError is raised.


def whichall(command, path=None, verbose=<NUM_LIT:0>, exts=None):

return list(whichgen(command, path, verbose, exts))<EOL>

Return a list of full paths to all matches of the given command on the path.

    "command" is a the name of the executable to search for.
    "path" is an optional alternate path list to search. The default it
        to use the PATH environment variable.
    "verbose", if true, will cause a 2-tuple to be returned for each
        match. The second element is a textual description of where the
        match was found.
    "exts" optionally allows one to specify a list of extensions to use
        instead of the standard list for this system. This can
        effectively be used as an optimization to, for example, avoid
        stat's of "foo.vbs" when searching for "foo" and you know it is
        not a VisualBasic script but ".vbs" is on PATHEXT. This option
        is only supported on Windows.


<EOL>self.run('<STR_LIT>', **RUN_KWARGS)<EOL>unchanged = True<EOL>try:<EOL><INDENT>self.run('<STR_LIT>', report_error=False, **RUN_KWARGS)<EOL><DEDENT>except exceptions.Failure:<EOL><INDENT>unchanged = False<EOL>if not quiet:<EOL><INDENT>notify.warning('<STR_LIT>')<EOL>self.run('<STR_LIT>', **RUN_KWARGS)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>self.run('<STR_LIT>', report_error=False, **RUN_KWARGS)<EOL><DEDENT>except exceptions.Failure:<EOL><INDENT>unchanged = False<EOL>if not quiet:<EOL><INDENT>notify.warning('<STR_LIT>')<EOL>self.run('<STR_LIT>', **RUN_KWARGS)<EOL><DEDENT><DEDENT>return unchanged<EOL>

Check for uncommitted changes, return `True` if everything is clean.

            Inspired by http://stackoverflow.com/questions/3878624/.


self.run('<STR_LIT>'.format(filename), **RUN_KWARGS)<EOL>


self.run_elective('<STR_LIT>'.format(message))<EOL>


options = '<STR_LIT>'.format(message) if message else '<STR_LIT>'<EOL>self.run_elective('<STR_LIT>'.format(options, label))<EOL>


def pep440_dev_version(self, verbose=False, non_local=False):

version = capture("<STR_LIT>", echo=verbose)<EOL>if verbose:<EOL><INDENT>notify.info("<STR_LIT>".format(version))<EOL><DEDENT>now = '<STR_LIT>'.format(datetime.now())<EOL>tag = capture("<STR_LIT>".format(now), echo=verbose)<EOL>if verbose:<EOL><INDENT>notify.info("<STR_LIT>".format(tag))<EOL><DEDENT>try:<EOL><INDENT>tag, date, time = tag.split('<STR_LIT:!>')<EOL><DEDENT>except ValueError:<EOL><INDENT>date = time = '<STR_LIT>'<EOL><DEDENT>tag, commits, short_hash = tag.rsplit('<STR_LIT:->', <NUM_LIT:3>)<EOL>label = tag<EOL>if re.match(r"<STR_LIT>", label):<EOL><INDENT>label = label[<NUM_LIT:1>:]<EOL><DEDENT>if commits == '<STR_LIT:0>' and label == version:<EOL><INDENT>pep440 = None<EOL><DEDENT>else:<EOL><INDENT>local_part = [<EOL>re.sub(r"<STR_LIT>", '<STR_LIT:.>', label).strip('<STR_LIT:.>'),  <EOL>short_hash,<EOL>date + ('<STR_LIT:T>' + time if time else '<STR_LIT>'),<EOL>]<EOL>build_number = os.environ.get('<STR_LIT>', '<STR_LIT>')<EOL>if build_number.isdigit():<EOL><INDENT>local_part.extend(['<STR_LIT>', build_number])<EOL>if verbose:<EOL><INDENT>notify.info("<STR_LIT>".format(build_number))<EOL><DEDENT><DEDENT>local_part = [i for i in local_part if i]<EOL>pep440 = '<STR_LIT>'.format(commits, '<STR_LIT:.>'.join(local_part).strip('<STR_LIT:.>'))<EOL>if non_local:<EOL><INDENT>pep440, _ = pep440.split('<STR_LIT:+>', <NUM_LIT:1>)<EOL><DEDENT><DEDENT>return pep440<EOL>

Return a PEP-440 dev version appendix to the main version number.

            Result is ``None`` if the workdir is in a release-ready state
            (i.e. clean and properly tagged).


if not quiet:<EOL><INDENT>notify.warning('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>return True<EOL>

Check for uncommitted changes, return `True` if everything is clean.


notify.warning('<STR_LIT>'.format(filename))<EOL>

Stage a file for committing, or commit it directly (depending on the SCM).


notify.warning('<STR_LIT>'.format(message))<EOL>


notify.warning('<STR_LIT>'.format(<EOL>label, '<STR_LIT>'.format(message) if message else '<STR_LIT>',<EOL>))<EOL>


<EOL>pep440 = '<STR_LIT>'.format(datetime.now())<EOL>if not non_local:<EOL><INDENT>build_number = os.environ.get('<STR_LIT>', '<STR_LIT>')<EOL>if build_number.isdigit():<EOL><INDENT>pep440 += '<STR_LIT>'.format(build_number)<EOL>if verbose:<EOL><INDENT>notify.info("<STR_LIT>".format(build_number))<EOL><DEDENT><DEDENT><DEDENT>return pep440<EOL>

Return a PEP-440 dev version appendix to the main version number.


runner = self.ctx.run if self.ctx else None<EOL>return run(cmd, runner=runner, *args, **kwargs)<EOL>


def run_elective(self, cmd, *args, **kwargs):

if self._commit:<EOL><INDENT>return self.run(cmd, *args, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>notify.warning("<STR_LIT>".format(cmd))<EOL>kwargs = kwargs.copy()<EOL>kwargs['<STR_LIT>'] = False<EOL>return self.run('<STR_LIT:true>', *args, **kwargs)<EOL><DEDENT>

Run a command, or just echo it, depending on `commit`.


<EOL>if os.path.isdir(os.path.join(workdir, '<STR_LIT>')) and os.path.isfile(os.path.join(workdir, '<STR_LIT>', '<STR_LIT>')):<EOL><INDENT>return '<STR_LIT>'<EOL><DEDENT>return '<STR_LIT>'<EOL>

Return string signifying the SCM used in the given directory.

        Currently, 'git' is supported. Anything else returns 'unknown'.


def provider(workdir, commit=True, **kwargs):

return SCM_PROVIDER[auto_detect(workdir)](workdir, commit=commit, **kwargs)<EOL>

Factory for the correct SCM provider in `workdir`.


return "<STR_LIT>".join(<EOL>re.escape(bit).replace(r'<STR_LIT>', '<STR_LIT>').replace(r'<STR_LIT>', '<STR_LIT:[>').replace(r'<STR_LIT>', '<STR_LIT:]>')<EOL>for bit in part.split("<STR_LIT:*>")<EOL>)<EOL>


if not pattern:<EOL><INDENT>return<EOL><DEDENT>bits = pattern.split("<STR_LIT:/>")<EOL>dirs, filename = bits[:-<NUM_LIT:1>], bits[-<NUM_LIT:1>]<EOL>for dirname in dirs:<EOL><INDENT>if dirname == "<STR_LIT>":<EOL><INDENT>yield  "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>yield glob2re(dirname) + "<STR_LIT:/>"<EOL><DEDENT><DEDENT>yield glob2re(filename)<EOL>

Generate parts of regex transformed from glob pattern.


parsed = "<STR_LIT>".join(parse_glob(spec))<EOL>regex = "<STR_LIT>".format(parsed)<EOL>return re.compile(regex)<EOL>

Convert the given glob `spec` to a compiled regex.


return Pattern(pattern, inclusive=True)<EOL>


return Pattern(pattern, inclusive=False)<EOL>


self.compiled = compile_glob(spec.rstrip('<STR_LIT:/>'))<EOL>self.inclusive = inclusive<EOL>self.is_dir = spec.endswith('<STR_LIT:/>')<EOL>

Create regex-based pattern matcher from glob `spec`.


return ('<STR_LIT:+>' if self.inclusive else '<STR_LIT:->') + self.compiled.pattern<EOL>

Return inclusiveness indicator and original glob pattern.


return bool(self.compiled.match(path))<EOL>

Check this pattern against given `path`.


inclusive = None<EOL>for pattern in self.patterns:<EOL><INDENT>if pattern.is_dir == is_dir and pattern.matches(path):<EOL><INDENT>inclusive = pattern.inclusive<EOL><DEDENT><DEDENT>return inclusive<EOL>

Check patterns in order, last match that includes or excludes `path` wins. Return `None` on undecided.


lead = '<STR_LIT>'<EOL>if '<STR_LIT>' in kwargs and kwargs.pop('<STR_LIT>'):<EOL><INDENT>lead = self.root.rstrip(os.sep) + os.sep<EOL><DEDENT>for base, dirs, files in os.walk(self.root, **kwargs):<EOL><INDENT>prefix = base[len(self.root):].lstrip(os.sep)<EOL>bits = prefix.split(os.sep) if prefix else []<EOL>for dirname in dirs[:]:<EOL><INDENT>path = '<STR_LIT:/>'.join(bits + [dirname])<EOL>inclusive = self.included(path, is_dir=True)<EOL>if inclusive:<EOL><INDENT>yield lead + path + '<STR_LIT:/>'<EOL><DEDENT>elif inclusive is False:<EOL><INDENT>dirs.remove(dirname)<EOL><DEDENT><DEDENT>for filename in files:<EOL><INDENT>path = '<STR_LIT:/>'.join(bits + [filename])<EOL>if self.included(path):<EOL><INDENT>yield lead + path<EOL><DEDENT><DEDENT><DEDENT>

Like `os.walk` and taking the same keyword arguments,
            but generating paths relative to the root.

            Starts in the fileset's root and filters based on its patterns.
            If ``with_root=True`` is passed in, the generated paths include
            the root path.


kw = kw.copy()<EOL>kw['<STR_LIT>'] = '<STR_LIT>'<EOL>if not kw.get('<STR_LIT>', False):<EOL><INDENT>kw['<STR_LIT>'] = False<EOL><DEDENT>ignore_failures = kw.pop('<STR_LIT>', False)<EOL>try:<EOL><INDENT>return invoke_run(cmd, **kw).stdout.strip()<EOL><DEDENT>except exceptions.Failure as exc:<EOL><INDENT>if not ignore_failures:<EOL><INDENT>notify.error("<STR_LIT>".format(cmd, exc.result.return_code,))<EOL>raise<EOL><DEDENT><DEDENT>

Run a command and return its stripped captured output.


kw = kw.copy()<EOL>kw.setdefault('<STR_LIT>', False)  <EOL>report_error = kw.pop('<STR_LIT>', True)<EOL>runner = kw.pop('<STR_LIT>', invoke_run)<EOL>try:<EOL><INDENT>return runner(cmd, **kw)<EOL><DEDENT>except exceptions.Failure as exc:<EOL><INDENT>sys.stdout.flush()<EOL>sys.stderr.flush()<EOL>if report_error:<EOL><INDENT>notify.error("<STR_LIT>".format(cmd, exc.result.return_code,))<EOL><DEDENT>raise<EOL><DEDENT>finally:<EOL><INDENT>sys.stdout.flush()<EOL>sys.stderr.flush()<EOL><DEDENT>


base = base or os.getcwd()<EOL>while base != os.path.dirname(base):<EOL><INDENT>if os.path.exists(os.path.join(base, name)):<EOL><INDENT>return base<EOL><DEDENT>base = os.path.dirname(base)<EOL><DEDENT>return None<EOL>

Search for a file named `name` from cwd or given directory to root.
        Return None if nothing's found.


py_path = os.environ.get('<STR_LIT>', '<STR_LIT>')<EOL>if path not in py_path.split(os.pathsep):<EOL><INDENT>py_path = '<STR_LIT>'.join([path, os.pathsep if py_path else '<STR_LIT>', py_path])<EOL>os.environ['<STR_LIT>'] = py_path<EOL><DEDENT>

Add given directory to PYTHONPATH, e.g. for pylint.


sys.stdout.flush()<EOL>sys.stderr.flush()<EOL>


if ECHO:<EOL><INDENT>_flush()<EOL>sys.stderr.write("<STR_LIT>".format(msg))<EOL>sys.stderr.flush()<EOL><DEDENT>

Emit a banner just like Invoke's `run(…, echo=True)`.


_flush()<EOL>sys.stdout.write(msg + '<STR_LIT:\n>')<EOL>sys.stdout.flush()<EOL>


_flush()<EOL>sys.stderr.write("<STR_LIT>".format(msg))<EOL>sys.stderr.flush()<EOL>


error(msg)<EOL>sys.exit(<NUM_LIT:1>)<EOL>


def pretty_path(path, _home_re=re.compile('<STR_LIT>' + re.escape(os.path.expanduser('<STR_LIT>') + os.sep))):

path = decode_filename(path)<EOL>path = _home_re.sub('<STR_LIT>' + os.sep, path)<EOL>return path<EOL>

Prettify path for humans, and make it Unicode.


saved = os.getcwd()<EOL>os.chdir(path)<EOL>try:<EOL><INDENT>yield saved<EOL><DEDENT>finally:<EOL><INDENT>os.chdir(saved)<EOL><DEDENT>

A context that enters a given directory and restores the old state on exit.

        The original directory is returned as the context variable.


if ext:<EOL><INDENT>ext = '<STR_LIT:.>' + ext.strip('<STR_LIT:.>')  <EOL><DEDENT>url_hint = '<STR_LIT>'.format(urlparse(url).hostname or '<STR_LIT>')<EOL>if url.startswith('<STR_LIT>'):<EOL><INDENT>url = os.path.abspath(url[len('<STR_LIT>'):])<EOL><DEDENT>if os.path.isabs(url):<EOL><INDENT>with open(url, '<STR_LIT:rb>') as handle:<EOL><INDENT>content = handle.read()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>content = requests.get(url).content<EOL><DEDENT>with tempfile.NamedTemporaryFile(suffix=ext or '<STR_LIT>', prefix=url_hint, delete=False) as handle:<EOL><INDENT>handle.write(content)<EOL><DEDENT>try:<EOL><INDENT>yield handle.name<EOL><DEDENT>finally:<EOL><INDENT>if os.path.exists(handle.name):<EOL><INDENT>os.remove(handle.name)<EOL><DEDENT><DEDENT>

Context manager that GETs a given `url` and provides it as a local file.

The file is in a closed state upon entering the context,
and removed when leaving it, if still there.

To give the file name a specific extension, use `ext`;
the extension can optionally include a separating dot,
otherwise it will be added.

Parameters:
    url (str): URL to retrieve.
    ext (str, optional): Extension for the generated filename.

Yields:
    str: The path to a temporary file with the content of the URL.

Raises:
    requests.RequestException: Base exception of ``requests``, see its
        docs for more detailed ones.

Example:
    >>> import io, re, json
    >>> with url_as_file('https://api.github.com/meta', ext='json') as meta:
    ...     meta, json.load(io.open(meta, encoding='ascii'))['hooks']
    (u'/tmp/www-api.github.com-Ba5OhD.json', [u'192.30.252.0/22'])


return os.path.join(*((project_root,) + args))<EOL>


<EOL>expected_keys = ('<STR_LIT:url>', '<STR_LIT:version>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>')<EOL>metadata = {}<EOL>with open(srcfile('<STR_LIT:src>', package_name, '<STR_LIT>'), encoding='<STR_LIT:utf-8>') as handle:<EOL><INDENT>pkg_init = handle.read()<EOL>metadata['<STR_LIT>'] = re.search(r'<STR_LIT>', pkg_init, re.DOTALL|re.MULTILINE).group(<NUM_LIT:1>)<EOL>for line in pkg_init.splitlines():<EOL><INDENT>match = re.match(r"""<STR_LIT>""".format('<STR_LIT:|>'.join(expected_keys)), line)<EOL>if match:<EOL><INDENT>metadata[match.group(<NUM_LIT:1>)] = match.group(<NUM_LIT:3>)<EOL><DEDENT><DEDENT><DEDENT>if not all(i in metadata for i in expected_keys):<EOL><INDENT>raise RuntimeError("<STR_LIT>".format(<EOL>name, '<STR_LIT:U+002CU+0020>'.join(sorted(set(expected_keys) - set(metadata.keys()))),<EOL>))<EOL><DEDENT>text = metadata['<STR_LIT>'].strip()<EOL>if text:<EOL><INDENT>metadata['<STR_LIT:description>'], text = text.split('<STR_LIT:.>', <NUM_LIT:1>)<EOL>metadata['<STR_LIT:description>'] = '<STR_LIT:U+0020>'.join(metadata['<STR_LIT:description>'].split()).strip() + '<STR_LIT:.>' <EOL>metadata['<STR_LIT>'] = textwrap.dedent(text).strip()<EOL><DEDENT>metadata['<STR_LIT>'] = metadata['<STR_LIT>'].replace('<STR_LIT:U+002C>', '<STR_LIT:U+0020>').strip().split()<EOL>requirements_files = dict(<EOL>install = '<STR_LIT>',<EOL>setup = '<STR_LIT>',<EOL>test = '<STR_LIT>',<EOL>)<EOL>requires = {}<EOL>for key, filename in requirements_files.items():<EOL><INDENT>requires[key] = []<EOL>if os.path.exists(srcfile(filename)):<EOL><INDENT>with open(srcfile(filename), encoding='<STR_LIT:utf-8>') as handle:<EOL><INDENT>for line in handle:<EOL><INDENT>line = line.strip()<EOL>if line and not line.startswith('<STR_LIT:#>'):<EOL><INDENT>if line.startswith('<STR_LIT>'):<EOL><INDENT>line = line.split()[<NUM_LIT:1>].split('<STR_LIT>')[<NUM_LIT:1>]<EOL><DEDENT>requires[key].append(line)<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>if not any('<STR_LIT>' == re.split('<STR_LIT>', i.lower())[<NUM_LIT:0>] for i in requires['<STR_LIT:test>']):<EOL><INDENT>requires['<STR_LIT:test>'].append('<STR_LIT>') <EOL><DEDENT>console_scripts = []<EOL>for path, dirs, files in os.walk(srcfile('<STR_LIT:src>', package_name)):<EOL><INDENT>dirs = [i for i in dirs if not i.startswith('<STR_LIT:.>')]<EOL>if '<STR_LIT>' in files:<EOL><INDENT>path = path[len(srcfile('<STR_LIT:src>') + os.sep):]<EOL>appname = path.split(os.sep)[-<NUM_LIT:1>]<EOL>with open(srcfile('<STR_LIT:src>', path, '<STR_LIT>'), encoding='<STR_LIT:utf-8>') as handle:<EOL><INDENT>for line in handle.readlines():<EOL><INDENT>match = re.match(r"""<STR_LIT>""", line)<EOL>if match:<EOL><INDENT>appname = match.group(<NUM_LIT:2>)<EOL><DEDENT><DEDENT><DEDENT>console_scripts.append('<STR_LIT>'.format(appname, path.replace(os.sep, '<STR_LIT:.>')))<EOL><DEDENT><DEDENT>candidate_files = [<EOL>'<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>]<EOL>data_files = defaultdict(list)<EOL>for filename in candidate_files:<EOL><INDENT>if os.path.exists(srcfile(filename)):<EOL><INDENT>data_files['<STR_LIT>'].append(filename)<EOL><DEDENT><DEDENT>classifiers = []<EOL>for classifiers_txt in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>classifiers_txt = srcfile(classifiers_txt)<EOL>if os.path.exists(classifiers_txt):<EOL><INDENT>with open(classifiers_txt, encoding='<STR_LIT:utf-8>') as handle:<EOL><INDENT>classifiers = [i.strip() for i in handle if i.strip() and not i.startswith('<STR_LIT:#>')]<EOL><DEDENT>break<EOL><DEDENT><DEDENT>metadata.update(dict(<EOL>name = name,<EOL>package_dir = {'<STR_LIT>': '<STR_LIT:src>'},<EOL>packages = find_packages(srcfile('<STR_LIT:src>'), exclude=['<STR_LIT>']),<EOL>data_files = data_files.items(),<EOL>zip_safe = False,<EOL>include_package_data = True,<EOL>install_requires = requires['<STR_LIT>'],<EOL>setup_requires = requires['<STR_LIT>'],<EOL>tests_require =  requires['<STR_LIT:test>'],<EOL>classifiers = classifiers,<EOL>cmdclass = dict(<EOL>test = PyTest,<EOL>),<EOL>entry_points = dict(<EOL>console_scripts = console_scripts,<EOL>),<EOL>))<EOL>return metadata<EOL>


response = yield req<EOL>while response < <NUM_LIT:0>:<EOL><INDENT>try:<EOL><INDENT>response = yield '<STR_LIT>'<EOL><DEDENT>except GeneratorExit:<EOL><INDENT>return<EOL><DEDENT>except ValueError:<EOL><INDENT>yield '<STR_LIT>'<EOL><DEDENT><DEDENT>return response<EOL>


response = yield req<EOL>while response % <NUM_LIT:2>:<EOL><INDENT>try:<EOL><INDENT>response = yield '<STR_LIT>'<EOL><DEDENT>except GeneratorExit:<EOL><INDENT>return<EOL><DEDENT>except ValueError:<EOL><INDENT>yield '<STR_LIT>'<EOL><DEDENT><DEDENT>return response<EOL>


while val < <NUM_LIT:100>:<EOL><INDENT>try:<EOL><INDENT>sent = yield val<EOL><DEDENT>except GeneratorExit:<EOL><INDENT>return<EOL><DEDENT>except ValueError:<EOL><INDENT>sent = yield '<STR_LIT>'<EOL><DEDENT>except TypeError:<EOL><INDENT>return '<STR_LIT>'<EOL><DEDENT>if sent > val:<EOL><INDENT>val = sent<EOL><DEDENT><DEDENT>return val * <NUM_LIT:3><EOL>


response = yield req<EOL>while response < <NUM_LIT:0>:<EOL><INDENT>try:<EOL><INDENT>response = yield '<STR_LIT>'<EOL><DEDENT>except GeneratorExit:<EOL><INDENT>return<EOL><DEDENT>except ValueError:<EOL><INDENT>yield '<STR_LIT>'<EOL><DEDENT><DEDENT>return_(response)<EOL>


response = yield req<EOL>while response % <NUM_LIT:2>:<EOL><INDENT>try:<EOL><INDENT>response = yield '<STR_LIT>'<EOL><DEDENT>except GeneratorExit:<EOL><INDENT>return<EOL><DEDENT>except ValueError:<EOL><INDENT>yield '<STR_LIT>'<EOL><DEDENT><DEDENT>return_(response)<EOL>


while val < <NUM_LIT:100>:<EOL><INDENT>try:<EOL><INDENT>sent = yield val<EOL><DEDENT>except GeneratorExit:<EOL><INDENT>return<EOL><DEDENT>except ValueError:<EOL><INDENT>sent = yield '<STR_LIT>'<EOL><DEDENT>except TypeError:<EOL><INDENT>return_('<STR_LIT>')<EOL><DEDENT>if sent > val:<EOL><INDENT>val = sent<EOL><DEDENT><DEDENT>return_(val * <NUM_LIT:3>)<EOL>


gens = [getattr(common, name)]<EOL>if not PY2:<EOL><INDENT>from . import py3<EOL>gens.append(getattr(py3, name))<EOL><DEDENT>return pytest.mark.parametrize(name, gens)<EOL>


def wrapper(cls):<EOL><INDENT>orig_vars = cls.__dict__.copy()<EOL>slots = orig_vars.get('<STR_LIT>')<EOL>if slots is not None:<EOL><INDENT>if isinstance(slots, str):<EOL><INDENT>slots = [slots]<EOL><DEDENT>for slots_var in slots:<EOL><INDENT>orig_vars.pop(slots_var)<EOL><DEDENT><DEDENT>orig_vars.pop('<STR_LIT>', None)<EOL>orig_vars.pop('<STR_LIT>', None)<EOL>return metaclass(cls.__name__, cls.__bases__, orig_vars)<EOL><DEDENT>return wrapper<EOL>

Class decorator for creating a class with a metaclass.


raise NotImplementedError()<EOL>

Returns
-------
~typing.Generator[T_yield, T_send, T_return]
    the generator iterator


raise NotImplementedError()<EOL>

Returns
-------
~typing.Generator[T_yield, T_send, T_return]
    the resulting generator


copied = self.__signature__.bind(*self._bound_args.args,<EOL>**self._bound_args.kwargs)<EOL>copied.arguments.update(**kwargs)<EOL>return self.__class__(*copied.args, **copied.kwargs)<EOL>

create a new instance with certain fields replaced

        Parameters
        ----------
        **kwargs
            fields to replace

        Returns
        -------
        ReusableGenerator
            a copy with replaced fields


return compose(GeneratorProxy, func)<EOL>

Decorate a generator function to make it Python 2/3 compatible.
    Use together with :func:`return_`.

    Example
    -------

    >>> @py2_compatible
    ... def my_max(value):
    ...     while value < 100:
    ...         newvalue = yield value
    ...         if newvalue > value:
    ...             value = newvalue
    ...     return_(value)

    is equivalent to:

    >>> def my_max(value):
    ...     while value < 100:
    ...         newvalue = yield value
    ...         if newvalue > value:
    ...             value = newvalue
    ...     return value

    Note
    ----
    This is necessary because PEP479 makes it impossible to replace
    ``return`` with ``raise StopIteration`` in newer python 3 versions.

    Warning
    -------
    Although the wrapped generator acts like a generator,
    it is not an strict generator instance.
    For most purposes (e.g. ``yield from``) it works fine,
    but :func:`~inspect.isgenerator` will return ``False``.

    See also
    --------
    `PEP 479 <https://www.python.org/dev/peps/pep-0479/>`_


raise GeneratorReturn(value)<EOL>

Python 2/3 compatible way to return a value from a generator

    Use only with the :func:`py2_compatible` decorator


sig = signature(func)<EOL>origin = func<EOL>while hasattr(origin, '<STR_LIT>'):<EOL><INDENT>origin = origin.__wrapped__<EOL><DEDENT>return type(<EOL>origin.__name__,<EOL>(ReusableGenerator, ),<EOL>dict([<EOL>('<STR_LIT>',       origin.__doc__),<EOL>('<STR_LIT>',    origin.__module__),<EOL>('<STR_LIT>', sig),<EOL>('<STR_LIT>',   staticmethod(func)),<EOL>] + [<EOL>(name, property(compose(itemgetter(name),<EOL>attrgetter('<STR_LIT>'))))<EOL>for name in sig.parameters<EOL>] + ([<EOL>('<STR_LIT>',  origin.__qualname__),<EOL>] if sys.version_info > (<NUM_LIT:3>, ) else [])))<EOL>

Create a reusable class from a generator function

    Parameters
    ----------
    func: GeneratorCallable[T_yield, T_send, T_return]
        the function to wrap

    Note
    ----
    * the callable must have an inspectable signature
    * If bound to a class, the new reusable generator is callable as a method.
      To opt out of this, add a :func:`staticmethod` decorator above
      this decorator.


try:<EOL><INDENT>gen.send(value)<EOL><DEDENT>except StopIteration as e:<EOL><INDENT>return stopiter_value(e)<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError('<STR_LIT>')<EOL><DEDENT>

Send an item into a generator expecting a final return value

    Parameters
    ----------
    gen: ~typing.Generator[T_yield, T_send, T_return]
        the generator to send the value to
    value: T_send
        the value to send

    Raises
    ------
    RuntimeError
        if the generator did not return as expected

    Returns
    -------
    T_return
        the generator's return value


gen = iter(gen)<EOL>assert _is_just_started(gen)<EOL>yielder = yield_from(gen)<EOL>for item in yielder:<EOL><INDENT>with yielder:<EOL><INDENT>yielder.send((yield func(item)))<EOL><DEDENT><DEDENT>return_(yielder.result)<EOL>

Apply a function to all ``yield`` values of a generator

    Parameters
    ----------
    func: ~typing.Callable[[T_yield], T_mapped]
        the function to apply
    gen: Generable[T_yield, T_send, T_return]
        the generator iterable.

    Returns
    -------
    ~typing.Generator[T_mapped, T_send, T_return]
        the mapped generator


gen = iter(gen)<EOL>assert _is_just_started(gen)<EOL>yielder = yield_from(gen)<EOL>for item in yielder:<EOL><INDENT>with yielder:<EOL><INDENT>yielder.send(func((yield item)))<EOL><DEDENT><DEDENT>return_(yielder.result)<EOL>

Apply a function to all ``send`` values of a generator

    Parameters
    ----------
    func: ~typing.Callable[[T_send], T_mapped]
        the function to apply
    gen: Generable[T_yield, T_mapped, T_return]
        the generator iterable.

    Returns
    -------
    ~typing.Generator[T_yield, T_send, T_return]
        the mapped generator


gen = iter(gen)<EOL>assert _is_just_started(gen)<EOL>yielder = yield_from(gen)<EOL>for item in yielder:<EOL><INDENT>with yielder:<EOL><INDENT>yielder.send((yield item))<EOL><DEDENT><DEDENT>return_(func(yielder.result))<EOL>

Apply a function to the ``return`` value of a generator

    Parameters
    ----------
    func: ~typing.Callable[[T_return], T_mapped]
        the function to apply
    gen: Generable[T_yield, T_send, T_return]
        the generator iterable.

    Returns
    -------
    ~typing.Generator[T_yield, T_send, T_mapped]


gen = iter(gen)<EOL>assert _is_just_started(gen)<EOL>yielder = yield_from(gen)<EOL>for item in yielder:<EOL><INDENT>with yielder:<EOL><INDENT>subgen = thru(item)<EOL>subyielder = yield_from(subgen)<EOL>for subitem in subyielder:<EOL><INDENT>with subyielder:<EOL><INDENT>subyielder.send((yield subitem))<EOL><DEDENT><DEDENT>yielder.send(subyielder.result)<EOL><DEDENT><DEDENT>return_(yielder.result)<EOL>

Create a new generator by relaying yield/send interactions
    through another generator

    Parameters
    ----------
    gen: Generable[T_yield, T_send, T_return]
        the original generator
    thru: ~typing.Callable[[T_yield], ~typing.Generator]
        the generator callable through which each interaction is relayed

    Returns
    -------
    ~typing.Generator
        the relayed generator


pass<EOL>

Sub test classes can modify the blok here for testing, before all tests are ran


def decorator(blok):<EOL><INDENT>for name in names or (blok.__name__, ):<EOL><INDENT>self[name] = blok<EOL><DEDENT>return blok<EOL><DEDENT>return decorator<EOL>

Returns back a class decorator that enables registering Blox to this factory


def __call__(self, product_name, **properties):

if not product_name in self:<EOL><INDENT>return self.default(tag=product_name, **properties)<EOL><DEDENT>return self[product_name](**properties)<EOL>


def output(self, to=None, *args, **kwargs):

for blok in self:<EOL><INDENT>blok.output(to, *args, **kwargs)<EOL><DEDENT>return self<EOL>

Outputs to a stream (like a file or request)


render_to = StringIO()<EOL>self.output(render_to, *args, **kwargs)<EOL>return render_to.getvalue()<EOL>


def __new__(metaclass, name, parents, class_dict, *kargs, **kwargs):

attributes = {name: attribute for name, attribute in class_dict.items() if isinstance(attribute,<EOL>AbstractAttribute)}<EOL>if attributes:<EOL><INDENT>if hasattr(parents[<NUM_LIT:0>], '<STR_LIT>'):<EOL><INDENT>full_attributes = parents[<NUM_LIT:0>].attribute_descriptors.copy()<EOL>full_attributes.update(attributes)<EOL>attributes = full_attributes<EOL><DEDENT>blok_attributes = {}<EOL>render_attributes = []<EOL>direct_attributes = []<EOL>init_attributes = []<EOL>accessor_attributes = []<EOL>attribute_map = {}<EOL>for attribute_name, attribute in attributes.items():<EOL><INDENT>if not hasattr(attribute, '<STR_LIT:name>'):<EOL><INDENT>attribute.name = attribute_name<EOL><DEDENT>if isinstance(attribute, DirectAttribute):<EOL><INDENT>direct_attributes.append(attribute)<EOL>if hasattr(attribute, '<STR_LIT>'):<EOL><INDENT>render_attributes.append(attribute)<EOL><DEDENT>if not hasattr(attribute, '<STR_LIT>'):<EOL><INDENT>attribute.object_attribute = '<STR_LIT>'.format(attribute_name)<EOL><DEDENT>if getattr(attribute, '<STR_LIT>', False):<EOL><INDENT>init_attributes.append(attribute_name)<EOL><DEDENT><DEDENT>if isinstance(attribute, (BlokAttribute, NestedBlokAttribute)) and hasattr(attribute.type, '<STR_LIT>'):<EOL><INDENT>blok_attributes[attribute.type.tag] = attribute<EOL><DEDENT>if isinstance(attribute, AccessorAttribute):<EOL><INDENT>accessor_attributes.append(attribute)<EOL>if not hasattr(attribute, '<STR_LIT>'):<EOL><INDENT>attribute.parent_attribute = '<STR_LIT>'.format(attribute_name)<EOL><DEDENT><DEDENT>attribute_map[attribute.name] = attribute_name<EOL><DEDENT>if direct_attributes and not name == '<STR_LIT>' and '<STR_LIT>' in class_dict:<EOL><INDENT>class_dict['<STR_LIT>'] += tuple(attribute.object_attribute for attribute in direct_attributes)<EOL>class_dict['<STR_LIT>'] += tuple(attribute.parent_attribute for attribute in accessor_attributes)<EOL><DEDENT>if render_attributes:<EOL><INDENT>if hasattr(parents[<NUM_LIT:0>], '<STR_LIT>'):<EOL><INDENT>render_attributes = list(parents[<NUM_LIT:0>].render_attributes) + render_attributes<EOL><DEDENT>class_dict['<STR_LIT>'] = set(render_attributes)<EOL><DEDENT>if init_attributes:<EOL><INDENT>if hasattr(parents[<NUM_LIT:0>], '<STR_LIT>'):<EOL><INDENT>init_attributes = list(parents[<NUM_LIT:0>].init_attributes) + init_attributes<EOL><DEDENT>class_dict['<STR_LIT>'] = init_attributes<EOL><DEDENT>if blok_attributes:<EOL><INDENT>if hasattr(parents[<NUM_LIT:0>], '<STR_LIT>'):<EOL><INDENT>full_blok_attributes = dict(parents[<NUM_LIT:0>].blok_attributes)<EOL>full_blok_attributes.update(blok_attributes)<EOL>blok_attributes = full_blok_attributes<EOL><DEDENT>class_dict['<STR_LIT>'] = blok_attributes<EOL><DEDENT>if attribute_map:<EOL><INDENT>if hasattr(parents[<NUM_LIT:0>], '<STR_LIT>'):<EOL><INDENT>full_attribute_map = dict(parents[<NUM_LIT:0>].attribute_map)<EOL>full_attribute_map.update(attribute_map)<EOL>attribute_map = full_attribute_map<EOL><DEDENT>class_dict['<STR_LIT>'] = attribute_map<EOL><DEDENT>class_dict['<STR_LIT>'] = attributes<EOL>attribute_signals = (attribute.signal for attribute in attributes.values() if getattr(attribute, '<STR_LIT>'))<EOL>if attribute_signals:<EOL><INDENT>class_dict['<STR_LIT>'] = class_dict.get('<STR_LIT>', ()) + tuple(attribute_signals)<EOL><DEDENT><DEDENT>return super(TagAttributes, metaclass).__new__(metaclass, name, parents, class_dict, *kargs, **kwargs)<EOL>

Updates a tag class to automatically register all signals


to.write('<STR_LIT>')<EOL>return self<EOL>


return self<EOL>

Returns the container that should be responsible adding children, outside of init


if not hasattr(self, '<STR_LIT>'):<EOL><INDENT>self._blox = Blox()<EOL><DEDENT>return self._blox<EOL>

Lazily creates and returns the list of child blox


def __call__(self, *blox, position=None):

if position is not None:<EOL><INDENT>for blok in blox:<EOL><INDENT>self.blox_container.blox.insert(position, blok)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for blok in blox:<EOL><INDENT>self.blox_container.blox.append(blok)<EOL><DEDENT><DEDENT>return blok<EOL>


def output(self, to=None, formatted=False, indent=<NUM_LIT:0>, indentation='<STR_LIT:U+0020>', *args, **kwargs):

if formatted and self.blox:<EOL><INDENT>self.blox[<NUM_LIT:0>].output(to=to, formatted=True, indent=indent, indentation=indentation, *args, **kwargs)<EOL>for blok in self.blox[<NUM_LIT:1>:]:<EOL><INDENT>to.write('<STR_LIT:\n>')<EOL>to.write(indent * indentation)<EOL>blok.output(to=to, formatted=True, indent=indent, indentation=indentation, *args, **kwargs)<EOL><DEDENT>if not indent:<EOL><INDENT>to.write('<STR_LIT:\n>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for blok in self.blox:<EOL><INDENT>blok.output(to=to, *args, **kwargs)<EOL><DEDENT><DEDENT>return self<EOL>


if not hasattr(self, '<STR_LIT>'):<EOL><INDENT>self._attributes = {}<EOL><DEDENT>return self._attributes<EOL>

Lazily creates and returns a tags attributes


direct_attributes = (attribute.render(self) for attribute in self.render_attributes)<EOL>attributes = ()<EOL>if hasattr(self, '<STR_LIT>'):<EOL><INDENT>attributes = ('<STR_LIT>'.format(key, value)<EOL>for key, value in self.attributes.items() if value)<EOL><DEDENT>rendered_attributes = "<STR_LIT:U+0020>".join(filter(bool, chain(direct_attributes, attributes)))<EOL>return '<STR_LIT>'.format(self.tag, '<STR_LIT:U+0020>' if rendered_attributes else '<STR_LIT>',<EOL>rendered_attributes, '<STR_LIT>' if self.tag_self_closes else "<STR_LIT>")<EOL>


if self.tag_self_closes:<EOL><INDENT>return '<STR_LIT>'<EOL><DEDENT>return "<STR_LIT>".format(self.tag)<EOL>


to.write(self.start_tag)<EOL>if not self.tag_self_closes:<EOL><INDENT>to.write(self.end_tag)<EOL><DEDENT>


if formatted:<EOL><INDENT>to.write(self.start_tag)<EOL>to.write('<STR_LIT:\n>')<EOL>if not self.tag_self_closes:<EOL><INDENT>for blok in self.blox:<EOL><INDENT>to.write(indentation * (indent + <NUM_LIT:1>))<EOL>blok.output(to=to, indent=indent + <NUM_LIT:1>, formatted=True, indentation=indentation, *args, **kwargs)<EOL>to.write('<STR_LIT:\n>')<EOL><DEDENT><DEDENT>to.write(indentation * indent)<EOL>to.write(self.end_tag)<EOL>if not indentation:<EOL><INDENT>to.write('<STR_LIT:\n>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>to.write(self.start_tag)<EOL>if not self.tag_self_closes:<EOL><INDENT>for blok in self.blox:<EOL><INDENT>blok.output(to=to, *args, **kwargs)<EOL><DEDENT><DEDENT>to.write(self.end_tag)<EOL><DEDENT>


self.value = text<EOL>return self<EOL>


to.write(cgi.escape(str(self._value)))<EOL>


def string(html, start_on=None, ignore=(), use_short=True, **queries):

if use_short:<EOL><INDENT>html = grow_short(html)<EOL><DEDENT>return _to_template(fromstring(html), start_on=start_on,<EOL>ignore=ignore, **queries)<EOL>

Returns a blox template from an html string


def file(file_object, start_on=None, ignore=(), use_short=True, **queries):

return string(file_object.read(), start_on=start_on, ignore=ignore, use_short=use_short, **queries)<EOL>

Returns a blox template from a file stream object


def filename(file_name, start_on=None, ignore=(), use_short=True, **queries):

with open(file_name) as template_file:<EOL><INDENT>return file(template_file, start_on=start_on, ignore=ignore, use_short=use_short, **queries)<EOL><DEDENT>

Returns a blox template from a valid file path


def serve(self, sock, request_handler, error_handler, debug=False,<EOL>request_timeout=<NUM_LIT>, ssl=None, request_max_size=None,<EOL>reuse_port=False, loop=None, protocol=HttpProtocol,<EOL>backlog=<NUM_LIT:100>, **kwargs):

Start asynchronous HTTP Server on an individual process.

        :param request_handler: Sanic request handler with middleware
        :param error_handler: Sanic error handler with middleware
        :param debug: enables debug output (slows server)
        :param request_timeout: time in seconds
        :param ssl: SSLContext
        :param sock: Socket for the server to accept connections from
        :param request_max_size: size in bytes, `None` for no limit
        :param reuse_port: `True` for multiple workers
        :param loop: asyncio compatible event loop
        :param protocol: subclass of asyncio protocol class
        :return: Nothing


ctx = ssl.SSLContext(cfg.ssl_version)<EOL>ctx.load_cert_chain(cfg.certfile, cfg.keyfile)<EOL>ctx.verify_mode = cfg.cert_reqs<EOL>if cfg.ca_certs:<EOL><INDENT>ctx.load_verify_locations(cfg.ca_certs)<EOL><DEDENT>if cfg.ciphers:<EOL><INDENT>ctx.set_ciphers(cfg.ciphers)<EOL><DEDENT>return ctx<EOL>

Creates SSLContext instance for usage in asyncio.create_server.
        See ssl.SSLSocket.__init__ for more details.


for key, value in copy(kwargs).items():<EOL><INDENT>if value is None or value == ():<EOL><INDENT>kwargs.pop(key)<EOL><DEDENT>if hasattr(value, '<STR_LIT>'):<EOL><INDENT>kwargs[key] = value.read()<EOL><DEDENT><DEDENT>

Remove default values (anything where the value is None). click is unfortunately bad at the way it
        sends through unspecified defaults.


def _lookup(self, fail_on_missing=False, fail_on_found=False, include_debug_header=True, **kwargs):

read_params = {}<EOL>for field_name in self.identity:<EOL><INDENT>if field_name in kwargs:<EOL><INDENT>read_params[field_name] = kwargs[field_name]<EOL><DEDENT><DEDENT>if '<STR_LIT:id>' in self.identity and len(self.identity) == <NUM_LIT:1>:<EOL><INDENT>return {}<EOL><DEDENT>if not read_params:<EOL><INDENT>raise exc.BadRequest('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>try:<EOL><INDENT>existing_data = self.get(include_debug_header=include_debug_header, **read_params)<EOL>if fail_on_found:<EOL><INDENT>raise exc.Found('<STR_LIT>' %<EOL>read_params)<EOL><DEDENT>return existing_data<EOL><DEDENT>except exc.NotFound:<EOL><INDENT>if fail_on_missing:<EOL><INDENT>raise exc.NotFound('<STR_LIT>' %<EOL>read_params)<EOL><DEDENT>return {}<EOL><DEDENT>

=====API DOCS=====
Attempt to perform a lookup that is expected to return a single result, and return the record.

This method is a wrapper around `get` that strips out non-unique keys, and is used internally by
`write` and `delete`.

:param fail_on_missing: Flag that raise exception if no resource is found.
:type fail_on_missing: bool
:param fail_on_found: Flag that raise exception if a resource is found.
:type fail_on_found: bool
:param include_debug_header: Flag determining whether to print debug messages when querying
                             Tower backend.
:type include_debug_header: bool
:param `**kwargs`: Keyword arguments list of available fields used for searching resource.
:returns: A JSON object containing details of the resource returned by Tower backend.
:rtype: dict

:raises tower_cli.exceptions.BadRequest: When no field are provided in kwargs.
:raises tower_cli.exceptions.Found: When a resource is found and fail_on_found flag is on.
:raises tower_cli.exceptions.NotFound: When no resource is found and fail_on_missing flag
                                       is on.
=====API DOCS=====


for key in ('<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>if not kwargs.get(key):<EOL><INDENT>continue<EOL><DEDENT>match = re.search(r'<STR_LIT>', kwargs[key])<EOL>if match is None and key == '<STR_LIT>':<EOL><INDENT>kwargs[key] = <NUM_LIT:1><EOL>continue<EOL><DEDENT>kwargs[key] = int(match.groupdict()['<STR_LIT>'])<EOL><DEDENT>

Convert next and previous from URLs to integers


def read(self, pk=None, fail_on_no_results=False, fail_on_multiple_results=False, **kwargs):

<EOL>url = self.endpoint<EOL>if pk:<EOL><INDENT>url += '<STR_LIT>' % pk<EOL><DEDENT>queries = kwargs.pop('<STR_LIT>', [])<EOL>self._pop_none(kwargs)<EOL>for field in self.fields:<EOL><INDENT>if field.no_lookup and field.name in kwargs:<EOL><INDENT>kwargs.pop(field.name)<EOL><DEDENT><DEDENT>params = list(kwargs.items())<EOL>for query in queries:<EOL><INDENT>params.append((query[<NUM_LIT:0>], query[<NUM_LIT:1>]))<EOL><DEDENT>r = client.get(url, params=params)<EOL>resp = r.json()<EOL>if pk:<EOL><INDENT>return {'<STR_LIT:count>': <NUM_LIT:1>, '<STR_LIT>': [resp]}<EOL><DEDENT>if fail_on_no_results and resp['<STR_LIT:count>'] == <NUM_LIT:0>:<EOL><INDENT>raise exc.NotFound('<STR_LIT>')<EOL><DEDENT>if fail_on_multiple_results and resp['<STR_LIT:count>'] >= <NUM_LIT:2>:<EOL><INDENT>raise exc.MultipleResults('<STR_LIT>'<EOL>'<STR_LIT>' % resp['<STR_LIT:count>'])<EOL><DEDENT>return resp<EOL>

=====API DOCS=====
Retrieve and return objects from the Ansible Tower API.

:param pk: Primary key of the resource to be read. Tower CLI will only attempt to read that object
           if ``pk`` is provided (not ``None``).
:type pk: int
:param fail_on_no_results: Flag that if set, zero results is considered a failure case and raises
                           an exception; otherwise, empty list is returned. (Note: This is always True
                           if a primary key is included.)
:type fail_on_no_results: bool
:param fail_on_multiple_results: Flag that if set, at most one result is expected, and more results
                                 constitutes a failure case. (Note: This is meaningless if a primary
                                 key is included, as there can never be multiple results.)
:type fail_on_multiple_results: bool
:param query: Contains 2-tuples used as query parameters to filter resulting resource objects.
:type query: list
:param `**kwargs`: Keyword arguments which, all together, will be used as query parameters to filter
                   resulting resource objects.
:returns: loaded JSON from Tower backend response body.
:rtype: dict
:raises tower_cli.exceptions.BadRequest: When 2-tuples in ``query`` overlaps key-value pairs in
                                         ``**kwargs``.
:raises tower_cli.exceptions.NotFound: When no objects are found and ``fail_on_no_results`` flag is on.
:raises tower_cli.exceptions.MultipleResults: When multiple objects are found and
                                              ``fail_on_multiple_results`` flag is on.

=====API DOCS=====


return url + '<STR_LIT>' % pk<EOL>

Overwrite this method to handle specific corner cases to the url passed to PATCH method.


def write(self, pk=None, create_on_missing=False, fail_on_found=False, force_on_exists=True, **kwargs):

existing_data = {}<EOL>self._pop_none(kwargs)<EOL>if not pk:<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>existing_data = self._lookup(<EOL>fail_on_found=fail_on_found, fail_on_missing=not create_on_missing, include_debug_header=False,<EOL>**kwargs<EOL>)<EOL>if existing_data:<EOL><INDENT>pk = existing_data['<STR_LIT:id>']<EOL><DEDENT><DEDENT>else:<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>existing_data = self.get(pk)<EOL><DEDENT>missing_fields = []<EOL>for i in self.fields:<EOL><INDENT>if i.key not in kwargs and i.name not in kwargs and i.required:<EOL><INDENT>missing_fields.append(i.key or i.name)<EOL><DEDENT><DEDENT>if missing_fields and not pk:<EOL><INDENT>raise exc.BadRequest('<STR_LIT>' % '<STR_LIT:U+002CU+0020>'.join(missing_fields).replace('<STR_LIT:_>', '<STR_LIT:->'))<EOL><DEDENT>if pk and not force_on_exists:<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>', nl=<NUM_LIT:2>)<EOL>answer = OrderedDict((('<STR_LIT>', False), ('<STR_LIT:id>', pk)))<EOL>answer.update(existing_data)<EOL>return answer<EOL><DEDENT>if all([kwargs[k] == existing_data.get(k, None) for k in kwargs.keys()]):<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>', nl=<NUM_LIT:2>)<EOL>answer = OrderedDict((('<STR_LIT>', False), ('<STR_LIT:id>', pk)))<EOL>answer.update(existing_data)<EOL>return answer<EOL><DEDENT>for key in kwargs:<EOL><INDENT>if kwargs[key] == '<STR_LIT:null>':<EOL><INDENT>kwargs[key] = None<EOL><DEDENT><DEDENT>url = self.endpoint<EOL>method = '<STR_LIT:POST>'<EOL>if pk:<EOL><INDENT>url = self._get_patch_url(url, pk)<EOL>method = '<STR_LIT>'<EOL><DEDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>r = getattr(client, method.lower())(url, data=kwargs)<EOL>answer = OrderedDict((('<STR_LIT>', True), ('<STR_LIT:id>', r.json()['<STR_LIT:id>'])))<EOL>answer.update(r.json())<EOL>return answer<EOL>

=====API DOCS=====
Modify the given object using the Ansible Tower API.

:param pk: Primary key of the resource to be read. Tower CLI will only attempt to read that object
           if ``pk`` is provided (not ``None``).
:type pk: int
:param create_on_missing: Flag that if set, a new object is created if ``pk`` is not set and objects
                          matching the appropriate unique criteria is not found.
:type create_on_missing: bool
:param fail_on_found: Flag that if set, the operation fails if an object matching the unique criteria
                      already exists.
:type fail_on_found: bool
:param force_on_exists: Flag that if set, then if an object is modified based on matching via unique
                        fields (as opposed to the primary key), other fields are updated based on data
                        sent; If unset, then the non-unique values are only written in a creation case.
:type force_on_exists: bool
:param `**kwargs`: Keyword arguments which, all together, will be used as POST/PATCH body to create/modify
                   the resource object. if ``pk`` is not set, key-value pairs of ``**kwargs`` which are
                   also in resource's identity will be used to lookup existing reosource.
:returns: A dictionary combining the JSON output of the resource, as well as two extra fields: "changed",
          a flag indicating if the resource is created or successfully updated; "id", an integer which
          is the primary key of the specified object.
:rtype: dict
:raises tower_cli.exceptions.BadRequest: When required fields are missing in ``**kwargs`` when creating
                                         a new resource object.

=====API DOCS=====


@resources.command<EOL><INDENT>def delete(self, pk=None, fail_on_missing=False, **kwargs):<DEDENT>

<EOL>if not pk:<EOL><INDENT>existing_data = self._lookup(fail_on_missing=fail_on_missing, **kwargs)<EOL>if not existing_data:<EOL><INDENT>return {'<STR_LIT>': False}<EOL><DEDENT>pk = existing_data['<STR_LIT:id>']<EOL><DEDENT>url = '<STR_LIT>' % (self.endpoint, pk)<EOL>debug.log('<STR_LIT>' % url, fg='<STR_LIT>', bold=True)<EOL>try:<EOL><INDENT>client.delete(url)<EOL>return {'<STR_LIT>': True}<EOL><DEDENT>except exc.NotFound:<EOL><INDENT>if fail_on_missing:<EOL><INDENT>raise<EOL><DEDENT>return {'<STR_LIT>': False}<EOL><DEDENT>

Remove the given object.

        If `fail_on_missing` is True, then the object's not being found is considered a failure; otherwise,
        a success with no change is reported.

        =====API DOCS=====
        Remove the given object.

        :param pk: Primary key of the resource to be deleted.
        :type pk: int
        :param fail_on_missing: Flag that if set, the object's not being found is considered a failure; otherwise,
                                a success with no change is reported.
        :type fail_on_missing: bool
        :param `**kwargs`: Keyword arguments used to look up resource object to delete if ``pk`` is not provided.
        :returns: dictionary of only one field "changed", which is a flag indicating whether the specified resource
                  is successfully deleted.
        :rtype: dict

        =====API DOCS=====


@resources.command(ignore_defaults=True)<EOL><INDENT>def get(self, pk=None, **kwargs):<DEDENT>

if kwargs.pop('<STR_LIT>', True):<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL><DEDENT>response = self.read(pk=pk, fail_on_no_results=True, fail_on_multiple_results=True, **kwargs)<EOL>return response['<STR_LIT>'][<NUM_LIT:0>]<EOL>

Return one and exactly one object.

        Lookups may be through a primary key, specified as a positional argument, and/or through filters specified
        through keyword arguments.

        If the number of results does not equal one, raise an exception.

        =====API DOCS=====
        Retrieve one and exactly one object.

        :param pk: Primary key of the resource to be read. Tower CLI will only attempt to read *that* object
                   if ``pk`` is provided (not ``None``).
        :type pk: int
        :param `**kwargs`: Keyword arguments used to look up resource object to retrieve if ``pk`` is not provided.
        :returns: loaded JSON of the retrieved resource object.
        :rtype: dict

        =====API DOCS=====


@resources.command(ignore_defaults=True, no_args_is_help=False)<EOL><INDENT>@click.option('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', is_flag=True, default=False, show_default=True,<EOL>help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', default=<NUM_LIT:1>, type=int, show_default=True,<EOL>help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', type=int, show_default=True, required=False,<EOL>help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', '<STR_LIT>', required=False, nargs=<NUM_LIT:2>, multiple=True,<EOL>help='<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL>def list(self, all_pages=False, **kwargs):<DEDENT>

<EOL>if kwargs.get('<STR_LIT:status>', None) and '<STR_LIT:U+002C>' in kwargs['<STR_LIT:status>']:<EOL><INDENT>all_status = kwargs.pop('<STR_LIT:status>').strip('<STR_LIT:U+002C>').split('<STR_LIT:U+002C>')<EOL>queries = list(kwargs.pop('<STR_LIT>', ()))<EOL>for status in all_status:<EOL><INDENT>if status in STATUS_CHOICES:<EOL><INDENT>queries.append(('<STR_LIT>', status))<EOL><DEDENT>else:<EOL><INDENT>raise exc.TowerCLIError('<STR_LIT>'.format(status))<EOL><DEDENT><DEDENT>kwargs['<STR_LIT>'] = tuple(queries)<EOL><DEDENT>if all_pages:<EOL><INDENT>kwargs.pop('<STR_LIT>', None)<EOL>kwargs.pop('<STR_LIT>', None)<EOL><DEDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>response = self.read(**kwargs)<EOL>self._convert_pagenum(response)<EOL>if all_pages and response['<STR_LIT>']:<EOL><INDENT>cursor = copy(response)<EOL>while cursor['<STR_LIT>']:<EOL><INDENT>cursor = self.read(**dict(kwargs, page=cursor['<STR_LIT>']))<EOL>self._convert_pagenum(cursor)<EOL>response['<STR_LIT>'] += cursor['<STR_LIT>']<EOL>response['<STR_LIT:count>'] += cursor['<STR_LIT:count>']<EOL><DEDENT>response['<STR_LIT>'] = None<EOL><DEDENT>return response<EOL>

Return a list of objects.

        If one or more filters are provided through keyword arguments, filter the results accordingly.

        If no filters are provided, return all results.

        =====API DOCS=====
        Retrieve a list of objects.

        :param all_pages: Flag that if set, collect all pages of content from the API when returning results.
        :type all_pages: bool
        :param page: The page to show. Ignored if all_pages is set.
        :type page: int
        :param query: Contains 2-tuples used as query parameters to filter resulting resource objects.
        :type query: list
        :param `**kwargs`: Keyword arguments list of available fields used for searching resource objects.
        :returns: A JSON object containing details of all resource objects returned by Tower backend.
        :rtype: dict

        =====API DOCS=====


def _assoc(self, url_fragment, me, other):

<EOL>url = self.endpoint + '<STR_LIT>' % (me, url_fragment)<EOL>r = client.get(url, params={'<STR_LIT:id>': other}).json()<EOL>if r['<STR_LIT:count>'] > <NUM_LIT:0>:<EOL><INDENT>return {'<STR_LIT>': False}<EOL><DEDENT>r = client.post(url, data={'<STR_LIT>': True, '<STR_LIT:id>': other})<EOL>return {'<STR_LIT>': True}<EOL>

Associate the `other` record with the `me` record.


def _disassoc(self, url_fragment, me, other):

<EOL>url = self.endpoint + '<STR_LIT>' % (me, url_fragment)<EOL>r = client.get(url, params={'<STR_LIT:id>': other}).json()<EOL>if r['<STR_LIT:count>'] == <NUM_LIT:0>:<EOL><INDENT>return {'<STR_LIT>': False}<EOL><DEDENT>r = client.post(url, data={'<STR_LIT>': True, '<STR_LIT:id>': other})<EOL>return {'<STR_LIT>': True}<EOL>

Disassociate the `other` record from the `me` record.


@resources.command<EOL><INDENT>@click.option('<STR_LIT>', default=False, show_default=True, type=bool, is_flag=True,<EOL>help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', default=False, show_default=True, type=bool, is_flag=True,<EOL>help='<STR_LIT>'<EOL>'<STR_LIT>')<EOL>def create(self, **kwargs):<DEDENT>

return self.write(create_on_missing=True, **kwargs)<EOL>

Create an object.

        Fields in the resource's `identity` tuple are used for a lookup; if a match is found, then no-op
        (unless `force_on_exists` is set) but do not fail (unless `fail_on_found` is set).

        =====API DOCS=====
        Create an object.

        :param fail_on_found: Flag that if set, the operation fails if an object matching the unique criteria
                              already exists.
        :type fail_on_found: bool
        :param force_on_exists: Flag that if set, then if a match is found on unique fields, other fields will
                                be updated to the provided values.; If unset, a match causes the request to be
                                a no-op.
        :type force_on_exists: bool
        :param `**kwargs`: Keyword arguments which, all together, will be used as POST body to create the
                           resource object.
        :returns: A dictionary combining the JSON output of the created resource, as well as two extra fields:
                  "changed", a flag indicating if the resource is created successfully; "id", an integer which
                  is the primary key of the created object.
        :rtype: dict

        =====API DOCS=====


@resources.command(ignore_defaults=True)<EOL><INDENT>@click.option('<STR_LIT>', default=None,<EOL>help='<STR_LIT>'<EOL>'<STR_LIT>')<EOL>def copy(self, pk=None, new_name=None, **kwargs):<DEDENT>

orig = self.read(pk, fail_on_no_results=True, fail_on_multiple_results=True)<EOL>orig = orig['<STR_LIT>'][<NUM_LIT:0>]<EOL>self._pop_none(kwargs)<EOL>newresource = copy(orig)<EOL>newresource.pop('<STR_LIT:id>')<EOL>basename = newresource['<STR_LIT:name>'].split('<STR_LIT:@>', <NUM_LIT:1>)[<NUM_LIT:0>].strip()<EOL>for field in self.fields:<EOL><INDENT>if field.multiple and field.name in newresource:<EOL><INDENT>newresource[field.name] = (newresource.get(field.name),)<EOL><DEDENT><DEDENT>if new_name is None:<EOL><INDENT>newresource['<STR_LIT:name>'] = "<STR_LIT>" % (basename, time.strftime('<STR_LIT>'))<EOL>newresource.update(kwargs)<EOL>return self.write(create_on_missing=True, fail_on_found=True,<EOL>**newresource)<EOL><DEDENT>else:<EOL><INDENT>if kwargs:<EOL><INDENT>raise exc.TowerCLIError('<STR_LIT>'.format(kwargs.keys()))<EOL><DEDENT>copy_endpoint = '<STR_LIT>'.format(self.endpoint.strip('<STR_LIT:/>'), pk)<EOL>return client.post(copy_endpoint, data={'<STR_LIT:name>': new_name}).json()<EOL><DEDENT>

Copy an object.

        Only the ID is used for the lookup. All provided fields are used to override the old data from the
        copied resource.

        =====API DOCS=====
        Copy an object.

        :param pk: Primary key of the resource object to be copied
        :param new_name: The new name to give the resource if deep copying via the API
        :type pk: int
        :param `**kwargs`: Keyword arguments of fields whose given value will override the original value.
        :returns: loaded JSON of the copied new resource object.
        :rtype: dict

        =====API DOCS=====


@resources.command(ignore_defaults=True)<EOL><INDENT>@click.option('<STR_LIT>', default=False, show_default=True, type=bool, is_flag=True,<EOL>help='<STR_LIT>'<EOL>'<STR_LIT>')<EOL>def modify(self, pk=None, create_on_missing=False, **kwargs):<DEDENT>

return self.write(pk, create_on_missing=create_on_missing, force_on_exists=True, **kwargs)<EOL>

Modify an already existing object.

        Fields in the resource's `identity` tuple can be used in lieu of a primary key for a lookup; in such a case,
        only other fields are written.

        To modify unique fields, you must use the primary key for the lookup.

        =====API DOCS=====
        Modify an already existing object.

        :param pk: Primary key of the resource to be modified.
        :type pk: int
        :param create_on_missing: Flag that if set, a new object is created if ``pk`` is not set and objects
                                  matching the appropriate unique criteria is not found.
        :type create_on_missing: bool
        :param `**kwargs`: Keyword arguments which, all together, will be used as PATCH body to modify the
                           resource object. if ``pk`` is not set, key-value pairs of ``**kwargs`` which are
                           also in resource's identity will be used to lookup existing reosource.
        :returns: A dictionary combining the JSON output of the modified resource, as well as two extra fields:
                  "changed", a flag indicating if the resource is successfully updated; "id", an integer which
                  is the primary key of the updated object.
        :rtype: dict

        =====API DOCS=====


raise NotImplementedError('<STR_LIT>')<EOL>

A stub method requesting the status of the resource.


def last_job_data(self, pk=None, **kwargs):

ujt = self.get(pk, include_debug_header=True, **kwargs)<EOL>if '<STR_LIT>' in ujt['<STR_LIT>']:<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>return client.get(ujt['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:7>:]).json()<EOL><DEDENT>elif ujt['<STR_LIT>'].get('<STR_LIT>', None):<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>return client.get(ujt['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:7>:]).json()<EOL><DEDENT>else:<EOL><INDENT>raise exc.NotFound('<STR_LIT>')<EOL><DEDENT>

Internal utility function for Unified Job Templates. Returns data about the last job run off of that UJT


def lookup_stdout(self, pk=None, start_line=None, end_line=None, full=True):

stdout_url = '<STR_LIT>' % (self.unified_job_type, pk)<EOL>payload = {'<STR_LIT>': '<STR_LIT>', '<STR_LIT>': '<STR_LIT>', '<STR_LIT>': '<STR_LIT>'}<EOL>if start_line:<EOL><INDENT>payload['<STR_LIT>'] = start_line<EOL><DEDENT>if end_line:<EOL><INDENT>payload['<STR_LIT>'] = end_line<EOL><DEDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>resp = client.get(stdout_url, params=payload).json()<EOL>content = b64decode(resp['<STR_LIT:content>'])<EOL>return content.decode('<STR_LIT:utf-8>', '<STR_LIT:replace>')<EOL>

Internal utility function to return standard out. Requires the pk of a unified job.


@resources.command<EOL><INDENT>@click.option('<STR_LIT>', required=False, type=int, help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', required=False, type=int, help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', required=False, type=str, help='<STR_LIT>')<EOL>def stdout(self, pk, start_line=None, end_line=None, outfile=sys.stdout, **kwargs):<DEDENT>

<EOL>if self.unified_job_type != self.endpoint:<EOL><INDENT>unified_job = self.last_job_data(pk, **kwargs)<EOL>pk = unified_job['<STR_LIT:id>']<EOL><DEDENT>elif not pk:<EOL><INDENT>unified_job = self.get(**kwargs)<EOL>pk = unified_job['<STR_LIT:id>']<EOL><DEDENT>content = self.lookup_stdout(pk, start_line, end_line)<EOL>opened = False<EOL>if isinstance(outfile, six.string_types):<EOL><INDENT>outfile = open(outfile, '<STR_LIT:w>')<EOL>opened = True<EOL><DEDENT>if len(content) > <NUM_LIT:0>:<EOL><INDENT>click.echo(content, nl=<NUM_LIT:1>, file=outfile)<EOL><DEDENT>if opened:<EOL><INDENT>outfile.close()<EOL><DEDENT>return {"<STR_LIT>": False}<EOL>

Print out the standard out of a unified job to the command line or output file.
For Projects, print the standard out of most recent update.
For Inventory Sources, print standard out of most recent sync.
For Jobs, print the job's standard out.
For Workflow Jobs, print a status table of its jobs.

=====API DOCS=====
Print out the standard out of a unified job to the command line or output file.
For Projects, print the standard out of most recent update.
For Inventory Sources, print standard out of most recent sync.
For Jobs, print the job's standard out.
For Workflow Jobs, print a status table of its jobs.

:param pk: Primary key of the job resource object to be monitored.
:type pk: int
:param start_line: Line at which to start printing job output
:param end_line: Line at which to end printing job output
:param outfile: Alternative file than stdout to write job stdout to.
:type outfile: file
:param `**kwargs`: Keyword arguments used to look up job resource object to monitor if ``pk`` is
                   not provided.
:returns: A dictionary containing changed=False
:rtype: dict

=====API DOCS=====


@resources.command<EOL><INDENT>@click.option('<STR_LIT>', default=<NUM_LIT>, help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', required=False, type=int,<EOL>help='<STR_LIT>')<EOL>def monitor(self, pk, parent_pk=None, timeout=None, interval=<NUM_LIT:0.5>, outfile=sys.stdout, **kwargs):<DEDENT>

<EOL>if pk is None:<EOL><INDENT>pk = self.last_job_data(parent_pk, **kwargs)['<STR_LIT:id>']<EOL><DEDENT>job_endpoint = '<STR_LIT>' % (self.unified_job_type, pk)<EOL>self.wait(pk, exit_on=['<STR_LIT>', '<STR_LIT>'], outfile=outfile)<EOL>start = time.time()<EOL>start_line = <NUM_LIT:0><EOL>result = client.get(job_endpoint).json()<EOL>click.echo('<STR_LIT>', nl=<NUM_LIT:2>, file=outfile)<EOL>while not result['<STR_LIT>'] and result['<STR_LIT:status>'] != '<STR_LIT>':<EOL><INDENT>result = client.get(job_endpoint).json()<EOL>time.sleep(interval)<EOL>content = self.lookup_stdout(pk, start_line, full=False)<EOL>if not content.startswith("<STR_LIT>"):<EOL><INDENT>line_count = len(content.splitlines())<EOL>start_line += line_count<EOL>click.echo(content, nl=<NUM_LIT:0>, file=outfile)<EOL><DEDENT>if timeout and time.time() - start > timeout:<EOL><INDENT>raise exc.Timeout('<STR_LIT>')<EOL><DEDENT><DEDENT>if self.endpoint == '<STR_LIT>':<EOL><INDENT>click.echo(self.lookup_stdout(pk, start_line, full=True), nl=<NUM_LIT:1>)<EOL><DEDENT>click.echo('<STR_LIT>', nl=<NUM_LIT:2>, file=outfile)<EOL>if result['<STR_LIT>']:<EOL><INDENT>raise exc.JobFailure('<STR_LIT>')<EOL><DEDENT>answer = OrderedDict((('<STR_LIT>', True), ('<STR_LIT:id>', pk)))<EOL>answer.update(result)<EOL>if parent_pk:<EOL><INDENT>answer['<STR_LIT:id>'] = parent_pk<EOL><DEDENT>else:<EOL><INDENT>answer['<STR_LIT:id>'] = pk<EOL><DEDENT>return answer<EOL>

Stream the standard output from a job, project update, or inventory udpate.

=====API DOCS=====
Stream the standard output from a job run to stdout.

:param pk: Primary key of the job resource object to be monitored.
:type pk: int
:param parent_pk: Primary key of the unified job template resource object whose latest job run will be
                  monitored if ``pk`` is not set.
:type parent_pk: int
:param timeout: Number in seconds after which this method will time out.
:type timeout: float
:param interval: Polling interval to refresh content from Tower.
:type interval: float
:param outfile: Alternative file than stdout to write job stdout to.
:type outfile: file
:param `**kwargs`: Keyword arguments used to look up job resource object to monitor if ``pk`` is
                   not provided.
:returns: A dictionary combining the JSON output of the finished job resource object, as well as
          two extra fields: "changed", a flag indicating if the job resource object is finished
          as expected; "id", an integer which is the primary key of the job resource object being
          monitored.
:rtype: dict
:raises tower_cli.exceptions.Timeout: When monitor time reaches time out.
:raises tower_cli.exceptions.JobFailure: When the job being monitored runs into failure.

=====API DOCS=====


@resources.command<EOL><INDENT>@click.option('<STR_LIT>', default=<NUM_LIT:1>, help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', default=<NUM_LIT:30>, help='<STR_LIT>')<EOL>@click.option('<STR_LIT>', required=False, type=int,<EOL>help='<STR_LIT>')<EOL>def wait(self, pk, parent_pk=None, min_interval=<NUM_LIT:1>, max_interval=<NUM_LIT:30>, timeout=None, outfile=sys.stdout,<EOL>exit_on=['<STR_LIT>'], **kwargs):<DEDENT>

<EOL>if pk is None:<EOL><INDENT>pk = self.last_job_data(parent_pk, **kwargs)['<STR_LIT:id>']<EOL><DEDENT>job_endpoint = '<STR_LIT>' % (self.unified_job_type, pk)<EOL>dots = itertools.cycle([<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>])<EOL>longest_string = <NUM_LIT:0><EOL>interval = min_interval<EOL>start = time.time()<EOL>result = client.get(job_endpoint).json()<EOL>last_poll = time.time()<EOL>timeout_check = <NUM_LIT:0><EOL>while result['<STR_LIT:status>'] not in exit_on:<EOL><INDENT>if result['<STR_LIT>']:<EOL><INDENT>if is_tty(outfile) and not settings.verbose:<EOL><INDENT>secho('<STR_LIT:\r>' + '<STR_LIT:U+0020>' * longest_string + '<STR_LIT:\n>', file=outfile)<EOL><DEDENT>raise exc.JobFailure('<STR_LIT>')<EOL><DEDENT>if timeout and timeout_check - start > timeout:<EOL><INDENT>raise exc.Timeout('<STR_LIT>')<EOL><DEDENT>output = '<STR_LIT>' % (result['<STR_LIT:status>'], '<STR_LIT:.>' * next(dots))<EOL>if longest_string > len(output):<EOL><INDENT>output += '<STR_LIT:U+0020>' * (longest_string - len(output))<EOL><DEDENT>else:<EOL><INDENT>longest_string = len(output)<EOL><DEDENT>if is_tty(outfile) and not settings.verbose:<EOL><INDENT>secho(output, nl=False, file=outfile)<EOL><DEDENT>time.sleep(<NUM_LIT>)<EOL>timeout_check = time.time()<EOL>if timeout and timeout_check - start > timeout:<EOL><INDENT>last_poll -= interval<EOL><DEDENT>if time.time() - last_poll > interval:<EOL><INDENT>result = client.get(job_endpoint).json()<EOL>last_poll = time.time()<EOL>interval = min(interval * <NUM_LIT>, max_interval)<EOL>if not is_tty(outfile) or settings.verbose:<EOL><INDENT>click.echo('<STR_LIT>' % result['<STR_LIT:status>'], file=outfile)<EOL><DEDENT><DEDENT>if is_tty(outfile) and not settings.verbose:<EOL><INDENT>secho('<STR_LIT:\r>' + '<STR_LIT:U+0020>' * longest_string, file=outfile, nl=False)<EOL>secho('<STR_LIT:\r>', file=outfile, nl=False)<EOL><DEDENT><DEDENT>answer = OrderedDict((('<STR_LIT>', True), ('<STR_LIT:id>', pk)))<EOL>answer.update(result)<EOL>if parent_pk:<EOL><INDENT>answer['<STR_LIT:id>'] = parent_pk<EOL><DEDENT>else:<EOL><INDENT>answer['<STR_LIT:id>'] = pk<EOL><DEDENT>return answer<EOL>

Wait for a running job to finish. Blocks further input until the job completes (whether successfully
or unsuccessfully) and a final status can be given.

=====API DOCS=====
Wait for a job resource object to enter certain status.

:param pk: Primary key of the job resource object to wait.
:type pk: int
:param parent_pk: Primary key of the unified job template resource object whose latest job run will be
                  waited if ``pk`` is not set.
:type parent_pk: int
:param timeout: Number in seconds after which this method will time out.
:type timeout: float
:param min_interval: Minimum polling interval to request an update from Tower.
:type min_interval: float
:param max_interval: Maximum polling interval to request an update from Tower.
:type max_interval: float
:param outfile: Alternative file than stdout to write job status updates on.
:type outfile: file
:param exit_on: Job resource object statuses to wait on.
:type exit_on: array
:param `**kwargs`: Keyword arguments used to look up job resource object to wait if ``pk`` is
                   not provided.
:returns: A dictionary combining the JSON output of the status-changed job resource object, as well
          as two extra fields: "changed", a flag indicating if the job resource object is status-changed
          as expected; "id", an integer which is the primary key of the job resource object being
          status-changed.
:rtype: dict
:raises tower_cli.exceptions.Timeout: When wait time reaches time out.
:raises tower_cli.exceptions.JobFailure: When the job being waited on runs into failure.
=====API DOCS=====


@resources.command<EOL><INDENT>@click.option('<STR_LIT>', is_flag=True, default=False, help='<STR_LIT>')<EOL>def status(self, pk=None, detail=False, **kwargs):<DEDENT>

<EOL>self._pop_none(kwargs)<EOL>if not pk:<EOL><INDENT>job = self.get(include_debug_header=True, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>debug.log('<STR_LIT>', header='<STR_LIT>')<EOL>finished_endpoint = '<STR_LIT>' % (self.endpoint, pk)<EOL>job = client.get(finished_endpoint).json()<EOL><DEDENT>if detail:<EOL><INDENT>return job<EOL><DEDENT>return {<EOL>'<STR_LIT>': job['<STR_LIT>'],<EOL>'<STR_LIT>': job['<STR_LIT>'],<EOL>'<STR_LIT:status>': job['<STR_LIT:status>'],<EOL>}<EOL>

Print the current job status. This is used to check a running job. You can look up the job with
        the same parameters used for a get request.

        =====API DOCS=====
        Retrieve the current job status.

        :param pk: Primary key of the resource to retrieve status from.
        :type pk: int
        :param detail: Flag that if set, return the full JSON of the job resource rather than a status summary.
        :type detail: bool
        :param `**kwargs`: Keyword arguments used to look up resource object to retrieve status from if ``pk``
                           is not provided.
        :returns: full loaded JSON of the specified unified job if ``detail`` flag is on; trimed JSON containing
                  only "elapsed", "failed" and "status" fields of the unified job if ``detail`` flag is off.
        :rtype: dict

        =====API DOCS=====


@resources.command<EOL><INDENT>@click.option('<STR_LIT>', is_flag=True, default=False,<EOL>help='<STR_LIT>')<EOL>def cancel(self, pk=None, fail_if_not_running=False, **kwargs):<DEDENT>

<EOL>if not pk:<EOL><INDENT>existing_data = self.get(**kwargs)<EOL>pk = existing_data['<STR_LIT:id>']<EOL><DEDENT>cancel_endpoint = '<STR_LIT>' % (self.endpoint, pk)<EOL>try:<EOL><INDENT>client.post(cancel_endpoint)<EOL>changed = True<EOL><DEDENT>except exc.MethodNotAllowed:<EOL><INDENT>changed = False<EOL>if fail_if_not_running:<EOL><INDENT>raise exc.TowerCLIError('<STR_LIT>')<EOL><DEDENT><DEDENT>return {'<STR_LIT:status>': '<STR_LIT>', '<STR_LIT>': changed}<EOL>

Cancel a currently running job.

        Fails with a non-zero exit status if the job cannot be canceled.
        You must provide either a pk or parameters in the job's identity.

        =====API DOCS=====
        Cancel a currently running job.

        :param pk: Primary key of the job resource to restart.
        :type pk: int
        :param fail_if_not_running: Flag that if set, raise exception if the job resource cannot be canceled.
        :type fail_if_not_running: bool
        :param `**kwargs`: Keyword arguments used to look up job resource object to restart if ``pk`` is not
                           provided.
        :returns: A dictionary of two keys: "status", which is "canceled", and "changed", which indicates if
                  the job resource has been successfully canceled.
        :rtype: dict
        :raises tower_cli.exceptions.TowerCLIError: When the job resource cannot be canceled and
                                                    ``fail_if_not_running`` flag is on.
        =====API DOCS=====


@resources.command<EOL><INDENT>def relaunch(self, pk=None, **kwargs):<DEDENT>

<EOL>if not pk:<EOL><INDENT>existing_data = self.get(**kwargs)<EOL>pk = existing_data['<STR_LIT:id>']<EOL><DEDENT>relaunch_endpoint = '<STR_LIT>' % (self.endpoint, pk)<EOL>data = {}<EOL>answer = {}<EOL>try:<EOL><INDENT>result = client.post(relaunch_endpoint, data=data).json()<EOL>if '<STR_LIT:id>' in result:<EOL><INDENT>answer.update(result)<EOL><DEDENT>answer['<STR_LIT>'] = True<EOL><DEDENT>except exc.MethodNotAllowed:<EOL><INDENT>answer['<STR_LIT>'] = False<EOL><DEDENT>return answer<EOL>

Relaunch a stopped job.

        Fails with a non-zero exit status if the job cannot be relaunched.
        You must provide either a pk or parameters in the job's identity.

        =====API DOCS=====
        Relaunch a stopped job resource.

        :param pk: Primary key of the job resource to relaunch.
        :type pk: int
        :param `**kwargs`: Keyword arguments used to look up job resource object to relaunch if ``pk`` is not
                           provided.
        :returns: A dictionary combining the JSON output of the relaunched job resource object, as well
                  as an extra field "changed", a flag indicating if the job resource object is status-changed
                  as expected.
        :rtype: dict

        =====API DOCS=====


@resources.command<EOL><INDENT>def survey(self, pk=None, **kwargs):<DEDENT>

job_template = self.get(pk=pk, **kwargs)<EOL>if settings.format == '<STR_LIT>':<EOL><INDENT>settings.format = '<STR_LIT>'<EOL><DEDENT>return client.get(self._survey_endpoint(job_template['<STR_LIT:id>'])).json()<EOL>

Get the survey_spec for the job template.
        To write a survey, use the modify command with the --survey-spec parameter.

        =====API DOCS=====
        Get the survey specification of a resource object.

        :param pk: Primary key of the resource to retrieve survey from. Tower CLI will only attempt to
                   read *that* object if ``pk`` is provided (not ``None``).
        :type pk: int
        :param `**kwargs`: Keyword arguments used to look up resource object to retrieve survey if ``pk``
                           is not provided.
        :returns: loaded JSON of the retrieved survey specification of the resource object.
        :rtype: dict
        =====API DOCS=====


if self.help_text:<EOL><INDENT>return self.help_text<EOL><DEDENT>return '<STR_LIT>' % self.name<EOL>

Return the help text that was passed to the constructor, or a
        sensible default if none was provided.


return '<STR_LIT>' + self.name.replace('<STR_LIT:_>', '<STR_LIT:->')<EOL>

Return the field name as a bash option string
        (e.g. "--field-name").


def configure_model(self, attrs, field_name):

self.relationship = field_name<EOL>self._set_method_names(relationship=field_name)<EOL>if self.res_name is None:<EOL><INDENT>self.res_name = grammar.singularize(attrs.get('<STR_LIT>', '<STR_LIT>').strip('<STR_LIT:/>'))<EOL><DEDENT>

Hook for ResourceMeta class to call when initializing model class.
Saves fields obtained from resource class backlinks


def method(res_self, **kwargs):<EOL><INDENT>obj_pk = kwargs.get(method._res_name)<EOL>other_obj_pk = kwargs.get(method._other_name)<EOL>internal_method = getattr(res_self, method._internal_name)<EOL>return internal_method(method._relationship, obj_pk, other_obj_pk)<EOL><DEDENT>return method<EOL>

Returns a callable which becomes the associate or disassociate
method for the related field.
Method can be overridden to add additional functionality, but
`_produce_method` may also need to be subclassed to decorate
it appropriately.


return '<STR_LIT:{>' + '<STR_LIT:U+002CU+0020>'.join(['<STR_LIT>' % (k, v)<EOL>for k, v in self.items()]) + '<STR_LIT:}>'<EOL>

Print a repr that resembles dict's repr, but preserves
        key order.


return_dict = {}<EOL>if var_string is None:<EOL><INDENT>return {}<EOL><DEDENT>fix_encoding_26 = False<EOL>if sys.version_info < (<NUM_LIT:2>, <NUM_LIT:7>) and '<STR_LIT:\x00>' in shlex.split(u'<STR_LIT:a>')[<NUM_LIT:0>]:<EOL><INDENT>fix_encoding_26 = True<EOL><DEDENT>is_unicode = False<EOL>if fix_encoding_26 or not isinstance(var_string, str):<EOL><INDENT>if isinstance(var_string, six.text_type):<EOL><INDENT>var_string = var_string.encode('<STR_LIT>')<EOL>is_unicode = True<EOL><DEDENT>else:<EOL><INDENT>var_string = str(var_string)<EOL><DEDENT><DEDENT>for token in shlex.split(var_string):<EOL><INDENT>if (is_unicode):<EOL><INDENT>token = token.decode('<STR_LIT>')<EOL><DEDENT>if fix_encoding_26:<EOL><INDENT>token = six.text_type(token)<EOL><DEDENT>if '<STR_LIT:=>' in token:<EOL><INDENT>(k, v) = token.split('<STR_LIT:=>', <NUM_LIT:1>)<EOL>if len(k) == <NUM_LIT:0> or len(v) == <NUM_LIT:0>:<EOL><INDENT>raise Exception<EOL><DEDENT>try:<EOL><INDENT>return_dict[k] = ast.literal_eval(v)<EOL><DEDENT>except Exception:<EOL><INDENT>return_dict[k] = v<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise Exception<EOL><DEDENT><DEDENT>return return_dict<EOL>

Similar to the Ansible function of the same name, parses file
    with a key=value pattern and stores information in a dictionary,
    but not as fully featured as the corresponding Ansible code.


def string_to_dict(var_string, allow_kv=True, require_dict=True):

<EOL>try:<EOL><INDENT>return_dict = yaml.load(var_string, Loader=yaml.SafeLoader)<EOL>if require_dict:<EOL><INDENT>assert type(return_dict) is dict<EOL><DEDENT><DEDENT>except (AttributeError, yaml.YAMLError, AssertionError):<EOL><INDENT>try:<EOL><INDENT>assert allow_kv<EOL>return_dict = parse_kv(var_string)<EOL><DEDENT>except Exception:<EOL><INDENT>raise exc.TowerCLIError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % var_string<EOL>)<EOL><DEDENT><DEDENT>return return_dict<EOL>

Returns a dictionary given a string with yaml or json syntax.
    If data is not present in a key: value format, then it return
    an empty dictionary.

    Attempts processing string by 3 different methods in order:
        1. as JSON      2. as YAML      3. as custom key=value syntax
    Throws an error if all of these fail in the standard ways.


<EOL>extra_vars = {}<EOL>extra_vars_yaml = "<STR_LIT>"<EOL>for extra_vars_opt in extra_vars_list:<EOL><INDENT>if extra_vars_opt.startswith("<STR_LIT:@>"):<EOL><INDENT>with open(extra_vars_opt[<NUM_LIT:1>:], '<STR_LIT:r>') as f:<EOL><INDENT>extra_vars_opt = f.read()<EOL><DEDENT>opt_dict = string_to_dict(extra_vars_opt, allow_kv=False)<EOL><DEDENT>else:<EOL><INDENT>opt_dict = string_to_dict(extra_vars_opt, allow_kv=True)<EOL><DEDENT>if any(line.startswith("<STR_LIT:#>") for line in extra_vars_opt.split('<STR_LIT:\n>')):<EOL><INDENT>extra_vars_yaml += extra_vars_opt + "<STR_LIT:\n>"<EOL><DEDENT>elif extra_vars_opt != "<STR_LIT>":<EOL><INDENT>extra_vars_yaml += yaml.dump(<EOL>opt_dict, default_flow_style=False) + "<STR_LIT:\n>"<EOL><DEDENT>extra_vars.update(opt_dict)<EOL><DEDENT>if not force_json:<EOL><INDENT>try:<EOL><INDENT>try_dict = yaml.load(extra_vars_yaml, Loader=yaml.SafeLoader)<EOL>assert type(try_dict) is dict<EOL>debug.log('<STR_LIT>', header='<STR_LIT>', nl=<NUM_LIT:2>)<EOL>return extra_vars_yaml.rstrip()<EOL><DEDENT>except Exception:<EOL><INDENT>debug.log('<STR_LIT>',<EOL>header='<STR_LIT>', nl=<NUM_LIT:2>)<EOL><DEDENT><DEDENT>if extra_vars == {}:<EOL><INDENT>return "<STR_LIT>"<EOL><DEDENT>return json.dumps(extra_vars, ensure_ascii=False)<EOL>

Returns a string that is valid JSON or YAML and contains all the
    variables in every extra_vars_opt inside of extra_vars_list.

    Args:
       parse_kv (bool): whether to allow key=value syntax.
       force_json (bool): if True, always output json.


def ordered_dump(data, Dumper=yaml.Dumper, **kws):

class OrderedDumper(Dumper):<EOL><INDENT>pass<EOL><DEDENT>def _dict_representer(dumper, data):<EOL><INDENT>return dumper.represent_mapping(<EOL>yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,<EOL>data.items())<EOL><DEDENT>OrderedDumper.add_representer(OrderedDict,<EOL>_dict_representer)<EOL>return yaml.dump(data, None, OrderedDumper, **kws)<EOL>

Expand PyYAML's built-in dumper to support parsing OrderedDict. Return
    a string as parse result of the original data structure, which includes
    OrderedDict.

    Args:
        data: the data structure to be dumped(parsed) which is supposed to
        contain OrderedDict.
        Dumper: the yaml serializer to be expanded and used.
        kws: extra key-value arguments to be passed to yaml.dump.


<EOL>if not settings.color:<EOL><INDENT>for key in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>kwargs.pop(key, None)<EOL><DEDENT><DEDENT>return click.secho(message, **kwargs)<EOL>

A wrapper around click.secho that disables any coloring being used
    if colors have been disabled.


def log(s, header='<STR_LIT>', file=sys.stderr, nl=<NUM_LIT:1>, **kwargs):

<EOL>if not settings.verbose:<EOL><INDENT>return<EOL><DEDENT>if header:<EOL><INDENT>word_arr = s.split('<STR_LIT:U+0020>')<EOL>multi = []<EOL>word_arr.insert(<NUM_LIT:0>, '<STR_LIT>' % header.upper())<EOL>i = <NUM_LIT:0><EOL>while i < len(word_arr):<EOL><INDENT>to_add = ['<STR_LIT>']<EOL>count = <NUM_LIT:3><EOL>while count <= <NUM_LIT>:<EOL><INDENT>count += len(word_arr[i]) + <NUM_LIT:1><EOL>if count <= <NUM_LIT>:<EOL><INDENT>to_add.append(word_arr[i])<EOL>i += <NUM_LIT:1><EOL>if i == len(word_arr):<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>if len(to_add) == <NUM_LIT:1>:<EOL><INDENT>to_add.append(word_arr[i])<EOL>i += <NUM_LIT:1><EOL><DEDENT>if i != len(word_arr):<EOL><INDENT>count -= len(word_arr[i]) + <NUM_LIT:1><EOL><DEDENT>to_add.append('<STR_LIT:*>' * (<NUM_LIT> - count))<EOL>multi.append('<STR_LIT:U+0020>'.join(to_add))<EOL><DEDENT>s = '<STR_LIT:\n>'.join(multi)<EOL>lines = len(multi)<EOL><DEDENT>else:<EOL><INDENT>lines = <NUM_LIT:1><EOL><DEDENT>if isinstance(nl, int) and nl > lines:<EOL><INDENT>s += '<STR_LIT:\n>' * (nl - lines)<EOL><DEDENT>return secho(s, file=file, **kwargs)<EOL>

Log the given output to stderr if and only if we are in
    verbose mode.

    If we are not in verbose mode, this is a no-op.


jt_dec = click.option(<EOL>'<STR_LIT>', type=types.Related('<STR_LIT>'),<EOL>help='<STR_LIT>')<EOL>prj_dec = click.option(<EOL>'<STR_LIT>', type=types.Related('<STR_LIT>'),<EOL>help='<STR_LIT>')<EOL>inv_src_dec = click.option(<EOL>'<STR_LIT>', type=types.Related('<STR_LIT>'),<EOL>help='<STR_LIT>')<EOL>def ujt_translation(_method):<EOL><INDENT>def _ujt_translation(*args, **kwargs):<EOL><INDENT>for fd in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>if fd in kwargs and kwargs[fd] is not None:<EOL><INDENT>kwargs['<STR_LIT>'] = kwargs.pop(fd)<EOL><DEDENT><DEDENT>return _method(*args, **kwargs)<EOL><DEDENT>return functools.wraps(_method)(_ujt_translation)<EOL><DEDENT>return ujt_translation(<EOL>inv_src_dec(<EOL>prj_dec(<EOL>jt_dec(<EOL>method<EOL>)<EOL>)<EOL>)<EOL>)<EOL>

Adds the decorators for all types of unified job templates,
and if the non-unified type is specified, converts it into the
unified_job_template kwarg.


module = importlib.import_module('<STR_LIT>' % name)<EOL>return module.Resource()<EOL>

Return an instance of the requested Resource class.

    Since all of the resource classes are named `Resource`, this provides
    a slightly cleaner interface for using these classes via. importing rather
    than through the CLI.


<EOL>click.echo('<STR_LIT>' % __version__)<EOL>click.echo('<STR_LIT>' % CUR_API_VERSION)<EOL>try:<EOL><INDENT>r = client.get('<STR_LIT>')<EOL><DEDENT>except RequestException as ex:<EOL><INDENT>raise exc.TowerCLIError('<STR_LIT>' %<EOL>six.text_type(ex))<EOL><DEDENT>config = r.json()<EOL>license = config.get('<STR_LIT>', {}).get('<STR_LIT>', '<STR_LIT>')<EOL>if license == '<STR_LIT>':<EOL><INDENT>server_type = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>server_type = '<STR_LIT>'<EOL><DEDENT>click.echo('<STR_LIT>' % (server_type, config['<STR_LIT:version>']))<EOL>click.echo('<STR_LIT>' % config['<STR_LIT>'])<EOL>


value = getattr(settings, key)<EOL>secho('<STR_LIT>' % key, fg='<STR_LIT>', bold=True, nl=False)<EOL>secho(<EOL>six.text_type(value),<EOL>bold=True,<EOL>fg='<STR_LIT>' if isinstance(value, six.text_type) else '<STR_LIT>',<EOL>)<EOL>


<EOL>if global_:<EOL><INDENT>scope = '<STR_LIT>'<EOL>warnings.warn('<STR_LIT>'<EOL>'<STR_LIT>',<EOL>DeprecationWarning)<EOL><DEDENT>if not key:<EOL><INDENT>seen = set()<EOL>parser_desc = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>',<EOL>'<STR_LIT:user>': '<STR_LIT>'<EOL>'<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'<EOL>'<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}<EOL>click.echo('<STR_LIT>')<EOL>for name, parser in zip(settings._parser_names, settings._parsers):<EOL><INDENT>will_echo = False<EOL>for option in parser.options('<STR_LIT>'):<EOL><INDENT>if option in seen:<EOL><INDENT>continue<EOL><DEDENT>will_echo = True<EOL><DEDENT>if will_echo:<EOL><INDENT>secho('<STR_LIT>' % parser_desc[name], fg='<STR_LIT>', bold=True)<EOL><DEDENT>for option in parser.options('<STR_LIT>'):<EOL><INDENT>if option in seen:<EOL><INDENT>continue<EOL><DEDENT>_echo_setting(option)<EOL>seen.add(option)<EOL><DEDENT>if will_echo:<EOL><INDENT>click.echo('<STR_LIT>')<EOL><DEDENT><DEDENT>return<EOL><DEDENT>if not hasattr(settings, key):<EOL><INDENT>raise exc.TowerCLIError('<STR_LIT>' % key)<EOL><DEDENT>if value and unset:<EOL><INDENT>raise exc.UsageError('<STR_LIT>')<EOL><DEDENT>if key and not value and not unset:<EOL><INDENT>_echo_setting(key)<EOL>return<EOL><DEDENT>filename = os.path.expanduser('<STR_LIT>')<EOL>if scope == '<STR_LIT>':<EOL><INDENT>if not os.path.isdir('<STR_LIT>'):<EOL><INDENT>raise exc.TowerCLIError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>filename = '<STR_LIT>'<EOL><DEDENT>elif scope == '<STR_LIT>':<EOL><INDENT>filename = '<STR_LIT>'<EOL><DEDENT>parser = Parser()<EOL>parser.add_section('<STR_LIT>')<EOL>parser.read(filename)<EOL>if unset:<EOL><INDENT>parser.remove_option('<STR_LIT>', key)<EOL><DEDENT>else:<EOL><INDENT>parser.set('<STR_LIT>', key, value)<EOL><DEDENT>with open(filename, '<STR_LIT:w>') as config_file:<EOL><INDENT>parser.write(config_file)<EOL><DEDENT>try:<EOL><INDENT>os.chmod(filename, stat.S_IRUSR | stat.S_IWUSR)<EOL><DEDENT>except Exception as e:<EOL><INDENT>warnings.warn(<EOL>'<STR_LIT>'.format(filename, e),<EOL>UserWarning<EOL>)<EOL><DEDENT>click.echo('<STR_LIT>')<EOL>

Read or write tower-cli configuration.

    `tower config` saves the given setting to the appropriate Tower CLI;
    either the user's ~/.tower_cli.cfg file, or the /etc/tower/tower_cli.cfg
    file if --global is used.

    Writing to /etc/tower/tower_cli.cfg is likely to require heightened
    permissions (in other words, sudo).


@click.command()<EOL>@click.argument('<STR_LIT:username>', required=True)<EOL>@click.option('<STR_LIT>', required=True, prompt=True, hide_input=True)<EOL>@click.option('<STR_LIT>', required=False)<EOL>@click.option('<STR_LIT>', required=False)<EOL>@click.option('<STR_LIT>', required=False, default='<STR_LIT>',<EOL>type=click.Choice(['<STR_LIT>', '<STR_LIT>']))<EOL>@click.option('<STR_LIT>', '<STR_LIT>', default=None,<EOL>help='<STR_LIT>', is_flag=True,<EOL>required=False, callback=_apply_runtime_setting, is_eager=True)<EOL>def login(username, password, scope, client_id, client_secret, verbose):

if not supports_oauth():<EOL><INDENT>raise exc.TowerCLIError(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>req = collections.namedtuple('<STR_LIT>', '<STR_LIT>')({})<EOL>if client_id and client_secret:<EOL><INDENT>HTTPBasicAuth(client_id, client_secret)(req)<EOL>req.headers['<STR_LIT:Content-Type>'] = '<STR_LIT>'<EOL>r = client.post(<EOL>'<STR_LIT>',<EOL>data={<EOL>"<STR_LIT>": "<STR_LIT:password>",<EOL>"<STR_LIT:username>": username,<EOL>"<STR_LIT:password>": password,<EOL>"<STR_LIT>": scope<EOL>},<EOL>headers=req.headers<EOL>)<EOL><DEDENT>elif client_id:<EOL><INDENT>req.headers['<STR_LIT:Content-Type>'] = '<STR_LIT>'<EOL>r = client.post(<EOL>'<STR_LIT>',<EOL>data={<EOL>"<STR_LIT>": "<STR_LIT:password>",<EOL>"<STR_LIT:username>": username,<EOL>"<STR_LIT:password>": password,<EOL>"<STR_LIT>": client_id,<EOL>"<STR_LIT>": scope<EOL>},<EOL>headers=req.headers<EOL>)<EOL><DEDENT>else:<EOL><INDENT>HTTPBasicAuth(username, password)(req)<EOL>r = client.post(<EOL>'<STR_LIT>'.format(username),<EOL>data={"<STR_LIT:description>": "<STR_LIT>", "<STR_LIT>": None, "<STR_LIT>": scope},<EOL>headers=req.headers<EOL>)<EOL><DEDENT>if r.ok:<EOL><INDENT>result = r.json()<EOL>result.pop('<STR_LIT>', None)<EOL>result.pop('<STR_LIT>', None)<EOL>if client_id:<EOL><INDENT>token = result.pop('<STR_LIT>', None)<EOL><DEDENT>else:<EOL><INDENT>token = result.pop('<STR_LIT>', None)<EOL><DEDENT>if settings.verbose:<EOL><INDENT>result['<STR_LIT>'] = token<EOL><DEDENT>secho(json.dumps(result, indent=<NUM_LIT:1>), fg='<STR_LIT>', bold=True)<EOL>config.main(['<STR_LIT>', token, '<STR_LIT>'])<EOL><DEDENT>

Retrieves and stores an OAuth2 personal auth token.


if not supports_oauth():<EOL><INDENT>raise exc.TowerCLIError(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>config.main(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL>

Removes an OAuth2 personal auth token from config.