# packages

pkgId: ef2c83f1f11d5936dc2b5badec22b4dd32f32de7643178a379a6f11e3672c88b
name: rh-python36-decorator
arch: noarch
version: 4.4.1
epoch: 0
release: 1
summary: Better living through Python with decorators
url: https://github.com/micheles/decorator
rpm_license: new BSD License
rpm_vendor: Michele Simionato <michele.simionato@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: cc231b4f5c1041e198eabdb07b9a049a
rpm_sourcerpm: rh-python36-decorator-4.4.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387224-rh-python36-decorator/rh-python36-decorator-4.4.1-1.noarch.rpm
checksum_type: sha256
description:
  Decorator module
  =================

  :Author: Michele Simionato
  :E-mail: michele.simionato@gmail.com
  :Requires: Python from 2.6 to 3.6
  :Download page: http://pypi.python.org/pypi/decorator
  :Installation: ``pip install decorator``
  :License: BSD license

  Installation
  -------------

  If you are lazy, just perform

   `$ pip install decorator`

  which will install just the module on your system.

  If you prefer to install the full distribution from source, including
  the documentation, clone the `GitHub repo`_ or download the tarball_, unpack it and run

   `$ pip install .`

  in the main directory, possibly as superuser.

  .. _tarball: http://pypi.python.org/pypi/decorator
  .. _GitHub repo: https://github.com/micheles/decorator

  Testing
  --------

  If you have the source code installation you can run the tests with

   `$ python src/tests/test.py -v`

  or (if you have setuptools installed)

   `$ python setup.py test`

  Notice that you may run into trouble if in your system there
  is an older version of the decorator module; in such a case remove the
  old version. It is safe even to copy the module `decorator.py` over
  an existing one, since we kept backward-compatibility for a long time.

  Repository
  ---------------

  The project is hosted on GitHub. You can look at the source here:

   https://github.com/micheles/decorator

  Documentation
  ---------------

  The documentation has been moved to http://decorator.readthedocs.io/en/latest/
  You can download a PDF version of it from http://media.readthedocs.org/pdf/decorator/latest/decorator.pdf


pkgId: 037daa08a0437a946620c734e0f7fb40e51de97818fdaff2542387adc7368d9a
name: rh-python36-defusedxml
arch: noarch
version: 0.5.0
epoch: 0
release: 1
summary: XML bomb protection for Python stdlib modules
url: https://github.com/tiran/defusedxml
rpm_license: PSFL
rpm_vendor: Christian Heimes <christian@python.org>
rpm_group: Development/Libraries
rpm_buildhost: 777d54758d6740fb8bd48747e075bfb4
rpm_sourcerpm: rh-python36-defusedxml-0.5.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387085-rh-python36-defusedxml/rh-python36-defusedxml-0.5.0-1.noarch.rpm
checksum_type: sha256
description:
  ===================================================
  defusedxml -- defusing XML bombs and other exploits
  ===================================================

      "It's just XML, what could probably go wrong?"

  Christian Heimes <christian@python.org>

  Synopsis
  ========

  The results of an attack on a vulnerable XML library can be fairly dramatic.
  With just a few hundred **Bytes** of XML data an attacker can occupy several
  **Gigabytes** of memory within **seconds**. An attacker can also keep
  CPUs busy for a long time with a small to medium size request. Under some
  circumstances it is even possible to access local files on your
  server, to circumvent a firewall, or to abuse services to rebound attacks to
  third parties.

  The attacks use and abuse less common features of XML and its parsers. The
  majority of developers are unacquainted with features such as processing
  instructions and entity expansions that XML inherited from SGML. At best
  they know about ``<!DOCTYPE>`` from experience with HTML but they are not
  aware that a document type definition (DTD) can generate an HTTP request
  or load a file from the file system.

  None of the issues is new. They have been known for a long time. Billion
  laughs was first reported in 2003. Nevertheless some XML libraries and
  applications are still vulnerable and even heavy users of XML are
  surprised by these features. It's hard to say whom to blame for the
  situation. It's too short sighted to shift all blame on XML parsers and
  XML libraries for using insecure default settings. After all they
  properly implement XML specifications. Application developers must not rely
  that a library is always configured for security and potential harmful data
  by default.


  .. contents:: Table of Contents
     :depth: 2


  Attack vectors
  ==============

  billion laughs / exponential entity expansion
  ---------------------------------------------

  The `Billion Laughs`_ attack -- also known as exponential entity expansion --
  uses multiple levels of nested entities. The original example uses 9 levels
  of 10 expansions in each level to expand the string ``lol`` to a string of
  3 * 10 :sup:`9` bytes, hence the name "billion laughs". The resulting string
  occupies 3 GB (2.79 GiB) of memory; intermediate strings require additional
  memory. Because most parsers don't cache the intermediate step for every
  expansion it is repeated over and over again. It increases the CPU load even
  more.

  An XML document of just a few hundred bytes can disrupt all services on a
  machine within seconds.

  Example XML::

      <!DOCTYPE xmlbomb [
      <!ENTITY a "1234567890" >
      <!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;">
      <!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;">
      <!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;">
      ]>
      <bomb>&d;</bomb>


  quadratic blowup entity expansion
  ---------------------------------

  A quadratic blowup attack is similar to a `Billion Laughs`_ attack; it abuses
  entity expansion, too. Instead of nested entities it repeats one large entity
  with a couple of thousand chars over and over again. The attack isn't as
  efficient as the exponential case but it avoids triggering countermeasures of
  parsers against heavily nested entities. Some parsers limit the depth and
  breadth of a single entity but not the total amount of expanded text
  throughout an entire XML document.

  A medium-sized XML document with a couple of hundred kilobytes can require a
  couple of hundred MB to several GB of memory. When the attack is combined
  with some level of nested expansion an attacker is able to achieve a higher
  ratio of success.

  ::

      <!DOCTYPE bomb [
      <!ENTITY a "xxxxxxx... a couple of ten thousand chars">
      ]>
      <bomb>&a;&a;&a;... repeat</bomb>


  external entity expansion (remote)
  ----------------------------------

  Entity declarations can contain more than just text for replacement. They can
  also point to external resources by public identifiers or system identifiers.
  System identifiers are standard URIs. When the URI is a URL (e.g. a
  ``http://`` locator) some parsers download the resource from the remote
  location and embed them into the XML document verbatim.

  Simple example of a parsed external entity::

      <!DOCTYPE external [
      <!ENTITY ee SYSTEM "http://www.python.org/some.xml">
      ]>
      <root>&ee;</root>

  The case of parsed external entities works only for valid XML content. The
  XML standard also supports unparsed external entities with a
  ``NData declaration``.

  External entity expansion opens the door to plenty of exploits. An attacker
  can abuse a vulnerable XML library and application to rebound and forward
  network requests with the IP address of the server. It highly depends
  on the parser and the application what kind of exploit is possible. For
  example:

  * An attacker can circumvent firewalls and gain access to restricted
    resources as all the requests are made from an internal and trustworthy
    IP address, not from the outside.
  * An attacker can abuse a service to attack, spy on or DoS your servers but
    also third party services. The attack is disguised with the IP address of
    the server and the attacker is able to utilize the high bandwidth of a big
    machine.
  * An attacker can exhaust additional resources on the machine, e.g. with
    requests to a service that doesn't respond or responds with very large
    files.
  * An attacker may gain knowledge, when, how often and from which IP address
    a XML document is accessed.
  * An attacker could send mail from inside your network if the URL handler
    supports ``smtp://`` URIs.


  external entity expansion (local file)
  --------------------------------------

  External entities with references to local files are a sub-case of external
  entity expansion. It's listed as an extra attack because it deserves extra
  attention. Some XML libraries such as lxml disable network access by default
  but still allow entity expansion with local file access by default. Local
  files are either referenced with a ``file://`` URL or by a file path (either
  relative or absolute).

  An attacker may be able to access and download all files that can be read by
  the application process. This may include critical configuration files, too.

  ::

      <!DOCTYPE external [
      <!ENTITY ee SYSTEM "file:///PATH/TO/simple.xml">
      ]>
      <root>&ee;</root>


  DTD retrieval
  -------------

  This case is similar to external entity expansion, too. Some XML libraries
  like Python's xml.dom.pulldom retrieve document type definitions from remote
  or local locations. Several attack scenarios from the external entity case
  apply to this issue as well.

  ::

      <?xml version="1.0" encoding="utf-8"?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html>
          <head/>
          <body>text</body>
      </html>


  Python XML Libraries
  ====================

  .. csv-table:: vulnerabilities and features
     :header: "kind", "sax", "etree", "minidom", "pulldom", "xmlrpc", "lxml", "genshi"
     :widths: 24, 7, 8, 8, 7, 8, 8, 8
     :stub-columns: 0

     "billion laughs", "**True**", "**True**", "**True**", "**True**", "**True**", "False (1)", "False (5)"
     "quadratic blowup", "**True**", "**True**", "**True**", "**True**", "**True**", "**True**", "False (5)"
     "external entity expansion (remote)", "**True**", "False (3)", "False (4)", "**True**", "false", "False (1)", "False (5)"
     "external entity expansion (local file)", "**True**", "False (3)", "False (4)", "**True**", "false", "**True**", "False (5)"
     "DTD retrieval", "**True**", "False", "False", "**True**", "false", "False (1)", "False"
     "gzip bomb", "False", "False", "False", "False", "**True**", "**partly** (2)", "False"
     "xpath support (7)", "False", "False", "False", "False", "False", "**True**", "False"
     "xsl(t) support (7)", "False", "False", "False", "False", "False", "**True**", "False"
     "xinclude support (7)", "False", "**True** (6)", "False", "False", "False", "**True** (6)", "**True**"
     "C library", "expat", "expat", "expat", "expat", "expat", "libxml2", "expat"

  1. Lxml is protected against billion laughs attacks and doesn't do network
     lookups by default.
  2. libxml2 and lxml are not directly vulnerable to gzip decompression bombs
     but they don't protect you against them either.
  3. xml.etree doesn't expand entities and raises a ParserError when an entity
     occurs.
  4. minidom doesn't expand entities and simply returns the unexpanded entity
     verbatim.
  5. genshi.input of genshi 0.6 doesn't support entity expansion and raises a
     ParserError when an entity occurs.
  6. Library has (limited) XInclude support but requires an additional step to
     process inclusion.
  7. These are features but they may introduce exploitable holes, see
     `Other things to consider`_


  Settings in standard library
  ----------------------------


  xml.sax.handler Features
  ........................

  feature_external_ges (http://xml.org/sax/features/external-general-entities)
    disables external entity expansion

  feature_external_pes (http://xml.org/sax/features/external-parameter-entities)
    the option is ignored and doesn't modify any functionality

  DOM xml.dom.xmlbuilder.Options
  ..............................

  external_parameter_entities
    ignored

  external_general_entities
    ignored

  external_dtd_subset
    ignored

  entities
    unsure


  defusedxml
  ==========

  The `defusedxml package`_ (`defusedxml on PyPI`_)
  contains several Python-only workarounds and fixes
  for denial of service and other vulnerabilities in Python's XML libraries.
  In order to benefit from the protection you just have to import and use the
  listed functions / classes from the right defusedxml module instead of the
  original module. Merely `defusedxml.xmlrpc`_ is implemented as monkey patch.

  Instead of::

     >>> from xml.etree.ElementTree import parse
     >>> et = parse(xmlfile)

  alter code to::

     >>> from defusedxml.ElementTree import parse
     >>> et = parse(xmlfile)

  Additionally the package has an **untested** function to monkey patch
  all stdlib modules with ``defusedxml.defuse_stdlib()``.

  All functions and parser classes accept three additional keyword arguments.
  They return either the same objects as the original functions or compatible
  subclasses.

  forbid_dtd (default: False)
    disallow XML with a ``<!DOCTYPE>`` processing instruction and raise a
    *DTDForbidden* exception when a DTD processing instruction is found.

  forbid_entities (default: True)
    disallow XML with ``<!ENTITY>`` declarations inside the DTD and raise an
    *EntitiesForbidden* exception when an entity is declared.

  forbid_external (default: True)
    disallow any access to remote or local resources in external entities
    or DTD and raising an *ExternalReferenceForbidden* exception when a DTD
    or entity references an external resource.


  defusedxml (package)
  --------------------

  DefusedXmlException, DTDForbidden, EntitiesForbidden,
  ExternalReferenceForbidden, NotSupportedError

  defuse_stdlib() (*experimental*)


  defusedxml.cElementTree
  -----------------------

  parse(), iterparse(), fromstring(), XMLParser


  defusedxml.ElementTree
  -----------------------

  parse(), iterparse(), fromstring(), XMLParser


  defusedxml.expatreader
  ----------------------

  create_parser(), DefusedExpatParser


  defusedxml.sax
  --------------

  parse(), parseString(), create_parser()


  defusedxml.expatbuilder
  -----------------------

  parse(), parseString(), DefusedExpatBuilder, DefusedExpatBuilderNS


  defusedxml.minidom
  ------------------

  parse(), parseString()


  defusedxml.pulldom
  ------------------

  parse(), parseString()


  defusedxml.xmlrpc
  -----------------

  The fix is implemented as monkey patch for the stdlib's xmlrpc package (3.x)
  or xmlrpclib module (2.x). The function `monkey_patch()` enables the fixes,
  `unmonkey_patch()` removes the patch and puts the code in its former state.

  The monkey patch protects against XML related attacks as well as
  decompression bombs and excessively large requests or responses. The default
  setting is 30 MB for requests, responses and gzip decompression. You can
  modify the default by changing the module variable `MAX_DATA`. A value of
  `-1` disables the limit.


  defusedxml.lxml
  ---------------

  The module acts as an *example* how you could protect code that uses
  lxml.etree. It implements a custom Element class that filters out
  Entity instances, a custom parser factory and a thread local storage for
  parser instances. It also has a check_docinfo() function which inspects
  a tree for internal or external DTDs and entity declarations. In order to
  check for entities lxml > 3.0 is required.

  parse(), fromstring()
  RestrictedElement, GlobalParserTLS, getDefaultParser(), check_docinfo()


  defusedexpat
  ============

  The `defusedexpat package`_ (`defusedexpat on PyPI`_)
  comes with binary extensions and a
  `modified expat`_ libary instead of the standard `expat parser`_. It's
  basically a stand-alone version of the patches for Python's standard
  library C extensions.

  Modifications in expat
  ----------------------

  new definitions::

    XML_BOMB_PROTECTION
    XML_DEFAULT_MAX_ENTITY_INDIRECTIONS
    XML_DEFAULT_MAX_ENTITY_EXPANSIONS
    XML_DEFAULT_RESET_DTD

  new XML_FeatureEnum members::

    XML_FEATURE_MAX_ENTITY_INDIRECTIONS
    XML_FEATURE_MAX_ENTITY_EXPANSIONS
    XML_FEATURE_IGNORE_DTD

  new XML_Error members::

    XML_ERROR_ENTITY_INDIRECTIONS
    XML_ERROR_ENTITY_EXPANSION

  new API functions::

    int XML_GetFeature(XML_Parser parser,
                       enum XML_FeatureEnum feature,
                       long *value);
    int XML_SetFeature(XML_Parser parser,
                       enum XML_FeatureEnum feature,
                       long value);
    int XML_GetFeatureDefault(enum XML_FeatureEnum feature,
                              long *value);
    int XML_SetFeatureDefault(enum XML_FeatureEnum feature,
                              long value);

  XML_FEATURE_MAX_ENTITY_INDIRECTIONS
     Limit the amount of indirections that are allowed to occur during the
     expansion of a nested entity. A counter starts when an entity reference
     is encountered. It resets after the entity is fully expanded. The limit
     protects the parser against exponential entity expansion attacks (aka
     billion laughs attack). When the limit is exceeded the parser stops and
     fails with `XML_ERROR_ENTITY_INDIRECTIONS`.
     A value of 0 disables the protection.

     Supported range
       0 .. UINT_MAX
     Default
       40

  XML_FEATURE_MAX_ENTITY_EXPANSIONS
     Limit the total length of all entity expansions throughout the entire
     document. The lengths of all entities are accumulated in a parser variable.
     The setting protects against quadratic blowup attacks (lots of expansions
     of a large entity declaration). When the sum of all entities exceeds
     the limit, the parser stops and fails with `XML_ERROR_ENTITY_EXPANSION`.
     A value of 0 disables the protection.

     Supported range
       0 .. UINT_MAX
     Default
       8 MiB

  XML_FEATURE_RESET_DTD
     Reset all DTD information after the <!DOCTYPE> block has been parsed. When
     the flag is set (default: false) all DTD information after the
     endDoctypeDeclHandler has been called. The flag can be set inside the
     endDoctypeDeclHandler. Without DTD information any entity reference in
     the document body leads to `XML_ERROR_UNDEFINED_ENTITY`.

     Supported range
       0, 1
     Default
       0


  How to avoid XML vulnerabilities
  ================================

  Best practices
  --------------

  * Don't allow DTDs
  * Don't expand entities
  * Don't resolve externals
  * Limit parse depth
  * Limit total input size
  * Limit parse time
  * Favor a SAX or iterparse-like parser for potential large data
  * Validate and properly quote arguments to XSL transformations and
    XPath queries
  * Don't use XPath expression from untrusted sources
  * Don't apply XSL transformations that come untrusted sources

  (based on Brad Hill's `Attacking XML Security`_)


  Other things to consider
  ========================

  XML, XML parsers and processing libraries have more features and possible
  issue that could lead to DoS vulnerabilities or security exploits in
  applications. I have compiled an incomplete list of theoretical issues that
  need further research and more attention. The list is deliberately pessimistic
  and a bit paranoid, too. It contains things that might go wrong under daffy
  circumstances.


  attribute blowup / hash collision attack
  ----------------------------------------

  XML parsers may use an algorithm with quadratic runtime O(n :sup:`2`) to
  handle attributes and namespaces. If it uses hash tables (dictionaries) to
  store attributes and namespaces the implementation may be vulnerable to
  hash collision attacks, thus reducing the performance to O(n :sup:`2`) again.
  In either case an attacker is able to forge a denial of service attack with
  an XML document that contains thousands upon thousands of attributes in
  a single node.

  I haven't researched yet if expat, pyexpat or libxml2 are vulnerable.


  decompression bomb
  ------------------

  The issue of decompression bombs (aka `ZIP bomb`_) apply to all XML libraries
  that can parse compressed XML stream like gzipped HTTP streams or LZMA-ed
  files. For an attacker it can reduce the amount of transmitted data by three
  magnitudes or more. Gzip is able to compress 1 GiB zeros to roughly 1 MB,
  lzma is even better::

      $ dd if=/dev/zero bs=1M count=1024 | gzip > zeros.gz
      $ dd if=/dev/zero bs=1M count=1024 | lzma -z > zeros.xy
      $ ls -sh zeros.*
      1020K zeros.gz
       148K zeros.xy

  None of Python's standard XML libraries decompress streams except for
  ``xmlrpclib``. The module is vulnerable <http://bugs.python.org/issue16043>
  to decompression bombs.

  lxml can load and process compressed data through libxml2 transparently.
  libxml2 can handle even very large blobs of compressed data efficiently
  without using too much memory. But it doesn't protect applications from
  decompression bombs. A carefully written SAX or iterparse-like approach can
  be safe.


  Processing Instruction
  ----------------------

  `PI`_'s like::

    <?xml-stylesheet type="text/xsl" href="style.xsl"?>

  may impose more threats for XML processing. It depends if and how a
  processor handles processing instructions. The issue of URL retrieval with
  network or local file access apply to processing instructions, too.


  Other DTD features
  ------------------

  `DTD`_ has more features like ``<!NOTATION>``. I haven't researched how
  these features may be a security threat.


  XPath
  -----

  XPath statements may introduce DoS vulnerabilities. Code should never execute
  queries from untrusted sources. An attacker may also be able to create a XML
  document that makes certain XPath queries costly or resource hungry.


  XPath injection attacks
  -----------------------

  XPath injeciton attacks pretty much work like SQL injection attacks.
  Arguments to XPath queries must be quoted and validated properly, especially
  when they are taken from the user. The page `Avoid the dangers of XPath injection`_
  list some ramifications of XPath injections.

  Python's standard library doesn't have XPath support. Lxml supports
  parameterized XPath queries which does proper quoting. You just have to use
  its xpath() method correctly::

     
     >>> tree.xpath("/tag[@id='%s']" % value)

     
     >>> tree.xpath("/tag[@id=$tagid]", tagid=name)


  XInclude
  --------

  `XML Inclusion`_ is another way to load and include external files::

     <root xmlns:xi="http://www.w3.org/2001/XInclude">
       <xi:include href="filename.txt" parse="text" />
     </root>

  This feature should be disabled when XML files from an untrusted source are
  processed. Some Python XML libraries and libxml2 support XInclude but don't
  have an option to sandbox inclusion and limit it to allowed directories.


  XMLSchema location
  ------------------

  A validating XML parser may download schema files from the information in a
  ``xsi:schemaLocation`` attribute.

  ::

    <ead xmlns="urn:isbn:1-931666-22-9"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="urn:isbn:1-931666-22-9 http://www.loc.gov/ead/ead.xsd">
    </ead>


  XSL Transformation
  ------------------

  You should keep in mind that XSLT is a Turing complete language. Never
  process XSLT code from unknown or untrusted source! XSLT processors may
  allow you to interact with external resources in ways you can't even imagine.
  Some processors even support extensions that allow read/write access to file
  system, access to JRE objects or scripting with Jython.

  Example from `Attacking XML Security`_ for Xalan-J::

      <xsl:stylesheet version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime"
       xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object"
       exclude-result-prefixes= "rt ob">
       <xsl:template match="/">
         <xsl:variable name="runtimeObject" select="rt:getRuntime()"/>
         <xsl:variable name="command"
           select="rt:exec($runtimeObject, &apos;c:\Windows\system32\cmd.exe&apos;)"/>
         <xsl:variable name="commandAsString" select="ob:toString($command)"/>
         <xsl:value-of select="$commandAsString"/>
       </xsl:template>
      </xsl:stylesheet>


  Related CVEs
  ============

  CVE-2013-1664
    Unrestricted entity expansion induces DoS vulnerabilities in Python XML
    libraries (XML bomb)

  CVE-2013-1665
    External entity expansion in Python XML libraries inflicts potential
    security flaws and DoS vulnerabilities


  Other languages / frameworks
  =============================

  Several other programming languages and frameworks are vulnerable as well. A
  couple of them are affected by the fact that libxml2 up to 2.9.0 has no
  protection against quadratic blowup attacks. Most of them have potential
  dangerous default settings for entity expansion and external entities, too.

  Perl
  ----

  Perl's XML::Simple is vulnerable to quadratic entity expansion and external
  entity expansion (both local and remote).


  Ruby
  ----

  Ruby's REXML document parser is vulnerable to entity expansion attacks
  (both quadratic and exponential) but it doesn't do external entity
  expansion by default. In order to counteract entity expansion you have to
  disable the feature::

    REXML::Document.entity_expansion_limit = 0

  libxml-ruby and hpricot don't expand entities in their default configuration.


  PHP
  ---

  PHP's SimpleXML API is vulnerable to quadratic entity expansion and loads
  entites from local and remote resources. The option ``LIBXML_NONET`` disables
  network access but still allows local file access. ``LIBXML_NOENT`` seems to
  have no effect on entity expansion in PHP 5.4.6.


  C# / .NET / Mono
  ----------------

  Information in `XML DoS and Defenses (MSDN)`_ suggest that .NET is
  vulnerable with its default settings. The article contains code snippets
  how to create a secure XML reader::

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ProhibitDtd = false;
    settings.MaxCharactersFromEntities = 1024;
    settings.XmlResolver = null;
    XmlReader reader = XmlReader.Create(stream, settings);


  Java
  ----

  Untested. The documentation of Xerces and its `Xerces SecurityMananger`_
  sounds like Xerces is also vulnerable to billion laugh attacks with its
  default settings. It also does entity resolving when an
  ``org.xml.sax.EntityResolver`` is configured. I'm not yet sure about the
  default setting here.

  Java specialists suggest to have a custom builder factory::

    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    builderFactory.setXIncludeAware(False);
    builderFactory.setExpandEntityReferences(False);
    builderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, True);
    
    builderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", True);
    
    builderFactory.setFeature("http://xml.org/sax/features/external-general-entities", False);
    builderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", False);
    builderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", False);
    builderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", False);


  TODO
  ====

  * DOM: Use xml.dom.xmlbuilder options for entity handling
  * SAX: take feature_external_ges and feature_external_pes (?) into account
  * test experimental monkey patching of stdlib modules
  * improve documentation


  License
  =======

  Copyright (c) 2013-2017 by Christian Heimes <christian@python.org>

  Licensed to PSF under a Contributor Agreement.

  See http://www.python.org/psf/license for licensing details.


  Acknowledgements
  ================

  Brett Cannon (Python Core developer)
    review and code cleanup

  Antoine Pitrou (Python Core developer)
    code review

  Aaron Patterson, Ben Murphy and Michael Koziarski (Ruby community)
    Many thanks to Aaron, Ben and Michael from the Ruby community for their
    report and assistance.

  Thierry Carrez (OpenStack)
    Many thanks to Thierry for his report to the Python Security Response
    Team on behalf of the OpenStack security team.

  Carl Meyer (Django)
    Many thanks to Carl for his report to PSRT on behalf of the Django security
    team.

  Daniel Veillard (libxml2)
    Many thanks to Daniel for his insight and assistance with libxml2.

  semantics GmbH (http://www.semantics.de/)
    Many thanks to my employer semantics for letting me work on the issue
    during working hours as part of semantics's open source initiative.


  References
  ==========

  * `XML DoS and Defenses (MSDN)`_
  * `Billion Laughs`_ on Wikipedia
  * `ZIP bomb`_ on Wikipedia
  * `Configure SAX parsers for secure processing`_
  * `Testing for XML Injection`_

  .. _defusedxml package: https://bitbucket.org/tiran/defusedxml
  .. _defusedxml on PyPI: https://pypi.python.org/pypi/defusedxml
  .. _defusedexpat package: https://bitbucket.org/tiran/defusedexpat
  .. _defusedexpat on PyPI: https://pypi.python.org/pypi/defusedexpat
  .. _modified expat: https://bitbucket.org/tiran/expat
  .. _expat parser: http://expat.sourceforge.net/
  .. _Attacking XML Security: https://www.isecpartners.com/media/12976/iSEC-HILL-Attacking-XML-Security-bh07.pdf
  .. _Billion Laughs: http://en.wikipedia.org/wiki/Billion_laughs
  .. _XML DoS and Defenses (MSDN): http://msdn.microsoft.com/en-us/magazine/ee335713.aspx
  .. _ZIP bomb: http://en.wikipedia.org/wiki/Zip_bomb
  .. _DTD: http://en.wikipedia.org/wiki/Document_Type_Definition
  .. _PI: https://en.wikipedia.org/wiki/Processing_Instruction
  .. _Avoid the dangers of XPath injection: http://www.ibm.com/developerworks/xml/library/x-xpathinjection/index.html
  .. _Configure SAX parsers for secure processing: http://www.ibm.com/developerworks/xml/library/x-tipcfsx/index.html
  .. _Testing for XML Injection: https://www.owasp.org/index.php/Testing_for_XML_Injection_(OWASP-DV-008)
  .. _Xerces SecurityMananger: http://xerces.apache.org/xerces2-j/javadocs/xerces2/org/apache/xerces/util/SecurityManager.html
  .. _XML Inclusion: http://www.w3.org/TR/xinclude/#include_element

  Changelog
  =========

  defusedxml 0.5.0
  ----------------

  *Release date: 07-Feb-2017*

  - No changes

  defusedxml 0.5.0.rc1
  --------------------

  *Release date: 28-Jan-2017*

  - Add compatibility with Python 3.6
  - Drop support for Python 2.6, 3.1, 3.2, 3.3
  - Fix lxml tests (XMLSyntaxError: Detected an entity reference loop)


  defusedxml 0.4.1
  ----------------

  *Release date: 28-Mar-2013*

  - Add more demo exploits, e.g. python_external.py and Xalan XSLT demos.
  - Improved documentation.


  defusedxml 0.4
  --------------

  *Release date: 25-Feb-2013*

  - As per http://seclists.org/oss-sec/2013/q1/340 please REJECT
    CVE-2013-0278, CVE-2013-0279 and CVE-2013-0280 and use CVE-2013-1664,
    CVE-2013-1665 for OpenStack/etc.
  - Add missing parser_list argument to sax.make_parser(). The argument is
    ignored, though. (thanks to Florian Apolloner)
  - Add demo exploit for external entity attack on Python's SAX parser, XML-RPC
    and WebDAV.


  defusedxml 0.3
  --------------

  *Release date: 19-Feb-2013*

  - Improve documentation


  defusedxml 0.2
  --------------

  *Release date: 15-Feb-2013*

  - Rename ExternalEntitiesForbidden to ExternalReferenceForbidden
  - Rename defusedxml.lxml.check_dtd() to check_docinfo()
  - Unify argument names in callbacks
  - Add arguments and formatted representation to exceptions
  - Add forbid_external argument to all functions and classs
  - More tests
  - LOTS of documentation
  - Add example code for other languages (Ruby, Perl, PHP) and parsers (Genshi)
  - Add protection against XML and gzip attacks to xmlrpclib

  defusedxml 0.1
  --------------

  *Release date: 08-Feb-2013*

  - Initial and internal release for PSRT review


pkgId: 412747c15ba6a1a3486538f7a0ac12e589d67c6100f4629754180c19cc206c94
name: rh-python36-deprecation
arch: noarch
version: 2.0
epoch: 0
release: 1
summary: A library to handle automated deprecations
url: http://deprecation.readthedocs.io/
rpm_license: Apache 2
rpm_vendor: Brian Curtin <brian@python.org>
rpm_group: Development/Libraries
rpm_buildhost: 0b82f64f3ca04418a3859cb1777058a2
rpm_sourcerpm: rh-python36-deprecation-2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387201-rh-python36-deprecation/rh-python36-deprecation-2.0-1.noarch.rpm
checksum_type: sha256
description:
  deprecation
  ===========

  .. image:: https://readthedocs.org/projects/deprecation/badge/?version=latest
     :target: http://deprecation.readthedocs.io/en/latest/
     :alt: Documentation Status

  .. image:: https://travis-ci.org/briancurtin/deprecation.svg?branch=master
      :target: https://travis-ci.org/briancurtin/deprecation

  .. image:: https://codecov.io/gh/briancurtin/deprecation/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/briancurtin/deprecation

  The ``deprecation`` library provides a ``deprecated`` decorator and a
  ``fail_if_not_removed`` decorator for your tests. Together, the two
  enable the automation of several things:

  1. The docstring of a deprecated method gets the deprecation details
     appended to the end of it. If you generate your API docs direct
     from your source, you don't need to worry about writing your own
     notification. You also don't need to worry about forgetting to
     write it. It's done for you.
  2. Rather than having code live on forever because you only deprecated
     it but never actually moved on from it, you can have your tests
     tell you when it's time to remove the code. The ``@deprecated``
     decorator can be told when it's time to entirely remove the code,
     which causes ``@fail_if_not_removed`` to raise an ``AssertionError``,
     causing either your unittest or py.test tests to fail.

  See http://deprecation.readthedocs.io/ for the full documentation.

  Installation
  ============

   ::

      pip install deprecation

  Usage
  =====

   ::

      import deprecation

      @deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
                              current_version=__version__,
                              details="Use the bar function instead")
      def foo():
          """Do some stuff"""
          return 1

  ...but doesn't Python ignore ``DeprecationWarning``?
  ====================================================

  Yes, by default since 2.7—and for good reason [#]_ —and this works fine
  with that.

  1. It often makes sense for you to run your tests with a ``-W`` flag or
     the ``PYTHONWARNINGS`` environment variable so you catch warnings
     in development and handle them appropriately. The warnings raised by
     this library show up there, as they're subclasses of the built-in
     ``DeprecationWarning``. See the `Command Line
     <https://docs.python.org/2/using/cmdline.html#cmdoption-W>`_
     and `Environment Variable
     <https://docs.python.org/2/using/cmdline.html#envvar-PYTHONWARNINGS>`_
     documentation for more details.
  2. Even if you don't enable those things, the behavior of this library
     remains the same. The docstrings will still be updated and the tests
     will still fail when they need to. You'll get the benefits regardless
     of what Python cares about ``DeprecationWarning``.

  ----

  .. [#] Exposing application users to ``DeprecationWarning``\s that are
         emitted by lower-level code needlessly involves end-users in
         "how things are done." It often leads to users raising issues
         about warnings they're presented, which on one hand is done
         rightfully so, as it's been presented to them as some sort of
         issue to resolve. However, at the same time, the warning could
         be well known and planned for. From either side, loud
         ``DeprecationWarning``\s can be seen as noise that isn't
         necessary outside of development.


pkgId: 57822258bc2e8b3b0c4b1bdcaa34fd552d3c24cd4ecaf0a2a65dd3158a1a4a72
name: rh-python36-django-auth-ldap
arch: noarch
version: 2.1.0
epoch: 0
release: 1
summary: Django LDAP authentication backend
url: https://github.com/django-auth-ldap/django-auth-ldap
rpm_license: BSD
rpm_vendor: Jon Dufresne <jon.dufresne@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: ccd4a7bdc001462d8b6fb8b8802b8d41
rpm_sourcerpm: rh-python36-django-auth-ldap-2.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387078-rh-python36-django-auth-ldap/rh-python36-django-auth-ldap-2.1.0-1.noarch.rpm
checksum_type: sha256
description:
  ================================
  Django Authentication Using LDAP
  ================================

  .. image:: https://readthedocs.org/projects/django-auth-ldap/badge/?version=latest
     :target: https://django-auth-ldap.pypa.io/en/latest

  .. image:: https://img.shields.io/pypi/v/django-auth-ldap.svg
     :target: https://pypi.org/project/django-auth-ldap/

  .. image:: https://img.shields.io/travis/django-auth-ldap/django-auth-ldap/master.svg?label=travis-ci
     :target: http://travis-ci.org/pypa/django-auth-ldap

  .. image:: https://img.shields.io/pypi/l/django-auth-ldap.svg
     :target: https://raw.githubusercontent.com/django-auth-ldap/django-auth-ldap/master/LICENSE

  This is a Django authentication backend that authenticates against an LDAP
  service. Configuration can be as simple as a single distinguished name
  template, but there are many rich configuration options for working with users,
  groups, and permissions.

  * Documentation: https://django-auth-ldap.readthedocs.io/
  * PyPI: https://pypi.org/project/django-auth-ldap/
  * Repository: https://github.com/django-auth-ldap/django-auth-ldap
  * Tests: http://travis-ci.org/pypa/django-auth-ldap
  * License: BSD 2-Clause

  This version is supported on Python 2.7 and 3.4+; and Django 1.11+. It requires
  `python-ldap`_ >= 3.0.

  .. _`python-ldap`: https://pypi.org/project/python-ldap/


  Installation
  ============

  Install the package with pip:

  .. code-block:: sh

      $ pip install django-auth-ldap

  It requires `python-ldap`_ >= 3.0. You'll need the `OpenLDAP`_ libraries and
  headers available on your system.

  To use the auth backend in a Django project, add
  ``'django_auth_ldap.backend.LDAPBackend'`` to ``AUTHENTICATION_BACKENDS``. Do
  not add anything to ``INSTALLED_APPS``.

  .. code-block:: python

      AUTHENTICATION_BACKENDS = [
          'django_auth_ldap.backend.LDAPBackend',
      ]

  ``LDAPBackend`` should work with custom user models, but it does assume that a
  database is present.

  .. note::

      ``LDAPBackend`` does not inherit from ``ModelBackend``. It is possible to
      use ``LDAPBackend`` exclusively by configuring it to draw group membership
      from the LDAP server. However, if you would like to assign permissions to
      individual users or add users to groups within Django, you'll need to have
      both backends installed:

      .. code-block:: python

          AUTHENTICATION_BACKENDS = [
              'django_auth_ldap.backend.LDAPBackend',
              'django.contrib.auth.backends.ModelBackend',
          ]

  .. _`python-ldap`: https://pypi.org/project/python-ldap/
  .. _`OpenLDAP`: https://www.openldap.org/


  Example Configuration
  =====================

  Here is a complete example configuration from ``settings.py`` that exercises
  nearly all of the features. In this example, we're authenticating against a
  global pool of users in the directory, but we have a special area set aside for
  Django groups (``ou=django,ou=groups,dc=example,dc=com``). Remember that most
  of this is optional if you just need simple authentication. Some default
  settings and arguments are included for completeness.

  .. code-block:: python

      import ldap
      from django_auth_ldap.config import LDAPSearch, GroupOfNamesType


      
      AUTH_LDAP_SERVER_URI = 'ldap://ldap.example.com'

      AUTH_LDAP_BIND_DN = 'cn=django-agent,dc=example,dc=com'
      AUTH_LDAP_BIND_PASSWORD = 'phlebotinum'
      AUTH_LDAP_USER_SEARCH = LDAPSearch(
          'ou=users,dc=example,dc=com',
          ldap.SCOPE_SUBTREE,
          '(uid=s)',
      )
      
      

      
      AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
          'ou=django,ou=groups,dc=example,dc=com',
          ldap.SCOPE_SUBTREE,
          '(objectClass=groupOfNames)',
      )
      AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr='cn')

      
      AUTH_LDAP_REQUIRE_GROUP = 'cn=enabled,ou=django,ou=groups,dc=example,dc=com'
      AUTH_LDAP_DENY_GROUP = 'cn=disabled,ou=django,ou=groups,dc=example,dc=com'

      
      AUTH_LDAP_USER_ATTR_MAP = {
          'first_name': 'givenName',
          'last_name': 'sn',
          'email': 'mail',
      }

      AUTH_LDAP_USER_FLAGS_BY_GROUP = {
          'is_active': 'cn=active,ou=django,ou=groups,dc=example,dc=com',
          'is_staff': 'cn=staff,ou=django,ou=groups,dc=example,dc=com',
          'is_superuser': 'cn=superuser,ou=django,ou=groups,dc=example,dc=com',
      }

      
      AUTH_LDAP_ALWAYS_UPDATE_USER = True

      
      AUTH_LDAP_FIND_GROUP_PERMS = True

      
      
      AUTH_LDAP_CACHE_TIMEOUT = 3600

      
      
      AUTHENTICATION_BACKENDS = (
          'django_auth_ldap.backend.LDAPBackend',
          'django.contrib.auth.backends.ModelBackend',
      )


  Contributing
  ============

  If you'd like to contribute, the best approach is to send a well-formed pull
  request, complete with tests and documentation. Pull requests should be
  focused: trying to do more than one thing in a single request will make it more
  difficult to process.

  If you have a bug or feature request you can try `logging an issue`_.

  There's no harm in creating an issue and then submitting a pull request to
  resolve it. This can be a good way to start a conversation and can serve as an
  anchor point.

  .. _`logging an issue`: https://github.com/django-auth-ldap/django-auth-ldap/issues


pkgId: 6f758e69ecc0197bf7bf267ec98282023ce59bed071f00c43ff860e50a0a193d
name: rh-python36-django-cors-headers
arch: noarch
version: 3.2.1
epoch: 0
release: 1
url: https://github.com/ottoyiu/django-cors-headers
rpm_license: MIT License
rpm_vendor: Otto Yiu <otto@live.ca>
rpm_group: Development/Libraries
rpm_buildhost: 3367bbb66eda4b53b828b5a56abb2505
rpm_sourcerpm: rh-python36-django-cors-headers-3.2.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387177-rh-python36-django-cors-headers/rh-python36-django-cors-headers-3.2.1-1.noarch.rpm
checksum_type: sha256
summary:
  django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS).

description:
  django-cors-headers
  ===================

  A Django App that adds CORS (Cross-Origin Resource Sharing) headers to
  responses.

  Although JSON-P is useful, it is strictly limited to GET requests. CORS
  builds on top of ``XmlHttpRequest`` to allow developers to make cross-domain
  requests, similar to same-domain requests. Read more about it here:
  http://www.html5rocks.com/en/tutorials/cors/

  .. image:: https://travis-ci.org/ottoyiu/django-cors-headers.svg?branch=master
     :target: https://travis-ci.org/ottoyiu/django-cors-headers


  Requirements
  ------------

  Tested with all combinations of:

  * Python: 2.7, 3.6
  * Django: 1.8, 1.9, 1.10, 1.11, 2.0

  Setup
  -----

  Install from **pip**:

  .. code-block:: sh

      pip install django-cors-headers

  and then add it to your installed apps:

  .. code-block:: python

      INSTALLED_APPS = (
          ...
          'corsheaders',
          ...
      )

  You will also need to add a middleware class to listen in on responses:

  .. code-block:: python

      MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
          ...
          'corsheaders.middleware.CorsMiddleware',
          'django.middleware.common.CommonMiddleware',
          ...
      ]

  ``CorsMiddleware`` should be placed as high as possible, especially before any
  middleware that can generate responses such as Django's ``CommonMiddleware`` or
  Whitenoise's ``WhiteNoiseMiddleware``. If it is not before, it will not be able
  to add the CORS headers to these responses.

  Also if you are using ``CORS_REPLACE_HTTPS_REFERER`` it should be placed before
  Django's ``CsrfViewMiddleware`` (see more below).

  Configuration
  -------------

  Configure the middleware's behaviour in your Django settings. You must add the
  hosts that are allowed to do cross-site requests to
  ``CORS_ORIGIN_WHITELIST``, or set ``CORS_ORIGIN_ALLOW_ALL`` to ``True``
  to allow all hosts.

  ``CORS_ORIGIN_ALLOW_ALL``
  ~~~~~~~~~~~~~~~~~~~~~~~~~
  If ``True``, the whitelist will not be used and all origins will be accepted.
  Defaults to ``False``.

  ``CORS_ORIGIN_WHITELIST``
  ~~~~~~~~~~~~~~~~~~~~~~~~~

  A list of origin hostnames that are authorized to make cross-site HTTP
  requests. The value ``'null'`` can also appear in this list, and will match the
  ``Origin: null`` header that is used in `"privacy-sensitive contexts"
  <https://tools.ietf.org/html/rfc6454#section-6>`_, such as when the client is
  running from a ``file://`` domain. Defaults to ``[]``.

  Example:

  .. code-block:: python

      CORS_ORIGIN_WHITELIST = (
          'google.com',
          'hostname.example.com',
          'localhost:8000',
          '127.0.0.1:9000'
      )


  ``CORS_ORIGIN_REGEX_WHITELIST``
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  A list of regexes that match origin regex list of origin hostnames that are
  authorized to make cross-site HTTP requests. Defaults to ``[]``. Useful when
  ``CORS_ORIGIN_WHITELIST`` is impractical, such as when you have a large
  number of subdomains.

  Example:

  .. code-block:: python

      CORS_ORIGIN_REGEX_WHITELIST = (r'^(https?://)?(\w+\.)?google\.com$', )

  --------------

  The following are optional settings, for which the defaults probably suffice.

  ``CORS_URLS_REGEX``
  ~~~~~~~~~~~~~~~~~~~

  A regex which restricts the URL's for which the CORS headers will be sent.
  Defaults to ``r'^.*$'``, i.e. match all URL's. Useful when you only need CORS
  on a part of your site, e.g. an API at ``/api/``.

  Example:

  .. code-block:: python

      CORS_URLS_REGEX = r'^/api/.*$'

  ``CORS_ALLOW_METHODS``
  ~~~~~~~~~~~~~~~~~~~~~~

  A list of HTTP verbs that are allowed for the actual request. Defaults to:

  .. code-block:: python

      CORS_ALLOW_METHODS = (
          'DELETE',
          'GET',
          'OPTIONS',
          'PATCH',
          'POST',
          'PUT',
      )

  The default can be imported as ``corsheaders.defaults.default_methods`` so you
  can just extend it with your custom methods. This allows you to keep up to date
  with any future changes. For example:

  .. code-block:: python

      from corsheaders.defaults import default_methods

      CORS_ALLOW_METHODS = default_methods + (
          'POKE',
      )

  ``CORS_ALLOW_HEADERS``
  ~~~~~~~~~~~~~~~~~~~~~~

  The list of non-standard HTTP headers that can be used when making the actual
  request. Defaults to:

  .. code-block:: python

      CORS_ALLOW_HEADERS = (
          'accept',
          'accept-encoding',
          'authorization',
          'content-type',
          'dnt',
          'origin',
          'user-agent',
          'x-csrftoken',
          'x-requested-with',
      )

  The default can be imported as ``corsheaders.defaults.default_headers`` so you
  can extend it with your custom headers. This allows you to keep up to date with
  any future changes. For example:

  .. code-block:: python

      from corsheaders.defaults import default_headers

      CORS_ALLOW_HEADERS = default_headers + (
          'my-custom-header',
      )

  ``CORS_EXPOSE_HEADERS``
  ~~~~~~~~~~~~~~~~~~~~~~~

  The list of HTTP headers that are to be exposed to the browser. Defaults to
  ``[]``.


  ``CORS_PREFLIGHT_MAX_AGE``
  ~~~~~~~~~~~~~~~~~~~~~~~~~~

  The number of seconds a client/browser can cache the preflight response. If
  this is 0 (or any falsey value), no max age header will be sent. Defaults to
  ``86400`` (one day).


  **Note:** A preflight request is an extra request that is made when making a
  "not-so-simple" request (e.g. ``Content-Type`` is not
  ``application/x-www-form-urlencoded``) to determine what requests the server
  actually accepts. Read more about it in the `HTML 5 Rocks CORS tutorial
  <https://www.html5rocks.com/en/tutorials/cors/>`_.

  ``CORS_ALLOW_CREDENTIALS``
  ~~~~~~~~~~~~~~~~~~~~~~~~~~

  If ``True``, cookies will be allowed to be included in cross-site HTTP
  requests. Defaults to ``False``.

  ``CORS_MODEL``
  ~~~~~~~~~~~~~~

  If set, this should be the path to a model to look up allowed origins, in the
  form ``app.modelname``. Defaults to ``None``.

  The model should inherit from ``corsheaders.models.AbstractCorsModel`` and specify
  the allowed origin in the ``CharField`` called ``cors``.

  CSRF Integration
  ----------------

  Most sites will need to take advantage of the `Cross-Site Request Forgery
  protection <https://docs.djangoproject.com/en/dev/ref/csrf/>`_ that Django
  offers. CORS and CSRF are separate, and Django has no way of using your CORS
  configuration to exempt sites from the ``Referer`` checking that it does on
  secure requests. The way to do that is with its `CSRF_TRUSTED_ORIGINS setting
  <https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins>`_.
  For example:

  .. code-block:: python

      CORS_ORIGIN_WHITELIST = (
          'read.only.com',
          'change.allowed.com',
      )

      CSRF_TRUSTED_ORIGINS = (
          'change.allowed.com',
      )

  ``CORS_REPLACE_HTTPS_REFERER``
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  ``CSRF_TRUSTED_ORIGINS`` was introduced in Django 1.9, so users of earlier
  versions will need an alternate solution. If ``CORS_REPLACE_HTTPS_REFERER`` is
  ``True``, ``CorsMiddleware`` will change the ``Referer`` header to something
  that will pass Django's CSRF checks whenever the CORS checks pass. Defaults to
  ``False``.

  Note that unlike ``CSRF_TRUSTED_ORIGINS``, this setting does not allow you to
  distinguish between domains that are trusted to *read* resources by CORS and
  domains that are trusted to *change* resources by avoiding CSRF protection.

  With this feature enabled you should also add
  ``corsheaders.middleware.CorsPostCsrfMiddleware`` after
  ``django.middleware.csrf.CsrfViewMiddleware`` in your ``MIDDLEWARE_CLASSES`` to
  undo the ``Referer`` replacement:

  .. code-block:: python

      MIDDLEWARE_CLASSES = [
          ...
          'corsheaders.middleware.CorsMiddleware',
          ...
          'django.middleware.csrf.CsrfViewMiddleware',
          'corsheaders.middleware.CorsPostCsrfMiddleware',
          ...
      ]

  Signals
  -------

  If you have a use case that requires more than just the above configuration,
  you can attach code to check if a given request should be allowed. For example,
  this can be used to read the list of origins you allow from a model. Attach any
  number of handlers to the ``check_request_enabled``
  `Django signal <https://docs.djangoproject.com/en/1.10/ref/signals/>`_, which
  provides the ``request`` argument (use ``**kwargs`` in your handler to protect
  against any future arguments being added). If any handler attached to the
  signal returns a truthy value, the request will be allowed.

  For example you might define a handler like this:

  .. code-block:: python

      
      from corsheaders.signals import check_request_enabled

      from .models import MySite

      def cors_allow_mysites(sender, request, **kwargs):
          return MySite.objects.filter(host=request.host).exists()

      check_request_enabled.connect(cors_allow_mysites)

  Then connect it at app ready time using a `Django AppConfig
  <https://docs.djangoproject.com/en/1.10/ref/applications/>`_:

  .. code-block:: python

      

      default_app_config = 'myapp.apps.MyAppConfig'

  .. code-block:: python

      

      from django.apps import AppConfig

      class MyAppConfig(AppConfig):
          name = 'myapp'

          def ready(self):
              
              from . import handlers  # noqa


  A common use case for the signal is to allow *all* origins to access a subset
  of URL's, whilst allowing a normal set of origins to access *all* URL's. This
  isn't possible using just the normal configuration, but it can be achieved with
  a signal handler.

  First set ``CORS_ORIGIN_WHITELIST`` to the list of trusted origins that are
  allowed to access every URL, and then add a handler to
  ``check_request_enabled`` to allow CORS regardless of the origin for the
  unrestricted URL's. For example:

  .. code-block:: python

      
      from corsheaders.signals import check_request_enabled

      def cors_allow_api_to_everyone(sender, request, **kwargs):
          return request.path.startswith('/api/')

      check_request_enabled.connect(cors_allow_api_to_everyone)

  Credits
  -------

  ``django-cors-headers`` was created by Otto Yiu (`@ottoyiu
  <https://github.com/ottoyiu>`_) and has been worked on by `25+ contributors
  <https://github.com/ottoyiu/django-cors-headers/graphs/contributors>`_.
  Thanks to every contributor, and if you want to get involved please don't
  hesitate to make a pull request.


  History
  =======

  Pending
  -------

  .. Insert new release notes below this line

  2.4.0 (2018-07-18)
  ------------------

  * Always add 'Origin' to the 'Vary' header for responses to enabled URL's,
    to prevent caching of responses intended for one origin being served for
    another.

  2.3.0 (2018-06-27)
  ------------------

  * Match ``CORS_URLS_REGEX`` to ``request.path_info`` instead of
    ``request.path``, so the patterns can work without knowing the site's path
    prefix at configuration time.

  2.2.1 (2018-06-27)
  ------------------

  * Add ``Content-Length`` header to CORS preflight requests. This fixes issues
    with some HTTP proxies and servers, e.g. AWS Elastic Beanstalk.

  2.2.0 (2018-02-28)
  ------------------

  * Django 2.0 compatibility. Again there were no changes to the actual library
    code, so previous versions probably work.
  * Ensured that ``request._cors_enabled`` is always a ``bool()`` - previously it
    could be set to a regex match object.

  2.1.0 (2017-05-28)
  ------------------

  * Django 1.11 compatibility. There were no changes to the actual library code,
    so previous versions probably work, though they weren't properly tested on
    1.11.

  2.0.2 (2017-02-06)
  ------------------

  * Fix when the check for ``CORS_MODEL`` is done to allow it to properly add
    the headers and respond to ``OPTIONS`` requests.

  2.0.1 (2017-01-29)
  ------------------

  * Add support for specifying 'null' in ``CORS_ORIGIN_WHITELIST``.

  2.0.0 (2017-01-07)
  ------------------

  * Remove previously undocumented ``CorsModel`` as it was causing migration
    issues. For backwards compatibility, any users previously using ``CorsModel``
    should create a model in their own app that inherits from the new
    ``AbstractCorsModel``, and to keep using the same data, set the model's
    ``db_table`` to 'corsheaders_corsmodel'. Users not using ``CorsModel``
    will find they have an unused table that they can drop.
  * Make sure that ``Access-Control-Allow-Credentials`` is in the response if the
    client asks for it.

  1.3.1 (2016-11-09)
  ------------------

  * Fix a bug with the single check if CORS enabled added in 1.3.0: on Django
    < 1.10 shortcut responses could be generated by middleware above
    ``CorsMiddleware``, before it processed the request, failing with an
    ``AttributeError`` for ``request._cors_enabled``. Also clarified the docs
    that ``CorsMiddleware`` should be kept as high as possible in your middleware
    stack, above any middleware that can generate such responses.

  1.3.0 (2016-11-06)
  ------------------

  * Add checks to validate the types of the settings.
  * Add the 'Do Not Track' header ``'DNT'`` to the default for
    ``CORS_ALLOW_HEADERS``.
  * Add 'Origin' to the 'Vary' header of outgoing requests when not allowing all
    origins, as per the CORS spec. Note this changes the way HTTP caching works
    with your CORS-enabled responses.
  * Check whether CORS should be enabled on a request only once. This has had a
    minor change on the conditions where any custom signals will be called -
    signals will now always be called *before* ``HTTP_REFERER`` gets replaced,
    whereas before they could be called before and after. Also this attaches the
    attribute ``_cors_enabled`` to ``request`` - please take care that other
    code you're running does not remove it.

  1.2.2 (2016-10-05)
  ------------------

  * Add ``CorsModel.__str__`` for human-readable text
  * Add a signal that allows you to add code for more intricate control over when
    CORS headers are added.

  1.2.1 (2016-09-30)
  ------------------

  * Made settings dynamically respond to changes, and which allows you to import
    the defaults for headers and methods in order to extend them.

  1.2.0 (2016-09-28)
  ------------------

  * Drop Python 2.6 support.
  * Drop Django 1.3-1.7 support, as they are no longer supported.
  * Confirmed Django 1.9 support (no changes outside of tests were necessary).
  * Added Django 1.10 support.
  * Package as a universal wheel.

  1.1.0 (2014-12-15)
  ------------------

  * django-cors-header now supports Django 1.8 with its new application loading
    system! Thanks @jpadilla for making this possible and sorry for the delay in
    making a release.

  1.0.0 (2014-12-13)
  ------------------

  django-cors-headers is all grown-up :) Since it's been used in production for
  many many deployments, I think it's time we mark this as a stable release.

  * Switching this middleware versioning over to semantic versioning
  * #46 add user-agent and accept-encoding default headers
  * #45 pep-8 this big boy up

  0.13 (2014-08-14)
  -----------------

  * Add support for Python 3
  * Updated tests
  * Improved docuemntation
  * Small bugfixes

  0.12 (2013-09-24)
  -----------------

  * Added an option to selectively enable CORS only for specific URLs

  0.11 (2013-09-24)

  * Added the ability to specify a regex for whitelisting many origin hostnames
    at once

  0.10 (2013-09-05)
  -----------------

  * Introduced port distinction for origin checking
  * Use ``urlparse`` for Python 3 support
  * Added testcases to project

  0.06 (2013-02-18)
  -----------------

  * Add support for exposed response headers

  0.05 (2013-01-26)
  -----------------

  * Fixed middleware to ensure correct response for CORS preflight requests

  0.04 (2013-01-25)
  -----------------

  * Add ``Access-Control-Allow-Credentials`` control to simple requests

  0.03 (2013-01-22)
  -----------------

  * Bugfix to repair mismatched default variable names

  0.02 (2013-01-19)
  -----------------

  * Refactor/pull defaults into separate file

  0.01 (2013-01-19)
  -----------------

  * Initial release


pkgId: e919b9955ecabb768ad976fed77500030dc40911615fdb402f4738ef60be199b
name: rh-python36-django-crum
arch: noarch
version: 0.7.5
epoch: 0
release: 1
summary: Django middleware to capture current request and user.
url: https://github.com/ninemoreminutes/django-crum/
rpm_license: BSD
rpm_vendor: Nine More Minutes, Inc. <support@ninemoreminutes.com>
rpm_group: Development/Libraries
rpm_buildhost: 8307c44a8c934bba92198cec1284ff3f
rpm_sourcerpm: rh-python36-django-crum-0.7.5-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387081-rh-python36-django-crum/rh-python36-django-crum-0.7.5-1.noarch.rpm
checksum_type: sha256
description:
  |Build Status| |PyPI Version| |PyPI License| |Python Versions|

  Django-CRUM
  ===========

  Django-CRUM (Current Request User Middleware) captures the current request and
  user in thread local storage.

  It enables apps to check permissions, capture audit trails or otherwise access
  the current request and user without requiring the request object to be passed
  directly. It also offers a context manager to allow for temporarily
  impersonating another user.

  It provides a signal to extend the built-in function for getting the current
  user, which could be helpful when using custom authentication methods or user
  models.

  It is tested against:
   * Django 1.8 (Python 2.7, 3.3, 3.4 and 3.5)
   * Django 1.9 (Python 2.7, 3.4 and 3.5)
   * Django 1.10 (Python 2.7, 3.4 and 3.5)
   * Django 1.11 (Python 2.7, 3.4, 3.5 and 3.6)
   * Django master/2.0 (Python 3.5 and 3.6)

  .. |Build Status| image:: http://img.shields.io/travis/ninemoreminutes/django-crum.svg
     :target: https://travis-ci.org/ninemoreminutes/django-crum
  .. |PyPI Version| image:: https://img.shields.io/pypi/v/django-crum.svg
     :target: https://pypi.python.org/pypi/django-crum/
  .. |PyPI License| image:: https://img.shields.io/pypi/l/django-crum.svg
     :target: https://pypi.python.org/pypi/django-crum/
  .. |Python Versions| image:: https://img.shields.io/pypi/pyversions/django-crum.svg
     :target: https://pypi.python.org/pypi/django-crum/


pkgId: 05e168d1a3f30d94014e5b3ac9d7e2b4e0a031dfbc46814a7f60307b6136b10f
name: rh-python36-django-extensions
arch: noarch
version: 2.2.8
epoch: 0
release: 1
summary: Extensions for Django
url: http://github.com/django-extensions/django-extensions
rpm_license: MIT License
rpm_vendor: Bas van Oostveen <v.oostveen@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 57a832180d9141d9be0ea485ba2af24b
rpm_sourcerpm: rh-python36-django-extensions-2.2.8-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387086-rh-python36-django-extensions/rh-python36-django-extensions-2.2.8-1.noarch.rpm
checksum_type: sha256
description:
  django-extensions bundles several useful
  additions for Django projects. See the project page for more information:
    http://github.com/django-extensions/django-extensions


pkgId: 32e011036a4ae9c42b3e6533eac3a14aa216fe5aed42fd8f2f9f7db61f7bd60c
name: rh-python36-django-jsonfield
arch: noarch
version: 1.2.0
epoch: 0
release: 1
summary: JSONField for django models
url: http://bitbucket.org/schinckel/django-jsonfield/
rpm_license: UNKNOWN
rpm_vendor: Matthew Schinckel <matt@schinckel.net>
rpm_group: Development/Libraries
rpm_buildhost: 5fd5e3998f884ff6950fd5074b81834d
rpm_sourcerpm: rh-python36-django-jsonfield-1.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387083-rh-python36-django-jsonfield/rh-python36-django-jsonfield-1.2.0-1.noarch.rpm
checksum_type: sha256
description:
  django-jsonfield
  ===================

  .. image:: https://codeship.com/projects/2e1a3d30-7db7-0132-629f-4abd151a3721/status?branch=default

  I had a serious need for a JSON field for django. There were a couple out
  there, but none packaged up nicely on bitbucket/github that were usable
  with ``pip install -e``.

  So I took the code from `David Cramer's blog`_, and packaged it up.

  Usage
  -----

  To use, just install the package, and then use the field::

      from django.db import models
      import jsonfield

      class MyModel(models.Model):
          the_json = jsonfield.JSONField()

  You can assign any JSON-encodable object to this field. It will be
  JSON-encoded before being stored in the database as a text value and it
  will be turned back into a python list/dict/string upon retrieval from the
  database.

  There is also a ``TypedJSONField``, that allows you to define data types that must be included within each object in the array. More documentation to follow.


  Notes
  ~~~~~

  If no ``default`` is provided, and ``null=True`` is not passed in to the
  field constructor, then a default of ``{}`` will be used.


  Supported django versions
  -------------------------

  All versions of Django from 1.8 onwards are tested, however, if you are using Postgres, I highly recommend that you consider using the ``django.contrib.postgres`` module's ``JSONField`` instead.

  Extras
  ------

  jsonify templatetag
  ~~~~~~~~~~~~~~~~~~~
  This allows you to convert a python data structure into JSON within a template::

      {% load jsonify %}

      <script>
      var foo = {{ bar|jsonify|safe }};
      </script>

  Note that you must only use the "safe" filter when you use the jsonify
  filter within a <script> tag (which is parsed like a CDATA section).

  If you use it in some other places like in an HTML attribute, then
  you must not use the safe filter so that its output is properly escaped::

      <div data-foo="{{ bar|jsonify }}">

  The above rules are important to avoid XSS attacks with unsafe strings
  stored in the converted data structure.

  History
  ----------

  1.0.1
  ~~~~~~
  Fix issue with Postgres JSONB fields.
  Limit XSS attacks with jsonify template tag.


  1.0.0
  ~~~~~

  Add support for Django 1.8 and 1.9 (without warnings). Remove support for Django < 1.8
  as none of those releases are supported upstream anyway.

  With this version, ``JSONField`` no longer decodes assigned string values as JSON. Instead it assumes that any value that you assign is the decoded value which will be JSON-encoded before storage in the database. This explains the bump to version 1.0 as it's a backwards incompatible change.

  0.9.19
  ~~~~~~
  Allow passing `decoder_kwargs` as an argument to a field. This dict will be passed as kwargs to
  the `json.loads()` calls when loading data that is a string.

  You may also set this as a global value in settings.JSONFIELD_DECODER_KWARGS.

  A new dict is created for each field: so if this value is altered after field definition, it shouldn't
  affect already attached fields.

  0.9.16
  ~~~~~~
  Allow passing an argument of `encoder_class` to a field, which will result in that object (or
  the object located at that path, for instance `core.utils.JSONEncoder`) being used as the `cls`
  argument when serializing objects.

  You may also set this as a global value in settings.JSONFIELD_ENCODER_CLASS

  0.9.15
  ~~~~~~
  Bump version number to get around uploading issues.

  0.9.14
  ~~~~~~
  No longer hit the db to work out db_type.

  0.9.12
  ~~~~~~
  Cache the result of db_type.
  Handle incoming data from multiple select widget better.

  0.9.9
  ~~~~~
  Finally strip out non-required files.

  0.9.8
  ~~~~~
  Remove freezegun workarounds.
  Fix broken build.

  0.9.4
  ~~~~~
  Fixes for mutable defaults: we serialize and then deserialize in this
  case, so you can still use ``default={}``.

  0.9.3
  ~~~~~
  Remove support for storing data using Postgres' 9.2's JSON data type, as
  you cannot currently query against this!

  Remove support for django < 1.3.


  0.9.0
  ~~~~~
  Add LICENSE file.
  Added TypedJSONField.


  0.8.10
  ~~~~~~
  Allow ``{{ variable|jsonify }}`` to work with querysets.

  0.8.8
  ~~~~~
  Prevent circular import problem with django 1.3.1 and gargoyle.

  0.8.7
  ~~~~~
  Better handle null=True and blank=True: it should make sense what they do now.

  0.8.5
  ~~~~~
  Allow for '{}' and '[]', and make them not appear to be None.

  0.8.4
  ~~~~~
  Ensure the version number file is installed with the package.

  0.8.3
  ~~~~~
  Store the version number in one place only, now.

  0.8.2
  ~~~~~
  Oops. Packaging error prevented install from pypi. Added README.rst to manifest.

  0.8.1
  ~~~~~
  Converting to string does nothing, as serializing a model instance with a JSONField would have a string version of that field, instead of it embedded inline. (Back to pre 0.8 behaviour).

  Added better querying support: (``field__contains={'key':'value','key2':'value2'}`` works.)

  Removed JSONTableWidget from package.

  0.8
  ~~~
  (Many thanks to `IanLewis`_ for these features)

  Supports django 1.2

  Supports callable and json serializable objects as default

  Implemented get_db_prep_value()

  Add tests and test runner.

  Removed JSONTableWidget from README.

  0.7.1
  ~~~~~
  Don't fail when trying to install before django is installed.

  0.7
  ~~~
  First time I tagged releases.


  Todo
  ----------
  Allow for passing in a function to use for processing unknown data types.

  Convert date/time objects nicely to/from ISO strings (YYYY-mm-dd HH:MM:SS
  TZNAME). This is actually a bit tricky, as we don't know if we are expecting
  a date/time object. We may parse objects as we go, but there could be
  some performance issues with this. I'm tempted to say "only do this on TypedJSONField()"

  .. _David Cramer's blog: http://justcramer.com/2009/04/14/cleaning-up-with-json-and-sql/
  .. _IanLewis: https://bitbucket.org/IanLewis


pkgId: 27d31b88228ab120e5f8acedf71269ac132b8526c13ab5d8ec31c9febe7ce79a
name: rh-python36-django-polymorphic
arch: noarch
version: 2.1.2
epoch: 0
release: 1
summary: Seamless polymorphic inheritance for Django models
url: https://github.com/django-polymorphic/django-polymorphic
rpm_license: UNKNOWN
rpm_vendor: Christopher Glass <tribaal@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 68d1e4d64f874c6596594a943ab210cf
rpm_sourcerpm: rh-python36-django-polymorphic-2.1.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387126-rh-python36-django-polymorphic/rh-python36-django-polymorphic-2.1.2-1.noarch.rpm
checksum_type: sha256
description:
  .. image::  https://travis-ci.org/django-polymorphic/django-polymorphic.svg?branch=master
      :target: http://travis-ci.org/django-polymorphic/django-polymorphic
  .. image:: https://img.shields.io/pypi/v/django-polymorphic.svg
      :target: https://pypi.python.org/pypi/django-polymorphic/
  .. image:: https://img.shields.io/codecov/c/github/django-polymorphic/django-polymorphic/master.svg
      :target: https://codecov.io/github/django-polymorphic/django-polymorphic?branch=master

  Polymorphic Models for Django
  =============================

  Django-polymorphic simplifies using inherited models in Django projects.
  When a query is made at the base model, the inherited model classes are returned.

  When we store models that inherit from a ``Project`` model...

  .. code-block:: python

      >>> Project.objects.create(topic="Department Party")
      >>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner")
      >>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")

  ...and want to retrieve all our projects, the subclassed models are returned!

  .. code-block:: python

      >>> Project.objects.all()
      [ <Project:         id 1, topic "Department Party">,
        <ArtProject:      id 2, topic "Painting with Tim", artist "T. Turner">,
        <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ]

  Using vanilla Django, we get the base class objects, which is rarely what we wanted:

  .. code-block:: python

      >>> Project.objects.all()
      [ <Project: id 1, topic "Department Party">,
        <Project: id 2, topic "Painting with Tim">,
        <Project: id 3, topic "Swallow Aerodynamics"> ]

  This also works when the polymorphic model is accessed via
  ForeignKeys, ManyToManyFields or OneToOneFields.

  Features
  --------

  * Full admin integration.
  * ORM integration:

    * support for ForeignKey, ManyToManyField, OneToOneField descriptors.
    * Filtering/ordering of inherited models (``ArtProject___artist``).
    * Filtering model types: ``instance_of(...)`` and ``not_instance_of(...)``
    * Combining querysets of different models (``qs3 = qs1 | qs2``)
    * Support for custom user-defined managers.
  * Uses the minumum amount of queries needed to fetch the inherited models.
  * Disabling polymorphic behavior when needed.

  While *django-polymorphic* makes subclassed models easy to use in Django,
  we still encourage to use them with caution. Each subclassed model will require
  Django to perform an ``INNER JOIN`` to fetch the model fields from the database.
  While taking this in mind, there are valid reasons for using subclassed models.
  That's what this library is designed for!

  The current release of *django-polymorphic* supports Django 1.11, 2.0 and Python 2.7 and 3.4+ is supported.
  For older Django versions, install *django-polymorphic==1.3*.

  For more information, see the `documentation at Read the Docs <https://django-polymorphic.readthedocs.io/>`_.

  Installation
  ------------

  Install using ``pip``\ ...

  .. code:: bash

      $ pip install django-polymorphic

  License
  =======

  Django-polymorphic uses the same license as Django (BSD-like).


pkgId: 52cfc2a772469f591bc7642fe5dc2635e2c49ac537e0d1a502f233cb784d9b26
name: rh-python36-django-qsstats-magic
arch: noarch
version: 1.1.0
epoch: 0
release: 1
summary: A django microframework that eases the generation of aggregate data for querysets.
url: http://bitbucket.org/kmike/django-qsstats-magic/
rpm_license: UNKNOWN
rpm_vendor: Matt Croydon, Mikhail Korobov <mcroydon@gmail.com, kmike84@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 7423f83fdf1c423ba5ede820447f0f74
rpm_sourcerpm: rh-python36-django-qsstats-magic-1.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387197-rh-python36-django-qsstats-magic/rh-python36-django-qsstats-magic-1.1.0-1.noarch.rpm
checksum_type: sha256
description:
  ====================================================
  django-qsstats-magic: QuerySet statistics for Django
  ====================================================

  The goal of django-qsstats is to be a microframework to make
  repetitive tasks such as generating aggregate statistics of querysets
  over time easier.  It's probably overkill for the task at hand, but yay
  microframeworks!

  django-qsstats-magic is a refactoring of django-qsstats app with slightly
  changed API, simplified internals and faster time_series implementation.


  Requirements
  ============

  * `python-dateutil <http://labix.org/python-dateutil>`_ > 1.4, < 2.0
  * `django <http://www.djangoproject.com/>`_ 1.2+

  License
  =======

  Liensed under a BSD-style license.

  Examples
  ========

  How many users signed up today? this month? this year?
  ------------------------------------------------------

  ::

      from django.contrib.auth.models import User
      import qsstats

      qs = User.objects.all()
      qss = qsstats.QuerySetStats(qs, 'date_joined')

      print '%s new accounts today.' % qss.this_day()
      print '%s new accounts this week.' % qss.this_week()
      print '%s new accounts this month.' % qss.this_month()
      print '%s new accounts this year.' % qss.this_year()
      print '%s new accounts until now.' % qss.until_now()

  This might print something like::

      5 new accounts today.
      11 new accounts this week.
      27 new accounts this month.
      377 new accounts this year.
      409 new accounts until now.

  Aggregating time-series data suitable for graphing
  --------------------------------------------------

  ::

      from django.contrib.auth.models import User
      import datetime, qsstats

      qs = User.objects.all()
      qss = qsstats.QuerySetStats(qs, 'date_joined')

      today = datetime.date.today()
      seven_days_ago = today - datetime.timedelta(days=7)

      time_series = qss.time_series(seven_days_ago, today)
      print 'New users in the last 7 days: %s' % [t[1] for t in time_series]

  This might print something like::

      New users in the last 7 days: [3, 10, 7, 4, 12, 9, 11]


  Please see qsstats/tests.py for similar usage examples.

  API
  ===

  The ``QuerySetStats`` object
  ----------------------------

  In order to provide maximum flexibility, the ``QuerySetStats`` object
  can be instantiated with as little or as much information as you like.
  All keword arguments are optional but ``DateFieldMissing`` and
  ``QuerySetMissing`` will be raised if you try to use ``QuerySetStats``
  without providing enough information.

  ``qs``
      The queryset to operate on.

      Default: ``None``

  ``date_field``
      The date field within the queryset to use.

      Default: ``None``

  ``aggregate``
      The django aggregation instance. Can be set also set when
      instantiating or calling one of the methods.

      Default: ``Count('id')``

  ``operator``
      The default operator to use for the ``pivot`` function.  Can be also set
      when calling ``pivot``.

      Default: ``'lte'``

  ``today``
      The date that will be considered as today date. If ``today`` param is None
      QuerySetStats' today will be datetime.date.today().

      Default: ``None``


  All of the documented methods take a standard set of keyword arguments
  that override any information already stored within the ``QuerySetStats``
  object.  These keyword arguments are ``date_field`` and ``aggregate``.

  Once you have a ``QuerySetStats`` object instantiated, you can receive a
  single aggregate result by using the following methods:

  * ``for_minute``
  * ``for_hour``
  * ``for_day``
  * ``for_week``
  * ``for_month``
  * ``for_year``

      Positional arguments: ``dt``, a ``datetime.datetime`` or ``datetime.date``
      object to filter the queryset to this interval (minute, hour, day, week,
      month or year).

  * ``this_minute``
  * ``this_hour``
  * ``this_day``
  * ``this_week``
  * ``this_month``
  * ``this_year``

      Wrappers around ``for_<interval>`` that uses ``dateutil.relativedelta`` to
      provide aggregate information for this current interval.

  ``QuerySetStats`` also provides a method for returning aggregated
  time-series data which may be extremely using in plotting data:

  ``time_series``
      Positional arguments: ``start`` and ``end``, each a
      ``datetime.date`` or ``datetime.datetime`` object used in marking
      the start and stop of the time series data.

      Keyword arguments: In addition to the standard ``date_field`` and
      ``aggregate`` keyword argument, ``time_series`` takes an optional
      ``interval`` keyword argument used to mark which interval to use while
      calculating aggregate data between ``start`` and ``end``.  This argument
      defaults to ``'days'`` and can accept ``'years'``, ``'months'``,
      ``'weeks'``, ``'days'``, ``'hours'`` or ``'minutes'``.
      It will raise ``InvalidInterval`` otherwise.

      This methods returns a list of tuples.  The first item in each
      tuple is a ``datetime.datetime`` object for the current inverval.  The
      second item is the result of the aggregate operation.  For
      example::

          [(datetime.datetime(2010, 3, 28, 0, 0), 12), (datetime.datetime(2010, 3, 29, 0, 0), 0), ...]

      Formatting of date information is left as an exercise to the user and may
      vary depending on interval used.

  ``until``
      Provide aggregate information until a given date or time, filtering the
      queryset using ``lte``.

      Positional arguments: ``dt`` a ``datetime.date`` or ``datetime.datetime``
      object to be used for filtering the queryset since.

      Keyword arguments: ``date_field``, ``aggregate``.

  ``until_now``
      Aggregate information until now.

      Positional arguments: ``dt`` a ``datetime.date`` or ``datetime.datetime``
      object to be used for filtering the queryset since (using ``lte``).

      Keyword arguments: ``date_field``, ``aggregate``.

  ``after``
      Aggregate information after a given date or time, filtering the queryset
      using ``gte``.

      Positional arguments: ``dt`` a ``datetime.date`` or ``datetime.datetime``
      object to be used for filtering the queryset since.

      Keyword arguments: ``date_field``, ``aggregate``.

  ``after_now``
      Aggregate information after now.

      Positional arguments: ``dt`` a ``datetime.date`` or ``datetime.datetime``
      object to be used for filtering the queryset since (using ``gte``).

      Keyword arguments: ``date_field``, ``aggregate``.

  ``pivot``
      Used by ``since``, ``after``, and ``until_now`` but potentially useful if
      you would like to specify your own operator instead of the defaults.

      Positional arguments: ``dt`` a ``datetime.date`` or ``datetime.datetime``
      object to be used for filtering the queryset since (using ``lte``).

      Keyword arguments: ``operator``, ``date_field``, ``aggregate``.

      Raises ``InvalidOperator`` if the operator provided is not one of ``'lt'``,
      ``'lte'``, ``gt`` or ``gte``.

  Testing
  =======

  If you'd like to test ``django-qsstats-magic`` against your local configuration, add
  ``qsstats`` to your ``INSTALLED_APPS`` and run ``./manage.py test qsstats``.
  The test suite assumes that ``django.contrib.auth`` is installed.

  For testing against different python, DB and django versions install tox
  (pip install tox) and run 'tox' from the source checkout::

      $ tox

  Db user 'qsstats_test' with password 'qsstats_test' and a DB 'qsstats_test'
  should exist.

  Difference from django-qsstats
  ==============================

  1. Faster time_series method using 1 sql query (currently works for MySQL and
     PostgreSQL, with a fallback to the old method for other DB backends).
  2. Single ``aggregate`` parameter instead of ``aggregate_field`` and
     ``aggregate_class``. Default value is always ``Count('id')`` and can't be
     specified in settings.py. ``QUERYSETSTATS_DEFAULT_OPERATOR`` option is also
     unsupported now.
  3. Support for minute and hour aggregates.
  4. ``start_date`` and ``end_date`` arguments are renamed to ``start`` and
     ``end`` because of 3.
  5. Internals are changed.

  I don't know if original author (Matt Croydon) would like my changes so
  I renamed a project for now. If the changes will be merged then
  django-qsstats-magic will become obsolete.


pkgId: cc4ff7d017cd6746b3489b51049eb9c718954956e8500d46c4c1d766ac6fc5c9
name: rh-python36-django-split-settings
arch: noarch
version: 1.0.0
epoch: 0
release: 1
url: http://github.com/sobolevn/django-split-settings
rpm_license: UNKNOWN
rpm_vendor: Nikita Sobolev, Visa Kopu, Antti Kaihola <mail@sobolevn.me>
rpm_group: Development/Libraries
rpm_buildhost: 6cad0f400e0540029d47c8cc3e4f93a9
rpm_sourcerpm: rh-python36-django-split-settings-1.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387124-rh-python36-django-split-settings/rh-python36-django-split-settings-1.0.0-1.noarch.rpm
checksum_type: sha256
summary:
  Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files.

description:
  .. image:: https://github.com/sobolevn/django-split-settings/blob/master/media/logo-black.png?raw=true
       :target: https://github.com/sobolevn/django-split-settings
       :align: center

  ----------

  .. image:: https://travis-ci.org/sobolevn/django-split-settings.svg?branch=master
       :target: https://travis-ci.org/sobolevn/django-split-settings

  .. image:: https://coveralls.io/repos/github/sobolevn/django-split-settings/badge.svg?branch=master
       :target: https://coveralls.io/github/sobolevn/django-split-settings?branch=master

  .. image:: https://badge.fury.io/py/django-split-settings.svg
       :target: http://badge.fury.io/py/django-split-settings

  .. image:: https://img.shields.io/pypi/pyversions/django-split-settings.svg
       :target: https://pypi.python.org/pypi/django-split-settings

  .. image:: https://readthedocs.org/projects/django-split-settings/badge/?version=latest
        :target: http://django-split-settings.readthedocs.io/en/latest/?badge=latest

  Organize Django settings into multiple files and directories. Easily
  override and modify settings. Use wildcards in settings file paths
  and mark settings files as optional.

  Read this `medium`_ post for more information.

  .. _medium: https://medium.com/wemake-services/managing-djangos-settings-e2b7f496120d

  Requirements
  ------------

  While this package will most likely work with the most versions of ``django``, we do not officially support any versions except the latest release and the current LTS version, which are ``1.11`` and ``2.0`` right now.

  This package has no dependencies itself.


  Installation
  ------------

  Install by using ``pip``:

  .. code:: bash

      pip install django-split-settings

  We also recommend to try `pipenv <https://docs.pipenv.org/>`_ to handle dependencies.


  Usage
  -----

  Replace your existing ``settings.py`` with a list of components that
  make up your Django settings. Preferably create a settings package
  that contains all the files.

  Here's a minimal example:

  .. code:: python

      from split_settings.tools import optional, include

      include(
          'components/base.py',
          'components/database.py',
          optional('local_settings.py')
      )

  In the example, the files ``base.py`` and ``database.py`` are included
  in that order from the subdirectory called ``components/``.
  ``local_settings.py`` in the same directory is included if it exists.

  **Note:** The local context is passed on to each file, so each
  following file can access and modify the settings declared in the
  previous files.

  We also made a in-depth `tutorial`_.

  .. _tutorial: https://medium.com/wemake-services/managing-djangos-settings-e2b7f496120d


  Tips and tricks
  ---------------

  You can use wildcards in file paths:

  .. code:: python

      include('components/my_app/*.py')

  Note that files are included in the order that ``glob`` returns them,
  probably in the same order as what ``ls -U`` would list them. The
  files are NOT in alphabetical order.


  Do you want to contribute?
  --------------------------

  Read the `contributing`_ file.

  .. _contributing: https://github.com/sobolevn/django-split-settings/blob/master/CONTRIBUTING.rst


  Version history
  ---------------

  See `changelog`_ file.

  .. _changelog: https://github.com/sobolevn/django-split-settings/blob/master/CHANGELOG.rst


pkgId: 98a39e80eb245e7ffc0e0d1a9ad494be571a2e560a54d21a51a4e69c2f4767dd
name: rh-python36-django-taggit
arch: noarch
version: 1.2.0
epoch: 0
release: 1
summary: django-taggit is a reusable Django application for simple tagging.
url: http://github.com/alex/django-taggit/tree/master
rpm_license: BSD
rpm_vendor: Alex Gaynor <alex.gaynor@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 46bc89491ba347ee8cf2e8acfb916c71
rpm_sourcerpm: rh-python36-django-taggit-1.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387087-rh-python36-django-taggit/rh-python36-django-taggit-1.2.0-1.noarch.rpm
checksum_type: sha256
description:
  django-taggit
  =============
  .. image:: https://travis-ci.org/alex/django-taggit.svg?branch=master
      :target: https://travis-ci.org/alex/django-taggit
  .. image:: https://codecov.io/gh/alex/django-taggit/coverage.svg?branch=master
      :target: https://codecov.io/gh/alex/django-taggit?branch=master

  ``django-taggit`` a simpler approach to tagging with Django.  Add ``"taggit"`` to your
  ``INSTALLED_APPS`` then just add a TaggableManager to your model and go:

  .. code:: python

      from django.db import models

      from taggit.managers import TaggableManager

      class Food(models.Model):
          

          tags = TaggableManager()


  Then you can use the API like so:

  .. code:: python

      >>> apple = Food.objects.create(name="apple")
      >>> apple.tags.add("red", "green", "delicious")
      >>> apple.tags.all()
      [<Tag: red>, <Tag: green>, <Tag: delicious>]
      >>> apple.tags.remove("green")
      >>> apple.tags.all()
      [<Tag: red>, <Tag: delicious>]
      >>> Food.objects.filter(tags__name__in=["red"])
      [<Food: apple>, <Food: cherry>]

  Tags will show up for you automatically in forms and the admin.

  ``django-taggit`` requires Django 1.8 or greater.

  For more info check out the `documentation <https://django-taggit.readthedocs.io/en/latest/>`_.  And for questions about usage or
  development you can contact the
  `mailinglist <http://groups.google.com/group/django-taggit>`_.


pkgId: 7de29acb25a144cde6c2adfd8b919b48cdc2c4cee8055511f5723652992826e5
name: rh-python36-djangorestframework
arch: noarch
version: 3.11.0
epoch: 0
release: 1
summary: Web APIs for Django, made easy.
url: http://www.django-rest-framework.org
rpm_license: BSD
rpm_vendor: Tom Christie <tom@tomchristie.com>
rpm_group: Development/Libraries
rpm_buildhost: 0e17ad3f00734a4286dc4131e346e67a
rpm_sourcerpm: rh-python36-djangorestframework-3.11.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387273-rh-python36-djangorestframework/rh-python36-djangorestframework-3.11.0-1.noarch.rpm
checksum_type: sha256
description:
  [![build-status-image]][travis]
  [![coverage-status-image]][codecov]
  [![pypi-version]][pypi]
  [![Gitter](https://badges.gitter.im/tomchristie/django-rest-framework.svg)](https://gitter.im/tomchristie/django-rest-framework?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)

  **Awesome web-browsable Web APIs.**

  Full documentation for the project is available at [http://www.django-rest-framework.org][docs].

  ---



  REST framework is a *collaboratively funded project*. If you use
  REST framework commercially we strongly encourage you to invest in its
  continued development by [signing up for a paid plan][funding].

  The initial aim is to provide a single full-time position on REST framework.
  *Every single sign-up makes a significant impact towards making that possible.*

  [![][rover-img]][rover-url]
  [![][sentry-img]][sentry-url]
  [![][stream-img]][stream-url]
  [![][machinalis-img]][machinalis-url]
  [![][rollbar-img]][rollbar-url]

  Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Rover][rover-url], [Sentry][sentry-url], [Stream][stream-url], [Machinalis][machinalis-url], and [Rollbar][rollbar-url].

  ---



  Django REST framework is a powerful and flexible toolkit for building Web APIs.

  Some reasons you might want to use REST framework:

  * The [Web browsable API][sandbox] is a huge usability win for your developers.
  * [Authentication policies][authentication] including optional packages for [OAuth1a][oauth1-section] and [OAuth2][oauth2-section].
  * [Serialization][serializers] that supports both [ORM][modelserializer-section] and [non-ORM][serializer-section] data sources.
  * Customizable all the way down - just use [regular function-based views][functionview-section] if you don't need the [more][generic-views] [powerful][viewsets] [features][routers].
  * [Extensive documentation][docs], and [great community support][group].

  There is a live example API for testing purposes, [available here][sandbox].

  **Below**: *Screenshot from the browsable API*

  ![Screenshot][image]

  ----



  * Python (2.7, 3.4, 3.5, 3.6)
  * Django (1.10, 1.11, 2.0)



  Install using `pip`...

      pip install djangorestframework

  Add `'rest_framework'` to your `INSTALLED_APPS` setting.

      INSTALLED_APPS = (
          ...
          'rest_framework',
      )



  Let's take a look at a quick example of using REST framework to build a simple model-backed API for accessing users and groups.

  Startup up a new project like so...

      pip install django
      pip install djangorestframework
      django-admin.py startproject example .
      ./manage.py migrate
      ./manage.py createsuperuser


  Now edit the `example/urls.py` module in your project:

  ```python
  from django.conf.urls import url, include
  from django.contrib.auth.models import User
  from rest_framework import serializers, viewsets, routers


  class UserSerializer(serializers.HyperlinkedModelSerializer):
      class Meta:
          model = User
          fields = ('url', 'username', 'email', 'is_staff')



  class UserViewSet(viewsets.ModelViewSet):
      queryset = User.objects.all()
      serializer_class = UserSerializer



  router = routers.DefaultRouter()
  router.register(r'users', UserViewSet)




  urlpatterns = [
      url(r'^', include(router.urls)),
      url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
  ]
  ```

  We'd also like to configure a couple of settings for our API.

  Add the following to your `settings.py` module:

  ```python
  INSTALLED_APPS = (
      ...  # Make sure to include the default installed apps here.
      'rest_framework',
  )

  REST_FRAMEWORK = {
      
      
      'DEFAULT_PERMISSION_CLASSES': [
          'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
      ]
  }
  ```

  That's it, we're done!

      ./manage.py runserver

  You can now open the API in your browser at `http://127.0.0.1:8000/`, and view your new 'users' API. If you use the `Login` control in the top right corner you'll also be able to add, create and delete users from the system.

  You can also interact with the API using command line tools such as [`curl`](http://curl.haxx.se/). For example, to list the users endpoint:

      $ curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
  	[
  	    {
  	        "url": "http://127.0.0.1:8000/users/1/",
  	        "username": "admin",
  	        "email": "admin@example.com",
  	        "is_staff": true,
  	    }
  	]

  Or to create a new user:

      $ curl -X POST -d username=new -d email=new@example.com -d is_staff=false -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
      {
          "url": "http://127.0.0.1:8000/users/2/",
          "username": "new",
          "email": "new@example.com",
          "is_staff": false,
      }



  Full documentation for the project is available at [http://www.django-rest-framework.org][docs].

  For questions and support, use the [REST framework discussion group][group], or `#restframework` on freenode IRC.

  You may also want to [follow the author on Twitter][twitter].



  If you believe you've found something in Django REST framework which has security implications, please **do not raise the issue in a public forum**.

  Send a description of the issue via email to [rest-framework-security@googlegroups.com][security-mail].  The project maintainers will then work with you to resolve any issues where required, prior to any public disclosure.

  [build-status-image]: https://secure.travis-ci.org/encode/django-rest-framework.svg?branch=master
  [travis]: http://travis-ci.org/encode/django-rest-framework?branch=master
  [coverage-status-image]: https://img.shields.io/codecov/c/github/encode/django-rest-framework/master.svg
  [codecov]: http://codecov.io/github/encode/django-rest-framework?branch=master
  [pypi-version]: https://img.shields.io/pypi/v/djangorestframework.svg
  [pypi]: https://pypi.python.org/pypi/djangorestframework
  [twitter]: https://twitter.com/_tomchristie
  [group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework
  [sandbox]: http://restframework.herokuapp.com/

  [funding]: https://fund.django-rest-framework.org/topics/funding/
  [sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors

  [rover-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/rover-readme.png
  [sentry-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/sentry-readme.png
  [stream-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/stream-readme.png
  [machinalis-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/machinalis-readme.png
  [rollbar-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/rollbar-readme.png

  [rover-url]: http://jobs.rover.com/
  [sentry-url]: https://getsentry.com/welcome/
  [stream-url]: https://getstream.io/try-the-api/?utm_source=drf&utm_medium=banner&utm_campaign=drf
  [machinalis-url]: https://hello.machinalis.co.uk/
  [rollbar-url]: https://rollbar.com/

  [oauth1-section]: http://www.django-rest-framework.org/api-guide/authentication/#django-rest-framework-oauth
  [oauth2-section]: http://www.django-rest-framework.org/api-guide/authentication/#django-oauth-toolkit
  [serializer-section]: http://www.django-rest-framework.org/api-guide/serializers/#serializers
  [modelserializer-section]: http://www.django-rest-framework.org/api-guide/serializers/#modelserializer
  [functionview-section]: http://www.django-rest-framework.org/api-guide/views/#function-based-views
  [generic-views]: http://www.django-rest-framework.org/api-guide/generic-views/
  [viewsets]: http://www.django-rest-framework.org/api-guide/viewsets/
  [routers]: http://www.django-rest-framework.org/api-guide/routers/
  [serializers]: http://www.django-rest-framework.org/api-guide/serializers/
  [authentication]: http://www.django-rest-framework.org/api-guide/authentication/
  [image]: http://www.django-rest-framework.org/img/quickstart.png

  [docs]: http://www.django-rest-framework.org/
  [security-mail]: mailto:rest-framework-security@googlegroups.com


pkgId: 4fd8b14ac182ca98728f0870bf06f427c2a802178649c95e22282a25224ff423
name: rh-python36-docutils
arch: noarch
version: 0.16
epoch: 0
release: 1
summary: Docutils -- Python Documentation Utilities
url: http://docutils.sourceforge.net/
rpm_license: public domain, Python, 2-Clause BSD, GPL 3 (see COPYING.txt)
rpm_vendor: docutils-develop list <docutils-develop@lists.sourceforge.net>
rpm_group: Development/Libraries
rpm_buildhost: ef4ed969aec2427eab5ecaae16a1e041
rpm_sourcerpm: rh-python36-docutils-0.16-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387291-rh-python36-docutils/rh-python36-docutils-0.16-1.noarch.rpm
checksum_type: sha256
description:
  Docutils is a modular system for processing documentation
  into useful formats, such as HTML, XML, and LaTeX.  For
  input Docutils supports reStructuredText, an easy-to-read,
  what-you-see-is-what-you-get plaintext markup syntax.


pkgId: 67451cc9f37e3d45acf3fb0617332834fb2fe370425a37ed06660af137638873
name: rh-python36-dogpile.cache
arch: noarch
version: 0.9.0
epoch: 0
release: 1
summary: A caching front-end based on the Dogpile lock.
url: http://bitbucket.org/zzzeek/dogpile.cache
rpm_license: BSD
rpm_vendor: Mike Bayer <mike_mp@zzzcomputing.com>
rpm_group: Development/Libraries
rpm_buildhost: 1d17142e070f4427adebf9108364b432
rpm_sourcerpm: rh-python36-dogpile.cache-0.9.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387226-rh-python36-dogpile.cache/rh-python36-dogpile.cache-0.9.0-1.noarch.rpm
checksum_type: sha256
description:
  dogpile
  =======

  Dogpile consists of two subsystems, one building on top of the other.

  ``dogpile`` provides the concept of a "dogpile lock", a control structure
  which allows a single thread of execution to be selected as the "creator" of
  some resource, while allowing other threads of execution to refer to the previous
  version of this resource as the creation proceeds; if there is no previous
  version, then those threads block until the object is available.

  ``dogpile.cache`` is a caching API which provides a generic interface to
  caching backends of any variety, and additionally provides API hooks which
  integrate these cache backends with the locking mechanism of ``dogpile``.

  Overall, dogpile.cache is intended as a replacement to the `Beaker
  <http://beaker.groovie.org>`_ caching system, the internals of which are
  written by the same author.   All the ideas of Beaker which "work" are re-
  implemented in dogpile.cache in a more efficient and succinct manner, and all
  the cruft (Beaker's internals were first written in 2005) relegated to the
  trash heap.

  Documentation
  -------------

  See dogpile.cache's full documentation at
  `dogpile.cache documentation <http://dogpilecache.readthedocs.org>`_.  The
  sections below provide a brief synopsis of the ``dogpile`` packages.

  Features
  --------

  * A succinct API which encourages up-front configuration of pre-defined
    "regions", each one defining a set of caching characteristics including
    storage backend, configuration options, and default expiration time.
  * A standard get/set/delete API as well as a function decorator API is
    provided.
  * The mechanics of key generation are fully customizable.   The function
    decorator API features a pluggable "key generator" to customize how
    cache keys are made to correspond to function calls, and an optional
    "key mangler" feature provides for pluggable mangling of keys
    (such as encoding, SHA-1 hashing) as desired for each region.
  * The dogpile lock, first developed as the core engine behind the Beaker
    caching system, here vastly simplified, improved, and better tested.
    Some key performance
    issues that were intrinsic to Beaker's architecture, particularly that
    values would frequently be "double-fetched" from the cache, have been fixed.
  * Backends implement their own version of a "distributed" lock, where the
    "distribution" matches the backend's storage system.  For example, the
    memcached backends allow all clients to coordinate creation of values
    using memcached itself.   The dbm file backend uses a lockfile
    alongside the dbm file.  New backends, such as a Redis-based backend,
    can provide their own locking mechanism appropriate to the storage
    engine.
  * Writing new backends or hacking on the existing backends is intended to be
    routine - all that's needed are basic get/set/delete methods. A distributed
    lock tailored towards the backend is an optional addition, else dogpile uses
    a regular thread mutex. New backends can be registered with dogpile.cache
    directly or made available via setuptools entry points.
  * Included backends feature three memcached backends (python-memcached, pylibmc,
    bmemcached), a Redis backend, a backend based on Python's
    anydbm, and a plain dictionary backend.
  * Space for third party plugins, including one which provides the
    dogpile.cache engine to Mako templates.


pkgId: 8d90ce2e1b9fe19841affd5834b2802997e1395858bb4905f0dbd8f560beba5e
name: rh-python36-extras
arch: noarch
version: 1.0.0
epoch: 0
release: 1
summary: Useful extra bits for Python - things that shold be in the standard library
url: https://github.com/testing-cabal/extras
rpm_license: UNKNOWN
rpm_vendor: Testing cabal <testtools-dev@lists.launchpad.net>
rpm_group: Development/Libraries
rpm_buildhost: b28fb9a959a84db0bef7af96bb3cac13
rpm_sourcerpm: rh-python36-extras-1.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387054-rh-python36-extras/rh-python36-extras-1.0.0-1.noarch.rpm
checksum_type: sha256
description:
  ======
  extras
  ======

  extras is a set of extensions to the Python standard library, originally
  written to make the code within testtools cleaner, but now split out for
  general use outside of a testing context.


  Documentation
  -------------

  pydoc extras is your friend. extras currently contains the following functions:

  * try_import

  * try_imports

  * safe_hasattr

  Which do what their name suggests.


  Licensing
  ---------

  This project is distributed under the MIT license and copyright is owned by
  the extras authors. See LICENSE for details.


  Required Dependencies
  ---------------------

   * Python 2.6+ or 3.0+


  Bug reports and patches
  -----------------------

  Please report bugs using github issues at <https://github.com/testing-cabal/extras>.
  Patches can also be submitted via github.  You can mail the authors directly
  via the mailing list testtools-dev@lists.launchpad.net. (Note that Launchpad
  discards email from unknown addresses - be sure to sign up for a Launchpad
  account before mailing the list, or your mail will be silently discarded).


  History
  -------

  extras used to be testtools.helpers, and was factored out when folk wanted to
  use it separately.


  Thanks
  ------

   * Martin Pool


pkgId: 2c77db39ac70a7b5ac5a51a1dd8cb546dc076207521add8551a1d010361b054a
name: rh-python36-fixtures
arch: noarch
version: 3.0.0
epoch: 0
release: 1
summary: Fixtures, reusable state for writing clean tests and more.
url: https://launchpad.net/python-fixtures
rpm_license: UNKNOWN
rpm_vendor: Robert Collins <robertc@robertcollins.net>
rpm_group: Development/Libraries
rpm_buildhost: 043b430145394fefb4d98a1551c899df
rpm_sourcerpm: rh-python36-fixtures-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387053-rh-python36-fixtures/rh-python36-fixtures-3.0.0-1.noarch.rpm
checksum_type: sha256
description:
  *************************************************************
  fixtures: Fixtures with cleanups for testing and convenience.
  *************************************************************

    Copyright (c) 2010, Robert Collins <robertc@robertcollins.net>

    Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
    license at the users choice. A copy of both licenses are available in the
    project source as Apache-2.0 and BSD. You may not use this file except in
    compliance with one of these two licences.

    Unless required by applicable law or agreed to in writing, software
    distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
    license you chose for the specific language governing permissions and
    limitations under that license.


  Fixtures defines a Python contract for reusable state / support logic,
  primarily for unit testing. Helper and adaption logic is included to make it
  easy to write your own fixtures using the fixtures contract. Glue code is
  provided that makes using fixtures that meet the Fixtures contract in unittest
  compatible test cases easy and straight forward.

  Dependencies
  ============

  * Python 2.6+, or 3.3+
    This is the base language fixtures is written in and for.

  * pbr
    Used for version and release management of fixtures.

  * testtools <https://launchpad.net/testtools> 0.9.22 or newer.
    testtools provides helpful glue functions for the details API used to report
    information about a fixture (whether its used in a testing or production
    environment).

  For use in a unit test suite using the included glue, one of:

  * Python 2.7+

  * unittest2

  * bzrlib.tests

  * Or any other test environment that supports TestCase.addCleanup.

  Writing your own glue code is easy, or you can simply use Fixtures directly
  without any support code.

  To run the test suite for fixtures, testtools is needed.

  Why Fixtures
  ============

  Standard Python unittest.py provides no obvious method for making and reusing
  state needed in a test case other than by adding a method on the test class.
  This scales poorly - complex helper functions propagating up a test class
  hierarchy is a regular pattern when this is done. Mocking while a great tool
  doesn't itself prevent this (and helpers to mock complex things can accumulate
  in the same way if placed on the test class).

  By defining a uniform contract where helpers have no dependency on the test
  class we permit all the regular code hygiene activities to take place without
  the distorting influence of being in a class hierarchy that is modelling an
  entirely different thing - which is what helpers on a TestCase suffer from.

  About Fixtures
  ==============

  A Fixture represents some state. Each fixture has attributes on it that are
  specific to the fixture. For instance, a fixture representing a directory that
  can be used for temporary files might have a attribute 'path'.

  Most fixtures have complete ``pydoc`` documentation, so be sure to check
  ``pydoc fixtures`` for usage information.

  Creating Fixtures
  =================

  Minimally, subclass Fixture, define _setUp to initialize your state and schedule
  a cleanup for when cleanUp is called and you're done::

    >>> import unittest
    >>> import fixtures
    >>> class NoddyFixture(fixtures.Fixture):
    ...     def _setUp(self):
    ...         self.frobnozzle = 42
    ...         self.addCleanup(delattr, self, 'frobnozzle')

  This will initialize frobnozzle when ``setUp`` is called, and when ``cleanUp``
  is called get rid of the frobnozzle attribute. Prior to version 1.3.0 fixtures
  recommended overriding ``setUp``. This is still supported, but since it is
  harder to write leak-free fixtures in this fashion, it is not recommended.

  If your fixture has diagnostic data - for instance the log file of an
  application server, or log messages, it can expose that by creating a content
  object (``testtools.content.Content``) and calling ``addDetail``.

    >>> from testtools.content import text_content
    >>> class WithLog(fixtures.Fixture):
    ...     def _setUp(self):
    ...         self.addDetail('message', text_content('foo bar baz'))

  The method ``useFixture`` will use another fixture, call ``setUp`` on it, call
  ``self.addCleanup(thefixture.cleanUp)``, attach any details from it and return
  the fixture. This allows simple composition of different fixtures.

    >>> class ReusingFixture(fixtures.Fixture):
    ...     def _setUp(self):
    ...         self.noddy = self.useFixture(NoddyFixture())

  There is a helper for adapting a function or function pair into Fixtures. it
  puts the result of the function in fn_result::

    >>> import os.path
    >>> import shutil
    >>> import tempfile
    >>> def setup_function():
    ...     return tempfile.mkdtemp()
    >>> def teardown_function(fixture):
    ...     shutil.rmtree(fixture)
    >>> fixture = fixtures.FunctionFixture(setup_function, teardown_function)
    >>> fixture.setUp()
    >>> print (os.path.isdir(fixture.fn_result))
    True
    >>> fixture.cleanUp()

  This can be expressed even more pithily:

    >>> fixture = fixtures.FunctionFixture(tempfile.mkdtemp, shutil.rmtree)
    >>> fixture.setUp()
    >>> print (os.path.isdir(fixture.fn_result))
    True
    >>> fixture.cleanUp()

  Another variation is MethodFixture which is useful for adapting alternate
  fixture implementations to Fixture::

    >>> class MyServer:
    ...    def start(self):
    ...        pass
    ...    def stop(self):
    ...        pass
    >>> server = MyServer()
    >>> fixture = fixtures.MethodFixture(server, server.start, server.stop)

  You can also combine existing fixtures using ``CompoundFixture``::

    >>> noddy_with_log = fixtures.CompoundFixture([NoddyFixture(),
    ...                                            WithLog()])
    >>> with noddy_with_log as x:
    ...     print (x.fixtures[0].frobnozzle)
    42

  The Fixture API
  ===============

  The example above introduces some of the Fixture API. In order to be able to
  clean up after a fixture has been used, all fixtures define a ``cleanUp``
  method which should be called when a fixture is finished with.

  Because it's nice to be able to build a particular set of related fixtures in
  advance of using them, fixtures also have a ``setUp`` method which should be
  called before trying to use them.

  One common desire with fixtures that are expensive to create is to reuse them
  in many test cases; to support this the base Fixture also defines a ``reset``
  which calls ``self.cleanUp(); self.setUp()``. Fixtures that can more
  efficiently make themselves reusable should override this method. This can then
  be used with multiple test state via things like ``testresources``,
  ``setUpClass``, or ``setUpModule``.

  When using a fixture with a test you can manually call the setUp and cleanUp
  methods. More convenient though is to use the included glue from
  ``fixtures.TestWithFixtures`` which provides a mixin defining
  ``useFixture`` (camel case because unittest is camel case throughout) method.
  It will call setUp on the fixture, call self.addCleanup(fixture) to schedule a
  cleanup, and return the fixture. This lets one write::

    >>> import testtools
    >>> import unittest

  Note that we use testtools TestCase here as we need to guarantee a
  TestCase.addCleanup method in this doctest. Unittest2 - Python2.7 and above -
  also have ``addCleanup``. testtools has it's own implementation of
  ``useFixture`` so there is no need to use ``fixtures.TestWithFixtures`` with
  ``testtools.TestCase``.

    >>> class NoddyTest(testtools.TestCase, fixtures.TestWithFixtures):
    ...     def test_example(self):
    ...         fixture = self.useFixture(NoddyFixture())
    ...         self.assertEqual(42, fixture.frobnozzle)
    >>> result = unittest.TestResult()
    >>> _ = NoddyTest('test_example').run(result)
    >>> print (result.wasSuccessful())
    True

  Fixtures implement the context protocol, so you can also use a fixture as a
  context manager::

    >>> with fixtures.FunctionFixture(setup_function, teardown_function) as fixture:
    ...    print (os.path.isdir(fixture.fn_result))
    True

  When multiple cleanups error, fixture.cleanUp() will raise a wrapper exception
  rather than choosing an arbitrary single exception to raise::

    >>> import sys
    >>> from fixtures.fixture import MultipleExceptions
    >>> class BrokenFixture(fixtures.Fixture):
    ...     def _setUp(self):
    ...         self.addCleanup(lambda:1/0)
    ...         self.addCleanup(lambda:1/0)
    >>> fixture = BrokenFixture()
    >>> fixture.setUp()
    >>> try:
    ...    fixture.cleanUp()
    ... except MultipleExceptions:
    ...    exc_info = sys.exc_info()
    >>> print (exc_info[1].args[0][0].__name__)
    ZeroDivisionError

  Fixtures often expose diagnostic details that can be useful for tracking down
  issues. The ``getDetails`` method will return a dict of all the attached
  details, but can only be called before ``cleanUp`` is called. Each detail
  object is an instance of ``testtools.content.Content``.

    >>> with WithLog() as l:
    ...     print(l.getDetails()['message'].as_text())
    foo bar baz

  Errors in setUp
  +++++++++++++++

  The examples above used ``_setUp`` rather than ``setUp`` because the base
  class implementation of ``setUp`` acts to reduce the chance of leaking
  external resources if an error is raised from ``_setUp``. Specifically,
  ``setUp`` contains a try:/except: block which catches all exceptions, captures
  any registered detail objects, and calls ``self.cleanUp`` before propagating
  the error. As long as you take care to register any cleanups before calling
  the code that may fail, this will cause them to be cleaned up. The captured
  detail objects are provided to the args of the raised exception.

  If the error that occured was a subclass of ``Exception`` then ``setUp`` will
  raise ``MultipleExceptions`` with the last element being a ``SetupError`` that
  contains the detail objects. Otherwise, to prevent causing normally
  uncatchable errors like KeyboardInterrupt being caught inappropriately in the
  calling layer, the original exception will be raised as-is and no diagnostic
  data other than that from the original exception will be available.

  Shared Dependencies
  +++++++++++++++++++

  A common use case within complex environments is having some fixtures shared by
  other ones.

  Consider the case of testing using a ``TempDir`` with two fixtures built on top
  of it; say a small database and a web server. Writing either one is nearly
  trivial. However handling ``reset()`` correctly is hard: both the database and
  web server would reasonably expect to be able to discard operating system
  resources they may have open within the temporary directory before its removed.
  A recursive ``reset()`` implementation would work for one, but not both.
  Calling ``reset()`` on the ``TempDir`` instance between each test is probably
  desirable but we don't want to have to do a complete ``cleanUp`` of the higher
  layer fixtures (which would make the ``TempDir`` be unused and trivially
  resettable. We have a few options available to us.

  Imagine that the webserver does not depend on the DB fixture in any way - we
  just want the webserver and DB fixture to coexist in the same tempdir.

  A simple option is to just provide an explicit dependency fixture for the
  higher layer fixtures to use.  This pushes complexity out of the core and onto
  users of fixtures::

    >>> class WithDep(fixtures.Fixture):
    ...     def __init__(self, tempdir, dependency_fixture):
    ...         super(WithDep, self).__init__()
    ...         self.tempdir = tempdir
    ...         self.dependency_fixture = dependency_fixture
    ...     def setUp(self):
    ...         super(WithDep, self).setUp()
    ...         self.addCleanup(self.dependency_fixture.cleanUp)
    ...         self.dependency_fixture.setUp()
    ...         # we assume that at this point self.tempdir is usable.
    >>> DB = WithDep
    >>> WebServer = WithDep
    >>> tempdir = fixtures.TempDir()
    >>> db = DB(tempdir, tempdir)
    >>> server = WebServer(tempdir, db)
    >>> server.setUp()
    >>> server.cleanUp()

  Another option is to write the fixtures to gracefully handle a dependency
  being reset underneath them. This is insufficient if the fixtures would
  block the dependency resetting (for instance by holding file locks open
  in a tempdir - on Windows this will prevent the directory being deleted).

  Another approach which ``fixtures`` neither helps nor hinders is to raise
  a signal of some sort for each user of a fixture before it is reset. In the
  example here, ``TempDir`` might offer a subscribers attribute that both the
  DB and web server would be registered in. Calling ``reset`` or ``cleanUp``
  on the tempdir would trigger a callback to all the subscribers; the DB and
  web server reset methods would look something like:

    >>> def reset(self):
    ...     if not self._cleaned:
    ...         self._clean()

  (Their action on the callback from the tempdir would be to do whatever work
  was needed and set ``self._cleaned``.) This approach has the (perhaps)
  suprising effect that resetting the webserver may reset the DB - if the
  webserver were to be depending on ``tempdir.reset`` as a way to reset the
  webservers state.

  Another approach which is not currently implemented is to provide an object
  graph of dependencies and a reset mechanism that can traverse that, along with
  a separation between 'reset starting' and 'reset finishing' - the DB and
  webserver would both have their ``reset_starting`` methods called, then the
  tempdir would be reset, and finally the DB and webserver would have
  ``reset_finishing`` called.

  Stock Fixtures
  ==============

  In addition to the Fixture, FunctionFixture and MethodFixture classes fixtures
  includes a number of precanned fixtures. The API docs for fixtures will list
  the complete set of these, should the dcs be out of date or not to hand. For
  the complete feature set of each fixture please see the API docs.

  ByteStream
  ++++++++++

  Trivial adapter to make a BytesIO (though it may in future auto-spill to disk
  for large content) and expose that as a detail object, for automatic inclusion
  in test failure descriptions. Very useful in combination with MonkeyPatch.

    >>> fixture = fixtures.StringStream('my-content')
    >>> fixture.setUp()
    >>> with fixtures.MonkeyPatch('sys.something', fixture.stream):
    ...     pass
    >>> fixture.cleanUp()

  EnvironmentVariable
  +++++++++++++++++++

  Isolate your code from environmental variables, delete them or set them to a
  new value.

    >>> fixture = fixtures.EnvironmentVariable('HOME')

  FakeLogger
  ++++++++++

  Isolate your code from an external logging configuration - so that your test
  gets the output from logged messages, but they don't go to e.g. the console.

    >>> fixture = fixtures.FakeLogger()

  FakePopen
  +++++++++

  Pretend to run an external command rather than needing it to be present to run
  tests.

    >>> from testtools.compat import BytesIO
    >>> fixture = fixtures.FakePopen(lambda _:{'stdout': BytesIO('foobar')})

  MockPatchObject
  +++++++++++++++

  Adapts ``mock.patch.object`` to be used as a Fixture.

    >>> class Fred:
    ...     value = 1
    >>> fixture = fixtures.MockPatchObject(Fred, 'value', 2)
    >>> with fixture:
    ...     Fred().value
    2
    >>> Fred().value
    1

  MockPatch
  +++++++++

  Adapts ``mock.patch`` to be used as a Fixture.

    >>> fixture = fixtures.MockPatch('subprocess.Popen.returncode', 3)

  MockPatchMultiple
  +++++++++++++++++

  Adapts ``mock.patch.multiple`` to be used as a Fixture.

    >>> fixture = fixtures.MockPatchMultiple('subprocess.Popen', returncode=3)

  MonkeyPatch
  +++++++++++

  Control the value of a named python attribute.

    >>> def fake_open(path, mode):
    ...     pass
    >>> fixture = fixtures.MonkeyPatch('__builtin__.open', fake_open)

  Note that there are some complexities when patching methods - please see the
  API documentation for details.

  NestedTempfile
  ++++++++++++++

  Change the default directory that the tempfile module places temporary files
  and directories in. This can be useful for containing the noise created by
  code which doesn't clean up its temporary files. This does not affect
  temporary file creation where an explicit containing directory was provided.

    >>> fixture = fixtures.NestedTempfile()

  PackagePathEntry
  ++++++++++++++++

  Adds a single directory to the path for an existing python package. This adds
  to the package.__path__ list. If the directory is already in the path, nothing
  happens, if it isn't then it is added on setUp and removed on cleanUp.

    >>> fixture = fixtures.PackagePathEntry('package/name', '/foo/bar')

  PythonPackage
  +++++++++++++

  Creates a python package directory. Particularly useful for testing code that
  dynamically loads packages/modules, or for mocking out the command line entry
  points to Python programs.

    >>> fixture = fixtures.PythonPackage('foo.bar', [('quux.py', '')])

  PythonPathEntry
  +++++++++++++++

  Adds a single directory to sys.path. If the directory is already in the path,
  nothing happens, if it isn't then it is added on setUp and removed on cleanUp.

    >>> fixture = fixtures.PythonPathEntry('/foo/bar')

  StringStream
  ++++++++++++

  Trivial adapter to make a StringIO (though it may in future auto-spill to disk
  for large content) and expose that as a detail object, for automatic inclusion
  in test failure descriptions. Very useful in combination with MonkeyPatch.

    >>> fixture = fixtures.StringStream('stdout')
    >>> fixture.setUp()
    >>> with fixtures.MonkeyPatch('sys.stdout', fixture.stream):
    ...     pass
    >>> fixture.cleanUp()

  TempDir
  +++++++

  Create a temporary directory and clean it up later.

    >>> fixture = fixtures.TempDir()

  The created directory is stored in the ``path`` attribute of the fixture after
  setUp.

  TempHomeDir
  +++++++++++

  Create a temporary directory and set it as $HOME in the environment.

    >>> fixture = fixtures.TempHomeDir()

  The created directory is stored in the ``path`` attribute of the fixture after
  setUp.

  The environment will now have $HOME set to the same path, and the value
  will be returned to its previous value after tearDown.

  Timeout
  +++++++

  Aborts if the covered code takes more than a specified number of whole wall-clock
  seconds.

  There are two possibilities, controlled by the 'gentle' argument: when gentle,
  an exception will be raised and the test (or other covered code) will fail.
  When not gentle, the entire process will be terminated, which is less clean,
  but more likely to break hangs where no Python code is running.

  *Caution:* Only one timeout can be active at any time across all threads in a
  single process.  Using more than one has undefined results.  (This could be
  improved by chaining alarms.)

  *Note:* Currently supported only on Unix because it relies on the ``alarm``
  system call.

  Contributing
  ============

  Fixtures has its project homepage on Launchpad
  <https://launchpad.net/python-fixtures>. Source code is hosted on GitHub
  <https://github.com/testing-cabal/fixtures>.


pkgId: 73eb79b92f80d67a5c38e068dadc5152ff52353c0b6525460677f15362b4eaaf
name: rh-python36-google-auth
arch: noarch
version: 1.11.3
epoch: 0
release: 1
summary: Google Authentication Library
url: https://github.com/GoogleCloudPlatform/google-auth-library-python
rpm_license: Apache 2.0
rpm_vendor: Google Cloud Platform <jonwayne+google-auth@google.com>
rpm_group: Development/Libraries
rpm_buildhost: 3e178d80980b4f809d8b40bcf8f0ada7
rpm_sourcerpm: rh-python36-google-auth-1.11.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387283-rh-python36-google-auth/rh-python36-google-auth-1.11.3-1.noarch.rpm
checksum_type: sha256
description:
  Google Auth Python Library
  ==========================

  |build| |docs| |pypi|

  This library simplifies using Google's various server-to-server authentication
  mechanisms to access Google APIs.

  .. |build| image:: https://travis-ci.org/GoogleCloudPlatform/google-auth-library-python.svg?branch=master
     :target: https://travis-ci.org/GoogleCloudPlatform/google-auth-library-python
  .. |docs| image:: https://readthedocs.org/projects/google-auth/badge/?version=latest
     :target: https://google-auth.readthedocs.io/en/latest/
  .. |pypi| image:: https://img.shields.io/pypi/v/google-auth.svg
     :target: https://pypi.python.org/pypi/google-auth

  Installing
  ----------

  You can install using `pip`_::

      $ pip install google-auth

  .. _pip: https://pip.pypa.io/en/stable/

  For more information on setting up your Python development environment, please refer to `Python Development Environment Setup Guide`_ for Google Cloud Platform.

  .. _`Python Development Environment Setup Guide`: https://cloud.google.com/python/setup

  Supported Python Versions
  ^^^^^^^^^^^^^^^^^^^^^^^^^
  Python >= 3.4

  Deprecated Python Versions
  ^^^^^^^^^^^^^^^^^^^^^^^^^^
  Python == 2.7. Python 2.7 support will be removed on January 1, 2020.

  Documentation
  -------------

  Google Auth Python Library has usage and reference documentation at `google-auth.readthedocs.io <https://google-auth.readthedocs.io>`_.

  Maintainers
  -----------

  - `@theacodes <https://github.com/theacodes>`_ (Thea Flowers)
  - `@dhermes <https://github.com/dhermes>`_ (Danny Hermes)
  - `@lukesneeringer <https://github.com/lukesneeringer>`_ (Luke Sneeringer)

  Contributing
  ------------

  Contributions to this library are always welcome and highly encouraged.

  See `CONTRIBUTING.rst`_ for more information on how to get started.

  .. _CONTRIBUTING.rst: https://github.com/GoogleCloudPlatform/google-auth-library-python/blob/master/CONTRIBUTING.rst

  License
  -------

  Apache 2.0 - See `the LICENSE`_ for more information.

  .. _the LICENSE: https://github.com/GoogleCloudPlatform/google-auth-library-python/blob/master/LICENSE


pkgId: 0317cf411fe0067a1ad13fbfc557ae1078f43bed552b0065af83e6199dd57de8
name: rh-python36-hiredis
arch: src
version: 1.0.1
epoch: 0
release: 1
summary: Python wrapper for hiredis
url: https://github.com/redis/hiredis-py
rpm_license: BSD
rpm_vendor: Jan-Erik Rediger, Pieter Noordhuis <janerik@fnordig.de, pcnoordhuis@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 1eeabfa2a1ac4bdc89fc34fa59eef529
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387014-rh-python36-hiredis/rh-python36-hiredis-1.0.1-1.src.rpm
checksum_type: sha256
description:
  [![Build Status](https://travis-ci.org/redis/hiredis-py.svg?branch=master)](https://travis-ci.org/redis/hiredis-py)
  [![Windows Build Status](https://ci.appveyor.com/api/projects/status/muso9gbe316tjsac/branch/master?svg=true)](https://ci.appveyor.com/project/duyue/hiredis-py/)

  Python extension that wraps protocol parsing code in [hiredis][hiredis].
  It primarily speeds up parsing of multi bulk replies.

  [hiredis]: http://github.com/redis/hiredis



  hiredis-py is available on [PyPI](https://pypi.org/project/hiredis/), and can
  be installed with:

  ```
  pip install hiredis
  ```



  hiredis-py requires **Python 2.7 or 3.4+**.

  Make sure Python development headers are available when installing hiredis-py.
  On Ubuntu/Debian systems, install them with `apt-get install python-dev` for Python 2
  or `apt-get install python3-dev` for Python 3.



  The `hiredis` module contains the `Reader` class. This class is responsible for
  parsing replies from the stream of data that is read from a Redis connection.
  It does not contain functionality to handle I/O.



  The `Reader` class has two methods that are used when parsing replies from a
  stream of data. `Reader.feed` takes a string argument that is appended to the
  internal buffer. `Reader.gets` reads this buffer and returns a reply when the
  buffer contains a full reply. If a single call to `feed` contains multiple
  replies, `gets` should be called multiple times to extract all replies.

  Example:

  ```python
  >>> reader = hiredis.Reader()
  >>> reader.feed("$5\r\nhello\r\n")
  >>> reader.gets()
  'hello'
  ```

  When the buffer does not contain a full reply, `gets` returns `False`. This
  means extra data is needed and `feed` should be called again before calling
  `gets` again:

  ```python
  >>> reader.feed("*2\r\n$5\r\nhello\r\n")
  >>> reader.gets()
  False
  >>> reader.feed("$5\r\nworld\r\n")
  >>> reader.gets()
  ['hello', 'world']
  ```



  `hiredis.Reader` is able to decode bulk data to any encoding Python supports.
  To do so, specify the encoding you want to use for decoding replies when
  initializing it:

  ```python
  >>> reader = hiredis.Reader(encoding="utf-8", errors="strict")
  >>> reader.feed("$3\r\n\xe2\x98\x83\r\n")
  >>> reader.gets()
  u'☃'
  ```

  Decoding of bulk data will be attempted using the specified encoding and
  error handler. If the error handler is `'strict'` (the default), a
  `UnicodeDecodeError` is raised when data cannot be dedcoded. This is identical
  to Python's default behavior. Other valid values to `errors` include
  `'replace'`, `'ignore'`, and `'backslashreplace'`. More information on the
  behavior of these error handlers can be found
  [here](https://docs.python.org/3/howto/unicode.html#the-string-type).


  When the specified encoding cannot be found, a `LookupError` will be raised
  when calling `gets` for the first reply with bulk data.



  When a protocol error occurs (because of multiple threads using the same
  socket, or some other condition that causes a corrupt stream), the error
  `hiredis.ProtocolError` is raised. Because the buffer is read in a lazy
  fashion, it will only be raised when `gets` is called and the first reply in
  the buffer contains an error. There is no way to recover from a faulty protocol
  state, so when this happens, the I/O code feeding data to `Reader` should
  probably reconnect.

  Redis can reply with error replies (`-ERR ...`). For these replies, the custom
  error class `hiredis.ReplyError` is returned, **but not raised**.

  When other error types should be used (so existing code doesn't have to change
  its `except` clauses), `Reader` can be initialized with the `protocolError` and
  `replyError` keywords. These keywords should contain a *class* that is a
  subclass of `Exception`. When not provided, `Reader` will use the default
  error types.



  The repository contains a benchmarking script in the `benchmark` directory,
  which uses [gevent](http://gevent.org/) to have non-blocking I/O and redis-py
  to handle connections. These benchmarks are done with a patched version of
  redis-py that uses hiredis-py when it is available.

  All benchmarks are done with 10 concurrent connections.

  * SET key value + GET key
    * redis-py: 11.76 Kops
    * redis-py *with* hiredis-py: 13.40 Kops
    * improvement: **1.1x**

  List entries in the following tests are 5 bytes.

  * LRANGE list 0 **9**:
    * redis-py: 4.78 Kops
    * redis-py *with* hiredis-py: 12.94 Kops
    * improvement: **2.7x**
  * LRANGE list 0 **99**:
    * redis-py: 0.73 Kops
    * redis-py *with* hiredis-py: 11.90 Kops
    * improvement: **16.3x**
  * LRANGE list 0 **999**:
    * redis-py: 0.07 Kops
    * redis-py *with* hiredis-py: 5.83 Kops
    * improvement: **83.2x**

  Throughput improvement for simple SET/GET is minimal, but the larger multi bulk replies
  get, the larger the performance improvement is.



  This code is released under the BSD license, after the license of hiredis.


pkgId: 52c71706e7952e03612a24f5757d1be7c1f08c10f0740d7d72e68f6dfb89f904
name: rh-python36-hiredis-debuginfo
arch: x86_64
version: 1.0.1
epoch: 0
release: 1
summary: Debug information for package rh-python36-hiredis
url: https://github.com/redis/hiredis-py
rpm_license: BSD
rpm_vendor: Jan-Erik Rediger, Pieter Noordhuis <janerik@fnordig.de, pcnoordhuis@gmail.com>
rpm_group: Development/Debug
rpm_buildhost: 74c7e8c52b254e26a816e9d19056ecff
rpm_sourcerpm: rh-python36-hiredis-1.0.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387014-rh-python36-hiredis/rh-python36-hiredis-debuginfo-1.0.1-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-hiredis.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: 47c722e906582c24fff9764fde9a85c44ad5dcab8413fc210b3d03f080164226
name: rh-python36-humanfriendly
arch: noarch
version: 4.18
epoch: 0
release: 1
summary: Human friendly output for text interfaces using Python
url: https://humanfriendly.readthedocs.io
rpm_license: UNKNOWN
rpm_vendor: Peter Odding <peter@peterodding.com>
rpm_group: Development/Libraries
rpm_buildhost: ab7a4c48173f46718aa3418c47a89922
rpm_sourcerpm: rh-python36-humanfriendly-4.18-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387227-rh-python36-humanfriendly/rh-python36-humanfriendly-4.18-1.noarch.rpm
checksum_type: sha256
description:
  humanfriendly: Human friendly input/output in Python
  ====================================================

  .. image:: https://travis-ci.org/xolox/python-humanfriendly.svg?branch=master
     :target: https://travis-ci.org/xolox/python-humanfriendly

  .. image:: https://coveralls.io/repos/xolox/python-humanfriendly/badge.png?branch=master
     :target: https://coveralls.io/r/xolox/python-humanfriendly?branch=master

  The functions and classes in the `humanfriendly` package can be used to make
  text interfaces more user friendly. Some example features:

  - Parsing and formatting numbers, file sizes, pathnames and timespans in
    simple, human friendly formats.

  - Easy to use timers for long running operations, with human friendly
    formatting of the resulting timespans.

  - Prompting the user to select a choice from a list of options by typing the
    option's number or a unique substring of the option.

  - Terminal interaction including text styling (ANSI escape sequences), user
    friendly rendering of usage messages and querying the terminal for its
    size.

  The `humanfriendly` package is currently tested on Python 2.6, 2.7, 3.4, 3.5,
  3.6 and PyPy (2.7) on Linux and Mac OS X. While the intention is to support
  Windows as well, you may encounter some rough edges.

  .. contents::
     :local:

  Getting started
  ---------------

  It's very simple to start using the `humanfriendly` package::

     >>> import humanfriendly
     >>> user_input = raw_input("Enter a readable file size: ")
     Enter a readable file size: 16G
     >>> num_bytes = humanfriendly.parse_size(user_input)
     >>> print num_bytes
     16000000000
     >>> print "You entered:", humanfriendly.format_size(num_bytes)
     You entered: 16 GB
     >>> print "You entered:", humanfriendly.format_size(num_bytes, binary=True)
     You entered: 14.9 GiB

  Command line
  ------------

  .. A DRY solution to avoid duplication of the `humanfriendly --help' text:
  ..
  .. [[[cog
  .. from humanfriendly.usage import inject_usage
  .. inject_usage('humanfriendly.cli')
  .. ]]]

  **Usage:** `humanfriendly [OPTIONS]`

  Human friendly input/output (text formatting) on the command
  line based on the Python package with the same name.

  **Supported options:**

  .. csv-table::
     :header: Option, Description
     :widths: 30, 70


     "``-c``, ``--run-command``","Execute an external command (given as the positional arguments) and render
     a spinner and timer while the command is running. The exit status of the
     command is propagated."
     ``--format-table``,"Read tabular data from standard input (each line is a row and each
     whitespace separated field is a column), format the data as a table and
     print the resulting table to standard output. See also the ``--delimiter``
     option."
     "``-d``, ``--delimiter=VALUE``","Change the delimiter used by ``--format-table`` to ``VALUE`` (a string). By default
     all whitespace is treated as a delimiter."
     "``-l``, ``--format-length=LENGTH``","Convert a length count (given as the integer or float ``LENGTH``) into a human
     readable string and print that string to standard output."
     "``-n``, ``--format-number=VALUE``","Format a number (given as the integer or floating point number ``VALUE``) with
     thousands separators and two decimal places (if needed) and print the
     formatted number to standard output."
     "``-s``, ``--format-size=BYTES``","Convert a byte count (given as the integer ``BYTES``) into a human readable
     string and print that string to standard output."
     "``-b``, ``--binary``","Change the output of ``-s``, ``--format-size`` to use binary multiples of bytes
     (base-2) instead of the default decimal multiples of bytes (base-10)."
     "``-t``, ``--format-timespan=SECONDS``","Convert a number of seconds (given as the floating point number ``SECONDS``)
     into a human readable timespan and print that string to standard output."
     ``--parse-length=VALUE``,"Parse a human readable length (given as the string ``VALUE``) and print the
     number of metres to standard output."
     ``--parse-size=VALUE``,"Parse a human readable data size (given as the string ``VALUE``) and print the
     number of bytes to standard output."
     ``--demo``,"Demonstrate changing the style and color of the terminal font using ANSI
     escape sequences."
     "``-h``, ``--help``",Show this message and exit.

  .. [[[end]]]

  A note about size units
  -----------------------

  When I originally published the `humanfriendly` package I went with binary
  multiples of bytes (powers of two). It was pointed out several times that this
  was a poor choice (see issue `#4`_ and pull requests `#8`_ and `#9`_) and thus
  the new default became decimal multiples of bytes (powers of ten):

  +------+---------------+---------------+
  | Unit | Binary value  | Decimal value |
  +------+---------------+---------------+
  | KB   |          1024 |          1000 +
  +------+---------------+---------------+
  | MB   |       1048576 |       1000000 |
  +------+---------------+---------------+
  | GB   |    1073741824 |    1000000000 |
  +------+---------------+---------------+
  | TB   | 1099511627776 | 1000000000000 |
  +------+---------------+---------------+
  | etc  |               |               |
  +------+---------------+---------------+

  The option to use binary multiples of bytes remains by passing the keyword
  argument `binary=True` to the `format_size()`_ and `parse_size()`_ functions.

  Contact
  -------

  The latest version of `humanfriendly` is available on PyPI_ and GitHub_. The
  documentation is hosted on `Read the Docs`_. For bug reports please create an
  issue on GitHub_. If you have questions, suggestions, etc. feel free to send me
  an e-mail at `peter@peterodding.com`_.

  License
  -------

  This software is licensed under the `MIT license`_.

  © 2018 Peter Odding.

  .. External references:
  .. _#4: https://github.com/xolox/python-humanfriendly/issues/4
  .. _#8: https://github.com/xolox/python-humanfriendly/pull/8
  .. _#9: https://github.com/xolox/python-humanfriendly/pull/9
  .. _format_size(): https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_size
  .. _GitHub: https://github.com/xolox/python-humanfriendly
  .. _MIT license: http://en.wikipedia.org/wiki/MIT_License
  .. _parse_size(): https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.parse_size
  .. _peter@peterodding.com: peter@peterodding.com
  .. _PyPI: https://pypi.python.org/pypi/humanfriendly
  .. _Read the Docs: https://humanfriendly.readthedocs.io


pkgId: 2c28ed9b6e313a2f03ae04d3ffeb0f75c3cfbfa9e2a52675335048b109be5e20
name: rh-python36-hyperlink
arch: noarch
version: 19.0.0
epoch: 0
release: 1
summary: A featureful, immutable, and correct URL for Python.
url: https://github.com/python-hyper/hyperlink
rpm_license: MIT
rpm_vendor: Mahmoud Hashemi and Glyph Lefkowitz <mahmoud@hatnote.com>
rpm_group: Development/Libraries
rpm_buildhost: d8bf6c41b5e849cfbb20f5b73bd3c7d5
rpm_sourcerpm: rh-python36-hyperlink-19.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387088-rh-python36-hyperlink/rh-python36-hyperlink-19.0.0-1.noarch.rpm
checksum_type: sha256
description:
  The humble, but powerful, URL runs everything around us. Chances
  are you've used several just to read this text.

  Hyperlink is a featureful, pure-Python implementation of the URL, with
  an emphasis on correctness. BSD licensed.

  See the docs at http://hyperlink.readthedocs.io.


pkgId: b6d089fe0dd212ce7144008b5d41d1d9e037e8eb433d5424480dd2e8343b972f
name: rh-python36-idna
arch: noarch
version: 2.9
epoch: 0
release: 1
summary: Internationalized Domain Names in Applications (IDNA)
url: https://github.com/kjd/idna
rpm_license: BSD-like
rpm_vendor: Kim Davies <kim@cynosure.com.au>
rpm_group: Development/Libraries
rpm_buildhost: df3c95ea7d094fd68b0722484de368fd
rpm_sourcerpm: rh-python36-idna-2.9-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387090-rh-python36-idna/rh-python36-idna-2.9-1.noarch.rpm
checksum_type: sha256
description:
  Internationalized Domain Names in Applications (IDNA)
  =====================================================

  Support for the Internationalised Domain Names in Applications
  (IDNA) protocol as specified in `RFC 5891 <http://tools.ietf.org/html/rfc5891>`_.
  This is the latest version of the protocol and is sometimes referred to as
  “IDNA 2008”.

  This library also provides support for Unicode Technical Standard 46,
  `Unicode IDNA Compatibility Processing <http://unicode.org/reports/tr46/>`_.

  This acts as a suitable replacement for the “encodings.idna” module that
  comes with the Python standard library, but only supports the
  old, deprecated IDNA specification (`RFC 3490 <http://tools.ietf.org/html/rfc3490>`_).

  Basic functions are simply executed:

  .. code-block:: pycon

      
      >>> import idna
      >>> idna.encode('ドメイン.テスト')
      b'xn--eckwd4c7c.xn--zckzah'
      >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))
      ドメイン.テスト

      
      >>> import idna
      >>> idna.encode(u'ドメイン.テスト')
      'xn--eckwd4c7c.xn--zckzah'
      >>> print idna.decode('xn--eckwd4c7c.xn--zckzah')
      ドメイン.テスト

  Packages
  --------

  The latest tagged release version is published in the PyPI repository:

  .. image:: https://badge.fury.io/py/idna.svg
     :target: http://badge.fury.io/py/idna


  Installation
  ------------

  To install this library, you can use pip:

  .. code-block:: bash

      $ pip install idna

  Alternatively, you can install the package using the bundled setup script:

  .. code-block:: bash

      $ python setup.py install

  This library works with Python 2.7 and Python 3.4 or later.


  Usage
  -----

  For typical usage, the ``encode`` and ``decode`` functions will take a domain
  name argument and perform a conversion to A-labels or U-labels respectively.

  .. code-block:: pycon

      
      >>> import idna
      >>> idna.encode('ドメイン.テスト')
      b'xn--eckwd4c7c.xn--zckzah'
      >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))
      ドメイン.テスト

  You may use the codec encoding and decoding methods using the
  ``idna.codec`` module:

  .. code-block:: pycon

      
      >>> import idna.codec
      >>> print u'домена.испытание'.encode('idna')
      xn--80ahd1agd.xn--80akhbyknj4f
      >>> print 'xn--80ahd1agd.xn--80akhbyknj4f'.decode('idna')
      домена.испытание

  Conversions can be applied at a per-label basis using the ``ulabel`` or ``alabel``
  functions if necessary:

  .. code-block:: pycon

      
      >>> idna.alabel(u'测试')
      'xn--0zwm56d'

  Compatibility Mapping (UTS #46)
  +++++++++++++++++++++++++++++++

  As described in `RFC 5895 <http://tools.ietf.org/html/rfc5895>`_, the IDNA
  specification no longer normalizes input from different potential ways a user
  may input a domain name. This functionality, known as a “mapping”, is now
  considered by the specification to be a local user-interface issue distinct
  from IDNA conversion functionality.

  This library provides one such mapping, that was developed by the Unicode
  Consortium. Known as `Unicode IDNA Compatibility Processing <http://unicode.org/reports/tr46/>`_,
  it provides for both a regular mapping for typical applications, as well as
  a transitional mapping to help migrate from older IDNA 2003 applications.

  For example, “Königsgäßchen” is not a permissible label as *LATIN CAPITAL
  LETTER K* is not allowed (nor are capital letters in general). UTS 46 will
  convert this into lower case prior to applying the IDNA conversion.

  .. code-block:: pycon

      
      >>> import idna
      >>> idna.encode(u'Königsgäßchen')
      ...
      idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed
      >>> idna.encode('Königsgäßchen', uts46=True)
      b'xn--knigsgchen-b4a3dun'
      >>> print(idna.decode('xn--knigsgchen-b4a3dun'))
      königsgäßchen

  Transitional processing provides conversions to help transition from the older
  2003 standard to the current standard. For example, in the original IDNA
  specification, the *LATIN SMALL LETTER SHARP S* (ß) was converted into two
  *LATIN SMALL LETTER S* (ss), whereas in the current IDNA specification this
  conversion is not performed.

  .. code-block:: pycon

      
      >>> idna.encode(u'Königsgäßchen', uts46=True, transitional=True)
      'xn--knigsgsschen-lcb0w'

  Implementors should use transitional processing with caution, only in rare
  cases where conversion from legacy labels to current labels must be performed
  (i.e. IDNA implementations that pre-date 2008). For typical applications
  that just need to convert labels, transitional processing is unlikely to be
  beneficial and could produce unexpected incompatible results.

  ``encodings.idna`` Compatibility
  ++++++++++++++++++++++++++++++++

  Function calls from the Python built-in ``encodings.idna`` module are
  mapped to their IDNA 2008 equivalents using the ``idna.compat`` module.
  Simply substitute the ``import`` clause in your code to refer to the
  new module name.

  Exceptions
  ----------

  All errors raised during the conversion following the specification should
  raise an exception derived from the ``idna.IDNAError`` base class.

  More specific exceptions that may be generated as ``idna.IDNABidiError``
  when the error reflects an illegal combination of left-to-right and right-to-left
  characters in a label; ``idna.InvalidCodepoint`` when a specific codepoint is
  an illegal character in an IDN label (i.e. INVALID); and ``idna.InvalidCodepointContext``
  when the codepoint is illegal based on its positional context (i.e. it is CONTEXTO
  or CONTEXTJ but the contextual requirements are not satisfied.)

  Building and Diagnostics
  ------------------------

  The IDNA and UTS 46 functionality relies upon pre-calculated lookup tables for
  performance. These tables are derived from computing against eligibility criteria
  in the respective standards. These tables are computed using the command-line
  script ``tools/idna-data``.

  This tool will fetch relevant tables from the Unicode Consortium and perform the
  required calculations to identify eligibility. It has three main modes:

  * ``idna-data make-libdata``. Generates ``idnadata.py`` and ``uts46data.py``,
    the pre-calculated lookup tables using for IDNA and UTS 46 conversions. Implementors
    who wish to track this library against a different Unicode version may use this tool
    to manually generate a different version of the ``idnadata.py`` and ``uts46data.py``
    files.

  * ``idna-data make-table``. Generate a table of the IDNA disposition
    (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix B.1 of RFC
    5892 and the pre-computed tables published by `IANA <http://iana.org/>`_.

  * ``idna-data U+0061``. Prints debugging output on the various properties
    associated with an individual Unicode codepoint (in this case, U+0061), that are
    used to assess the IDNA and UTS 46 status of a codepoint. This is helpful in debugging
    or analysis.

  The tool accepts a number of arguments, described using ``idna-data -h``. Most notably,
  the ``--version`` argument allows the specification of the version of Unicode to use
  in computing the table data. For example, ``idna-data --version 9.0.0 make-libdata``
  will generate library data against Unicode 9.0.0.

  Note that this script requires Python 3, but all generated library data will work
  in Python 2.7.


  Testing
  -------

  The library has a test suite based on each rule of the IDNA specification, as
  well as tests that are provided as part of the Unicode Technical Standard 46,
  `Unicode IDNA Compatibility Processing <http://unicode.org/reports/tr46/>`_.

  The tests are run automatically on each commit at Travis CI:

  .. image:: https://travis-ci.org/kjd/idna.svg?branch=master
     :target: https://travis-ci.org/kjd/idna


pkgId: f6716389c87938b44584bfd90e6bd83ab2ed676dcb44d4178de11d8417e48bdc
name: rh-python36-idna-ssl
arch: noarch
version: 1.1.0
epoch: 0
release: 1
summary: Patch ssl.match_hostname for Unicode(idna) domains support
url: https://github.com/aio-libs/idna-ssl
rpm_license: UNKNOWN
rpm_vendor: Victor Kovtun <hellysmile@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: cd7a36b0260f4272895c13ca81c25f43
rpm_sourcerpm: rh-python36-idna-ssl-1.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387013-rh-python36-idna-ssl/rh-python36-idna-ssl-1.1.0-1.noarch.rpm
checksum_type: sha256
description:
  idna-ssl
  ========

  :info: Patch ssl.match_hostname for Unicode(idna) domains support

  .. image:: https://travis-ci.com/aio-libs/idna-ssl.svg?branch=master
      :target: https://travis-ci.com/aio-libs/idna-ssl

  .. image:: https://img.shields.io/pypi/v/idna_ssl.svg
      :target: https://pypi.python.org/pypi/idna_ssl

  .. image:: https://codecov.io/gh/aio-libs/idna-ssl/branch/master/graph/badge.svg
      :target: https://codecov.io/gh/aio-libs/idna-ssl

  Installation
  ------------

  .. code-block:: shell

      pip install idna-ssl

  Usage
  -----

  .. code-block:: python

      from idna_ssl import patch_match_hostname  # noqa isort:skip
      patch_match_hostname()  # noqa isort:skip

      import asyncio

      import aiohttp

      URL = 'https://цфоут.мвд.рф/news/item/8065038/'


      async def main():
          async with aiohttp.ClientSession() as session:
              async with session.get(URL) as response:
                  print(response)


      loop = asyncio.get_event_loop()
      loop.run_until_complete(main())

  Motivation
  ----------

  * Here is 100% backward capability
  * Related aiohttp `issue <https://github.com/aio-libs/aiohttp/issues/949>`_
  * Related Python `bug <https://bugs.python.org/issue31872>`_
  * Related Python `pull request <https://github.com/python/cpython/pull/3462>`_
  * It is fixed (by January 27 2018) in upcoming Python 3.7, but `IDNA2008 <https://tools.ietf.org/html/rfc5895>`_ is still broken

  Thanks
  ------

  The library was donated by `Ocean S.A. <https://ocean.io/>`_

  Thanks to the company for contribution.


pkgId: 4a586d90e82cd7fcb4beee27ab69a897a66ac7f7e13cb7a4108cc5723795d715
name: rh-python36-importlib_metadata
arch: noarch
version: 1.5.0
epoch: 0
release: 1
summary: Read metadata from Python packages
url: http://importlib-metadata.readthedocs.io/
rpm_license: Apache Software License
rpm_vendor: Barry Warsaw <barry@python.org>
rpm_group: Development/Libraries
rpm_buildhost: 586f32c774c34569bb698bc531764a7e
rpm_sourcerpm: rh-python36-importlib_metadata-1.5.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387302-rh-python36-importlib_metadata/rh-python36-importlib_metadata-1.5.0-1.noarch.rpm
checksum_type: sha256
description:
  =========================
   ``importlib_metadata``
  =========================

  ``importlib_metadata`` is a library to access the metadata for a Python
  package.  It is intended to be ported to Python 3.8.


  Usage
  =====

  See the `online documentation <https://importlib_metadata.readthedocs.io/>`_
  for usage details.

  `Finder authors
  <https://docs.python.org/3/reference/import.html#finders-and-loaders>`_ can
  also add support for custom package installers.  See the above documentation
  for details.


  Caveats
  =======

  This project primarily supports third-party packages installed by PyPA
  tools (or other conforming packages). It does not support:

  - Packages in the stdlib.
  - Packages installed without metadata.

  Project details
  ===============

   * Project home: https://gitlab.com/python-devs/importlib_metadata
   * Report bugs at: https://gitlab.com/python-devs/importlib_metadata/issues
   * Code hosting: https://gitlab.com/python-devs/importlib_metadata.git
   * Documentation: http://importlib_metadata.readthedocs.io/


pkgId: 5665aab71b645dae00c3ede88396277285faecf920b1bdde371dcc12900967b2
name: rh-python36-importlib_resources
arch: noarch
version: 1.4.0
epoch: 0
release: 1
summary: Read resources from Python packages
url: http://importlib-resources.readthedocs.io/
rpm_license: UNKNOWN
rpm_vendor: Barry Warsaw <barry@python.org>
rpm_group: Development/Libraries
rpm_buildhost: 59be545cf9894cd287cd2c801d73bbcd
rpm_sourcerpm: rh-python36-importlib_resources-1.4.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387296-rh-python36-importlib_resources/rh-python36-importlib_resources-1.4.0-1.noarch.rpm
checksum_type: sha256
description:
  =========================
   ``importlib_resources``
  =========================

  ``importlib_resources`` is a backport of Python standard library
  `importlib.resources
  <https://docs.python.org/3.9/library/importlib.html#module-importlib.resources>`_
  module for Python 2.7, and 3.4 through 3.8.  Users of Python 3.9 and beyond
  should use the standard library module, since for these versions,
  ``importlib_resources`` just delegates to that module.

  The key goal of this module is to replace parts of `pkg_resources
  <https://setuptools.readthedocs.io/en/latest/pkg_resources.html>`_ with a
  solution in Python's stdlib that relies on well-defined APIs.  This makes
  reading resources included in packages easier, with more stable and consistent
  semantics.


  Project details
  ===============

   * Project home: https://gitlab.com/python-devs/importlib_resources
   * Report bugs at: https://gitlab.com/python-devs/importlib_resources/issues
   * Code hosting: https://gitlab.com/python-devs/importlib_resources.git
   * Documentation: https://importlib-resources.readthedocs.io/


pkgId: 6e4674e43ceda4b210117b90450f81776ac16d15ad0c7615c8dae044845e9e29
name: rh-python36-irc
arch: noarch
version: 18.0.0
epoch: 0
release: 1
summary: IRC (Internet Relay Chat) protocol library for Python
url: https://github.com/jaraco/irc
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: 0684a4855bda4ca6abee94a73d180f03
rpm_sourcerpm: rh-python36-irc-18.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387102-rh-python36-irc/rh-python36-irc-18.0.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/irc.svg
     :target: https://pypi.org/project/irc

  .. image:: https://img.shields.io/pypi/pyversions/irc.svg

  .. image:: https://img.shields.io/travis/jaraco/irc/master.svg
     :target: http://travis-ci.org/jaraco/irc

  .. image:: https://readthedocs.org/projects/python-irc/badge/?version=latest
     :target: http://python-irc.readthedocs.io/en/latest/?badge=latest

  .. image:: https://badges.gitter.im/jaraco/irc.svg
     :alt: Join the chat at https://gitter.im/jaraco/irc
     :target: https://gitter.im/jaraco/irc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge

  Full-featured Python IRC library for Python.

  - `Project home <https://github.com/jaraco/irc>`_
  - `Docs <https://python-irc.readthedocs.io/>`_
  - `History <https://python-irc.readthedocs.io/en/latest/history.html>`_

  Overview
  ========

  This library provides a low-level implementation of the IRC protocol for
  Python.  It provides an event-driven IRC client framework.  It has
  a fairly thorough support for the basic IRC protocol, CTCP, and DCC
  connections.

  In order to understand how to make an IRC client, it's best to read up first
  on the `IRC specifications
  <http://web.archive.org/web/20160628193730/http://www.irchelp.org/irchelp/rfc/>`_.

  Installation
  ============

  IRC requires Python versions specified in the `download pages
  <https://pypi.python.org/pypi/irc>`_ and definitely supports Python 3.

  You have several options to install the IRC project.

  * Use ``easy_install irc`` or ``pip install irc`` to grab the latest
    version from the cheeseshop (recommended).
  * Run ``python setup.py install`` (from the source distribution).

  Client Features
  ===============

  The main features of the IRC client framework are:

  * Abstraction of the IRC protocol.
  * Handles multiple simultaneous IRC server connections.
  * Handles server PONGing transparently.
  * Messages to the IRC server are done by calling methods on an IRC
    connection object.
  * Messages from an IRC server triggers events, which can be caught
    by event handlers.
  * Reading from and writing to IRC server sockets is normally done
    by an internal ``select()`` loop, but the ``select()`` may be done
    by an external main loop.
  * Functions can be registered to execute at specified times by the
    event-loop.
  * Decodes CTCP tagging correctly (hopefully); I haven't seen any
    other IRC client implementation that handles the CTCP
    specification subtilties.
  * A kind of simple, single-server, object-oriented IRC client class
    that dispatches events to instance methods is included.
  * DCC connection support.

  Current limitations:

  * The IRC protocol shines through the abstraction a bit too much.
  * Data is not written asynchronously to the server (and DCC peers),
    i.e. the ``write()`` may block if the TCP buffers are stuffed.
  * Like most projects, documentation is lacking ...

  Unfortunately, this library isn't as well-documented as I would like
  it to be.  I think the best way to get started is to read and
  understand the example program ``irccat``, which is included in the
  distribution.

  The following modules might be of interest:

  * ``irc.client``

    The library itself.  Read the code along with comments and
    docstrings to get a grip of what it does.  Use it at your own risk
    and read the source, Luke!

  * ``irc.bot``

    An IRC bot implementation.

  * ``irc.server``

    A basic IRC server implementation. Suitable for testing, but not
    intended as a production service.

    Invoke the server with ``python -m irc.server``.

  Examples
  ========

  Example scripts in the scripts directory:

  * ``irccat``

    A simple example of how to use the IRC client.  ``irccat`` reads
    text from stdin and writes it to a specified user or channel on
    an IRC server.

  * ``irccat2``

    The same as above, but using the ``SimpleIRCClient`` class.

  * ``servermap``

    Another simple example.  ``servermap`` connects to an IRC server,
    finds out what other IRC servers there are in the net and prints
    a tree-like map of their interconnections.

  * ``testbot``

    An example bot that uses the ``SingleServerIRCBot`` class from
    ``irc.bot``.  The bot enters a channel and listens for commands in
    private messages or channel traffic.  It also accepts DCC
    invitations and echos back sent DCC chat messages.

  * ``dccreceive``

    Receives a file over DCC.

  * ``dccsend``

    Sends a file over DCC.


  NOTE: If you're running one of the examples on a unix command line, you need
  to escape the ``#`` symbol in the channel. For example, use ``\\#test`` or
  ``"#test"`` instead of ``#test``.


  Scheduling Events
  =================

  The library includes a default event Scheduler as
  ``irc.schedule.DefaultScheduler``,
  but this scheduler can be replaced with any other scheduler. For example,
  to use the `schedule <https://pypi.org/project/schedule>`_ package,
  include it
  in your dependencies and install it into the IRC library as so:

      class ScheduleScheduler(irc.schedule.IScheduler):
          def execute_every(self, period, func):
              schedule.every(period).do(func)

          def execute_at(self, when, func):
              schedule.at(when).do(func)

          def execute_after(self, delay, func):
              raise NotImplementedError("Not supported")

          def run_pending(self):
              schedule.run_pending()

      irc.client.Reactor.scheduler_class = ScheduleScheduler


  Decoding Input
  ==============

  By default, the IRC library attempts to decode all incoming streams as
  UTF-8, even though the IRC spec stipulates that no specific encoding can be
  expected. Since assuming UTF-8 is not reasonable in the general case, the IRC
  library provides options to customize decoding of input by customizing the
  ``ServerConnection`` class. The ``buffer_class`` attribute on the
  ``ServerConnection`` determines which class is used for buffering lines from the
  input stream, using the ``buffer`` module in `jaraco.stream
  <https://pypi.python.org/pypi/jaraco.stream>`_. By default it is
  ``buffer.DecodingLineBuffer``, but may be
  re-assigned with another class, following the interface of ``buffer.LineBuffer``.
  The ``buffer_class`` attribute may be assigned for all instances of
  ``ServerConnection`` by overriding the class attribute.

  For example:

  .. code:: python

      from jaraco.stream import buffer
      irc.client.ServerConnection.buffer_class = buffer.LenientDecodingLineBuffer

  The ``LenientDecodingLineBuffer`` attempts UTF-8 but falls back to latin-1, which
  will avoid ``UnicodeDecodeError`` in all cases (but may produce unexpected
  behavior if an IRC user is using another encoding).

  The buffer may be overridden on a per-instance basis (as long as it's
  overridden before the connection is established):

  .. code:: python

      server = irc.client.IRC().server()
      server.buffer_class = buffer.LenientDecodingLineBuffer
      server.connect()

  Alternatively, some clients may still want to decode the input using a
  different encoding. To decode all input as latin-1 (which decodes any input),
  use the following:

  .. code:: python

      irc.client.ServerConnection.buffer_class.encoding = 'latin-1'

  Or decode to UTF-8, but use a replacement character for unrecognized byte
  sequences:

  .. code:: python

      irc.client.ServerConnection.buffer_class.errors = 'replace'

  Or, to simply ignore all input that cannot be decoded:

  .. code:: python

      class IgnoreErrorsBuffer(buffer.DecodingLineBuffer):
          def handle_exception(self):
              pass
      irc.client.ServerConnection.buffer_class = IgnoreErrorsBuffer

  On Python 2, it was possible to use the ``buffer.LineBuffer`` itself, which will
  pass the raw bytes. On Python 3, the library requires text for message
  processing, so a decoding buffer must be used. Therefore, use of the
  ``LineBuffer`` is considered deprecated and not supported on Python 3. Clients
  should use one of the above techniques for decoding input to text.

  Notes and Contact Info
  ======================

  Enjoy.

  Maintainer:
  Jason R. Coombs <jaraco@jaraco.com>

  Original Author:
  Joel Rosdahl <joel@rosdahl.net>

  Copyright © 1999-2002 Joel Rosdahl
  Copyright © 2011-2016 Jason R. Coombs
  Copyright © 2009 Ferry Boender


pkgId: 95c854f0d919453027b20350cd9d7be88f134060f9ba54f2ee6430b16e5f90b2
name: rh-python36-itsdangerous
arch: noarch
version: 1.1.0
epoch: 0
release: 1
summary: Various helpers to pass data to untrusted environments and back.
url: https://palletsprojects.com/p/itsdangerous/
rpm_license: BSD
rpm_vendor: Pallets Team <contact@palletsprojects.com>
rpm_group: Development/Libraries
rpm_buildhost: 13c1a1e7bed747068eda30c9ececd9f7
rpm_sourcerpm: rh-python36-itsdangerous-1.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387035-rh-python36-itsdangerous/rh-python36-itsdangerous-1.1.0-1.noarch.rpm
checksum_type: sha256
description:
  itsdangerous
  ============

  ... so better sign this

  Various helpers to pass data to untrusted environments and to get it
  back safe and sound. Data is cryptographically signed to ensure that a
  token has not been tampered with.

  It's possible to customize how data is serialized. Data is compressed as
  needed. A timestamp can be added and verified automatically while
  loading a token.


  Installing
  ----------

  Install and update using `pip`_:

  .. code-block:: text

      pip install -U itsdangerous

  .. _pip: https://pip.pypa.io/en/stable/quickstart/


  A Simple Example
  ----------------

  Here's how you could generate a token for transmitting a user's id and
  name between web requests.

  .. code-block:: python

      from itsdangerous import URLSafeSerializer
      auth_s = URLSafeSerializer("secret key", "auth")
      token = auth_s.dumps({"id": 5, "name": "itsdangerous"})

      print(token)
      

      data = auth_s.loads(token)
      print(data["name"])
      


  Donate
  ------

  The Pallets organization develops and supports itsdangerous and other
  popular packages. In order to grow the community of contributors and
  users, and allow the maintainers to devote more time to the projects,
  `please donate today`_.

  .. _please donate today: https://palletsprojects.com/donate


  Links
  -----

  *   Website: https://palletsprojects.com/p/itsdangerous/
  *   Documentation: https://itsdangerous.palletsprojects.com/
  *   License: `BSD <https://github.com/pallets/itsdangerous/blob/master/LICENSE.rst>`_
  *   Releases: https://pypi.org/project/itsdangerous/
  *   Code: https://github.com/pallets/itsdangerous
  *   Issue tracker: https://github.com/pallets/itsdangerous/issues
  *   Test status: https://travis-ci.org/pallets/itsdangerous
  *   Test coverage: https://codecov.io/gh/pallets/itsdangerous


pkgId: 09fa0c9aa87fe69c67dd2f006ab943a8fb75da72207e8bc4f013dd8a62a675c1
name: rh-python36-jaraco.classes
arch: noarch
version: 3.1.0
epoch: 0
release: 1
summary: Utility functions for Python class constructs
url: https://github.com/jaraco/jaraco.classes
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: aadecafde0e24f709f7cbf9549ef9a4a
rpm_sourcerpm: rh-python36-jaraco.classes-3.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387127-rh-python36-jaraco.classes/rh-python36-jaraco.classes-3.1.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jaraco.classes.svg
     :target: https://pypi.org/project/jaraco.classes

  .. image:: https://img.shields.io/pypi/pyversions/jaraco.classes.svg

  .. image:: https://img.shields.io/travis/jaraco/jaraco.classes/master.svg
     :target: http://travis-ci.org/jaraco/jaraco.classes

  .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest
     :target: http://skeleton.readthedocs.io/en/latest/?badge=latest


pkgId: 165e26a39716cf5fbc34470a6f8fe71c32fc92be1fdb2233d4d406f8a67a6b16
name: rh-python36-jaraco.collections
arch: noarch
version: 3.0.0
epoch: 0
release: 1
summary: jaraco.collections
url: https://github.com/jaraco/jaraco.collections
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: 928823b250734603bd5540bb24ae657e
rpm_sourcerpm: rh-python36-jaraco.collections-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387128-rh-python36-jaraco.collections/rh-python36-jaraco.collections-3.0.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jaraco.collections.svg
     :target: https://pypi.io/project/jaraco.collections

  .. image:: https://img.shields.io/pypi/pyversions/jaraco.collections.svg

  .. image:: https://img.shields.io/travis/jaraco/jaraco.collections/master.svg
     :target: https://travis-ci.org/jaraco/jaraco.collections

  .. .. image:: https://img.shields.io/appveyor/ci/jaraco/skeleton/master.svg
  ..    :target: https://ci.appveyor.com/project/jaraco/skeleton/branch/master

  .. image:: https://readthedocs.org/projects/jaracocollections/badge/?version=latest
     :target: https://jaracocollections.readthedocs.io/en/latest/?badge=latest

  Models and classes to supplement the stdlib 'collections' module.

  RangeMap
  --------

  A dictionary-like object that maps a range of values to a given value.


pkgId: c754b90e8ed515dcf47d4daa08379c3960f37372869d4448bcd98da9dda73ca2
name: rh-python36-jaraco.functools
arch: noarch
version: 3.0.0
epoch: 0
release: 1
summary: jaraco.functools
url: https://github.com/jaraco/jaraco.functools
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: 6b5aaecfae27412ea1640a5c531a3580
rpm_sourcerpm: rh-python36-jaraco.functools-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387130-rh-python36-jaraco.functools/rh-python36-jaraco.functools-3.0.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jaraco.functools.svg
     :target: https://pypi.org/project/jaraco.functools

  .. image:: https://img.shields.io/pypi/pyversions/jaraco.functools.svg

  .. image:: https://img.shields.io/travis/jaraco/jaraco.functools/master.svg
     :target: http://travis-ci.org/jaraco/jaraco.functools

  .. image:: https://readthedocs.org/projects/jaracofunctools/badge/?version=latest
     :target: http://jaracofunctools.readthedocs.io/en/latest/?badge=latest

  Additional functools in the spirit of stdlib's functools.


pkgId: d6e21de2ce5ea3c1032ef0e454ce26f9d1a4f5c2afab150eae2022411f055a59
name: rh-python36-jaraco.itertools
arch: noarch
version: 4.4.2
epoch: 0
release: 1
summary: jaraco.itertools
url: https://github.com/jaraco/jaraco.itertools
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: 397473a7a12e4560bb7c9fdb6f8dc758
rpm_sourcerpm: rh-python36-jaraco.itertools-4.4.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387092-rh-python36-jaraco.itertools/rh-python36-jaraco.itertools-4.4.2-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jaraco.itertools.svg
     :target: https://pypi.org/project/jaraco.itertools

  .. image:: https://img.shields.io/pypi/pyversions/jaraco.itertools.svg

  .. image:: https://img.shields.io/travis/jaraco/jaraco.itertools/master.svg
     :target: https://travis-ci.org/jaraco/jaraco.itertools

  .. .. image:: https://img.shields.io/appveyor/ci/jaraco/jaraco.itertools/master.svg
  ..    :target: https://ci.appveyor.com/project/jaraco/jaraco.itertools/branch/master

  .. image:: https://readthedocs.org/projects/jaracoitertools/badge/?version=latest
     :target: https://jaracoitertools.readthedocs.io/en/latest/?badge=latest


pkgId: fc448e0b455c03dad016d3bc8e257281ff764628c56a19bb07dbde60b9d20958
name: rh-python36-jaraco.logging
arch: noarch
version: 3.0.0
epoch: 0
release: 1
summary: jaraco.logging
url: https://github.com/jaraco/jaraco.logging
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: cc190ca2639b421aaf1d56a58e23b0f3
rpm_sourcerpm: rh-python36-jaraco.logging-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387104-rh-python36-jaraco.logging/rh-python36-jaraco.logging-3.0.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jaraco.logging.svg
     :target: https://pypi.org/project/jaraco.logging

  .. image:: https://img.shields.io/pypi/pyversions/jaraco.logging.svg

  .. image:: https://img.shields.io/travis/jaraco/jaraco.logging/master.svg
     :target: http://travis-ci.org/jaraco/jaraco.logging

  .. image:: https://readthedocs.org/projects/jaracologging/badge/?version=latest
     :target: https://jaracologging.readthedocs.io/en/latest/?badge=latest

  Argument Parsing
  ================

  Quickly solicit log level info from command-line parameters::

      parser = argparse.ArgumentParser()
      jaraco.logging.add_arguments(parser)
      args = parser.parse_args()
      jaraco.logging.setup(args)


pkgId: 31fb45b4ee621a76a64ac43226d2da98ca92b4dd2696436857a774e9a920dfdf
name: rh-python36-jaraco.stream
arch: noarch
version: 3.0.0
epoch: 0
release: 1
summary: routines for dealing with data streams
url: https://github.com/jaraco/jaraco.stream
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: c9aa9ef16a414261b877f78e4fc65496
rpm_sourcerpm: rh-python36-jaraco.stream-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387148-rh-python36-jaraco.stream/rh-python36-jaraco.stream-3.0.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jaraco.stream.svg
     :target: https://pypi.org/project/jaraco.stream

  .. image:: https://img.shields.io/pypi/pyversions/jaraco.stream.svg

  .. image:: https://img.shields.io/pypi/dm/jaraco.stream.svg

  .. image:: https://img.shields.io/travis/jaraco/jaraco.stream/master.svg
     :target: http://travis-ci.org/jaraco/jaraco.stream

  Routines for handling streaming data, including a
  set of generators for loading gzip data on the fly.

  License
  =======

  License is indicated in the project metadata (typically one or more
  of the Trove classifiers). For more details, see `this explanation
  <https://github.com/jaraco/skeleton/issues/1>`_.


pkgId: eba66c2d4606314a211a27df78ff2ddba2b0e09c4671e7c5f31a99b75bcf5825
name: rh-python36-jaraco.text
arch: noarch
version: 3.2.0
epoch: 0
release: 1
summary: jaraco.text
url: https://github.com/jaraco/jaraco.text
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: e87f749554414172a3c7442337d9634d
rpm_sourcerpm: rh-python36-jaraco.text-3.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387129-rh-python36-jaraco.text/rh-python36-jaraco.text-3.2.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jaraco.text.svg
     :target: https://pypi.org/project/jaraco.text

  .. image:: https://img.shields.io/pypi/pyversions/jaraco.text.svg

  .. image:: https://img.shields.io/travis/jaraco/jaraco.text/master.svg
     :target: https://travis-ci.org/jaraco/jaraco.text

  .. .. image:: https://img.shields.io/appveyor/ci/jaraco/skeleton/master.svg
  ..    :target: https://ci.appveyor.com/project/jaraco/skeleton/branch/master

  .. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest
  ..    :target: https://skeleton.readthedocs.io/en/latest/?badge=latest


pkgId: 159841e6e062690a6abc5f1180460de9a651b82c32230b89784c81741d199451
name: rh-python36-jmespath
arch: noarch
version: 0.9.4
epoch: 0
release: 1
summary: JSON Matching Expressions
url: https://github.com/jmespath/jmespath.py
rpm_license: MIT
rpm_vendor: James Saryerwinnie <js@jamesls.com>
rpm_group: Development/Libraries
rpm_buildhost: b8abd5646b5f46a1b5ef6203d74c4dd8
rpm_sourcerpm: rh-python36-jmespath-0.9.4-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387225-rh-python36-jmespath/rh-python36-jmespath-0.9.4-1.noarch.rpm
checksum_type: sha256
description:
  JMESPath
  ========


  .. image:: https://badges.gitter.im/Join Chat.svg
     :target: https://gitter.im/jmespath/chat


  .. image:: https://secure.travis-ci.org/jmespath/jmespath.py.png?branch=develop
     :target: http://travis-ci.org/jmespath/jmespath.py


  .. image:: https://codecov.io/github/jmespath/jmespath.py/coverage.svg?branch=develop
      :target: https://codecov.io/github/jmespath/jmespath.py?branch=develop


  JMESPath (pronounced "james path") allows you to declaratively specify how to
  extract elements from a JSON document.

  For example, given this document::

      {"foo": {"bar": "baz"}}

  The jmespath expression ``foo.bar`` will return "baz".

  JMESPath also supports:

  Referencing elements in a list.  Given the data::

      {"foo": {"bar": ["one", "two"]}}

  The expression: ``foo.bar[0]`` will return "one".
  You can also reference all the items in a list using the ``*``
  syntax::

     {"foo": {"bar": [{"name": "one"}, {"name": "two"}]}}

  The expression: ``foo.bar[*].name`` will return ["one", "two"].
  Negative indexing is also supported (-1 refers to the last element
  in the list).  Given the data above, the expression
  ``foo.bar[-1].name`` will return "two".

  The ``*`` can also be used for hash types::

     {"foo": {"bar": {"name": "one"}, "baz": {"name": "two"}}}

  The expression: ``foo.*.name`` will return ["one", "two"].


  API
  ===

  The ``jmespath.py`` library has two functions
  that operate on python data structures.  You can use ``search``
  and give it the jmespath expression and the data:

  .. code:: python

      >>> import jmespath
      >>> path = jmespath.search('foo.bar', {'foo': {'bar': 'baz'}})
      'baz'

  Similar to the ``re`` module, you can use the ``compile`` function
  to compile the JMESPath expression and use this parsed expression
  to perform repeated searches:

  .. code:: python

      >>> import jmespath
      >>> expression = jmespath.compile('foo.bar')
      >>> expression.search({'foo': {'bar': 'baz'}})
      'baz'
      >>> expression.search({'foo': {'bar': 'other'}})
      'other'

  This is useful if you're going to use the same jmespath expression to
  search multiple documents.  This avoids having to reparse the
  JMESPath expression each time you search a new document.

  Options
  -------

  You can provide an instance of ``jmespath.Options`` to control how
  a JMESPath expression is evaluated.  The most common scenario for
  using an ``Options`` instance is if you want to have ordered output
  of your dict keys.  To do this you can use either of these options:

  .. code:: python

      >>> import jmespath
      >>> jmespath.search('{a: a, b: b},
      ...                 mydata,
      ...                 jmespath.Options(dict_cls=collections.OrderedDict))


      >>> import jmespath
      >>> parsed = jmespath.compile('{a: a, b: b}')
      >>> parsed.search('{a: a, b: b},
      ...               mydata,
      ...               jmespath.Options(dict_cls=collections.OrderedDict))


  Custom Functions
  ~~~~~~~~~~~~~~~~

  The JMESPath language has numerous
  `built-in functions
  <http://jmespath.org/specification.html#built-in-functions>`__, but it is
  also possible to add your own custom functions.  Keep in mind that
  custom function support in jmespath.py is experimental and the API may
  change based on feedback.

  **If you have a custom function that you've found useful, consider submitting
  it to jmespath.site and propose that it be added to the JMESPath language.**
  You can submit proposals
  `here <https://github.com/jmespath/jmespath.site/issues>`__.

  To create custom functions:

  * Create a subclass of ``jmespath.functions.Functions``.
  * Create a method with the name ``_func_<your function name>``.
  * Apply the ``jmespath.functions.signature`` decorator that indicates
    the expected types of the function arguments.
  * Provide an instance of your subclass in a ``jmespath.Options`` object.

  Below are a few examples:

  .. code:: python

      import jmespath
      from jmespath import functions

      
      
      
      
      class CustomFunctions(functions.Functions):

          
          
          
          
          
          
          @functions.signature({'types': ['string']})
          def _func_unique_letters(self, s):
              
              
              return ''.join(sorted(set(s)))

          
          
          
          @functions.signature({'types': ['number']}, {'types': ['number']})
          def _func_my_add(self, x, y):
              return x + y

      
      options = jmespath.Options(custom_functions=CustomFunctions())

      
      
      print(
          jmespath.search(
              'my_add(`1`, `2`)', {}, options=options)
      )

      
      print(
          jmespath.search(
              'foo.bar | unique_letters(@)',
              {'foo': {'bar': 'ccbbadd'}},
              options=options)
      )

  Again, if you come up with useful functions that you think make
  sense in the JMESPath language (and make sense to implement in all
  JMESPath libraries, not just python), please let us know at
  `jmespath.site <https://github.com/jmespath/jmespath.site/issues>`__.


  Specification
  =============

  If you'd like to learn more about the JMESPath language, you can check out
  the `JMESPath tutorial <http://jmespath.org/tutorial.html>`__.  Also check
  out the `JMESPath examples page <http://jmespath.org/examples.html>`__ for
  examples of more complex jmespath queries.

  The grammar is specified using ABNF, as described in
  `RFC4234 <http://www.ietf.org/rfc/rfc4234.txt>`_.
  You can find the most up to date
  `grammar for JMESPath here <http://jmespath.org/specification.html#grammar>`__.

  You can read the full
  `JMESPath specification here <http://jmespath.org/specification.html>`__.


  Testing
  =======

  In addition to the unit tests for the jmespath modules,
  there is a ``tests/compliance`` directory that contains
  .json files with test cases.  This allows other implementations
  to verify they are producing the correct output.  Each json
  file is grouped by feature.


  Discuss
  =======

  Join us on our `Gitter channel <https://gitter.im/jmespath/chat>`__
  if you want to chat or if you have any questions.


pkgId: 14e978e9d3a142c71eb43e277b6a7b78ebaa6270b4cd162da9e096114739de89
name: rh-python36-jsonpatch
arch: noarch
version: 1.25
epoch: 0
release: 1
summary: Apply JSON-Patches (RFC 6902)
url: https://github.com/stefankoegl/python-json-patch
rpm_license: Modified BSD License
rpm_vendor: Stefan Kögl <stefan@skoegl.net>
rpm_group: Development/Libraries
rpm_buildhost: 07b405f2ecb0434caad5cf90a2a8783a
rpm_sourcerpm: rh-python36-jsonpatch-1.25-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387228-rh-python36-jsonpatch/rh-python36-jsonpatch-1.25-1.noarch.rpm
checksum_type: sha256
description:
  python-json-patch [![Build Status](https://secure.travis-ci.org/stefankoegl/python-json-patch.png?branch=master)](https://travis-ci.org/stefankoegl/python-json-patch) [![Coverage Status](https://coveralls.io/repos/stefankoegl/python-json-patch/badge.png?branch=master)](https://coveralls.io/r/stefankoegl/python-json-patch?branch=master)
  =================
  Applying JSON Patches in Python
  -------------------------------

  Library to apply JSON Patches according to
  [RFC 6902](http://tools.ietf.org/html/rfc6902)

  See Sourcecode for Examples

  * Website: https://github.com/stefankoegl/python-json-patch
  * Repository: https://github.com/stefankoegl/python-json-patch.git
  * Documentation: https://python-json-patch.readthedocs.org/
  * PyPI: https://pypi.python.org/pypi/jsonpatch
  * Travis-CI: https://travis-ci.org/stefankoegl/python-json-patch
  * Coveralls: https://coveralls.io/r/stefankoegl/python-json-patch

  Running external tests
  ----------------------
  To run external tests (such as those from https://github.com/json-patch/json-patch-tests) use ext_test.py

      ./ext_tests.py ../json-patch-tests/tests.json


pkgId: 9756cf8a4464f1063462a2cd26bf009352fee1dff3f4c807c57a68251148cc7d
name: rh-python36-jsonschema
arch: noarch
version: 3.2.0
epoch: 0
release: 1
summary: An implementation of JSON Schema validation for Python
url: http://github.com/Julian/jsonschema
rpm_license: MIT
rpm_vendor: Julian Berman <Julian@GrayVines.com>
rpm_group: Development/Libraries
rpm_buildhost: a590be96f3a249edbc953a297c2e0a0a
rpm_sourcerpm: rh-python36-jsonschema-3.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387147-rh-python36-jsonschema/rh-python36-jsonschema-3.2.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/jsonschema.svg
      :target: https://pypi.python.org/pypi/jsonschema
  .. image:: https://travis-ci.org/Julian/jsonschema.svg?branch=master
      :target: https://travis-ci.org/Julian/jsonschema
  .. image:: https://img.shields.io/pypi/l/jsonschema.svg
      :target: https://pypi.python.org/pypi/jsonschema

  ==========
  jsonschema
  ==========

  ``jsonschema`` is an implementation of `JSON Schema <http://json-schema.org>`_
  for Python (supporting 2.7+ including Python 3).

  .. code-block:: python

      >>> from jsonschema import validate

      >>> # A sample schema, like what we'd get from json.load()
      >>> schema = {
      ...     "type" : "object",
      ...     "properties" : {
      ...         "price" : {"type" : "number"},
      ...         "name" : {"type" : "string"},
      ...     },
      ... }

      >>> # If no exception is raised by validate(), the instance is valid.
      >>> validate({"name" : "Eggs", "price" : 34.99}, schema)

      >>> validate(
      ...     {"name" : "Eggs", "price" : "Invalid"}, schema
      ... )                                   # doctest: +IGNORE_EXCEPTION_DETAIL
      Traceback (most recent call last):
          ...
      ValidationError: 'Invalid' is not of type 'number'

  It can also be used from console:

  .. code-block:: bash

      $ jsonschema -i sample.json sample.schema

  Features
  --------

  * Full support for
    `Draft 3 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft3Validator>`_
    **and** `Draft 4 <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.Draft4Validator>`_
    of the schema.

  * `Lazy validation <https://python-jsonschema.readthedocs.io/en/latest/validate/#jsonschema.IValidator.iter_errors>`_
    that can iteratively report *all* validation errors.

  * Small and extensible

  * `Programmatic querying <https://python-jsonschema.readthedocs.io/en/latest/errors/#module-jsonschema>`_
    of which properties or items failed validation.


  Release Notes
  -------------

  Version 2.5.0 is mainly a performance release. The interface for `RefResolver`
  was extended to add methods that improve performance on CPython.

  Support for custom `RefResolver` objects with the legacy interface should *not*
  be affected. If you notice something amiss please file an issue ticket.


  Running the Test Suite
  ----------------------

  If you have ``tox`` installed (perhaps via ``pip install tox`` or your
  package manager), running``tox`` in the directory of your source checkout will
  run ``jsonschema``'s test suite on all of the versions of Python ``jsonschema``
  supports. Note that you'll need to have all of those versions installed in
  order to run the tests on each of them, otherwise ``tox`` will skip (and fail)
  the tests on that version.

  Of course you're also free to just run the tests on a single version with your
  favorite test runner. The tests live in the ``jsonschema.tests`` package.


  Community
  ---------

  There's a `mailing list <https://groups.google.com/forum/#!forum/jsonschema>`_
  for this implementation on Google Groups.

  Please join, and feel free to send questions there.


  Contributing
  ------------

  I'm Julian Berman.

  ``jsonschema`` is on `GitHub <http://github.com/Julian/jsonschema>`_.

  Get in touch, via GitHub or otherwise, if you've got something to contribute,
  it'd be most welcome!

  You can also generally find me on Freenode (nick: ``tos9``) in various
  channels, including ``#python``.

  If you feel overwhelmingly grateful, you can woo me with beer money on
  `Gittip <https://www.gittip.com/Julian/>`_ or via Google Wallet with the email
  in my GitHub profile.


pkgId: 312c88a9f90d1221461386bb13e7a6e16707859e96ee9a27c27c8f79bbb71179
name: rh-python36-junit-xml
arch: noarch
version: 1.8
epoch: 0
release: 1
summary: Creates JUnit XML test result documents that can be read by tools such as Jenkins
url: https://github.com/kyrus/python-junit-xml
rpm_license: MIT
rpm_vendor: Brian Beyer <brian@kyr.us>
rpm_group: Development/Libraries
rpm_buildhost: 718759af52074f1988343b188477ddd5
rpm_sourcerpm: rh-python36-junit-xml-1.8-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387042-rh-python36-junit-xml/rh-python36-junit-xml-1.8-1.noarch.rpm
checksum_type: sha256
description:
  python-junit-xml
  ================
  .. image:: https://travis-ci.org/kyrus/python-junit-xml.png?branch=master

  About
  -----

  A Python module for creating JUnit XML test result documents that can be
  read by tools such as Jenkins. If you are ever working with test tool or
  test suite written in Python and want to take advantage of Jenkins'
  pretty graphs and test reporting capabilities, this module will let you
  generate the XML test reports.

  *As there is no definitive Jenkins JUnit XSD that I could find, the XML
  documents created by this module support a schema based on Google
  searches and the Jenkins JUnit XML reader source code. File a bug if
  something doesn't work like you expect it to.*

  Installation
  ------------

  Install using pip or easy_install:

  ::

  	pip install junit-xml
  	or
  	easy_install junit-xml

  You can also clone the Git repository from Github and install it manually:

  ::

      git clone https://github.com/kyrus/python-junit-xml.git
      python setup.py install

  Using
  -----

  Create a test suite, add a test case, and print it to the screen:

  .. code-block:: python

      from junit_xml import TestSuite, TestCase

      test_cases = [TestCase('Test1', 'some.class.name', 123.345, 'I am stdout!', 'I am stderr!')]
      ts = TestSuite("my test suite", test_cases)
      
      print(TestSuite.to_xml_string([ts]))

  Produces the following output

  .. code-block:: xml

      <?xml version="1.0" ?>
      <testsuites>
          <testsuite errors="0" failures="0" name="my test suite" tests="1">
              <testcase classname="some.class.name" name="Test1" time="123.345000">
                  <system-out>
                      I am stdout!
                  </system-out>
                  <system-err>
                      I am stderr!
                  </system-err>
              </testcase>
          </testsuite>
      </testsuites>

  Writing XML to a file:

  .. code-block:: python

      
      with open('output.xml', 'w') as f:
          TestSuite.to_file(f, [ts], prettyprint=False)

  See the docs and unit tests for more examples.

  NOTE: Unicode characters identified as "illegal or discouraged" are automatically
  stripped from the XML string or file.

  Running the tests
  -----------------

  ::

      
      pip install tox
      tox


pkgId: 9f3850730d43bdef2300cc7c28c0723a148351c450eba9cd9aff5d0dae3d93ee
name: rh-python36-keystoneauth1
arch: noarch
version: 3.18.0
epoch: 0
release: 1
summary: Authentication Library for OpenStack Identity
url: https://docs.openstack.org/keystoneauth/latest/
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-dev@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: bc13aca081d44cfe9581d468bd4bf92a
rpm_sourcerpm: rh-python36-keystoneauth1-3.18.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387243-rh-python36-keystoneauth1/rh-python36-keystoneauth1-3.18.0-1.noarch.rpm
checksum_type: sha256
description:
  ========================
  Team and repository tags
  ========================

  .. image:: https://governance.openstack.org/badges/keystoneauth.svg
      :target: https://governance.openstack.org/reference/tags/index.html

  .. Change things from this point on

  ============
  keystoneauth
  ============

  .. image:: https://img.shields.io/pypi/v/keystoneauth1.svg
      :target: https://pypi.python.org/pypi/keystoneauth1/
      :alt: Latest Version

  .. image:: https://img.shields.io/pypi/dm/keystoneauth1.svg
      :target: https://pypi.python.org/pypi/keystoneauth1/
      :alt: Downloads

  This package contains tools for authenticating to an OpenStack-based cloud.
  These tools include:

  * Authentication plugins (password, token, and federation based)
  * Discovery mechanisms to determine API version support
  * A session that is used to maintain client settings across requests (based on
    the requests Python library)

  Further information:

  * Free software: Apache license
  * Documentation: https://docs.openstack.org/keystoneauth/latest/
  * Source: https://git.openstack.org/cgit/openstack/keystoneauth
  * Bugs: https://bugs.launchpad.net/keystoneauth


pkgId: 0edf8a4db69f4d17d3ecd9abc76207c9144509f1a90efa906eae49af6f9e7322
name: rh-python36-kombu
arch: noarch
version: 4.6.7
epoch: 0
release: 1
summary: Messaging library for Python.
url: https://kombu.readthedocs.io
rpm_license: BSD
rpm_vendor: Ask Solem <ask@celeryproject.org>
rpm_group: Development/Libraries
rpm_buildhost: 96ab44d297844584ba6e54237bfb0297
rpm_sourcerpm: rh-python36-kombu-4.6.7-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387105-rh-python36-kombu/rh-python36-kombu-4.6.7-1.noarch.rpm
checksum_type: sha256
description:
  ========================================
   kombu - Messaging library for Python
  ========================================

  |build-status| |coverage| |license| |wheel| |pyversion| |pyimp|

  :Version: 4.2.1
  :Web: http://kombu.me/
  :Download: https://pypi.python.org/pypi/kombu/
  :Source: https://github.com/celery/kombu/
  :Keywords: messaging, amqp, rabbitmq, redis, mongodb, python, queue

  About
  =====

  `Kombu` is a messaging library for Python.

  The aim of `Kombu` is to make messaging in Python as easy as possible by
  providing an idiomatic high-level interface for the AMQ protocol, and also
  provide proven and tested solutions to common messaging problems.

  `AMQP`_ is the Advanced Message Queuing Protocol, an open standard protocol
  for message orientation, queuing, routing, reliability and security,
  for which the `RabbitMQ`_ messaging server is the most popular implementation.

  Features
  ========

  * Allows application authors to support several message server
    solutions by using pluggable transports.

      * AMQP transport using the `py-amqp`_, `librabbitmq`_, or `qpid-python`_ libraries.

      * High performance AMQP transport written in C - when using `librabbitmq`_

        This is automatically enabled if librabbitmq is installed:

        ::

          $ pip install librabbitmq

      * Virtual transports makes it really easy to add support for non-AMQP
        transports. There is already built-in support for `Redis`_,
        `Amazon SQS`_, `ZooKeeper`_, `SoftLayer MQ`_ and `Pyro`_.

      * In-memory transport for unit testing.

  * Supports automatic encoding, serialization and compression of message
    payloads.

  * Consistent exception handling across transports.

  * The ability to ensure that an operation is performed by gracefully
    handling connection and channel errors.

  * Several annoyances with `amqplib`_ has been fixed, like supporting
    timeouts and the ability to wait for events on more than one channel.

  * Projects already using `carrot`_ can easily be ported by using
    a compatibility layer.

  For an introduction to AMQP you should read the article `Rabbits and warrens`_,
  and the `Wikipedia article about AMQP`_.

  .. _`RabbitMQ`: https://www.rabbitmq.com/
  .. _`AMQP`: https://amqp.org
  .. _`py-amqp`: https://pypi.python.org/pypi/amqp/
  .. _`qpid-python`: https://pypi.python.org/pypi/qpid-python/
  .. _`Redis`: https://redis.io
  .. _`Amazon SQS`: https://aws.amazon.com/sqs/
  .. _`Zookeeper`: https://zookeeper.apache.org/
  .. _`Rabbits and warrens`: http://web.archive.org/web/20160323134044/http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/
  .. _`amqplib`: https://barryp.org/software/py-amqplib/
  .. _`Wikipedia article about AMQP`: https://en.wikipedia.org/wiki/AMQP
  .. _`carrot`: https://pypi.python.org/pypi/carrot/
  .. _`librabbitmq`: https://pypi.python.org/pypi/librabbitmq
  .. _`Pyro`: https://pythonhosting.org/Pyro4
  .. _`SoftLayer MQ`: https://sldn.softlayer.com/reference/messagequeueapi

  .. _transport-comparison:

  Transport Comparison
  ====================

  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | **Client**    | **Type** | **Direct** | **Topic**  | **Fanout**    | **Priority** | **TTL**               |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *amqp*        | Native   | Yes        | Yes        | Yes           | Yes [#f3]_   | Yes [#f4]_            |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *qpid*        | Native   | Yes        | Yes        | Yes           | No           | No                    |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *redis*       | Virtual  | Yes        | Yes        | Yes (PUB/SUB) | Yes          | No                    |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *mongodb*     | Virtual  | Yes        | Yes        | Yes           | Yes          | Yes                   |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *SQS*         | Virtual  | Yes        | Yes [#f1]_ | Yes [#f2]_    | No           | No                    |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *zookeeper*   | Virtual  | Yes        | Yes [#f1]_ | No            | Yes          | No                    |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *in-memory*   | Virtual  | Yes        | Yes [#f1]_ | No            | No           | No                    |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+
  | *SLMQ*        | Virtual  | Yes        | Yes [#f1]_ | No            | No           | No                    |
  +---------------+----------+------------+------------+---------------+--------------+-----------------------+


  .. [#f1] Declarations only kept in memory, so exchanges/queues
           must be declared by all clients that needs them.

  .. [#f2] Fanout supported via storing routing tables in SimpleDB.
           Disabled by default, but can be enabled by using the
           ``supports_fanout`` transport option.

  .. [#f3] AMQP Message priority support depends on broker implementation.

  .. [#f4] AMQP Message/Queue TTL support depends on broker implementation.

  Documentation
  -------------

  Kombu is using Sphinx, and the latest documentation can be found here:

      https://kombu.readthedocs.io/

  Quick overview
  --------------

  .. code:: python

      from kombu import Connection, Exchange, Queue

      media_exchange = Exchange('media', 'direct', durable=True)
      video_queue = Queue('video', exchange=media_exchange, routing_key='video')

      def process_media(body, message):
          print body
          message.ack()

      
      with Connection('amqp://guest:guest@localhost//') as conn:

          
          producer = conn.Producer(serializer='json')
          producer.publish({'name': '/tmp/lolcat1.avi', 'size': 1301013},
                            exchange=media_exchange, routing_key='video',
                            declare=[video_queue])

          
          
          
          
          
          

          
          with conn.Consumer(video_queue, callbacks=[process_media]) as consumer:
              
              while True:
                  conn.drain_events()

      
      video_queue = Queue('video', exchange=media_exchange, key='video')
      image_queue = Queue('image', exchange=media_exchange, key='image')

      with connection.Consumer([video_queue, image_queue],
                               callbacks=[process_media]) as consumer:
          while True:
              connection.drain_events()


  Or handle channels manually:

  .. code:: python

      with connection.channel() as channel:
          producer = Producer(channel, ...)
          consumer = Producer(channel)


  All objects can be used outside of with statements too,
  just remember to close the objects after use:

  .. code:: python

      from kombu import Connection, Consumer, Producer

      connection = Connection()
          
      connection.release()

      consumer = Consumer(channel_or_connection, ...)
      consumer.register_callback(my_callback)
      consumer.consume()
          
      consumer.cancel()


  `Exchange` and `Queue` are simply declarations that can be pickled
  and used in configuration files etc.

  They also support operations, but to do so they need to be bound
  to a channel.

  Binding exchanges and queues to a connection will make it use
  that connections default channel.

  ::

      >>> exchange = Exchange('tasks', 'direct')

      >>> connection = Connection()
      >>> bound_exchange = exchange(connection)
      >>> bound_exchange.delete()

      
      >>> exchange.delete()
      raise NotBoundError: Can't call delete on Exchange not bound to
          a channel.

  Terminology
  ===========

  There are some concepts you should be familiar with before starting:

      * Producers

          Producers sends messages to an exchange.

      * Exchanges

          Messages are sent to exchanges. Exchanges are named and can be
          configured to use one of several routing algorithms. The exchange
          routes the messages to consumers by matching the routing key in the
          message with the routing key the consumer provides when binding to
          the exchange.

      * Consumers

          Consumers declares a queue, binds it to a exchange and receives
          messages from it.

      * Queues

          Queues receive messages sent to exchanges. The queues are declared
          by consumers.

      * Routing keys

          Every message has a routing key. The interpretation of the routing
          key depends on the exchange type. There are four default exchange
          types defined by the AMQP standard, and vendors can define custom
          types (so see your vendors manual for details).

          These are the default exchange types defined by AMQP/0.8:

              * Direct exchange

                  Matches if the routing key property of the message and
                  the `routing_key` attribute of the consumer are identical.

              * Fan-out exchange

                  Always matches, even if the binding does not have a routing
                  key.

              * Topic exchange

                  Matches the routing key property of the message by a primitive
                  pattern matching scheme. The message routing key then consists
                  of words separated by dots (`"."`, like domain names), and
                  two special characters are available; star (`"*"`) and hash
                  (`"#"`). The star matches any word, and the hash matches
                  zero or more words. For example `"*.stock.#"` matches the
                  routing keys `"usd.stock"` and `"eur.stock.db"` but not
                  `"stock.nasdaq"`.


  Installation
  ============

  You can install `Kombu` either via the Python Package Index (PyPI)
  or from source.

  To install using `pip`,:

  ::

      $ pip install kombu

  To install using `easy_install`,:

  ::

      $ easy_install kombu

  If you have downloaded a source tarball you can install it
  by doing the following,:

  ::

      $ python setup.py build
      



  Getting Help
  ============

  Mailing list
  ------------

  Join the `celery-users`_ mailing list.

  .. _`celery-users`: https://groups.google.com/group/celery-users/

  Bug tracker
  ===========

  If you have any suggestions, bug reports or annoyances please report them
  to our issue tracker at https://github.com/celery/kombu/issues/

  Contributing
  ============

  Development of `Kombu` happens at Github: https://github.com/celery/kombu

  You are highly encouraged to participate in the development. If you don't
  like Github (for some reason) you're welcome to send regular patches.

  License
  =======

  This software is licensed under the `New BSD License`. See the `LICENSE`
  file in the top distribution directory for the full license text.


  .. |build-status| image:: https://secure.travis-ci.org/celery/kombu.png?branch=master
      :alt: Build status
      :target: https://travis-ci.org/celery/kombu

  .. |coverage| image:: https://codecov.io/github/celery/kombu/coverage.svg?branch=master
      :target: https://codecov.io/github/celery/kombu?branch=master

  .. |license| image:: https://img.shields.io/pypi/l/kombu.svg
      :alt: BSD License
      :target: https://opensource.org/licenses/BSD-3-Clause

  .. |wheel| image:: https://img.shields.io/pypi/wheel/kombu.svg
      :alt: Kombu can be installed via wheel
      :target: https://pypi.python.org/pypi/kombu/

  .. |pyversion| image:: https://img.shields.io/pypi/pyversions/kombu.svg
      :alt: Supported Python versions.
      :target: https://pypi.python.org/pypi/kombu/

  .. |pyimp| image:: https://img.shields.io/pypi/implementation/kombu.svg
      :alt: Support Python implementations.
      :target: https://pypi.python.org/pypi/kombu/
  --


pkgId: cd191e6f46d053c8929fc37780932eca03e60b5c82da53d708a9b490f88457e1
name: rh-python36-libselinux-python
arch: src
version: 2.5
epoch: 0
release: 14.1.el7
summary: SELinux SCL Python36 python bindings
url: https://github.com/SELinuxProject/selinux/wiki
rpm_license: Public Domain
rpm_group: System Environment/Libraries
rpm_buildhost: 10a5f8b093454c9ea1163556aa99c099
location_href: 01387021-rh-python36-libselinux-python/rh-python36-libselinux-python-2.5-14.1.el7.src.rpm
checksum_type: sha256
description:
  Security-enhanced Linux is a feature of the Linux® kernel and a number
  of utilities with enhanced security functionality designed to add
  mandatory access controls to Linux.  The Security-enhanced Linux
  kernel contains new architectural components originally developed to
  improve the security of the Flask operating system. These
  architectural components provide general support for the enforcement
  of many kinds of mandatory access control policies, including those
  based on the concepts of Type Enforcement®, Role-based Access
  Control, and Multi-level Security.

  libselinux provides an API for SELinux applications to get and set
  process and file security contexts and to obtain security policy
  decisions.  Required for any applications that use the SELinux API.


pkgId: c39101efebe632f1497ac414b6d80e0b3715d238521d0c6be58c2244a0341142
name: rh-python36-libselinux-python-debuginfo
arch: x86_64
version: 2.5
epoch: 0
release: 14.1.el7
summary: Debug information for package rh-python36-libselinux-python
url: https://github.com/SELinuxProject/selinux/wiki
rpm_license: Public Domain
rpm_group: Development/Debug
rpm_buildhost: 858b478f217d4ad088c0a106211208ae
rpm_sourcerpm: rh-python36-libselinux-python-2.5-14.1.el7.src.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-libselinux-python.
  Debug information is useful when developing applications that use this
  package or when debugging this package.

location_href:
  01387021-rh-python36-libselinux-python/rh-python36-libselinux-python-debuginfo-2.5-14.1.el7.x86_64.rpm


pkgId: 6c3d1abd30b967a811ebd148524743f279f5fbbb1290d6d668c0f6843a1665b4
name: rh-python36-lxml
arch: src
version: 4.5.0
epoch: 0
release: 1
summary: Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
url: http://lxml.de/
rpm_license: BSD
rpm_vendor: lxml dev team <lxml-dev@lxml.de>
rpm_group: Development/Libraries
rpm_buildhost: ec87853fd3bf41e88a959a90549f0f0a
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387150-rh-python36-lxml/rh-python36-lxml-4.5.0-1.src.rpm
checksum_type: sha256
description:
  lxml is a Pythonic, mature binding for the libxml2 and libxslt libraries.  It
  provides safe and convenient access to these libraries using the ElementTree
  API.

  It extends the ElementTree API significantly to offer support for XPath,
  RelaxNG, XML Schema, XSLT, C14N and much more.

  To contact the project, go to the `project home page
  <http://lxml.de/>`_ or see our bug tracker at
  https://launchpad.net/lxml

  In case you want to use the current in-development version of lxml,
  you can get it from the github repository at
  https://github.com/lxml/lxml .  Note that this requires Cython to
  build the sources, see the build instructions on the project home
  page.  To the same end, running ``easy_install lxml==dev`` will
  install lxml from
  https://github.com/lxml/lxml/tarball/master#egg=lxml-dev if you have
  an appropriate version of Cython installed.


  After an official release of a new stable series, bug fixes may become
  available at
  https://github.com/lxml/lxml/tree/lxml-4.1 .
  Running ``easy_install lxml==4.1bugfix`` will install
  the unreleased branch state from
  https://github.com/lxml/lxml/tarball/lxml-4.1#egg=lxml-4.1bugfix
  as soon as a maintenance branch has been established.  Note that this
  requires Cython to be installed at an appropriate version for the build.

  4.1.1 (2017-11-04)
  ==================

  * Rebuild with Cython 0.27.3 to improve support for Py3.7.


pkgId: 7a4d6848637409d1f197f49fea827ded442753230ea8ae8bd4f6b35d32cf45df
name: rh-python36-lxml-debuginfo
arch: x86_64
version: 4.5.0
epoch: 0
release: 1
summary: Debug information for package rh-python36-lxml
url: http://lxml.de/
rpm_license: BSD
rpm_vendor: lxml dev team <lxml-dev@lxml.de>
rpm_group: Development/Debug
rpm_buildhost: e87ae2e3895447139dd875096db65bee
rpm_sourcerpm: rh-python36-lxml-4.5.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387150-rh-python36-lxml/rh-python36-lxml-debuginfo-4.5.0-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-lxml.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: 1c56f1f25d166c5b9416b696539c7d82946890331e4a0d839593d4981483d892
name: rh-python36-monotonic
arch: noarch
version: 1.5
epoch: 0
release: 1
summary: An implementation of time.monotonic() for Python 2 & < 3.3
url: https://github.com/atdt/monotonic
rpm_license: Apache
rpm_vendor: Ori Livneh <ori@wikimedia.org>
rpm_group: Development/Libraries
rpm_buildhost: 62efcbc4ccd34a5b86b71623aa68a5f3
rpm_sourcerpm: rh-python36-monotonic-1.5-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387231-rh-python36-monotonic/rh-python36-monotonic-1.5-1.noarch.rpm
checksum_type: sha256
description:
  monotonic
  ~~~~~~~~~

  This module provides a ``monotonic()`` function which returns the
  value (in fractional seconds) of a clock which never goes backwards.

  On Python 3.3 or newer, ``monotonic`` will be an alias of
  ``time.monotonic`` from the standard library. On older versions,
  it will fall back to an equivalent implementation:

  +------------------+----------------------------------------+
  | Linux, BSD, AIX  | ``clock_gettime(3)``                   |
  +------------------+----------------------------------------+
  | Windows          | ``GetTickCount`` or ``GetTickCount64`` |
  +------------------+----------------------------------------+
  | OS X             | ``mach_absolute_time``                 |
  +------------------+----------------------------------------+

  If no suitable implementation exists for the current platform,
  attempting to import this module (or to import from it) will
  cause a ``RuntimeError`` exception to be raised.


pkgId: 532cd452fd164a4d21b09970f0b777ad2a28d888163e13a942d0d23acaeee6bc
name: rh-python36-more-itertools
arch: noarch
version: 8.2.0
epoch: 0
release: 1
summary: More routines for operating on iterables, beyond itertools
url: https://github.com/erikrose/more-itertools
rpm_license: MIT
rpm_vendor: Erik Rose <erikrose@grinchcentral.com>
rpm_group: Development/Libraries
rpm_buildhost: 4dacd616faac40d5a90315b0693cc7ad
rpm_sourcerpm: rh-python36-more-itertools-8.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387151-rh-python36-more-itertools/rh-python36-more-itertools-8.2.0-1.noarch.rpm
checksum_type: sha256
description:
  ==============
  More Itertools
  ==============

  .. image:: https://coveralls.io/repos/github/erikrose/more-itertools/badge.svg?branch=master
    :target: https://coveralls.io/github/erikrose/more-itertools?branch=master

  Python's ``itertools`` library is a gem - you can compose elegant solutions
  for a variety of problems with the functions it provides. In ``more-itertools``
  we collect additional building blocks, recipes, and routines for working with
  Python iterables.

  Getting started
  ===============

  To get started, install the library with `pip <https://pip.pypa.io/en/stable/>`_:

  .. code-block:: shell

      pip install more-itertools

  The recipes from the `itertools docs <https://docs.python.org/3/library/itertools.html#itertools-recipes>`_
  are included in the top-level package:

  .. code-block:: python

      >>> from more_itertools import flatten
      >>> iterable = [(0, 1), (2, 3)]
      >>> list(flatten(iterable))
      [0, 1, 2, 3]

  Several new recipes are available as well:

  .. code-block:: python

      >>> from more_itertools import chunked
      >>> iterable = [0, 1, 2, 3, 4, 5, 6, 7, 8]
      >>> list(chunked(iterable, 3))
      [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

      >>> from more_itertools import spy
      >>> iterable = (x * x for x in range(1, 6))
      >>> head, iterable = spy(iterable, n=3)
      >>> list(head)
      [1, 4, 9]
      >>> list(iterable)
      [1, 4, 9, 16, 25]



  For the full listing of functions, see the `API documentation <https://more-itertools.readthedocs.io/en/latest/api.html>`_.

  Development
  ===========

  ``more-itertools`` is maintained by `@erikrose <https://github.com/erikrose>`_
  and `@bbayles <https://github.com/bbayles>`_, with help from `many others <https://github.com/erikrose/more-itertools/graphs/contributors>`_.
  If you have a problem or suggestion, please file a bug or pull request in this
  repository. Thanks for contributing!


  Version History
  ===============



  4.1.0
  -----

  * New itertools:
      * split_at (thanks to michael-celani)
      * circular_shifts (thanks to hiqua)
      * make_decorator - see the blog post `Yo, I heard you like decorators <https://sites.google.com/site/bbayles/index/decorator_factory>`_
        for a tour (thanks to pylang)
      * always_reversible (thanks to michael-celani)
      * nth_combination (from the `Python 3.7 docs <https://docs.python.org/3.7/library/itertools.html#itertools-recipes>`_)

  * Improvements to existing itertools:
      * seekable now has an ``elements`` method to return cached items.
      * The performance tradeoffs between roundrobin and
        interleave_longest are now documented (thanks michael-celani,
        pylang, and MSeifert04)

  4.0.1
  -----

  * No code changes - this release fixes how the docs display on PyPI.

  4.0.0
  -----

  * New itertools:
      * consecutive_groups (Based on the example in the `Python 2.4 docs <https://docs.python.org/release/2.4.4/lib/itertools-example.html>`_)
      * seekable (If you're looking for how to "reset" an iterator,
        you're in luck!)
      * exactly_n (thanks to michael-celani)
      * run_length.encode and run_length.decode
      * difference

  * Improvements to existing itertools:
      * The number of items between filler elements in intersperse can
        now be specified (thanks to pylang)
      * distinct_permutations and peekable got some minor
        adjustments (thanks to MSeifert04)
      * always_iterable now returns an iterator object. It also now
        allows different types to be considered iterable (thanks to jaraco)
      * bucket can now limit the keys it stores in memory
      * one now allows for custom exceptions (thanks to kalekundert)

  * Other changes:
      * A few typos were fixed (thanks to EdwardBetts)
      * All tests can now be run with ``python setup.py test``

  The major version update is due to the change in the return value of always_iterable.
  It now always returns iterator objects:

  .. code-block:: python

      >>> from more_itertools import always_iterable
      
      >>> always_iterable(12345)
      <tuple_iterator object at 0x7fb24c9488d0>
      >>> list(always_iterable(12345))
      [12345]
      
      >>> always_iterable([1, 2, 3, 4, 5])
      <list_iterator object at 0x7fb24c948c50>

  3.2.0
  -----

  * New itertools:
      * lstrip, rstrip, and strip
        (thanks to MSeifert04 and pylang)
      * islice_extended
  * Improvements to existing itertools:
      * Some bugs with slicing peekable-wrapped iterables were fixed

  3.1.0
  -----

  * New itertools:
      * numeric_range (Thanks to BebeSparkelSparkel and MSeifert04)
      * count_cycle (Thanks to BebeSparkelSparkel)
      * locate (Thanks to pylang and MSeifert04)
  * Improvements to existing itertools:
      * A few itertools are now slightly faster due to some function
        optimizations. (Thanks to MSeifert04)
  * The docs have been substantially revised with installation notes,
    categories for library functions, links, and more. (Thanks to pylang)


  3.0.0
  -----

  * Removed itertools:
      * ``context`` has been removed due to a design flaw - see below for
        replacement options. (thanks to NeilGirdhar)
  * Improvements to existing itertools:
      * ``side_effect`` now supports ``before`` and ``after`` keyword
        arguments. (Thanks to yardsale8)
  * PyPy and PyPy3 are now supported.

  The major version change is due to the removal of the ``context`` function.
  Replace it with standard ``with`` statement context management:

  .. code-block:: python

      
      file_obj = StringIO()
      consume(print(x, file=f) for f in context(file_obj) for x in u'123')

      
      file_obj = StringIO()
      with file_obj as f:
          consume(print(x, file=f) for x in u'123')

  2.6.0
  -----

  * New itertools:
      * ``adjacent`` and ``groupby_transform`` (Thanks to diazona)
      * ``always_iterable`` (Thanks to jaraco)
      * (Removed in 3.0.0) ``context`` (Thanks to yardsale8)
      * ``divide`` (Thanks to mozbhearsum)
  * Improvements to existing itertools:
      * ``ilen`` is now slightly faster. (Thanks to wbolster)
      * ``peekable`` can now prepend items to an iterable. (Thanks to diazona)

  2.5.0
  -----

  * New itertools:
      * ``distribute`` (Thanks to mozbhearsum and coady)
      * ``sort_together`` (Thanks to clintval)
      * ``stagger`` and ``zip_offset`` (Thanks to joshbode)
      * ``padded``
  * Improvements to existing itertools:
      * ``peekable`` now handles negative indexes and slices with negative
        components properly.
      * ``intersperse`` is now slightly faster. (Thanks to pylang)
      * ``windowed`` now accepts a ``step`` keyword argument.
        (Thanks to pylang)
  * Python 3.6 is now supported.

  2.4.1
  -----

  * Move docs 100% to readthedocs.io.

  2.4
  -----

  * New itertools:
      * ``accumulate``, ``all_equal``, ``first_true``, ``partition``, and
        ``tail`` from the itertools documentation.
      * ``bucket`` (Thanks to Rosuav and cvrebert)
      * ``collapse`` (Thanks to abarnet)
      * ``interleave`` and ``interleave_longest`` (Thanks to abarnet)
      * ``side_effect`` (Thanks to nvie)
      * ``sliced`` (Thanks to j4mie and coady)
      * ``split_before`` and ``split_after`` (Thanks to astronouth7303)
      * ``spy`` (Thanks to themiurgo and mathieulongtin)
  * Improvements to existing itertools:
      * ``chunked`` is now simpler and more friendly to garbage collection.
        (Contributed by coady, with thanks to piskvorky)
      * ``collate`` now delegates to ``heapq.merge`` when possible.
        (Thanks to kmike and julianpistorius)
      * ``peekable``-wrapped iterables are now indexable and sliceable.
        Iterating through ``peekable``-wrapped iterables is also faster.
      * ``one`` and ``unique_to_each`` have been simplified.
        (Thanks to coady)


  2.3
  -----

  * Added ``one`` from ``jaraco.util.itertools``. (Thanks, jaraco!)
  * Added ``distinct_permutations`` and ``unique_to_each``. (Contributed by
    bbayles)
  * Added ``windowed``. (Contributed by bbayles, with thanks to buchanae,
    jaraco, and abarnert)
  * Simplified the implementation of ``chunked``. (Thanks, nvie!)
  * Python 3.5 is now supported. Python 2.6 is no longer supported.
  * Python 3 is now supported directly; there is no 2to3 step.

  2.2
  -----

  * Added ``iterate`` and ``with_iter``. (Thanks, abarnert!)

  2.1
  -----

  * Added (tested!) implementations of the recipes from the itertools
    documentation. (Thanks, Chris Lonnen!)
  * Added ``ilen``. (Thanks for the inspiration, Matt Basta!)

  2.0
  -----

  * ``chunked`` now returns lists rather than tuples. After all, they're
    homogeneous. This slightly backward-incompatible change is the reason for
    the major version bump.
  * Added ``@consumer``.
  * Improved test machinery.

  1.1
  -----

  * Added ``first`` function.
  * Added Python 3 support.
  * Added a default arg to ``peekable.peek()``.
  * Noted how to easily test whether a peekable iterator is exhausted.
  * Rewrote documentation.

  1.0
  -----

  * Initial release, with ``collate``, ``peekable``, and ``chunked``. Could
    really use better docs.


pkgId: cd9701e3752dc255f9693f5421d17699c84b39e233562622a4a7dc89a3d2bb36
name: rh-python36-msgpack
arch: src
version: 0.6.2
epoch: 0
release: 1
summary: MessagePack (de)serializer.
url: https://msgpack.org/
rpm_license: Apache 2.0
rpm_vendor: INADA Naoki <songofacandy@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: ceb5b05e15ac48b0a1e90beb46237e67
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387012-rh-python36-msgpack/rh-python36-msgpack-0.6.2-1.src.rpm
checksum_type: sha256
description:
  ======================
  MessagePack for Python
  ======================

  .. image:: https://travis-ci.org/msgpack/msgpack-python.svg?branch=master
     :target: https://travis-ci.org/msgpack/msgpack-python
     :alt: Build Status

  .. image:: https://readthedocs.org/projects/msgpack-python/badge/?version=latest
     :target: https://msgpack-python.readthedocs.io/en/latest/?badge=latest
     :alt: Documentation Status


  What's this
  -----------

  `MessagePack <https://msgpack.org/>`_ is an efficient binary serialization format.
  It lets you exchange data among multiple languages like JSON.
  But it's faster and smaller.
  This package provides CPython bindings for reading and writing MessagePack data.


  Very important notes for existing users
  ---------------------------------------

  PyPI package name
  ^^^^^^^^^^^^^^^^^

  TL;DR: When upgrading from msgpack-0.4 or earlier, don't do `pip install -U msgpack-python`.
  Do `pip uninstall msgpack-python; pip install msgpack` instead.

  Package name on PyPI was changed to msgpack from 0.5.
  I upload transitional package (msgpack-python 0.5 which depending on msgpack)
  for smooth transition from msgpack-python to msgpack.

  Sadly, this doesn't work for upgrade install.  After `pip install -U msgpack-python`,
  msgpack is removed and `import msgpack` fail.


  Deprecating encoding option
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  encoding and unicode_errors options are deprecated.

  In case of packer, use UTF-8 always.  Storing other than UTF-8 is not recommended.

  For backward compatibility, you can use ``use_bin_type=False`` and pack ``bytes``
  object into msgpack raw type.

  In case of unpacker, there is new ``raw`` option.  It is ``True`` by default
  for backward compatibility, but it is changed to ``False`` in near future.
  You can use ``raw=False`` instead of ``encoding='utf-8'``.

  Planned backward incompatible changes
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  When msgpack 1.0, I planning these breaking changes:

  * packer and unpacker: Remove ``encoding`` and ``unicode_errors`` option.
  * packer: Change default of ``use_bin_type`` option from False to True.
  * unpacker: Change default of ``raw`` option from True to False.
  * unpacker: Reduce all ``max_xxx_len`` options for typical usage.
  * unpacker: Remove ``write_bytes`` option from all methods.

  To avoid these breaking changes breaks your application, please:

  * Don't use deprecated options.
  * Pass ``use_bin_type`` and ``raw`` options explicitly.
  * If your application handle large (>1MB) data, specify ``max_xxx_len`` options too.


  Install
  -------

  ::

     $ pip install msgpack

  PyPy
  ^^^^

  msgpack provides a pure Python implementation.  PyPy can use this.

  Windows
  ^^^^^^^

  When you can't use a binary distribution, you need to install Visual Studio
  or Windows SDK on Windows.
  Without extension, using pure Python implementation on CPython runs slowly.

  For Python 2.7, `Microsoft Visual C++ Compiler for Python 2.7 <https://www.microsoft.com/en-us/download/details.aspx?id=44266>`_
  is recommended solution.

  For Python 3.5, `Microsoft Visual Studio 2015 <https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx>`_
  Community Edition or Express Edition can be used to build extension module.


  How to use
  ----------

  One-shot pack & unpack
  ^^^^^^^^^^^^^^^^^^^^^^

  Use ``packb`` for packing and ``unpackb`` for unpacking.
  msgpack provides ``dumps`` and ``loads`` as an alias for compatibility with
  ``json`` and ``pickle``.

  ``pack`` and ``dump`` packs to a file-like object.
  ``unpack`` and ``load`` unpacks from a file-like object.

  .. code-block:: pycon

     >>> import msgpack
     >>> msgpack.packb([1, 2, 3], use_bin_type=True)
     '\x93\x01\x02\x03'
     >>> msgpack.unpackb(_, raw=False)
     [1, 2, 3]

  ``unpack`` unpacks msgpack's array to Python's list, but can also unpack to tuple:

  .. code-block:: pycon

     >>> msgpack.unpackb(b'\x93\x01\x02\x03', use_list=False, raw=False)
     (1, 2, 3)

  You should always specify the ``use_list`` keyword argument for backward compatibility.
  See performance issues relating to `use_list option`_ below.

  Read the docstring for other options.


  Streaming unpacking
  ^^^^^^^^^^^^^^^^^^^

  ``Unpacker`` is a "streaming unpacker". It unpacks multiple objects from one
  stream (or from bytes provided through its ``feed`` method).

  .. code-block:: python

     import msgpack
     from io import BytesIO

     buf = BytesIO()
     for i in range(100):
        buf.write(msgpack.packb(i, use_bin_type=True))

     buf.seek(0)

     unpacker = msgpack.Unpacker(buf, raw=False)
     for unpacked in unpacker:
         print(unpacked)


  Packing/unpacking of custom data type
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  It is also possible to pack/unpack custom data types. Here is an example for
  ``datetime.datetime``.

  .. code-block:: python

      import datetime
      import msgpack

      useful_dict = {
          "id": 1,
          "created": datetime.datetime.now(),
      }

      def decode_datetime(obj):
          if b'__datetime__' in obj:
              obj = datetime.datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%SOURCE.%f")
          return obj

      def encode_datetime(obj):
          if isinstance(obj, datetime.datetime):
              return {'__datetime__': True, 'as_str': obj.strftime("%Y%m%dT%H:%M:%SOURCE.%f")}
          return obj


      packed_dict = msgpack.packb(useful_dict, default=encode_datetime, use_bin_type=True)
      this_dict_again = msgpack.unpackb(packed_dict, object_hook=decode_datetime, raw=False)

  ``Unpacker``'s ``object_hook`` callback receives a dict; the
  ``object_pairs_hook`` callback may instead be used to receive a list of
  key-value pairs.


  Extended types
  ^^^^^^^^^^^^^^

  It is also possible to pack/unpack custom data types using the **ext** type.

  .. code-block:: pycon

      >>> import msgpack
      >>> import array
      >>> def default(obj):
      ...     if isinstance(obj, array.array) and obj.typecode == 'd':
      ...         return msgpack.ExtType(42, obj.tostring())
      ...     raise TypeError("Unknown type: %r" % (obj,))
      ...
      >>> def ext_hook(code, data):
      ...     if code == 42:
      ...         a = array.array('d')
      ...         a.fromstring(data)
      ...         return a
      ...     return ExtType(code, data)
      ...
      >>> data = array.array('d', [1.2, 3.4])
      >>> packed = msgpack.packb(data, default=default, use_bin_type=True)
      >>> unpacked = msgpack.unpackb(packed, ext_hook=ext_hook, raw=False)
      >>> data == unpacked
      True


  Advanced unpacking control
  ^^^^^^^^^^^^^^^^^^^^^^^^^^

  As an alternative to iteration, ``Unpacker`` objects provide ``unpack``,
  ``skip``, ``read_array_header`` and ``read_map_header`` methods. The former two
  read an entire message from the stream, respectively de-serialising and returning
  the result, or ignoring it. The latter two methods return the number of elements
  in the upcoming container, so that each element in an array, or key-value pair
  in a map, can be unpacked or skipped individually.

  Each of these methods may optionally write the packed data it reads to a
  callback function:

  .. code-block:: python

      from io import BytesIO

      def distribute(unpacker, get_worker):
          nelems = unpacker.read_map_header()
          for i in range(nelems):
              
              key = unpacker.unpack()
              worker = get_worker(key)

              
              bytestream = BytesIO()
              unpacker.skip(bytestream.write)
              worker.send(bytestream.getvalue())


  Notes
  -----

  string and binary type
  ^^^^^^^^^^^^^^^^^^^^^^

  Early versions of msgpack didn't distinguish string and binary types (like Python 1).
  The type for representing both string and binary types was named **raw**.

  For backward compatibility reasons, msgpack-python will still default all
  strings to byte strings, unless you specify the ``use_bin_type=True`` option in
  the packer. If you do so, it will use a non-standard type called **bin** to
  serialize byte arrays, and **raw** becomes to mean **str**. If you want to
  distinguish **bin** and **raw** in the unpacker, specify ``raw=False``.

  Note that Python 2 defaults to byte-arrays over Unicode strings:

  .. code-block:: pycon

      >>> import msgpack
      >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs']))
      ['spam', 'eggs']
      >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=True),
                          raw=False)
      ['spam', u'eggs']

  This is the same code in Python 3 (same behaviour, but Python 3 has a
  different default):

  .. code-block:: pycon

      >>> import msgpack
      >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs']))
      [b'spam', b'eggs']
      >>> msgpack.unpackb(msgpack.packb([b'spam', u'eggs'], use_bin_type=True),
                          raw=False)
      [b'spam', 'eggs']


  ext type
  ^^^^^^^^

  To use the **ext** type, pass ``msgpack.ExtType`` object to packer.

  .. code-block:: pycon

      >>> import msgpack
      >>> packed = msgpack.packb(msgpack.ExtType(42, b'xyzzy'))
      >>> msgpack.unpackb(packed)
      ExtType(code=42, data='xyzzy')

  You can use it with ``default`` and ``ext_hook``. See below.


  Note about performance
  ----------------------

  GC
  ^^

  CPython's GC starts when growing allocated object.
  This means unpacking may cause useless GC.
  You can use ``gc.disable()`` when unpacking large message.

  use_list option
  ^^^^^^^^^^^^^^^

  List is the default sequence type of Python.
  But tuple is lighter than list.
  You can use ``use_list=False`` while unpacking when performance is important.

  Python's dict can't use list as key and MessagePack allows array for key of mapping.
  ``use_list=False`` allows unpacking such message.
  Another way to unpacking such object is using ``object_pairs_hook``.


  Development
  -----------

  Test
  ^^^^

  MessagePack uses `pytest` for testing.
  Run test with following command:

      $ make test


  ..
      vim: filetype=rst


pkgId: 427295b4f209cb3caf1cccef8cf1a398e4c7a2af9f3b0514cbde90bfa49a27a8
name: rh-python36-msgpack-debuginfo
arch: x86_64
version: 0.6.2
epoch: 0
release: 1
summary: Debug information for package rh-python36-msgpack
url: https://msgpack.org/
rpm_license: Apache 2.0
rpm_vendor: INADA Naoki <songofacandy@gmail.com>
rpm_group: Development/Debug
rpm_buildhost: ce2bb1070afd42ba8fd723a3915978f3
rpm_sourcerpm: rh-python36-msgpack-0.6.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387012-rh-python36-msgpack/rh-python36-msgpack-debuginfo-0.6.2-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-msgpack.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: f2a546677fc6587f88f97dfb4f2c370177a1bb1f8ada2f5ab1ab88e2a293a6e3
name: rh-python36-msgpack-python-debuginfo
arch: x86_64
version: 0.5.6
epoch: 0
release: 1
summary: Debug information for package rh-python36-msgpack-python
url: http://msgpack.org/
rpm_license: Apache 2.0
rpm_vendor: INADA Naoki <songofacandy@gmail.com>
rpm_group: Development/Debug
rpm_buildhost: 2ab7fd07cf224e9cbfa222dcafd9f310
rpm_sourcerpm: rh-python36-msgpack-python-0.5.6-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387065-rh-python36-msgpack-python/rh-python36-msgpack-python-debuginfo-0.5.6-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-msgpack-python.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: c27d6b6d467c23959c6c0e284d67308b4dbd6407f2ae5aac75cbb77ba85f82c0
name: rh-python36-msrest
arch: noarch
version: 0.6.11
epoch: 0
release: 1
summary: AutoRest swagger generator Python client runtime.
url: https://github.com/Azure/msrest-for-python
rpm_license: MIT License
rpm_vendor: Microsoft Corporation <UNKNOWN>
rpm_group: Development/Libraries
rpm_buildhost: 3d266c7ee6314b7195371feaea3211ab
rpm_sourcerpm: rh-python36-msrest-0.6.11-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387187-rh-python36-msrest/rh-python36-msrest-0.6.11-1.noarch.rpm
checksum_type: sha256
description:
  AutoRest: Python Client Runtime
  ===============================

  .. image:: https://travis-ci.org/Azure/msrest-for-python.svg?branch=master
   :target: https://travis-ci.org/Azure/msrest-for-python

  .. image:: https://codecov.io/gh/azure/msrest-for-python/branch/master/graph/badge.svg
   :target: https://codecov.io/gh/azure/msrest-for-python

  Installation
  ------------

  To install:

  .. code-block:: bash

      $ pip install msrest


  Release History
  ---------------

  2018-04-30 Version 0.4.29
  +++++++++++++++++++++++++

  - Improve `SDKClient.__exit__` to take exc_details as optional parameters and not required

  2018-04-18 Version 0.4.28
  +++++++++++++++++++++++++

  **Features**

  - msrest is now able to keep the "requests.Session" alive for performance. To activate this behavior:

    - Use the final Client as a context manager (requires generation with Autorest.Python 3.0.50 at least)
    - Use `client.config.keep_alive = True` and `client.close()` (requires generation with Autorest.Python 3.0.50 at least)
    - Use `client.config.keep_alive = True` and client._client.close() (not recommended, but available in old releases of SDK)

  - All Authentication classes now define `signed_session` and `refresh_session` with an optional `session` parameter.
    To take benefits of the session improvement, a subclass of Authentication *MUST* add this optional parameter
    and use it if it's not `None`:

       def signed_session(self, session=None):
           session = session or requests.Session()

           

  2018-03-07 Version 0.4.27
  +++++++++++++++++++++++++

  **Features**

  - Disable HTTP log by default (security), add `enable_http_log` to restore it #86

  **BugFixes**

  - Fix incorrect date parsing if ms precision is over 6 digits #82

  2018-01-30 Version 0.4.26
  +++++++++++++++++++++++++

  **Features**

  - Add TopicCredentials for EventGrid client

  **Bugfixes**

  - Fix minimal dependency of isodate
  - Fix serialisation from dict if datetime provided

  2018-01-08 Version 0.4.25
  +++++++++++++++++++++++++

  **Features**

  - Add LROPoller class. This is a customizable LRO engine.
    This is the poller engine of Autorest.Python 3.0, and is not used by code generated by previous Autorest version.

  2018-01-03 Version 0.4.24
  +++++++++++++++++++++++++

  **Bugfixes**

  - Date parsing is now compliant with Autorest / Swagger 2.0 specification (less lenient)

  **Internal optimisation**

  - Call that does not return a streamable object are now executed in requests stream mode False (was True whatever the type of the call).
    This should reduce the number of leaked opened session and allow urllib3 to manage connection pooling more efficiently.
    Only clients generated with Autorest.Python >= 2.1.31 (not impacted otherwise, fully backward compatible)

  2017-12-21 Version 0.4.23
  +++++++++++++++++++++++++

  **Bugfixes**

  - Accept to deserialize enum of different type if content string match #75
  - Stop failing on deserialization if enum string is unkwon. Return the string instead.

  **Features**

  - Model now accept kwargs in constructor for future kwargs models

  2017-12-15 Version 0.4.22
  +++++++++++++++++++++++++

  **Bugfixes**

  - Do not validate additional_properties #73
  - Improve validation error if expected type is dict, but actual type is not #73

  2017-12-14 Version 0.4.21
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix additional_properties if Swagger was flatten #72

  2017-12-13 Version 0.4.20
  +++++++++++++++++++++++++

  **Features**

  - Add support for additional_properties

    - By default, all additional_properties are kept.
    - Additional properties are sent to the server only if it was specified in the Swagger,
      or if "enable_additional_properties_sending" is called on the model we want it.
      This is a class method that enables it for all instance of this model.

  2017-11-20 Version 0.4.19
  +++++++++++++++++++++++++

  **Features**

  - The interpretation of Swagger 2.0 "discriminator" is now lenient. This means for these two scenarios:

    - Discriminator value is missing from the received payload
    - Discriminator value is not defined in the Swagger

    Instead of failing with an exception, this now returns the base type for this "discriminator".

    Note that this is not a contradiction of the Swagger 2.0 spec, that specifies
    "validation SHOULD fail [...] there may exist valid reasons in particular circumstances to ignore a particular item,
    but the full implications must be understood and carefully weighed before choosing a different course."

    This cannot be configured for now and is the new default behvaior, but can be in the future if needed.

  **Bugfixes**

  - Optional formdata parameters were raising an exception (#65)
  - "application/x-www-form-urlencoded" form was sent using "multipart/form-data".
    This causes problems if the server does not support "multipart/form-data" (#66)

  2017-10-26 Version 0.4.18
  +++++++++++++++++++++++++

  **Features**

  - Add ApiKeyCredentials class. This can be used to support OpenAPI ApiKey feature.
  - Add CognitiveServicesAuthentication class. Pre-declared ApiKeyCredentials class for Cognitive Services.

  2017-10-12 Version 0.4.17
  +++++++++++++++++++++++++

  **Features**

  This make Authentication classes more consistent:

  - OAuthTokenAuthentication is now a subclass of BasicTokenAuthentication (was Authentication)
  - BasicTokenAuthentication has now a "set_token" methods that does nothing.

  This allows test like "isintance(o, BasicTokenAuthentication)" to be guaranted that the following attributes exists:

  - token
  - set_token()
  - signed_session()

  This means for users of "msrestazure", that they are guaranted that all AD classes somehow inherits from "BasicTokenAuthentication"

  2017-10-05 Version 0.4.16
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix regression: accept "set<str>" as a valid "[str]" (#60)

  2017-09-28 Version 0.4.15
  +++++++++++++++++++++++++

  **Bugfixes**

  - Always log response body (#16)
  - Improved exception message if error JSON is Odata v4 (#55)
  - Refuse "str" as a valid "[str]" type (#41)
  - Better exception handling if input from server is not JSON valid

  **Features**

  - Add Configuration.session_configuration_callback to customize the requests.Session if necessary (#52)
  - Add a flag to Serializer to disable client-side-validation (#51)
  - Remove "import requests" from "exceptions.py" for apps that require fast loading time (#23)

  Thank you to jayden-at-arista for his contribution

  2017-08-23 Version 0.4.14
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix regression introduced in msrest 0.4.12 - dict syntax with enum modeled as string and enum used

  2017-08-22 Version 0.4.13
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix regression introduced in msrest 0.4.12 - dict syntax using isodate.Duration (#42)

  2017-08-21 Version 0.4.12
  +++++++++++++++++++++++++

  **Features**

  - Input is now more lenient
  - Model have a "validate" method to check content constraints
  - Model have now 4 new methods:

    - "serialize" that gives the RestAPI that will be sent
    - "as_dict" that returns a dict version of the Model. Callbacks are available.
    - "deserialize" the parses the RestAPI JSON into a Model
    - "from_dict" that parses several dict syntax into a Model. Callbacks are available.

  More details and examples in the Wiki article on Github:
  https://github.com/Azure/msrest-for-python/wiki/msrest-0.4.12---Serialization-change

  **Bugfixes**

  - Better Enum checking (#38)

  2017-06-21 Version 0.4.11
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix incorrect dependency to "requests" 2.14.x, instead of 2.x meant in 0.4.8

  2017-06-15 Version 0.4.10
  +++++++++++++++++++++++++

  **Features**

  - Add requests hooks to configuration

  2017-06-08 Version 0.4.9
  ++++++++++++++++++++++++

  **Bugfixes**

  - Accept "null" value for paging array as an empty list and do not raise (#30)

  2017-05-22 Version 0.4.8
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fix random "pool is closed" error (#29)
  - Fix requests dependency to version 2.x, since version 3.x is annunced to be breaking.

  2017-04-04 Version 0.4.7
  ++++++++++++++++++++++++

  **BugFixes**

  - Refactor paging #22:

     - "next" is renamed "advance_page" and "next" returns only 1 element (Python 2 expected behavior)
     - paging objects are now real generator and support the "next()" built-in function without need for "iter()"

  - Raise accurate DeserialisationError on incorrect RestAPI discriminator usage #27
  - Fix discriminator usage of the base class name #27
  - Remove default mutable arguments in Clients #20
  - Fix object comparison in some scenarios #24

  2017-03-06 Version 0.4.6
  ++++++++++++++++++++++++

  **Bugfixes**

  - Allow Model sub-classes to be serialized if type is "object"

  2017-02-13 Version 0.4.5
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fix polymorphic deserialization #11
  - Fix regexp validation if '\\w' is used in Python 2.7 #13
  - Fix dict deserialization if keys are unicode in Python 2.7

  **Improvements**

  - Add polymorphic serialisation from dict objects
  - Remove chardet and use HTTP charset declaration (fallback to utf8)

  2016-09-14 Version 0.4.4
  ++++++++++++++++++++++++

  **Bugfixes**

  - Remove paging URL validation, part of fix https://github.com/Azure/autorest/pull/1420

  **Disclaimer**

  In order to get paging fixes for impacted clients, you need this package and Autorest > 0.17.0 Nightly 20160913

  2016-09-01 Version 0.4.3
  ++++++++++++++++++++++++

  **Bugfixes**

  - Better exception message (https://github.com/Azure/autorest/pull/1300)

  2016-08-15 Version 0.4.2
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fix serialization if "object" type contains None (https://github.com/Azure/autorest/issues/1353)

  2016-08-08 Version 0.4.1
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fix compatibility issues with requests 2.11.0 (https://github.com/Azure/autorest/issues/1337)
  - Allow url of ClientRequest to have parameters (https://github.com/Azure/autorest/issues/1217)

  2016-05-25 Version 0.4.0
  ++++++++++++++++++++++++

  This version has no bug fixes, but implements new features of Autorest:
  - Base64 url type
  - unixtime type
  - x-ms-enum modelAsString flag

  **Behaviour changes**

  - Add Platform information in UserAgent
  - Needs Autorest > 0.17.0 Nightly 20160525

  2016-04-26 Version 0.3.0
  ++++++++++++++++++++++++

  **Bugfixes**

  - Read only values are no longer in __init__ or sent to the server (https://github.com/Azure/autorest/pull/959)
  - Useless kwarg removed

  **Behaviour changes**

  - Needs Autorest > 0.16.0 Nightly 20160426


  2016-03-25 Version 0.2.0
  ++++++++++++++++++++++++

  **Bugfixes**

  - Manage integer enum values (https://github.com/Azure/autorest/pull/879)
  - Add missing application/json Accept HTTP header (https://github.com/Azure/azure-sdk-for-python/issues/553)

  **Behaviour changes**

  - Needs Autorest > 0.16.0 Nightly 20160324


  2016-03-21 Version 0.1.3
  ++++++++++++++++++++++++

  **Bugfixes**

  - Deserialisation of generic resource if null in JSON (https://github.com/Azure/azure-sdk-for-python/issues/544)


  2016-03-14 Version 0.1.2
  ++++++++++++++++++++++++

  **Bugfixes**

  - urllib3 side effect (https://github.com/Azure/autorest/issues/824)


  2016-03-04 Version 0.1.1
  ++++++++++++++++++++++++

  **Bugfixes**

  - Source package corrupted in Pypi (https://github.com/Azure/autorest/issues/799)

  2016-03-04 Version 0.1.0
  +++++++++++++++++++++++++

  **Behavioural Changes**

  - Removed custom logging set up and configuration. All loggers are now children of the root logger 'msrest' with no pre-defined configurations.
  - Replaced _required attribute in Model class with more extensive _validation dict.

  **Improvement**

  - Removed hierarchy scanning for attribute maps from base Model class - relies on generator to populate attribute
    maps according to hierarchy.
  - Base class Paged now inherits from collections.Iterable.
  - Data validation during serialization using custom parameters (e.g. max, min etc).
  - Added ValidationError to be raised if invalid data encountered during serialization.

  2016-02-29 Version 0.0.3
  ++++++++++++++++++++++++

  **Bugfixes**

  - Source package corrupted in Pypi (https://github.com/Azure/autorest/issues/718)

  2016-02-19 Version 0.0.2
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fixed bug in exception logging before logger configured.

  2016-02-19 Version 0.0.1
  ++++++++++++++++++++++++

  - Initial release.


pkgId: 1f4cb4ff6dcfd9b2a228df59217c6f4b029b5f62c066e921a16e1083d8c880a8
name: rh-python36-msrestazure
arch: noarch
version: 0.6.3
epoch: 0
release: 1
summary: AutoRest swagger generator Python client runtime. Azure-specific module.
url: https://github.com/Azure/msrestazure-for-python
rpm_license: MIT License
rpm_vendor: Microsoft Corporation <azpysdkhelp@microsoft.com>
rpm_group: Development/Libraries
rpm_buildhost: a34c01c2e892441fa34da0db98623222
rpm_sourcerpm: rh-python36-msrestazure-0.6.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387202-rh-python36-msrestazure/rh-python36-msrestazure-0.6.3-1.noarch.rpm
checksum_type: sha256
description:
  AutoRest: Python Client Runtime - Azure Module
  ===============================================

  .. image:: https://travis-ci.org/Azure/msrestazure-for-python.svg?branch=master
   :target: https://travis-ci.org/Azure/msrestazure-for-python

  .. image:: https://codecov.io/gh/azure/msrestazure-for-python/branch/master/graph/badge.svg
   :target: https://codecov.io/gh/azure/msrestazure-for-python

  Installation
  ------------

  To install:

  .. code-block:: bash

      $ pip install msrestazure


  Release History
  ---------------

  2018-05-17 Version 0.4.31
  +++++++++++++++++++++++++

  **Features**

  - Improve MSI for VM token polling algorithm

  2018-05-16 Version 0.4.30
  +++++++++++++++++++++++++

  **Features**

  - Allow ADAL 0.5.0 to 2.0.0 excluded as valid ADAL dependency

  2018-04-30 Version 0.4.29
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix refresh Token on `AADTokenCredentials` (was broken in 0.4.27)
  - Now `UserPasswordCredentials` correctly use the refreshToken, and not user/password to refresh the session (was broken in 0.4.27)
  - Bring back `keyring`, with minimal dependency 12.0.2 that fixes the installation problem on old Python

  2018-04-23 Version 0.4.28
  +++++++++++++++++++++++++

  **Disclaimer**

  Do to some stability issues with "keyring" dependency that highly change from one system to another,
  this package is no longer a dependency of "msrestazure".
  If you were using the secured token cache of `ServicePrincipalCredentials` and `UserPassCredentials`,
  the feature is still available, but you need to install manually "keyring". The functionnality will activate automatically.

  2018-04-18 Version 0.4.27
  +++++++++++++++++++++++++

  **Features**

  - Implements new features of msrest 0.4.28 on session improvement. See msrest ChangeLog for details.

  Update msrest dependency to 0.4.28

  2018-04-17 Version 0.4.26
  +++++++++++++++++++++++++

  **Bugfixes**

  - IMDS/MSI: Retry on more error codes (#87)
  - IMDS/MSI: fix a boundary case on timeout (#86)

  2018-03-29 Version 0.4.25
  +++++++++++++++++++++++++

  **Features**

  - MSIAuthentication now uses IMDS endpoint if available
  - MSIAuthentication can be used in any environment that defines MSI_ENDPOINT env variable

  2018-03-26 Version 0.4.24
  +++++++++++++++++++++++++

  **Bugfix**

  - Fix parse_resource_id() tool to be case-insensitive to keywords when matching #81
  - Add missing baseclass init call for AdalAuthentication #82

  2018-03-19 Version 0.4.23
  +++++++++++++++++++++++++

  **Bugfix**

  - Fix LRO result if POST uses AsyncOperation header (Autorest.Python 3.0 only) #79

  2018-02-27 Version 0.4.22
  +++++++++++++++++++++++++

  **Bugfix**

  - Remove a possible infinite loop with MSIAuthentication #77

  **Disclaimer**

  From this version, MSIAuthentication will fail instantly if you try to get MSI token
  from a VM where the extension is not installed, or not yet ready.
  You need to do your own retry mechanism if you think the extension is provisioning and
  the call might succeed later.
  This behavior is consistent with other Azure SDK implementation of MSI scenarios.

  2018-01-26 Version 0.4.21
  +++++++++++++++++++++++++

  - Update allowed ADAL dependency to 0.5.x

  2018-01-08 Version 0.4.20
  +++++++++++++++++++++++++

  **Features**

  - CloudError now includes the "innererror" attribute to match OData v4 #73
  - Introduces ARMPolling implementation of Azure Resource Management LRO. Requires msrest 0.4.25 (new dependency).
    This is used by code generated with Autorest.Python 3.0, and is not used by code generated by previous Autorest version.
  - Change msrest dependency to ">=0.4.25,<2.0.0" to allow (future) msrest 1.0.0 as compatible dependency.

  Thank you to demyanenko for his contribution.

  2017-12-14 Version 0.4.19
  +++++++++++++++++++++++++

  **Feature**

  * Improve MSIAuthentication to support User Assigned Identity #70

  **Bugfixes**

  * Fix session obj for cloudmetadata endpoint #67
  * Fix authentication resource node for AzureSatck #65
  * Better detection of AppService with MSIAuthentication #70

  2017-12-01 Version 0.4.18
  +++++++++++++++++++++++++

  **Bugfixes**

  - get_cloud_from_metadata_endpoint incorrect on AzureStack #62
  - get_cloud_from_metadata_endpoint certificate issue #61

  2017-11-22 Version 0.4.17
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix AttributeError if error JSON from ARM does not follow ODatav4 (as it should)

  2017-10-31 Version 0.4.16
  +++++++++++++++++++++++++

  **Bugfixes**

  - Fix AttributeError if input JSON is not a dict (#54)

  2017-10-13 Version 0.4.15
  +++++++++++++++++++++++++

  **Features**

  - Add support for WebApp/Functions in MSIAuthentication classes
  - Add parse_resource_id(), resource_id(), validate_resource_id() to parse ARM ids
  - Retry strategy now n reach 24 seconds (instead of 12 seconds)

  2017-09-11 Version 0.4.14
  +++++++++++++++++++++++++

  **Features**

  - Add Managed Service Integrated (MSI) authentication

  **Bug fix**

  - Fix AdalError handling in some scenarios (#44)

  Thank you to Hexadite-Omer for his contribution

  2017-08-24 Version 0.4.13
  +++++++++++++++++++++++++

  **Features**

  - "keyring" is now completely optional

  2017-08-23 Version 0.4.12
  +++++++++++++++++++++++++

  **Features**

  - add "timeout" to ServicePrincipalCredentials and UserPasswordCredentials
  - Threads created by AzureOperationPoller have now a name prefixed by "AzureOperationPoller" to help identify them

  **Bugfixes**

  - Do not fail if keyring is badly installed
  - Update Azure Gov login endpoint
  - Update metadata ARM endpoint parser

  **Breaking changes**

  - Remove InteractiveCredentials. This class was deprecated and unusable. Use ADAL device code instead.

  2017-06-29 Version 0.4.11
  +++++++++++++++++++++++++

  **Features**

  - Add cloud definitions for public Azure, German Azure, China Azure and Azure Gov
  - Add get_cloud_from_metadata_endpoint to automatically create a Cloud object from an ARM endpoint
  - Add `cloud_environment` to all Credentials objects (except AdalAuthentication)

  **Note**

  - This deprecates "china=True", to be replaced by "cloud_environment=AZURE_CHINA_CLOUD"

  Example:

  .. code:: python

    from msrestazure.azure_cloud import AZURE_CHINA_CLOUD
    from msrestazure.azure_active_directory import UserPassCredentials

    credentials = UserPassCredentials(
        login,
        password,
        cloud_environment=AZURE_CHINA_CLOUD
    )

  `base_url` of SDK client can be pointed to "cloud_environment.endpoints.resource_manager" for basic scenario:

  Example:

  .. code:: python

    from msrestazure.azure_cloud import AZURE_CHINA_CLOUD
    from msrestazure.azure_active_directory import UserPassCredentials
    from azure.mgmt.resource import ResourceManagementClient

    credentials = UserPassCredentials(
        login,
        password,
        cloud_environment=AZURE_CHINA_CLOUD
    )
    client = ResourceManagementClient(
        credentials,
        subscription_id,
        base_url=AZURE_CHINA_CLOUD.endpoints.resource_manager
    )

  Azure Stack connection can be done:

  .. code:: python

    from msrestazure.azure_cloud import get_cloud_from_metadata_endpoint
    from msrestazure.azure_active_directory import UserPassCredentials
    from azure.mgmt.resource import ResourceManagementClient

    mystack_cloud = get_cloud_from_metadata_endpoint("https://myazurestack-arm-endpoint.com")
    credentials = UserPassCredentials(
        login,
        password,
        cloud_environment=mystack_cloud
    )
    client = ResourceManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager
    )


  2017-06-27 Version 0.4.10
  +++++++++++++++++++++++++

  **Bugfixes**

  - Accept PATCH/201 as LRO valid state
  - Close token session on exit (ServicePrincipal and UserPassword credentials)

  2017-06-19 Version 0.4.9
  ++++++++++++++++++++++++

  **Features**

  - Add proxies parameters to ServicePrincipal and UserPassword credentials class #29
  - Add automatic Azure provider registration if needed (requires msrest 0.4.10) #28

  Thank you to likel for his contribution

  2017-05-31 Version 0.4.8
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fix LRO if first call never returns 200, but ends on 201 (#26)
  - FiX LRO AttributeError if timeout is short (#21)

  **Features**

  - Expose a "status()" method in AzureOperationPoller (#18)

  2017-01-23 Version 0.4.7
  ++++++++++++++++++++++++

  **Bugfixes**

  - Adding `accept_language` and `generate_client_request_id` default values

  2016-12-12 Version 0.4.6
  ++++++++++++++++++++++++

  **Bugfixes**

  Refactor Long Running Operation algorithm.

  - There is no breaking changes, however you might need to record again your offline HTTP records
    if you use unittests with VCRpy.
  - Fix a couple of latent bugs

  2016-11-30 Version 0.4.5
  ++++++++++++++++++++++++

  **New features**

  - Add AdalAuthentification class to wrap ADAL library (https://github.com/Azure/msrestazure-for-python/pull/8)

  2016-10-17 Version 0.4.4
  ++++++++++++++++++++++++

  **Bugfixes**

  - More informative and well-formed CloudError exceptions (https://github.com/Azure/autorest/issues/1460)
  - Raise CustomException is defined in Swagger (https://github.com/Azure/autorest/issues/1404)

  2016-09-14 Version 0.4.3
  ++++++++++++++++++++++++

  **Bugfixes**

  - Make AzureOperationPoller thread as daemon (do not block anymore a Ctrl+C) (https://github.com/Azure/autorest/pull/1379)

  2016-09-01 Version 0.4.2
  ++++++++++++++++++++++++

  **Bugfixes**

  - Better exception message (https://github.com/Azure/autorest/pull/1300)

  This version needs msrest >= 0.4.3

  2016-06-08 Version 0.4.1
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fix for LRO PUT operation https://github.com/Azure/autorest/issues/1133

  2016-05-25 Version 0.4.0
  ++++++++++++++++++++++++

  Update msrest dependency to 0.4.0

  **Bugfixes**

  - Fix for several AAD issues https://github.com/Azure/autorest/issues/1055
  - Fix for LRO PATCH bug and refactor https://github.com/Azure/autorest/issues/993

  **Behaviour changes**

  - Needs Autorest > 0.17.0 Nightly 20160525


  2016-04-26 Version 0.3.0
  ++++++++++++++++++++++++

  Update msrest dependency to 0.3.0

  **Bugfixes**

  - Read only values are no longer in __init__ or sent to the server (https://github.com/Azure/autorest/pull/959)
  - Useless kwarg removed

  **Behaviour changes**

  - Needs Autorest > 0.16.0 Nightly 20160426


  2016-03-31 Version 0.2.1
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fix AzurePollerOperation if Swagger defines provisioning status as enum type (https://github.com/Azure/autorest/pull/892)


  2016-03-25 Version 0.2.0
  ++++++++++++++++++++++++

  Update msrest dependency to 0.2.0

  **Behaviour change**

  - async methods called with raw=True don't return anymore AzureOperationPoller but ClientRawResponse
  - Needs Autorest > 0.16.0 Nightly 20160324


  2016-03-21 Version 0.1.2
  ++++++++++++++++++++++++

  Update msrest dependency to 0.1.3

  **Bugfixes**

  - AzureOperationPoller.wait() failed to raise exception if query error (https://github.com/Azure/autorest/pull/856)


  2016-03-04 Version 0.1.1
  ++++++++++++++++++++++++

  **Bugfixes**

  - Source package corrupted in Pypi (https://github.com/Azure/autorest/issues/799)

  2016-03-04 Version 0.1.0
  ++++++++++++++++++++++++

  **Behaviour change**

  - Replaced _required attribute in CloudErrorData class with _validation dict.

  2016-02-29 Version 0.0.2
  ++++++++++++++++++++++++

  **Bugfixes**

  - Fixed AAD bug to include connection verification in UserPassCredentials. (https://github.com/Azure/autorest/pull/725)
  - Source package corrupted in Pypi (https://github.com/Azure/autorest/issues/718)

  2016-02-19 Version 0.0.1
  ++++++++++++++++++++++++

  - Initial release.


pkgId: 13ad46c50bdf981711594faa4095598a254dd93acc7d7f221f9ccb5d10ac5c9b
name: rh-python36-netifaces
arch: src
version: 0.10.9
epoch: 0
release: 1
summary: Portable network interface information.
url: https://bitbucket.org/al45tair/netifaces
rpm_license: MIT License
rpm_vendor: Alastair Houghton <alastair@alastairs-place.net>
rpm_group: Development/Libraries
rpm_buildhost: af92ca7e68cb4d2c92ecd4e209dbf669
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387203-rh-python36-netifaces/rh-python36-netifaces-0.10.9-1.src.rpm
checksum_type: sha256
description:
  netifaces 0.10.6
  ================

  .. image:: https://drone.io/bitbucket.org/al45tair/netifaces/status.png
     :target: https://drone.io/bitbucket.org/al45tair/netifaces/latest
     :alt: Build Status

  1. What is this?
  ----------------

  It's been annoying me for some time that there's no easy way to get the
  address(es) of the machine's network interfaces from Python.  There is
  a good reason for this difficulty, which is that it is virtually impossible
  to do so in a portable manner.  However, it seems to me that there should
  be a package you can easy_install that will take care of working out the
  details of doing so on the machine you're using, then you can get on with
  writing Python code without concerning yourself with the nitty gritty of
  system-dependent low-level networking APIs.

  This package attempts to solve that problem.

  2. How do I use it?
  -------------------

  First you need to install it, which you can do by typing::

    tar xvzf netifaces-0.10.6.tar.gz
    cd netifaces-0.10.6
    python setup.py install

  **Note that you will need the relevant developer tools for your platform**,
  as netifaces is written in C and installing this way will compile the extension.

  Once that's done, you'll need to start Python and do something like the
  following::

  >>> import netifaces

  Then if you enter

  >>> netifaces.interfaces()
  ['lo0', 'gif0', 'stf0', 'en0', 'en1', 'fw0']

  you'll see the list of interface identifiers for your machine.

  You can ask for the addresses of a particular interface by doing

  >>> netifaces.ifaddresses('lo0')
  {18: [{'addr': ''}], 2: [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}], 30: [{'peer': '::1', 'netmask': 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', 'addr': '::1'}, {'peer': '', 'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::1%lo0'}]}

  Hmmmm.  That result looks a bit cryptic; let's break it apart and explain
  what each piece means.  It returned a dictionary, so let's look there first::

    { 18: [...], 2: [...], 30: [...] }

  Each of the numbers refers to a particular address family.  In this case, we
  have three address families listed; on my system, 18 is ``AF_LINK`` (which means
  the link layer interface, e.g. Ethernet), 2 is ``AF_INET`` (normal Internet
  addresses), and 30 is ``AF_INET6`` (IPv6).

  But wait!  Don't use these numbers in your code.  The numeric values here are
  system dependent; fortunately, I thought of that when writing netifaces, so
  the module declares a range of values that you might need.  e.g.

  >>> netifaces.AF_LINK
  18

  Again, on your system, the number may be different.

  So, what we've established is that the dictionary that's returned has one
  entry for each address family for which this interface has an address.  Let's
  take a look at the ``AF_INET`` addresses now:

  >>> addrs = netifaces.ifaddresses('lo0')
  >>> addrs[netifaces.AF_INET]
  [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]

  You might be wondering why this value is a list.  The reason is that it's
  possible for an interface to have more than one address, even within the
  same family.  I'll say that again: *you can have more than one address of
  the same type associated with each interface*.

  *Asking for "the" address of a particular interface doesn't make sense.*

  Right, so, we can see that this particular interface only has one address,
  and, because it's a loopback interface, it's point-to-point and therefore
  has a *peer* address rather than a broadcast address.

  Let's look at a more interesting interface.

  >>> addrs = netifaces.ifaddresses('en0')
  >>> addrs[netifaces.AF_INET]
  [{'broadcast': '10.15.255.255', 'netmask': '255.240.0.0', 'addr': '10.0.1.4'}, {'broadcast': '192.168.0.255', 'addr': '192.168.0.47'}]

  This interface has two addresses (see, I told you...)  Both of them are
  regular IPv4 addresses, although in one case the netmask has been changed
  from its default.  The netmask *may not* appear on your system if it's set
  to the default for the address range.

  Because this interface isn't point-to-point, it also has broadcast addresses.

  Now, say we want, instead of the IP addresses, to get the MAC address; that
  is, the hardware address of the Ethernet adapter running this interface.  We
  can do

  >>> addrs[netifaces.AF_LINK]
  [{'addr': '00:12:34:56:78:9a'}]

  Note that this may not be available on platforms without getifaddrs(), unless
  they happen to implement ``SIOCGIFHWADDR``.  Note also that you just get the
  address; it's unlikely that you'll see anything else with an ``AF_LINK`` address.
  Oh, and don't assume that all ``AF_LINK`` addresses are Ethernet; you might, for
  instance, be on a Mac, in which case:

  >>> addrs = netifaces.ifaddresses('fw0')
  >>> addrs[netifaces.AF_LINK]
  [{'addr': '00:12:34:56:78:9a:bc:de'}]

  No, that isn't an exceptionally long Ethernet MAC address---it's a FireWire
  address.

  As of version 0.10.0, you can also obtain a list of gateways on your
  machine:

  >>> netifaces.gateways()
  {2: [('10.0.1.1', 'en0', True), ('10.2.1.1', 'en1', False)], 30: [('fe80::1', 'en0', True)], 'default': { 2: ('10.0.1.1', 'en0'), 30: ('fe80::1', 'en0') }}

  This dictionary is keyed on address family---in this case, ``AF_INET``---and
  each entry is a list of gateways as ``(address, interface, is_default)`` tuples.
  Notice that here we have two separate gateways for IPv4 (``AF_INET``); some
  operating systems support configurations like this and can either route packets
  based on their source, or based on administratively configured routing tables.

  For convenience, we also allow you to index the dictionary with the special
  value ``'default'``, which returns a dictionary mapping address families to the
  default gateway in each case.  Thus you can get the default IPv4 gateway with

  >>> gws = netifaces.gateways()
  >>> gws['default'][netifaces.AF_INET]
  ('10.0.1.1', 'en0')

  Do note that there may be no default gateway for any given address family;
  this is currently very common for IPv6 and much less common for IPv4 but it
  can happen even for ``AF_INET``.

  BTW, if you're trying to configure your machine to have multiple gateways for
  the same address family, it's a very good idea to check the documentation for
  your operating system *very* carefully, as some systems become extremely
  confused or route packets in a non-obvious manner.

  I'm very interested in hearing from anyone (on any platform) for whom the
  ``gateways()`` method doesn't produce the expected results.  It's quite
  complicated extracting this information from the operating system (whichever
  operating system we're talking about), and so I expect there's at least one
  system out there where this just won't work.

  3. This is great!  What platforms does it work on?
  --------------------------------------------------

  It gets regular testing on OS X, Linux and Windows.  It has also been used
  successfully on Solaris, and it's expected to work properly on other UNIX-like
  systems as well.  If you are running something that is not supported, and
  wish to contribute a patch, please use BitBucket to send a pull request.

  4. What license is this under?
  ------------------------------

  It's an MIT-style license.  Here goes:

  Copyright (c) 2007-2017 Alastair Houghton

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.

  5. Why the jump to 0.10.0?
  --------------------------

  Because someone released a fork of netifaces with the version 0.9.0.
  Hopefully skipping the version number should remove any confusion.  In
  addition starting with 0.10.0 Python 3 is now supported and other
  features/bugfixes have been included as well.  See the CHANGELOG for a
  more complete list of changes.


pkgId: 09dfd539f86a57c6db6857a5afbdc4a0e08b104d2589720ad0fff4416d7fddcb
name: rh-python36-netifaces-debuginfo
arch: x86_64
version: 0.10.9
epoch: 0
release: 1
summary: Debug information for package rh-python36-netifaces
url: https://bitbucket.org/al45tair/netifaces
rpm_license: MIT License
rpm_vendor: Alastair Houghton <alastair@alastairs-place.net>
rpm_group: Development/Debug
rpm_buildhost: 0634f350be974f12b77e9dd0d15958ee
rpm_sourcerpm: rh-python36-netifaces-0.10.9-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387203-rh-python36-netifaces/rh-python36-netifaces-debuginfo-0.10.9-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-netifaces.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: fb643cdc88d36f124cad72e04a0a34754fd9866620fed90a0842d3d9b2d409f3
name: rh-python36-oauthlib
arch: noarch
version: 3.1.0
epoch: 0
release: 1
summary: A generic, spec-compliant, thorough implementation of the OAuth request-signing logic
url: https://github.com/oauthlib/oauthlib
rpm_license: BSD
rpm_vendor: Ib Lundgren <ib.lundgren@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 76389ef8bb574aa58e400202fa2a0916
rpm_sourcerpm: rh-python36-oauthlib-3.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387153-rh-python36-oauthlib/rh-python36-oauthlib-3.1.0-1.noarch.rpm
checksum_type: sha256
description:
  OAuthLib - Python Framework for OAuth1 & OAuth2
  ===============================================

  *A generic, spec-compliant, thorough implementation of the OAuth request-signing
  logic for Python 2.7 and 3.4+.*

  .. image:: https://travis-ci.org/oauthlib/oauthlib.svg?branch=master
    :target: https://travis-ci.org/oauthlib/oauthlib
    :alt: Travis
  .. image:: https://coveralls.io/repos/oauthlib/oauthlib/badge.svg?branch=master
    :target: https://coveralls.io/r/oauthlib/oauthlib
    :alt: Coveralls
  .. image:: https://img.shields.io/pypi/pyversions/oauthlib.svg
    :target: https://pypi.org/project/oauthlib/
    :alt: Download from PyPI
  .. image:: https://img.shields.io/pypi/l/oauthlib.svg
    :target: https://pypi.org/project/oauthlib/
    :alt: License
  .. image:: https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauthlib%2Foauthlib.svg?type=shield
     :target: https://app.fossa.io/projects/git%2Bgithub.com%2Foauthlib%2Foauthlib?ref=badge_shield
     :alt: FOSSA Status
  .. image:: https://img.shields.io/readthedocs/oauthlib.svg
    :target: https://oauthlib.readthedocs.io/en/latest/index.html
    :alt: Read the Docs
  .. image:: https://badges.gitter.im/oauthlib/oauthlib.svg
    :target: https://gitter.im/oauthlib/Lobby
    :alt: Chat on Gitter

  OAuth often seems complicated and difficult-to-implement. There are several
  prominent libraries for handling OAuth requests, but they all suffer from one or
  both of the following:

  1. They predate the `OAuth 1.0 spec`_, AKA RFC 5849.
  2. They predate the `OAuth 2.0 spec`_, AKA RFC 6749.
  3. They assume the usage of a specific HTTP request library.

  .. _`OAuth 1.0 spec`: https://tools.ietf.org/html/rfc5849
  .. _`OAuth 2.0 spec`: https://tools.ietf.org/html/rfc6749

  OAuthLib is a framework which implements the logic of OAuth1 or OAuth2 without
  assuming a specific HTTP request object or web framework. Use it to graft OAuth
  client support onto your favorite HTTP library, or provide support onto your
  favourite web framework. If you're a maintainer of such a library, write a thin
  veneer on top of OAuthLib and get OAuth support for very little effort.


  Documentation
  --------------

  Full documentation is available on `Read the Docs`_. All contributions are very
  welcome! The documentation is still quite sparse, please open an issue for what
  you'd like to know, or discuss it in our `Gitter community`_, or even better, send a
  pull request!

  .. _`Gitter community`: https://gitter.im/oauthlib/Lobby
  .. _`Read the Docs`: https://oauthlib.readthedocs.io/en/latest/index.html

  Interested in making OAuth requests?
  ------------------------------------

  Then you might be more interested in using `requests`_ which has OAuthLib
  powered OAuth support provided by the `requests-oauthlib`_ library.

  .. _`requests`: https://github.com/requests/requests
  .. _`requests-oauthlib`: https://github.com/requests/requests-oauthlib

  Which web frameworks are supported?
  -----------------------------------

  The following packages provide OAuth support using OAuthLib.

  - For Django there is `django-oauth-toolkit`_, which includes `Django REST framework`_ support.
  - For Flask there is `flask-oauthlib`_ and `Flask-Dance`_.
  - For Pyramid there is `pyramid-oauthlib`_.
  - For Bottle there is `bottle-oauthlib`_.

  If you have written an OAuthLib package that supports your favorite framework,
  please open a Pull Request, updating the documentation.

  .. _`django-oauth-toolkit`: https://github.com/evonove/django-oauth-toolkit
  .. _`flask-oauthlib`: https://github.com/lepture/flask-oauthlib
  .. _`Django REST framework`: http://django-rest-framework.org
  .. _`Flask-Dance`: https://github.com/singingwolfboy/flask-dance
  .. _`pyramid-oauthlib`: https://github.com/tilgovi/pyramid-oauthlib
  .. _`bottle-oauthlib`: https://github.com/thomsonreuters/bottle-oauthlib

  Using OAuthLib? Please get in touch!
  ------------------------------------
  Patching OAuth support onto an http request framework? Creating an OAuth
  provider extension for a web framework? Simply using OAuthLib to Get Things Done
  or to learn?

  No matter which we'd love to hear from you in our `Gitter community`_ or if you have
  anything in particular you would like to have, change or comment on don't
  hesitate for a second to send a pull request or open an issue. We might be quite
  busy and therefore slow to reply but we love feedback!

  Chances are you have run into something annoying that you wish there was
  documentation for, if you wish to gain eternal fame and glory, and a drink if we
  have the pleasure to run into eachother, please send a docs pull request =)

  .. _`Gitter community`: https://gitter.im/oauthlib/Lobby

  License
  -------

  OAuthLib is yours to use and abuse according to the terms of the BSD license.
  Check the LICENSE file for full details.

  Credits
  -------

  OAuthLib has been started and maintained several years by Idan Gazit and other
  amazing `AUTHORS`_. Thanks to their wonderful work, the open-source `community`_
  creation has been possible and the project can stay active and reactive to users
  requests.


  .. _`AUTHORS`: https://github.com/oauthlib/oauthlib/blob/master/AUTHORS
  .. _`community`: https://github.com/oauthlib/

  Changelog
  ---------

  *OAuthLib is in active development, with the core of both OAuth1 and OAuth2
  completed, for providers as well as clients.* See `supported features`_ for
  details.

  .. _`supported features`: https://oauthlib.readthedocs.io/en/latest/feature_matrix.html

  For a full changelog see ``CHANGELOG.rst``.


pkgId: 0f9bd6731781385d55adf7b3c9335fcf13ce12115dff08e13cff5617ecb4de99
name: rh-python36-openstacksdk
arch: noarch
version: 0.37.0
epoch: 0
release: 1
summary: An SDK for building applications to work with OpenStack
url: http://developer.openstack.org/sdks/python/openstacksdk/
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-dev@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: 0c39a1841b884fb4b90209f7cebd579e
rpm_sourcerpm: rh-python36-openstacksdk-0.37.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387188-rh-python36-openstacksdk/rh-python36-openstacksdk-0.37.0-1.noarch.rpm
checksum_type: sha256
description:
  openstacksdk
  ============

  openstacksdk is a client library for for building applications to work
  with OpenStack clouds. The project aims to provide a consistent and
  complete set of interactions with OpenStack's many services, along with
  complete documentation, examples, and tools.

  It also contains an abstraction interface layer. Clouds can do many things, but
  there are probably only about 10 of them that most people care about with any
  regularity. If you want to do complicated things, the per-service oriented
  portions of the SDK are for you. However, if what you want is to be able to
  write an application that talks to clouds no matter what crazy choices the
  deployer has made in an attempt to be more hipster than their self-entitled
  narcissist peers, then the Cloud Abstraction layer is for you.

  A Brief History
  ---------------

  .. TODO(shade) This history section should move to the docs. We can put a
     link to the published URL here in the README, but it's too long.

  openstacksdk started its life as three different libraries: shade,
  os-client-config and python-openstacksdk.

  ``shade`` started its life as some code inside of OpenStack Infra's `nodepool`_
  project, and as some code inside of the `Ansible OpenStack Modules`_.
  Ansible had a bunch of different OpenStack related modules, and there was a
  ton of duplicated code. Eventually, between refactoring that duplication into
  an internal library, and adding the logic and features that the OpenStack Infra
  team had developed to run client applications at scale, it turned out that we'd
  written nine-tenths of what we'd need to have a standalone library.

  Because of its background from nodepool, shade contained abstractions to
  work around deployment differences and is resource oriented rather than service
  oriented. This allows a user to think about Security Groups without having to
  know whether Security Groups are provided by Nova or Neutron on a given cloud.
  On the other hand, as an interface that provides an abstraction, it deviates
  from the published OpenStack REST API and adds its own opinions, which may not
  get in the way of more advanced users with specific needs.

  ``os-client-config`` was a library for collecting client configuration for
  using an OpenStack cloud in a consistent and comprehensive manner, which
  introduced the ``clouds.yaml`` file for expressing named cloud configurations.

  ``python-openstacksdk`` was a library that exposed the OpenStack APIs to
  developers in a consistent and predictable manner.

  After a while it became clear that there was value in both the high-level
  layer that contains additional business logic and the lower-level SDK that
  exposes services and their resources faithfully and consistently as Python
  objects.

  Even with both of those layers, it is still beneficial at times to be able to
  make direct REST calls and to do so with the same properly configured
  `Session`_ from `python-requests`_.

  This led to the merge of the three projects.

  The original contents of the shade library have been moved into
  ``openstack.cloud`` and os-client-config has been moved in to
  ``openstack.config``. Future releases of shade will provide a thin
  compatibility layer that subclasses the objects from ``openstack.cloud``
  and provides different argument defaults where needed for compatibility.
  Similarly future releases of os-client-config will provide a compatibility
  layer shim around ``openstack.config``.

  .. _nodepool: https://docs.openstack.org/infra/nodepool/
  .. _Ansible OpenStack Modules: http://docs.ansible.com/ansible/latest/list_of_cloud_modules.html#openstack
  .. _Session: http://docs.python-requests.org/en/master/user/advanced/#session-objects
  .. _python-requests: http://docs.python-requests.org/en/master/

  openstack
  =========

  List servers using objects configured with the ``clouds.yaml`` file:

  .. code-block:: python

      import openstack

      
      openstack.enable_logging(debug=True)

      
      conn = openstack.connect(cloud='mordred')

      for server in conn.compute.servers():
          print(server.to_dict())

  openstack.config
  ================

  ``openstack.config`` will find cloud configuration for as few as 1 clouds and
  as many as you want to put in a config file. It will read environment variables
  and config files, and it also contains some vendor specific default values so
  that you don't have to know extra info to use OpenStack

  * If you have a config file, you will get the clouds listed in it
  * If you have environment variables, you will get a cloud named `envvars`
  * If you have neither, you will get a cloud named `defaults` with base defaults

  Sometimes an example is nice.

  Create a ``clouds.yaml`` file:

  .. code-block:: yaml

       clouds:
        mordred:
          region_name: Dallas
          auth:
            username: 'mordred'
            password: XXXXXXX
            project_name: 'shade'
            auth_url: 'https://identity.example.com'

  Please note: ``openstack.config`` will look for a file called ``clouds.yaml``
  in the following locations:

  * Current Directory
  * ``~/.config/openstack``
  * ``/etc/openstack``

  More information at https://developer.openstack.org/sdks/python/openstacksdk/users/config

  openstack.cloud
  ===============

  Create a server using objects configured with the ``clouds.yaml`` file:

  .. code-block:: python

      import openstack.cloud

      
      openstack.enable_logging(debug=True)

      
      
      conn = openstack.connect(cloud='mordred')

      
      image = conn.create_image(
          'ubuntu-trusty', filename='ubuntu-trusty.qcow2', wait=True)

      
      flavor = conn.get_flavor_by_ram(512)

      
      
      conn.create_server(
          'my-server', image=image, flavor=flavor, wait=True, auto_ip=True)

  Links
  =====

  * `Issue Tracker <https://storyboard.openstack.org/#!/project/760>`_
  * `Code Review <https://review.openstack.org/#/q/status:open+project:openstack/python-openstacksdk,n,z>`_
  * `Documentation <https://developer.openstack.org/sdks/python/openstacksdk/>`_
  * `PyPI <https://pypi.python.org/pypi/python-openstacksdk/>`_
  * `Mailing list <http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev>`_
  * `Bugs <https://bugs.launchpad.net/python-openstacksdk>`_


pkgId: be7f49aac40981124ffb897dc21929abbeb3b52eee47de5649595b48fcb35399
name: rh-python36-os-service-types
arch: noarch
version: 1.7.0
epoch: 0
release: 1
summary: Python library for consuming OpenStack sevice-types-authority data
url: http://www.openstack.org/
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-dev@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: 2af1ce157c1e4be6984d981359cbc5c2
rpm_sourcerpm: rh-python36-os-service-types-1.7.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387205-rh-python36-os-service-types/rh-python36-os-service-types-1.7.0-1.noarch.rpm
checksum_type: sha256
description:
  ================
  os-service-types
  ================

  Python library for consuming OpenStack sevice-types-authority data

  The `OpenStack Service Types Authority`_ contains information about official
  OpenStack services and their historical ``service-type`` aliases.

  The data is in JSON and the latest data should always be used. This simple
  library exists to allow for easy consumption of the data, along with a built-in
  version of the data to use in case network access is for some reason not
  possible and local caching of the fetched data.

  * Free software: Apache license
  * Documentation: http://docs.openstack.org/developer/os-service-types
  * Source: http://git.openstack.org/cgit/openstack/os-service-types
  * Bugs: https://storyboard.openstack.org/#!/project/904

  .. _OpenStack Service Types Authority: https://service-types.openstack.org/


pkgId: 51c7bdb89061f18e05a0c89fb19a8a50ce79457d7c3afff636af1c659ce49044
name: rh-python36-oslo.i18n
arch: noarch
version: 3.23.1
epoch: 0
release: 1
summary: Oslo i18n library
url: https://docs.openstack.org/oslo.i18n/latest
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-discuss@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: a98dba72067f40e0b6876c3e7a44d920
rpm_sourcerpm: rh-python36-oslo.i18n-3.23.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387055-rh-python36-oslo.i18n/rh-python36-oslo.i18n-3.23.1-1.noarch.rpm
checksum_type: sha256
description:
  ========================
  Team and repository tags
  ========================

  .. image:: https://governance.openstack.org/tc/badges/oslo.i18n.svg
      :target: https://governance.openstack.org/tc/reference/tags/index.html

  .. Change things from this point on

  ==================================================
   oslo.i18n -- Oslo Internationalization Utilities
  ==================================================

  .. image:: https://img.shields.io/pypi/v/oslo.i18n.svg
      :target: https://pypi.org/project/oslo.i18n/
      :alt: Latest Version

  .. image:: https://img.shields.io/pypi/dm/oslo.i18n.svg
      :target: https://pypi.org/project/oslo.i18n/
      :alt: Downloads

  The oslo.i18n library contain utilities for working with
  internationalization (i18n) features, especially translation for text
  strings in an application or library.

  * Free software: Apache license
  * Documentation: https://docs.openstack.org/oslo.i18n/latest
  * Source: https://git.openstack.org/cgit/openstack/oslo.i18n
  * Bugs: https://bugs.launchpad.net/oslo.i18n
  * Release notes:  https://docs.openstack.org/releasenotes/oslo.i18n/


pkgId: 7beeb3fc6edbd5c863336efc6c729b55928726a09efa4eec71dbe06508807593
name: rh-python36-oslo.serialization
arch: noarch
version: 2.29.1
epoch: 0
release: 1
summary: Oslo Serialization library
url: https://docs.openstack.org/oslo.serialization/latest/
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-discuss@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: d00a1a1eee994d4da3672bead7e63d33
rpm_sourcerpm: rh-python36-oslo.serialization-2.29.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387043-rh-python36-oslo.serialization/rh-python36-oslo.serialization-2.29.1-1.noarch.rpm
checksum_type: sha256
description:
  ========================
  Team and repository tags
  ========================

  .. image:: https://governance.openstack.org/tc/badges/oslo.serialization.svg
      :target: https://governance.openstack.org/tc/ference/tags/index.html

  .. Change things from this point on

  ===================
   oslo.serialization
  ===================

  .. image:: https://img.shields.io/pypi/v/oslo.serialization.svg
      :target: https://pypi.org/project/oslo.serialization/
      :alt: Latest Version

  .. image:: https://img.shields.io/pypi/dm/oslo.serialization.svg
      :target: https://pypi.org/project/oslo.serialization/
      :alt: Downloads

  The oslo.serialization library provides support for representing objects
  in transmittable and storable formats, such as Base64, JSON and MessagePack.

  * Free software: Apache license
  * Documentation: https://docs.openstack.org/oslo.serialization/latest/
  * Source: https://git.openstack.org/cgit/openstack/oslo.serialization
  * Bugs: https://bugs.launchpad.net/oslo.serialization
  * Release notes: https://docs.openstack.org/releasenotes/oslo.serialization/


pkgId: a454fa14eaf2673da9db5c32f01c45b76fd455532d61a6d3850e6dbda90ed9d3
name: rh-python36-oslo.utils
arch: noarch
version: 3.41.0
epoch: 0
release: 1
summary: Oslo Utility library
url: https://docs.openstack.org/oslo.utils/latest/
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-discuss@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: 34072d70c10148a08801a614e5a1ad7b
rpm_sourcerpm: rh-python36-oslo.utils-3.41.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387032-rh-python36-oslo.utils/rh-python36-oslo.utils-3.41.0-1.noarch.rpm
checksum_type: sha256
description:
  ========================
  Team and repository tags
  ========================

  .. image:: https://governance.openstack.org/tc/badges/oslo.utils.svg
      :target: https://governance.openstack.org/tc/reference/tags/index.html

  .. Change things from this point on

  ==========
  oslo.utils
  ==========

  .. image:: https://img.shields.io/pypi/v/oslo.utils.svg
      :target: https://pypi.org/project/oslo.utils/
      :alt: Latest Version

  .. image:: https://img.shields.io/pypi/dm/oslo.utils.svg
      :target: https://pypi.org/project/oslo.utils/
      :alt: Downloads

  The oslo.utils library provides support for common utility type functions,
  such as encoding, exception handling, string manipulation, and time handling.

  * Free software: Apache license
  * Documentation: https://docs.openstack.org/oslo.utils/latest/
  * Source: https://git.openstack.org/cgit/openstack/oslo.utils
  * Bugs: https://bugs.launchpad.net/oslo.utils
  * Release notes: https://docs.openstack.org/releasenotes/oslo.utils/


pkgId: 0bb87efdba73591edfc184dbb0ac7b9f1b49c7a980fa3b37b91c1f03ffba9981
name: rh-python36-ovirt-engine-sdk-python
arch: src
version: 4.3.0
epoch: 0
release: 1
summary: Python SDK for oVirt Engine API
rpm_license: ASL2
rpm_group: Development/Libraries
rpm_buildhost: c9ef3652021646adbafa6f165893859d
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387233-rh-python36-ovirt-engine-sdk-python/rh-python36-ovirt-engine-sdk-python-4.3.0-1.src.rpm
checksum_type: sha256
description:
  = oVirt Engine API Python SDK

  == Introduction

  This project contains the Python SDK for the oVirt Engine API.

  == Important

  Note that most of the code of this SDK is automatically generated. If
  you just installed the package then you will have everything already,
  but if you downloaded the source then you will need to generate it,
  follow the instructions in the `README.adoc` file of the parent
  directory.

  == Installation

  The SDK can be installed in Fedora 24 and CentOS 7 using the RPM packages
  provided by the oVirt project. To do so install the oVirt release package:

    

  Then install the SDK packages. For Python 2:

    

  For Python 3:

    

  For other operating systems (and also for Fedora and CentOS) you can
  install the SDK using the `pip` command, which will download the source
  from https://pypi.python.org/pypi[PyPI], build and install it.

  The SDK uses http://www.xmlsoft.org[libxml2] for parsing and rendering
  XML. The part of the SDK that interacts with that library is written in
  C. This means that before building you must make sure you have the C
  compiler and the required header and libraries files installed in your
  system. For example, if you are using distributions like Fedora, or
  CentOS:

    
    gcc \
    libxml2-devel \
    python-devel

  For Python 3:

    
    gcc \
    libxml2-devel \
    python3-devel

  If you are using distributions like Debian, or Ubuntu:

    
    gcc \
    libxml2-dev \
    python-dev

  For Python 3:

    
    gcc \
    libxml2-dev \
    python3-dev

  NOTE: The examples above use the `dnf` command, which is the default in
  Fedora 24. In CentOS 7 you may need to use the `yum` command, as `dnf`
  is optional.

  == Usage

  === Packages

  The following are the Python modules that are most frequently needed in
  order to use the SDK:

  ovirtsdk4::

  This is the top level module. It most important element is the
  `Connection` class, as is the mechanism to connect to the server and to
  get the reference to the root of the services tree.
  +
  The `Error` class, is the base exception class that the
  SDK will raise when it needs to report any error.

  For certain kinds of errors there are specific error classes, extending
  the base error class:

  * `AuthError` - Raised when authentication or authorization fail.

  * `ConnectionError` - Raised when the name of the server can't be resolved,
  and when the server is down or unreachable.

  * `NotFoundError` - Raised when the requested object doesn't exist.

  * `TimeoutError` - Raised when an operation times out.

  ovirtsdk4.types::

  This module contains the classes that implement the _types_ used in the
  API. For example, the `ovirtsdk4.types.Vm` Python class is the
  implementation of the virtual machine type. These classes are just
  containers of data, they don't contain any logic.
  +
  Instances of these classes are used as parameters and return values of
  _service methods_. The conversion to/from the underlying representation
  is handled transparently by the SDK.

  ovirtsdk4.services::

  This module contains the classes that implement the _services_ supported
  by the API. For example, the `ovirtsdk4.services.VmsService` Python
  class is the implementation of the service that manages the collection
  of virtual machines of the system.
  +
  Instances of these classes are automatically created by the SDK when a
  service is located. For example, a new instance of the `VmsService`
  class will be automatically created by the SDK when doing the following:
  +
  [source,python]
  ----
  vms_service = connection.system_service().vms_service()
  ----
  +
  Avoid creating instances of these classes manually, as the parameters of
  the constructors, and in general all the methods except the _service
  locators_ and _service methods_ (described later) may change in the
  future.

  There are other modules, like `ovirtsdk4.http`, `ovirtsdk4.readers` and
  `ovirtsdk4.writers`. These are used to implement the HTTP communication,
  and to for XML parsing and rendering. Refrain from using them, as they
  are internal implementation details that may change in the future:
  backwards compatibility isn't guaranteed.

  === Connecting to the server

  To connect to the server import the `ovirtsdk4` module. That will give
  to the `Connection` class. This is the entry point of the SDK, and gives
  you access to the root of the tree of services of the API:

  [source,python]
  ----
  import ovirtsdk4 as sdk


  connection = sdk.Connection(
    url='https://engine.example.com/ovirt-engine/api',
    username='admin@internal',
    password='...',
    ca_file='ca.pem',
  )
  ----

  The connection holds expensive resources, including a pool of HTTP
  connections to the server and an authentication token. It is very
  important to free these resources when they are no longer in use:

  [source,python]
  ----

  connection.close()
  ----

  Once a connection is closed it can't be reused.

  The `ca.pem` file is required when connecting to a server protected
  with TLS. In an usual oVirt installation it will be in
  `/etc/pki/ovirt-engine/ca.pem`. If you don't specify `ca_file`, then
  system wide CA certificate store will be used.

  If something fails when trying to create the connection (authentication
  failure, communication failure, etc) the SDK will raise a
  `ovirtsdk4.Error` exception containing the details.

  === Using _types_

  The classes in the `ovirtsdk4.types` module are pure data containers,
  they don't have any logic or operations. Instances can be created and
  modified at will.

  Creating or modifying one of this instances does *not* have any effect
  in the server side, unless one they are explicitly passed to a call to
  one of the service methods described below. Changes in the server side
  are *not* automatically reflected in the instances that already exist in
  memory.

  The constructors of these classes have multiple optional arguments, one
  for each attribute of the type. This is intended to simplify creation of
  objects using nested calls to multiple constructors. For example, to
  create an instance of a virtual machine, with an specification of the
  cluster and template that it should use, and the memory it should have:

  [source,python]
  ----
  from ovirtsdk4 import types

  vm = types.Vm(
      name='myvm',
      cluster=types.Cluster(
          name='mycluster'
      ),
      template=types.Template(
          name='mytemplate'
      ),
      memory=1073741824
  )
  ----

  Using the constructors in this way is recommended, but not mandatory.
  You can also create the instance with no arguments in the call to the
  constructor, and then populate the object step by step, using the
  setters, or using a mix of both approaches:

  [source,python]
  ----
  vm = types.Vm()
  vm.name = 'myvm'
  vm.cluster = types.Cluster(name='mycluster')
  vm.template = types.Template(name='mytemplate')
  vm.memory=1073741824
  ----

  Attributes that are defined as lists of objects in the specification of
  the API are implemented as Python lists. For example, the
  `custom_properties` attributes of the
  http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm[Vm]
  type is defined as a list of objects of type `CustomProperty`, so when
  using it in the SDK it will be a Python list:

  [source,python]
  ----
  vm = types.Vm(
      name='myvm',
      custom_properties=[
          types.CustomProperty(...),
          types.CustomProperty(...),
          ...
      ]
  )
  ----

  Attributes that are defined as enumerated values in the specification of
  the API are implemented as `enum` in Python, using the native support
  for enums in Python 3, and using the
  https://pypi.python.org/pypi/enum34[enum34] package in Python 2.7. For
  example, the `status` attribute of the `Vm` type is defined using the
  http://ovirt.github.io/ovirt-engine-api-model/master/#types/vm_status[VmStatus]
  enum:

  [source,python]
  ----
  if vm.status == types.VmStatus.DOWN:
      ...
  elif vm.status == types.VmStatus.IMAGE_LOCKED:
      ....
  ----

  NOTE: In the specification of the API the values of enum types appear in
  lower case, because that is what is used in the XML or JSON documents.
  But in Python it is common practice to use upper case for this kind of
  constants, so that is how they are defined in the Python SDK: all upper
  case.

  Reading the attributes of instances of types is done using the
  corresponding properties:

  [source,python]
  ----
  print("vm.name: %s" % vm.name)
  print("vm.memory: %s" % vm.memory)
  for custom_property in vm.custom_properties:
      ...
  ----

  === Using _links_

  Some of the attributes of types are defined as _links_ in the
  specification of the API. This is done to indicate that their value
  won't usually be populated when retrieving the representation of that
  object, only a link will be returned instead. For example, when
  retrieving a virtual machine, the XML returned by the server will look
  like this:

  [source,python]
  ----
  <vm id="123" href="/ovirt-engine/api/vms/123">
    <name>myvm</name>
    <link rel="diskattachments" href="/ovirt-engine/api/vms/123/diskattachments/>
    ...
  </vm>
  ----

  That link is available as `vm.diskattachments`, but it doesn't contain
  the actual disk attachments. To get the actual data the `Connection`
  class provides a `follow_link` method that uses the value of the `href`
  XML attribute to retrieve the actual data. For example, to retrieve the
  details of the disks of the virtual machine, you can first follow the
  link to the disk attachments, and then follow the link to each of the
  disks:

  [source,python]
  ----

  vm = vm_service.get()


  attachments = connection.follow_link(vm.disk_attachments)
  for attachment in attachments:
      disk = connection.follow_link(attachment.disk)
      print("disk.alias: " % disk.alias)
  ----

  === Locating services

  The API provides a set of _services_, each associated to a particular
  path within the URL space of the server. For example, the service that
  manages the collection of virtual machines of the system lives in
  `/vms`, and the service that manages the virtual machine with identifier
  `123` lives in `/vms/123`.

  In the SDK the root of that tree of services is implemented by the
  _system service_. It is obtained calling the `system_service` method
  of the connection:

  [source,python]
  ----
  system_service = connection.system_service()
  ----

  Once you have the reference to this system service you can use it to get
  references to other services, calling the `+*_service+` methods (called
  _service locators_) of the previous service. For example, to get a
  reference to the service that manages the collection of virtual machines
  of the system use the `vms_service` service locator:

  [source,python]
  ----
  vms_service = system_service.vms_service()
  ----

  To get a reference to the service that manages the virtual machine with
  identifier `123`, use the `vm_service` service locator of the service
  that manages the collection of virtual machines. It receives as a
  parameter the identifier of the virtual machine:

  [source,python]
  ----
  vm_service = vms_service.vms_service('123')
  ----

  IMPORTANT: Calling the service locators doesn't send any request to the
  server. The Python objects that they return are pure services, they
  don't contain any data. For example, the `vm_service` Python object
  obtained in the previous example is *not* the representation of a
  virtual machine. It is the service that can be used to retrieve, update,
  delete, start and stop that virtual machine.

  === Using services

  Once you have located the service you are interested on, you can start
  calling its _service methods_, the methods that send requests to the
  server and do the real work.

  The services that manage collections of object usually have the
  following `list` and `add` methods.

  The services that manage a single object usually have the `get`,
  `update` and `remove` methods.

  Both kind of services can also have additional _action methods_, which
  perform actions other than retrieving, creating, updating or removing.
  Most frequently they available in services that manage a single object.

  ==== Using the _get_ methods

  These service methods are used to retrieve the representation of a
  single object. For example, to retrieve the representation of the
  virtual machine with identifier `123`:

  [source,python]
  ----

  vms_service = system_service.vms_service()
  vm_service = vms_service.vm_service('123')


  vm = vm_service.get()
  ----

  The result will be an instance of the corresponding type. For example,
  in this case, the result will be an instance of the Python class
  `ovirtsdk4.types.Vm`.

  The `get` methods of some services support additional parameters that
  control how to retrieve the representation of the object, or what
  representation to retrieve in case there are multiple representations.
  For example, for virtual machines you may want to retrieve its current
  state, or the state that will be used the next time it is started, as
  they may be different. To do so the `get` method of the service that
  manages a virtual machine supports a
  http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/get/parameters/next_run[next_run]
  boolean parameter:

  [source,python]
  ----



  vm = vm_service.get(next_run=True)
  ----

  Check the http://ovirt.github.io/ovirt-engine-sdk/master[reference]
  documentation of the SDK to find out the details.

  If the object can't be retrieved, for whatever the reason, the SDK will
  raise a `ovirtsdk4.Error` exception, containing the details of the
  failure. This includes the situation when the object doesn't actually
  exist. Note that the exception will be raised when calling the `get`
  service method, the call to the service locator method never fails, even
  if the object doesn't exist, because it doesn't send any request to the
  server. For example:

  [source,python]
  ----


  vm_service = vms_service.vm_service('junk')


  vm = vm_service.get()
  ----

  ==== Using the _list_ methods

  These service methods are used to retrieve the representations of the
  objects of the collection. For example, to retrieve the complete
  collection of virtual machines of the system:

  [source,python]
  ----


  vms_service = system_service.vms_service()
  vms = vms_service.list()
  ----

  The result will be a Python list containing the instances of
  corresponding types. For example, in this case, the result will be a
  list of instances of the Python class `ovirtsdk4.types.Vm`.

  The `list` methods of some services support additional parameters. For
  example, almost all the top level collections support a `search`
  parameter that can be used ask the server to filter the results, and a
  `max` parameter that can be used to limit the number of results returned
  by the server. For example, to get the list of virtual machines whose
  name starts with `my`, and to get at most 10 results:

  [source,python]
  ----
  vms = vms_service.list(search='name=my*', max=10)
  ----

  NOTE: Not all the `list` methods support these parameters, and some
  `list` methods may support other additional parameters. Check the
  http://ovirt.github.io/ovirt-engine-sdk/master[reference] documentation
  of the SDK to find out the details.

  If list of results is empty, for whatever the reason, the returned value
  will be an empty Python list, it will never be `None`.

  If there is an error while trying to retrieve the result, then the SDK
  will raise an `ovirtsdk4.Error` exception containing the details of the
  failure.

  ==== Using the _add_ methods

  These service methods add new elements to the collection. They receive
  an instance of the relevant type describing the object to add, send the
  request to add it, and return an instance of the type describing the
  added object.

  For example, to add a new virtual machine named `myvm`:

  [source,python]
  ----
  from ovirtsdk4 import types


  vm = vms_service.add(
      vm=types.Vm(
          name='myvm',
          cluster=types.Cluster(
              name='mycluster'
          ),
          template=types.Template(
              name='mytemplate'
          )
      )
  )
  ----

  If the object can't be created, for whatever the reason, the SDK will
  raise an `ovirtsdk4.Error` exception containing the details of the
  failure. It will never return `None`.

  It is very important to understand that the Python object returned by
  this `add` method is an instance of the relevant type, it isn't a
  service, just a container of data. In this particular example the
  returned object will be an instance of the `ovirtsdk4.types.Vm` class.
  If once the virtual machine is created you need to perform some
  operation on it, like retrieving it again, or starting it, you will
  first need to find the service that manages it, calling the
  corresponding service locator:

  [source,python]
  ----

  vm = vms_service.add(
    ...
  )


  vm_service = vms_service.vm_service(vm.id)



  vm_service.start()
  ----

  Note that the creation of most objects is an asynchronous task. That
  means, for example, that when creating a new virtual machine the `add`
  method will return *before* the virtual machine is completely created
  and ready to be used. It is good practice to poll the status of the
  object till it is completely created. For a virtual machine that means
  checking till the status is _down_. So the recommended approach to create
  a virtual machine is the following:

  [source,python]
  ----

  vm = vms_service.add(
    ...
  )


  vm_service = vms_service.vm_service(vm.id)



  while True:
      time.sleep(5)
      vm = vm_service.get()
      if vm.status == types.VmStatus.DOWN:
          break
  ----

  In the above loop it is very important to retrieve the object each time,
  using the `get` method, otherwise the `status` attribute won't be
  updated.

  ==== Using the _update_ methods

  These service methods update existing objects. They receive
  an instance of the relevant type describing the update to perform, send
  the request to update it, and return an instance of the type describing
  the updated object.

  For example, to update the name of a virtual machine from `myvm` to
  `newvm`:

  [source,python]
  ----
  from ovirtsdk4 import types



  vm = vms_service.list(search='name=myvm')[0]
  vm_service = vms_service.vm_service(vm.id)


  updated_vm = vms_service.update(
      vm=types.Vm(
          name='newvm'
      )
  )
  ----

  When performing updates, try to avoid sending the complete
  representation of the object, send only the attributes that you want to
  update. For example, try to *avoid* this:

  [source,python]
  ----

  vm = vm_service.get()



  vm.name = 'newvm'


  vms_service.update(vm)
  ----

  The problem with that is double. First you are sending much more
  information than what the server needs, thus wasting resources. Second,
  and more important, the server will try to update all the attributes of
  the object, even those that you didn't need to change. Usually that
  isn't a problem, but has caused many unexpected bugs in the server side
  in the past.

  The `update` methods of some services support additional parameters that
  control how or what to update. For example, for virtual machines you may
  want to update its current state, or the state that will be used the
  next time it is started. To do so the `update` method of the service
  that manages a virtual machine supports a
  http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/update/parameters/next_run[next_run]
  boolean parameter:

  [source,python]
  ----


  vm = vm_service.update(
      vm=types.Vm(
          memory=1073741824
      ),
      next_run=True
  )
  ----

  If the update can't be performed, for whatever the reason, the SDK will
  raise an `ovirtsdk4.Error` exception containing the details of the
  failure. It will never return `None`.

  The Python object returned by this `update` method is an instance of the
  relevant type, it isn't a service, just a container of data. In this
  particular example the returned object will be an instance of the
  `ovirtsdk4.types.Vm` class.

  ==== Using the _remove_ methods

  These service methods remove existing objects. They usually don't
  receive any parameters, as they are methods of the services that manage
  single objects, therefore the service already knows what object to
  remove.

  For example, to remove the virtual machine with identifier `123`:

  [source,python]
  ----

  vm_service = vms_service.vm_service('123')


  vms_service.remove()
  ----

  The `remove` methods of some services support additional parameters that
  control how or what to remove. For example, for virtual machines it is
  possible to remove the virtual machine while preserving the disks.
  To do so the `remove` method of the service that manages a virtual machine supports a
  http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/remove[detach_only]
  boolean parameter:

  [source,python]
  ----

  vm_service.remove(detach_only=True)
  ----

  The `remove` methods return `None` if the object is removed
  successfully. It does *not* return the removed object. If the object
  can't removed, for whatever the reason, the SDK will raise an
  `ovirtsdk4.Error` exception containing the details of the failure.

  ==== Using _action_ methods

  These service methods perform miscellaneous operations. For example, the
  service that manages a virtual machine has methods to start and stop it:

  [source,python]
  ----

  vm_service.start()
  ----

  Many of these methods include parameters that modify the operation. For
  example, the method that starts a virtual machine supports a
  http://ovirt.github.io/ovirt-engine-api-model/master/#services/vm/methods/start/parameters/use_cloud_init[use_cloud_init]
  parameter that indicates if you want to start it using
  https://cloudinit.readthedocs.io/cloud-init[cloud-init]:

  [source,python]
  ----

  vm_service.start(cloud_init=True)
  ----

  Most action methods return `None` when they succeed, and raise a
  `ovirtsdk4.Error` when they fail. But a few action methods return
  values. For example, the service that manages a storage domains has an
  http://ovirt.github.io/ovirt-engine-api-model/master/#services/storage_domain/methods/is_attachedd[is_attached]
  action method that checks if the storage domain is already attached to a
  data center. That method returns a boolean:

  [source,python]
  ----

  sds_service = system_service.storage_domains_service()
  sd_service = sds_service.storage_domain_service('123')
  if sd_service.is_attached():
      ...
  ----

  Check the http://ovirt.github.io/ovirt-engine-sdk[reference]
  documentation of the SDK to see the action methods supported by each
  service, the parameters that they support, and the values that they
  return.

  == More information

  The reference documentation of the API is available
  http://ovirt.github.io/ovirt-engine-api-model[here].

  The reference documentation of the SDK is available
  http://ovirt.github.io/ovirt-engine-sdk[here].

  There is a collection of examples that show how to use the SDK
  https://github.com/oVirt/ovirt-engine-sdk/tree/master/sdk/examples[here].

rpm_vendor:
  Michael Pasternak, Juan Hernandez, Ondra Machacek <mishka8520@yahoo.com, juan.hernandez@redhat.com, omachace@redhat.com>


pkgId: 7dc0b16bb78c18a0c08b5167714b4f43d4dc5bd1833168ff45a5cc34a1c9ae38
name: rh-python36-ovirt-engine-sdk-python-debuginfo
arch: x86_64
version: 4.3.0
epoch: 0
release: 1
summary: Debug information for package rh-python36-ovirt-engine-sdk-python
rpm_license: ASL2
rpm_group: Development/Debug
rpm_buildhost: 2eee4dee3c844fb996093afbe6b3be33
rpm_sourcerpm: rh-python36-ovirt-engine-sdk-python-4.3.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-ovirt-engine-sdk-python.
  Debug information is useful when developing applications that use this
  package or when debugging this package.

rpm_vendor:
  Michael Pasternak, Juan Hernandez, Ondra Machacek <mishka8520@yahoo.com, juan.hernandez@redhat.com, omachace@redhat.com>

location_href:
  01387233-rh-python36-ovirt-engine-sdk-python/rh-python36-ovirt-engine-sdk-python-debuginfo-4.3.0-1.x86_64.rpm


pkgId: 77326bbb373b338d2ed948231ac1d711bcec72f5231cd89041ef3638dfb873d0
name: rh-python36-packaging
arch: noarch
version: 19.2
epoch: 0
release: 1
summary: Core utilities for Python packages
url: https://github.com/pypa/packaging
rpm_license: BSD or Apache License, Version 2.0
rpm_vendor: Donald Stufft and individual contributors <donald@stufft.io>
rpm_group: Development/Libraries
rpm_buildhost: 5e2771010a324eb992301e3b7ed687ff
rpm_sourcerpm: rh-python36-packaging-19.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387232-rh-python36-packaging/rh-python36-packaging-19.2-1.noarch.rpm
checksum_type: sha256
description:
  packaging
  =========

  Core utilities for Python packages


  Documentation
  -------------

  `documentation`_


  Discussion
  ----------

  If you run into bugs, you can file them in our `issue tracker`_.

  You can also join ``#pypa`` on Freenode to ask questions or get involved.


  .. _`documentation`: https://packaging.pypa.io/
  .. _`issue tracker`: https://github.com/pypa/packaging/issues


  Code of Conduct
  ---------------

  Everyone interacting in the packaging project's codebases, issue trackers, chat
  rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_.

  .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/

  Changelog
  ---------

  17.1 - 2017-02-28
  ~~~~~~~~~~~~~~~~~

  * Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions.


  17.0 - 2017-02-28
  ~~~~~~~~~~~~~~~~~

  * Drop support for python 2.6, 3.2, and 3.3.

  * Define minimal pyparsing version to 2.0.2 (`#91 <https://github.com/pypa/packaging/issues/91>`__).

  * Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to
    ``Version`` and ``LegacyVersion`` (`#34 <https://github.com/pypa/packaging/issues/34>`__).

  * Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to
    make it easy to determine if a release is a development release.

  * Add ``utils.canonicalize_version`` to canonicalize version strings or
    ``Version`` instances (`#121 <https://github.com/pypa/packaging/issues/121>`__).


  16.8 - 2016-10-29
  ~~~~~~~~~~~~~~~~~

  * Fix markers that utilize ``in`` so that they render correctly.

  * Fix an erroneous test on Python RC releases.


  16.7 - 2016-04-23
  ~~~~~~~~~~~~~~~~~

  * Add support for the deprecated ``python_implementation`` marker which was
    an undocumented setuptools marker in addition to the newer markers.


  16.6 - 2016-03-29
  ~~~~~~~~~~~~~~~~~

  * Add support for the deprecated, PEP 345 environment markers in addition to
    the newer markers.


  16.5 - 2016-02-26
  ~~~~~~~~~~~~~~~~~

  * Fix a regression in parsing requirements with whitespaces between the comma
    separators.


  16.4 - 2016-02-22
  ~~~~~~~~~~~~~~~~~

  * Fix a regression in parsing requirements like ``foo (==4)``.


  16.3 - 2016-02-21
  ~~~~~~~~~~~~~~~~~

  * Fix a bug where ``packaging.requirements:Requirement`` was overly strict when
    matching legacy requirements.


  16.2 - 2016-02-09
  ~~~~~~~~~~~~~~~~~

  * Add a function that implements the name canonicalization from PEP 503.


  16.1 - 2016-02-07
  ~~~~~~~~~~~~~~~~~

  * Implement requirement specifiers from PEP 508.


  16.0 - 2016-01-19
  ~~~~~~~~~~~~~~~~~

  * Relicense so that packaging is available under *either* the Apache License,
    Version 2.0 or a 2 Clause BSD license.

  * Support installation of packaging when only distutils is available.

  * Fix ``==`` comparison when there is a prefix and a local version in play.
    (`#41 <https://github.com/pypa/packaging/issues/41>`__).

  * Implement environment markers from PEP 508.


  15.3 - 2015-08-01
  ~~~~~~~~~~~~~~~~~

  * Normalize post-release spellings for rev/r prefixes. `#35 <https://github.com/pypa/packaging/issues/35>`__


  15.2 - 2015-05-13
  ~~~~~~~~~~~~~~~~~

  * Fix an error where the arbitary specifier (``===``) was not correctly
    allowing pre-releases when it was being used.

  * Expose the specifier and version parts through properties on the
    ``Specifier`` classes.

  * Allow iterating over the ``SpecifierSet`` to get access to all of the
    ``Specifier`` instances.

  * Allow testing if a version is contained within a specifier via the ``in``
    operator.


  15.1 - 2015-04-13
  ~~~~~~~~~~~~~~~~~

  * Fix a logic error that was causing inconsistent answers about whether or not
    a pre-release was contained within a ``SpecifierSet`` or not.


  15.0 - 2015-01-02
  ~~~~~~~~~~~~~~~~~

  * Add ``Version().is_postrelease`` and ``LegacyVersion().is_postrelease`` to
    make it easy to determine if a release is a post release.

  * Add ``Version().base_version`` and ``LegacyVersion().base_version`` to make
    it easy to get the public version without any pre or post release markers.

  * Support the update to PEP 440 which removed the implied ``!=V.*`` when using
    either ``>V`` or ``<V`` and which instead special cased the handling of
    pre-releases, post-releases, and local versions when using ``>V`` or ``<V``.


  14.5 - 2014-12-17
  ~~~~~~~~~~~~~~~~~

  * Normalize release candidates as ``rc`` instead of ``c``.

  * Expose the ``VERSION_PATTERN`` constant, a regular expression matching
    a valid version.


  14.4 - 2014-12-15
  ~~~~~~~~~~~~~~~~~

  * Ensure that versions are normalized before comparison when used in a
    specifier with a less than (``<``) or greater than (``>``) operator.


  14.3 - 2014-11-19
  ~~~~~~~~~~~~~~~~~

  * **BACKWARDS INCOMPATIBLE** Refactor specifier support so that it can sanely
    handle legacy specifiers as well as PEP 440 specifiers.

  * **BACKWARDS INCOMPATIBLE** Move the specifier support out of
    ``packaging.version`` into ``packaging.specifiers``.


  14.2 - 2014-09-10
  ~~~~~~~~~~~~~~~~~

  * Add prerelease support to ``Specifier``.
  * Remove the ability to do ``item in Specifier()`` and replace it with
    ``Specifier().contains(item)`` in order to allow flags that signal if a
    prerelease should be accepted or not.
  * Add a method ``Specifier().filter()`` which will take an iterable and returns
    an iterable with items that do not match the specifier filtered out.


  14.1 - 2014-09-08
  ~~~~~~~~~~~~~~~~~

  * Allow ``LegacyVersion`` and ``Version`` to be sorted together.
  * Add ``packaging.version.parse()`` to enable easily parsing a version string
    as either a ``Version`` or a ``LegacyVersion`` depending on it's PEP 440
    validity.


  14.0 - 2014-09-05
  ~~~~~~~~~~~~~~~~~

  * Initial release.


pkgId: c6ec0dbb70a3f058033e234f049b32d74ad310ba46afb535b4afd66e18ebbdc7
name: rh-python36-paramiko
arch: noarch
version: 2.7.1
epoch: 0
release: 1
summary: SSH2 protocol library
url: https://github.com/paramiko/paramiko/
rpm_license: LGPL
rpm_vendor: Jeff Forcier <jeff@bitprophet.org>
rpm_group: Development/Libraries
rpm_buildhost: 66100aa9a7c3434c80c6ccdc5a18c3a7
rpm_sourcerpm: rh-python36-paramiko-2.7.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387234-rh-python36-paramiko/rh-python36-paramiko-2.7.1-1.noarch.rpm
checksum_type: sha256
description:
  This is a library for making SSH2 connections (client or server).
  Emphasis is on using SSH2 as an alternative to SSL for making secure
  connections between python scripts.  All major ciphers and hash methods
  are supported.  SFTP client and server mode are both supported too.

  Required packages:
      Cryptography

  To install the development version, ``pip install -e
  git+https://github.com/paramiko/paramiko/#egg=paramiko``.


pkgId: e3942c8cb7b9a3899a046966f1097d2ceeaadfbac5b3a86d2827145949b25de1
name: rh-python36-pbr
arch: noarch
version: 5.4.4
epoch: 0
release: 1
summary: Python Build Reasonableness
url: https://docs.openstack.org/pbr/latest/
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-dev@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: a1b5f9e41e2242e5a94fbf184fd18955
rpm_sourcerpm: rh-python36-pbr-5.4.4-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387206-rh-python36-pbr/rh-python36-pbr-5.4.4-1.noarch.rpm
checksum_type: sha256
description:
  Introduction
  ============

  .. image:: https://img.shields.io/pypi/v/pbr.svg
      :target: https://pypi.python.org/pypi/pbr/
      :alt: Latest Version

  .. image:: https://img.shields.io/pypi/dm/pbr.svg
      :target: https://pypi.python.org/pypi/pbr/
      :alt: Downloads

  PBR is a library that injects some useful and sensible default behaviors
  into your setuptools run. It started off life as the chunks of code that
  were copied between all of the `OpenStack`_ projects. Around the time that
  OpenStack hit 18 different projects each with at least 3 active branches,
  it seemed like a good time to make that code into a proper reusable library.

  PBR is only mildly configurable. The basic idea is that there's a decent
  way to run things and if you do, you should reap the rewards, because then
  it's simple and repeatable. If you want to do things differently, cool! But
  you've already got the power of Python at your fingertips, so you don't
  really need PBR.

  PBR builds on top of the work that `d2to1`_ started to provide for declarative
  configuration. `d2to1`_ is itself an implementation of the ideas behind
  `distutils2`_. Although `distutils2`_ is now abandoned in favor of work towards
  `PEP 426`_ and Metadata 2.0, declarative config is still a great idea and
  specifically important in trying to distribute setup code as a library
  when that library itself will alter how the setup is processed. As Metadata
  2.0 and other modern Python packaging PEPs come out, PBR aims to support
  them as quickly as possible.

  * License: Apache License, Version 2.0
  * Documentation: https://docs.openstack.org/pbr/latest/
  * Source: https://git.openstack.org/cgit/openstack-dev/pbr
  * Bugs: https://bugs.launchpad.net/pbr
  * Change Log: https://docs.openstack.org/pbr/latest/user/history.html

  .. _d2to1: https://pypi.python.org/pypi/d2to1
  .. _distutils2: https://pypi.python.org/pypi/Distutils2
  .. _PEP 426: http://legacy.python.org/dev/peps/pep-0426/
  .. _OpenStack: https://www.openstack.org/


pkgId: 72e1ebb411641409e01d20b8ac9438c1125571d1ad65d2d97e851072fc30c400
name: rh-python36-pexpect
arch: noarch
version: 4.7.0
epoch: 0
release: 1
summary: Pexpect allows easy control of interactive console applications.
url: https://pexpect.readthedocs.io/
rpm_license: ISC license
rpm_group: Development/Libraries
rpm_buildhost: f38833316149439983d12c28a5ad10cc
rpm_sourcerpm: rh-python36-pexpect-4.7.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387132-rh-python36-pexpect/rh-python36-pexpect-4.7.0-1.noarch.rpm
checksum_type: sha256
description:
  Pexpect is a pure Python module for spawning child applications; controlling
  them; and responding to expected patterns in their output. Pexpect works like
  Don Libes' Expect. Pexpect allows your script to spawn a child application and
  control it as if a human were typing commands.

  Pexpect can be used for automating interactive applications such as ssh, ftp,
  passwd, telnet, etc. It can be used to a automate setup scripts for duplicating
  software package installations on different servers. It can be used for
  automated software testing. Pexpect is in the spirit of Don Libes' Expect, but
  Pexpect is pure Python.

  The main features of Pexpect require the pty module in the Python standard
  library, which is only available on Unix-like systems. Some features—waiting
  for patterns from file descriptors or subprocesses—are also available on
  Windows.

rpm_vendor:
  Noah Spurrier; Thomas Kluyver; Jeff Quast <noah@noah.org, thomas@kluyver.me.uk, contact@jeffquast.com>


pkgId: 034d9605a632bf5900e369d38a116d08fc62a33aed8bb84ced03cbdcdcb0adcc
name: rh-python36-prettytable
arch: noarch
version: 0.7.2
epoch: 0
release: 1
description: UNKNOWN
url: http://code.google.com/p/prettytable
rpm_license: BSD (3 clause)
rpm_vendor: Luke Maurits <luke@maurits.id.au>
rpm_group: Development/Libraries
rpm_buildhost: 1c55112393a7421a94b67da3c9818f90
rpm_sourcerpm: rh-python36-prettytable-0.7.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387049-rh-python36-prettytable/rh-python36-prettytable-0.7.2-1.noarch.rpm
checksum_type: sha256
summary:
  A simple Python library for easily displaying tabular data in a visually appealing ASCII table format


pkgId: 61b379c0dff14dd201e88dd00b1c76c7ce1ee83366c5818ecb0ef4d95ab88e6f
name: rh-python36-psutil
arch: src
version: 5.7.0
epoch: 0
release: 1
summary: Cross-platform lib for process and system monitoring in Python.
url: https://github.com/giampaolo/psutil
rpm_license: BSD
rpm_vendor: Giampaolo Rodola <g.rodola@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: e7eac4be23154862a367040a5396ea12
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387094-rh-python36-psutil/rh-python36-psutil-5.7.0-1.src.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/travis/giampaolo/psutil/master.svg?maxAge=3600&label=Linux%20/%20OSX
      :target: https://travis-ci.org/giampaolo/psutil
      :alt: Linux tests (Travis)

  .. image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
      :target: https://ci.appveyor.com/project/giampaolo/psutil
      :alt: Windows tests (Appveyor)

  .. image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
      :target: https://coveralls.io/github/giampaolo/psutil?branch=master
      :alt: Test coverage (coverall.io)

  .. image:: https://readthedocs.org/projects/psutil/badge/?version=latest
      :target: http://psutil.readthedocs.io/en/latest/?badge=latest
      :alt: Documentation Status

  .. image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
      :target: https://pypi.python.org/pypi/psutil/
      :alt: Latest version

  .. image:: https://img.shields.io/github/stars/giampaolo/psutil.svg
      :target: https://github.com/giampaolo/psutil/
      :alt: Github stars

  .. image:: https://img.shields.io/pypi/l/psutil.svg
      :target: https://pypi.python.org/pypi/psutil/
      :alt: License

  ===========
  Quick links
  ===========

  - `Home page <https://github.com/giampaolo/psutil>`_
  - `Install <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
  - `Documentation <http://psutil.readthedocs.io>`_
  - `Download <https://pypi.python.org/pypi?:action=display&name=psutil#downloads>`_
  - `Forum <http://groups.google.com/group/psutil/topics>`_
  - `Blog <http://grodola.blogspot.com/search/label/psutil>`_
  - `Development guide <https://github.com/giampaolo/psutil/blob/master/DEVGUIDE.rst>`_
  - `What's new <https://github.com/giampaolo/psutil/blob/master/HISTORY.rst>`_

  =======
  Summary
  =======

  psutil (process and system utilities) is a cross-platform library for
  retrieving information on **running processes** and **system utilization**
  (CPU, memory, disks, network, sensors) in Python.
  It is useful mainly for **system monitoring**, **profiling and limiting process
  resources** and **management of running processes**.
  It implements many functionalities offered by UNIX command line tools such as:
  ps, top, lsof, netstat, ifconfig, who, df, kill, free, nice, ionice, iostat,
  iotop, uptime, pidof, tty, taskset, pmap.
  psutil currently supports the following platforms:

  - **Linux**
  - **Windows**
  - **OSX**,
  - **FreeBSD, OpenBSD**, **NetBSD**
  - **Sun Solaris**
  - **AIX**

  ...both **32-bit** and **64-bit** architectures, with Python
  versions from **2.6 to 3.6**.
  `PyPy <http://pypy.org/>`__ is also known to work.

  ====================
  Example applications
  ====================

  +------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
  | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/procinfo-small.png     | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/top-small.png      |
  |    :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/procinfo.png          |     :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/top.png          |
  +------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+
  | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/procsmem-small.png     | .. image:: https://github.com/giampaolo/psutil/blob/master/docs/_static/pmap-small.png     |
  |     :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/procsmem.png         |     :target: https://github.com/giampaolo/psutil/blob/master/docs/_static/pmap.png         |
  +------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+

  Also see `scripts directory <https://github.com/giampaolo/psutil/tree/master/scripts>`__
  and `doc recipes <http://psutil.readthedocs.io/#recipes/>`__.

  =====================
  Projects using psutil
  =====================

  At the time of writing psutil has roughly
  `2.9 milion downloads <https://github.com/giampaolo/psutil/issues/1053#issuecomment-340166262>`__
  per month and there are over
  `6000 open source projects <https://libraries.io/pypi/psutil/dependent_repositories?page=1>`__
  on github which depend from psutil.
  Here's some I find particularly interesting:

  - https://github.com/facebook/osquery/
  - https://github.com/nicolargo/glances
  - https://github.com/google/grr
  - https://github.com/Jahaja/psdash
  - https://github.com/ajenti/ajenti
  - https://github.com/home-assistant/home-assistant/

  ========
  Portings
  ========

  - Go: https://github.com/shirou/gopsutil
  - C: https://github.com/hamon-in/cpslib
  - Node: https://github.com/christkv/node-psutil
  - Rust: https://github.com/borntyping/rust-psutil
  - Ruby: https://github.com/spacewander/posixpsutil
  - Nim: https://github.com/johnscillieri/psutil-nim

  ==============
  Example usages
  ==============

  CPU
  ===

  .. code-block:: python

      >>> import psutil
      >>> psutil.cpu_times()
      scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, nice=0.0)
      >>>
      >>> for x in range(3):
      ...     psutil.cpu_percent(interval=1)
      ...
      4.0
      5.9
      3.8
      >>>
      >>> for x in range(3):
      ...     psutil.cpu_percent(interval=1, percpu=True)
      ...
      [4.0, 6.9, 3.7, 9.2]
      [7.0, 8.5, 2.4, 2.1]
      [1.2, 9.0, 9.9, 7.2]
      >>>
      >>> for x in range(3):
      ...     psutil.cpu_times_percent(interval=1, percpu=False)
      ...
      scputimes(user=1.5, nice=0.0, system=0.5, idle=96.5, iowait=1.5, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
      scputimes(user=1.0, nice=0.0, system=0.0, idle=99.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
      scputimes(user=2.0, nice=0.0, system=0.0, idle=98.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
      >>>
      >>> psutil.cpu_count()
      4
      >>> psutil.cpu_count(logical=False)
      2
      >>>
      >>> psutil.cpu_stats()
      scpustats(ctx_switches=20455687, interrupts=6598984, soft_interrupts=2134212, syscalls=0)
      >>>
      >>> psutil.cpu_freq()
      scpufreq(current=931.42925, min=800.0, max=3500.0)
      >>>

  Memory
  ======

  .. code-block:: python

      >>> import psutil
      >>> psutil.virtual_memory()
      svmem(total=10367352832, available=6472179712, percent=37.6, used=8186245120, free=2181107712, active=4748992512, inactive=2758115328, buffers=790724608, cached=3500347392, shared=787554304)
      >>> psutil.swap_memory()
      sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944)
      >>>

  Disks
  =====

  .. code-block:: python

      >>> import psutil
      >>> psutil.disk_partitions()
      [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
       sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
      >>>
      >>> psutil.disk_usage('/')
      sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
      >>>
      >>> psutil.disk_io_counters(perdisk=False)
      sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568, read_merged_count=619166, write_merged_count=812396, busy_time=4523412)
      >>>

  Network
  =======

  .. code-block:: python

      >>> import psutil
      >>> psutil.net_io_counters(pernic=True)
      {'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
       'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
      >>>
      >>> psutil.net_connections()
      [sconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED', pid=1254),
       sconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING', pid=2987),
       sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED', pid=None),
       sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT', pid=None)
       ...]
      >>>
      >>> psutil.net_if_addrs()
      {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
              snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
              snic(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
       'wlan0': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
                 snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
                 snic(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
      >>>
      >>> psutil.net_if_stats()
      {'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
       'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
      >>>

  Sensors
  =======

  .. code-block:: python

      >>> import psutil
      >>> psutil.sensors_temperatures()
      {'acpitz': [shwtemp(label='', current=47.0, high=103.0, critical=103.0)],
       'asus': [shwtemp(label='', current=47.0, high=None, critical=None)],
       'coretemp': [shwtemp(label='Physical id 0', current=52.0, high=100.0, critical=100.0),
                    shwtemp(label='Core 0', current=45.0, high=100.0, critical=100.0),
                    shwtemp(label='Core 1', current=52.0, high=100.0, critical=100.0),
                    shwtemp(label='Core 2', current=45.0, high=100.0, critical=100.0),
                    shwtemp(label='Core 3', current=47.0, high=100.0, critical=100.0)]}
      >>>
      >>> psutil.sensors_fans()
      {'asus': [sfan(label='cpu_fan', current=3200)]}
      >>>
      >>> psutil.sensors_battery()
      sbattery(percent=93, secsleft=16628, power_plugged=False)
      >>>

  Other system info
  =================

  .. code-block:: python

      >>> import psutil
      >>> psutil.users()
      [suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0, pid=1352),
       suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0, pid=1788)]
      >>>
      >>> psutil.boot_time()
      1365519115.0
      >>>

  Process management
  ==================

  .. code-block:: python

      >>> import psutil
      >>> psutil.pids()
      [1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224, 268, 1215, 1216, 1220, 1221, 1243, 1244,
       1301, 1601, 2237, 2355, 2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, 4263, 4282,
       4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, 4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446,
       5167, 5234, 5235, 5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
      >>>
      >>> p = psutil.Process(7055)
      >>> p.name()
      'python'
      >>> p.exe()
      '/usr/bin/python'
      >>> p.cwd()
      '/home/giampaolo'
      >>> p.cmdline()
      ['/usr/bin/python', 'main.py']
      >>>
      >>> p.pid
      7055
      >>> p.ppid()
      7054
      >>> p.parent()
      <psutil.Process(pid=7054, name='bash') at 140008329539408>
      >>> p.children()
      [<psutil.Process(pid=8031, name='python') at 14020832451977>,
       <psutil.Process(pid=8044, name='python') at 19229444921932>]
      >>>
      >>> p.status()
      'running'
      >>> p.username()
      'giampaolo'
      >>> p.create_time()
      1267551141.5019531
      >>> p.terminal()
      '/dev/pts/0'
      >>>
      >>> p.uids()
      puids(real=1000, effective=1000, saved=1000)
      >>> p.gids()
      pgids(real=1000, effective=1000, saved=1000)
      >>>
      >>> p.cpu_times()
      pcputimes(user=1.02, system=0.31, children_user=0.32, children_system=0.1)
      >>> p.cpu_percent(interval=1.0)
      12.1
      >>> p.cpu_affinity()
      [0, 1, 2, 3]
      >>> p.cpu_affinity([0, 1])  # set
      >>> p.cpu_num()
      1
      >>>
      >>> p.memory_info()
      pmem(rss=10915840, vms=67608576, shared=3313664, text=2310144, lib=0, data=7262208, dirty=0)
      >>> p.memory_full_info()  # "real" USS memory usage (Linux, OSX, Win only)
      pfullmem(rss=10199040, vms=52133888, shared=3887104, text=2867200, lib=0, data=5967872, dirty=0, uss=6545408, pss=6872064, swap=0)
      >>> p.memory_percent()
      0.7823
      >>> p.memory_maps()
      [pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=32768, size=2125824, pss=32768, shared_clean=0, shared_dirty=0, private_clean=20480, private_dirty=12288, referenced=32768, anonymous=12288, swap=0),
       pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=3821568, size=3842048, pss=3821568, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=3821568, referenced=3575808, anonymous=3821568, swap=0),
       pmmap_grouped(path='/lib/x8664-linux-gnu/libcrypto.so.0.1', rss=34124, rss=32768, size=2134016, pss=15360, shared_clean=24576, shared_dirty=0, private_clean=0, private_dirty=8192, referenced=24576, anonymous=8192, swap=0),
       pmmap_grouped(path='[heap]',  rss=32768, size=139264, pss=32768, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=32768, referenced=32768, anonymous=32768, swap=0),
       pmmap_grouped(path='[stack]', rss=2465792, size=2494464, pss=2465792, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=2465792, referenced=2277376, anonymous=2465792, swap=0),
       ...]
      >>>
      >>> p.io_counters()
      pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632, read_chars=456232, write_chars=517543)
      >>>
      >>> p.open_files()
      [popenfile(path='/home/giampaolo/svn/psutil/setup.py', fd=3, position=0, mode='r', flags=32768),
       popenfile(path='/var/log/monitd', fd=4, position=235542, mode='a', flags=33793)]
      >>>
      >>> p.connections()
      [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
       pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING'),
       pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED'),
       pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT')]
      >>>
      >>> p.num_threads()
      4
      >>> p.num_fds()
      8
      >>> p.threads()
      [pthread(id=5234, user_time=22.5, system_time=9.2891),
       pthread(id=5235, user_time=0.0, system_time=0.0),
       pthread(id=5236, user_time=0.0, system_time=0.0),
       pthread(id=5237, user_time=0.0707, system_time=1.1)]
      >>>
      >>> p.num_ctx_switches()
      pctxsw(voluntary=78, involuntary=19)
      >>>
      >>> p.nice()
      0
      >>> p.nice(10)  # set
      >>>
      >>> p.ionice(psutil.IOPRIO_CLASS_IDLE)  # IO priority (Win and Linux only)
      >>> p.ionice()
      pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
      >>>
      >>> p.rlimit(psutil.RLIMIT_NOFILE, (5, 5))  # set resource limits (Linux only)
      >>> p.rlimit(psutil.RLIMIT_NOFILE)
      (5, 5)
      >>>
      >>> p.environ()
      {'LC_PAPER': 'it_IT.UTF-8', 'SHELL': '/bin/bash', 'GREP_OPTIONS': '--color=auto',
      'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg', 'COLORTERM': 'gnome-terminal',
       ...}
      >>>
      >>> p.as_dict()
      {'status': 'running', 'num_ctx_switches': pctxsw(voluntary=63, involuntary=1), 'pid': 5457, ...}
      >>> p.is_running()
      True
      >>> p.suspend()
      >>> p.resume()
      >>>
      >>> p.terminate()
      >>> p.wait(timeout=3)
      0
      >>>
      >>> psutil.test()
      USER         PID %CPU %MEM     VSZ     RSS TTY        START    TIME  COMMAND
      root           1  0.0  0.0   24584    2240            Jun17   00:00  init
      root           2  0.0  0.0       0       0            Jun17   00:00  kthreadd
      root           3  0.0  0.0       0       0            Jun17   00:05  ksoftirqd/0
      ...
      giampaolo  31475  0.0  0.0   20760    3024 /dev/pts/0 Jun19   00:00  python2.4
      giampaolo  31721  0.0  2.2  773060  181896            00:04   10:30  chrome
      root       31763  0.0  0.0       0       0            00:05   00:00  kworker/0:1
      >>>

  Further process APIs
  ====================

  .. code-block:: python

      >>> import psutil
      >>> for proc in psutil.process_iter(attrs=['pid', 'name']):
      ...     print(proc.info)
      ...
      {'pid': 1, 'name': 'systemd'}
      {'pid': 2, 'name': 'kthreadd'}
      {'pid': 3, 'name': 'ksoftirqd/0'}
      ...
      >>>
      >>> psutil.pid_exists(3)
      True
      >>>
      >>> def on_terminate(proc):
      ...     print("process {} terminated".format(proc))
      ...
      >>> # waits for multiple processes to terminate
      >>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
      >>>

  Popen wrapper:

  .. code-block:: python

      >>> import psutil
      >>> from subprocess import PIPE
      >>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
      >>> p.name()
      'python'
      >>> p.username()
      'giampaolo'
      >>> p.communicate()
      ('hello\n', None)
      >>> p.wait(timeout=2)
      0
      >>>

  Windows services
  ================

  .. code-block:: python

      >>> list(psutil.win_service_iter())
      [<WindowsService(name='AeLookupSvc', display_name='Application Experience') at 38850096>,
       <WindowsService(name='ALG', display_name='Application Layer Gateway Service') at 38850128>,
       <WindowsService(name='APNMCP', display_name='Ask Update Service') at 38850160>,
       <WindowsService(name='AppIDSvc', display_name='Application Identity') at 38850192>,
       ...]
      >>> s = psutil.win_service_get('alg')
      >>> s.as_dict()
      {'binpath': 'C:\\Windows\\System32\\alg.exe',
       'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
       'display_name': 'Application Layer Gateway Service',
       'name': 'alg',
       'pid': None,
       'start_type': 'manual',
       'status': 'stopped',
       'username': 'NT AUTHORITY\\LocalService'}

  Other samples
  =============

  See `doc recipes <http://psutil.readthedocs.io/#recipes>`__.

  ======
  Author
  ======

  psutil was created and is maintained by
  `Giampaolo Rodola' <http://grodola.blogspot.com/p/about.html>`__.
  A lot of time and effort went into making psutil as it is right now.
  If you feel psutil is useful to you or your business and want to support its
  future development please consider donating me
  (`Giampaolo <http://grodola.blogspot.com/p/about.html>`__) some money.

  .. image:: http://www.paypal.com/en_US/i/btn/x-click-but04.gif
      :target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
      :alt: Donate via PayPal

  Don't want to donate money? Then maybe you could `write me a recommendation on Linkedin <https://www.linkedin.com/in/grodola>`_.


pkgId: f46989823ba479b41f8787a25532a8d9a378654c7620edf7a3ea35221ee6431f
name: rh-python36-psutil-debuginfo
arch: x86_64
version: 5.7.0
epoch: 0
release: 1
summary: Debug information for package rh-python36-psutil
url: https://github.com/giampaolo/psutil
rpm_license: BSD
rpm_vendor: Giampaolo Rodola <g.rodola@gmail.com>
rpm_group: Development/Debug
rpm_buildhost: a4dc5bd71bdb43a2ac11c81580139cc9
rpm_sourcerpm: rh-python36-psutil-5.7.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387094-rh-python36-psutil/rh-python36-psutil-debuginfo-5.7.0-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-psutil.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: 64e109fe9f0a63c03b46f63c7b2a4662f0b095457d2a13ef0e552d8633730c95
name: rh-python36-psycopg2
arch: src
version: 2.8.4
epoch: 0
release: 1
summary: psycopg2 - Python-PostgreSQL Database Adapter
url: http://initd.org/psycopg/
rpm_license: LGPL with exceptions or ZPL
rpm_vendor: Federico Di Gregorio <fog@initd.org>
rpm_group: Development/Libraries
rpm_buildhost: 8b91c5f40b714a2ca14497b2b3d740c3
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387107-rh-python36-psycopg2/rh-python36-psycopg2-2.8.4-1.src.rpm
checksum_type: sha256
description:
  Psycopg is the most popular PostgreSQL database adapter for the Python
  programming language.  Its main features are the complete implementation of
  the Python DB API 2.0 specification and the thread safety (several threads can
  share the same connection).  It was designed for heavily multi-threaded
  applications that create and destroy lots of cursors and make a large number
  of concurrent "INSERT"s or "UPDATE"s.

  Psycopg 2 is mostly implemented in C as a libpq wrapper, resulting in being
  both efficient and secure.  It features client-side and server-side cursors,
  asynchronous communication and notifications, "COPY TO/COPY FROM" support.
  Many Python types are supported out-of-the-box and adapted to matching
  PostgreSQL data types; adaptation can be extended and customized thanks to a
  flexible objects adaptation system.

  Psycopg 2 is both Unicode and Python 3 friendly.


  Documentation
  -------------

  Documentation is included in the ``doc`` directory and is `available online`__.

  .. __: http://initd.org/psycopg/docs/


  Installation
  ------------

  If your ``pip`` version supports wheel_ packages it should be possible to
  install a binary version of Psycopg including all the dependencies from PyPI_.
  Just run::

      $ pip install -U pip      # make sure your pip is up-to-date
      $ pip install psycopg2

  If you want to build Psycopg from source you will need some prerequisites (a C
  compiler, development packages): please check the install_ and the faq_
  documents in the ``doc`` dir for the details.

  .. _wheel: http://pythonwheels.com/
  .. _PyPI: https://pypi.python.org/pypi/psycopg2
  .. _install: http://initd.org/psycopg/docs/install.html#install-from-source
  .. _faq: http://initd.org/psycopg/docs/faq.html#faq-compile

  For any other resource (source code repository, bug tracker, mailing list)
  please check the `project homepage`__.

  .. __: http://initd.org/psycopg/


  :Linux/OSX: |travis|
  :Windows: |appveyor|

  .. |travis| image:: https://travis-ci.org/psycopg/psycopg2.svg?branch=master
      :target: https://travis-ci.org/psycopg/psycopg2
      :alt: Linux and OSX build status

  .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/psycopg/psycopg2?branch=master&svg=true
      :target: https://ci.appveyor.com/project/psycopg/psycopg2/branch/master
      :alt: Windows build status


pkgId: 3fb851f8a76cd8ebfa1d6599f23ac0f94823b88211207784c98d65e20538b7f9
name: rh-python36-psycopg2-debuginfo
arch: x86_64
version: 2.8.4
epoch: 0
release: 1
summary: Debug information for package rh-python36-psycopg2
url: http://initd.org/psycopg/
rpm_license: LGPL with exceptions or ZPL
rpm_vendor: Federico Di Gregorio <fog@initd.org>
rpm_group: Development/Debug
rpm_buildhost: f0c348402b104fb19149b9902c5a5fc1
rpm_sourcerpm: rh-python36-psycopg2-2.8.4-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387107-rh-python36-psycopg2/rh-python36-psycopg2-debuginfo-2.8.4-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-psycopg2.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: 882b3809754fdb14b936ba82b3014b60f78dc00f2ee9e77ba9153df7614b9444
name: rh-python36-pyasn1-modules
arch: noarch
version: 0.2.8
epoch: 0
release: 1
summary: A collection of ASN.1-based protocols modules.
url: https://github.com/etingof/pyasn1-modules
rpm_license: BSD
rpm_vendor: Ilya Etingof <etingof@gmail.com> <etingof@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: e32445ab6ee8419dad0e3219efc2e6dc
rpm_sourcerpm: rh-python36-pyasn1-modules-0.2.8-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387152-rh-python36-pyasn1-modules/rh-python36-pyasn1-modules-0.2.8-1.noarch.rpm
checksum_type: sha256
description:
  A collection of ASN.1 modules expressed in form of pyasn1 classes. Includes protocols PDUs definition (SNMP, LDAP etc.) and various data structures (X.509, PKCS etc.).


pkgId: bd0ba1173ee85cab9826ce210ea2abea01674f9c9576a0c2356e42dac9749769
name: rh-python36-pycparser
arch: noarch
version: 2.20
epoch: 0
release: 1
summary: C parser in Python
url: https://github.com/eliben/pycparser
rpm_license: BSD
rpm_vendor: Eli Bendersky <eliben@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: c67dc34ff9cc49c284dd775fa65a28b4
rpm_sourcerpm: rh-python36-pycparser-2.20-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387108-rh-python36-pycparser/rh-python36-pycparser-2.20-1.noarch.rpm
checksum_type: sha256
description:
          pycparser is a complete parser of the C language, written in
          pure Python using the PLY parsing library.
          It parses C code into an AST and can serve as a front-end for
          C compilers or analysis tools.


pkgId: 05e95e51e298f75108e0d012b442ac99de2fa88acd849788441dcde91fc5f795
name: rh-python36-pycurl
arch: src
version: 7.43.0.3
epoch: 0
release: 1
summary: PycURL -- A Python Interface To The cURL library
url: http://pycurl.io/
rpm_license: LGPL/MIT
rpm_vendor: Oleg Pudeyev <oleg@bsdpower.com>
rpm_group: Development/Libraries
rpm_buildhost: 77c29029128843ea9256cd143be2ab43
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387259-rh-python36-pycurl/rh-python36-pycurl-7.43.0.3-1.src.rpm
checksum_type: sha256
description:
  PycURL -- A Python Interface To The cURL library
  ================================================

  PycURL is a Python interface to `libcurl`_, the multiprotocol file
  transfer library. Similarly to the urllib_ Python module,
  PycURL can be used to fetch objects identified by a URL from a Python program.
  Beyond simple fetches however PycURL exposes most of the functionality of
  libcurl, including:

  - Speed - libcurl is very fast and PycURL, being a thin wrapper above
    libcurl, is very fast as well. PycURL `was benchmarked`_ to be several
    times faster than requests_.
  - Features including multiple protocol support, SSL, authentication and
    proxy options. PycURL supports most of libcurl's callbacks.
  - Multi_ and share_ interfaces.
  - Sockets used for network operations, permitting integration of PycURL
    into the application's I/O loop (e.g., using Tornado_).

  .. _was benchmarked: http://stackoverflow.com/questions/15461995/python-requests-vs-pycurl-performance
  .. _requests: http://python-requests.org/
  .. _Multi: https://curl.haxx.se/libcurl/c/libcurl-multi.html
  .. _share: https://curl.haxx.se/libcurl/c/libcurl-share.html
  .. _Tornado: http://www.tornadoweb.org/


  Requirements
  ------------

  - Python 2.6, 2.7 or 3.1 through 3.6.
  - libcurl 7.19.0 or better.


  Installation
  ------------

  Download source and binary distributions from `PyPI`_ or `Bintray`_.
  Binary wheels are now available for 32 and 64 bit Windows versions.

  Please see `the installation documentation`_ for installation instructions.

  .. _PyPI: https://pypi.python.org/pypi/pycurl
  .. _Bintray: https://dl.bintray.com/pycurl/pycurl/
  .. _the installation documentation: http://pycurl.io/docs/latest/install.html


  Documentation
  -------------

  Documentation for the most recent PycURL release is available on
  `PycURL website <http://pycurl.io/docs/latest/>`_.


  Support
  -------

  For support questions please use `curl-and-python mailing list`_.
  `Mailing list archives`_ are available for your perusal as well.

  Although not an official support venue, `Stack Overflow`_ has been
  popular with some PycURL users.

  Bugs can be reported `via GitHub`_. Please use GitHub only for bug
  reports and direct questions to our mailing list instead.

  .. _curl-and-python mailing list: http://cool.haxx.se/mailman/listinfo/curl-and-python
  .. _Stack Overflow: http://stackoverflow.com/questions/tagged/pycurl
  .. _Mailing list archives: https://curl.haxx.se/mail/list.cgi?list=curl-and-python
  .. _via GitHub: https://github.com/pycurl/pycurl/issues


  License
  -------

  PycURL is dual licensed under the LGPL and an MIT/X derivative license
  based on the libcurl license. The complete text of the licenses is available
  in COPYING-LGPL_ and COPYING-MIT_ files in the source distribution.

  .. _libcurl: https://curl.haxx.se/libcurl/
  .. _urllib: http://docs.python.org/library/urllib.html
  .. _COPYING-LGPL: https://raw.githubusercontent.com/pycurl/pycurl/master/COPYING-LGPL
  .. _COPYING-MIT: https://raw.githubusercontent.com/pycurl/pycurl/master/COPYING-MIT


pkgId: 7f9742d1ed94be302a1e1d63c6854fd8965152ef797452d3d2d2784dda084f3d
name: rh-python36-pycurl-debuginfo
arch: x86_64
version: 7.43.0.3
epoch: 0
release: 1
summary: Debug information for package rh-python36-pycurl
url: http://pycurl.io/
rpm_license: LGPL/MIT
rpm_vendor: Oleg Pudeyev <oleg@bsdpower.com>
rpm_group: Development/Debug
rpm_buildhost: f2be916dee3b4e1fbbef756edbfaf55b
rpm_sourcerpm: rh-python36-pycurl-7.43.0.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387259-rh-python36-pycurl/rh-python36-pycurl-debuginfo-7.43.0.3-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-pycurl.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: b072e5aa83a1eabd6d83ba8ef248a61b77a0ca2e128599043e8f295569af5daa
name: rh-python36-pyfakefs
arch: noarch
version: 3.5.8
epoch: 0
release: 1
summary: pyfakefs implements a fake file system that mocks the Python file system modules.
url: http://pyfakefs.org
rpm_license: UNKNOWN
rpm_vendor: John McGehee <pyfakefs@johnnado.com>
rpm_group: Development/Libraries
rpm_buildhost: 03f9bb2a755448b39d712001acf613fa
rpm_sourcerpm: rh-python36-pyfakefs-3.5.8-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387031-rh-python36-pyfakefs/rh-python36-pyfakefs-3.5.8-1.noarch.rpm
checksum_type: sha256
description:
  pyfakefs implements a fake file system that mocks the Python file system modules.
  Using pyfakefs, your tests operate on a fake file system in memory without
  touching the real disk.  The software under test requires no modification to
  work with pyfakefs.

  pyfakefs works with Linux, Windows and MacOS.



  This file provides general usage instructions for pyfakefs.  There is more:

  * The documentation at [GitHub Pages:](http://jmcgeheeiv.github.io/pyfakefs)
    * The [Release documentation](http://jmcgeheeiv.github.io/pyfakefs/release)
      contains usage documentation for pyfakefs and a description of the
      most relevent classes, methods and functions for the last version
      released on PyPi
    * The [Development documentation](http://jmcgeheeiv.github.io/pyfakefs/master)
      contains the same documentation for the current master branch
    * The [Release 3.3 documentation](http://jmcgeheeiv.github.io/pyfakefs/release33)
      contains usage documentation for the last version of pyfakefs
      supporting Python 2.6, and for the old-style API (which is still
      supported but not documented in the current release)
  * The [Release Notes](https://github.com/jmcgeheeiv/pyfakefs/blob/master/CHANGES.md)
    show a list of changes in the latest versions



  In your own documentation, please link to pyfakefs using the canonical URL <http://pyfakefs.org>.
  This URL always points to the most relevant top page for pyfakefs.



  pyfakefs has support for `unittest` and `pytest`, but can also be used
  directly using `fake_filesystem_unittest.Patcher`. Refer to the
  [usage documentation](http://jmcgeheeiv.github.io/pyfakefs/master/usage.html)
  for more information on test scenarios, test customization and
  using convenience functions.




  pyfakefs works with CPython 2.7, 3.4 and above, on Linux, Windows and OSX
  (MacOS), and with PyPy2 and PyPy3.

  pyfakefs works with [PyTest](http://doc.pytest.org) version 2.8.6 or above.

  pyfakefs will not work with Python libraries that use C libraries to access the
  file system.  This is because pyfakefs cannot patch the underlying C libraries'
  file access functions--the C libraries will always access the real file system.
  For example, pyfakefs will not work with [`lxml`](http://lxml.de/).  In this case
  `lxml` must be replaced with a pure Python alternative such as
  [`xml.etree.ElementTree`](https://docs.python.org/3/library/xml.etree.elementtree.html).


  [pyfakefs is available on PyPi](https://pypi.python.org/pypi/pyfakefs/).





  pyfakefs is currently automatically tested:
  * [![Build Status](https://travis-ci.org/jmcgeheeiv/pyfakefs.svg)](https://travis-ci.org/jmcgeheeiv/pyfakefs)
    on Linux, with Python 2.7, and 3.4 to 3.7, using [Travis](https://travis-ci.org/jmcgeheeiv/pyfakefs)
  * [![Build Status](https://travis-ci.org/jmcgeheeiv/pyfakefs.svg)](https://travis-ci.org/jmcgeheeiv/pyfakefs)
    on MacOS, with Python 2.7, 3.6 and 3.7, using [Travis](https://travis-ci.org/jmcgeheeiv/pyfakefs)
  * [![Build status](https://ci.appveyor.com/api/projects/status/4o8j21ufuo056873/branch/master?svg=true)](https://ci.appveyor.com/project/jmcgeheeiv/pyfakefs/branch/master)
    on Windows, with Python 2.7, and 3.4 to 3.7 using [Appveyor](https://ci.appveyor.com/project/jmcgeheeiv/pyfakefs)




  pyfakefs unit tests can be run using `unittest` or `pytest`:

  ```bash
  $ cd pyfakefs/
  $ export PYTHONPATH=$PWD

  $ python -m pyfakefs.tests.all_tests
  $ python -m pyfakefs.tests.all_tests_without_extra_packages
  $ python -m pytest pyfakefs/pytest_tests/pytest_plugin_test.py
  ```

  These scripts are called by `tox` and Travis-CI. `tox` can be used to run tests
  locally against supported python versions:

  ```bash
  $ tox
  ```



  The `Dockerfile` at the top of the repository will run the tests on the latest
  Ubuntu version.  Build the container:
  ```bash
  cd pyfakefs/
  docker build -t pyfakefs .
  ```
  Run the unit tests in the container:
  ```bash
  docker run -t pyfakefs
  ```



  We always welcome contributions to the library. Check out the [Contributing
  Guide](https://github.com/jmcgeheeiv/pyfakefs/blob/master/CONTRIBUTING.md)
  for more information.


  pyfakefs.py was initially developed at Google by Mike Bland as a modest fake
  implementation of core Python modules.  It was introduced to all of Google
  in September 2006. Since then, it has been enhanced to extend its
  functionality and usefulness.  At last count, pyfakefs is used in over 2,000
  Python tests at Google.

  Google released pyfakefs to the public in 2011 as Google Code project
  [pyfakefs](http://code.google.com/p/pyfakefs/):
  * Fork
    [jmcgeheeiv-pyfakefs](http://code.google.com/p/jmcgeheeiv-pyfakefs/) added
    [direct support for unittest and doctest](../../wiki/Automatically-find-and-patch-file-functions-and-modules)
  * Fork
    [shiffdane-jmcgeheeiv-pyfakefs](http://code.google.com/p/shiffdane-jmcgeheeiv-pyfakefs/)
    added further corrections

  After the [shutdown of Google Code](http://google-opensource.blogspot.com/2015/03/farewell-to-google-code.html)
  was announced, [John McGehee](https://github.com/jmcgeheeiv) merged all three Google Code projects together
  [here on GitHub](https://github.com/jmcgeheeiv/pyfakefs) where an enthusiastic community actively supports, maintains
  and extends pyfakefs.


pkgId: e0d2c0a17b869326c8c7eccca01fa83b89e9442dfb8c8f4f22931069ac99448c
name: rh-python36-pyperclip
arch: noarch
version: 1.7.0
epoch: 0
release: 1
summary: A cross-platform clipboard module for Python. (Only handles plain text for now.)
url: https://github.com/asweigart/pyperclip
rpm_license: BSD
rpm_vendor: Al Sweigart <al@inventwithpython.com>
rpm_group: Development/Libraries
rpm_buildhost: 0cb38accc98247c48cc389d9fe047e11
rpm_sourcerpm: rh-python36-pyperclip-1.7.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387052-rh-python36-pyperclip/rh-python36-pyperclip-1.7.0-1.noarch.rpm
checksum_type: sha256
description:
  Pyperclip is a cross-platform Python module for copy and paste clipboard functions. It works with Python 2 and 3.

  `pip install pyperclip`

  Al Sweigart al@inventwithpython.com
  BSD License

  Example Usage
  =============

      >>> import pyperclip
      >>> pyperclip.copy('The text to be copied to the clipboard.')
      >>> pyperclip.paste()
      'The text to be copied to the clipboard.'


  Currently only handles plaintext.

  On Windows, no additional modules are needed.

  On Mac, this module makes use of the pbcopy and pbpaste commands, which should come with the os.

  On Linux, this module makes use of the xclip or xsel commands, which should come with the os. Otherwise run "sudo apt-get install xclip" or "sudo apt-get install xsel" (Note: xsel does not always seem to work.)

  Otherwise on Linux, you will need the gtk or PyQt4 modules installed.


pkgId: 21523ab437d4e22cdf2caa681da2829e36a89be566836ae6c1f9ea0e059ac1b1
name: rh-python36-pyrad
arch: noarch
version: 2.3
epoch: 0
release: 1
summary: RADIUS tools
url: https://github.com/wichert/pyrad
rpm_license: BSD
rpm_vendor: Wichert Akkerman <wichert@wiggy.net>
rpm_group: Development/Libraries
rpm_buildhost: d4fb297417d5413983bd327ca4f7afb9
rpm_sourcerpm: rh-python36-pyrad-2.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387159-rh-python36-pyrad/rh-python36-pyrad-2.3-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://travis-ci.org/wichert/pyrad.svg?branch=master
      :target: https://travis-ci.org/wichert/pyrad
  .. image:: https://img.shields.io/pypi/v/pyrad.svg
      :target: https://pypi.python.org/pypi/pyrad
  .. image:: https://img.shields.io/pypi/dm/pyrad.svg
      :target: https://pypi.python.org/pypi/pyrad

  Introduction
  ============

  pyrad is an implementation of a RADIUS client/server as described in RFC2865.
  It takes care of all the details like building RADIUS packets, sending
  them and decoding responses.

  Here is an example of doing a authentication request::

      from __future__ import print_function
      from pyrad.client import Client
      from pyrad.dictionary import Dictionary
      import pyrad.packet

      srv = Client(server="localhost", secret=b"Kah3choteereethiejeimaeziecumi",
                   dict=Dictionary("dictionary"))

      
      req = srv.CreateAuthPacket(code=pyrad.packet.AccessRequest,
                                 User_Name="wichert", NAS_Identifier="localhost")
      req["User-Password"] = req.PwCrypt("password")

      
      reply = srv.SendPacket(req)

      if reply.code == pyrad.packet.AccessAccept:
          print("access accepted")
      else:
          print("access denied")

      print("Attributes returned by server:")
      for i in reply.keys():
          print("%s: %s" % (i, reply[i]))



  Requirements & Installation
  ===========================

  pyrad requires Python 2.6 or later, or Python 3.2 or later

  Installing is simple; pyrad uses the standard distutils system for installing
  Python modules::

    python setup.py install


  Author, Copyright, Availability
  ===============================

  pyrad was written by Wichert Akkerman <wichert@wiggy.net> and is licensed
  under a BSD license.

  Copyright and license information can be found in the LICENSE.txt file.

  The current version and documentation can be found on pypi:
  http://pypi.python.org/pypi/pyrad

  Bugs and wishes can be submitted in the pyrad issue tracker on github:
  https://github.com/wichert/pyrad/issues


pkgId: 0fb5359f734941b98ea2abb238a1e1ebe4334a84169c2c51315f645be4f84a5b
name: rh-python36-pyrsistent
arch: src
version: 0.15.7
epoch: 0
release: 1
summary: Persistent/Functional/Immutable data structures
url: http://github.com/tobgu/pyrsistent/
rpm_license: MIT
rpm_vendor: Tobias Gustafsson <tobias.l.gustafsson@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 9558dcc1b3e14bc5ad5745d67d609da8
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387297-rh-python36-pyrsistent/rh-python36-pyrsistent-0.15.7-1.src.rpm
checksum_type: sha256
description:
  Pyrsistent
  ==========
  .. image:: https://travis-ci.org/tobgu/pyrsistent.png?branch=master
      :target: https://travis-ci.org/tobgu/pyrsistent

  .. image:: https://badge.fury.io/py/pyrsistent.svg
      :target: https://badge.fury.io/py/pyrsistent

  .. image:: https://coveralls.io/repos/tobgu/pyrsistent/badge.svg?branch=master&service=github
      :target: https://coveralls.io/github/tobgu/pyrsistent?branch=master


  .. _Pyrthon: https://www.github.com/tobgu/pyrthon/

  Pyrsistent is a number of persistent collections (by some referred to as functional data structures). Persistent in
  the sense that they are immutable.

  All methods on a data structure that would normally mutate it instead return a new copy of the structure containing the
  requested updates. The original structure is left untouched.

  This will simplify the reasoning about what a program does since no hidden side effects ever can take place to these
  data structures. You can rest assured that the object you hold a reference to will remain the same throughout its
  lifetime and need not worry that somewhere five stack levels below you in the darkest corner of your application
  someone has decided to remove that element that you expected to be there.

  Pyrsistent is influenced by persistent data structures such as those found in the standard library of Clojure. The
  data structures are designed to share common elements through path copying.
  It aims at taking these concepts and make them as pythonic as possible so that they can be easily integrated into any python
  program without hassle.

  If you want to go all in on persistent data structures and use literal syntax to define them in your code rather
  than function calls check out Pyrthon_.

  Examples
  --------
  .. _Sequence: collections_
  .. _Hashable: collections_
  .. _Mapping: collections_
  .. _Mappings: collections_
  .. _Set: collections_
  .. _collections: https://docs.python.org/3/library/collections.abc.html
  .. _documentation: http://pyrsistent.readthedocs.org/

  The collection types and key features currently implemented are:

  * PVector_, similar to a python list
  * PMap_, similar to dict
  * PSet_, similar to set
  * PRecord_, a PMap on steroids with fixed fields, optional type and invariant checking and much more
  * PClass_, a Python class fixed fields, optional type and invariant checking and much more
  * `Checked collections`_, PVector, PMap and PSet with optional type and invariance checks and more
  * PBag, similar to collections.Counter
  * PList, a classic singly linked list
  * PDeque, similar to collections.deque
  * Immutable object type (immutable) built on the named tuple
  * freeze_ and thaw_ functions to convert between pythons standard collections and pyrsistent collections.
  * Flexible transformations_ of arbitrarily complex structures built from PMaps and PVectors.

  Below are examples of common usage patterns for some of the structures and features. More information and
  full documentation for all data structures is available in the documentation_.

  .. _PVector:

  PVector
  ~~~~~~~
  With full support for the Sequence_ protocol PVector is meant as a drop in replacement to the built in list from a readers
  point of view. Write operations of course differ since no in place mutation is done but naming should be in line
  with corresponding operations on the built in list.

  Support for the Hashable_ protocol also means that it can be used as key in Mappings_.

  Appends are amortized O(1). Random access and insert is log32(n) where n is the size of the vector.

  .. code:: python

      >>> from pyrsistent import v, pvector

      
      
      >>> v1 = v(1, 2, 3)
      >>> v2 = v1.append(4)
      >>> v3 = v2.set(1, 5)
      >>> v1
      pvector([1, 2, 3])
      >>> v2
      pvector([1, 2, 3, 4])
      >>> v3
      pvector([1, 5, 3, 4])

      
      >>> v3[1]
      5
      >>> v3[1:3]
      pvector([5, 3])

      
      >>> list(x + 1 for x in v3)
      [2, 6, 4, 5]
      >>> pvector(2 * x for x in range(3))
      pvector([0, 2, 4])

  .. _PMap:

  PMap
  ~~~~
  With full support for the Mapping_ protocol PMap is meant as a drop in replacement to the built in dict from a readers point
  of view. Support for the Hashable_ protocol also means that it can be used as key in other Mappings_.

  Random access and insert is log32(n) where n is the size of the map.

  .. code:: python

      >>> from pyrsistent import m, pmap, v

      
      
      >>> m1 = m(a=1, b=2)
      >>> m2 = m1.set('c', 3)
      >>> m3 = m2.set('a', 5)
      >>> m1
      pmap({'a': 1, 'b': 2})
      >>> m2
      pmap({'a': 1, 'c': 3, 'b': 2})
      >>> m3
      pmap({'a': 5, 'c': 3, 'b': 2})
      >>> m3['a']
      5

      
      >>> m4 = m(a=5, b=6, c=v(1, 2))
      >>> m4.transform(('c', 1), 17)
      pmap({'a': 5, 'c': pvector([1, 17]), 'b': 6})
      >>> m5 = m(a=1, b=2)

      
      >>> m5.update(m(a=2, c=3), {'a': 17, 'd': 35})
      pmap({'a': 17, 'c': 3, 'b': 2, 'd': 35})
      >>> pmap({'x': 1, 'y': 2}) + pmap({'y': 3, 'z': 4})
      pmap({'y': 3, 'x': 1, 'z': 4})

      
      >>> m3.items()
      pvector([('a', 5), ('c', 3), ('b', 2)])
      >>> list(m3)
      ['a', 'c', 'b']

  .. _PSet:

  PSet
  ~~~~
  With full support for the Set_ protocol PSet is meant as a drop in replacement to the built in set from a readers point
  of view. Support for the Hashable_ protocol also means that it can be used as key in Mappings_.

  Random access and insert is log32(n) where n is the size of the set.

  .. code:: python

      >>> from pyrsistent import s

      
      >>> s1 = s(1, 2, 3, 2)
      >>> s2 = s1.add(4)
      >>> s3 = s1.remove(1)
      >>> s1
      pset([1, 2, 3])
      >>> s2
      pset([1, 2, 3, 4])
      >>> s3
      pset([2, 3])

      
      >>> s1 | s(3, 4, 5)
      pset([1, 2, 3, 4, 5])
      >>> s1 & s(3, 4, 5)
      pset([3])
      >>> s1 < s2
      True
      >>> s1 < s(3, 4, 5)
      False

  .. _PRecord:

  PRecord
  ~~~~~~~
  A PRecord is a PMap with a fixed set of specified fields. Records are declared as python classes inheriting
  from PRecord. Because it is a PMap it has full support for all Mapping methods such as iteration and element
  access using subscript notation.

  .. code:: python

      >>> from pyrsistent import PRecord, field
      >>> class ARecord(PRecord):
      ...     x = field()
      ...
      >>> r = ARecord(x=3)
      >>> r
      ARecord(x=3)
      >>> r.x
      3
      >>> r.set(x=2)
      ARecord(x=2)
      >>> r.set(y=2)
      Traceback (most recent call last):
      AttributeError: 'y' is not among the specified fields for ARecord

  Type information
  ****************
  It is possible to add type information to the record to enforce type checks. Multiple allowed types can be specified
  by providing an iterable of types.

  .. code:: python

      >>> class BRecord(PRecord):
      ...     x = field(type=int)
      ...     y = field(type=(int, type(None)))
      ...
      >>> BRecord(x=3, y=None)
      BRecord(y=None, x=3)
      >>> BRecord(x=3.0)
      Traceback (most recent call last):
      PTypeError: Invalid type for field BRecord.x, was float


  Custom types (classes) that are iterable should be wrapped in a tuple to prevent their
  members being added to the set of valid types.  Although Enums in particular are now
  supported without wrapping, see #83 for more information.

  Mandatory fields
  ****************
  Fields are not mandatory by default but can be specified as such. If fields are missing an
  *InvariantException* will be thrown which contains information about the missing fields.

  .. code:: python

      >>> from pyrsistent import InvariantException
      >>> class CRecord(PRecord):
      ...     x = field(mandatory=True)
      ...
      >>> r = CRecord(x=3)
      >>> try:
      ...    r.discard('x')
      ... except InvariantException as e:
      ...    print(e.missing_fields)
      ...
      ('CRecord.x',)

  Invariants
  **********
  It is possible to add invariants that must hold when evolving the record. Invariants can be
  specified on both field and record level. If invariants fail an *InvariantException* will be
  thrown which contains information about the failing invariants. An invariant function should
  return a tuple consisting of a boolean that tells if the invariant holds or not and an object
  describing the invariant. This object can later be used to identify which invariant that failed.

  The global invariant function is only executed if all field invariants hold.

  Global invariants are inherited to subclasses.

  .. code:: python

      >>> class RestrictedVector(PRecord):
      ...     __invariant__ = lambda r: (r.y >= r.x, 'x larger than y')
      ...     x = field(invariant=lambda x: (x > 0, 'x negative'))
      ...     y = field(invariant=lambda y: (y > 0, 'y negative'))
      ...
      >>> r = RestrictedVector(y=3, x=2)
      >>> try:
      ...    r.set(x=-1, y=-2)
      ... except InvariantException as e:
      ...    print(e.invariant_errors)
      ...
      ('y negative', 'x negative')
      >>> try:
      ...    r.set(x=2, y=1)
      ... except InvariantException as e:
      ...    print(e.invariant_errors)
      ...
      ('x larger than y',)

  Invariants may also contain multiple assertions. For those cases the invariant function should
  return a tuple of invariant tuples as described above. This structure is reflected in the
  invariant_errors attribute of the exception which will contain tuples with data from all failed
  invariants. Eg:

  .. code:: python

      >>> class EvenX(PRecord):
      ...     x = field(invariant=lambda x: ((x > 0, 'x negative'), (x % 2 == 0, 'x odd')))
      ...
      >>> try:
      ...    EvenX(x=-1)
      ... except InvariantException as e:
      ...    print(e.invariant_errors)
      ...
      (('x negative', 'x odd'),)


  Factories
  *********
  It's possible to specify factory functions for fields. The factory function receives whatever
  is supplied as field value and the actual returned by the factory is assigned to the field
  given that any type and invariant checks hold.
  PRecords have a default factory specified as a static function on the class, create(). It takes
  a *Mapping* as argument and returns an instance of the specific record.
  If a record has fields of type PRecord the create() method of that record will
  be called to create the "sub record" if no factory has explicitly been specified to override
  this behaviour.

  .. code:: python

      >>> class DRecord(PRecord):
      ...     x = field(factory=int)
      ...
      >>> class ERecord(PRecord):
      ...     d = field(type=DRecord)
      ...
      >>> ERecord.create({'d': {'x': '1'}})
      ERecord(d=DRecord(x=1))

  Collection fields
  *****************
  It is also possible to have fields with ``pyrsistent`` collections.

  .. code:: python

     >>> from pyrsistent import pset_field, pmap_field, pvector_field
     >>> class MultiRecord(PRecord):
     ...     set_of_ints = pset_field(int)
     ...     map_int_to_str = pmap_field(int, str)
     ...     vector_of_strs = pvector_field(str)
     ...

  Serialization
  *************
  PRecords support serialization back to dicts. Default serialization will take keys and values
  "as is" and output them into a dict. It is possible to specify custom serialization functions
  to take care of fields that require special treatment.

  .. code:: python

      >>> from datetime import date
      >>> class Person(PRecord):
      ...     name = field(type=unicode)
      ...     birth_date = field(type=date,
      ...                        serializer=lambda format, d: d.strftime(format['date']))
      ...
      >>> john = Person(name=u'John', birth_date=date(1985, 10, 21))
      >>> john.serialize({'date': '%Y-%m-%d'})
      {'birth_date': '1985-10-21', 'name': u'John'}


  .. _instar: https://github.com/boxed/instar/

  .. _PClass:

  PClass
  ~~~~~~
  A PClass is a python class with a fixed set of specified fields. PClasses are declared as python classes inheriting
  from PClass. It is defined the same way that PRecords are and behaves like a PRecord in all aspects except that it
  is not a PMap and hence not a collection but rather a plain Python object.

  .. code:: python

      >>> from pyrsistent import PClass, field
      >>> class AClass(PClass):
      ...     x = field()
      ...
      >>> a = AClass(x=3)
      >>> a
      AClass(x=3)
      >>> a.x
      3


  Checked collections
  ~~~~~~~~~~~~~~~~~~~
  Checked collections currently come in three flavors: CheckedPVector, CheckedPMap and CheckedPSet.

  .. code:: python

      >>> from pyrsistent import CheckedPVector, CheckedPMap, CheckedPSet, thaw
      >>> class Positives(CheckedPSet):
      ...     __type__ = (long, int)
      ...     __invariant__ = lambda n: (n >= 0, 'Negative')
      ...
      >>> class Lottery(PRecord):
      ...     name = field(type=str)
      ...     numbers = field(type=Positives, invariant=lambda p: (len(p) > 0, 'No numbers'))
      ...
      >>> class Lotteries(CheckedPVector):
      ...     __type__ = Lottery
      ...
      >>> class LotteriesByDate(CheckedPMap):
      ...     __key_type__ = date
      ...     __value_type__ = Lotteries
      ...
      >>> lotteries = LotteriesByDate.create({date(2015, 2, 15): [{'name': 'SuperLotto', 'numbers': {1, 2, 3}},
      ...                                                         {'name': 'MegaLotto',  'numbers': {4, 5, 6}}],
      ...                                     date(2015, 2, 16): [{'name': 'SuperLotto', 'numbers': {3, 2, 1}},
      ...                                                         {'name': 'MegaLotto',  'numbers': {6, 5, 4}}]})
      >>> lotteries
      LotteriesByDate({datetime.date(2015, 2, 15): Lotteries([Lottery(numbers=Positives([1, 2, 3]), name='SuperLotto'), Lottery(numbers=Positives([4, 5, 6]), name='MegaLotto')]), datetime.date(2015, 2, 16): Lotteries([Lottery(numbers=Positives([1, 2, 3]), name='SuperLotto'), Lottery(numbers=Positives([4, 5, 6]), name='MegaLotto')])})

      
      
      >>> lottery_0215 = lotteries[date(2015, 2, 15)]
      >>> lottery_0215.transform([0, 'name'], 'SuperDuperLotto')
      Lotteries([Lottery(numbers=Positives([1, 2, 3]), name='SuperDuperLotto'), Lottery(numbers=Positives([4, 5, 6]), name='MegaLotto')])

      
      >>> lottery_0215.transform([0, 'name'], 999)
      Traceback (most recent call last):
      PTypeError: Invalid type for field Lottery.name, was int

      >>> lottery_0215.transform([0, 'numbers'], set())
      Traceback (most recent call last):
      InvariantException: Field invariant failed

      
      
      >>> thaw(lottery_0215)
      [{'numbers': set([1, 2, 3]), 'name': 'SuperLotto'}, {'numbers': set([4, 5, 6]), 'name': 'MegaLotto'}]
      >>> lottery_0215.serialize()
      [{'numbers': set([1, 2, 3]), 'name': 'SuperLotto'}, {'numbers': set([4, 5, 6]), 'name': 'MegaLotto'}]

  .. _transformations:

  Transformations
  ~~~~~~~~~~~~~~~
  Transformations are inspired by the cool library instar_ for Clojure. They let you evolve PMaps and PVectors
  with arbitrarily deep/complex nesting using simple syntax and flexible matching syntax.

  The first argument to transformation is the path that points out the value to transform. The
  second is the transformation to perform. If the transformation is callable it will be applied
  to the value(s) matching the path. The path may also contain callables. In that case they are
  treated as matchers. If the matcher returns True for a specific key it is considered for transformation.

  .. code:: python

      
      >>> from pyrsistent import inc, freeze, thaw, rex, ny, discard
      >>> v1 = freeze([1, 2, 3, 4, 5])
      >>> v1.transform([2], inc)
      pvector([1, 2, 4, 4, 5])
      >>> v1.transform([lambda ix: 0 < ix < 4], 8)
      pvector([1, 8, 8, 8, 5])
      >>> v1.transform([lambda ix, v: ix == 0 or v == 5], 0)
      pvector([0, 2, 3, 4, 0])

      
      >>> v1.transform([ny], 8)
      pvector([8, 8, 8, 8, 8])

      
      >>> scores = freeze({'John': 12, 'Joseph': 34, 'Sara': 23})
      >>> scores.transform([rex('^Jo')], 0)
      pmap({'Joseph': 0, 'Sara': 23, 'John': 0})

      
      >>> news_paper = freeze({'articles': [{'author': 'Sara', 'content': 'A short article'},
      ...                                   {'author': 'Steve', 'content': 'A slightly longer article'}],
      ...                      'weather': {'temperature': '11C', 'wind': '5m/s'}})
      >>> short_news = news_paper.transform(['articles', ny, 'content'], lambda c: c[:25] + '...' if len(c) > 25 else c)
      >>> very_short_news = news_paper.transform(['articles', ny, 'content'], lambda c: c[:15] + '...' if len(c) > 15 else c)
      >>> very_short_news.articles[0].content
      'A short article'
      >>> very_short_news.articles[1].content
      'A slightly long...'

      
      >>> short_news is news_paper
      True
      >>> very_short_news is news_paper
      False
      >>> very_short_news.articles[0] is news_paper.articles[0]
      True

      
      
      >>> thaw(news_paper.transform(['weather'], discard, ['articles', ny, 'content'], discard))
      {'articles': [{'author': 'Sara'}, {'author': 'Steve'}]}

  Evolvers
  ~~~~~~~~
  PVector, PMap and PSet all have support for a concept dubbed *evolvers*. An evolver acts like a mutable
  view of the underlying persistent data structure with "transaction like" semantics. No updates of the original
  data structure is ever performed, it is still fully immutable.

  The evolvers have a very limited API by design to discourage excessive, and inappropriate, usage as that would
  take us down the mutable road. In principle only basic mutation and element access functions are supported.
  Check out the documentation_ of each data structure for specific examples.

  Examples of when you may want to use an evolver instead of working directly with the data structure include:

  * Multiple updates are done to the same data structure and the intermediate results are of no
    interest. In this case using an evolver may be a more efficient and easier to work with.
  * You need to pass a vector into a legacy function or a function that you have no control
    over which performs in place mutations. In this case pass an evolver instance
    instead and then create a new pvector from the evolver once the function returns.

  .. code:: python

      >>> from pyrsistent import v

      
      >>> v1 = v(1, 2, 3)
      >>> e = v1.evolver()
      >>> e[1] = 22
      >>> e = e.append(4)
      >>> e = e.extend([5, 6])
      >>> e[5] += 1
      >>> len(e)
      6

      
      >>> e.is_dirty()
      True

      
      >>> v1
      pvector([1, 2, 3])

      
      
      
      >>> v2 = e.persistent()
      >>> v2
      pvector([1, 22, 3, 4, 5, 7])

      
      
      >>> e.is_dirty()
      False

      
      >>> e[0] = 11

      
      
      >>> e2 = v2.evolver()
      >>> e2[0] = 1111
      >>> e.persistent()
      pvector([11, 22, 3, 4, 5, 7])
      >>> e2.persistent()
      pvector([1111, 22, 3, 4, 5, 7])

  .. _freeze:
  .. _thaw:

  freeze and thaw
  ~~~~~~~~~~~~~~~
  These functions are great when your cozy immutable world has to interact with the evil mutable world outside.

  .. code:: python

      >>> from pyrsistent import freeze, thaw, v, m
      >>> freeze([1, {'a': 3}])
      pvector([1, pmap({'a': 3})])
      >>> thaw(v(1, m(a=3)))
      [1, {'a': 3}]

  Compatibility
  -------------

  Pyrsistent is developed and tested on Python 2.7, 3.5, 3.6, 3.7 and PyPy (Python 2 and 3 compatible). It will most
  likely work on all other versions >= 3.4 but no guarantees are given. :)

  Compatibility issues
  ~~~~~~~~~~~~~~~~~~~~

  .. _27: https://github.com/tobgu/pyrsistent/issues/27

  There is currently one known compatibility issue when comparing built in sets and frozensets to PSets as discussed in 27_.
  It affects python 2 versions < 2.7.8 and python 3 versions < 3.4.0 and is due to a bug described in
  http://bugs.python.org/issue8743.

  Comparisons will fail or be incorrect when using the set/frozenset as left hand side of the comparison. As a workaround
  you need to either upgrade Python to a more recent version, avoid comparing sets/frozensets with PSets or always make
  sure to convert both sides of the comparison to the same type before performing the comparison.

  Performance
  -----------

  Pyrsistent is developed with performance in mind. Still, while some operations are nearly on par with their built in,
  mutable, counterparts in terms of speed, other operations are slower. In the cases where attempts at
  optimizations have been done, speed has generally been valued over space.

  Pyrsistent comes with two API compatible flavors of PVector (on which PMap and PSet are based), one pure Python
  implementation and one implemented as a C extension. The latter generally being 2 - 20 times faster than the former.
  The C extension will be used automatically when possible.

  The pure python implementation is fully PyPy compatible. Running it under PyPy speeds operations up considerably if
  the structures are used heavily (if JITed), for some cases the performance is almost on par with the built in counterparts.

  Type hints
  ----------

  PEP 561 style type hints for use with mypy and various editors are available for most types and functions in pyrsistent.

  Type classes for annotating your own code with pyrsistent types are also available under pyrsistent.typing.

  Installation
  ------------

  pip install pyrsistent

  Documentation
  -------------

  Available at http://pyrsistent.readthedocs.org/

  Brief presentation available at http://slides.com/tobiasgustafsson/immutability-and-python/

  Contributors
  ------------

  Tobias Gustafsson https://github.com/tobgu

  Christopher Armstrong https://github.com/radix

  Anders Hovmöller https://github.com/boxed

  Itamar Turner-Trauring https://github.com/itamarst

  Jonathan Lange https://github.com/jml

  Richard Futrell https://github.com/Futrell

  Jakob Hollenstein https://github.com/jkbjh

  David Honour https://github.com/foolswood

  David R. MacIver https://github.com/DRMacIver

  Marcus Ewert https://github.com/sarum90

  Jean-Paul Calderone https://github.com/exarkun

  Douglas Treadwell https://github.com/douglas-treadwell

  Travis Parker https://github.com/teepark

  Julian Berman https://github.com/Julian

  Dennis Tomas https://github.com/dtomas

  Neil Vyas https://github.com/neilvyas

  doozr https://github.com/doozr

  Kamil Galuszka https://github.com/galuszkak

  Tsuyoshi Hombashi https://github.com/thombashi

  nattofriends https://github.com/nattofriends

  agberk https://github.com/agberk

  Waleed Khan https://github.com/arxanas

  Jean-Louis Fuchs https://github.com/ganwell

  Carlos Corbacho https://github.com/ccorbacho

  Felix Yan https://github.com/felixonmars

  benrg https://github.com/benrg

  Jere Lahelma https://github.com/je-l

  Max Taggart https://github.com/MaxTaggart

  Vincent Philippon https://github.com/vphilippon

  Semen Zhydenko https://github.com/ss18

  Till Varoquaux  https://github.com/till-varoquaux

  Contributing
  ------------

  Want to contribute? That's great! If you experience problems please log them on GitHub. If you want to contribute code,
  please fork the repository and submit a pull request.

  Run tests
  ~~~~~~~~~
  .. _tox: https://tox.readthedocs.io/en/latest/

  Tests can be executed using tox_.

  Install tox: ``pip install tox``

  Run test for Python 2.7: ``tox -epy27``

  Release
  ~~~~~~~
  * Update CHANGES.txt
  * Update README with any new contributors and potential info needed.
  * Update _pyrsistent_version.py
  * python setup.py sdist upload
  * Commit and tag with new version: git add -u . && git commit -m 'Prepare version vX.Y.Z' && git tag -a vX.Y.Z -m 'vX.Y.Z'
  * Push commit and tags: git push && git push --tags

  Project status
  --------------
  Pyrsistent can be considered stable and mature (who knows, there may even be a 1.0 some day :-)). The project is
  maintained, bugs fixed, PRs reviewed and merged and new releases made. I currently do not have time for development
  of new features or functionality which I don't have use for myself. I'm more than happy to take PRs for new
  functionality though!

  There are a bunch of issues marked with ``enhancement`` and ``help wanted`` that contain requests for new functionality
  that would be nice to include. The level of difficulty and extend of the issues varies, please reach out to me if you're
  interested in working on any of them.

  If you feel that you have a grand master plan for where you would like Pyrsistent to go and have the time to put into
  it please don't hesitate to discuss this with me and submit PRs for it. If all goes well I'd be more than happy to add
  additional maintainers to the project!


pkgId: 30383cb0a653856e55b37205370f4d33d58b2bbbada346f30fae692258861c63
name: rh-python36-pyrsistent-debuginfo
arch: x86_64
version: 0.15.7
epoch: 0
release: 1
summary: Debug information for package rh-python36-pyrsistent
url: http://github.com/tobgu/pyrsistent/
rpm_license: MIT
rpm_vendor: Tobias Gustafsson <tobias.l.gustafsson@gmail.com>
rpm_group: Development/Debug
rpm_buildhost: 7ea2604bd4a24986b2a6425a433709ad
rpm_sourcerpm: rh-python36-pyrsistent-0.15.7-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387297-rh-python36-pyrsistent/rh-python36-pyrsistent-debuginfo-0.15.7-1.x86_64.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-pyrsistent.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: b0c359cde4ccb13bc65476e8c70b402cc1ba99dba7a078207e16c5071c4ffcee
name: rh-python36-pytest-runner
arch: noarch
version: 4.2
epoch: 0
release: 1
summary: Invoke py.test as distutils command with dependency resolution
url: https://github.com/pytest-dev/pytest-runner
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: 16f660d375954606bb3a57a397733e8e
rpm_sourcerpm: rh-python36-pytest-runner-4.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01387239-rh-python36-pytest-runner/rh-python36-pytest-runner-4.2-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/pytest-runner.svg
     :target: https://pypi.org/project/pytest-runner

  .. image:: https://img.shields.io/pypi/pyversions/pytest-runner.svg

  .. image:: https://img.shields.io/travis/pytest-dev/pytest-runner/master.svg
     :target: https://travis-ci.org/pytest-dev/pytest-runner

  .. .. image:: https://img.shields.io/appveyor/ci/pytest-dev/pytest-runner/master.svg
  ..    :target: https://ci.appveyor.com/project/pytest-dev/pytest-runner/branch/master

  .. .. image:: https://readthedocs.org/projects/pytest-runner/badge/?version=latest
  ..    :target: https://pytest-runner.readthedocs.io/en/latest/?badge=latest

  Setup scripts can use pytest-runner to add setup.py test support for pytest
  runner.

  Usage
  =====

  - Add 'pytest-runner' to your 'setup_requires'. Pin to '>=2.0,<3dev' (or
    similar) to avoid pulling in incompatible versions.
  - Include 'pytest' and any other testing requirements to 'tests_require'.
  - Invoke tests with ``setup.py pytest``.
  - Pass ``--index-url`` to have test requirements downloaded from an alternate
    index URL (unnecessary if specified for easy_install in setup.cfg).
  - Pass additional py.test command-line options using ``--addopts``.
  - Set permanent options for the ``python setup.py pytest`` command (like ``index-url``)
    in the ``[pytest]`` section of ``setup.cfg``.
  - Set permanent options for the ``py.test`` run (like ``addopts`` or ``pep8ignore``) in the ``[pytest]``
    section of ``pytest.ini`` or ``tox.ini`` or put them in the ``[tool:pytest]``
    section of ``setup.cfg``. See `pytest issue 567
    <https://github.com/pytest-dev/pytest/issues/567>`_.
  - Optionally, set ``test=pytest`` in the ``[aliases]`` section of ``setup.cfg``
    to cause ``python setup.py test`` to invoke pytest.

  Example
  =======

  The most simple usage looks like this in setup.py::

      setup(
          setup_requires=[
              'pytest-runner',
          ],
          tests_require=[
              'pytest',
          ],
      )

  Additional dependencies require to run the tests (e.g. mock or pytest
  plugins) may be added to tests_require and will be downloaded and
  required by the session before invoking pytest.

  Follow `this search on github
  <https://github.com/search?utf8=%E2%9C%93&q=filename%3Asetup.py+pytest-runner&type=Code&ref=searchresults>`_
  for examples of real-world usage.

  Standalone Example
  ==================

  This technique is deprecated - if you have standalone scripts
  you wish to invoke with dependencies, `use rwt
  <https://pypi.org/project/rwt>`_.

  Although ``pytest-runner`` is typically used to add pytest test
  runner support to maintained packages, ``pytest-runner`` may
  also be used to create standalone tests. Consider `this example
  failure <https://gist.github.com/jaraco/d979a558bc0bf2194c23>`_,
  reported in `jsonpickle #117
  <https://github.com/jsonpickle/jsonpickle/issues/117>`_
  or `this MongoDB test
  <https://gist.github.com/jaraco/0b9e482f5c0a1300dc9a>`_
  demonstrating a technique that works even when dependencies
  are required in the test.

  Either example file may be cloned or downloaded and simply run on
  any system with Python and Setuptools. It will download the
  specified dependencies and run the tests. Afterward, the the
  cloned directory can be removed and with it all trace of
  invoking the test. No other dependencies are needed and no
  system configuration is altered.

  Then, anyone trying to replicate the failure can do so easily
  and with all the power of pytest (rewritten assertions,
  rich comparisons, interactive debugging, extensibility through
  plugins, etc).

  As a result, the communication barrier for describing and
  replicating failures is made almost trivially low.

  Considerations
  ==============

  Conditional Requirement
  -----------------------

  Because it uses Setuptools setup_requires, pytest-runner will install itself
  on every invocation of setup.py. In some cases, this causes delays for
  invocations of setup.py that will never invoke pytest-runner. To help avoid
  this contingency, consider requiring pytest-runner only when pytest
  is invoked::

      needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv)
      pytest_runner = ['pytest-runner'] if needs_pytest else []

      

      setup(
          
          setup_requires=[
              
          ] + pytest_runner,
      )


