def _parseRequestValues(self, request, command):

for key, ampType in command.arguments:<EOL><INDENT>ampClass = ampType.__class__<EOL>if ampClass is exposed.ExposedResponderLocator:<EOL><INDENT>request[key] = self._remote<EOL>continue<EOL><DEDENT>decoder = _decoders.get(ampClass)<EOL>if decoder is not None:<EOL><INDENT>value = request.get(key)<EOL>request[key] = decoder(value, self)<EOL><DEDENT><DEDENT>

Parses all the values in the request that are in a form specific
        to the JSON AMP dialect.


def _runResponder(self, responder, request, command, identifier):

d = defer.maybeDeferred(responder, **request)<EOL>def _addIdentifier(response):<EOL><INDENT>"""<STR_LIT>"""<EOL>response["<STR_LIT>"] = identifier<EOL>return response<EOL><DEDENT>def _serializeFailure(failure):<EOL><INDENT>"""<STR_LIT>"""<EOL>key = failure.trap(*command.allErrors)<EOL>response = {<EOL>"<STR_LIT>": command.allErrors[key],<EOL>"<STR_LIT>": str(failure.value),<EOL>"<STR_LIT>": identifier<EOL>}<EOL>return response<EOL><DEDENT>d.addCallbacks(_addIdentifier, _serializeFailure)<EOL>return d<EOL>

Run the responser function. If it succeeds, add the _answer key.
        If it fails with an error known to the command, serialize the
        error.


encoded = dumps(response, default=_default)<EOL>self.transport.write(encoded)<EOL>

Serializes the response to JSON, and writes it to the transport.


self._remote.boxReceiver.stopReceivingBoxes(reason)<EOL>return basic.NetstringReceiver.connectionLost(self, reason)<EOL>

Tells the box receiver to stop receiving boxes.


self._factory = factory<EOL>


proto = self._factory.buildProtocol(addr)<EOL>return JSONAMPDialectReceiver(proto)<EOL>

Builds a bridge and associates it with an AMP protocol instance.


log.msg("<STR_LIT>")<EOL>localFactory = multiplexing.ProxyingFactory(client, "<STR_LIT:hello>")<EOL>return listeningEndpoint.listen(localFactory)<EOL>

Connected to AMP server, start listening locally, and give the AMP
client a reference to the local listening factory.


def render_ditaa(self, code, options, prefix='<STR_LIT>'):

hashkey = code.encode('<STR_LIT:utf-8>') + str(options) +str(self.builder.config.ditaa) +str(self.builder.config.ditaa_args)<EOL>infname = '<STR_LIT>' % (prefix, sha(hashkey).hexdigest(), "<STR_LIT>")<EOL>outfname = '<STR_LIT>' % (prefix, sha(hashkey).hexdigest(), "<STR_LIT>")<EOL>inrelfn = posixpath.join(self.builder.imgpath, infname)<EOL>infullfn = path.join(self.builder.outdir, '<STR_LIT>', infname)<EOL>outrelfn = posixpath.join(self.builder.imgpath, outfname)<EOL>outfullfn = path.join(self.builder.outdir, '<STR_LIT>', outfname)<EOL>if path.isfile(outfullfn):<EOL><INDENT>return outrelfn, outfullfn<EOL><DEDENT>ensuredir(path.dirname(outfullfn))<EOL>if isinstance(code, str):<EOL><INDENT>code = code.encode('<STR_LIT:utf-8>')<EOL><DEDENT>ditaa_args = [self.builder.config.ditaa]<EOL>ditaa_args.extend(self.builder.config.ditaa_args)<EOL>ditaa_args.extend(options)<EOL>ditaa_args.extend( [infullfn] )<EOL>ditaa_args.extend( [outfullfn] )<EOL>f = open(infullfn, '<STR_LIT:w>')<EOL>f.write(code)<EOL>f.close()<EOL>try:<EOL><INDENT>self.builder.warn(ditaa_args)<EOL>p = Popen(ditaa_args, stdout=PIPE, stdin=PIPE, stderr=PIPE)<EOL><DEDENT>except OSError as err:<EOL><INDENT>if err.errno != ENOENT:   <EOL><INDENT>raise<EOL><DEDENT>self.builder.warn('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>self.builder.config.ditaa)<EOL>self.builder._ditaa_warned_dot = True<EOL>return None, None<EOL><DEDENT>wentWrong = False<EOL>try:<EOL><INDENT>stdout, stderr = p.communicate(code)<EOL><DEDENT>except OSError as err:<EOL><INDENT>if err.errno != EPIPE:<EOL><INDENT>raise<EOL><DEDENT>wentWrong = True<EOL><DEDENT>except IOError as err:<EOL><INDENT>if err.errno != EINVAL:<EOL><INDENT>raise<EOL><DEDENT>wentWrong = True<EOL><DEDENT>if wentWrong:<EOL><INDENT>stdout, stderr = p.stdout.read(), p.stderr.read()<EOL>p.wait()<EOL><DEDENT>if p.returncode != <NUM_LIT:0>:<EOL><INDENT>raise DitaaError('<STR_LIT>'<EOL>'<STR_LIT>' % (stderr, stdout))<EOL><DEDENT>return outrelfn, outfullfn<EOL>

Render ditaa code into a PNG output file.


return self.code<EOL>

return the code object to be used by Machine


def execute(self, globals_=None, _locals=None):

if globals_ is None:<EOL><INDENT>globals_ = globals()<EOL><DEDENT>if _locals is None:<EOL><INDENT>self._locals = globals_<EOL><DEDENT>else:<EOL><INDENT>self._locals = _locals<EOL><DEDENT>self.globals_ = globals_<EOL>if self.contains_op("<STR_LIT>"):<EOL><INDENT>return self.iterate_instructions()<EOL><DEDENT>else:<EOL><INDENT>return self.execute_instructions()<EOL><DEDENT>

Execute a code object

The inputs and behavior of this function should match those of
eval_ and exec_.

.. _eval: https://docs.python.org/3/library/functions.html?highlight=eval#eval
.. _exec: https://docs.python.org/3/library/functions.html?highlight=exec#exec

.. note:: Need to figure out how the internals of this function must change for
   ``eval`` or ``exec``.

:param code: a python code object
:param globals_: optional globals dictionary
:param _locals: optional locals dictionary


if name in self.globals_:<EOL><INDENT>return self.globals_[name]<EOL><DEDENT>b = self.globals_['<STR_LIT>']<EOL>if isinstance(b, dict):<EOL><INDENT>return b[name]<EOL><DEDENT>else:<EOL><INDENT>return getattr(b, name)<EOL><DEDENT>

Implementation of the LOAD_NAME operation


self._locals[name] = val<EOL>

Implementation of the STORE_NAME operation
in global scope, locals and globals should reference the same dict so this would also
set the global


poped = self.__stack[len(self.__stack) - n:]<EOL>del self.__stack[len(self.__stack) - n:]<EOL>return poped<EOL>

Pop the **n** topmost items from the stack and return them as a ``list``.


self._print('<STR_LIT>')<EOL>self._print(callable_)<EOL>self._print('<STR_LIT>',args)<EOL>if isinstance(args[<NUM_LIT:0>], FunctionType):<EOL><INDENT>c = args[<NUM_LIT:0>].get_code()<EOL><DEDENT>else:<EOL><INDENT>c = args[<NUM_LIT:0>].__closure__[<NUM_LIT:0>].cell_contents.__code__<EOL><DEDENT>print('<STR_LIT>')<EOL>machine = MachineClassSource(c, self.verbose)<EOL>l = dict()<EOL>machine.execute(self.globals_, l)<EOL>a = Assembler()<EOL>for name, value in l.items():<EOL><INDENT>a.load_const(value)<EOL>a.store_name(name)<EOL><DEDENT>a.load_const(None)<EOL>a.return_value()<EOL>print('<STR_LIT>')<EOL>dis.dis(a.code())<EOL>f = types.FunctionType(a.code(), self.globals_, args[<NUM_LIT:1>])<EOL>args = (f, *args[<NUM_LIT:1>:])<EOL>self.call_callbacks('<STR_LIT>', callable_, *args)<EOL>return callable_(*args)<EOL>

Implement ``builtins.__build_class__``.
We must wrap all class member functions using :py:func:`function_wrapper`.
This requires using a :py:class:`Machine` to execute the class source code
and then recreating the class source code using an :py:class:`Assembler`.

.. note: We might be able to bypass the call to ``builtins.__build_class__``
   entirely and manually construct a class object.

   https://github.com/python/cpython/blob/master/Python/bltinmodule.c


callable_ = self.__stack[-<NUM_LIT:1>-i.arg]<EOL>args = tuple(self.__stack[len(self.__stack) - i.arg:])<EOL>self._print('<STR_LIT>')<EOL>self._print('<STR_LIT>', callable_)<EOL>self._print('<STR_LIT>', i.arg)<EOL>self._print('<STR_LIT>', args)<EOL>self.call_callbacks('<STR_LIT>', callable_, *args)<EOL>if isinstance(callable_, FunctionType):<EOL><INDENT>ret = callable_(*args)<EOL><DEDENT>elif callable_ is builtins.__build_class__:<EOL><INDENT>ret = self.build_class(callable_, args)<EOL><DEDENT>elif callable_ is builtins.globals:<EOL><INDENT>ret = self.builtins_globals()<EOL><DEDENT>else:<EOL><INDENT>ret = callable_(*args)<EOL><DEDENT>self.pop(<NUM_LIT:1> + i.arg)<EOL>self.__stack.append(ret)<EOL>

Implement the CALL_FUNCTION_ operation.

.. _CALL_FUNCTION: https://docs.python.org/3/library/dis.html#opcode-CALL_FUNCTION


STDOUT_FILENO = <NUM_LIT:1><EOL>STDERR_FILENO = <NUM_LIT:2><EOL>with open(os.devnull, "<STR_LIT:w>") as null:<EOL><INDENT>stdout = os.dup(STDOUT_FILENO)<EOL>stderr = os.dup(STDERR_FILENO)<EOL>os.dup2(null.fileno(), STDOUT_FILENO)<EOL>os.dup2(null.fileno(), STDERR_FILENO)<EOL><DEDENT>try:<EOL><INDENT>yield<EOL><DEDENT>finally:<EOL><INDENT>os.dup2(stdout, STDOUT_FILENO)<EOL>os.dup2(stderr, STDERR_FILENO)<EOL>os.close(stdout)<EOL>os.close(stderr)<EOL><DEDENT>

Silence error messages from the "patch" command


def apply_patch(self, patch_name, force=False, quiet=False):

self._check()<EOL>patch = Patch(patch_name)<EOL>patches = self.series.patches_until(patch)[:]<EOL>applied = self.db.applied_patches()<EOL>for patch in applied:<EOL><INDENT>if patch in patches:<EOL><INDENT>patches.remove(patch)<EOL><DEDENT><DEDENT>if not patches:<EOL><INDENT>raise AllPatchesApplied(self.series, self.db.top_patch())<EOL><DEDENT>self.applying(patch)<EOL>try:<EOL><INDENT>for cur_patch in patches:<EOL><INDENT>self._apply_patch(cur_patch, force, quiet)<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>self.db.save()<EOL><DEDENT>self.applied(self.db.top_patch())<EOL>


def apply_next_patch(self, force=False, quiet=False):

self._check()<EOL>top = self.db.top_patch()<EOL>if not top:<EOL><INDENT>patch = self.series.first_patch()<EOL><DEDENT>else:<EOL><INDENT>patch = self.series.patch_after(top)<EOL><DEDENT>if not patch:<EOL><INDENT>raise AllPatchesApplied(self.series, top)<EOL><DEDENT>self.applying(patch)<EOL>self._apply_patch(patch, force, quiet)<EOL>self.db.save()<EOL>self.applied(self.db.top_patch())<EOL>


def apply_all(self, force=False, quiet=False):

self._check()<EOL>top = self.db.top_patch()<EOL>if top:<EOL><INDENT>patches = self.series.patches_after(top)<EOL><DEDENT>else:<EOL><INDENT>patches = self.series.patches()<EOL><DEDENT>if not patches:<EOL><INDENT>raise AllPatchesApplied(self.series, top)<EOL><DEDENT>try:<EOL><INDENT>for patch in patches:<EOL><INDENT>self.applying(patch)<EOL>self._apply_patch(patch, force, quiet)<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>self.db.save()<EOL><DEDENT>self.applied(self.db.top_patch())<EOL>


def _file_in_patch(self, filename, patch, ignore):

file = self.quilt_pc + File(os.path.join(patch.get_name(), filename))<EOL>if file.exists():<EOL><INDENT>if ignore:<EOL><INDENT>return True<EOL><DEDENT>else:<EOL><INDENT>raise QuiltError("<STR_LIT>" % (filename,<EOL>patch.get_name()))<EOL><DEDENT><DEDENT>return False<EOL>

Checks if a backup file of the filename in the current patch
        exists


def _file_in_next_patches(self, filename, patch):

if not self.db.is_patch(patch):<EOL><INDENT>return<EOL><DEDENT>patches = self.db.patches_after(patch)<EOL>for patch in patches:<EOL><INDENT>file = self.quilt_pc + File(os.path.join(patch.get_name(),<EOL>filename))<EOL>if file.exists():<EOL><INDENT>raise QuiltError("<STR_LIT>" %<EOL>(filename, patch.get_name()))<EOL><DEDENT><DEDENT>

Checks if a backup file of the filename in the applied patches after
        patch exists


dest_dir = self.quilt_pc + patch.get_name()<EOL>file_dir = file.get_directory()<EOL>if file_dir:<EOL><INDENT>dest_dir = dest_dir + file_dir<EOL><DEDENT>backup = Backup()<EOL>backup.backup_file(file, dest_dir, copy_empty=True)<EOL>


def add_file(self, filename, patch_name=None, ignore=False):

file = File(filename)<EOL>if patch_name:<EOL><INDENT>patch = Patch(patch_name)<EOL><DEDENT>else:<EOL><INDENT>patch = self.db.top_patch()<EOL>if not patch:<EOL><INDENT>raise NoAppliedPatch(self.db)<EOL><DEDENT><DEDENT>exists = self._file_in_patch(filename, patch, ignore)<EOL>if exists:<EOL><INDENT>return<EOL><DEDENT>self._file_in_next_patches(filename, patch)<EOL>if file.is_link():<EOL><INDENT>raise QuiltError("<STR_LIT>" % filename)<EOL><DEDENT>self._backup_file(file, patch)<EOL>if file.exists():<EOL><INDENT>os.chmod(filename, file.get_mode() | stat.S_IWUSR | stat.S_IRUSR)<EOL><DEDENT>self.file_added(file, patch)<EOL>

Add file to the patch with patch_name.
        If patch_name is None or empty the topmost patch will be used.
        Adding an already added patch will raise an QuiltError if ignore is
        False.


patch = Patch(patchname)<EOL>if self.series.is_patch(patch):<EOL><INDENT>raise PatchAlreadyExists(self.series, patchname)<EOL><DEDENT>patch_dir = self.quilt_patches<EOL>patch_dir.create()<EOL>patchfile = patch_dir + File(patchname)<EOL>patchfile.touch()<EOL>pc_dir = self.quilt_pc + patchname<EOL>if pc_dir.exists():<EOL><INDENT>pc_dir.delete()<EOL><DEDENT>pc_dir.create()<EOL>top = self.db.top_patch()<EOL>self.series.add_patches([patch], top)<EOL>self.db.add_patch(patch)<EOL>self.series.save()<EOL>self.db.save()<EOL>self.patch_created(patch)<EOL>

Adds a new patch with patchname to the queue

        The new patch will be added as the topmost applied patch.


@DirectoryParam(["<STR_LIT>"])<EOL><INDENT>@FileParam(["<STR_LIT:file>"])<EOL>def backup_file(self, file, dest_dir, copy_empty=False):<DEDENT>

if file.exists():<EOL><INDENT>if not copy_empty and file.is_empty():<EOL><INDENT>return None<EOL><DEDENT>dest_dir.create()<EOL>file.copy(dest_dir)<EOL>return dest_dir + file.get_basefile()<EOL><DEDENT>elif copy_empty:<EOL><INDENT>dest_dir = dest_dir + file.get_directory()<EOL>dest_dir.create()<EOL>dest_file = dest_dir + file.get_basefile()<EOL>dest_file.touch()<EOL>return dest_file<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Backup file in dest_dir Directory.
        The return value is a File object pointing to the copied file in the
        destination directory or None if no file is copied.

        If file exists and it is not empty it is copied to dest_dir.
        If file exists and it is empty the file is copied only if copy_empty is
        True.
        If file does not exist and copy_empty is True a new file in dest_dir
        will be created.
        In all other cases no file will be copied and None is returned.


def unapply_patch(self, patch_name, force=False):

self._check(force)<EOL>patches = self.db.patches_after(Patch(patch_name))<EOL>for patch in reversed(patches):<EOL><INDENT>self._unapply_patch(patch)<EOL><DEDENT>self.db.save()<EOL>self.unapplied(self.db.top_patch())<EOL>

Unapply patches up to patch_name. patch_name will end up as top
            patch


self._check(force)<EOL>patch = self.db.top_patch()<EOL>self._unapply_patch(patch)<EOL>self.db.save()<EOL>self.unapplied(self.db.top_patch())<EOL>


self._check(force)<EOL>for patch in reversed(self.db.applied_patches()):<EOL><INDENT>self._unapply_patch(patch)<EOL><DEDENT>self.db.save()<EOL>self.unapplied(self.db.top_patch())<EOL>


self.comment = "<STR_LIT>"<EOL>self.patch = None<EOL>self.line = "<STR_LIT>"<EOL>if isinstance(patch, six.string_types):<EOL><INDENT>self._parse_line(patch)<EOL><DEDENT>elif isinstance(patch, Patch):<EOL><INDENT>self.patch = patch<EOL>self.line = patch.get_name()<EOL><DEDENT>

patch can be either a string or a Patch object


return os.path.exists(self.series_file)<EOL>


self.patchlines = []<EOL>self.patch2line = dict()<EOL>if self.exists():<EOL><INDENT>with open(self.series_file, "<STR_LIT:r>") as f:<EOL><INDENT>for line in f:<EOL><INDENT>self.add_patch(line)<EOL><DEDENT><DEDENT><DEDENT>


with open(self.series_file, "<STR_LIT:wb>") as f:<EOL><INDENT>for patchline in self.patchlines:<EOL><INDENT>f.write(_encode_str(str(patchline)))<EOL>f.write(b"<STR_LIT:\n>")<EOL><DEDENT><DEDENT>

Saves current patches list in the series file


patchline = PatchLine(patch)<EOL>patch = patchline.get_patch()<EOL>if patch:<EOL><INDENT>self.patch2line[patch] = patchline<EOL><DEDENT>self.patchlines.append(patchline)<EOL>


patchlines = []<EOL>for patch_name in patches:<EOL><INDENT>patchline = PatchLine(patch_name)<EOL>patch = patchline.get_patch()<EOL>if patch:<EOL><INDENT>self.patch2line[patch] = patchline<EOL><DEDENT>patchlines.append(patchline)<EOL><DEDENT>patchlines.extend(self.patchlines)<EOL>self.patchlines = patchlines<EOL>

Insert list of patches at the front of the curent patches list


def add_patches(self, patches, after=None):

if after is None:<EOL><INDENT>self.insert_patches(patches)<EOL><DEDENT>else:<EOL><INDENT>self._check_patch(after)<EOL>patchlines = self._patchlines_before(after)<EOL>patchlines.append(self.patch2line[after])<EOL>for patch in patches:<EOL><INDENT>patchline = PatchLine(patch)<EOL>patchlines.append(patchline)<EOL>self.patch2line[patchline.get_patch()] = patchline<EOL><DEDENT>patchlines.extend(self._patchlines_after(after))<EOL>self.patchlines = patchlines<EOL><DEDENT>

Add a list of patches to the patches list


self._check_patch(patch)<EOL>patchline = self.patch2line[patch]<EOL>del self.patch2line[patch]<EOL>self.patchlines.remove(patchline)<EOL>


patches = self.patches()<EOL>if not patches:<EOL><INDENT>return None<EOL><DEDENT>return patches[-<NUM_LIT:1>]<EOL>

Returns the last patch from the patches list or None if the list
            is empty


patches = self.patches()<EOL>if not patches:<EOL><INDENT>return None<EOL><DEDENT>return patches[<NUM_LIT:0>]<EOL>

Returns the first patch from the patches list or None if the list
            is empty


return [line.get_patch() for line in self.patchlines if<EOL>line.get_patch()]<EOL>


return [line.get_patch() for line in self._patchlines_after(patch) if<EOL>line.get_patch()]<EOL>

Returns a list of patches after patch from the patches list


patches = self.patches_after(patch)<EOL>if patches:<EOL><INDENT>return patches[<NUM_LIT:0>]<EOL><DEDENT>return None<EOL>

Returns the patch followed by patch from the patches list or None if
        no patch after can be found.


return [line.get_patch() for line in self._patchlines_before(patch)<EOL>if line.get_patch()]<EOL>

Returns a list of patches before patch from the patches list


patches = self.patches_before(patch)<EOL>if patches:<EOL><INDENT>return patches[-<NUM_LIT:1>]<EOL><DEDENT>return None<EOL>

Returns the patch before patch from the patches list or None if no
        patch before can be found.


return [line.get_patch() for line in self._patchlines_until(patch) if<EOL>line.get_patch()]<EOL>

Returns a list of patches before patch from the patches list
        including the provided patch


return patch in self.patch2line<EOL>

Returns True if patch is in the list of patches. Otherwise it
            returns False.


return len(self.patch2line) == <NUM_LIT:0><EOL>

Returns true if no patch is in the series


def replace(self, old_patch, new_patch):

self._check_patch(old_patch)<EOL>old_patchline = self.patch2line[old_patch]<EOL>index = self.patchlines.index(old_patchline)<EOL>self.patchlines.pop(index)<EOL>new_patchline = PatchLine(new_patch)<EOL>new_patchline.set_comment(old_patchline.get_comment())<EOL>self.patchlines.insert(index, new_patchline)<EOL>del self.patch2line[old_patch]<EOL>self.patch2line[new_patch] = new_patchline<EOL>

Replace old_patch with new_patch
        The method only replaces the patch and doesn't change any comments.


if not os.path.exists(self.dirname):<EOL><INDENT>os.makedirs(self.dirname)<EOL><DEDENT>self._create_version(self.version_file)<EOL>

Creates the dirname and inserts a .version file


self.create()<EOL>super(Db, self).save()<EOL>

Create version file and save applied patches


return self.patches()<EOL>


<EOL>with open(version_file, "<STR_LIT:r>") as f:<EOL><INDENT>version = f.read(<NUM_LIT:10>)<EOL><DEDENT>version = version.rstrip("<STR_LIT:\r\n>")<EOL>if len(version) >= <NUM_LIT:10> or version != str(DB_VERSION):<EOL><INDENT>raise DBError("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" % (version, DB_VERSION))<EOL><DEDENT>

Checks if the .version file in dirname has the correct supported
            version number


def refresh(self, patch_name=None, edit=False):

if patch_name:<EOL><INDENT>patch = Patch(patch_name)<EOL><DEDENT>else:<EOL><INDENT>patch = self.db.top_patch()<EOL>if not patch:<EOL><INDENT>raise QuiltError("<STR_LIT>")<EOL><DEDENT><DEDENT>pc_dir = self.quilt_pc + patch.get_name()<EOL>patch_file = self.quilt_patches + File(patch.get_name())<EOL>files = pc_dir.content()[<NUM_LIT:1>]<EOL>with TmpFile(prefix="<STR_LIT>") as tmpfile:<EOL><INDENT>f = tmpfile.open()<EOL>if patch_file.exists():<EOL><INDENT>header = patch.get_header(self.quilt_patches)<EOL>tmpfile.write(header)<EOL><DEDENT>for file_name in files:<EOL><INDENT>if file_name == "<STR_LIT>":<EOL><INDENT>continue<EOL><DEDENT>orig_file = pc_dir + File(file_name)<EOL>new_file = File(file_name)<EOL>left_label, right_label, index = self._get_labels(file_name,<EOL>orig_file,<EOL>new_file)<EOL>self._write_index(tmpfile, index)<EOL>diff = Diff(orig_file, new_file)<EOL>diff.run(self.cwd, fd=f, left_label=left_label,<EOL>right_label=right_label)<EOL><DEDENT>if tmpfile.is_empty():<EOL><INDENT>raise QuiltError("<STR_LIT>")<EOL><DEDENT>if edit:<EOL><INDENT>self.edit_patch(tmpfile)<EOL>tpatch = Patch(tmpfile.get_name())<EOL>tpatch.run(pc_dir.get_name(), dry_run=True, quiet=True)<EOL><DEDENT>if patch_file.exists():<EOL><INDENT>diff = Diff(patch_file, tmpfile)<EOL>if diff.equal(self.cwd):<EOL><INDENT>raise QuiltError("<STR_LIT>")<EOL><DEDENT><DEDENT>tmpfile.copy(patch_file)<EOL><DEDENT>timestamp = pc_dir + File("<STR_LIT>")<EOL>timestamp.touch()<EOL>refresh = self.quilt_pc + File(patch.get_name() + "<STR_LIT>")<EOL>refresh.delete_if_exists()<EOL>self.refreshed(patch)<EOL>

Refresh patch with patch_name or applied top patch if patch_name is
        None


arguments = get_declared_instances_dict(bases, attrs, Argument,<EOL>"<STR_LIT>")<EOL>groups = get_declared_instances_list(bases, attrs, ArgumentGroup,<EOL>"<STR_LIT>")<EOL>subparsers = get_declared_instances_dict(bases, attrs, BaseSubParser,<EOL>"<STR_LIT>")<EOL>sgroup = get_first_declared_instance(bases, attrs, SubParserGroup,<EOL>"<STR_LIT>")<EOL>new_class = super(ArgumentsCollectorMetaClass, cls).__new__(<EOL>cls, name, bases, attrs)<EOL>if groups:<EOL><INDENT>for name, group in groups:<EOL><INDENT>group.set_name(name)<EOL>for arg_name in group.argument_names:<EOL><INDENT>arg = arguments.pop(arg_name)<EOL>arg.set_name(arg_name)<EOL>group.add_argument(arg)<EOL><DEDENT><DEDENT><DEDENT>new_class.base_argument_groups = groups<EOL>if not sgroup and subparsers:<EOL><INDENT>sgroup = None, SubParserGroup(subparser_names=[key for key in<EOL>subparsers.keys()])<EOL><DEDENT>if sgroup:<EOL><INDENT>name, group = sgroup<EOL>group.set_name(name)<EOL>for sname in group.subparser_names:<EOL><INDENT>sparser = subparsers.pop(sname)<EOL>sparser.set_name(sname)<EOL>group.add_subparser(sparser)<EOL><DEDENT>new_class.subparser_group = group<EOL><DEDENT>args = []<EOL>if arguments:<EOL><INDENT>for name, arg in arguments.items():<EOL><INDENT>arg.set_name(name)<EOL>args.append((name, arg))<EOL><DEDENT><DEDENT>args.sort(key=lambda x: x[<NUM_LIT:1>].creation_counter)<EOL>new_class.base_arguments = args<EOL>new_class.base_subparsers = subparsers<EOL>return new_class<EOL>

Collects all Argument and Group instances and sets them as
base_arguments respectively base_argument_groups in the new created
class. Arguments mentioned in the Group instances will be not added to
base_arguments.


def __init__(self, title=None, description=None, argument_names=None):

self.title = title<EOL>self.description = description<EOL>self.argument_names = argument_names or []<EOL>self.arguments = []<EOL>self.creation_counter = ArgumentGroup.creation_counter<EOL>ArgumentGroup.creation_counter += <NUM_LIT:1><EOL>

Constructs a ArgumentGroup instance

@param title The title of the group displayed as headline
@param description A detailed description of the argument group
@param argument_names A list of strings containing the Arguments to be
                      grouped


self.group = parser.add_argument_group(self.title, self.description)<EOL>for arg in self.arguments:<EOL><INDENT>arg.add_to_parser(self.group)<EOL><DEDENT>

Adds the group and its arguments to a argparse.ArgumentParser instance

@param parser A argparse.ArgumentParser instance


self.name = name<EOL>

Sets the name of this group. Normally this method should not be called
directly. It is used by the ArgumentsCollectorMetaClass.

@param name A string for a name


self.arguments.append(arg)<EOL>

Adds a Argument to this group.
Normally this method should not be called directly.
It is used by the ArgumentsCollectorMetaClass.

@parma arg An Argument instance to be added to this group.


self.name = name<EOL>

Sets the name of this SubParser

Normally this method should not be called directly.
It is used by the ArgumentsCollectorMetaClass.

:param name A string for a name


self.subparsers.append(parser)<EOL>

Adds a SubParser to this group
Normally this method should not be called directly.
It is used by the ArgumentsCollectorMetaClass.

:param arg An Argument instance to be added to this group.


self.args = args<EOL>self.kwargs = kwargs<EOL>self.creation_counter = Argument.creation_counter<EOL>Argument.creation_counter += <NUM_LIT:1><EOL>

Constructs an Argument instance

args and kwargs are passed directly to
argparse.ArgumentParser.add_argument


kwargs = self._get_kwargs()<EOL>args = self._get_args()<EOL>parser.add_argument(*args, **kwargs)<EOL>

Adds the argument to an argparse.ArgumentParser instance

@param parser An argparse.ArgumentParser instance


self.name = name<EOL>

Sets the name of this Argument.
Normally this method should not be called directly.
It is used by the ArgumentsCollectorMetaClass.

@param name A string for a name


self.name = name<EOL>

Sets the name of this Subparse.
Normally this method should not be called directly.
It is used by the ArgumentsCollectorMetaClass.

:param name A string for a name


parser = subparsers.add_parser(*self._get_args(), **self._get_kwargs())<EOL>parser.set_defaults(**self.get_defaults())<EOL>for name, group in self.base_argument_groups:<EOL><INDENT>group.add_to_parser(parser)<EOL><DEDENT>for name, arg in self.base_arguments:<EOL><INDENT>arg.add_to_parser(parser)<EOL><DEDENT>self.add_subparsers(parser)<EOL>

Adds this SubParser to the subparsers created by
argparse.ArgumentParser.add_subparsers method.

@param subparsers Normally a _SubParsersAction instance created by
argparse.ArgumentParser.add_subparsers method


def set_subparsers_args(self, *args, **kwargs):

self.subparsers_args = args<EOL>self.subparsers_kwargs = kwargs<EOL>

Sets args and kwargs that are passed when creating a subparsers group
in an argparse.ArgumentParser i.e. when calling
argparser.ArgumentParser.add_subparsers


self.subparsers.append(parser)<EOL>

Adds a SubParser instance to the list of subparsers

@param parser A SubParser instance


return self.default_subparsers_kwargs<EOL>

Returns the default kwargs to be passed to
argparse.ArgumentParser.add_subparsers


return self.default_subparsers_args<EOL>

Returns the default args to be passed to
argparse.ArgumentParser.add_subparsers


sgroup = getattr(self, "<STR_LIT>", None)<EOL>if sgroup:<EOL><INDENT>sgroup.add_to_parser(self)<EOL><DEDENT>if not self.subparsers:<EOL><INDENT>return<EOL><DEDENT>args = self.subparsers_args or self.get_default_subparsers_args()<EOL>kwargs = self.subparsers_kwargs or self.get_default_subparsers_kwargs()<EOL>subs = parser.add_subparsers(*args, **kwargs)<EOL>for subparser in self.subparsers:<EOL><INDENT>subparser.add_to_parser(subs)<EOL><DEDENT>

Adds the subparsers to an argparse.ArgumentParser

@param parser An argparse.ArgumentParser instance


parser = argparse.ArgumentParser(*self.args, **self.kwargs)<EOL>for name, group in self.base_argument_groups:<EOL><INDENT>group.add_to_parser(parser)<EOL><DEDENT>for name, arg in self.base_arguments:<EOL><INDENT>arg.add_to_parser(parser)<EOL><DEDENT>self.add_subparsers(parser)<EOL>self.parser = parser<EOL>

Method to create and initalize an argparser.ArgumentParser


def delete_next(self, remove=False, backup=False):

patch = self.db.top_patch()<EOL>if patch:<EOL><INDENT>after = self.series.patch_after(patch)<EOL><DEDENT>else:<EOL><INDENT>after = self.series.first_patch()<EOL><DEDENT>if not after:<EOL><INDENT>raise QuiltError("<STR_LIT>")<EOL><DEDENT>self._delete_patch(after, remove=remove, backup=backup)<EOL>

Delete next unapplied patch
        If remove is True the patch file will also be removed. If remove and
        backup are True a copy of the deleted patch file will be made.


def delete_patch(self, patch_name=None, remove=False, backup=False):

if patch_name:<EOL><INDENT>patch = Patch(patch_name)<EOL><DEDENT>else:<EOL><INDENT>patch = self.db.top_patch()<EOL>if not patch:<EOL><INDENT>raise NoAppliedPatch(self.db)<EOL><DEDENT><DEDENT>self._delete_patch(patch, remove=remove, backup=backup)<EOL>

Delete specified patch from the series
        If remove is True the patch file will also be removed. If remove and
        backup are True a copy of the deleted patch file will be made.


def import_patch(self, patch_name, new_name=None):

if new_name:<EOL><INDENT>dir_name = os.path.dirname(new_name)<EOL>name = os.path.basename(new_name)<EOL>dest_dir = self.quilt_patches + Directory(dir_name)<EOL>dest_dir.create()<EOL><DEDENT>else:<EOL><INDENT>name = os.path.basename(patch_name)<EOL>dest_dir = self.quilt_patches<EOL><DEDENT>patch_file = File(patch_name)<EOL>dest_file = dest_dir + File(name)<EOL>patch_file.copy(dest_file)<EOL>self._import_patches([name])<EOL>

Import patch into the patch queue
        The patch is inserted as the next unapplied patch.


dest_dir = self.quilt_patches<EOL>patch_names = []<EOL>for patch in patches:<EOL><INDENT>patch_name = os.path.basename(patch)<EOL>patch_file = File(patch)<EOL>dest_file = dest_dir + File(patch_name)<EOL>patch_file.copy(dest_file)<EOL>patch_names.append(patch_name)<EOL><DEDENT>self._import_patches(patch_names)<EOL>

Import several patches into the patch queue


return not self.__eq__(other)<EOL>


def run(self, suppress_output=False, inputdata=None, **kw):

if inputdata is not None:<EOL><INDENT>kw["<STR_LIT>"] = subprocess.PIPE<EOL><DEDENT>if suppress_output:<EOL><INDENT>kw["<STR_LIT>"] = open(os.devnull, "<STR_LIT:w>")<EOL>kw["<STR_LIT>"] = kw["<STR_LIT>"]<EOL><DEDENT>try:<EOL><INDENT>try:<EOL><INDENT>process = subprocess.Popen(self.cmd, **kw)<EOL><DEDENT>finally:<EOL><INDENT>if suppress_output:<EOL><INDENT>kw["<STR_LIT>"].close()<EOL><DEDENT><DEDENT><DEDENT>except OSError as e:<EOL><INDENT>msg = "<STR_LIT>".format(self.cmd, e)<EOL>raise QuiltError(msg)<EOL><DEDENT>if inputdata is not None:<EOL><INDENT>process.stdin.write(inputdata)<EOL>process.stdin.close()<EOL><DEDENT>ret = process.wait()<EOL>if ret != <NUM_LIT:0>:<EOL><INDENT>raise SubprocessError(self.cmd, ret)<EOL><DEDENT>

Run command as a subprocess and wait until it is finished.

        The command should be given as a list of strings to avoid problems
        with shell quoting.  If the command exits with a return code other
        than 0, a SubprocessError is raised.


self.dirname = dirname<EOL>


return os.path.exists(self.dirname)<EOL>


if self.dirname and not os.path.exists(self.dirname):<EOL><INDENT>os.makedirs(self.dirname)<EOL><DEDENT>

Creates the directory and all its parent directories if it does not
        exist yet


(dirs, files) = self._content(self.dirname)<EOL>return files<EOL>

Returns all files in this directory and its subdirectories


return self._content(self.dirname)<EOL>

Returns all directories and files in this directory and its
            subdirectories


if self.exists():<EOL><INDENT>shutil.rmtree(self.dirname)<EOL><DEDENT>

Delete the directory and its content if directory exists


return self.dirname<EOL>


return Directory(os.path.abspath(self.dirname))<EOL>

Returns this directory with absolute path


contents = os.listdir(self.dirname)<EOL>return len(contents) == <NUM_LIT:0><EOL>

Returns True if the directory doesn't contain any files or
        subdirectories


if isinstance(dest, Directory):<EOL><INDENT>dest = dest.get_name()<EOL><DEDENT>shutil.copytree(self.dirname, dest)<EOL>

Copy to destination directory recursively.
        If symlinks is true, symbolic links in the source tree are represented
        as symbolic links in the new tree, but the metadata of the original
        links is NOT copied; if false or omitted, the contents and metadata of
        the linked files are copied to the new tree.


open(self.filename, "<STR_LIT:w>").close()<EOL>


if isinstance(link, File):<EOL><INDENT>link = link.filename<EOL><DEDENT>os.link(self.filename, link)<EOL>


if isinstance(dest, File):<EOL><INDENT>dest_dir = dest.get_directory()<EOL>dest_dir.create()<EOL>dest = dest.filename<EOL><DEDENT>elif isinstance(dest, Directory):<EOL><INDENT>dest = dest.dirname<EOL><DEDENT>shutil.copy2(self.filename, dest)<EOL>


st = os.stat(self.filename)<EOL>return st.st_size == <NUM_LIT:0><EOL>

Returns True if the size of the file is 0


return self.filename<EOL>


return os.path.basename(self.filename)<EOL>

Return the base name of the file e.g. file if filename is /foo/file.
        If filename doesn't contain a directory get_name and get_basename
        are equal.


dirname = os.path.dirname(self.filename)<EOL>if dirname:<EOL><INDENT>return Directory(dirname)<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Returns the directory where the file is placed in or None if the
        path to the file doesn't contain a directory


return File(os.path.abspath(self.filename))<EOL>


return File(self.get_basename())<EOL>


return functools.partial(self.__call__, obj)<EOL>


lines = []<EOL>if patch_dir:<EOL><INDENT>file = patch_dir + File(self.get_name())<EOL>name = file.get_name()<EOL><DEDENT>else:<EOL><INDENT>name = self.get_name()<EOL><DEDENT>with open(name, "<STR_LIT:rb>") as f:<EOL><INDENT>for line in f:<EOL><INDENT>if line.startswith(b"<STR_LIT>") or line.startswith(b"<STR_LIT>"):<EOL><INDENT>break<EOL><DEDENT>lines.append(line)<EOL><DEDENT><DEDENT>return b"<STR_LIT>".join(lines)<EOL>


@FileParam(["<STR_LIT:left>", "<STR_LIT:right>"])<EOL><INDENT>def __init__(self, left, right):<DEDENT>

self.left = left<EOL>if not self.left.exists():<EOL><INDENT>self.left = File("<STR_LIT>")<EOL><DEDENT>self.right = right<EOL>if not self.right.exists():<EOL><INDENT>self.right = File("<STR_LIT>")<EOL><DEDENT>

left points to the first file and right to the second file


cmd = ["<STR_LIT>"]<EOL>cmd.append("<STR_LIT>")<EOL>cmd.append(self.left.get_name())<EOL>cmd.append(self.right.get_name())<EOL>try:<EOL><INDENT>Process(cmd).run(cwd=cwd, suppress_output=True)<EOL><DEDENT>except SubprocessError as e:<EOL><INDENT>if e.get_returncode() == <NUM_LIT:1>:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>raise e<EOL><DEDENT><DEDENT>return True<EOL>

Returns True if left and right are equal


def _file_in_patch(self, filename, patch):

pc_dir = self.quilt_pc + patch.get_name()<EOL>file = pc_dir + File(filename)<EOL>if not file.exists():<EOL><INDENT>raise QuiltError("<STR_LIT>" % (filename,<EOL>patch.get_name()))<EOL><DEDENT>

Checks if a backup file of the filename in the current patch
        exists and raises a QuiltError if not.


if not self.db.is_patch(patch):<EOL><INDENT>return<EOL><DEDENT>patches = self.db.patches_after(patch)<EOL>for patch in patches:<EOL><INDENT>file = self.quilt_pc + File(os.path.join(patch.get_name(),<EOL>filename))<EOL>if file.exists():<EOL><INDENT>raise QuiltError("<STR_LIT>" %<EOL>(filename, patch.get_name()))<EOL><DEDENT><DEDENT>

Checks if a backup file of the filename in the applied patches after
        patch exists


def revert_file(self, filename, patch_name=None):

file = File(filename)<EOL>if patch_name:<EOL><INDENT>patch = Patch(patch_name)<EOL><DEDENT>else:<EOL><INDENT>patch = self.db.top_patch()<EOL>if not patch:<EOL><INDENT>raise QuiltError("<STR_LIT>")<EOL><DEDENT><DEDENT>self._file_in_patch(filename, patch)<EOL>self._file_in_next_patches(filename, patch)<EOL>pc_dir = self.quilt_pc + patch.get_name()<EOL>pc_file = pc_dir + file<EOL>if not file.exists() and pc_file.is_empty():<EOL><INDENT>pc_file.delete()<EOL>self.file_reverted(file, patch)<EOL>return<EOL><DEDENT>with TmpDirectory(prefix="<STR_LIT>") as tmpdir:<EOL><INDENT>tmp_file = self._apply_patch_temporary(tmpdir, pc_file, patch)<EOL>if tmp_file and tmp_file.exists() and not tmp_file.is_empty():<EOL><INDENT>diff = Diff(file, tmp_file)<EOL>if diff.equal(self.cwd):<EOL><INDENT>self.file_unchanged(file, patch)<EOL>return<EOL><DEDENT>dir = file.get_directory()<EOL>if not dir:<EOL><INDENT>dir = Directory(os.getcwd())<EOL><DEDENT>else:<EOL><INDENT>dir.create()<EOL><DEDENT>tmp_file.copy(dir)<EOL>self.file_reverted(file, patch)<EOL><DEDENT>else:<EOL><INDENT>self.file_unchanged(file, patch)<EOL><DEDENT><DEDENT>

Revert not added changes of filename.
        If patch_name is None or empty the topmost patch will be used.


def constanted(*args, **kwargs):<EOL><INDENT>return x<EOL><DEDENT>return constanted<EOL>

Produce a function that always returns a supplied value.

    Args:
        x: Any object.

    Returns:
        A function that accepts any number of positional and keyword arguments, discards them, and returns ``x``.


def splat(f: Callable[..., A]) -> Callable[[Iterable], A]:

def splatted(args):<EOL><INDENT>return f(*args)<EOL><DEDENT>return splatted<EOL>

Convert a function taking multiple arguments into a function taking a single iterable argument.

    Args:
        f: Any function

    Returns:
        A function that accepts a single iterable argument. Each element of this iterable argument is passed as an
        argument to ``f``.

    Example:
        $ def f(a, b, c):
        $     return a + b + c
        $
        $ f(1, 2, 3)  # 6
        $ g = splat(f)
        $ g([1, 2, 3])  # 6


def unsplat(f: Callable[[Iterable], A]) -> Callable[..., A]:

def unsplatted(*args):<EOL><INDENT>return f(args)<EOL><DEDENT>return unsplatted<EOL>

Convert a function taking a single iterable argument into a function taking multiple arguments.

    Args:
        f: Any function taking a single iterable argument

    Returns:
        A function that accepts multiple arguments. Each argument of this function is passed as an element of an
        iterable to ``f``.

    Example:
        $ def f(a):
        $     return a[0] + a[1] + a[2]
        $
        $ f([1, 2, 3])  # 6
        $ g = unsplat(f)
        $ g(1, 2, 3)  # 6


def completely_parse_reader(parser: Parser[Input, Output], reader: Reader[Input]) -> Result[Output]:

result = (parser << eof).consume(reader)<EOL>if isinstance(result, Continue):<EOL><INDENT>return Success(result.value)<EOL><DEDENT>else:<EOL><INDENT>used = set()<EOL>unique_expected = []<EOL>for expected_lambda in result.expected:<EOL><INDENT>expected = expected_lambda()<EOL>if expected not in used:<EOL><INDENT>used.add(expected)<EOL>unique_expected.append(expected)<EOL><DEDENT><DEDENT>return Failure(result.farthest.expected_error('<STR_LIT>'.join(unique_expected)))<EOL><DEDENT>

Consume reader and return Success only on complete consumption.

    This is a helper function for ``parse`` methods, which return ``Success``
    when the input is completely consumed and ``Failure`` with an appropriate
    message otherwise.

    Args:
        parser: The parser doing the consuming
        reader: The input being consumed

    Returns:
        A parsing ``Result``


def lit(literal: Sequence[Input], *literals: Sequence[Sequence[Input]]) -> Parser:

if len(literals) > <NUM_LIT:0>:<EOL><INDENT>return AlternativeParser(options.handle_literal(literal), *map(options.handle_literal, literals))<EOL><DEDENT>else:<EOL><INDENT>return options.handle_literal(literal)<EOL><DEDENT>

Match a literal sequence.

    In the `TextParsers`` context, this matches the literal string
    provided. In the ``GeneralParsers`` context, this matches a sequence of
    input.

    If multiple literals are provided, they are treated as alternatives. e.g.
    ``lit('+', '-')`` is the same as ``lit('+') | lit('-')``.

    Args:
        literal: A literal to match
        *literals: Alternative literals to match

    Returns:
        A ``LiteralParser`` in the ``GeneralContext``, a ``LiteralStringParser``
        in the ``TextParsers`` context, and an ``AlternativeParser`` if multiple
        arguments are provided.


return RegexParser(pattern, options.whitespace)<EOL>

Match with a regular expression.

    This matches the text with a regular expression. The regular expressions is
    treated as greedy. Backtracking in the parser combinators does not flow into
    regular expression backtracking. This is only valid in the ``TextParsers``
    context and not in the ``GeneralParsers`` context because regular
    expressions only operate on text.

    Args:
        pattern: str or python regular expression.


def opt(parser: Union[Parser, Sequence[Input]]) -> OptionalParser:

if isinstance(parser, str):<EOL><INDENT>parser = lit(parser)<EOL><DEDENT>return OptionalParser(parser)<EOL>

Optionally match a parser.

    An ``OptionalParser`` attempts to match ``parser``. If it succeeds, it
    returns a list of length one with the value returned by the parser as the
    only element. If it fails, it returns an empty list.

    Args:
        parser: Parser or literal


def rep1(parser: Union[Parser, Sequence[Input]]) -> RepeatedOnceParser:

if isinstance(parser, str):<EOL><INDENT>parser = lit(parser)<EOL><DEDENT>return RepeatedOnceParser(parser)<EOL>

Match a parser one or more times repeatedly.

    This matches ``parser`` multiple times in a row. If it matches as least
    once, it returns a list of values from each time ``parser`` matched. If it
    does not match ``parser`` at all, it fails.

    Args:
        parser: Parser or literal


def rep(parser: Union[Parser, Sequence[Input]]) -> RepeatedParser:

if isinstance(parser, str):<EOL><INDENT>parser = lit(parser)<EOL><DEDENT>return RepeatedParser(parser)<EOL>

Match a parser zero or more times repeatedly.

    This matches ``parser`` multiple times in a row. A list is returned
    containing the value from each match. If there are no matches, an empty list
    is returned.

    Args:
        parser: Parser or literal


def rep1sep(parser: Union[Parser, Sequence[Input]], separator: Union[Parser, Sequence[Input]])-> RepeatedOnceSeparatedParser:

if isinstance(parser, str):<EOL><INDENT>parser = lit(parser)<EOL><DEDENT>if isinstance(separator, str):<EOL><INDENT>separator = lit(separator)<EOL><DEDENT>return RepeatedOnceSeparatedParser(parser, separator)<EOL>

Match a parser one or more times separated by another parser.

    This matches repeated sequences of ``parser`` separated by ``separator``.
    If there is at least one match, a list containing the values of the
    ``parser`` matches is returned. The values from ``separator`` are discarded.
    If it does not match ``parser`` at all, it fails.

    Args:
        parser: Parser or literal
        separator: Parser or literal


def repsep(parser: Union[Parser, Sequence[Input]], separator: Union[Parser, Sequence[Input]])-> RepeatedSeparatedParser:

if isinstance(parser, str):<EOL><INDENT>parser = lit(parser)<EOL><DEDENT>if isinstance(separator, str):<EOL><INDENT>separator = lit(separator)<EOL><DEDENT>return RepeatedSeparatedParser(parser, separator)<EOL>

Match a parser zero or more times separated by another parser.

    This matches repeated sequences of ``parser`` separated by ``separator``. A
    list is returned containing the value from each match of ``parser``. The
    values from ``separator`` are discarded. If there are no matches, an empty
    list is returned.

    Args:
        parser: Parser or literal
        separator: Parser or literal


return SuccessParser(value)<EOL>

Always succeed in matching and return a value.

    This parser always succeeds and returns the given ``value``. No input is
    consumed. This is useful for inserting arbitrary values into complex
    parsers.

    Args:
        value: Any value


def failure(expected: str = '<STR_LIT>'):

return FailureParser(expected)<EOL>

Always fail in matching with a given message.

    This parser always backtracks with a message that it is expecting the
    given ``expected``. This is useful for appending to parsers that are
    expected to be seen in the input, but are not valid so that a more useful
    error message can be given.

    Args:
        expected: Message to be conveyed


def consume(self, reader: Reader[Input]) -> Status[Input, Output]:

raise NotImplementedError()<EOL>

Abstract method for matching this parser at the current location.

        This is the critical method of every parser combinator.

        Args:
            reader: The current state of the parser.

        Returns:
            If the pattern matches, a ``Continue`` is returned. If the pattern
            does not match, a ``Failure`` is returned. In either case, if
            multiple branches are explored, the error from the farthest point is
            merged with the returned status.


def parse(self, source: Sequence[Input]) -> Result[Output]:

raise NotImplementedError()<EOL>

Abstract method for completely parsing a source.

        While ``parse`` is a method on every parser for convenience, it
        is really a function of the context. It is the duty of the context
        to set the correct ``Reader`` to use and to handle whitespace
        not handled by the parsers themselves. This method is pulled from the
        context when the parser is initialized.

        Args:
            source: What will be parsed.

        Returns:
            If the parser succeeded in matching and consumed the entire output,
            the value from ``Continue`` is copied to make a ``Success``. If the
            parser failed in matching, the error message is copied to a
            ``Failure``. If the parser succeeded but the source was not
            completelt consumed, a ``Failure`` with a message indicating this
            is returned.


return ForwardDeclaration()<EOL>

Manually create a forward declaration.

    Normally, forward declarations are created automatically by the contexts.
    But they can be created manually if not in a context or if the user wants
    to avoid confusing the IDE.


def expected_error(self, expected: str) -> str:

if self.finished:<EOL><INDENT>return '<STR_LIT>'.format(expected)<EOL><DEDENT>else:<EOL><INDENT>return '<STR_LIT>'.format(expected, self.next_token(), self.position)<EOL><DEDENT>

Generate a basic error to include the current state.

        A parser can supply only a representation of what it is expecting to
        this method and the reader will provide the context, including the index
        to the error.

        Args:
            expected: A representation of what the parser is currently expecting

        Returns:
            A full error message


def recursion_error(self, repeated_parser: str):

if self.finished:<EOL><INDENT>return '<STR_LIT>''<STR_LIT>'.format(repeated_parser)<EOL><DEDENT>else:<EOL><INDENT>return '<STR_LIT>''<STR_LIT>'.format(repeated_parser, self.position, self.next_token())<EOL><DEDENT>

Generate an error to indicate that infinite recursion was encountered.

        A parser can supply a representation of itself to this method and the
        reader will supply the context, including the location where the
        parser stalled.

        Args:
            repeated_parser: A representation of the repeated parser

        Returns:
            A full error message


if self.finished:<EOL><INDENT>return super().expected_error(expected)<EOL><DEDENT>else:<EOL><INDENT>line_index, character_index, line, pointer = self.current_line()<EOL>return '<STR_LIT>'.format(<EOL>expected, repr(self.next_token()), line_index, character_index, line, pointer)<EOL><DEDENT>

Generate a basic error to include the current state.

        A parser can supply only a representation of what it is expecting to
        this method and the reader will provide the context, including the line
        and character positions.

        Args:
            expected: A representation of what the parser is currently expecting

        Returns:
            A full error message


if self.finished:<EOL><INDENT>return super().recursion_error(repeated_parser)<EOL><DEDENT>else:<EOL><INDENT>line_index, character_index, line, pointer = self.current_line()<EOL>return '<STR_LIT>''<STR_LIT>'.format(repeated_parser, line_index, character_index, line, pointer)<EOL><DEDENT>


def merge(self, status: '<STR_LIT>') -> '<STR_LIT>':

if status is None or status.farthest is None:<EOL><INDENT>pass<EOL><DEDENT>elif self.farthest is None:<EOL><INDENT>self.farthest = status.farthest<EOL>self.expected = status.expected<EOL><DEDENT>elif status.farthest.position < self.farthest.position:<EOL><INDENT>pass<EOL><DEDENT>elif status.farthest.position > self.farthest.position:<EOL><INDENT>self.farthest = status.farthest<EOL>self.expected = status.expected<EOL><DEDENT>else:<EOL><INDENT>self.expected = status.expected + self.expected<EOL><DEDENT>return self<EOL>

Merge the failure message from another status into this one.

        Whichever status represents parsing that has gone the farthest is
        retained. If both statuses have gone the same distance, then the
        expected values from both are retained.

        Args:
            status: The status to merge into this one.

        Returns:
            This ``Status`` which may have ``farthest`` and ``expected``
            updated accordingly.


<EOL>m = _U_ESCAPE.search(s)<EOL>if not m:<EOL><INDENT>return s if PY2 else s.encode('<STR_LIT:utf-8>')<EOL><DEDENT>chunks = []<EOL>pos = <NUM_LIT:0><EOL>while m:<EOL><INDENT>start = m.start()<EOL>end = m.end()<EOL>g = m.group(<NUM_LIT:1>)<EOL>if g is None:<EOL><INDENT>chunks.append(s[pos:end])<EOL><DEDENT>else:<EOL><INDENT>c = int(g, <NUM_LIT:16>)<EOL>if c < <NUM_LIT>:<EOL><INDENT>chunks.append(s[pos:end])<EOL><DEDENT>else:<EOL><INDENT>if PY3:   <EOL><INDENT>if c & <NUM_LIT> == <NUM_LIT> and s[end:end + <NUM_LIT:2>] == '<STR_LIT>':<EOL><INDENT>esc2 = s[end + <NUM_LIT:2>:end + <NUM_LIT:6>]<EOL>c2 = int(esc2, <NUM_LIT:16>)<EOL>if c2 & <NUM_LIT> == <NUM_LIT>:<EOL><INDENT>c = <NUM_LIT> + (((c - <NUM_LIT>) << <NUM_LIT:10>) |<EOL>(c2 - <NUM_LIT>))<EOL>end += <NUM_LIT:6><EOL><DEDENT><DEDENT><DEDENT>chunks.append(s[pos:start])<EOL>chunks.append(unichr(c))<EOL><DEDENT><DEDENT>pos = end<EOL>m = _U_ESCAPE.search(s, pos)<EOL><DEDENT>chunks.append(s[pos:])<EOL>return ('<STR_LIT>'.join(chunks)).encode("<STR_LIT:utf-8>")<EOL>

Unpack `\\uNNNN` escapes in 's' and encode the result as UTF-8

    This method takes the output of the JSONEncoder and expands any \\uNNNN
    escapes it finds (except for \\u0000 to \\u001F, which are converted to
    \\xNN escapes).

    For performance, it assumes that the input is valid JSON, and performs few
    sanity checks.


s = _canonical_encoder.encode(json_object)<EOL>return _unascii(s)<EOL>

Encodes the shortest UTF-8 JSON encoding with dictionary keys
    lexicographically sorted by unicode code point.

    Args:
        json_object (dict): The JSON object to encode.

    Returns:
        bytes encoding the JSON object


return _pretty_encoder.encode(json_object).encode("<STR_LIT:ascii>")<EOL>

Encodes the JSON object dict as human readable ascii bytes.


file_path = os.path.join(here, *path_segments)<EOL>with open(file_path, encoding="<STR_LIT:utf-8>") as f:<EOL><INDENT>return f.read()<EOL><DEDENT>

Read a UTF-8 file from the package. Takes a list of strings to join to
    make the path


result = {}<EOL>code = read_file(path_segments)<EOL>lines = [line for line in code.split('<STR_LIT:\n>') if line.startswith(name)]<EOL>exec("<STR_LIT:\n>".join(lines), result)<EOL>return result[name]<EOL>

Extract a constant from a python file by looking for a line defining
    the constant and executing it.


_jb = JWKSBundle('<STR_LIT>')<EOL>for fo in args:<EOL><INDENT>_jb[fo.iss] = fo.signing_keys_as_jwks()<EOL><DEDENT>return Operator(jwks_bundle=_jb)<EOL>

Anonymous member of a set of federations.
Used to parse compounded metadata statements.

:param args: The federations
:return: An Operator instance


def make_federation_entity(config, eid='<STR_LIT>', httpcli=None, verify_ssl=True):

args = {}<EOL>if not eid:<EOL><INDENT>try:<EOL><INDENT>eid = config['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if '<STR_LIT>' in config:<EOL><INDENT>self_signer = make_internal_signing_service(config['<STR_LIT>'],<EOL>eid)<EOL>args['<STR_LIT>'] = self_signer<EOL><DEDENT>try:<EOL><INDENT>bundle_cnf = config['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>_args = dict([(k, v) for k, v in bundle_cnf.items() if k in KJ_SPECS])<EOL>if _args:<EOL><INDENT>_kj = init_key_jar(**_args)<EOL><DEDENT>else:<EOL><INDENT>_kj = None<EOL><DEDENT>if '<STR_LIT>' in bundle_cnf:<EOL><INDENT>jb = FSJWKSBundle(eid, _kj, bundle_cnf['<STR_LIT>'],<EOL>key_conv={'<STR_LIT:to>': quote_plus, '<STR_LIT>': unquote_plus})<EOL><DEDENT>else:<EOL><INDENT>jb = JWKSBundle(eid, _kj)<EOL><DEDENT>args['<STR_LIT>'] = jb<EOL><DEDENT>for item in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>try:<EOL><INDENT>args[item] = config[item]<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if '<STR_LIT>' not in args:<EOL><INDENT>args['<STR_LIT>'] = eid<EOL><DEDENT>if '<STR_LIT>' in config:<EOL><INDENT>args['<STR_LIT>'] = config['<STR_LIT>']<EOL>return FederationEntityOOB(httpcli, iss=eid, **args)<EOL><DEDENT>elif '<STR_LIT>' in config:<EOL><INDENT>args['<STR_LIT>'] = verify_ssl<EOL>args['<STR_LIT>'] = config['<STR_LIT>']<EOL>return FederationEntityAMS(httpcli, iss=eid, **args)<EOL><DEDENT>elif '<STR_LIT>' in config:<EOL><INDENT>args['<STR_LIT>'] = verify_ssl<EOL>for key in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>args[key] = config[key]<EOL><DEDENT>return FederationEntitySwamid(httpcli, iss=eid, **args)<EOL><DEDENT>

Construct a :py:class:`fedoidcmsg.entity.FederationEntity` instance based
on given configuration.

:param config: Federation entity configuration
:param eid: Entity ID
:param httpcli: A http client instance to use when sending HTTP requests
:param verify_ssl: Whether TLS/SSL certificates should be verified
:return: A :py:class:`fedoidcmsg.entity.FederationEntity` instance


def __init__(self, srv, iss='<STR_LIT>', signer=None, self_signer=None,<EOL>fo_bundle=None, context='<STR_LIT>', entity_id='<STR_LIT>',<EOL>fo_priority=None, verify_ssl=True):

Operator.__init__(self, self_signer=self_signer, iss=iss, httpcli=srv,<EOL>jwks_bundle=fo_bundle, verify_ssl=verify_ssl)<EOL>self.signer = signer<EOL>self.federation = None<EOL>self.context = context<EOL>self.entity_id = entity_id<EOL>self.fo_priority = fo_priority or []<EOL>self.provider_federations = None<EOL>self.registration_federations = None<EOL>

:param srv: A Client or Provider instance
:param iss: A identifier assigned to this entity by the operator
:param self_signer: Signer this entity can use to sign things
:param signer: A signer to use for signing documents
    (client registration requests/provide info response) this
    entity produces.
:param fo_bundle: A bundle of keys that can be used to verify
    the root signature of a compounded metadata statement.
:param fo_priority:
:param verify_ssl: Whether SSL certificates should be verified


def pick_signed_metadata_statements_regex(self, pattern, context):

comp_pat = re.compile(pattern)<EOL>sms_dict = self.signer.metadata_statements[context]<EOL>res = []<EOL>for iss, vals in sms_dict.items():<EOL><INDENT>if comp_pat.search(iss):<EOL><INDENT>res.extend((iss, vals))<EOL><DEDENT><DEDENT>return res<EOL>

Pick signed metadata statements based on ISS pattern matching

:param pattern: A regular expression to match the iss against
:return: list of tuples (FO ID, signed metadata statement)


def pick_signed_metadata_statements(self, fo, context):

sms_dict = self.signer.metadata_statements[context]<EOL>res = []<EOL>for iss, vals in sms_dict.items():<EOL><INDENT>if iss == fo:<EOL><INDENT>res.extend((iss, vals))<EOL><DEDENT><DEDENT>return res<EOL>

Pick signed metadata statements based on ISS pattern matching

:param fo: Federation operators ID
:param context: In connect with which operation (one of the values in
    :py:data:`fedoidc.CONTEXTS`).
:return: list of tuples (FO ID, signed metadata statement)


def get_metadata_statement(self, input, cls=MetadataStatement,<EOL>context='<STR_LIT>'):

logger.debug('<STR_LIT>'.format(input))<EOL>if isinstance(input, dict):<EOL><INDENT>data = input<EOL><DEDENT>else:<EOL><INDENT>if isinstance(input, Message):<EOL><INDENT>data = input.to_dict()<EOL><DEDENT>else:<EOL><INDENT>data = json.loads(input)<EOL><DEDENT><DEDENT>_pi = self.unpack_metadata_statement(ms_dict=data, cls=cls)<EOL>if not _pi.result:<EOL><INDENT>return []<EOL><DEDENT>logger.debug('<STR_LIT>')<EOL>if context:<EOL><INDENT>_cms = self.correct_usage(_pi.result, context)<EOL><DEDENT>else:<EOL><INDENT>_cms = _pi.result<EOL><DEDENT>logger.debug('<STR_LIT>'.format(_cms))<EOL>if _cms:<EOL><INDENT>return self.evaluate_metadata_statement(_cms)<EOL><DEDENT>else:<EOL><INDENT>return []<EOL><DEDENT>

Unpack and evaluate a compound metadata statement. Goes through the
necessary three steps.
* unpack the metadata statement
* verify that the given statements are expected to be used in this context
* evaluate the metadata statements (= flatten)

:param input: The metadata statement as a JSON document or a
    dictionary
:param cls: The class the response should be typed into
:param context: In which context the metadata statement should be used.
:return: A list of :py:class:`fedoidc.operator.LessOrEqual` instances


def self_sign(self, req, receiver='<STR_LIT>', aud=None):

if self.entity_id:<EOL><INDENT>_iss = self.entity_id<EOL><DEDENT>else:<EOL><INDENT>_iss = self.iss<EOL><DEDENT>creq = req.copy()<EOL>if not '<STR_LIT>' in creq and not'<STR_LIT>' in creq:<EOL><INDENT>_copy = creq.copy()<EOL>_jws = self.self_signer.sign(_copy, receiver=receiver, iss=_iss,<EOL>aud=aud)<EOL>sms_spec = {'<STR_LIT>': {self.iss: _jws}}<EOL><DEDENT>else:<EOL><INDENT>for ref in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>try:<EOL><INDENT>del creq[ref]<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>sms_spec = {'<STR_LIT>': Message()}<EOL>for ref in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>if ref not in req:<EOL><INDENT>continue<EOL><DEDENT>for foid, value in req[ref].items():<EOL><INDENT>_copy = creq.copy()<EOL>_copy[ref] = Message()<EOL>_copy[ref][foid] = value<EOL>_jws = self.self_signer.sign(_copy, receiver=receiver,<EOL>iss=_iss, aud=aud)<EOL>sms_spec['<STR_LIT>'][foid] = _jws<EOL><DEDENT><DEDENT><DEDENT>creq.update(sms_spec)<EOL>return creq<EOL>

Sign the extended request.

:param req: Request, a :py:class:`fedoidcmsg.MetadataStatement' instance
:param receiver: The intended user of this metadata statement
:param aud: The audience, a list of receivers.
:return: An augmented set of request arguments


statement['<STR_LIT>'] = self.self_signer.export_jwks_as_json()<EOL>return statement<EOL>

Adding signing keys by value to a statement.

:param statement: Metadata statement to be extended
:return: The extended statement


def update_metadata_statement(self, metadata_statement, receiver='<STR_LIT>',<EOL>federation=None, context='<STR_LIT>'):

self.add_sms_spec_to_request(metadata_statement, federation=federation,<EOL>context=context)<EOL>self.add_signing_keys(metadata_statement)<EOL>metadata_statement = self.self_sign(metadata_statement, receiver)<EOL>del metadata_statement['<STR_LIT>']<EOL>return metadata_statement<EOL>

Update a metadata statement by:
 * adding signed metadata statements or uris pointing to signed
   metadata statements.
 * adding the entities signing keys
 * create metadata statements one per signed metadata statement or uri
   sign these and add them to the metadata statement

:param metadata_statement: A :py:class:`fedoidcmsg.MetadataStatement`
    instance
:param receiver: The intended receiver of the metadata statement
:param federation:
:param context:
:return: An augmented metadata statement


def add_sms_spec_to_request(self, req, federation='<STR_LIT>', loes=None,<EOL>context='<STR_LIT>'):

if federation:  <EOL><INDENT>if isinstance(federation, list):<EOL><INDENT>req.update(self.gather_metadata_statements(federation,<EOL>context=context))<EOL><DEDENT>else:<EOL><INDENT>req.update(self.gather_metadata_statements([federation],<EOL>context=context))<EOL><DEDENT><DEDENT>else:  <EOL><INDENT>if loes:<EOL><INDENT>_fos = list([r.fo for r in loes])<EOL>req.update(self.gather_metadata_statements(_fos,<EOL>context=context))<EOL><DEDENT>else:<EOL><INDENT>req.update(self.gather_metadata_statements(context=context))<EOL><DEDENT><DEDENT>return req<EOL>

Update a request with signed metadata statements.

:param req: The request
:param federation: Federation Operator ID
:param loes: List of :py:class:`fedoidc.operator.LessOrEqual` instances
:param context:
:return: The updated request


def gather_metadata_statements(self, fos=None, context='<STR_LIT>'):

if not context:<EOL><INDENT>context = self.context<EOL><DEDENT>_res = {}<EOL>if self.metadata_statements:<EOL><INDENT>try:<EOL><INDENT>cms = self.metadata_statements[context]<EOL><DEDENT>except KeyError:<EOL><INDENT>if self.metadata_statements == {<EOL>'<STR_LIT>': {},<EOL>'<STR_LIT>': {},<EOL>'<STR_LIT>': {}<EOL>}:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>logger.error(<EOL>'<STR_LIT>'.format(<EOL>context))<EOL>raise ValueError('<STR_LIT>'.format(context))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if cms != {}:<EOL><INDENT>if fos is None:<EOL><INDENT>fos = list(cms.keys())<EOL><DEDENT>for f in fos:<EOL><INDENT>try:<EOL><INDENT>val = cms[f]<EOL><DEDENT>except KeyError:<EOL><INDENT>continue<EOL><DEDENT>if val.startswith('<STR_LIT:http>'):<EOL><INDENT>value_type = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>value_type = '<STR_LIT>'<EOL><DEDENT>try:<EOL><INDENT>_res[value_type][f] = val<EOL><DEDENT>except KeyError:<EOL><INDENT>_res[value_type] = Message()<EOL>_res[value_type][f] = val<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>return _res<EOL>

Only gathers metadata statements and returns them.

:param fos: Signed metadata statements from these Federation Operators
    should be added.
:param context: context of the metadata exchange
:return: Dictionary with signed Metadata Statements as values


def add_sms_spec_to_request(self, req, federation='<STR_LIT>', loes=None,<EOL>context='<STR_LIT>', url='<STR_LIT>'):

<EOL>if federation:<EOL><INDENT>if not isinstance(federation, list):<EOL><INDENT>federation = [federation]<EOL><DEDENT><DEDENT>if not url:<EOL><INDENT>url = "<STR_LIT>".format(self.mds_service, context,<EOL>quote_plus(self.entity_id))<EOL><DEDENT>http_resp = self.httpcli(method='<STR_LIT:GET>', url=url, verify=self.verify_ssl)<EOL>if http_resp.status_code >= <NUM_LIT>:<EOL><INDENT>raise ConnectionError('<STR_LIT>'.format(http_resp.text))<EOL><DEDENT>msg = JsonWebToken().from_jwt(http_resp.text,<EOL>keyjar=self.jwks_bundle[self.mds_owner])<EOL>if msg['<STR_LIT>'] != self.mds_owner:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if federation:<EOL><INDENT>_ms = dict(<EOL>[(fo, _ms) for fo, _ms in msg.items() if fo in federation])<EOL><DEDENT>else:<EOL><INDENT>_ms = msg.extra()<EOL>try:<EOL><INDENT>del _ms['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>_sms = {}<EOL>_smsu = {}<EOL>for fo, item in _ms.items():<EOL><INDENT>if item.startswith('<STR_LIT>') or item.startswith('<STR_LIT>'):<EOL><INDENT>_smsu[fo] = item<EOL><DEDENT>else:<EOL><INDENT>_sms[fo] = item<EOL><DEDENT><DEDENT>if _sms:<EOL><INDENT>req.update({'<STR_LIT>': _sms})<EOL><DEDENT>if _smsu:<EOL><INDENT>req.update({'<STR_LIT>': _smsu})<EOL><DEDENT>return req<EOL>

Add signed metadata statements to the request

:param req: The request so far
:param federation: If only signed metadata statements from a specific
    set of federations should be included this is the set.
:param loes: - not used -
:param context: What kind of request/response it is: 'registration',
    'discovery' or 'response'. The later being registration response.
:param url: Just for testing !!
:return: A possibly augmented request.


<EOL>if federation:<EOL><INDENT>if not isinstance(federation, list):<EOL><INDENT>federation = [federation]<EOL><DEDENT><DEDENT>if not url:<EOL><INDENT>url = "<STR_LIT>".format(self.mdss_endpoint, context,<EOL>quote_plus(self.entity_id))<EOL><DEDENT>http_resp = self.httpcli(method='<STR_LIT:GET>', url=url, verify=self.verify_ssl)<EOL>if http_resp.status_code >= <NUM_LIT>:<EOL><INDENT>raise ConnectionError('<STR_LIT>'.format(http_resp.text))<EOL><DEDENT>msg = JsonWebToken().from_jwt(http_resp.text, keyjar=self.mdss_keys)<EOL>if msg['<STR_LIT>'] != self.mdss_owner:<EOL><INDENT>raise KeyError('<STR_LIT>')<EOL><DEDENT>if federation:<EOL><INDENT>_sms = dict(<EOL>[(fo, _ms) for fo, _ms in msg.items() if fo in federation])<EOL><DEDENT>else:<EOL><INDENT>_sms = msg.extra()<EOL>try:<EOL><INDENT>del _sms['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>req.update({'<STR_LIT>': _sms})<EOL>return req<EOL>


_jwt = JWT(ver_keys)<EOL>return _jwt.unpack(signed_bundle)<EOL>

Verify the signature of a signed JWT.

:param signed_bundle: A signed JWT where the body is a JWKS bundle
:param ver_keys: Keys that can be used to verify signatures of the
    signed_bundle.
:type ver_keys: A :py:class:`oidcmsg.key_jar.KeyJar` instance
:return: The bundle or None


def get_bundle(iss, ver_keys, bundle_file):

fp = open(bundle_file, '<STR_LIT:r>')<EOL>signed_bundle = fp.read()<EOL>fp.close()<EOL>return JWKSBundle(iss, None).upload_signed_bundle(signed_bundle, ver_keys)<EOL>

Read a signed JWKS bundle from disc, verify the signature and
instantiate a JWKSBundle instance with the information from the file.

:param iss:
:param ver_keys:
:param bundle_file:
:return:


def get_signing_keys(eid, keydef, key_file):

if os.path.isfile(key_file):<EOL><INDENT>kj = KeyJar()<EOL>kj.import_jwks(json.loads(open(key_file, '<STR_LIT:r>').read()), eid)<EOL><DEDENT>else:<EOL><INDENT>kj = build_keyjar(keydef)[<NUM_LIT:1>]<EOL>fp = open(key_file, '<STR_LIT:w>')<EOL>fp.write(json.dumps(kj.export_jwks()))<EOL>fp.close()<EOL>kj.issuer_keys[eid] = kj.issuer_keys['<STR_LIT>']<EOL><DEDENT>return kj<EOL>

If the *key_file* file exists then read the keys from there, otherwise
create the keys and store them a file with the name *key_file*.

:param eid: The ID of the entity that the keys belongs to
:param keydef: What keys to create
:param key_file: A file name
:return: A :py:class:`oidcmsg.key_jar.KeyJar` instance


if not isinstance(jwks, dict):<EOL><INDENT>try:<EOL><INDENT>jwks = json.loads(jwks)<EOL><DEDENT>except json.JSONDecodeError:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>kj = KeyJar()<EOL>kj.import_jwks(jwks, issuer=iss)<EOL>return kj<EOL>

Convert a JWKS to a KeyJar instance.

:param jwks: String representation of a JWKS
:return: A :py:class:`oidcmsg.key_jar.KeyJar` instance


return k_to_j(keyjar)<EOL>

Convert a KeyJar instance to a JWKS (JSON document).

:param keyjar: A :py:class:`oidcmsg.key_jar.KeyJar` instance


return k_to_j(keyjar, private=True)<EOL>

Convert a KeyJar instance to a JWKS (JSON document).
Including the private key.

:param keyjar: A :py:class:`oidcmsg.key_jar.KeyJar` instance


def __init__(self, iss, sign_keys=None):

self.iss = iss<EOL>self.sign_keys = sign_keys<EOL>self.bundle = {}<EOL>

:param iss: Issuer identifier, will be used as the value of 'iss'
    when a signed JWT containg the bundle is constructed.
:param sign_keys: Keys that this entity can use to sign JWTs.
:type sign_keys: py:class:`oidcmsg.key_jar.KeyJar` instance


if not isinstance(value, KeyJar):<EOL><INDENT>kj = KeyJar()<EOL>if isinstance(value, dict):<EOL><INDENT>kj.import_jwks(value, issuer=key)<EOL><DEDENT>else:<EOL><INDENT>kj.import_jwks_as_json(value, issuer=key)<EOL><DEDENT>value = kj<EOL><DEDENT>else:<EOL><INDENT>_val = value.copy()<EOL>_iss = list(_val.owners())<EOL>if _iss == ['<STR_LIT>']:<EOL><INDENT>_val.issuer_keys[key] = _val.issuer_keys['<STR_LIT>']<EOL>del _val.issuer_keys['<STR_LIT>']<EOL><DEDENT>elif len(_iss) == <NUM_LIT:1>:<EOL><INDENT>if _iss[<NUM_LIT:0>] != key:<EOL><INDENT>_val.issuer_keys[key] = _val.issuer_keys[_iss[<NUM_LIT:0>]]<EOL>del _val.issuer_keys[_iss[<NUM_LIT:0>]]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>value = _val<EOL><DEDENT>self.bundle[key] = value<EOL>

Add a set of keys, as a KeyJar or a JWKS under an issuer ID

:param key: issuer ID
:type: String
:param value: Cryptographic keys that should be connected to to an
 issuer ID.
:type value: KeyJar or a JWKS (JSON document)


kj = self.bundle[item]<EOL>if item not in list(kj.issuer_keys.keys()):<EOL><INDENT>kj.issuer_keys[item] = kj.issuer_keys['<STR_LIT>']<EOL>del kj.issuer_keys['<STR_LIT>']<EOL><DEDENT>return kj<EOL>

Returns a KeyJar instance representing the keys belonging to an
issuer

:param item: Issuer ID
:return: A KeyJar instance


del self.bundle[key]<EOL>

Remove the KeyJar that belong to a specific issuer

:param key: Issuer ID


def create_signed_bundle(self, sign_alg='<STR_LIT>', iss_list=None):

data = self.dict(iss_list)<EOL>_jwt = JWT(self.sign_keys, iss=self.iss, sign_alg=sign_alg)<EOL>return _jwt.pack({'<STR_LIT>':data})<EOL>

Create a signed JWT containing a dictionary with Issuer IDs as keys
and JWKSs as values. If iss_list is empty then all available issuers are
included.

:param sign_alg: Which algorithm to use when signing the JWT
:param iss_list: A list of issuer IDs who's keys should be included in
    the signed bundle.
:return: A signed JWT


if isinstance(jstr, dict):<EOL><INDENT>_info = jstr<EOL><DEDENT>else:<EOL><INDENT>_info = json.loads(jstr)<EOL><DEDENT>for iss, jwks in _info.items():<EOL><INDENT>kj = KeyJar()<EOL>if isinstance(jwks, dict):<EOL><INDENT>kj.import_jwks(jwks, issuer=iss)<EOL><DEDENT>else:<EOL><INDENT>kj.import_jwks_as_json(jwks, issuer=iss)<EOL><DEDENT>self.bundle[iss] = kj<EOL><DEDENT>return self<EOL>

Upload a bundle from an unsigned JSON document

:param jstr: A bundle as a dictionary or a JSON document


return json.dumps(self.dict(iss_list))<EOL>

Dumps a bundle of keys into a string. If iss_list is empty then all
available issuers are included

:param iss_list: List of issuers who's keys should be dumped
:return: A JSON document


return self.bundle.keys()<EOL>

Return a list of all issuers kept in this bundle.

:return: List of Issuer IDs


_int = {}<EOL>for iss, kj in self.bundle.items():<EOL><INDENT>if iss_list is None or iss in iss_list:<EOL><INDENT>try:<EOL><INDENT>_int[iss] = kj.export_jwks_as_json(issuer=iss)<EOL><DEDENT>except KeyError:<EOL><INDENT>_int[iss] = kj.export_jwks_as_json()<EOL><DEDENT><DEDENT><DEDENT>return _int<EOL>

Return the bundle of keys as a dictionary with the issuer IDs as
the keys and the key sets represented as JWKS instances.

:param iss_list: List of Issuer IDs that should be part of the
 output
:rtype: Dictionary


def upload_signed_bundle(self, sign_bundle, ver_keys):

jwt = verify_signed_bundle(sign_bundle, ver_keys)<EOL>self.loads(jwt['<STR_LIT>'])<EOL>

Input is a signed JWT with a JSON document representing the key bundle
as body. This method verifies the signature and the updates the instance
bundle with whatever was in the received package. Note, that as with
dictionary update if an Issuer ID already exists in the instance bundle
that will be overwritten with the new information.

:param sign_bundle: A signed JWT
:param ver_keys: Keys that can be used to verify the JWT signature.


kj = KeyJar()<EOL>for iss, k in self.bundle.items():<EOL><INDENT>try:<EOL><INDENT>kj.issuer_keys[iss] = k.issuer_keys[iss]<EOL><DEDENT>except KeyError:<EOL><INDENT>kj.issuer_keys[iss] = k.issuer_keys['<STR_LIT>']<EOL><DEDENT><DEDENT>return kj<EOL>

Convert a key bundle into a KeyJar instance.

:return: An :py:class:`oidcmsg.key_jar.KeyJar` instance


def __init__(self, iss, sign_keys=None, fdir='<STR_LIT>', key_conv=None):

JWKSBundle.__init__(self, iss, sign_keys=sign_keys)<EOL>self.bundle = FileSystem(fdir, key_conv=key_conv,<EOL>value_conv={'<STR_LIT:to>': keyjar_to_jwks,<EOL>'<STR_LIT>': jwks_to_keyjar})<EOL>

:param iss: Issuer ID for this entity
:param sign_keys: Signing Keys used by this entity to sign JWTs
:param fdir: A directory where JWKS can be stored
:param key_conv: Specification of directory key to file name conversion.
    A set of keys are represented in the local cache as a KeyJar
    instance and as a JWKS on disc.


_args = dict([(k, v) for k, v in config.items() if k in KJ_SPECS])<EOL>_kj = init_key_jar(**_args)<EOL>return InternalSigningService(entity_id, _kj)<EOL>

Given configuration initiate an InternalSigningService instance

:param config: The signing service configuration
:param entity_id: The entity identifier
:return: A InternalSigningService instance


_args = dict([(k, v) for k, v in config.items() if k in KJ_SPECS])<EOL>_kj = init_key_jar(**_args)<EOL>if config['<STR_LIT:type>'] == '<STR_LIT>':<EOL><INDENT>signer = InternalSigningService(entity_id, _kj)<EOL><DEDENT>elif config['<STR_LIT:type>'] == '<STR_LIT>':<EOL><INDENT>_kj.issuer_keys[config['<STR_LIT>']] = _kj.issuer_keys['<STR_LIT>']<EOL>del _kj.issuer_keys['<STR_LIT>']<EOL>signer = WebSigningServiceClient(config['<STR_LIT>'], config['<STR_LIT:url>'],<EOL>entity_id, _kj)<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>'.format(config['<STR_LIT:type>']))<EOL><DEDENT>return signer<EOL>

Given configuration initiate a SigningService instance

:param config: The signing service configuration
:param entity_id: The entity identifier
:return: A SigningService instance


def __init__(self, iss, keyjar, add_ons=None, alg='<STR_LIT>',<EOL>lifetime=<NUM_LIT>, keyconf=None, remove_after=<NUM_LIT>):

SigningService.__init__(self, add_ons=add_ons, alg=alg)<EOL>self.keyjar = keyjar<EOL>self.iss = iss<EOL>self.lifetime = lifetime<EOL>self.keyconf = keyconf<EOL>self.remove_after = remove_after<EOL>

:param iss: The ID for this entity
:param keyjar: Signing keys this entity can use to sign JWTs with.
:param add_ons: Additional information the signing service must
    add to the Metadata statement before signing it.
:param alg: The signing algorithm
:param lifetime: The lifetime of the signed JWT


def sign(self, req, receiver='<STR_LIT>', iss='<STR_LIT>', lifetime=<NUM_LIT:0>, sign_alg='<STR_LIT>', aud=None):

if not sign_alg:<EOL><INDENT>for key_type, s_alg in [('<STR_LIT>', '<STR_LIT>'), ('<STR_LIT>', '<STR_LIT>')]:<EOL><INDENT>if self.keyjar.get_signing_key(key_type=key_type):<EOL><INDENT>sign_alg = s_alg<EOL>break<EOL><DEDENT><DEDENT><DEDENT>if not sign_alg:<EOL><INDENT>raise NoSigningKeys('<STR_LIT>')<EOL><DEDENT>return self.pack(req=req, receiver=receiver, iss=iss, lifetime=lifetime,<EOL>sign=True, encrypt=False, sign_alg=sign_alg)<EOL>

Creates a signed JWT

:param req: Original metadata statement as a
    :py:class:`MetadataStatement` instance
:param receiver: The intended audience for the JWS
:param iss: Issuer or the JWT
:param lifetime: Lifetime of the signature
:param sign_alg: Which signature algorithm to use
:param aud: The audience, a list of receivers.
:return: A signed JWT


def encrypt(self, req, receiver='<STR_LIT>', iss='<STR_LIT>', lifetime=<NUM_LIT:0>,<EOL>enc_enc="<STR_LIT>", enc_alg="<STR_LIT>", aud=None):

return self.pack(req=req, receiver=receiver, iss=iss, lifetime=lifetime,<EOL>sign=False, encrypt=True, enc_enc=enc_enc,<EOL>enc_alg=enc_alg)<EOL>

:param req: Original metadata statement as a
    :py:class:`MetadataStatement` instance
:param receiver: The intended audience for the JWS
:param iss:
:param lifetime:
:param enc_alg:
:param enc_enc:
:param aud: The audience, a list of receivers.
:return: A dictionary with a signed JWT as value with the key 'sms'


def pack(self, req, receiver='<STR_LIT>', iss='<STR_LIT>', lifetime=<NUM_LIT:0>, sign=True,<EOL>sign_alg='<STR_LIT>', encrypt=False, enc_enc="<STR_LIT>",<EOL>enc_alg="<STR_LIT>", aud=None):

if not iss:<EOL><INDENT>iss = self.iss<EOL><DEDENT>if not lifetime:<EOL><INDENT>lifetime = self.lifetime<EOL><DEDENT>keyjar = self.keyjar<EOL>_metadata = copy.deepcopy(req)<EOL>if self.add_ons:<EOL><INDENT>_metadata.update(self.add_ons)<EOL><DEDENT>args = {}<EOL>if sign:<EOL><INDENT>if sign_alg:<EOL><INDENT>args['<STR_LIT>'] = sign_alg<EOL><DEDENT>else:<EOL><INDENT>args['<STR_LIT>'] = self.alg<EOL><DEDENT><DEDENT>if encrypt:<EOL><INDENT>args['<STR_LIT>'] = enc_enc<EOL>args['<STR_LIT>'] = enc_alg<EOL><DEDENT>_jwt = JWT(keyjar, iss=iss, msg_cls=_metadata.__class__,<EOL>lifetime=lifetime, **args)<EOL>if iss in keyjar.issuer_keys:<EOL><INDENT>owner = iss<EOL><DEDENT>else:<EOL><INDENT>owner = '<STR_LIT>'<EOL><DEDENT>return _jwt.pack(payload=_metadata.to_dict(), owner=owner,<EOL>recv=receiver, aud=aud)<EOL>

:param req: Original metadata statement as a
    :py:class:`MetadataStatement` instance
:param receiver: The immediate receiver of the JWS
:param iss:
:param lifetime:
:param sign:
:param sign_alg:
:param encrypt:
:param enc_alg:
:param enc_enc:
:param aud: The audience, a list of receivers.
:return: A dictionary with a signed JWT as value with the key 'sms'


def __init__(self, iss, url, eid, keyjar, add_ons=None, alg='<STR_LIT>',<EOL>token='<STR_LIT>', token_type='<STR_LIT>', verify_ssl_cert=True):

SigningService.__init__(self, add_ons=add_ons, alg=alg)<EOL>self.url = url<EOL>self.iss = iss<EOL>self.eid = eid<EOL>self.keyjar = keyjar<EOL>self.token = token<EOL>self.token_type = token_type<EOL>self.verify_ssl_cert = verify_ssl_cert<EOL>

:param iss: The issuer ID of the signer
:param url: The URL of the signing service
:param eid: The identifier of this entity
:param keyjar: A key jar containing the public part of the signers key
:param add_ons: Additional information the signing service must
    add to the Metadata statement before signing it.
:param alg: Signing algorithm


response = requests.post(self.url, json=req, **self.req_args())<EOL>return self.parse_response(response)<EOL>

Uses POST to send a first metadata statement signing request to
a signing service.

:param req: The metadata statement that the entity wants signed
:return: returns a dictionary with 'sms' and 'loc' as keys.


def update_metadata_statement(self, location, req):

response = requests.put(location, json=req, **self.req_args())<EOL>return self.parse_response(response)<EOL>

Uses PUT to update an earlier accepted and signed metadata statement.

:param location: A URL to which the update request is sent
:param req: The diff between what is registereed with the signing
    service and what it should be.
:return: returns a dictionary with 'sms' and 'loc' as keys.


response = requests.get(location, **self.req_args())<EOL>return self.parse_response(response)<EOL>

Uses GET to get a newly signed metadata statement.

:param location: A URL to which the request is sent
:return: returns a dictionary with 'sms' and 'loc' as keys.


def __init__(self, fdir, key_conv=None, value_conv=None, c_size=<NUM_LIT:0>):

self.fdir = fdir<EOL>self.fmtime = {}<EOL>self.db = {}<EOL>self.key_conv = key_conv or {}<EOL>self.value_conv = value_conv or {}<EOL>if not os.path.isdir(fdir):<EOL><INDENT>os.makedirs(fdir)<EOL><DEDENT>

:param fdir: The root of the directory
:param key_conv: Converts to/from the key displayed by this class to
users of it to something that can be used as a file name.
The value of key_conv is a dictionary with to keys ['to', 'from']
where the value of 'to' is a function that can be used to convert
the instance key value to the file name. The value of 'from' is a
function that can be used to convert a file name to a key value.
:type key_conv: Dictionary
:param value_conv: As with key_conv you can convert/translate
the value bound to a key in the database to something that can easily
be stored in a file. Like with key_conv the value of this parameter
is a dictionary with the keys ['to', 'from'].
:type value_conv: dictionary


try:<EOL><INDENT>item = self.key_conv['<STR_LIT:to>'](item)<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>if self.is_changed(item):<EOL><INDENT>logger.info("<STR_LIT>".format(item))<EOL>fname = os.path.join(self.fdir, item)<EOL>self.db[item] = self._read_info(fname)<EOL><DEDENT>return self.db[item]<EOL>

Return the value bound to an identifier.

:param item: The identifier.
:return:


if not os.path.isdir(self.fdir):<EOL><INDENT>os.makedirs(self.fdir, exist_ok=True)<EOL><DEDENT>try:<EOL><INDENT>_key = self.key_conv['<STR_LIT:to>'](key)<EOL><DEDENT>except KeyError:<EOL><INDENT>_key = key<EOL><DEDENT>fname = os.path.join(self.fdir, _key)<EOL>fp = open(fname, '<STR_LIT:w>')<EOL>try:<EOL><INDENT>fp.write(self.value_conv['<STR_LIT:to>'](value))<EOL><DEDENT>except KeyError:<EOL><INDENT>fp.write(value)<EOL><DEDENT>fp.close()<EOL>self.db[_key] = value<EOL>self.fmtime[_key] = self.get_mtime(fname)<EOL>

Binds a value to a specific key. If the file that the key maps to
does not exist it will be created. The content of the file will be
set to the value given.

:param key: Identifier
:param value: Value that should be bound to the identifier.
:return:


self.sync()<EOL>for k in self.db.keys():<EOL><INDENT>try:<EOL><INDENT>yield self.key_conv['<STR_LIT>'](k)<EOL><DEDENT>except KeyError:<EOL><INDENT>yield k<EOL><DEDENT><DEDENT>


try:<EOL><INDENT>mtime = os.stat(fname).st_mtime_ns<EOL><DEDENT>except OSError:<EOL><INDENT>time.sleep(<NUM_LIT:1>)<EOL>mtime = os.stat(fname).st_mtime_ns<EOL><DEDENT>return mtime<EOL>

Find the time this file was last modified.

:param fname: File name
:return: The last time the file was modified.


fname = os.path.join(self.fdir, item)<EOL>if os.path.isfile(fname):<EOL><INDENT>mtime = self.get_mtime(fname)<EOL>try:<EOL><INDENT>_ftime = self.fmtime[item]<EOL><DEDENT>except KeyError:  <EOL><INDENT>self.fmtime[item] = mtime<EOL>return True<EOL><DEDENT>if mtime > _ftime:  <EOL><INDENT>self.fmtime[item] = mtime<EOL>return True<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>else:<EOL><INDENT>logger.error('<STR_LIT>'.format(fname))<EOL>raise KeyError(item)<EOL><DEDENT>

Find out if this item has been modified since last

:param item: A key
:return: True/False


if not os.path.isdir(self.fdir):<EOL><INDENT>os.makedirs(self.fdir)<EOL><DEDENT>for f in os.listdir(self.fdir):<EOL><INDENT>fname = os.path.join(self.fdir, f)<EOL>if not os.path.isfile(fname):<EOL><INDENT>continue<EOL><DEDENT>if f in self.fmtime:<EOL><INDENT>if self.is_changed(f):<EOL><INDENT>self.db[f] = self._read_info(fname)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>mtime = self.get_mtime(fname)<EOL>self.db[f] = self._read_info(fname)<EOL>self.fmtime[f] = mtime<EOL><DEDENT><DEDENT>

Goes through the directory and builds a local cache based on
the content of the directory.


self.sync()<EOL>for k, v in self.db.items():<EOL><INDENT>try:<EOL><INDENT>yield self.key_conv['<STR_LIT>'](k), v<EOL><DEDENT>except KeyError:<EOL><INDENT>yield k, v<EOL><DEDENT><DEDENT>


if not os.path.isdir(self.fdir):<EOL><INDENT>os.makedirs(self.fdir, exist_ok=True)<EOL>return<EOL><DEDENT>for f in os.listdir(self.fdir):<EOL><INDENT>del self[f]<EOL><DEDENT>

Completely resets the database. This means that all information in
the local cache and on disc will be erased.


for key, val in ava.items():<EOL><INDENT>self[key] = val<EOL><DEDENT>


_rp_jwt = factory(jwt)<EOL>return json.loads(_rp_jwt.jwt.part[<NUM_LIT:1>].decode('<STR_LIT:utf8>'))<EOL>

Return the body of a signed JWT, without verifying the signature.

:param jwt: A signed JWT
:return: The body of the JWT as a 'UTF-8' string


keyjar = KeyJar()<EOL>for ms in msl:<EOL><INDENT>keyjar.import_jwks(ms['<STR_LIT>'], iss)<EOL><DEDENT>return keyjar<EOL>

Builds a keyJar instance based on the information in the 'signing_keys'
claims in a list of metadata statements.

:param iss: Owner of the signing keys
:param msl: List of :py:class:`MetadataStatement` instances.
:return: A :py:class:`oidcmsg.key_jar.KeyJar` instance


_jwks = open(jwks_file, '<STR_LIT:r>').read()<EOL>_kj = KeyJar()<EOL>_kj.import_jwks(json.loads(_jwks), '<STR_LIT>')<EOL>return _kj<EOL>

Reads a file containing a JWKS and populates a
:py:class:`oidcmsg.key_jar.KeyJar` from it.

:param jwks_file: file name of the JWKS file
:return: A :py:class:`oidcmsg.key_jar.KeyJar` instance


if type(a) != type(b):<EOL><INDENT>return False<EOL><DEDENT>if isinstance(a, str) and isinstance(b, str):<EOL><INDENT>return a == b<EOL><DEDENT>elif isinstance(a, bool) and isinstance(b, bool):<EOL><INDENT>return a == b<EOL><DEDENT>elif isinstance(a, list) and isinstance(b, list):<EOL><INDENT>for element in a:<EOL><INDENT>flag = <NUM_LIT:0><EOL>for e in b:<EOL><INDENT>if is_lesser(element, e):<EOL><INDENT>flag = <NUM_LIT:1><EOL>break<EOL><DEDENT><DEDENT>if not flag:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL><DEDENT>elif isinstance(a, dict) and isinstance(b, dict):<EOL><INDENT>if is_lesser(list(a.keys()), list(b.keys())):<EOL><INDENT>for key, val in a.items():<EOL><INDENT>if not is_lesser(val, b[key]):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL><DEDENT>return False<EOL><DEDENT>elif isinstance(a, int) and isinstance(b, int):<EOL><INDENT>return a <= b<EOL><DEDENT>elif isinstance(a, float) and isinstance(b, float):<EOL><INDENT>return a <= b<EOL><DEDENT>return False<EOL>

Verify that an item *a* is <= then an item *b*

:param a: An item
:param b: Another item
:return: True or False


super(MetadataStatement, self).verify(**kwargs)<EOL>if "<STR_LIT>" in self:<EOL><INDENT>if '<STR_LIT>' in self:<EOL><INDENT>raise VerificationError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>kj = KeyJar()<EOL>try:<EOL><INDENT>kj.import_jwks(self['<STR_LIT>'], '<STR_LIT>')<EOL><DEDENT>except Exception:<EOL><INDENT>raise VerificationError('<STR_LIT>')<EOL><DEDENT><DEDENT><DEDENT>if "<STR_LIT>" in self and "<STR_LIT>" in self:<EOL><INDENT>s = set(self['<STR_LIT>'].keys())<EOL>t = set(self['<STR_LIT>'].keys())<EOL>if s.intersection(t):<EOL><INDENT>raise VerificationError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>return True<EOL>

Verifies that an instance of this class adheres to the given
restrictions.

:param kwargs: A set of keyword arguments
:return: True if it verifies OK otherwise False.


<EOL>try:<EOL><INDENT>if response.headers["<STR_LIT:Content-Type>"] == '<STR_LIT:application/json>':<EOL><INDENT>logger.debug(<EOL>"<STR_LIT>" % (response.text, self.source))<EOL>try:<EOL><INDENT>return json.loads(response.text)<EOL><DEDENT>except ValueError:<EOL><INDENT>return None<EOL><DEDENT><DEDENT>elif response.headers["<STR_LIT:Content-Type>"] == '<STR_LIT>':<EOL><INDENT>logger.debug(<EOL>"<STR_LIT>" % (response.text, self.source))<EOL>_jws = factory(response.text)<EOL>_resp = _jws.verify_compact(<EOL>response.text, keys=self.verify_keys.get_signing_key())<EOL>return _resp<EOL><DEDENT>else:<EOL><INDENT>logger.error('<STR_LIT>'.format(<EOL>response.headers['<STR_LIT:Content-Type>']))<EOL>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>

Parse simple JWKS or signed JWKS from the HTTP response.

:param response: HTTP response from the 'jwks_uri' or 'signed_jwks_uri'
    endpoint
:return: response parsed as JSON or None


def make_signing_sequence(entity_id, entity_dict, context='<STR_LIT>',<EOL>lifetime=<NUM_LIT>):

n = len(entity_id)<EOL>i = n-<NUM_LIT:1><EOL>fo = entity_dict[entity_id[i]].iss<EOL>sms = None<EOL>i -= <NUM_LIT:1><EOL>while i >= <NUM_LIT:0>:<EOL><INDENT>metadata_statement = MetadataStatement()<EOL>ent = entity_dict[entity_id[i]]<EOL>ent.add_signing_keys(metadata_statement)<EOL>sup = entity_dict[entity_id[i+<NUM_LIT:1>]]<EOL>sup.add_sms_spec_to_request(metadata_statement, context=context)<EOL>sms = sup.self_signer.sign(metadata_statement, ent.iss,<EOL>lifetime=lifetime)<EOL>try:<EOL><INDENT>ent.metadata_statements[context][fo] = sms<EOL><DEDENT>except KeyError:<EOL><INDENT>ent.metadata_statements[context] = {fo: sms}<EOL><DEDENT>i -= <NUM_LIT:1><EOL><DEDENT>return sms<EOL>

Signing sequence with nothing but keys no actual content

:param entity_id: A list of entity IDs
:param entity_dict: A dictionayr with entity IDs as keys and
    :py:class:`fedoidcmsg.entity.FederationEntity` instances as values.
:param context:
:param lifetime: The lifetime of the JWT signatures
:return: A signed compounded metadata statement


def create_compounded_metadata_statement(entity_id, entity_dict, statement,<EOL>context='<STR_LIT>', lifetime=<NUM_LIT>):

n = len(entity_id)<EOL>i = n-<NUM_LIT:1><EOL>fo = entity_dict[entity_id[i]].iss<EOL>sms = None<EOL>i -= <NUM_LIT:1><EOL>while i >= <NUM_LIT:0>:<EOL><INDENT>cms = statement[entity_id[i]]<EOL>ent = entity_dict[entity_id[i]]<EOL>ent.add_signing_keys(cms)<EOL>sup = entity_dict[entity_id[i+<NUM_LIT:1>]]<EOL>sup.add_sms_spec_to_request(cms, context=context)<EOL>sms = sup.self_signer.sign(cms, ent.iss, lifetime=lifetime)<EOL>try:<EOL><INDENT>ent.metadata_statements[context][fo] = sms<EOL><DEDENT>except KeyError:<EOL><INDENT>ent.metadata_statements[context] = {fo: sms}<EOL><DEDENT>i -= <NUM_LIT:1><EOL><DEDENT>return sms<EOL>

:param entity_id:
:param entity_dict:
:param statement:
:param context:
:param lifetime:
:return:


def self_sign_jwks(keyjar, iss, kid='<STR_LIT>', lifetime=<NUM_LIT>):

<EOL>_jwt = JWT(keyjar, iss=iss, lifetime=lifetime)<EOL>jwks = keyjar.export_jwks(issuer=iss)<EOL>return _jwt.pack(payload={'<STR_LIT>': jwks}, owner=iss, kid=kid)<EOL>

Create a signed JWT containing a JWKS. The JWT is signed by one of the
keys in the JWKS.

:param keyjar: A KeyJar instance with at least one private signing key
:param iss: issuer of the JWT, should be the owner of the keys
:param kid: A key ID if a special key should be used otherwise one
    is picked at random.
:param lifetime: The lifetime of the signed JWT
:return: A signed JWT


_jws = factory(sjwt)<EOL>_json = _jws.jwt.part[<NUM_LIT:1>]<EOL>_body = json.loads(as_unicode(_json))<EOL>iss = _body['<STR_LIT>']<EOL>_jwks = _body['<STR_LIT>']<EOL>_kj = jwks_to_keyjar(_jwks, iss)<EOL>try:<EOL><INDENT>_kid = _jws.jwt.headers['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>_keys = _kj.get_signing_key(owner=iss)<EOL><DEDENT>else:<EOL><INDENT>_keys = _kj.get_signing_key(owner=iss, kid=_kid)<EOL><DEDENT>_ver = _jws.verify_compact(sjwt, _keys)<EOL>return {'<STR_LIT>': _ver['<STR_LIT>'], '<STR_LIT>': iss}<EOL>

Verify the signature of a signed JWT containing a JWKS.
The JWT is signed by one of the keys in the JWKS.
In the JWT the JWKS is stored using this format ::

    'jwks': {
        'keys': [ ]
    }

:param sjwt: Signed Jason Web Token
:return: Dictionary containing 'jwks' (the JWKS) and 'iss' (the issuer of
    the JWT)


def request_signed_by_signing_keys(keyjar, msreq, iss, lifetime, kid='<STR_LIT>'):

try:<EOL><INDENT>jwks_to_keyjar(msreq['<STR_LIT>'], iss)<EOL><DEDENT>except KeyError:<EOL><INDENT>jwks = keyjar.export_jwks(issuer=iss)<EOL>msreq['<STR_LIT>'] = jwks<EOL><DEDENT>_jwt = JWT(keyjar, iss=iss, lifetime=lifetime)<EOL>return _jwt.pack(owner=iss, kid=kid, payload=msreq.to_dict())<EOL>

A metadata statement signing request with 'signing_keys' signed by one
of the keys in 'signing_keys'.

:param keyjar: A KeyJar instance with the private signing key
:param msreq: Metadata statement signing request. A MetadataStatement
    instance.
:param iss: Issuer of the signing request also the owner of the signing
    keys.
:return: Signed JWT where the body is the metadata statement


_jws = factory(smsreq)<EOL>_json = _jws.jwt.part[<NUM_LIT:1>]<EOL>_body = json.loads(as_unicode(_json))<EOL>iss = _body['<STR_LIT>']<EOL>_jwks = _body['<STR_LIT>']<EOL>_kj = jwks_to_keyjar(_jwks, iss)<EOL>try:<EOL><INDENT>_kid = _jws.jwt.headers['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>_keys = _kj.get_signing_key(owner=iss)<EOL><DEDENT>else:<EOL><INDENT>_keys = _kj.get_signing_key(owner=iss, kid=_kid)<EOL><DEDENT>_ver = _jws.verify_compact(smsreq, _keys)<EOL>for k in JsonWebToken.c_param.keys():<EOL><INDENT>try:<EOL><INDENT>del _ver[k]<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>try:<EOL><INDENT>del _ver['<STR_LIT>']<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>return {'<STR_LIT>': MetadataStatement(**_ver), '<STR_LIT>': iss}<EOL>

Verify that a JWT is signed with a key that is inside the JWT.

:param smsreq: Signed Metadata Statement signing request
:return: Dictionary containing 'ms' (the signed request) and 'iss' (the
    issuer of the JWT).


def __init__(self, iss='<STR_LIT>', sup=None, exp=<NUM_LIT:0>, keyjar=None, **kwargs):

if sup:<EOL><INDENT>self.fo = sup.fo<EOL><DEDENT>else:<EOL><INDENT>self.fo = iss<EOL><DEDENT>self.iss = iss<EOL>self.sup = sup<EOL>self.err = {}<EOL>self.le = {}<EOL>self.exp = exp<EOL>self.keyjar = keyjar<EOL>

:param iss: Issuer ID
:param sup: Superior
:type sup: LessOrEqual instance
:param exp: Expiration time


if self.sup:<EOL><INDENT>return self.sup.le.items()<EOL><DEDENT>else:<EOL><INDENT>return {}<EOL><DEDENT>


_le = {}<EOL>_err = []<EOL>for k, v in self.sup_items():<EOL><INDENT>if k in DoNotCompare:<EOL><INDENT>continue<EOL><DEDENT>if k in orig:<EOL><INDENT>if is_lesser(orig[k], v):<EOL><INDENT>_le[k] = orig[k]<EOL><DEDENT>else:<EOL><INDENT>_err.append({'<STR_LIT>': k, '<STR_LIT>': orig[k], '<STR_LIT>': v,<EOL>'<STR_LIT>': self.iss})<EOL><DEDENT><DEDENT>else:<EOL><INDENT>_le[k] = v<EOL><DEDENT><DEDENT>for k, v in orig.items():<EOL><INDENT>if k in DoNotCompare:<EOL><INDENT>continue<EOL><DEDENT>if k not in _le:<EOL><INDENT>_le[k] = v<EOL><DEDENT><DEDENT>self.le = _le<EOL>self.err = _err<EOL>

Apply the less or equal algorithm on the ordered list of metadata
statements

:param orig: Start values
:return:


if self.sup:<EOL><INDENT>return self.sup.le<EOL><DEDENT>

Someone in the list of signers has said this information is OK


if self.sup:<EOL><INDENT>res = {}<EOL>for k, v in self.le.items():<EOL><INDENT>if k not in self.sup.le:<EOL><INDENT>res[k] = v<EOL><DEDENT>else:<EOL><INDENT>res[k] = self.sup.le[k]<EOL><DEDENT><DEDENT>return res<EOL><DEDENT>else:<EOL><INDENT>return self.le<EOL><DEDENT>

This is both verified and self asserted information. As expected
verified information beats self-asserted so if there is both
self-asserted and verified values for a claim then only the verified
will be returned.


def __init__(self, self_signer=None, jwks_bundle=None, httpcli=None,<EOL>iss=None, lifetime=<NUM_LIT>, verify_ssl=True):

self.self_signer = self_signer<EOL>self.jwks_bundle = jwks_bundle<EOL>self.httpcli = httpcli<EOL>self.iss = iss<EOL>self.failed = {}<EOL>self.lifetime = lifetime<EOL>self.verify_ssl = verify_ssl<EOL>

:param self_signer: A Signing Service instance
:param jwks_bundle: Contains the federation operators signing keys
    for all the federations this instance wants to talk to.
    If present it MUST be a JWKSBundle instance.
:param httpcli: A http client to use when information has to be
    fetched from somewhere else
:param iss: Issuer ID
:param lifetime: Default lifetime of signed statements produced
    by this signer.
:param verify_ssl: Whether SSL certificates should be verified


_l = [x.serialize() for x in self.self_signer.keyjar.get_signing_key()]<EOL>if not _l:<EOL><INDENT>_l = [x.serialize() for x in<EOL>self.self_signer.keyjar.get_signing_key(owner=self.iss)]<EOL><DEDENT>return {'<STR_LIT>': _l}<EOL>

Build a JWKS from the signing keys belonging to the self signer

:return: Dictionary


def _unpack(self, ms_dict, keyjar, cls, jwt_ms=None, liss=None):

if liss is None:<EOL><INDENT>liss = []<EOL><DEDENT>_pr = ParseInfo()<EOL>_pr.input = ms_dict<EOL>ms_flag = False<EOL>if '<STR_LIT>' in ms_dict:<EOL><INDENT>ms_flag = True<EOL>for iss, _ms in ms_dict['<STR_LIT>'].items():<EOL><INDENT>if liss and iss not in liss:<EOL><INDENT>continue<EOL><DEDENT>_pr = self._ums(_pr, _ms, keyjar)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in ms_dict:<EOL><INDENT>ms_flag = True<EOL>if self.httpcli:<EOL><INDENT>for iss, url in ms_dict['<STR_LIT>'].items():<EOL><INDENT>if liss and iss not in liss:<EOL><INDENT>continue<EOL><DEDENT>rsp = self.httpcli(method='<STR_LIT:GET>', url=url,<EOL>verify=self.verify_ssl)<EOL>if rsp.status_code == <NUM_LIT:200>:<EOL><INDENT>_pr = self._ums(_pr, rsp.text, keyjar)<EOL><DEDENT>else:<EOL><INDENT>raise ParseError(<EOL>'<STR_LIT>'.format(url))<EOL><DEDENT><DEDENT><DEDENT><DEDENT>for _ms in _pr.parsed_statement:<EOL><INDENT>if _ms:  <EOL><INDENT>loaded = False<EOL>try:<EOL><INDENT>keyjar.import_jwks_as_json(_ms['<STR_LIT>'],<EOL>ms_dict['<STR_LIT>'])<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT>except TypeError:<EOL><INDENT>try:<EOL><INDENT>keyjar.import_jwks(_ms['<STR_LIT>'], ms_dict['<STR_LIT>'])<EOL><DEDENT>except Exception as err:<EOL><INDENT>logger.error(err)<EOL>raise<EOL><DEDENT>else:<EOL><INDENT>loaded = True<EOL><DEDENT><DEDENT>else:<EOL><INDENT>loaded = True<EOL><DEDENT>if loaded:<EOL><INDENT>logger.debug(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'.format(ms_dict['<STR_LIT>']))<EOL><DEDENT><DEDENT><DEDENT>if ms_flag is True and not _pr.parsed_statement:<EOL><INDENT>return _pr<EOL><DEDENT>if jwt_ms:<EOL><INDENT>logger.debug("<STR_LIT>".format(jwt_ms))<EOL>try:<EOL><INDENT>_pr.result = cls().from_jwt(jwt_ms, keyjar=keyjar)<EOL><DEDENT>except MissingSigningKey:<EOL><INDENT>if '<STR_LIT>' in ms_dict:<EOL><INDENT>try:<EOL><INDENT>_pr.result = self.self_signed(ms_dict, jwt_ms, cls)<EOL><DEDENT>except MissingSigningKey as err:<EOL><INDENT>logger.error('<STR_LIT>'.format(err))<EOL>_pr.error[jwt_ms] = err<EOL><DEDENT><DEDENT><DEDENT>except (JWSException, BadSignature, KeyError) as err:<EOL><INDENT>logger.error('<STR_LIT>'.format(err))<EOL>_pr.error[jwt_ms] = err<EOL><DEDENT><DEDENT>else:<EOL><INDENT>_pr.result = ms_dict<EOL><DEDENT>if _pr.result and _pr.parsed_statement:<EOL><INDENT>_prr = _pr.result<EOL>_res = {}<EOL>for x in _pr.parsed_statement:<EOL><INDENT>if x:<EOL><INDENT>_res[get_fo(x)] = x<EOL><DEDENT><DEDENT>_msg = Message(**_res)<EOL>logger.debug('<STR_LIT>'.format(_msg))<EOL>_pr.result['<STR_LIT>'] = _msg<EOL><DEDENT>return _pr<EOL>

:param ms_dict: Metadata statement as a dictionary
:param keyjar: A keyjar with the necessary FO keys
:param cls: What class to map the metadata into
:param jwt_ms: Metadata statement as a JWS
:param liss: List of FO issuer IDs
:return: ParseInfo instance


def unpack_metadata_statement(self, ms_dict=None, jwt_ms='<STR_LIT>', keyjar=None,<EOL>cls=ClientMetadataStatement, liss=None):

if not keyjar:<EOL><INDENT>if self.jwks_bundle:<EOL><INDENT>keyjar = self.jwks_bundle.as_keyjar()<EOL><DEDENT>else:<EOL><INDENT>keyjar = KeyJar()<EOL><DEDENT><DEDENT>if jwt_ms:<EOL><INDENT>try:<EOL><INDENT>ms_dict = unfurl(jwt_ms)<EOL><DEDENT>except JWSException as err:<EOL><INDENT>logger.error('<STR_LIT>'.format(err))<EOL>raise<EOL><DEDENT><DEDENT>if ms_dict:<EOL><INDENT>return self._unpack(ms_dict, keyjar, cls, jwt_ms, liss)<EOL><DEDENT>else:<EOL><INDENT>raise AttributeError('<STR_LIT>')<EOL><DEDENT>

Starting with a signed JWT or a JSON document unpack and verify all
the separate metadata statements.

:param ms_dict: Metadata statement as a dictionary
:param jwt_ms: Metadata statement as JWT
:param keyjar: Keys that should be used to verify the signature of the
    document
:param cls: What type (Class) of metadata statement this is
:param liss: list of FO identifiers that matters. The rest will be
    ignored
:return: A ParseInfo instance


def pack_metadata_statement(self, metadata, receiver='<STR_LIT>', iss='<STR_LIT>', lifetime=<NUM_LIT:0>,<EOL>sign_alg='<STR_LIT>'):

return self.self_signer.sign(metadata, receiver=receiver, iss=iss,<EOL>lifetime=lifetime, sign_alg=sign_alg)<EOL>

Given a MetadataStatement instance create a signed JWT.

:param metadata: Original metadata statement as a MetadataStatement
    instance
:param receiver: Receiver (audience) of the JWT
:param iss: Issuer ID if different from default
:param lifetime: jWT signature life time
:param sign_alg: JWT signature algorithm
:return: A JWT